valgrind.h revision 05b07158841423adc250f04e034bf11e6f892b23
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
8759570ffbe31930ab4d678754daaeec0715117a3dsewardj   latter (on Linux, that is).
8859570ffbe31930ab4d678754daaeec0715117a3dsewardj
8959570ffbe31930ab4d678754daaeec0715117a3dsewardj   Misc note: how to find out what's predefined in gcc by default:
9059570ffbe31930ab4d678754daaeec0715117a3dsewardj   gcc -Wp,-dM somefile.c
9159570ffbe31930ab4d678754daaeec0715117a3dsewardj*/
927af3230a91de23a737946c1b4649b2f826672bf6sewardj#undef PLAT_ppc64_aix5
937af3230a91de23a737946c1b4649b2f826672bf6sewardj#undef PLAT_ppc32_aix5
947af3230a91de23a737946c1b4649b2f826672bf6sewardj#undef PLAT_x86_darwin
957af3230a91de23a737946c1b4649b2f826672bf6sewardj#undef PLAT_amd64_darwin
96f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_x86_linux
97f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_amd64_linux
98f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc32_linux
99f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc64_linux
10059570ffbe31930ab4d678754daaeec0715117a3dsewardj#undef PLAT_arm_linux
101f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
102f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(_AIX) && defined(__64BIT__)
103f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_ppc64_aix5 1
104f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(_AIX) && !defined(__64BIT__)
105f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_ppc32_aix5 1
106f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(__APPLE__) && defined(__i386__)
107f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_x86_darwin 1
108f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(__APPLE__) && defined(__x86_64__)
109f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define PLAT_amd64_darwin 1
11059570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__i386__)
111f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_x86_linux 1
11259570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__x86_64__)
113f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_amd64_linux 1
11459570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
115f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_ppc32_linux 1
11659570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
117f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#  define PLAT_ppc64_linux 1
11859570ffbe31930ab4d678754daaeec0715117a3dsewardj#elif defined(__linux__) && defined(__arm__)
11959570ffbe31930ab4d678754daaeec0715117a3dsewardj#  define PLAT_arm_linux 1
120f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#else
121f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* If we're not compiling for our target platform, don't generate
1220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   any inline asms.  */
1230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  if !defined(NVALGRIND)
1240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#    define NVALGRIND 1
1250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  endif
126b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj#endif
127b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj
1280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
12930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
1300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
1310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* in here of use to end-users -- skip to the next section.           */
13230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
133de4a1d01951937632098a6cda45859afa587a06fsewardj
1340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#if defined(NVALGRIND)
13526aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
13626aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn/* Define NVALGRIND to completely remove the Valgrind magic sequence
1370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   from the compiled code (analogous to NDEBUG's effects on
1380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   assert()) */
1390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
1400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
1419af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
1420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {                                                              \
1430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      (_zzq_rlval) = (_zzq_default);                              \
14426aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn   }
14526aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
1460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#else  /* ! NVALGRIND */
1470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* The following defines the magic code sequences which the JITter
1490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   spots and handles magically.  Don't look too closely at them as
1500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   they will rot your brain.
151de4a1d01951937632098a6cda45859afa587a06fsewardj
1520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The assembly code sequences for all architectures is in this one
1530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   file.  This is because this file must be stand-alone, and we don't
1540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   want to have multiple files.
1550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
1570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   value gets put in the return slot, so that everything works when
1580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   this is executed not under Valgrind.  Args are passed in a memory
1590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   block, and so there's no intrinsic limit to the number that could
1609af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj   be passed, but it's currently five.
161e90c6836fd430124799e52896c99ea27b1c88541nethercote
1625426544c9c3fc835ead99fae9e2054625110ef3enethercote   The macro args are:
1635426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_rlval    result lvalue
1645426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_default  default value (result returned when running on real CPU)
1655426544c9c3fc835ead99fae9e2054625110ef3enethercote      _zzq_request  request code
1669af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj      _zzq_arg1..5  request params
1675426544c9c3fc835ead99fae9e2054625110ef3enethercote
1680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The other two macros are used to support function wrapping, and are
169d68ac3e974d25f88492774f6baa491999afde9f9sewardj   a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
170d68ac3e974d25f88492774f6baa491999afde9f9sewardj   guest's NRADDR pseudo-register and whatever other information is
171d68ac3e974d25f88492774f6baa491999afde9f9sewardj   needed to safely run the call original from the wrapper: on
172d68ac3e974d25f88492774f6baa491999afde9f9sewardj   ppc64-linux, the R2 value at the divert point is also needed.  This
173d68ac3e974d25f88492774f6baa491999afde9f9sewardj   information is abstracted into a user-visible type, OrigFn.
174d68ac3e974d25f88492774f6baa491999afde9f9sewardj
175d68ac3e974d25f88492774f6baa491999afde9f9sewardj   VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
176d68ac3e974d25f88492774f6baa491999afde9f9sewardj   guest, but guarantees that the branch instruction will not be
177d68ac3e974d25f88492774f6baa491999afde9f9sewardj   redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
178d68ac3e974d25f88492774f6baa491999afde9f9sewardj   branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
179d68ac3e974d25f88492774f6baa491999afde9f9sewardj   complete inline asm, since it needs to be combined with more magic
180d68ac3e974d25f88492774f6baa491999afde9f9sewardj   inline asm stuff to be useful.
181e90c6836fd430124799e52896c99ea27b1c88541nethercote*/
182de4a1d01951937632098a6cda45859afa587a06fsewardj
183f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------- x86-{linux,darwin} ---------------- */
1840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
185f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)
186c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
187c885844f7484a13bcf1c7f9b14cf5bc527462963sewardjtypedef
188c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   struct {
189c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned int nraddr; /* where's the code? */
190c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   }
191c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   OrigFn;
192c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
1930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
1940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
1951a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "roll $29, %%edi ; roll $19, %%edi\n\t"
1960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
1980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
1999af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
2009af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj  { volatile unsigned int _zzq_args[6];                           \
2010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    volatile unsigned int _zzq_result;                            \
2020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
2030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
2040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
2050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
2060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
2079af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
2080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %EDX = client_request ( %EAX ) */         \
2100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%ebx,%%ebx"                          \
2110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=d" (_zzq_result)                         \
2120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
2130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
2150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_rlval = _zzq_result;                                     \
216c616819253fcf211745060b2be26076174b1df19njn  }
2170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
218c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
219c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
220c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    volatile unsigned int __addr;                                 \
2210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %EAX = guest_NRADDR */                    \
2230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%ecx,%%ecx"                          \
2240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=a" (__addr)                              \
2250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
2260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
228c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    _zzq_orig->nraddr = __addr;                                   \
229ca0518df66f8c3375a860f1a55a51f18e2a16c44njn  }
2300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CALL_NOREDIR_EAX                                 \
2320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
2330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* call-noredir *%EAX */                     \
2340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgl %%edx,%%edx\n\t"
235f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_x86_linux || PLAT_x86_darwin */
2360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
237f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------ amd64-{linux,darwin} --------------- */
2380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
239f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
240c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
241c885844f7484a13bcf1c7f9b14cf5bc527462963sewardjtypedef
242c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   struct {
243c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned long long int nraddr; /* where's the code? */
244c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   }
245c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj   OrigFn;
246c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj
2470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
2480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
2491a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
2500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
2520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
2539af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
2549af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj  { volatile unsigned long long int _zzq_args[6];                 \
2550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    volatile unsigned long long int _zzq_result;                  \
2560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
2570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
2580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
2590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
2600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
2619af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
2620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %RDX = client_request ( %RAX ) */         \
2640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rbx,%%rbx"                          \
2650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=d" (_zzq_result)                         \
2660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
2670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
2690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_rlval = _zzq_result;                                     \
27085665ca6fa29dd64754dabe50eb98f25896e752acerion  }
2710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
272c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
273c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
274c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    volatile unsigned long long int __addr;                       \
2750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
2760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %RAX = guest_NRADDR */                    \
2770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rcx,%%rcx"                          \
2780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "=a" (__addr)                              \
2790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
2800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "cc", "memory"                             \
2810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
282c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj    _zzq_orig->nraddr = __addr;                                   \
2832c48c7b0a453d32375a4df17e153011b797ef28csewardj  }
2840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CALL_NOREDIR_RAX                                 \
2860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
2870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* call-noredir *%RAX */                     \
2880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "xchgq %%rdx,%%rdx\n\t"
289f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
2900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
291f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-linux ------------------------ */
2920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
293f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_linux)
294d68ac3e974d25f88492774f6baa491999afde9f9sewardj
295d68ac3e974d25f88492774f6baa491999afde9f9sewardjtypedef
296d68ac3e974d25f88492774f6baa491999afde9f9sewardj   struct {
297c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      unsigned int nraddr; /* where's the code? */
298d68ac3e974d25f88492774f6baa491999afde9f9sewardj   }
299d68ac3e974d25f88492774f6baa491999afde9f9sewardj   OrigFn;
300d68ac3e974d25f88492774f6baa491999afde9f9sewardj
3010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
3020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
3031a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
3040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
3060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
3079af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
3080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                                                  \
3099af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj  {          unsigned int  _zzq_args[6];                          \
3101c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj             unsigned int  _zzq_result;                           \
3111c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj             unsigned int* _zzq_ptr;                              \
3120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
3130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
3140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
3150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
3160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
3179af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
3180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_ptr = _zzq_args;                                         \
3191c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
3201c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr 4,%2\n\t" /*ptr*/                        \
3211c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
3220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %R3 = client_request ( %R4 ) */           \
3231c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "or 1,1,1\n\t"                               \
3241c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr %0,3"     /*result*/                     \
3251c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "=b" (_zzq_result)                         \
3261c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "b" (_zzq_default), "b" (_zzq_ptr)         \
3271c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "cc", "memory", "r3", "r4");               \
3280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_rlval = _zzq_result;                                     \
3290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
3300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
331d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
332d68ac3e974d25f88492774f6baa491999afde9f9sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
3331c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj    unsigned int __addr;                                          \
3340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
3350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* %R3 = guest_NRADDR */                     \
3361c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "or 2,2,2\n\t"                               \
3371c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     "mr %0,3"                                    \
3381c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "=b" (__addr)                              \
3390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     :                                            \
3401c5bcb1e17532ec1630056fb2e58ef8e15267f15sewardj                     : "cc", "memory", "r3"                       \
3410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                    );                                            \
342d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->nraddr = __addr;                                   \
3430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
3440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
3450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
3460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
3470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     /* branch-and-link-to-noredir *%R11 */       \
3480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     "or 3,3,3\n\t"
349f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_linux */
3500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
351f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-linux ------------------------ */
3520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
353f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_linux)
354d68ac3e974d25f88492774f6baa491999afde9f9sewardj
355d68ac3e974d25f88492774f6baa491999afde9f9sewardjtypedef
356d68ac3e974d25f88492774f6baa491999afde9f9sewardj   struct {
357d68ac3e974d25f88492774f6baa491999afde9f9sewardj      unsigned long long int nraddr; /* where's the code? */
358d68ac3e974d25f88492774f6baa491999afde9f9sewardj      unsigned long long int r2;  /* what tocptr do we need? */
359d68ac3e974d25f88492774f6baa491999afde9f9sewardj   }
360d68ac3e974d25f88492774f6baa491999afde9f9sewardj   OrigFn;
361d68ac3e974d25f88492774f6baa491999afde9f9sewardj
3621a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
3631a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
3641a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
3651a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
3660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
3670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
3689af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
3690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                                                                  \
3709af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj  {          unsigned long long int  _zzq_args[6];                \
3711a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    register unsigned long long int  _zzq_result __asm__("r3");   \
3721a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    register unsigned long long int* _zzq_ptr __asm__("r4");      \
3731a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
3741a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
3751a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
3761a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
3771a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
3789af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj    _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
3790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _zzq_ptr = _zzq_args;                                         \
3801a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
3811a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* %R3 = client_request ( %R4 ) */           \
3821a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "or 1,1,1"                                   \
3831a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     : "=r" (_zzq_result)                         \
3840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                     : "0" (_zzq_default), "r" (_zzq_ptr)         \
3851a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     : "cc", "memory");                           \
3861a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    _zzq_rlval = _zzq_result;                                     \
3871a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj  }
3881a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
389d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
390d68ac3e974d25f88492774f6baa491999afde9f9sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
391d68ac3e974d25f88492774f6baa491999afde9f9sewardj    register unsigned long long int __addr __asm__("r3");         \
3921a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
3931a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* %R3 = guest_NRADDR */                     \
3941a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "or 2,2,2"                                   \
3951a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     : "=r" (__addr)                              \
3961a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     :                                            \
3971a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     : "cc", "memory"                             \
3981a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                    );                                            \
399d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->nraddr = __addr;                                   \
400d68ac3e974d25f88492774f6baa491999afde9f9sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
401d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     /* %R3 = guest_NRADDR_GPR2 */                \
402d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     "or 4,4,4"                                   \
403d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     : "=r" (__addr)                              \
404d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     :                                            \
405d68ac3e974d25f88492774f6baa491999afde9f9sewardj                     : "cc", "memory"                             \
406d68ac3e974d25f88492774f6baa491999afde9f9sewardj                    );                                            \
407d68ac3e974d25f88492774f6baa491999afde9f9sewardj    _zzq_orig->r2 = __addr;                                       \
4080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj  }
4091a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
4101a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
4111a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
4121a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     /* branch-and-link-to-noredir *%R11 */       \
4131a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj                     "or 3,3,3\n\t"
4141a85f4f4e5e1ec2518137ffa9a6a9bf7d9c50df9sewardj
415f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_linux */
416f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
41759570ffbe31930ab4d678754daaeec0715117a3dsewardj/* ------------------------- arm-linux ------------------------- */
41859570ffbe31930ab4d678754daaeec0715117a3dsewardj
41959570ffbe31930ab4d678754daaeec0715117a3dsewardj#if defined(PLAT_arm_linux)
42059570ffbe31930ab4d678754daaeec0715117a3dsewardj
42159570ffbe31930ab4d678754daaeec0715117a3dsewardjtypedef
42259570ffbe31930ab4d678754daaeec0715117a3dsewardj   struct {
42359570ffbe31930ab4d678754daaeec0715117a3dsewardj      unsigned int nraddr; /* where's the code? */
42459570ffbe31930ab4d678754daaeec0715117a3dsewardj   }
42559570ffbe31930ab4d678754daaeec0715117a3dsewardj   OrigFn;
42659570ffbe31930ab4d678754daaeec0715117a3dsewardj
42759570ffbe31930ab4d678754daaeec0715117a3dsewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
42859570ffbe31930ab4d678754daaeec0715117a3dsewardj            "mov r12, r12, ror #3  ; mov r12, r12, ror #13 \n\t"  \
42959570ffbe31930ab4d678754daaeec0715117a3dsewardj            "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
43059570ffbe31930ab4d678754daaeec0715117a3dsewardj
43159570ffbe31930ab4d678754daaeec0715117a3dsewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
43259570ffbe31930ab4d678754daaeec0715117a3dsewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
43359570ffbe31930ab4d678754daaeec0715117a3dsewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
43459570ffbe31930ab4d678754daaeec0715117a3dsewardj                                                                  \
43559570ffbe31930ab4d678754daaeec0715117a3dsewardj  { volatile unsigned int  _zzq_args[6];                          \
43659570ffbe31930ab4d678754daaeec0715117a3dsewardj    volatile unsigned int  _zzq_result;                           \
43759570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
43859570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
43959570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
44059570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
44159570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
44259570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
44359570ffbe31930ab4d678754daaeec0715117a3dsewardj    __asm__ volatile("mov r3, %1\n\t" /*default*/                 \
44459570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "mov r4, %2\n\t" /*ptr*/                     \
44559570ffbe31930ab4d678754daaeec0715117a3dsewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
44659570ffbe31930ab4d678754daaeec0715117a3dsewardj                     /* R3 = client_request ( R4 ) */             \
44759570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "orr r10, r10, r10\n\t"                      \
44859570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "mov %0, r3"     /*result*/                  \
44959570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "=r" (_zzq_result)                         \
45059570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "r" (_zzq_default), "r" (&_zzq_args[0])    \
45159570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "cc","memory", "r3", "r4");                \
45259570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_rlval = _zzq_result;                                     \
45359570ffbe31930ab4d678754daaeec0715117a3dsewardj  }
45459570ffbe31930ab4d678754daaeec0715117a3dsewardj
45559570ffbe31930ab4d678754daaeec0715117a3dsewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
45659570ffbe31930ab4d678754daaeec0715117a3dsewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
45759570ffbe31930ab4d678754daaeec0715117a3dsewardj    unsigned int __addr;                                          \
45859570ffbe31930ab4d678754daaeec0715117a3dsewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
45959570ffbe31930ab4d678754daaeec0715117a3dsewardj                     /* R3 = guest_NRADDR */                      \
46059570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "orr r11, r11, r11\n\t"                      \
46159570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "mov %0, r3"                                 \
46259570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "=r" (__addr)                              \
46359570ffbe31930ab4d678754daaeec0715117a3dsewardj                     :                                            \
46459570ffbe31930ab4d678754daaeec0715117a3dsewardj                     : "cc", "memory", "r3"                       \
46559570ffbe31930ab4d678754daaeec0715117a3dsewardj                    );                                            \
46659570ffbe31930ab4d678754daaeec0715117a3dsewardj    _zzq_orig->nraddr = __addr;                                   \
46759570ffbe31930ab4d678754daaeec0715117a3dsewardj  }
46859570ffbe31930ab4d678754daaeec0715117a3dsewardj
46959570ffbe31930ab4d678754daaeec0715117a3dsewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                    \
47059570ffbe31930ab4d678754daaeec0715117a3dsewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
47159570ffbe31930ab4d678754daaeec0715117a3dsewardj                     /* branch-and-link-to-noredir *%R4 */        \
47259570ffbe31930ab4d678754daaeec0715117a3dsewardj                     "orr r12, r12, r12\n\t"
47359570ffbe31930ab4d678754daaeec0715117a3dsewardj
47459570ffbe31930ab4d678754daaeec0715117a3dsewardj#endif /* PLAT_arm_linux */
47559570ffbe31930ab4d678754daaeec0715117a3dsewardj
476f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-aix5 ------------------------- */
477f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
478f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_aix5)
479f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
480f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardjtypedef
481f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   struct {
482f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      unsigned int nraddr; /* where's the code? */
483f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      unsigned int r2;  /* what tocptr do we need? */
484f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   }
485f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   OrigFn;
486f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
487f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
488f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
489f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
490f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
491f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
492f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
493f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
494f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                                                  \
495f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  {          unsigned int  _zzq_args[7];                          \
496f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned int  _zzq_result;                           \
497f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned int* _zzq_ptr;                              \
498f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[0] = (unsigned int)(_zzq_request);                  \
499f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
500f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
501f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
502f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
503f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
504f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[6] = (unsigned int)(_zzq_default);                  \
505f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_ptr = _zzq_args;                                         \
506f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile("mr 4,%1\n\t"                                \
507f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "lwz 3, 24(4)\n\t"                           \
508f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
509f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = client_request ( %R4 ) */           \
510f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 1,1,1\n\t"                               \
511f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
512f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (_zzq_result)                         \
513f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "b" (_zzq_ptr)                             \
514f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "r4", "cc", "memory");               \
515f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_rlval = _zzq_result;                                     \
516f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  }
517f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
518f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
519f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
520f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned int __addr;                                 \
521f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
522f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = guest_NRADDR */                     \
523f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 2,2,2\n\t"                               \
524f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
525f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (__addr)                              \
526f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     :                                            \
527f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "cc", "memory"                       \
528f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                    );                                            \
529f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_orig->nraddr = __addr;                                   \
530f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
531f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = guest_NRADDR_GPR2 */                \
532f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 4,4,4\n\t"                               \
533f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
534f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (__addr)                              \
535f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     :                                            \
536f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "cc", "memory"                       \
537f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                    );                                            \
538f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_orig->r2 = __addr;                                       \
539f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  }
540f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
541f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
542f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
543f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* branch-and-link-to-noredir *%R11 */       \
544f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 3,3,3\n\t"
545f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
546f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_aix5 */
547f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
548f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-aix5 ------------------------- */
549f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
550f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_aix5)
551f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
552f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardjtypedef
553f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   struct {
554f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      unsigned long long int nraddr; /* where's the code? */
555f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      unsigned long long int r2;  /* what tocptr do we need? */
556f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   }
557f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   OrigFn;
558f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
559f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define __SPECIAL_INSTRUCTION_PREAMBLE                            \
560f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
561f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
562f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
563f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_DO_CLIENT_REQUEST(                               \
564f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        _zzq_rlval, _zzq_default, _zzq_request,                   \
565f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
566f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                                                  \
567f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  {          unsigned long long int  _zzq_args[7];                \
568f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned long long int  _zzq_result;                 \
569f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned long long int* _zzq_ptr;                    \
570f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[0] = (unsigned int long long)(_zzq_request);        \
571f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[1] = (unsigned int long long)(_zzq_arg1);           \
572f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[2] = (unsigned int long long)(_zzq_arg2);           \
573f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[3] = (unsigned int long long)(_zzq_arg3);           \
574f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[4] = (unsigned int long long)(_zzq_arg4);           \
575f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[5] = (unsigned int long long)(_zzq_arg5);           \
576f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_args[6] = (unsigned int long long)(_zzq_default);        \
577f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_ptr = _zzq_args;                                         \
578f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile("mr 4,%1\n\t"                                \
579f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "ld 3, 48(4)\n\t"                            \
580f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
581f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = client_request ( %R4 ) */           \
582f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 1,1,1\n\t"                               \
583f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
584f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (_zzq_result)                         \
585f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "b" (_zzq_ptr)                             \
586f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "r4", "cc", "memory");               \
587f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_rlval = _zzq_result;                                     \
588f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  }
589f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
590f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
591f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
592f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    register unsigned long long int __addr;                       \
593f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
594f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = guest_NRADDR */                     \
595f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 2,2,2\n\t"                               \
596f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
597f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (__addr)                              \
598f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     :                                            \
599f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "cc", "memory"                       \
600f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                    );                                            \
601f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_orig->nraddr = __addr;                                   \
602f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
603f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* %R3 = guest_NRADDR_GPR2 */                \
604f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 4,4,4\n\t"                               \
605f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "mr %0,3"                                    \
606f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "=b" (__addr)                              \
607f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     :                                            \
608f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     : "r3", "cc", "memory"                       \
609f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                    );                                            \
610f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj    _zzq_orig->r2 = __addr;                                       \
611f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj  }
612f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
613f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
614f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     __SPECIAL_INSTRUCTION_PREAMBLE               \
615f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     /* branch-and-link-to-noredir *%R11 */       \
616f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                     "or 3,3,3\n\t"
617f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
618f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_aix5 */
61985665ca6fa29dd64754dabe50eb98f25896e752acerion
620f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* Insert assembly code for other platforms here... */
62126aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
62237091fb739760631f436043c47de612cf9fd2dd1sewardj#endif /* NVALGRIND */
6232e93c50dc50235189661b70e3f27a4098d5cccccsewardj
62469d9c4625034b60c08e04cc246fcf8093d23fde5nethercote
62530d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
626f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
6270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ugly.  It's the least-worst tradeoff I can think of.               */
6280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ------------------------------------------------------------------ */
6290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* This section defines magic (a.k.a appalling-hack) macros for doing
6310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   guaranteed-no-redirection macros, so as to get from function
6320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   wrappers to the functions they are wrapping.  The whole point is to
6330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   construct standard call sequences, but to do the call itself with a
6340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   special no-redirect call pseudo-instruction that the JIT
6350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   understands and handles specially.  This section is long and
6360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   repetitious, and I can't see a way to make it shorter.
6370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   The naming scheme is as follows:
6390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
6410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   'W' stands for "word" and 'v' for "void".  Hence there are
6430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
6440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   and for each, the possibility of returning a word-typed result, or
6450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   no result.
6460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj*/
6470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Use these to write the name of your wrapper.  NOTE: duplicates
6490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
6500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6515f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn/* Use an extra level of macroisation so as to ensure the soname/fnname
6525f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn   args are fully macro-expanded before pasting them together. */
6535f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn#define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
6545f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn
6550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
6565f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn   VG_CONCAT4(_vgwZU_,soname,_,fnname)
6570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
6595f5ef2ae9e7c2ce5ebc36c1e2fc98e5f81650be3njn   VG_CONCAT4(_vgwZZ_,soname,_,fnname)
6600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
661d68ac3e974d25f88492774f6baa491999afde9f9sewardj/* Use this macro from within a wrapper function to collect the
662d68ac3e974d25f88492774f6baa491999afde9f9sewardj   context (address and possibly other info) of the original function.
663d68ac3e974d25f88492774f6baa491999afde9f9sewardj   Once you have that you can then use it in one of the CALL_FN_
664d68ac3e974d25f88492774f6baa491999afde9f9sewardj   macros.  The type of the argument _lval is OrigFn. */
665d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
6660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Derivatives of the main macros below, for calling functions
6680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   returning void. */
6690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_v(fnptr)                                        \
6710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
6720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_v(_junk,fnptr); } while (0)
6730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_W(fnptr, arg1)                                  \
6750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
6760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
6770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
6790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do { volatile unsigned long _junk;                             \
6800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj        CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
6810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
6825ce4b150ce5d32c9af07a24717081ea34568388asewardj#define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
6835ce4b150ce5d32c9af07a24717081ea34568388asewardj   do { volatile unsigned long _junk;                             \
6845ce4b150ce5d32c9af07a24717081ea34568388asewardj        CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
6855ce4b150ce5d32c9af07a24717081ea34568388asewardj
6862b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4)                \
6872b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
6882b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
6892b5f0a90334a2271791c110548a842fadb5ffc65njn
6902b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5)             \
6912b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
6922b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
6932b5f0a90334a2271791c110548a842fadb5ffc65njn
6942b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6)        \
6952b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
6962b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
6972b5f0a90334a2271791c110548a842fadb5ffc65njn
6982b5f0a90334a2271791c110548a842fadb5ffc65njn#define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7)   \
6992b5f0a90334a2271791c110548a842fadb5ffc65njn   do { volatile unsigned long _junk;                             \
7002b5f0a90334a2271791c110548a842fadb5ffc65njn        CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
7012b5f0a90334a2271791c110548a842fadb5ffc65njn
702f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------- x86-{linux,darwin} ---------------- */
7030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
704f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)
7050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call.  No need to mention eax
7070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   as gcc can already see that, plus causes gcc to bomb. */
7080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
7090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
7100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
7110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   long) == 4. */
7120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
71366226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_v(lval, orig)                                   \
7140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
71566226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
7160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[1];                          \
7170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
71866226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
7200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
7220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
7230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
7240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
7260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
7270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
7280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
72966226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
7300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
73166226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
7320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[2];                          \
7330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
73466226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
7360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
7370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
7380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
7400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $4, %%esp\n"                                       \
7410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
7420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
7430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
7450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
7460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
7470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
74866226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
7490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
75066226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
7510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[3];                          \
7520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
75366226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
7550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
7560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
7570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
7580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
7590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
7610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $8, %%esp\n"                                       \
7620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
7639e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         : /*in*/    "a" (&_argvec[0])                            \
7649e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7659e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      );                                                          \
7669e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      lval = (__typeof__(lval)) _res;                             \
7679e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj   } while (0)
7689e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj
7699e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
7709e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj   do {                                                           \
7719e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile OrigFn        _orig = (orig);                      \
7729e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile unsigned long _argvec[4];                          \
7739e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      volatile unsigned long _res;                                \
7749e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7759e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[1] = (unsigned long)(arg1);                         \
7769e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[2] = (unsigned long)(arg2);                         \
7779e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      _argvec[3] = (unsigned long)(arg3);                         \
7789e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj      __asm__ volatile(                                           \
7799e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 12(%%eax)\n\t"                                    \
7809e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 8(%%eax)\n\t"                                     \
7819e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "pushl 4(%%eax)\n\t"                                     \
7829e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
7839e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         VALGRIND_CALL_NOREDIR_EAX                                \
7849e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         "addl $12, %%esp\n"                                      \
7859e8b07ab0fb74fb15098c406a5dc71e273d50b1csewardj         : /*out*/   "=a" (_res)                                  \
7860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
7870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
7880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
7890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
7900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
7910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
79266226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
7930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
79466226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
7950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[5];                          \
7960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
79766226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
7980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
7990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
8000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
8010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
8020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
8030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
8040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
8050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
8060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
8070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
8080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
8090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $16, %%esp\n"                                      \
8100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
8110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
8120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
8130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
8140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
8150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
8160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
81766226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
8180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
81966226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
8200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[6];                          \
8210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
82266226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
8230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
8240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
8250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
8260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
8270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
8280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
8290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
8300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
8310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
8320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
8330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
8340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
8350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
8360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $20, %%esp\n"                                      \
8370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
8380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
8390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
8400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
8410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
8420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
8430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
84466226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
8450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
84666226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
8470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[7];                          \
8480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
84966226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
8500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
8510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
8520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
8530ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
8540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
8550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
8560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
8570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
8580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
8590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
8600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
8610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
8620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
8630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
8640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
8650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $24, %%esp\n"                                      \
8660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
8670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
8680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
8690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
8700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
8710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
8720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
87366226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
87466226cc1e5e852de3584c76984dace8679730b42sewardj                                 arg7)                            \
8750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
87666226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
8770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[8];                          \
8780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
87966226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
8800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
8810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
8820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
8830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
8840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
8850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
8860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
8870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
8880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
8890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
8900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
8910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
8920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
8930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
8940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
8950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
8960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
8970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $28, %%esp\n"                                      \
8980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
8990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
9000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
9010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
9020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
9030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
9040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
90566226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
90666226cc1e5e852de3584c76984dace8679730b42sewardj                                 arg7,arg8)                       \
9070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
90866226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
9090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[9];                          \
9100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
91166226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
9120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
9130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
9140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
9150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
9160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
9170ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
9180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
9190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[8] = (unsigned long)(arg8);                         \
9200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
9210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 32(%%eax)\n\t"                                    \
9220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
9230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
9240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
9250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
9260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
9270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
9280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
9290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
9300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
9310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $32, %%esp\n"                                      \
9320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
9330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
9340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
9350ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
9360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
9370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
9380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
93945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
94045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj                                 arg7,arg8,arg9)                  \
94145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   do {                                                           \
94245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile OrigFn        _orig = (orig);                      \
94345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _argvec[10];                         \
94445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _res;                                \
94545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
94645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[1] = (unsigned long)(arg1);                         \
94745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[2] = (unsigned long)(arg2);                         \
94845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[3] = (unsigned long)(arg3);                         \
94945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[4] = (unsigned long)(arg4);                         \
95045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[5] = (unsigned long)(arg5);                         \
95145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[6] = (unsigned long)(arg6);                         \
95245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[7] = (unsigned long)(arg7);                         \
95345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[8] = (unsigned long)(arg8);                         \
95445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[9] = (unsigned long)(arg9);                         \
95545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      __asm__ volatile(                                           \
95645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 36(%%eax)\n\t"                                    \
95745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 32(%%eax)\n\t"                                    \
95845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 28(%%eax)\n\t"                                    \
95945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 24(%%eax)\n\t"                                    \
96045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 20(%%eax)\n\t"                                    \
96145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 16(%%eax)\n\t"                                    \
96245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 12(%%eax)\n\t"                                    \
96345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 8(%%eax)\n\t"                                     \
96445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 4(%%eax)\n\t"                                     \
96545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
96645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         VALGRIND_CALL_NOREDIR_EAX                                \
96745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "addl $36, %%esp\n"                                      \
96845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*out*/   "=a" (_res)                                  \
96945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*in*/    "a" (&_argvec[0])                            \
97045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
97145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      );                                                          \
97245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      lval = (__typeof__(lval)) _res;                             \
97345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   } while (0)
97445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
97545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
97645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj                                  arg7,arg8,arg9,arg10)           \
97745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   do {                                                           \
97845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile OrigFn        _orig = (orig);                      \
97945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _argvec[11];                         \
98045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      volatile unsigned long _res;                                \
98145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
98245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[1] = (unsigned long)(arg1);                         \
98345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[2] = (unsigned long)(arg2);                         \
98445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[3] = (unsigned long)(arg3);                         \
98545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[4] = (unsigned long)(arg4);                         \
98645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[5] = (unsigned long)(arg5);                         \
98745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[6] = (unsigned long)(arg6);                         \
98845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[7] = (unsigned long)(arg7);                         \
98945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[8] = (unsigned long)(arg8);                         \
99045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[9] = (unsigned long)(arg9);                         \
99145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      _argvec[10] = (unsigned long)(arg10);                       \
99245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      __asm__ volatile(                                           \
99345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 40(%%eax)\n\t"                                    \
99445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 36(%%eax)\n\t"                                    \
99545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 32(%%eax)\n\t"                                    \
99645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 28(%%eax)\n\t"                                    \
99745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 24(%%eax)\n\t"                                    \
99845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 20(%%eax)\n\t"                                    \
99945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 16(%%eax)\n\t"                                    \
100045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 12(%%eax)\n\t"                                    \
100145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 8(%%eax)\n\t"                                     \
100245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "pushl 4(%%eax)\n\t"                                     \
100345fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
100445fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         VALGRIND_CALL_NOREDIR_EAX                                \
100545fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         "addl $40, %%esp\n"                                      \
100645fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*out*/   "=a" (_res)                                  \
100745fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*in*/    "a" (&_argvec[0])                            \
100845fa5b0cef1884f5025e64401a1443d3e129ed5esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
100945fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      );                                                          \
101045fa5b0cef1884f5025e64401a1443d3e129ed5esewardj      lval = (__typeof__(lval)) _res;                             \
101145fa5b0cef1884f5025e64401a1443d3e129ed5esewardj   } while (0)
101245fa5b0cef1884f5025e64401a1443d3e129ed5esewardj
10135ce4b150ce5d32c9af07a24717081ea34568388asewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
10145ce4b150ce5d32c9af07a24717081ea34568388asewardj                                  arg6,arg7,arg8,arg9,arg10,      \
10155ce4b150ce5d32c9af07a24717081ea34568388asewardj                                  arg11)                          \
10165ce4b150ce5d32c9af07a24717081ea34568388asewardj   do {                                                           \
10175ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile OrigFn        _orig = (orig);                      \
10185ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile unsigned long _argvec[12];                         \
10195ce4b150ce5d32c9af07a24717081ea34568388asewardj      volatile unsigned long _res;                                \
10205ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
10215ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[1] = (unsigned long)(arg1);                         \
10225ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[2] = (unsigned long)(arg2);                         \
10235ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[3] = (unsigned long)(arg3);                         \
10245ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[4] = (unsigned long)(arg4);                         \
10255ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[5] = (unsigned long)(arg5);                         \
10265ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[6] = (unsigned long)(arg6);                         \
10275ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[7] = (unsigned long)(arg7);                         \
10285ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[8] = (unsigned long)(arg8);                         \
10295ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[9] = (unsigned long)(arg9);                         \
10305ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[10] = (unsigned long)(arg10);                       \
10315ce4b150ce5d32c9af07a24717081ea34568388asewardj      _argvec[11] = (unsigned long)(arg11);                       \
10325ce4b150ce5d32c9af07a24717081ea34568388asewardj      __asm__ volatile(                                           \
10335ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 44(%%eax)\n\t"                                    \
10345ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 40(%%eax)\n\t"                                    \
10355ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 36(%%eax)\n\t"                                    \
10365ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 32(%%eax)\n\t"                                    \
10375ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 28(%%eax)\n\t"                                    \
10385ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 24(%%eax)\n\t"                                    \
10395ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 20(%%eax)\n\t"                                    \
10405ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 16(%%eax)\n\t"                                    \
10415ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 12(%%eax)\n\t"                                    \
10425ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 8(%%eax)\n\t"                                     \
10435ce4b150ce5d32c9af07a24717081ea34568388asewardj         "pushl 4(%%eax)\n\t"                                     \
10445ce4b150ce5d32c9af07a24717081ea34568388asewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
10455ce4b150ce5d32c9af07a24717081ea34568388asewardj         VALGRIND_CALL_NOREDIR_EAX                                \
10465ce4b150ce5d32c9af07a24717081ea34568388asewardj         "addl $44, %%esp\n"                                      \
10475ce4b150ce5d32c9af07a24717081ea34568388asewardj         : /*out*/   "=a" (_res)                                  \
10485ce4b150ce5d32c9af07a24717081ea34568388asewardj         : /*in*/    "a" (&_argvec[0])                            \
10495ce4b150ce5d32c9af07a24717081ea34568388asewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
10505ce4b150ce5d32c9af07a24717081ea34568388asewardj      );                                                          \
10515ce4b150ce5d32c9af07a24717081ea34568388asewardj      lval = (__typeof__(lval)) _res;                             \
10525ce4b150ce5d32c9af07a24717081ea34568388asewardj   } while (0)
10535ce4b150ce5d32c9af07a24717081ea34568388asewardj
105466226cc1e5e852de3584c76984dace8679730b42sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
105566226cc1e5e852de3584c76984dace8679730b42sewardj                                  arg6,arg7,arg8,arg9,arg10,      \
105666226cc1e5e852de3584c76984dace8679730b42sewardj                                  arg11,arg12)                    \
10570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
105866226cc1e5e852de3584c76984dace8679730b42sewardj      volatile OrigFn        _orig = (orig);                      \
10590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[13];                         \
10600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
106166226cc1e5e852de3584c76984dace8679730b42sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
10620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
10630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
10640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[3] = (unsigned long)(arg3);                         \
10650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[4] = (unsigned long)(arg4);                         \
10660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[5] = (unsigned long)(arg5);                         \
10670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[6] = (unsigned long)(arg6);                         \
10680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[7] = (unsigned long)(arg7);                         \
10690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[8] = (unsigned long)(arg8);                         \
10700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[9] = (unsigned long)(arg9);                         \
10710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[10] = (unsigned long)(arg10);                       \
10720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[11] = (unsigned long)(arg11);                       \
10730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[12] = (unsigned long)(arg12);                       \
10740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
10750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 48(%%eax)\n\t"                                    \
10760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 44(%%eax)\n\t"                                    \
10770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 40(%%eax)\n\t"                                    \
10780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 36(%%eax)\n\t"                                    \
10790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 32(%%eax)\n\t"                                    \
10800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 28(%%eax)\n\t"                                    \
10810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 24(%%eax)\n\t"                                    \
10820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 20(%%eax)\n\t"                                    \
10830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 16(%%eax)\n\t"                                    \
10840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 12(%%eax)\n\t"                                    \
10850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 8(%%eax)\n\t"                                     \
10860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "pushl 4(%%eax)\n\t"                                     \
10870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
10880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_EAX                                \
10890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "addl $48, %%esp\n"                                      \
10900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
10910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
10920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
10930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
10940ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
10950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
10960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1097f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_x86_linux || PLAT_x86_darwin */
10980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1099f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* ------------------------ amd64-{linux,darwin} --------------- */
11000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1101f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
11020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
11030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
11040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
11050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call. */
11060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
11070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                            "rdi", "r8", "r9", "r10", "r11"
11080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
11090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
11100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   long) == 8. */
11110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1112a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj/* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
1113a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   macros.  In order not to trash the stack redzone, we need to drop
1114a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   %rsp by 128 before the hidden call, and restore afterwards.  The
1115a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   nastyness is that it is only by luck that the stack still appears
1116a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   to be unwindable during the hidden call - since then the behaviour
1117a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   of any routine using this macro does not match what the CFI data
1118a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   says.  Sigh.
1119a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1120a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Why is this important?  Imagine that a wrapper has a stack
1121a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   allocated local, and passes to the hidden call, a pointer to it.
1122a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Because gcc does not know about the hidden call, it may allocate
1123a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   that local in the redzone.  Unfortunately the hidden call may then
1124a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   trash it before it comes to use it.  So we must step clear of the
1125a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   redzone, for the duration of the hidden call, to make it safe.
1126a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1127a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   Probably the same problem afflicts the other redzone-style ABIs too
1128a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is
1129a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   self describing (none of this CFI nonsense) so at least messing
1130a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   with the stack pointer doesn't give a danger of non-unwindable
1131a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj   stack. */
1132a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj
1133c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define CALL_FN_W_v(lval, orig)                                   \
11340ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1135c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      volatile OrigFn        _orig = (orig);                      \
11360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[1];                          \
11370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1138c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
11390ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
1140a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
11410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
11420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1143a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
11440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
11450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
11460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
11470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
11480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
11490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
11500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1151c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
11520ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1153c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      volatile OrigFn        _orig = (orig);                      \
11540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[2];                          \
11550ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1156c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
11570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
11580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
1159a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
11600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
11610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
11620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1163a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
11640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
11650ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
11660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
11670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
11680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
11690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
11700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1171c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
11720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1173c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      volatile OrigFn        _orig = (orig);                      \
11740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[3];                          \
11750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1176c885844f7484a13bcf1c7f9b14cf5bc527462963sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
11770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)(arg1);                         \
11780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)(arg2);                         \
11790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
1180a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
11810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
11820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
11830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
11840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1185a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
11860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=a" (_res)                                  \
11870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "a" (&_argvec[0])                            \
11880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
11890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
11900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
11910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
11920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1193a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
1194a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1195a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1196a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[4];                          \
1197a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1198a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1199a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1200a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1201a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1202a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1203a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1204a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1205a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1206a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1207a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1208a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1209a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1210a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1211a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1212a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1213a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1214a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1215a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1216a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1217a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
1218a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1219a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1220a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[5];                          \
1221a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1222a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1223a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1224a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1225a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1226a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1227a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1228a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1229a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1230a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1231a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1232a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1233a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1234a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1235a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1236a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1237a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1238a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1239a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1240a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1241a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1242a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1243a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
1244a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1245a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1246a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[6];                          \
1247a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1248a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1249a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1250a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1251a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1252a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1253a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1254a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1255a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1256a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1257a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1258a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1259a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1260a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1261a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1262a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1263a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1264a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1265a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1266a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1267a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1268a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1269a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1270a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1271a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
1272a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1273a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1274a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[7];                          \
1275a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1276a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1277a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1278a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1279a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1280a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1281a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1282a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1283a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1284a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1285a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1286a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1287a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1288a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1289a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1290a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1291a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1292a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1293a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1294a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1295a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1296a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1297a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1298a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1299a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1300a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1301a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1302a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                 arg7)                            \
1303a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1304a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1305a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[8];                          \
1306a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1307a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1308a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1309a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1310a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1311a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1312a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1313a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1314a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1315a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1316a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1317a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1318a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1319a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1320a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1321a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1322a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1323a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1324a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1325a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1326a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $8, %%rsp\n"                                       \
1327a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1328a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1329a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1330a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1331a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1332a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1333a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1334a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1335a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1336a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                 arg7,arg8)                       \
1337a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1338a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1339a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[9];                          \
1340a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1341a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1342a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1343a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1344a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1345a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1346a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1347a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1348a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1349a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1350a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1351a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1352a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1353a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1354a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1355a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1356a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1357a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1358a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1359a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1360a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1361a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1362a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $16, %%rsp\n"                                      \
1363a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1364a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1365a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1366a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1367a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1368a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1369a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1370a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1371a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1372a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                 arg7,arg8,arg9)                  \
1373a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1374a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1375a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[10];                         \
1376a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1377a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1378a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1379a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1380a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1381a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1382a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1383a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1384a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1385a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1386a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1387a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1388a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1389a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1390a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1391a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1392a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1393a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1394a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1395a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1396a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1397a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1398a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1399a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1400a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $24, %%rsp\n"                                      \
1401a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1402a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1403a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1404a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1405a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1406a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1407a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1408a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1409a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1410a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                  arg7,arg8,arg9,arg10)           \
1411a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1412a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1413a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[11];                         \
1414a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1415a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1416a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1417a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1418a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1419a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1420a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1421a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1422a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1423a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1424a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1425a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[10] = (unsigned long)(arg10);                       \
1426a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1427a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1428a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 80(%%rax)\n\t"                                    \
1429a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1430a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1431a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1432a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1433a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1434a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1435a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1436a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1437a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1438a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1439a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1440a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $32, %%rsp\n"                                      \
1441a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1442a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1443a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1444a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1445a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1446a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1447a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1448a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1449a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1450a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                  arg7,arg8,arg9,arg10,arg11)     \
1451a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1452a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1453a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[12];                         \
1454a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1455a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1456a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1457a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1458a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1459a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1460a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1461a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1462a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1463a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1464a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1465a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[10] = (unsigned long)(arg10);                       \
1466a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[11] = (unsigned long)(arg11);                       \
1467a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1468a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1469a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 88(%%rax)\n\t"                                    \
1470a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 80(%%rax)\n\t"                                    \
1471a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1472a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1473a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1474a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1475a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1476a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1477a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1478a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1479a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1480a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1481a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1482a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $40, %%rsp\n"                                      \
1483a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1484a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1485a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1486a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1487a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1488a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1489a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1490a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1491a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1492a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
1493a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   do {                                                           \
1494a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile OrigFn        _orig = (orig);                      \
1495a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _argvec[13];                         \
1496a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      volatile unsigned long _res;                                \
1497a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1498a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[1] = (unsigned long)(arg1);                         \
1499a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[2] = (unsigned long)(arg2);                         \
1500a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[3] = (unsigned long)(arg3);                         \
1501a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[4] = (unsigned long)(arg4);                         \
1502a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[5] = (unsigned long)(arg5);                         \
1503a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[6] = (unsigned long)(arg6);                         \
1504a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[7] = (unsigned long)(arg7);                         \
1505a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[8] = (unsigned long)(arg8);                         \
1506a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[9] = (unsigned long)(arg9);                         \
1507a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[10] = (unsigned long)(arg10);                       \
1508a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[11] = (unsigned long)(arg11);                       \
1509a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      _argvec[12] = (unsigned long)(arg12);                       \
1510a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      __asm__ volatile(                                           \
1511a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "subq $128,%%rsp\n\t"                                    \
1512a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 96(%%rax)\n\t"                                    \
1513a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 88(%%rax)\n\t"                                    \
1514a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 80(%%rax)\n\t"                                    \
1515a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 72(%%rax)\n\t"                                    \
1516a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 64(%%rax)\n\t"                                    \
1517a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "pushq 56(%%rax)\n\t"                                    \
1518a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 48(%%rax), %%r9\n\t"                               \
1519a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 40(%%rax), %%r8\n\t"                               \
1520a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 32(%%rax), %%rcx\n\t"                              \
1521a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 24(%%rax), %%rdx\n\t"                              \
1522a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 16(%%rax), %%rsi\n\t"                              \
1523a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq 8(%%rax), %%rdi\n\t"                               \
1524a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
1525a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         VALGRIND_CALL_NOREDIR_RAX                                \
1526a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         "addq $48, %%rsp\n"                                      \
1527a07c2e157185dc577d6fa5fa154a44e4b3afe185sewardj         "addq $128,%%rsp\n\t"                                    \
1528a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*out*/   "=a" (_res)                                  \
1529a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*in*/    "a" (&_argvec[0])                            \
1530a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1531a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      );                                                          \
1532a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj      lval = (__typeof__(lval)) _res;                             \
1533a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj   } while (0)
1534a50f9dcb3a7609e10047a4c6dfa3eb7363088bd2sewardj
1535f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
15360ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1537f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-linux ------------------------ */
15380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1539f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_linux)
15400ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1541ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj/* This is useful for finding out about the on-stack stuff:
1542ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1543ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f9  ( int,int,int,int,int,int,int,int,int );
1544ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f10 ( int,int,int,int,int,int,int,int,int,int );
1545ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
1546ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
1547ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1548ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g9 ( void ) {
1549ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f9(11,22,33,44,55,66,77,88,99);
1550ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1551ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g10 ( void ) {
1552ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f10(11,22,33,44,55,66,77,88,99,110);
1553ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1554ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g11 ( void ) {
1555ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f11(11,22,33,44,55,66,77,88,99,110,121);
1556ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1557ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   int g12 ( void ) {
1558ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      return f12(11,22,33,44,55,66,77,88,99,110,121,132);
1559ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   }
1560ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj*/
1561ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
15620ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
15630ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
15640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These regs are trashed by the hidden call. */
1565ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define __CALLER_SAVED_REGS                                       \
1566ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "lr", "ctr", "xer",                                            \
1567ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
1568ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
1569ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   "r11", "r12", "r13"
15700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1571ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj/* These CALL_FN_ macros assume that on ppc32-linux,
1572ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   sizeof(unsigned long) == 4. */
15730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
157438de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_v(lval, orig)                                   \
15750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
1576d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
15770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[1];                          \
15780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
1579d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
15800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
15810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
15820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
15830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
15840ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
15850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
15860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
15870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
15880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
15890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
15900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
15910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
159238de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
15930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
159438de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      volatile OrigFn        _orig = (orig);                      \
15950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[2];                          \
15960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
159738de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
15980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)arg1;                           \
15990ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
16000ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
16010ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
16020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
16030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
16040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
16050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
16060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
16070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
16080ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
16090ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
16100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
16110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
161238de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
16130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   do {                                                           \
161438de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      volatile OrigFn        _orig = (orig);                      \
16150ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _argvec[3];                          \
16160ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      volatile unsigned long _res;                                \
161738de0994e3561760a8e1ff2efd51a0c9217a3d8dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
16180ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[1] = (unsigned long)arg1;                           \
16190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      _argvec[2] = (unsigned long)arg2;                           \
16200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      __asm__ volatile(                                           \
16210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr 11,%1\n\t"                                           \
16220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
16230ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 4,8(11)\n\t"                                        \
16240ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
16250ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
16260ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         "mr %0,3"                                                \
16270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*out*/   "=r" (_res)                                  \
16280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*in*/    "r" (&_argvec[0])                            \
16290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
16300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      );                                                          \
16310ec07f32bbbb209d749b9974408e6f025ad40b31sewardj      lval = (__typeof__(lval)) _res;                             \
16320ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   } while (0)
16330ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
1634ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
1635ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1636ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1637ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[4];                          \
1638ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1639ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1640ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1641ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1642ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1643ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1644ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1645ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1646ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1647ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1648ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1649ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1650ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1651ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1652ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1653ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1654ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1655ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1656ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1657ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1658ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
1659ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1660ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1661ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[5];                          \
1662ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1663ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1664ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1665ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1666ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1667ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1668ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1669ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1670ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1671ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1672ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1673ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1674ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1675ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1676ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1677ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1678ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1679ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1680ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1681ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1682ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1683ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1684ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
1685ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1686ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1687ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[6];                          \
1688ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1689ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1690ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1691ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1692ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1693ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1694ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1695ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1696ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1697ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1698ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1699ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1700ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1701ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1702ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1703ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1704ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1705ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1706ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1707ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1708ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1709ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1710ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1711ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1712ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
1713ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1714ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1715ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[7];                          \
1716ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1717ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1718ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1719ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1720ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1721ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1722ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1723ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1724ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1725ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1726ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1727ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1728ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1729ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1730ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1731ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1732ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1733ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1734ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1735ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1736ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1737ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1738ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1739ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1740ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1741ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1742ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1743ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7)                            \
1744ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1745ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1746ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[8];                          \
1747ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1748ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1749ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1750ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1751ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1752ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1753ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1754ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1755ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1756ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1757ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1758ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1759ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1760ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1761ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1762ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1763ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1764ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1765ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1766ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1767ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1768ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1769ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1770ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1771ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1772ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1773ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1774ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1775ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1776ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7,arg8)                       \
1777ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1778ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1779ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[9];                          \
1780ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1781ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1782ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1783ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1784ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1785ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1786ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1787ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1788ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1789ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1790ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1791ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1792ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1793ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1794ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1795ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1796ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1797ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1798ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1799ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1800ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1801ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1802ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1803ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1804ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1805ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1806ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1807ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1808ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1809ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1810ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
1811ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                 arg7,arg8,arg9)                  \
1812ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1813ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1814ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[10];                         \
1815ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1816ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1817ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1818ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1819ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1820ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1821ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1822ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1823ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1824ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1825ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
1826ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1827ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1828ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-16\n\t"                                       \
1829ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
1830ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
1831ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
1832ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
1833ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1834ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1835ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1836ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1837ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1838ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1839ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1840ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1841ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1842ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1843ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,16\n\t"                                        \
1844ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1845ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1846ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1847ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1848ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1849ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1850ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1851ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1852ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1853ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                  arg7,arg8,arg9,arg10)           \
1854ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1855ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1856ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[11];                         \
1857ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1858ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1859ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1860ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1861ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1862ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1863ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1864ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1865ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1866ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1867ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
1868ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
1869ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1870ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1871ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-16\n\t"                                       \
1872ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
1873ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
1874ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
1875ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
1876ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
1877ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
1878ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
1879ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1880ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1881ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1882ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1883ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1884ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1885ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1886ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1887ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1888ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1889ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,16\n\t"                                        \
1890ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1891ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1892ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1893ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1894ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1895ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1896ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1897ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1898ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1899ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                  arg7,arg8,arg9,arg10,arg11)     \
1900ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1901ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1902ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[12];                         \
1903ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1904ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1905ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1906ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1907ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1908ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1909ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1910ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1911ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1912ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1913ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
1914ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
1915ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[11] = (unsigned long)arg11;                         \
1916ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1917ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1918ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-32\n\t"                                       \
1919ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg11 */                                              \
1920ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,44(11)\n\t"                                       \
1921ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,16(1)\n\t"                                        \
1922ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
1923ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
1924ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
1925ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
1926ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
1927ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
1928ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
1929ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1930ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1931ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1932ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1933ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1934ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1935ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1936ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1937ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1938ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1939ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,32\n\t"                                        \
1940ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1941ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1942ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1943ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1944ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1945ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
1946ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
1947ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
1948ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
1949ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
1950ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   do {                                                           \
1951ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile OrigFn        _orig = (orig);                      \
1952ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _argvec[13];                         \
1953ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      volatile unsigned long _res;                                \
1954ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
1955ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[1] = (unsigned long)arg1;                           \
1956ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[2] = (unsigned long)arg2;                           \
1957ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[3] = (unsigned long)arg3;                           \
1958ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[4] = (unsigned long)arg4;                           \
1959ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[5] = (unsigned long)arg5;                           \
1960ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[6] = (unsigned long)arg6;                           \
1961ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[7] = (unsigned long)arg7;                           \
1962ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[8] = (unsigned long)arg8;                           \
1963ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[9] = (unsigned long)arg9;                           \
1964ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[10] = (unsigned long)arg10;                         \
1965ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[11] = (unsigned long)arg11;                         \
1966ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      _argvec[12] = (unsigned long)arg12;                         \
1967ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      __asm__ volatile(                                           \
1968ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr 11,%1\n\t"                                           \
1969ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,-32\n\t"                                       \
1970ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg12 */                                              \
1971ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,48(11)\n\t"                                       \
1972ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,20(1)\n\t"                                        \
1973ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg11 */                                              \
1974ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,44(11)\n\t"                                       \
1975ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,16(1)\n\t"                                        \
1976ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg10 */                                              \
1977ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,40(11)\n\t"                                       \
1978ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,12(1)\n\t"                                        \
1979ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* arg9 */                                               \
1980ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,36(11)\n\t"                                       \
1981ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "stw 3,8(1)\n\t"                                         \
1982ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         /* args1-8 */                                            \
1983ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
1984ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 4,8(11)\n\t"                                        \
1985ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 5,12(11)\n\t"                                       \
1986ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
1987ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 7,20(11)\n\t"                                       \
1988ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 8,24(11)\n\t"                                       \
1989ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 9,28(11)\n\t"                                       \
1990ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
1991ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "lwz 11,0(11)\n\t"  /* target->r11 */                    \
1992ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
1993ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "addi 1,1,32\n\t"                                        \
1994ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         "mr %0,3"                                                \
1995ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*out*/   "=r" (_res)                                  \
1996ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*in*/    "r" (&_argvec[0])                            \
1997ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
1998ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      );                                                          \
1999ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj      lval = (__typeof__(lval)) _res;                             \
2000ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj   } while (0)
2001ead61df62ca9c9194f62d4c4a8ba288782acbb0esewardj
2002f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_linux */
20030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2004f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-linux ------------------------ */
20050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
2006f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_linux)
20079734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
20089734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
20099734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
20109734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* These regs are trashed by the hidden call. */
2011cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define __CALLER_SAVED_REGS                                       \
2012cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "lr", "ctr", "xer",                                            \
2013cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
2014cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
2015cd63639e41d591b17cf8900e49e28048d39104c2sewardj   "r11", "r12", "r13"
20169734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
20179734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj/* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
20189734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   long) == 8. */
20199734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2020d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_v(lval, orig)                                   \
20219734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
2022d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
2023d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+0];                        \
20249734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
2025d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
2026d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1] = (unsigned long)_orig.r2;                       \
2027d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2] = (unsigned long)_orig.nraddr;                   \
20289734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
20299734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
2030d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2031d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2032d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
20339734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
20349734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
20359734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
2036d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
20379734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
2038d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
20399734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
20409734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
20419734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
20429734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
20439734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2044d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
20459734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
2046d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
2047d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+1];                        \
20489734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
2049d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
2050d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2051d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2052d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
20539734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
20549734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
2055d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2056d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2057d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2058d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
20599734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
20609734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
20619734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
2062d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
20639734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
2064d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
20659734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
20669734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
20679734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
20689734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
20699734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2070d68ac3e974d25f88492774f6baa491999afde9f9sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
20719734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   do {                                                           \
2072d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile OrigFn        _orig = (orig);                      \
2073d68ac3e974d25f88492774f6baa491999afde9f9sewardj      volatile unsigned long _argvec[3+2];                        \
20749734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      volatile unsigned long _res;                                \
2075d68ac3e974d25f88492774f6baa491999afde9f9sewardj      /* _argvec[0] holds current r2 across the call */           \
2076d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2077d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2078d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2079d68ac3e974d25f88492774f6baa491999afde9f9sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
20809734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      __asm__ volatile(                                           \
20819734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
2082d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2083d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2084d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2085cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2086cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2087cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2088cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2089cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2090cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2091cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2092cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2093cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2094cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2095cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2096cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2097cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2098cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
2099cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2100cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2101cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+3];                        \
2102cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2103cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2104cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2105cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2106cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2107cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2108cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2109cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2110cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2111cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2112cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2113cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2114cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2115cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2116d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
21179734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
21189734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr 11,%1\n\t"                                           \
21199734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         "mr %0,3\n\t"                                            \
2120d68ac3e974d25f88492774f6baa491999afde9f9sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
21219734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*out*/   "=r" (_res)                                  \
2122d68ac3e974d25f88492774f6baa491999afde9f9sewardj         : /*in*/    "r" (&_argvec[2])                            \
21239734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2124cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2125cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2126cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2127cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2128cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
2129cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2130cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2131cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+4];                        \
2132cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2133cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2134cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2135cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2136cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2137cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2138cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2139cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2140cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2141cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2142cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2143cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2144cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2145cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2146cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2147cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2148cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2149cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2150cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2151cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2152cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2153cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2154cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2155cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2156cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2157cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2158cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2159cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2160cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
2161cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2162cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2163cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+5];                        \
2164cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2165cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2166cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2167cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2168cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2169cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2170cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2171cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2172cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2173cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2174cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2175cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2176cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2177cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2178cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2179cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2180cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2181cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2182cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2183cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2184cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2185cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2186cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2187cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2188cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2189cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2190cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2191cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2192cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2193cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2194cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
2195cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2196cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2197cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+6];                        \
2198cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2199cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2200cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2201cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2202cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2203cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2204cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2205cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2206cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2207cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2208cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2209cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2210cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2211cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2212cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2213cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2214cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2215cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2216cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2217cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2218cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2219cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2220cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2221cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2222cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2223cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2224cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2225cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2226cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2227cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2228cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2229cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2230cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2231cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7)                            \
2232cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2233cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2234cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+7];                        \
2235cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2236cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2237cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2238cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2239cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2240cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2241cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2242cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2243cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2244cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2245cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2246cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2247cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2248cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2249cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2250cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2251cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2252cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2253cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2254cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2255cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2256cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2257cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2258cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2259cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2260cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2261cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2262cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2263cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2264cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2265cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2266cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2267cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2268cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2269cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2270cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7,arg8)                       \
2271cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2272cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2273cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+8];                        \
2274cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2275cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2276cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2277cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2278cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2279cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2280cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2281cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2282cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2283cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2284cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2285cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2286cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2287cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2288cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2289cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2290cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2291cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2292cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2293cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2294cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2295cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2296cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2297cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2298cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2299cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2300cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2301cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2302cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)" /* restore tocptr */                      \
2303cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2304cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2305cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2306cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2307cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2308cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2309cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2310cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
2311cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                 arg7,arg8,arg9)                  \
2312cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2313cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2314cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+9];                        \
2315cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2316cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2317cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2318cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2319cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2320cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2321cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2322cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2323cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2324cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2325cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2326cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2327cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2328cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2329cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2330cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2331cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2332cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2333cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2334cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2335cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2336cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2337cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2338cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2339cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2340cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2341cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2342cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2343cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2344cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2345cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2346cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2347cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2348cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2349cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2350cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,128"     /* restore frame */                   \
2351cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2352cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2353cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2354cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2355cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2356cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2357cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2358cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2359cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                  arg7,arg8,arg9,arg10)           \
2360cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2361cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2362cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+10];                       \
2363cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2364cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2365cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2366cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2367cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2368cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2369cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2370cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2371cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2372cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2373cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2374cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2375cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2376cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2377cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2378cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2379cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2380cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2381cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-128\n\t"  /* expand stack frame */            \
2382cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2383cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2384cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2385cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2386cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2387cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2388cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2389cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2390cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2391cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2392cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2393cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2394cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2395cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2396cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2397cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2398cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2399cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2400cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2401cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2402cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,128"     /* restore frame */                   \
2403cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2404cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2405cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2406cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2407cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2408cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2409cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2410cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2411cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                  arg7,arg8,arg9,arg10,arg11)     \
2412cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2413cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2414cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+11];                       \
2415cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2416cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2417cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2418cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2419cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2420cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2421cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2422cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2423cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2424cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2425cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2426cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2427cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2428cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2429cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
2430cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2431cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2432cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2433cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2434cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2435cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg11 */                                              \
2436cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,88(11)\n\t"                                       \
2437cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,128(1)\n\t"                                       \
2438cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2439cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2440cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2441cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2442cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2443cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2444cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2445cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2446cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2447cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2448cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2449cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2450cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2451cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2452cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2453cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2454cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2455cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2456cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2457cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2458cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,144"     /* restore frame */                   \
2459cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2460cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2461cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2462cd63639e41d591b17cf8900e49e28048d39104c2sewardj      );                                                          \
2463cd63639e41d591b17cf8900e49e28048d39104c2sewardj      lval = (__typeof__(lval)) _res;                             \
2464cd63639e41d591b17cf8900e49e28048d39104c2sewardj   } while (0)
2465cd63639e41d591b17cf8900e49e28048d39104c2sewardj
2466cd63639e41d591b17cf8900e49e28048d39104c2sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
2467cd63639e41d591b17cf8900e49e28048d39104c2sewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
2468cd63639e41d591b17cf8900e49e28048d39104c2sewardj   do {                                                           \
2469cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile OrigFn        _orig = (orig);                      \
2470cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _argvec[3+12];                       \
2471cd63639e41d591b17cf8900e49e28048d39104c2sewardj      volatile unsigned long _res;                                \
2472cd63639e41d591b17cf8900e49e28048d39104c2sewardj      /* _argvec[0] holds current r2 across the call */           \
2473cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
2474cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
2475cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
2476cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
2477cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
2478cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
2479cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
2480cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
2481cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
2482cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
2483cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
2484cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
2485cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
2486cd63639e41d591b17cf8900e49e28048d39104c2sewardj      _argvec[2+12] = (unsigned long)arg12;                       \
2487cd63639e41d591b17cf8900e49e28048d39104c2sewardj      __asm__ volatile(                                           \
2488cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2489cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 2,-16(11)\n\t"  /* save tocptr */                   \
2490cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
2491cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,-144\n\t"  /* expand stack frame */            \
2492cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg12 */                                              \
2493cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,96(11)\n\t"                                       \
2494cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,136(1)\n\t"                                       \
2495cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg11 */                                              \
2496cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,88(11)\n\t"                                       \
2497cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,128(1)\n\t"                                       \
2498cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg10 */                                              \
2499cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,80(11)\n\t"                                       \
2500cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,120(1)\n\t"                                       \
2501cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* arg9 */                                               \
2502cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  3,72(11)\n\t"                                       \
2503cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "std 3,112(1)\n\t"                                       \
2504cd63639e41d591b17cf8900e49e28048d39104c2sewardj         /* args1-8 */                                            \
2505cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
2506cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
2507cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
2508cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
2509cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
2510cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
2511cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
2512cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
2513cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
2514cd63639e41d591b17cf8900e49e28048d39104c2sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2515cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr 11,%1\n\t"                                           \
2516cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "mr %0,3\n\t"                                            \
2517cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
2518cd63639e41d591b17cf8900e49e28048d39104c2sewardj         "addi 1,1,144"     /* restore frame */                   \
2519cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*out*/   "=r" (_res)                                  \
2520cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*in*/    "r" (&_argvec[2])                            \
2521cd63639e41d591b17cf8900e49e28048d39104c2sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
25229734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      );                                                          \
25239734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj      lval = (__typeof__(lval)) _res;                             \
25249734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj   } while (0)
25259734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
2526f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_linux */
2527f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
252859570ffbe31930ab4d678754daaeec0715117a3dsewardj/* ------------------------- arm-linux ------------------------- */
252959570ffbe31930ab4d678754daaeec0715117a3dsewardj
253059570ffbe31930ab4d678754daaeec0715117a3dsewardj#if defined(PLAT_arm_linux)
253159570ffbe31930ab4d678754daaeec0715117a3dsewardj
253259570ffbe31930ab4d678754daaeec0715117a3dsewardj/* These regs are trashed by the hidden call. */
253359570ffbe31930ab4d678754daaeec0715117a3dsewardj#define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
253459570ffbe31930ab4d678754daaeec0715117a3dsewardj
253559570ffbe31930ab4d678754daaeec0715117a3dsewardj/* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
253659570ffbe31930ab4d678754daaeec0715117a3dsewardj   long) == 4. */
253759570ffbe31930ab4d678754daaeec0715117a3dsewardj
253859570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_v(lval, orig)                                   \
253959570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
254059570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
254159570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[1];                          \
254259570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
254359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
254459570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
254559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
254659570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
254759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
254859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
254959570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
255059570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
255159570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
255259570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
255359570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
255459570ffbe31930ab4d678754daaeec0715117a3dsewardj
255559570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
255659570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
255759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
255859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[2];                          \
255959570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
256059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
256159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
256259570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
256359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
256459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
256559570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
256659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
256759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
256859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
256959570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory",  __CALLER_SAVED_REGS         \
257059570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
257159570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
257259570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
257359570ffbe31930ab4d678754daaeec0715117a3dsewardj
257459570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
257559570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
257659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
257759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[3];                          \
257859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
257959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
258059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
258159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
258259570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
258359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
258459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
258559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
258659570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
258759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
258859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
258959570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
259059570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
259159570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
259259570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
259359570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
259459570ffbe31930ab4d678754daaeec0715117a3dsewardj
259559570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
259659570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
259759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
259859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[4];                          \
259959570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
260059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
260159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
260259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
260359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
260459570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
260559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
260659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
260759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
260859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
260959570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
261059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0\n"                                           \
261159570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
261259570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
261359570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
261459570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
261559570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
261659570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
261759570ffbe31930ab4d678754daaeec0715117a3dsewardj
261859570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
261959570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
262059570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
262159570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[5];                          \
262259570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
262359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
262459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
262559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
262659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
262759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
262859570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
262959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
263059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
263159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
263259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
263359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
263459570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
263559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
263659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
263759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
263859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
263959570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
264059570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
264159570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
264259570ffbe31930ab4d678754daaeec0715117a3dsewardj
264359570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
264459570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
264559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
264659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[6];                          \
264759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
264859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
264959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
265059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
265159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
265259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
265359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
265459570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
265559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
265659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0} \n\t"                                         \
265759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
265859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
265959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
266059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
266159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
266259570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
266359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #4 \n\t"                                    \
266459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
266559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
266659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
266759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
266859570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
266959570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
267059570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
267159570ffbe31930ab4d678754daaeec0715117a3dsewardj
267259570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
267359570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
267459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
267559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[7];                          \
267659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
267759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
267859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
267959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
268059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
268159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
268259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
268359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
268459570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
268559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
268659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
268759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1} \n\t"                                     \
268859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
268959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
269059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
269159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
269259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
269359570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
269459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #8 \n\t"                                    \
269559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
269659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
269759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
269859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
269959570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
270059570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
270159570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
270259570ffbe31930ab4d678754daaeec0715117a3dsewardj
270359570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
270459570ffbe31930ab4d678754daaeec0715117a3dsewardj                                 arg7)                            \
270559570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
270659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
270759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[8];                          \
270859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
270959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
271059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
271159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
271259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
271359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
271459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
271559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
271659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
271759570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
271859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
271959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
272059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
272159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2} \n\t"                                 \
272259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
272359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
272459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
272559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
272659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
272759570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
272859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #12 \n\t"                                   \
272959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
273059570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
273159570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
273259570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
273359570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
273459570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
273559570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
273659570ffbe31930ab4d678754daaeec0715117a3dsewardj
273759570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
273859570ffbe31930ab4d678754daaeec0715117a3dsewardj                                 arg7,arg8)                       \
273959570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
274059570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
274159570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[9];                          \
274259570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
274359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
274459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
274559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
274659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
274759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
274859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
274959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
275059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
275159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
275259570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
275359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
275459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
275559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
275659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
275759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3} \n\t"                             \
275859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
275959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
276059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
276159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
276259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
276359570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
276459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #16 \n\t"                                   \
276559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
276659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
276759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
276859570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
276959570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
277059570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
277159570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
277259570ffbe31930ab4d678754daaeec0715117a3dsewardj
277359570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
277459570ffbe31930ab4d678754daaeec0715117a3dsewardj                                 arg7,arg8,arg9)                  \
277559570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
277659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
277759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[10];                         \
277859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
277959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
278059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
278159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
278259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
278359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
278459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
278559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
278659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
278759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
278859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
278959570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
279059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
279159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
279259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
279359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
279459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
279559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
279659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
279759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
279859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
279959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
280059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
280159570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
280259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #20 \n\t"                                   \
280359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
280459570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
280559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
280659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
280759570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
280859570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
280959570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
281059570ffbe31930ab4d678754daaeec0715117a3dsewardj
281159570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
281259570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg7,arg8,arg9,arg10)           \
281359570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
281459570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
281559570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[11];                         \
281659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
281759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
281859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
281959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
282059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
282159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
282259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
282359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
282459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
282559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
282659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
282759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[10] = (unsigned long)(arg10);                       \
282859570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
282959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #40] \n\t"                                 \
283059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0} \n\t"                                         \
283159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
283259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
283359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
283459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
283559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
283659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
283759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
283859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
283959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
284059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
284159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
284259570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
284359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #24 \n\t"                                   \
284459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
284559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
284659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
284759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
284859570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
284959570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
285059570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
285159570ffbe31930ab4d678754daaeec0715117a3dsewardj
285259570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
285359570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg6,arg7,arg8,arg9,arg10,      \
285459570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg11)                          \
285559570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
285659570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
285759570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[12];                         \
285859570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
285959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
286059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
286159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
286259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
286359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
286459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
286559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
286659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
286759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
286859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
286959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[10] = (unsigned long)(arg10);                       \
287059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[11] = (unsigned long)(arg11);                       \
287159570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
287259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #40] \n\t"                                 \
287359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #44] \n\t"                                 \
287459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1} \n\t"                                     \
287559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
287659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
287759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
287859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
287959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
288059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
288159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
288259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
288359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
288459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
288559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
288659570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
288759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #28 \n\t"                                   \
288859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
288959570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
289059570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
289159570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory",__CALLER_SAVED_REGS           \
289259570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
289359570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
289459570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
289559570ffbe31930ab4d678754daaeec0715117a3dsewardj
289659570ffbe31930ab4d678754daaeec0715117a3dsewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
289759570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg6,arg7,arg8,arg9,arg10,      \
289859570ffbe31930ab4d678754daaeec0715117a3dsewardj                                  arg11,arg12)                    \
289959570ffbe31930ab4d678754daaeec0715117a3dsewardj   do {                                                           \
290059570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile OrigFn        _orig = (orig);                      \
290159570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _argvec[13];                         \
290259570ffbe31930ab4d678754daaeec0715117a3dsewardj      volatile unsigned long _res;                                \
290359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[0] = (unsigned long)_orig.nraddr;                   \
290459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[1] = (unsigned long)(arg1);                         \
290559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[2] = (unsigned long)(arg2);                         \
290659570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[3] = (unsigned long)(arg3);                         \
290759570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[4] = (unsigned long)(arg4);                         \
290859570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[5] = (unsigned long)(arg5);                         \
290959570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[6] = (unsigned long)(arg6);                         \
291059570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[7] = (unsigned long)(arg7);                         \
291159570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[8] = (unsigned long)(arg8);                         \
291259570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[9] = (unsigned long)(arg9);                         \
291359570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[10] = (unsigned long)(arg10);                       \
291459570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[11] = (unsigned long)(arg11);                       \
291559570ffbe31930ab4d678754daaeec0715117a3dsewardj      _argvec[12] = (unsigned long)(arg12);                       \
291659570ffbe31930ab4d678754daaeec0715117a3dsewardj      __asm__ volatile(                                           \
291759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #40] \n\t"                                 \
291859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #44] \n\t"                                 \
291959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #48] \n\t"                                 \
292059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2} \n\t"                                 \
292159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #20] \n\t"                                 \
292259570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #24] \n\t"                                 \
292359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #28] \n\t"                                 \
292459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #32] \n\t"                                 \
292559570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1, #36] \n\t"                                 \
292659570ffbe31930ab4d678754daaeec0715117a3dsewardj         "push {r0, r1, r2, r3, r4} \n\t"                         \
292759570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r0, [%1, #4] \n\t"                                  \
292859570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r1, [%1, #8] \n\t"                                  \
292959570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r2, [%1, #12] \n\t"                                 \
293059570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r3, [%1, #16] \n\t"                                 \
293159570ffbe31930ab4d678754daaeec0715117a3dsewardj         "ldr r4, [%1] \n\t"  /* target->r4 */                    \
293259570ffbe31930ab4d678754daaeec0715117a3dsewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
293359570ffbe31930ab4d678754daaeec0715117a3dsewardj         "add sp, sp, #32 \n\t"                                   \
293459570ffbe31930ab4d678754daaeec0715117a3dsewardj         "mov %0, r0"                                             \
293559570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*out*/   "=r" (_res)                                  \
293659570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*in*/    "0" (&_argvec[0])                            \
293759570ffbe31930ab4d678754daaeec0715117a3dsewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
293859570ffbe31930ab4d678754daaeec0715117a3dsewardj      );                                                          \
293959570ffbe31930ab4d678754daaeec0715117a3dsewardj      lval = (__typeof__(lval)) _res;                             \
294059570ffbe31930ab4d678754daaeec0715117a3dsewardj   } while (0)
294159570ffbe31930ab4d678754daaeec0715117a3dsewardj
294259570ffbe31930ab4d678754daaeec0715117a3dsewardj#endif /* PLAT_arm_linux */
294359570ffbe31930ab4d678754daaeec0715117a3dsewardj
2944f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc32-aix5 ------------------------- */
2945f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2946f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc32_aix5)
2947f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2948f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
2949f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2950f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* These regs are trashed by the hidden call. */
2951f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define __CALLER_SAVED_REGS                                       \
2952f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "lr", "ctr", "xer",                                            \
2953f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
2954f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
2955f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "r11", "r12", "r13"
2956f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2957f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* Expand the stack frame, copying enough info that unwinding
2958f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   still works.  Trashes r3. */
2959f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2960f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
2961f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "addi 1,1,-" #_n_fr "\n\t"                               \
2962f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3," #_n_fr "(1)\n\t"                               \
2963f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  3,0(1)\n\t"
2964f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2965f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
2966f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "addi 1,1," #_n_fr "\n\t"
2967f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2968f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned
2969f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   long) == 4. */
2970f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2971f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_v(lval, orig)                                   \
2972f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2973f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
2974f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+0];                        \
2975f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
2976f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
2977f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1] = (unsigned long)_orig.r2;                       \
2978f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2] = (unsigned long)_orig.nraddr;                   \
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         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
2985f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
2986f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
2987f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
2988f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
2989f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
2990f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
2991f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
2992f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
2993f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
2994f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
2995f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
2996f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
2997f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
2998f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
2999f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3000f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+1];                        \
3001f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3002f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3003f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3004f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3005f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3006f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3007f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3008f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3009f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3010f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3011f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3012f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3013f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3014f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3015f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3016f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3017f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3018f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3019f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3020f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3021f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3022f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3023f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3024f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3025f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
3026f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3027f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3028f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+2];                        \
3029f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3030f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3031f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3032f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3033f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3034f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3035f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3036f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3037f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3038f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3039f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3040f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3041f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
3042f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3043f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3044f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3045f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3046f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3047f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3048f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3049f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3050f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3051f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3052f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3053f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3054f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3055f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
3056f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3057f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3058f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+3];                        \
3059f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3060f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3061f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3062f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3063f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3064f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3065f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3066f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3067f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3068f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3069f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3070f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3071f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3072f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
3073f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
3074f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3075f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3076f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3077f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3078f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3079f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3080f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3081f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3082f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3083f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3084f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3085f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3086f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3087f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
3088f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3089f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3090f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+4];                        \
3091f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3092f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3093f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3094f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3095f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3096f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3097f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3098f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3099f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3100f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3101f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3102f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3103f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3104f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3105f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
3106f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
3107f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
3108f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3109f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3110f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3111f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3112f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3113f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3114f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3115f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3116f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3117f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3118f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3119f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3120f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3121f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
3122f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3123f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3124f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+5];                        \
3125f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3126f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3127f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3128f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3129f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3130f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3131f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3132f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3133f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3134f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3135f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3136f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3137f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3138f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3139f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3140f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t" /* arg2->r4 */                       \
3141f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
3142f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
3143f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
3144f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3145f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3146f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3147f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3148f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3149f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3150f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3151f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3152f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3153f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3154f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3155f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3156f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3157f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
3158f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3159f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3160f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+6];                        \
3161f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3162f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3163f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3164f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3165f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3166f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3167f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3168f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3169f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3170f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3171f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3172f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3173f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3174f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3175f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3176f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3177f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
3178f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
3179f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
3180f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
3181f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
3182f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3183f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3184f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3185f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3186f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3187f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3188f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3189f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3190f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3191f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3192f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3193f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3194f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3195f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3196f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7)                            \
3197f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3198f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3199f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+7];                        \
3200f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3201f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3202f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3203f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3204f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3205f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3206f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3207f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3208f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3209f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3210f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3211f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3212f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3213f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3214f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3215f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3216f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3217f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
3218f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
3219f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
3220f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
3221f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
3222f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
3223f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3224f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3225f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3226f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3227f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3228f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3229f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3230f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3231f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3232f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3233f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3234f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3235f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3236f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3237f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7,arg8)                       \
3238f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3239f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3240f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+8];                        \
3241f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3242f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3243f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3244f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3245f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3246f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3247f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3248f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3249f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3250f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3251f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3252f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3253f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3254f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3255f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3256f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3257f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3258f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3259f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
3260f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
3261f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
3262f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
3263f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
3264f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
3265f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
3266f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3267f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3268f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3269f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3270f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3271f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3272f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3273f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3274f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3275f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3276f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3277f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3278f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3279f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3280f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7,arg8,arg9)                  \
3281f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3282f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3283f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+9];                        \
3284f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3285f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3286f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3287f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3288f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3289f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3290f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3291f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3292f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3293f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3294f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3295f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3296f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
3297f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3298f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3299f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3300f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3301f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3302f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
3303f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
3304f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,36(11)\n\t"                                       \
3305f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,56(1)\n\t"                                        \
3306f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
3307f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3308f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
3309f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
3310f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
3311f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
3312f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
3313f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
3314f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
3315f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3316f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3317f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3318f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3319f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3320f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(64)                                 \
3321f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3322f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3323f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3324f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3325f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3326f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3327f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3328f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3329f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3330f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                  arg7,arg8,arg9,arg10)           \
3331f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3332f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3333f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+10];                       \
3334f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3335f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3336f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3337f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3338f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3339f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3340f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3341f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3342f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3343f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3344f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3345f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3346f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
3347f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
3348f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3349f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3350f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3351f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3352f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3353f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
3354f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
3355f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,40(11)\n\t"                                       \
3356f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,60(1)\n\t"                                        \
3357f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
3358f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,36(11)\n\t"                                       \
3359f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,56(1)\n\t"                                        \
3360f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
3361f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3362f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
3363f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
3364f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
3365f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
3366f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
3367f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
3368f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
3369f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3370f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3371f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3372f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3373f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3374f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(64)                                 \
3375f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3376f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3377f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3378f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3379f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3380f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3381f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3382f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3383f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3384f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                  arg7,arg8,arg9,arg10,arg11)     \
3385f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3386f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3387f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+11];                       \
3388f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3389f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3390f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3391f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3392f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3393f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3394f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3395f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3396f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3397f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3398f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3399f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3400f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
3401f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
3402f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
3403f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3404f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3405f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3406f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3407f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3408f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
3409f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg11 */                                              \
3410f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,44(11)\n\t"                                       \
3411f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,64(1)\n\t"                                        \
3412f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
3413f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,40(11)\n\t"                                       \
3414f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,60(1)\n\t"                                        \
3415f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
3416f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,36(11)\n\t"                                       \
3417f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,56(1)\n\t"                                        \
3418f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
3419f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3420f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
3421f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
3422f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
3423f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
3424f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
3425f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
3426f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
3427f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3428f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3429f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3430f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3431f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3432f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(72)                                 \
3433f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3434f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3435f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3436f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3437f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3438f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3439f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3440f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3441f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3442f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
3443f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3444f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3445f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+12];                       \
3446f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3447f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3448f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3449f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3450f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3451f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3452f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3453f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3454f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3455f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3456f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3457f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3458f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
3459f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
3460f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
3461f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+12] = (unsigned long)arg12;                       \
3462f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3463f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3464f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3465f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw  2,-8(11)\n\t"  /* save tocptr */                   \
3466f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
3467f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
3468f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg12 */                                              \
3469f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,48(11)\n\t"                                       \
3470f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,68(1)\n\t"                                        \
3471f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg11 */                                              \
3472f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,44(11)\n\t"                                       \
3473f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,64(1)\n\t"                                        \
3474f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
3475f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,40(11)\n\t"                                       \
3476f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,60(1)\n\t"                                        \
3477f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
3478f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 3,36(11)\n\t"                                       \
3479f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "stw 3,56(1)\n\t"                                        \
3480f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
3481f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
3482f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
3483f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
3484f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
3485f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
3486f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
3487f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
3488f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
3489f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
3490f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3491f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3492f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3493f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
3494f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(72)                                 \
3495f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3496f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3497f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3498f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3499f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3500f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3501f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3502f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3503f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc32_aix5 */
3504f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3505f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ------------------------ ppc64-aix5 ------------------------- */
3506f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3507f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#if defined(PLAT_ppc64_aix5)
3508f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3509f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
3510f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3511f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* These regs are trashed by the hidden call. */
3512f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define __CALLER_SAVED_REGS                                       \
3513f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "lr", "ctr", "xer",                                            \
3514f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
3515f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
3516f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   "r11", "r12", "r13"
3517f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3518f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* Expand the stack frame, copying enough info that unwinding
3519f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   still works.  Trashes r3. */
3520f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3521f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
3522f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "addi 1,1,-" #_n_fr "\n\t"                               \
3523f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3," #_n_fr "(1)\n\t"                               \
3524f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  3,0(1)\n\t"
3525f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3526f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define VG_CONTRACT_FRAME_BY(_n_fr)                               \
3527f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "addi 1,1," #_n_fr "\n\t"
3528f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3529f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj/* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned
3530f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   long) == 8. */
3531f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3532f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_v(lval, orig)                                   \
3533f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3534f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3535f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+0];                        \
3536f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3537f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3538f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1] = (unsigned long)_orig.r2;                       \
3539f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2] = (unsigned long)_orig.nraddr;                   \
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         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3546f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3547f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3548f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3549f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
3550f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3551f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3552f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3553f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3554f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3555f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3556f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3557f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3558f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_W(lval, orig, arg1)                             \
3559f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3560f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3561f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+1];                        \
3562f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3563f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3564f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3565f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3566f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3567f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3568f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3569f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3570f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3571f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3572f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3573f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3574f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3575f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3576f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3577f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld 2,-16(11)\n\t" /* restore tocptr */                  \
3578f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3579f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3580f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3581f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3582f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3583f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3584f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3585f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3586f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
3587f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3588f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3589f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+2];                        \
3590f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3591f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3592f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3593f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3594f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3595f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3596f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3597f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3598f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3599f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3600f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3601f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3602f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3603f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3604f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3605f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3606f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3607f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3608f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3609f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3610f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3611f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3612f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3613f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3614f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3615f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3616f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
3617f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3618f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3619f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+3];                        \
3620f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3621f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3622f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3623f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3624f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3625f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3626f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3627f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3628f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3629f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3630f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3631f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3632f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3633f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3634f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3635f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3636f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3637f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3638f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3639f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3640f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3641f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3642f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3643f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3644f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3645f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3646f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3647f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3648f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
3649f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3650f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3651f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+4];                        \
3652f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3653f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3654f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3655f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3656f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3657f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3658f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3659f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3660f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3661f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3662f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3663f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3664f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3665f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3666f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3667f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3668f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3669f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3670f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3671f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3672f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3673f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3674f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3675f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3676f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3677f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3678f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3679f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3680f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3681f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3682f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
3683f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3684f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3685f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+5];                        \
3686f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3687f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3688f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3689f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3690f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3691f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3692f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3693f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3694f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3695f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3696f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3697f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3698f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3699f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3700f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3701f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3702f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3703f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3704f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3705f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3706f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3707f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3708f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3709f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3710f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3711f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3712f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3713f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3714f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3715f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3716f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3717f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3718f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
3719f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3720f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3721f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+6];                        \
3722f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3723f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3724f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3725f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3726f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3727f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3728f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3729f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3730f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3731f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3732f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3733f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3734f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3735f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3736f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3737f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3738f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3739f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3740f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3741f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3742f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3743f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3744f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3745f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3746f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3747f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3748f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3749f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3750f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3751f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3752f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3753f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3754f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3755f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3756f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3757f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7)                            \
3758f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3759f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3760f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+7];                        \
3761f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3762f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3763f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3764f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3765f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3766f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3767f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3768f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3769f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3770f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3771f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3772f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3773f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3774f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3775f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3776f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3777f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3778f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3779f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3780f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3781f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3782f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3783f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3784f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3785f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3786f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3787f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3788f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3789f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3790f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3791f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3792f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3793f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3794f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3795f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3796f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3797f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3798f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7,arg8)                       \
3799f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3800f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3801f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+8];                        \
3802f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3803f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3804f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3805f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3806f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3807f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3808f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3809f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3810f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3811f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3812f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3813f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3814f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3815f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3816f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3817f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3818f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3819f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3820f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3821f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3822f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3823f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3824f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3825f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3826f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3827f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3828f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3829f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3830f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3831f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3832f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3833f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3834f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3835f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3836f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3837f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3838f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3839f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3840f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
3841f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                 arg7,arg8,arg9)                  \
3842f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3843f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3844f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+9];                        \
3845f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3846f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3847f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3848f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3849f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3850f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3851f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3852f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3853f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3854f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3855f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3856f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3857f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
3858f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3859f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3860f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3861f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3862f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3863f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
3864f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
3865f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,72(11)\n\t"                                       \
3866f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,112(1)\n\t"                                       \
3867f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
3868f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3869f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3870f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3871f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3872f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3873f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3874f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3875f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3876f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3877f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3878f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3879f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3880f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3881f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(128)                                \
3882f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3883f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3884f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3885f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3886f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3887f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3888f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3889f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3890f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3891f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                  arg7,arg8,arg9,arg10)           \
3892f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3893f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3894f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+10];                       \
3895f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3896f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3897f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3898f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3899f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3900f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3901f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3902f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3903f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3904f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3905f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3906f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3907f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
3908f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
3909f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3910f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3911f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3912f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3913f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3914f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
3915f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
3916f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,80(11)\n\t"                                       \
3917f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,120(1)\n\t"                                       \
3918f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
3919f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,72(11)\n\t"                                       \
3920f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,112(1)\n\t"                                       \
3921f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
3922f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3923f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3924f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3925f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3926f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3927f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3928f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3929f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3930f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3931f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3932f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3933f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3934f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3935f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(128)                                \
3936f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3937f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3938f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3939f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3940f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3941f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
3942f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
3943f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
3944f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
3945f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                  arg7,arg8,arg9,arg10,arg11)     \
3946f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
3947f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
3948f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+11];                       \
3949f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
3950f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
3951f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
3952f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
3953f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
3954f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
3955f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
3956f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
3957f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
3958f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
3959f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
3960f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
3961f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
3962f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
3963f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
3964f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
3965f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3966f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
3967f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
3968f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
3969f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
3970f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg11 */                                              \
3971f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,88(11)\n\t"                                       \
3972f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,128(1)\n\t"                                       \
3973f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
3974f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,80(11)\n\t"                                       \
3975f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,120(1)\n\t"                                       \
3976f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
3977f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,72(11)\n\t"                                       \
3978f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,112(1)\n\t"                                       \
3979f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
3980f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
3981f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
3982f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
3983f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
3984f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
3985f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
3986f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
3987f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
3988f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
3989f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
3990f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
3991f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
3992f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
3993f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(144)                                \
3994f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
3995f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
3996f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
3997f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
3998f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
3999f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
4000f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
4001f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
4002f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
4003f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj                                arg7,arg8,arg9,arg10,arg11,arg12) \
4004f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   do {                                                           \
4005f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile OrigFn        _orig = (orig);                      \
4006f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _argvec[3+12];                       \
4007f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      volatile unsigned long _res;                                \
4008f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      /* _argvec[0] holds current r2 across the call */           \
4009f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[1]   = (unsigned long)_orig.r2;                     \
4010f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2]   = (unsigned long)_orig.nraddr;                 \
4011f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+1] = (unsigned long)arg1;                         \
4012f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+2] = (unsigned long)arg2;                         \
4013f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+3] = (unsigned long)arg3;                         \
4014f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+4] = (unsigned long)arg4;                         \
4015f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+5] = (unsigned long)arg5;                         \
4016f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+6] = (unsigned long)arg6;                         \
4017f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+7] = (unsigned long)arg7;                         \
4018f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+8] = (unsigned long)arg8;                         \
4019f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+9] = (unsigned long)arg9;                         \
4020f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+10] = (unsigned long)arg10;                       \
4021f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+11] = (unsigned long)arg11;                       \
4022f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      _argvec[2+12] = (unsigned long)arg12;                       \
4023f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      __asm__ volatile(                                           \
4024f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
4025f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
4026f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std  2,-16(11)\n\t" /* save tocptr */                   \
4027f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
4028f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
4029f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg12 */                                              \
4030f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,96(11)\n\t"                                       \
4031f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,136(1)\n\t"                                       \
4032f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg11 */                                              \
4033f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,88(11)\n\t"                                       \
4034f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,128(1)\n\t"                                       \
4035f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg10 */                                              \
4036f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,80(11)\n\t"                                       \
4037f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,120(1)\n\t"                                       \
4038f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* arg9 */                                               \
4039f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  3,72(11)\n\t"                                       \
4040f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "std 3,112(1)\n\t"                                       \
4041f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         /* args1-8 */                                            \
4042f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
4043f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
4044f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
4045f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
4046f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
4047f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
4048f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
4049f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
4050f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  11, 0(11)\n\t"  /* target->r11 */                   \
4051f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
4052f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr 11,%1\n\t"                                           \
4053f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "mr %0,3\n\t"                                            \
4054f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         "ld  2,-16(11)\n\t" /* restore tocptr */                 \
4055f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(144)                                \
4056f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         VG_CONTRACT_FRAME_BY(512)                                \
4057f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*out*/   "=r" (_res)                                  \
4058f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*in*/    "r" (&_argvec[2])                            \
4059f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj         : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
4060f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      );                                                          \
4061f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      lval = (__typeof__(lval)) _res;                             \
4062f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj   } while (0)
4063f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
4064f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#endif /* PLAT_ppc64_aix5 */
40659734b20023ddaaf95a8d1f3849224ab27fe058bfsewardj
40660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
40670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ------------------------------------------------------------------ */
40680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
40690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/*                                                                    */
407030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn/* ------------------------------------------------------------------ */
407130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
40722e93c50dc50235189661b70e3f27a4098d5cccccsewardj/* Some request codes.  There are many more of these, but most are not
40732e93c50dc50235189661b70e3f27a4098d5cccccsewardj   exposed to end-user view.  These are the public ones, all of the
4074e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   form 0x1000 + small_number.
4075d799418996812817596beaa8b59563e3f3cb2ddanjn
40760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   Core ones are in the range 0x00000000--0x0000ffff.  The non-public
40770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ones start at 0x2000.
40782e93c50dc50235189661b70e3f27a4098d5cccccsewardj*/
40792e93c50dc50235189661b70e3f27a4098d5cccccsewardj
40800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These macros are used by tools -- they must be public, but don't
40810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   embed them into other programs. */
4082fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn#define VG_USERREQ_TOOL_BASE(a,b) \
40834c791211835f0e90cbde578187c06e563de3b023njn   ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
4084fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn#define VG_IS_TOOL_USERREQ(a, b, v) \
4085fc26ff9ed636a3dd79ee3d90e5e521bc7749f105njn   (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
408634042515c1715b3e0c5c0a5e0bd033e9d4858f01sewardj
40875ce4b150ce5d32c9af07a24717081ea34568388asewardj/* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
40885ce4b150ce5d32c9af07a24717081ea34568388asewardj   This enum comprises an ABI exported by Valgrind to programs
40895ce4b150ce5d32c9af07a24717081ea34568388asewardj   which use client requests.  DO NOT CHANGE THE ORDER OF THESE
40905ce4b150ce5d32c9af07a24717081ea34568388asewardj   ENTRIES, NOR DELETE ANY -- add new ones at the end. */
4091e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjntypedef
40924c791211835f0e90cbde578187c06e563de3b023njn   enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
40934c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
40943e88418f808bf2840646504481d6a5be1df16541njn
40950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* These allow any function to be called from the simulated
40960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             CPU but run on the real CPU.  Nb: the first arg passed to
40970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             the function is always the ThreadId of the running
40980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             thread!  So CLIENT_CALL0 actually requires a 1 arg
4099d4795be03ad94334c7517d93d3f5b35a97c7bba0njn             function, etc. */
41004c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL0 = 0x1101,
41014c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL1 = 0x1102,
41024c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL2 = 0x1103,
41034c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__CLIENT_CALL3 = 0x1104,
41043e88418f808bf2840646504481d6a5be1df16541njn
41050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* Can be useful in regression testing suites -- eg. can
41060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             send Valgrind's output to /dev/null and still count
41070ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             errors. */
41084c791211835f0e90cbde578187c06e563de3b023njn          VG_USERREQ__COUNT_ERRORS = 0x1201,
410947363aba8fa03b094195bca99fc232ce5f85605dnjn
41100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj          /* These are useful and can be interpreted by any tool that
41110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj             tracks malloc() et al, by using vg_replace_malloc.c. */
4112d799418996812817596beaa8b59563e3f3cb2ddanjn          VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
4113d799418996812817596beaa8b59563e3f3cb2ddanjn          VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
4114bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          /* Memory pool support. */
4115bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
4116bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
4117bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
4118bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh          VG_USERREQ__MEMPOOL_FREE     = 0x1306,
41192c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj          VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
4120c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
4121c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
4122c740d7660ad140b79e561e0d578ab8435a5a5289sewardj          VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
4123d799418996812817596beaa8b59563e3f3cb2ddanjn
412439de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge          /* Allow printfs to valgrind log. */
412530d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn          VG_USERREQ__PRINTF           = 0x1401,
41260140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
41270140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
41280140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          /* Stack support. */
41290140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__STACK_REGISTER   = 0x1501,
41300140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh          VG_USERREQ__STACK_DEREGISTER = 0x1502,
4131c8259b85b701d25d72aabe9dc0a8154517f96913sewardj          VG_USERREQ__STACK_CHANGE     = 0x1503,
4132c8259b85b701d25d72aabe9dc0a8154517f96913sewardj
4133c8259b85b701d25d72aabe9dc0a8154517f96913sewardj          /* Wine support */
4134c8259b85b701d25d72aabe9dc0a8154517f96913sewardj          VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601
4135e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   } Vg_ClientRequest;
41362e93c50dc50235189661b70e3f27a4098d5cccccsewardj
41370ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#if !defined(__GNUC__)
41380ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  define __extension__ /* */
4139c9b365507e9bd5d500476e3e83f4d30f9c68a351mueller#endif
41402e93c50dc50235189661b70e3f27a4098d5cccccsewardj
41410ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* Returns the number of Valgrinds this code is running under.  That
41420ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   is, 0 if running natively, 1 if running under Valgrind, 2 if
41430ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   running under Valgrind which is running under another Valgrind,
41440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   etc. */
41450ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define RUNNING_ON_VALGRIND  __extension__                        \
41460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned int _qzz_res;                                       \
41470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */,          \
41480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__RUNNING_ON_VALGRIND,   \
41499af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               0, 0, 0, 0, 0);                    \
41500ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qzz_res;                                                     \
4151de4a1d01951937632098a6cda45859afa587a06fsewardj   })
4152de4a1d01951937632098a6cda45859afa587a06fsewardj
4153de4a1d01951937632098a6cda45859afa587a06fsewardj
415418d7513cc08bf982711c8a22b70d56af6aa87b33sewardj/* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
415518d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   _qzz_len - 1].  Useful if you are debugging a JITter or some such,
415618d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   since it provides a way to make sure valgrind will retranslate the
415718d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   invalidated area.  Returns no value. */
41580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)         \
41590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
41600ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
41610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__DISCARD_TRANSLATIONS,  \
41629af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               _qzz_addr, _qzz_len, 0, 0, 0);     \
416318d7513cc08bf982711c8a22b70d56af6aa87b33sewardj   }
416418d7513cc08bf982711c8a22b70d56af6aa87b33sewardj
416526aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
41660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj/* These requests are for getting Valgrind itself to print something.
4167d55f0d924062c7b5b3453242a6f9611bd5ce7458njn   Possibly with a backtrace.  This is a really ugly hack.  The return value
4168d55f0d924062c7b5b3453242a6f9611bd5ce7458njn   is the number of characters printed, excluding the "**<pid>** " part at the
4169d55f0d924062c7b5b3453242a6f9611bd5ce7458njn   start and the backtrace (if present). */
41700ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
41710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#if defined(NVALGRIND)
41720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
41730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  define VALGRIND_PRINTF(...)
41740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#  define VALGRIND_PRINTF_BACKTRACE(...)
417526aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn
417626aba4d3ef6cebc34879e82d88bcbe3c3b3b9f9enjn#else /* NVALGRIND */
417739de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
41787eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj/* Modern GCC will optimize the static routine out if unused,
41797eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   and unused attribute will shut down warnings about it.  */
41807eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int VALGRIND_PRINTF(const char *format, ...)
41817eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   __attribute__((format(__printf__, 1, 2), __unused__));
41827eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int
4183a09a1b5d4e02b7451345dac00f2d321d1b4b2ccefitzhardingeVALGRIND_PRINTF(const char *format, ...)
418439de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge{
4185c616819253fcf211745060b2be26076174b1df19njn   unsigned long _qzz_res;
418605b07158841423adc250f04e034bf11e6f892b23sewardj   union {
418705b07158841423adc250f04e034bf11e6f892b23sewardj      va_list vargs;
418805b07158841423adc250f04e034bf11e6f892b23sewardj      unsigned long ul;
418905b07158841423adc250f04e034bf11e6f892b23sewardj   } args;
419005b07158841423adc250f04e034bf11e6f892b23sewardj   va_start(args.vargs, format);
41910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
419205b07158841423adc250f04e034bf11e6f892b23sewardj                              (unsigned long)format,
419305b07158841423adc250f04e034bf11e6f892b23sewardj                              (unsigned long)(args.ul),
41949af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              0, 0, 0);
419505b07158841423adc250f04e034bf11e6f892b23sewardj   va_end(args.vargs);
4196c616819253fcf211745060b2be26076174b1df19njn   return (int)_qzz_res;
419739de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge}
419839de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
41997eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
42007eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardj   __attribute__((format(__printf__, 1, 2), __unused__));
42017eca0cc8e2bc1c260be1b596c54e4b55d1e2517asewardjstatic int
4202a09a1b5d4e02b7451345dac00f2d321d1b4b2ccefitzhardingeVALGRIND_PRINTF_BACKTRACE(const char *format, ...)
420339de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge{
4204c616819253fcf211745060b2be26076174b1df19njn   unsigned long _qzz_res;
420505b07158841423adc250f04e034bf11e6f892b23sewardj   union {
420605b07158841423adc250f04e034bf11e6f892b23sewardj      va_list vargs;
420705b07158841423adc250f04e034bf11e6f892b23sewardj      unsigned long ul;
420805b07158841423adc250f04e034bf11e6f892b23sewardj   } args;
420905b07158841423adc250f04e034bf11e6f892b23sewardj   va_start(args.vargs, format);
42100ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
421105b07158841423adc250f04e034bf11e6f892b23sewardj                              (unsigned long)format,
421205b07158841423adc250f04e034bf11e6f892b23sewardj                              (unsigned long)(args.ul),
42139af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                              0, 0, 0);
421405b07158841423adc250f04e034bf11e6f892b23sewardj   va_end(args.vargs);
4215c616819253fcf211745060b2be26076174b1df19njn   return (int)_qzz_res;
421639de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge}
421739de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge
421839de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge#endif /* NVALGRIND */
421918d7513cc08bf982711c8a22b70d56af6aa87b33sewardj
42200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
42213e88418f808bf2840646504481d6a5be1df16541njn/* These requests allow control to move from the simulated CPU to the
42221319b49115bd0763628273b8a3fe08ac30712e31njn   real CPU, calling an arbitary function.
42231319b49115bd0763628273b8a3fe08ac30712e31njn
42241319b49115bd0763628273b8a3fe08ac30712e31njn   Note that the current ThreadId is inserted as the first argument.
42251319b49115bd0763628273b8a3fe08ac30712e31njn   So this call:
42261319b49115bd0763628273b8a3fe08ac30712e31njn
42271319b49115bd0763628273b8a3fe08ac30712e31njn     VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
42281319b49115bd0763628273b8a3fe08ac30712e31njn
42291319b49115bd0763628273b8a3fe08ac30712e31njn   requires f to have this signature:
42301319b49115bd0763628273b8a3fe08ac30712e31njn
42311319b49115bd0763628273b8a3fe08ac30712e31njn     Word f(Word tid, Word arg1, Word arg2)
42321319b49115bd0763628273b8a3fe08ac30712e31njn
42331319b49115bd0763628273b8a3fe08ac30712e31njn   where "Word" is a word-sized type.
423445fb4d304f59e4e4cca917d372278eeb75be2c33njn
423545fb4d304f59e4e4cca917d372278eeb75be2c33njn   Note that these client requests are not entirely reliable.  For example,
423645fb4d304f59e4e4cca917d372278eeb75be2c33njn   if you call a function with them that subsequently calls printf(),
423745fb4d304f59e4e4cca917d372278eeb75be2c33njn   there's a high chance Valgrind will crash.  Generally, your prospects of
423845fb4d304f59e4e4cca917d372278eeb75be2c33njn   these working are made higher if the called function does not refer to
423945fb4d304f59e4e4cca917d372278eeb75be2c33njn   any global variables, and does not refer to any libc or other functions
424045fb4d304f59e4e4cca917d372278eeb75be2c33njn   (printf et al).  Any kind of entanglement with libc or dynamic linking is
424145fb4d304f59e4e4cca917d372278eeb75be2c33njn   likely to have a bad outcome, for tricky reasons which we've grappled
424245fb4d304f59e4e4cca917d372278eeb75be2c33njn   with a lot in the past.
42431319b49115bd0763628273b8a3fe08ac30712e31njn*/
42440ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
4245315dc8d060cada7e7eab1f38a513ed8659785609sewardj   __extension__                                                  \
42460ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned long _qyy_res;                                      \
42470ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
42480ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__CLIENT_CALL0,          \
42490ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               _qyy_fn,                           \
42509af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               0, 0, 0, 0);                       \
42510ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qyy_res;                                                     \
42523e88418f808bf2840646504481d6a5be1df16541njn   })
42533e88418f808bf2840646504481d6a5be1df16541njn
42540ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)               \
4255315dc8d060cada7e7eab1f38a513ed8659785609sewardj   __extension__                                                  \
42560ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned long _qyy_res;                                      \
42570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
42580ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__CLIENT_CALL1,          \
42590ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               _qyy_fn,                           \
42609af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               _qyy_arg1, 0, 0, 0);               \
42610ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qyy_res;                                                     \
42623e88418f808bf2840646504481d6a5be1df16541njn   })
42633e88418f808bf2840646504481d6a5be1df16541njn
42640ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)    \
4265315dc8d060cada7e7eab1f38a513ed8659785609sewardj   __extension__                                                  \
42660ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned long _qyy_res;                                      \
42670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
42680ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__CLIENT_CALL2,          \
42690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               _qyy_fn,                           \
42709af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               _qyy_arg1, _qyy_arg2, 0, 0);       \
42710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qyy_res;                                                     \
42723e88418f808bf2840646504481d6a5be1df16541njn   })
42733e88418f808bf2840646504481d6a5be1df16541njn
42740ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
4275315dc8d060cada7e7eab1f38a513ed8659785609sewardj   __extension__                                                  \
42760ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned long _qyy_res;                                      \
42770ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
42780ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__CLIENT_CALL3,          \
42790ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               _qyy_fn,                           \
42809af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               _qyy_arg1, _qyy_arg2,              \
42819af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               _qyy_arg3, 0);                     \
42820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qyy_res;                                                     \
42833e88418f808bf2840646504481d6a5be1df16541njn   })
42843e88418f808bf2840646504481d6a5be1df16541njn
42853e88418f808bf2840646504481d6a5be1df16541njn
42867cc9c239f785f2903b597cdb34418bed42d25331nethercote/* Counts the number of errors that have been recorded by a tool.  Nb:
42877cc9c239f785f2903b597cdb34418bed42d25331nethercote   the tool must record the errors with VG_(maybe_record_error)() or
428847363aba8fa03b094195bca99fc232ce5f85605dnjn   VG_(unique_error)() for them to be counted. */
42890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_COUNT_ERRORS                                     \
4290315dc8d060cada7e7eab1f38a513ed8659785609sewardj   __extension__                                                  \
42910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned int _qyy_res;                                       \
42920ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
42930ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__COUNT_ERRORS,          \
42949af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               0, 0, 0, 0, 0);                    \
42950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qyy_res;                                                     \
429647363aba8fa03b094195bca99fc232ce5f85605dnjn   })
429747363aba8fa03b094195bca99fc232ce5f85605dnjn
42983ac96953bf8c912a2aaa2870652dda8b9b75337bnjn/* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
42993ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   when heap blocks are allocated in order to give accurate results.  This
43003ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   happens automatically for the standard allocator functions such as
43013ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
43023ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   delete[], etc.
43033ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43043ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   But if your program uses a custom allocator, this doesn't automatically
43053ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   happen, and Valgrind will not do as well.  For example, if you allocate
43063ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   superblocks with mmap() and then allocates chunks of the superblocks, all
43073ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Valgrind's observations will be at the mmap() level and it won't know that
43083ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   the chunks should be considered separate entities.  In Memcheck's case,
43093ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   that means you probably won't get heap block overrun detection (because
43103ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   there won't be redzones marked as unaddressable) and you definitely won't
43113ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   get any leak detection.
43123ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43133ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   The following client requests allow a custom allocator to be annotated so
43143ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   that it can be handled accurately by Valgrind.
43153ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43163ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
43173ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   by a malloc()-like function.  For Memcheck (an illustrative case), this
43183ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   does two things:
43193ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43203ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It records that the block has been allocated.  This means any addresses
43213ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     within the block mentioned in error messages will be
43223ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     identified as belonging to the block.  It also means that if the block
43233ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     isn't freed it will be detected by the leak checker.
43243ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43253ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It marks the block as being addressable and undefined (if 'is_zeroed' is
43263ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     not set), or addressable and defined (if 'is_zeroed' is set).  This
43273ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     controls how accesses to the block by the program are handled.
43283ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43293ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   'addr' is the start of the usable block (ie. after any
43303ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
43313ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   can apply redzones -- these are blocks of padding at the start and end of
43323ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   each block.  Adding redzones is recommended as it makes it much more likely
43333ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
43343ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   zeroed (or filled with another predictable value), as is the case for
43353ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   calloc().
43363ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43373ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
43383ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   heap block -- that will be used by the client program -- is allocated.
43393ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   It's best to put it at the outermost level of the allocator if possible;
43403ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   for example, if you have a function my_alloc() which calls
43413ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   internal_alloc(), and the client request is put inside internal_alloc(),
43423ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   stack traces relating to the heap block will contain entries for both
43433ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   my_alloc() and internal_alloc(), which is probably not what you want.
43443ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
4345b965efb4990bdedc3215ffcca8ea566d25874d26njn   For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
4346b965efb4990bdedc3215ffcca8ea566d25874d26njn   custom blocks from within a heap block, B, that has been allocated with
4347b965efb4990bdedc3215ffcca8ea566d25874d26njn   malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
4348b965efb4990bdedc3215ffcca8ea566d25874d26njn   -- the custom blocks will take precedence.
4349b965efb4990bdedc3215ffcca8ea566d25874d26njn
43503ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK.  For
43513ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Memcheck, it does two things:
43523ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43533ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It records that the block has been deallocated.  This assumes that the
43543ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     block was annotated as having been allocated via
43553ac96953bf8c912a2aaa2870652dda8b9b75337bnjn     VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
43563ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43573ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   - It marks the block as being unaddressable.
43583ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43593ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
43603ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   heap block is deallocated.
43613ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43623ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   In many cases, these two client requests will not be enough to get your
43633ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   allocator working well with Memcheck.  More specifically, if your allocator
43643ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
43653ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   will be necessary to mark the memory as addressable just before the zeroing
43663ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   occurs, otherwise you'll get a lot of invalid write errors.  For example,
43673ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   you'll need to do this if your allocator recycles freed blocks, but it
43683ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
43693ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Alternatively, if your allocator reuses freed blocks for allocator-internal
43703ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
43713ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43723ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Really, what's happening is a blurring of the lines between the client
43733ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
43743ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   memory should be considered unaddressable to the client program, but the
43753ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   allocator knows more than the rest of the client program and so may be able
43763ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   to safely access it.  Extra client requests are necessary for Valgrind to
43773ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   understand the distinction between the allocator and the rest of the
43783ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   program.
43793ac96953bf8c912a2aaa2870652dda8b9b75337bnjn
43803ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   Note: there is currently no VALGRIND_REALLOCLIKE_BLOCK client request;  it
43813ac96953bf8c912a2aaa2870652dda8b9b75337bnjn   has to be emulated with MALLOCLIKE/FREELIKE and memory copying.
4382d799418996812817596beaa8b59563e3f3cb2ddanjn
438332f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn   Ignored if addr == 0.
43843ac96953bf8c912a2aaa2870652dda8b9b75337bnjn*/
43850ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)    \
43860ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
43870ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
43880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__MALLOCLIKE_BLOCK,      \
43899af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               addr, sizeB, rzB, is_zeroed, 0);   \
4390d799418996812817596beaa8b59563e3f3cb2ddanjn   }
4391d799418996812817596beaa8b59563e3f3cb2ddanjn
439232f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn/* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
439332f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn   Ignored if addr == 0.
439432f8d8c0dcb3a7c3ff14aa9892ea2410eba3207cnjn*/
43950ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_FREELIKE_BLOCK(addr, rzB)                        \
43960ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
43970ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
43980ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__FREELIKE_BLOCK,        \
43999af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               addr, rzB, 0, 0, 0);               \
4400d799418996812817596beaa8b59563e3f3cb2ddanjn   }
4401d799418996812817596beaa8b59563e3f3cb2ddanjn
4402bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Create a memory pool. */
44030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
44040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
44050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
44060ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__CREATE_MEMPOOL,        \
44079af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               pool, rzB, is_zeroed, 0, 0);       \
4408bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh   }
4409bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
4410bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Destroy a memory pool. */
44110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_DESTROY_MEMPOOL(pool)                            \
44120ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
44130ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
44140ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__DESTROY_MEMPOOL,       \
44159af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               pool, 0, 0, 0, 0);                 \
4416bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh   }
4417bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
4418bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Associate a piece of memory with a memory pool. */
44190ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
44200ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
44210ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
44220ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__MEMPOOL_ALLOC,         \
44239af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               pool, addr, size, 0, 0);           \
4424bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh   }
4425bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
4426bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh/* Disassociate a piece of memory from a memory pool. */
44270ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
44280ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
44290ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
44300ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__MEMPOOL_FREE,          \
44319af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               pool, addr, 0, 0, 0);              \
4432bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh   }
4433bc0bb8302c37c0c24aafbcfde0cc96d2c2805c94rjwalsh
44342c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj/* Disassociate any pieces outside a particular range. */
44352c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj#define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
44362c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj   {unsigned int _qzz_res;                                        \
44372c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
44382c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj                               VG_USERREQ__MEMPOOL_TRIM,          \
44392c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj                               pool, addr, size, 0, 0);           \
44402c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj   }
44412c1c9dfe806d62d43768b23c29799dc6a100cb09sewardj
4442c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Resize and/or move a piece associated with a memory pool. */
4443c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
4444c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   {unsigned int _qzz_res;                                        \
4445c740d7660ad140b79e561e0d578ab8435a5a5289sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
4446c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               VG_USERREQ__MOVE_MEMPOOL,          \
4447c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               poolA, poolB, 0, 0, 0);            \
4448c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   }
4449c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
4450c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Resize and/or move a piece associated with a memory pool. */
4451c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
4452c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   {unsigned int _qzz_res;                                        \
4453c740d7660ad140b79e561e0d578ab8435a5a5289sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
4454c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               VG_USERREQ__MEMPOOL_CHANGE,        \
4455c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               pool, addrA, addrB, size, 0);      \
4456c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   }
4457c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
4458c740d7660ad140b79e561e0d578ab8435a5a5289sewardj/* Return 1 if a mempool exists, else 0. */
4459c740d7660ad140b79e561e0d578ab8435a5a5289sewardj#define VALGRIND_MEMPOOL_EXISTS(pool)                             \
44604486297d932a229cb383ca0671d57657677dd56enjn   __extension__                                                  \
4461c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   ({unsigned int _qzz_res;                                       \
4462c740d7660ad140b79e561e0d578ab8435a5a5289sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
4463c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               VG_USERREQ__MEMPOOL_EXISTS,        \
4464c740d7660ad140b79e561e0d578ab8435a5a5289sewardj                               pool, 0, 0, 0, 0);                 \
4465c740d7660ad140b79e561e0d578ab8435a5a5289sewardj    _qzz_res;                                                     \
4466c740d7660ad140b79e561e0d578ab8435a5a5289sewardj   })
4467c740d7660ad140b79e561e0d578ab8435a5a5289sewardj
44680140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Mark a piece of memory as being a stack. Returns a stack id. */
44690ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_REGISTER(start, end)                       \
44704486297d932a229cb383ca0671d57657677dd56enjn   __extension__                                                  \
44710ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   ({unsigned int _qzz_res;                                       \
44720ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
44730ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__STACK_REGISTER,        \
44749af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               start, end, 0, 0, 0);              \
44750ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    _qzz_res;                                                     \
44760140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh   })
44770140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
44780140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Unmark the piece of memory associated with a stack id as being a
44790140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh   stack. */
44800ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_DEREGISTER(id)                             \
44810ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
44820ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
44830ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__STACK_DEREGISTER,      \
44849af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               id, 0, 0, 0, 0);                   \
44850140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh   }
44860140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
44870140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh/* Change the start and end address of the stack id. */
44880ec07f32bbbb209d749b9974408e6f025ad40b31sewardj#define VALGRIND_STACK_CHANGE(id, start, end)                     \
44890ec07f32bbbb209d749b9974408e6f025ad40b31sewardj   {unsigned int _qzz_res;                                        \
44900ec07f32bbbb209d749b9974408e6f025ad40b31sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
44910ec07f32bbbb209d749b9974408e6f025ad40b31sewardj                               VG_USERREQ__STACK_CHANGE,          \
44929af10a1c0d1b8897195ccfbc6dc46d8113d77153sewardj                               id, start, end, 0, 0);             \
44930140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh   }
44940140af5b913b1a57b5c28ef776bbb2dda23e8b64rjwalsh
4495c8259b85b701d25d72aabe9dc0a8154517f96913sewardj/* Load PDB debug info for Wine PE image_map. */
4496c8259b85b701d25d72aabe9dc0a8154517f96913sewardj#define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)   \
4497c8259b85b701d25d72aabe9dc0a8154517f96913sewardj   {unsigned int _qzz_res;                                        \
4498c8259b85b701d25d72aabe9dc0a8154517f96913sewardj    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
4499c8259b85b701d25d72aabe9dc0a8154517f96913sewardj                               VG_USERREQ__LOAD_PDB_DEBUGINFO,    \
4500c8259b85b701d25d72aabe9dc0a8154517f96913sewardj                               fd, ptr, total_size, delta, 0);    \
4501c8259b85b701d25d72aabe9dc0a8154517f96913sewardj   }
4502c8259b85b701d25d72aabe9dc0a8154517f96913sewardj
45030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
4504f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_x86_linux
4505f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_amd64_linux
4506f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc32_linux
4507f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc64_linux
450859570ffbe31930ab4d678754daaeec0715117a3dsewardj#undef PLAT_arm_linux
4509f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc32_aix5
4510f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj#undef PLAT_ppc64_aix5
45110ec07f32bbbb209d749b9974408e6f025ad40b31sewardj
45123e88418f808bf2840646504481d6a5be1df16541njn#endif   /* __VALGRIND_H */
4513