LCOV - code coverage report
Current view: top level - testing - valgrind.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 10 0
Test Date: 2025-12-26 23:00:34 Functions: 0.0 % 2 0

            Line data    Source code
       1              : /* -*- c -*-
       2              :    ----------------------------------------------------------------
       3              : 
       4              :    Notice that the following BSD-style license applies to this one
       5              :    file (valgrind.h) only.  The rest of Valgrind is licensed under the
       6              :    terms of the GNU General Public License, version 2, unless
       7              :    otherwise indicated.  See the COPYING file in the source
       8              :    distribution for details.
       9              : 
      10              :    ----------------------------------------------------------------
      11              : 
      12              :    This file is part of Valgrind, a dynamic binary instrumentation
      13              :    framework.
      14              : 
      15              :    Copyright (C) 2000-2017 Julian Seward.  All rights reserved.
      16              : 
      17              :    Redistribution and use in source and binary forms, with or without
      18              :    modification, are permitted provided that the following conditions
      19              :    are met:
      20              : 
      21              :    1. Redistributions of source code must retain the above copyright
      22              :       notice, this list of conditions and the following disclaimer.
      23              : 
      24              :    2. The origin of this software must not be misrepresented; you must 
      25              :       not claim that you wrote the original software.  If you use this 
      26              :       software in a product, an acknowledgment in the product 
      27              :       documentation would be appreciated but is not required.
      28              : 
      29              :    3. Altered source versions must be plainly marked as such, and must
      30              :       not be misrepresented as being the original software.
      31              : 
      32              :    4. The name of the author may not be used to endorse or promote 
      33              :       products derived from this software without specific prior written 
      34              :       permission.
      35              : 
      36              :    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
      37              :    OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
      38              :    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      39              :    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
      40              :    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      41              :    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
      42              :    GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      43              :    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      44              :    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
      45              :    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
      46              :    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              :    ----------------------------------------------------------------
      49              : 
      50              :    Notice that the above BSD-style license applies to this one file
      51              :    (valgrind.h) only.  The entire rest of Valgrind is licensed under
      52              :    the terms of the GNU General Public License, version 2.  See the
      53              :    COPYING file in the source distribution for details.
      54              : 
      55              :    ---------------------------------------------------------------- 
      56              : */
      57              : 
      58              : 
      59              : /* This file is for inclusion into client (your!) code.
      60              : 
      61              :    You can use these macros to manipulate and query Valgrind's 
      62              :    execution inside your own programs.
      63              : 
      64              :    The resulting executables will still run without Valgrind, just a
      65              :    little bit more slowly than they otherwise would, but otherwise
      66              :    unchanged.  When not running on valgrind, each client request
      67              :    consumes very few (eg. 7) instructions, so the resulting performance
      68              :    loss is negligible unless you plan to execute client requests
      69              :    millions of times per second.  Nevertheless, if that is still a
      70              :    problem, you can compile with the NVALGRIND symbol defined (gcc
      71              :    -DNVALGRIND) so that client requests are not even compiled in.  */
      72              : 
      73              : #ifndef __VALGRIND_H
      74              : #define __VALGRIND_H
      75              : 
      76              : 
      77              : /* ------------------------------------------------------------------ */
      78              : /* VERSION NUMBER OF VALGRIND                                         */
      79              : /* ------------------------------------------------------------------ */
      80              : 
      81              : /* Specify Valgrind's version number, so that user code can
      82              :    conditionally compile based on our version number.  Note that these
      83              :    were introduced at version 3.6 and so do not exist in version 3.5
      84              :    or earlier.  The recommended way to use them to check for "version
      85              :    X.Y or later" is (eg)
      86              : 
      87              : #if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__)   \
      88              :     && (__VALGRIND_MAJOR__ > 3                                   \
      89              :         || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
      90              : */
      91              : #define __VALGRIND_MAJOR__    3
      92              : #define __VALGRIND_MINOR__    19
      93              : 
      94              : 
      95              : #include <stdarg.h>
      96              : 
      97              : /* Nb: this file might be included in a file compiled with -ansi.  So
      98              :    we can't use C++ style "//" comments nor the "asm" keyword (instead
      99              :    use "__asm__"). */
     100              : 
     101              : /* Derive some tags indicating what the target platform is.  Note
     102              :    that in this file we're using the compiler's CPP symbols for
     103              :    identifying architectures, which are different to the ones we use
     104              :    within the rest of Valgrind.  Note, __powerpc__ is active for both
     105              :    32 and 64-bit PPC, whereas __powerpc64__ is only active for the
     106              :    latter (on Linux, that is).
     107              : 
     108              :    Misc note: how to find out what's predefined in gcc by default:
     109              :    gcc -Wp,-dM somefile.c
     110              : */
     111              : #undef PLAT_x86_darwin
     112              : #undef PLAT_amd64_darwin
     113              : #undef PLAT_x86_freebsd
     114              : #undef PLAT_amd64_freebsd
     115              : #undef PLAT_x86_win32
     116              : #undef PLAT_amd64_win64
     117              : #undef PLAT_x86_linux
     118              : #undef PLAT_amd64_linux
     119              : #undef PLAT_ppc32_linux
     120              : #undef PLAT_ppc64be_linux
     121              : #undef PLAT_ppc64le_linux
     122              : #undef PLAT_arm_linux
     123              : #undef PLAT_arm64_linux
     124              : #undef PLAT_s390x_linux
     125              : #undef PLAT_mips32_linux
     126              : #undef PLAT_mips64_linux
     127              : #undef PLAT_nanomips_linux
     128              : #undef PLAT_x86_solaris
     129              : #undef PLAT_amd64_solaris
     130              : 
     131              : 
     132              : #if defined(__APPLE__) && defined(__i386__)
     133              : #  define PLAT_x86_darwin 1
     134              : #elif defined(__APPLE__) && defined(__x86_64__)
     135              : #  define PLAT_amd64_darwin 1
     136              : #elif defined(__FreeBSD__) && defined(__i386__)
     137              : #  define PLAT_x86_freebsd 1
     138              : #elif defined(__FreeBSD__) && defined(__amd64__)
     139              : #  define PLAT_amd64_freebsd 1
     140              : #elif (defined(__MINGW32__) && defined(__i386__)) \
     141              :       || defined(__CYGWIN32__) \
     142              :       || (defined(_WIN32) && defined(_M_IX86))
     143              : #  define PLAT_x86_win32 1
     144              : #elif (defined(__MINGW32__) && defined(__x86_64__)) \
     145              :       || (defined(_WIN32) && defined(_M_X64))
     146              : /* __MINGW32__ and _WIN32 are defined in 64 bit mode as well. */
     147              : #  define PLAT_amd64_win64 1
     148              : #elif defined(__linux__) && defined(__i386__)
     149              : #  define PLAT_x86_linux 1
     150              : #elif defined(__linux__) && defined(__x86_64__) && !defined(__ILP32__)
     151              : #  define PLAT_amd64_linux 1
     152              : #elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
     153              : #  define PLAT_ppc32_linux 1
     154              : #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF != 2
     155              : /* Big Endian uses ELF version 1 */
     156              : #  define PLAT_ppc64be_linux 1
     157              : #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__) && _CALL_ELF == 2
     158              : /* Little Endian uses ELF version 2 */
     159              : #  define PLAT_ppc64le_linux 1
     160              : #elif defined(__linux__) && defined(__arm__) && !defined(__aarch64__)
     161              : #  define PLAT_arm_linux 1
     162              : #elif defined(__linux__) && defined(__aarch64__) && !defined(__arm__)
     163              : #  define PLAT_arm64_linux 1
     164              : #elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
     165              : #  define PLAT_s390x_linux 1
     166              : #elif defined(__linux__) && defined(__mips__) && (__mips==64)
     167              : #  define PLAT_mips64_linux 1
     168              : #elif defined(__linux__) && defined(__mips__) && (__mips==32)
     169              : #  define PLAT_mips32_linux 1
     170              : #elif defined(__linux__) && defined(__nanomips__)
     171              : #  define PLAT_nanomips_linux 1
     172              : #elif defined(__sun) && defined(__i386__)
     173              : #  define PLAT_x86_solaris 1
     174              : #elif defined(__sun) && defined(__x86_64__)
     175              : #  define PLAT_amd64_solaris 1
     176              : #else
     177              : /* If we're not compiling for our target platform, don't generate
     178              :    any inline asms.  */
     179              : #  if !defined(NVALGRIND)
     180              : #    define NVALGRIND 1
     181              : #  endif
     182              : #endif
     183              : 
     184              : 
     185              : /* ------------------------------------------------------------------ */
     186              : /* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
     187              : /* in here of use to end-users -- skip to the next section.           */
     188              : /* ------------------------------------------------------------------ */
     189              : 
     190              : /*
     191              :  * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client
     192              :  * request. Accepts both pointers and integers as arguments.
     193              :  *
     194              :  * VALGRIND_DO_CLIENT_REQUEST_STMT(): a statement that invokes a Valgrind
     195              :  * client request that does not return a value.
     196              : 
     197              :  * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
     198              :  * client request and whose value equals the client request result.  Accepts
     199              :  * both pointers and integers as arguments.  Note that such calls are not
     200              :  * necessarily pure functions -- they may have side effects.
     201              :  */
     202              : 
     203              : #define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default,            \
     204              :                                    _zzq_request, _zzq_arg1, _zzq_arg2,  \
     205              :                                    _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
     206              :   do { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default),   \
     207              :                         (_zzq_request), (_zzq_arg1), (_zzq_arg2),       \
     208              :                         (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
     209              : 
     210              : #define VALGRIND_DO_CLIENT_REQUEST_STMT(_zzq_request, _zzq_arg1,        \
     211              :                            _zzq_arg2,  _zzq_arg3, _zzq_arg4, _zzq_arg5) \
     212              :   do { (void) VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                        \
     213              :                     (_zzq_request), (_zzq_arg1), (_zzq_arg2),           \
     214              :                     (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); } while (0)
     215              : 
     216              : #if defined(NVALGRIND)
     217              : 
     218              : /* Define NVALGRIND to completely remove the Valgrind magic sequence
     219              :    from the compiled code (analogous to NDEBUG's effects on
     220              :    assert()) */
     221              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
     222              :         _zzq_default, _zzq_request,                               \
     223              :         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
     224              :       (_zzq_default)
     225              : 
     226              : #else  /* ! NVALGRIND */
     227              : 
     228              : /* The following defines the magic code sequences which the JITter
     229              :    spots and handles magically.  Don't look too closely at them as
     230              :    they will rot your brain.
     231              : 
     232              :    The assembly code sequences for all architectures is in this one
     233              :    file.  This is because this file must be stand-alone, and we don't
     234              :    want to have multiple files.
     235              : 
     236              :    For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
     237              :    value gets put in the return slot, so that everything works when
     238              :    this is executed not under Valgrind.  Args are passed in a memory
     239              :    block, and so there's no intrinsic limit to the number that could
     240              :    be passed, but it's currently five.
     241              :    
     242              :    The macro args are: 
     243              :       _zzq_rlval    result lvalue
     244              :       _zzq_default  default value (result returned when running on real CPU)
     245              :       _zzq_request  request code
     246              :       _zzq_arg1..5  request params
     247              : 
     248              :    The other two macros are used to support function wrapping, and are
     249              :    a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
     250              :    guest's NRADDR pseudo-register and whatever other information is
     251              :    needed to safely run the call original from the wrapper: on
     252              :    ppc64-linux, the R2 value at the divert point is also needed.  This
     253              :    information is abstracted into a user-visible type, OrigFn.
     254              : 
     255              :    VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
     256              :    guest, but guarantees that the branch instruction will not be
     257              :    redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
     258              :    branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
     259              :    complete inline asm, since it needs to be combined with more magic
     260              :    inline asm stuff to be useful.
     261              : */
     262              : 
     263              : /* ----------------- x86-{linux,darwin,solaris} ---------------- */
     264              : 
     265              : #if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)  \
     266              :     ||  (defined(PLAT_x86_win32) && defined(__GNUC__)) \
     267              :     ||  defined(PLAT_x86_solaris) || defined(PLAT_x86_freebsd)
     268              : 
     269              : typedef
     270              :    struct { 
     271              :       unsigned int nraddr; /* where's the code? */
     272              :    }
     273              :    OrigFn;
     274              : 
     275              : #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
     276              :                      "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
     277              :                      "roll $29, %%edi ; roll $19, %%edi\n\t"
     278              : 
     279              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
     280              :         _zzq_default, _zzq_request,                               \
     281              :         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
     282              :   __extension__                                                   \
     283              :   ({volatile unsigned int _zzq_args[6];                           \
     284              :     volatile unsigned int _zzq_result;                            \
     285              :     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
     286              :     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
     287              :     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
     288              :     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
     289              :     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
     290              :     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
     291              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     292              :                      /* %EDX = client_request ( %EAX ) */         \
     293              :                      "xchgl %%ebx,%%ebx"                          \
     294              :                      : "=d" (_zzq_result)                         \
     295              :                      : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
     296              :                      : "cc", "memory"                             \
     297              :                     );                                            \
     298              :     _zzq_result;                                                  \
     299              :   })
     300              : 
     301              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
     302              :   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
     303              :     volatile unsigned int __addr;                                 \
     304              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     305              :                      /* %EAX = guest_NRADDR */                    \
     306              :                      "xchgl %%ecx,%%ecx"                          \
     307              :                      : "=a" (__addr)                              \
     308              :                      :                                            \
     309              :                      : "cc", "memory"                             \
     310              :                     );                                            \
     311              :     _zzq_orig->nraddr = __addr;                                   \
     312              :   }
     313              : 
     314              : #define VALGRIND_CALL_NOREDIR_EAX                                 \
     315              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     316              :                      /* call-noredir *%EAX */                     \
     317              :                      "xchgl %%edx,%%edx\n\t"
     318              : 
     319              : #define VALGRIND_VEX_INJECT_IR()                                 \
     320              :  do {                                                            \
     321              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
     322              :                      "xchgl %%edi,%%edi\n\t"                     \
     323              :                      : : : "cc", "memory"                        \
     324              :                     );                                           \
     325              :  } while (0)
     326              : 
     327              : #endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__)
     328              :           || PLAT_x86_solaris */
     329              : 
     330              : /* ------------------------- x86-Win32 ------------------------- */
     331              : 
     332              : #if defined(PLAT_x86_win32) && !defined(__GNUC__)
     333              : 
     334              : typedef
     335              :    struct { 
     336              :       unsigned int nraddr; /* where's the code? */
     337              :    }
     338              :    OrigFn;
     339              : 
     340              : #if defined(_MSC_VER)
     341              : 
     342              : #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
     343              :                      __asm rol edi, 3  __asm rol edi, 13          \
     344              :                      __asm rol edi, 29 __asm rol edi, 19
     345              : 
     346              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
     347              :         _zzq_default, _zzq_request,                               \
     348              :         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
     349              :     valgrind_do_client_request_expr((uintptr_t)(_zzq_default),    \
     350              :         (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1),        \
     351              :         (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3),           \
     352              :         (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5))
     353              : 
     354              : static __inline uintptr_t
     355              : valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
     356              :                                 uintptr_t _zzq_arg1, uintptr_t _zzq_arg2,
     357              :                                 uintptr_t _zzq_arg3, uintptr_t _zzq_arg4,
     358              :                                 uintptr_t _zzq_arg5)
     359              : {
     360              :     volatile uintptr_t _zzq_args[6];
     361              :     volatile unsigned int _zzq_result;
     362              :     _zzq_args[0] = (uintptr_t)(_zzq_request);
     363              :     _zzq_args[1] = (uintptr_t)(_zzq_arg1);
     364              :     _zzq_args[2] = (uintptr_t)(_zzq_arg2);
     365              :     _zzq_args[3] = (uintptr_t)(_zzq_arg3);
     366              :     _zzq_args[4] = (uintptr_t)(_zzq_arg4);
     367              :     _zzq_args[5] = (uintptr_t)(_zzq_arg5);
     368              :     __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default
     369              :             __SPECIAL_INSTRUCTION_PREAMBLE
     370              :             /* %EDX = client_request ( %EAX ) */
     371              :             __asm xchg ebx,ebx
     372              :             __asm mov _zzq_result, edx
     373              :     }
     374              :     return _zzq_result;
     375              : }
     376              : 
     377              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
     378              :   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
     379              :     volatile unsigned int __addr;                                 \
     380              :     __asm { __SPECIAL_INSTRUCTION_PREAMBLE                        \
     381              :             /* %EAX = guest_NRADDR */                             \
     382              :             __asm xchg ecx,ecx                                    \
     383              :             __asm mov __addr, eax                                 \
     384              :     }                                                             \
     385              :     _zzq_orig->nraddr = __addr;                                   \
     386              :   }
     387              : 
     388              : #define VALGRIND_CALL_NOREDIR_EAX ERROR
     389              : 
     390              : #define VALGRIND_VEX_INJECT_IR()                                 \
     391              :  do {                                                            \
     392              :     __asm { __SPECIAL_INSTRUCTION_PREAMBLE                       \
     393              :             __asm xchg edi,edi                                   \
     394              :     }                                                            \
     395              :  } while (0)
     396              : 
     397              : #else
     398              : #error Unsupported compiler.
     399              : #endif
     400              : 
     401              : #endif /* PLAT_x86_win32 */
     402              : 
     403              : /* ----------------- amd64-{linux,darwin,solaris} --------------- */
     404              : 
     405              : #if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin) \
     406              :     ||  defined(PLAT_amd64_solaris) \
     407              :     ||  defined(PLAT_amd64_freebsd) \
     408              :     ||  (defined(PLAT_amd64_win64) && defined(__GNUC__))
     409              : 
     410              : typedef
     411              :    struct { 
     412              :       unsigned long int nraddr; /* where's the code? */
     413              :    }
     414              :    OrigFn;
     415              : 
     416              : #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
     417              :                      "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
     418              :                      "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
     419              : 
     420              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
     421              :         _zzq_default, _zzq_request,                               \
     422              :         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
     423              :     __extension__                                                 \
     424              :     ({ volatile unsigned long int _zzq_args[6];                   \
     425              :     volatile unsigned long int _zzq_result;                       \
     426              :     _zzq_args[0] = (unsigned long int)(_zzq_request);             \
     427              :     _zzq_args[1] = (unsigned long int)(_zzq_arg1);                \
     428              :     _zzq_args[2] = (unsigned long int)(_zzq_arg2);                \
     429              :     _zzq_args[3] = (unsigned long int)(_zzq_arg3);                \
     430              :     _zzq_args[4] = (unsigned long int)(_zzq_arg4);                \
     431              :     _zzq_args[5] = (unsigned long int)(_zzq_arg5);                \
     432              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     433              :                      /* %RDX = client_request ( %RAX ) */         \
     434              :                      "xchgq %%rbx,%%rbx"                          \
     435              :                      : "=d" (_zzq_result)                         \
     436              :                      : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
     437              :                      : "cc", "memory"                             \
     438              :                     );                                            \
     439              :     _zzq_result;                                                  \
     440              :     })
     441              : 
     442              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
     443              :   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
     444              :     volatile unsigned long int __addr;                            \
     445              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     446              :                      /* %RAX = guest_NRADDR */                    \
     447              :                      "xchgq %%rcx,%%rcx"                          \
     448              :                      : "=a" (__addr)                              \
     449              :                      :                                            \
     450              :                      : "cc", "memory"                             \
     451              :                     );                                            \
     452              :     _zzq_orig->nraddr = __addr;                                   \
     453              :   }
     454              : 
     455              : #define VALGRIND_CALL_NOREDIR_RAX                                 \
     456              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     457              :                      /* call-noredir *%RAX */                     \
     458              :                      "xchgq %%rdx,%%rdx\n\t"
     459              : 
     460              : #define VALGRIND_VEX_INJECT_IR()                                 \
     461              :  do {                                                            \
     462              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
     463              :                      "xchgq %%rdi,%%rdi\n\t"                     \
     464              :                      : : : "cc", "memory"                        \
     465              :                     );                                           \
     466              :  } while (0)
     467              : 
     468              : #endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */
     469              : 
     470              : /* ------------------------- amd64-Win64 ------------------------- */
     471              : 
     472              : #if defined(PLAT_amd64_win64) && !defined(__GNUC__)
     473              : 
     474              : #error Unsupported compiler.
     475              : 
     476              : #endif /* PLAT_amd64_win64 */
     477              : 
     478              : /* ------------------------ ppc32-linux ------------------------ */
     479              : 
     480              : #if defined(PLAT_ppc32_linux)
     481              : 
     482              : typedef
     483              :    struct { 
     484              :       unsigned int nraddr; /* where's the code? */
     485              :    }
     486              :    OrigFn;
     487              : 
     488              : #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
     489              :                     "rlwinm 0,0,3,0,31  ; rlwinm 0,0,13,0,31\n\t" \
     490              :                     "rlwinm 0,0,29,0,31 ; rlwinm 0,0,19,0,31\n\t"
     491              : 
     492              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
     493              :         _zzq_default, _zzq_request,                               \
     494              :         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
     495              :                                                                   \
     496              :     __extension__                                                 \
     497              :   ({         unsigned int  _zzq_args[6];                          \
     498              :              unsigned int  _zzq_result;                           \
     499              :              unsigned int* _zzq_ptr;                              \
     500              :     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
     501              :     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
     502              :     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
     503              :     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
     504              :     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
     505              :     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
     506              :     _zzq_ptr = _zzq_args;                                         \
     507              :     __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
     508              :                      "mr 4,%2\n\t" /*ptr*/                        \
     509              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     510              :                      /* %R3 = client_request ( %R4 ) */           \
     511              :                      "or 1,1,1\n\t"                               \
     512              :                      "mr %0,3"     /*result*/                     \
     513              :                      : "=b" (_zzq_result)                         \
     514              :                      : "b" (_zzq_default), "b" (_zzq_ptr)         \
     515              :                      : "cc", "memory", "r3", "r4");               \
     516              :     _zzq_result;                                                  \
     517              :     })
     518              : 
     519              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
     520              :   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
     521              :     unsigned int __addr;                                          \
     522              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     523              :                      /* %R3 = guest_NRADDR */                     \
     524              :                      "or 2,2,2\n\t"                               \
     525              :                      "mr %0,3"                                    \
     526              :                      : "=b" (__addr)                              \
     527              :                      :                                            \
     528              :                      : "cc", "memory", "r3"                       \
     529              :                     );                                            \
     530              :     _zzq_orig->nraddr = __addr;                                   \
     531              :   }
     532              : 
     533              : #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
     534              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     535              :                      /* branch-and-link-to-noredir *%R11 */       \
     536              :                      "or 3,3,3\n\t"
     537              : 
     538              : #define VALGRIND_VEX_INJECT_IR()                                 \
     539              :  do {                                                            \
     540              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
     541              :                      "or 5,5,5\n\t"                              \
     542              :                     );                                           \
     543              :  } while (0)
     544              : 
     545              : #endif /* PLAT_ppc32_linux */
     546              : 
     547              : /* ------------------------ ppc64-linux ------------------------ */
     548              : 
     549              : #if defined(PLAT_ppc64be_linux)
     550              : 
     551              : typedef
     552              :    struct { 
     553              :       unsigned long int nraddr; /* where's the code? */
     554              :       unsigned long int r2;  /* what tocptr do we need? */
     555              :    }
     556              :    OrigFn;
     557              : 
     558              : #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
     559              :                      "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
     560              :                      "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
     561              : 
     562              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
     563              :         _zzq_default, _zzq_request,                               \
     564              :         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
     565              :                                                                   \
     566              :   __extension__                                                   \
     567              :   ({         unsigned long int  _zzq_args[6];                     \
     568              :              unsigned long int  _zzq_result;                      \
     569              :              unsigned long int* _zzq_ptr;                         \
     570              :     _zzq_args[0] = (unsigned long int)(_zzq_request);             \
     571              :     _zzq_args[1] = (unsigned long int)(_zzq_arg1);                \
     572              :     _zzq_args[2] = (unsigned long int)(_zzq_arg2);                \
     573              :     _zzq_args[3] = (unsigned long int)(_zzq_arg3);                \
     574              :     _zzq_args[4] = (unsigned long int)(_zzq_arg4);                \
     575              :     _zzq_args[5] = (unsigned long int)(_zzq_arg5);                \
     576              :     _zzq_ptr = _zzq_args;                                         \
     577              :     __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
     578              :                      "mr 4,%2\n\t" /*ptr*/                        \
     579              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     580              :                      /* %R3 = client_request ( %R4 ) */           \
     581              :                      "or 1,1,1\n\t"                               \
     582              :                      "mr %0,3"     /*result*/                     \
     583              :                      : "=b" (_zzq_result)                         \
     584              :                      : "b" (_zzq_default), "b" (_zzq_ptr)         \
     585              :                      : "cc", "memory", "r3", "r4");               \
     586              :     _zzq_result;                                                  \
     587              :   })
     588              : 
     589              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
     590              :   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
     591              :     unsigned long int __addr;                                     \
     592              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     593              :                      /* %R3 = guest_NRADDR */                     \
     594              :                      "or 2,2,2\n\t"                               \
     595              :                      "mr %0,3"                                    \
     596              :                      : "=b" (__addr)                              \
     597              :                      :                                            \
     598              :                      : "cc", "memory", "r3"                       \
     599              :                     );                                            \
     600              :     _zzq_orig->nraddr = __addr;                                   \
     601              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     602              :                      /* %R3 = guest_NRADDR_GPR2 */                \
     603              :                      "or 4,4,4\n\t"                               \
     604              :                      "mr %0,3"                                    \
     605              :                      : "=b" (__addr)                              \
     606              :                      :                                            \
     607              :                      : "cc", "memory", "r3"                       \
     608              :                     );                                            \
     609              :     _zzq_orig->r2 = __addr;                                       \
     610              :   }
     611              : 
     612              : #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
     613              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     614              :                      /* branch-and-link-to-noredir *%R11 */       \
     615              :                      "or 3,3,3\n\t"
     616              : 
     617              : #define VALGRIND_VEX_INJECT_IR()                                 \
     618              :  do {                                                            \
     619              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
     620              :                      "or 5,5,5\n\t"                              \
     621              :                     );                                           \
     622              :  } while (0)
     623              : 
     624              : #endif /* PLAT_ppc64be_linux */
     625              : 
     626              : #if defined(PLAT_ppc64le_linux)
     627              : 
     628              : typedef
     629              :    struct {
     630              :       unsigned long int nraddr; /* where's the code? */
     631              :       unsigned long int r2;     /* what tocptr do we need? */
     632              :    }
     633              :    OrigFn;
     634              : 
     635              : #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
     636              :                      "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
     637              :                      "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
     638              : 
     639              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
     640              :         _zzq_default, _zzq_request,                               \
     641              :         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
     642              :                                                                   \
     643              :   __extension__                                                   \
     644              :   ({         unsigned long int  _zzq_args[6];                     \
     645              :              unsigned long int  _zzq_result;                      \
     646              :              unsigned long int* _zzq_ptr;                         \
     647              :     _zzq_args[0] = (unsigned long int)(_zzq_request);             \
     648              :     _zzq_args[1] = (unsigned long int)(_zzq_arg1);                \
     649              :     _zzq_args[2] = (unsigned long int)(_zzq_arg2);                \
     650              :     _zzq_args[3] = (unsigned long int)(_zzq_arg3);                \
     651              :     _zzq_args[4] = (unsigned long int)(_zzq_arg4);                \
     652              :     _zzq_args[5] = (unsigned long int)(_zzq_arg5);                \
     653              :     _zzq_ptr = _zzq_args;                                         \
     654              :     __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
     655              :                      "mr 4,%2\n\t" /*ptr*/                        \
     656              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     657              :                      /* %R3 = client_request ( %R4 ) */           \
     658              :                      "or 1,1,1\n\t"                               \
     659              :                      "mr %0,3"     /*result*/                     \
     660              :                      : "=b" (_zzq_result)                         \
     661              :                      : "b" (_zzq_default), "b" (_zzq_ptr)         \
     662              :                      : "cc", "memory", "r3", "r4");               \
     663              :     _zzq_result;                                                  \
     664              :   })
     665              : 
     666              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
     667              :   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
     668              :     unsigned long int __addr;                                     \
     669              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     670              :                      /* %R3 = guest_NRADDR */                     \
     671              :                      "or 2,2,2\n\t"                               \
     672              :                      "mr %0,3"                                    \
     673              :                      : "=b" (__addr)                              \
     674              :                      :                                            \
     675              :                      : "cc", "memory", "r3"                       \
     676              :                     );                                            \
     677              :     _zzq_orig->nraddr = __addr;                                   \
     678              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     679              :                      /* %R3 = guest_NRADDR_GPR2 */                \
     680              :                      "or 4,4,4\n\t"                               \
     681              :                      "mr %0,3"                                    \
     682              :                      : "=b" (__addr)                              \
     683              :                      :                                            \
     684              :                      : "cc", "memory", "r3"                       \
     685              :                     );                                            \
     686              :     _zzq_orig->r2 = __addr;                                       \
     687              :   }
     688              : 
     689              : #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                   \
     690              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     691              :                      /* branch-and-link-to-noredir *%R12 */       \
     692              :                      "or 3,3,3\n\t"
     693              : 
     694              : #define VALGRIND_VEX_INJECT_IR()                                 \
     695              :  do {                                                            \
     696              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
     697              :                      "or 5,5,5\n\t"                              \
     698              :                     );                                           \
     699              :  } while (0)
     700              : 
     701              : #endif /* PLAT_ppc64le_linux */
     702              : 
     703              : /* ------------------------- arm-linux ------------------------- */
     704              : 
     705              : #if defined(PLAT_arm_linux)
     706              : 
     707              : typedef
     708              :    struct { 
     709              :       unsigned int nraddr; /* where's the code? */
     710              :    }
     711              :    OrigFn;
     712              : 
     713              : #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
     714              :             "mov r12, r12, ror #3  ; mov r12, r12, ror #13 \n\t"  \
     715              :             "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
     716              : 
     717              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
     718              :         _zzq_default, _zzq_request,                               \
     719              :         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
     720              :                                                                   \
     721              :   __extension__                                                   \
     722              :   ({volatile unsigned int  _zzq_args[6];                          \
     723              :     volatile unsigned int  _zzq_result;                           \
     724              :     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
     725              :     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
     726              :     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
     727              :     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
     728              :     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
     729              :     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
     730              :     __asm__ volatile("mov r3, %1\n\t" /*default*/                 \
     731              :                      "mov r4, %2\n\t" /*ptr*/                     \
     732              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     733              :                      /* R3 = client_request ( R4 ) */             \
     734              :                      "orr r10, r10, r10\n\t"                      \
     735              :                      "mov %0, r3"     /*result*/                  \
     736              :                      : "=r" (_zzq_result)                         \
     737              :                      : "r" (_zzq_default), "r" (&_zzq_args[0])    \
     738              :                      : "cc","memory", "r3", "r4");                \
     739              :     _zzq_result;                                                  \
     740              :   })
     741              : 
     742              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
     743              :   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
     744              :     unsigned int __addr;                                          \
     745              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     746              :                      /* R3 = guest_NRADDR */                      \
     747              :                      "orr r11, r11, r11\n\t"                      \
     748              :                      "mov %0, r3"                                 \
     749              :                      : "=r" (__addr)                              \
     750              :                      :                                            \
     751              :                      : "cc", "memory", "r3"                       \
     752              :                     );                                            \
     753              :     _zzq_orig->nraddr = __addr;                                   \
     754              :   }
     755              : 
     756              : #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                    \
     757              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     758              :                      /* branch-and-link-to-noredir *%R4 */        \
     759              :                      "orr r12, r12, r12\n\t"
     760              : 
     761              : #define VALGRIND_VEX_INJECT_IR()                                 \
     762              :  do {                                                            \
     763              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
     764              :                      "orr r9, r9, r9\n\t"                        \
     765              :                      : : : "cc", "memory"                        \
     766              :                     );                                           \
     767              :  } while (0)
     768              : 
     769              : #endif /* PLAT_arm_linux */
     770              : 
     771              : /* ------------------------ arm64-linux ------------------------- */
     772              : 
     773              : #if defined(PLAT_arm64_linux)
     774              : 
     775              : typedef
     776              :    struct { 
     777              :       unsigned long int nraddr; /* where's the code? */
     778              :    }
     779              :    OrigFn;
     780              : 
     781              : #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
     782              :             "ror x12, x12, #3  ;  ror x12, x12, #13 \n\t"         \
     783              :             "ror x12, x12, #51 ;  ror x12, x12, #61 \n\t"
     784              : 
     785              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
     786              :         _zzq_default, _zzq_request,                               \
     787              :         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
     788              :                                                                   \
     789              :   __extension__                                                   \
     790              :   ({volatile unsigned long int  _zzq_args[6];                     \
     791              :     volatile unsigned long int  _zzq_result;                      \
     792              :     _zzq_args[0] = (unsigned long int)(_zzq_request);             \
     793              :     _zzq_args[1] = (unsigned long int)(_zzq_arg1);                \
     794              :     _zzq_args[2] = (unsigned long int)(_zzq_arg2);                \
     795              :     _zzq_args[3] = (unsigned long int)(_zzq_arg3);                \
     796              :     _zzq_args[4] = (unsigned long int)(_zzq_arg4);                \
     797              :     _zzq_args[5] = (unsigned long int)(_zzq_arg5);                \
     798              :     __asm__ volatile("mov x3, %1\n\t" /*default*/                 \
     799              :                      "mov x4, %2\n\t" /*ptr*/                     \
     800              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     801              :                      /* X3 = client_request ( X4 ) */             \
     802              :                      "orr x10, x10, x10\n\t"                      \
     803              :                      "mov %0, x3"     /*result*/                  \
     804              :                      : "=r" (_zzq_result)                         \
     805              :                      : "r" ((unsigned long int)(_zzq_default)),   \
     806              :                        "r" (&_zzq_args[0])                        \
     807              :                      : "cc","memory", "x3", "x4");                \
     808              :     _zzq_result;                                                  \
     809              :   })
     810              : 
     811              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
     812              :   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
     813              :     unsigned long int __addr;                                     \
     814              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     815              :                      /* X3 = guest_NRADDR */                      \
     816              :                      "orr x11, x11, x11\n\t"                      \
     817              :                      "mov %0, x3"                                 \
     818              :                      : "=r" (__addr)                              \
     819              :                      :                                            \
     820              :                      : "cc", "memory", "x3"                       \
     821              :                     );                                            \
     822              :     _zzq_orig->nraddr = __addr;                                   \
     823              :   }
     824              : 
     825              : #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                    \
     826              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     827              :                      /* branch-and-link-to-noredir X8 */          \
     828              :                      "orr x12, x12, x12\n\t"
     829              : 
     830              : #define VALGRIND_VEX_INJECT_IR()                                 \
     831              :  do {                                                            \
     832              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
     833              :                      "orr x9, x9, x9\n\t"                        \
     834              :                      : : : "cc", "memory"                        \
     835              :                     );                                           \
     836              :  } while (0)
     837              : 
     838              : #endif /* PLAT_arm64_linux */
     839              : 
     840              : /* ------------------------ s390x-linux ------------------------ */
     841              : 
     842              : #if defined(PLAT_s390x_linux)
     843              : 
     844              : typedef
     845              :   struct {
     846              :      unsigned long int nraddr; /* where's the code? */
     847              :   }
     848              :   OrigFn;
     849              : 
     850              : /* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific
     851              :  * code. This detection is implemented in platform specific toIR.c
     852              :  * (e.g. VEX/priv/guest_s390_decoder.c).
     853              :  */
     854              : #define __SPECIAL_INSTRUCTION_PREAMBLE                           \
     855              :                      "lr 15,15\n\t"                              \
     856              :                      "lr 1,1\n\t"                                \
     857              :                      "lr 2,2\n\t"                                \
     858              :                      "lr 3,3\n\t"
     859              : 
     860              : #define __CLIENT_REQUEST_CODE "lr 2,2\n\t"
     861              : #define __GET_NR_CONTEXT_CODE "lr 3,3\n\t"
     862              : #define __CALL_NO_REDIR_CODE  "lr 4,4\n\t"
     863              : #define __VEX_INJECT_IR_CODE  "lr 5,5\n\t"
     864              : 
     865              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                         \
     866              :        _zzq_default, _zzq_request,                               \
     867              :        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
     868              :   __extension__                                                  \
     869              :  ({volatile unsigned long int _zzq_args[6];                      \
     870              :    volatile unsigned long int _zzq_result;                       \
     871              :    _zzq_args[0] = (unsigned long int)(_zzq_request);             \
     872              :    _zzq_args[1] = (unsigned long int)(_zzq_arg1);                \
     873              :    _zzq_args[2] = (unsigned long int)(_zzq_arg2);                \
     874              :    _zzq_args[3] = (unsigned long int)(_zzq_arg3);                \
     875              :    _zzq_args[4] = (unsigned long int)(_zzq_arg4);                \
     876              :    _zzq_args[5] = (unsigned long int)(_zzq_arg5);                \
     877              :    __asm__ volatile(/* r2 = args */                              \
     878              :                     "lgr 2,%1\n\t"                               \
     879              :                     /* r3 = default */                           \
     880              :                     "lgr 3,%2\n\t"                               \
     881              :                     __SPECIAL_INSTRUCTION_PREAMBLE               \
     882              :                     __CLIENT_REQUEST_CODE                        \
     883              :                     /* results = r3 */                           \
     884              :                     "lgr %0, 3\n\t"                              \
     885              :                     : "=d" (_zzq_result)                         \
     886              :                     : "a" (&_zzq_args[0]),                       \
     887              :                       "0" ((unsigned long int)_zzq_default)      \
     888              :                     : "cc", "2", "3", "memory"                   \
     889              :                    );                                            \
     890              :    _zzq_result;                                                  \
     891              :  })
     892              : 
     893              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                      \
     894              :  { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
     895              :    volatile unsigned long int __addr;                            \
     896              :    __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     897              :                     __GET_NR_CONTEXT_CODE                        \
     898              :                     "lgr %0, 3\n\t"                              \
     899              :                     : "=a" (__addr)                              \
     900              :                     :                                            \
     901              :                     : "cc", "3", "memory"                        \
     902              :                    );                                            \
     903              :    _zzq_orig->nraddr = __addr;                                   \
     904              :  }
     905              : 
     906              : #define VALGRIND_CALL_NOREDIR_R1                                 \
     907              :                     __SPECIAL_INSTRUCTION_PREAMBLE               \
     908              :                     __CALL_NO_REDIR_CODE
     909              : 
     910              : #define VALGRIND_VEX_INJECT_IR()                                 \
     911              :  do {                                                            \
     912              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
     913              :                      __VEX_INJECT_IR_CODE);                      \
     914              :  } while (0)
     915              : 
     916              : #endif /* PLAT_s390x_linux */
     917              : 
     918              : /* ------------------------- mips32-linux ---------------- */
     919              : 
     920              : #if defined(PLAT_mips32_linux)
     921              : 
     922              : typedef
     923              :    struct { 
     924              :       unsigned int nraddr; /* where's the code? */
     925              :    }
     926              :    OrigFn;
     927              : 
     928              : /* .word  0x342
     929              :  * .word  0x742
     930              :  * .word  0xC2
     931              :  * .word  0x4C2*/
     932              : #define __SPECIAL_INSTRUCTION_PREAMBLE          \
     933              :                      "srl $0, $0, 13\n\t"       \
     934              :                      "srl $0, $0, 29\n\t"       \
     935              :                      "srl $0, $0, 3\n\t"        \
     936              :                      "srl $0, $0, 19\n\t"
     937              :                     
     938              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
     939              :        _zzq_default, _zzq_request,                                \
     940              :        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
     941              :   __extension__                                                   \
     942              :   ({ volatile unsigned int _zzq_args[6];                          \
     943              :     volatile unsigned int _zzq_result;                            \
     944              :     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
     945              :     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
     946              :     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
     947              :     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
     948              :     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
     949              :     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
     950              :         __asm__ volatile("move $11, %1\n\t" /*default*/           \
     951              :                      "move $12, %2\n\t" /*ptr*/                   \
     952              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
     953              :                      /* T3 = client_request ( T4 ) */             \
     954              :                      "or $13, $13, $13\n\t"                       \
     955              :                      "move %0, $11\n\t"     /*result*/            \
     956              :                      : "=r" (_zzq_result)                         \
     957              :                      : "r" (_zzq_default), "r" (&_zzq_args[0])    \
     958              :                      : "$11", "$12", "memory");                   \
     959              :     _zzq_result;                                                  \
     960              :   })
     961              : 
     962              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
     963              :   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
     964              :     volatile unsigned int __addr;                                 \
     965              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
     966              :                      /* %t9 = guest_NRADDR */                     \
     967              :                      "or $14, $14, $14\n\t"                       \
     968              :                      "move %0, $11"     /*result*/                \
     969              :                      : "=r" (__addr)                              \
     970              :                      :                                            \
     971              :                      : "$11"                                      \
     972              :                     );                                            \
     973              :     _zzq_orig->nraddr = __addr;                                   \
     974              :   }
     975              : 
     976              : #define VALGRIND_CALL_NOREDIR_T9                                 \
     977              :                      __SPECIAL_INSTRUCTION_PREAMBLE              \
     978              :                      /* call-noredir *%t9 */                     \
     979              :                      "or $15, $15, $15\n\t"
     980              : 
     981              : #define VALGRIND_VEX_INJECT_IR()                                 \
     982              :  do {                                                            \
     983              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE              \
     984              :                      "or $11, $11, $11\n\t"                      \
     985              :                     );                                           \
     986              :  } while (0)
     987              : 
     988              : 
     989              : #endif /* PLAT_mips32_linux */
     990              : 
     991              : /* ------------------------- mips64-linux ---------------- */
     992              : 
     993              : #if defined(PLAT_mips64_linux)
     994              : 
     995              : typedef
     996              :    struct {
     997              :       unsigned long nraddr; /* where's the code? */
     998              :    }
     999              :    OrigFn;
    1000              : 
    1001              : /* dsll $0,$0, 3
    1002              :  * dsll $0,$0, 13
    1003              :  * dsll $0,$0, 29
    1004              :  * dsll $0,$0, 19*/
    1005              : #define __SPECIAL_INSTRUCTION_PREAMBLE                              \
    1006              :                      "dsll $0,$0, 3 ; dsll $0,$0,13\n\t"            \
    1007              :                      "dsll $0,$0,29 ; dsll $0,$0,19\n\t"
    1008              : 
    1009              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                            \
    1010              :        _zzq_default, _zzq_request,                                  \
    1011              :        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)       \
    1012              :   __extension__                                                     \
    1013              :   ({ volatile unsigned long int _zzq_args[6];                       \
    1014              :     volatile unsigned long int _zzq_result;                         \
    1015              :     _zzq_args[0] = (unsigned long int)(_zzq_request);               \
    1016              :     _zzq_args[1] = (unsigned long int)(_zzq_arg1);                  \
    1017              :     _zzq_args[2] = (unsigned long int)(_zzq_arg2);                  \
    1018              :     _zzq_args[3] = (unsigned long int)(_zzq_arg3);                  \
    1019              :     _zzq_args[4] = (unsigned long int)(_zzq_arg4);                  \
    1020              :     _zzq_args[5] = (unsigned long int)(_zzq_arg5);                  \
    1021              :         __asm__ volatile("move $11, %1\n\t" /*default*/             \
    1022              :                          "move $12, %2\n\t" /*ptr*/                 \
    1023              :                          __SPECIAL_INSTRUCTION_PREAMBLE             \
    1024              :                          /* $11 = client_request ( $12 ) */         \
    1025              :                          "or $13, $13, $13\n\t"                     \
    1026              :                          "move %0, $11\n\t"     /*result*/          \
    1027              :                          : "=r" (_zzq_result)                       \
    1028              :                          : "r" (_zzq_default), "r" (&_zzq_args[0])  \
    1029              :                          : "$11", "$12", "memory");                 \
    1030              :     _zzq_result;                                                    \
    1031              :   })
    1032              : 
    1033              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                         \
    1034              :   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                     \
    1035              :     volatile unsigned long int __addr;                              \
    1036              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE                 \
    1037              :                      /* $11 = guest_NRADDR */                       \
    1038              :                      "or $14, $14, $14\n\t"                         \
    1039              :                      "move %0, $11"     /*result*/                  \
    1040              :                      : "=r" (__addr)                                \
    1041              :                      :                                              \
    1042              :                      : "$11");                                      \
    1043              :     _zzq_orig->nraddr = __addr;                                     \
    1044              :   }
    1045              : 
    1046              : #define VALGRIND_CALL_NOREDIR_T9                                    \
    1047              :                      __SPECIAL_INSTRUCTION_PREAMBLE                 \
    1048              :                      /* call-noredir $25 */                         \
    1049              :                      "or $15, $15, $15\n\t"
    1050              : 
    1051              : #define VALGRIND_VEX_INJECT_IR()                                    \
    1052              :  do {                                                               \
    1053              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE                 \
    1054              :                      "or $11, $11, $11\n\t"                         \
    1055              :                     );                                              \
    1056              :  } while (0)
    1057              : 
    1058              : #endif /* PLAT_mips64_linux */
    1059              : 
    1060              : #if defined(PLAT_nanomips_linux)
    1061              : 
    1062              : typedef
    1063              :    struct {
    1064              :       unsigned int nraddr; /* where's the code? */
    1065              :    }
    1066              :    OrigFn;
    1067              : /*
    1068              :    8000 c04d  srl  zero, zero, 13
    1069              :    8000 c05d  srl  zero, zero, 29
    1070              :    8000 c043  srl  zero, zero,  3
    1071              :    8000 c053  srl  zero, zero, 19
    1072              : */
    1073              : 
    1074              : #define __SPECIAL_INSTRUCTION_PREAMBLE "srl[32] $zero, $zero, 13 \n\t" \
    1075              :                                        "srl[32] $zero, $zero, 29 \n\t" \
    1076              :                                        "srl[32] $zero, $zero, 3  \n\t" \
    1077              :                                        "srl[32] $zero, $zero, 19 \n\t"
    1078              : 
    1079              : #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                          \
    1080              :        _zzq_default, _zzq_request,                                \
    1081              :        _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)     \
    1082              :   __extension__                                                   \
    1083              :   ({ volatile unsigned int _zzq_args[6];                          \
    1084              :     volatile unsigned int _zzq_result;                            \
    1085              :     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
    1086              :     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
    1087              :     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
    1088              :     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
    1089              :     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
    1090              :     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
    1091              :     __asm__ volatile("move $a7, %1\n\t" /* default */             \
    1092              :                      "move $t0, %2\n\t" /* ptr */                 \
    1093              :                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    1094              :                      /* $a7 = client_request( $t0 ) */            \
    1095              :                      "or[32] $t0, $t0, $t0\n\t"                   \
    1096              :                      "move %0, $a7\n\t"     /* result */          \
    1097              :                      : "=r" (_zzq_result)                         \
    1098              :                      : "r" (_zzq_default), "r" (&_zzq_args[0])    \
    1099              :                      : "$a7", "$t0", "memory");                   \
    1100              :     _zzq_result;                                                  \
    1101              :   })
    1102              : 
    1103              : #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                         \
    1104              :   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                     \
    1105              :     volatile unsigned long int __addr;                              \
    1106              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE                 \
    1107              :                      /* $a7 = guest_NRADDR */                       \
    1108              :                      "or[32] $t1, $t1, $t1\n\t"                     \
    1109              :                      "move %0, $a7"     /*result*/                  \
    1110              :                      : "=r" (__addr)                                \
    1111              :                      :                                              \
    1112              :                      : "$a7");                                      \
    1113              :     _zzq_orig->nraddr = __addr;                                     \
    1114              :   }
    1115              : 
    1116              : #define VALGRIND_CALL_NOREDIR_T9                                    \
    1117              :                      __SPECIAL_INSTRUCTION_PREAMBLE                 \
    1118              :                      /* call-noredir $25 */                         \
    1119              :                      "or[32] $t2, $t2, $t2\n\t"
    1120              : 
    1121              : #define VALGRIND_VEX_INJECT_IR()                                    \
    1122              :  do {                                                               \
    1123              :     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE                 \
    1124              :                      "or[32] $t3, $t3, $t3\n\t"                     \
    1125              :                     );                                              \
    1126              :  } while (0)
    1127              : 
    1128              : #endif
    1129              : /* Insert assembly code for other platforms here... */
    1130              : 
    1131              : #endif /* NVALGRIND */
    1132              : 
    1133              : 
    1134              : /* ------------------------------------------------------------------ */
    1135              : /* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
    1136              : /* ugly.  It's the least-worst tradeoff I can think of.               */
    1137              : /* ------------------------------------------------------------------ */
    1138              : 
    1139              : /* This section defines magic (a.k.a appalling-hack) macros for doing
    1140              :    guaranteed-no-redirection macros, so as to get from function
    1141              :    wrappers to the functions they are wrapping.  The whole point is to
    1142              :    construct standard call sequences, but to do the call itself with a
    1143              :    special no-redirect call pseudo-instruction that the JIT
    1144              :    understands and handles specially.  This section is long and
    1145              :    repetitious, and I can't see a way to make it shorter.
    1146              : 
    1147              :    The naming scheme is as follows:
    1148              : 
    1149              :       CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
    1150              : 
    1151              :    'W' stands for "word" and 'v' for "void".  Hence there are
    1152              :    different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
    1153              :    and for each, the possibility of returning a word-typed result, or
    1154              :    no result.
    1155              : */
    1156              : 
    1157              : /* Use these to write the name of your wrapper.  NOTE: duplicates
    1158              :    VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h.  NOTE also: inserts
    1159              :    the default behaviour equivalance class tag "0000" into the name.
    1160              :    See pub_tool_redir.h for details -- normally you don't need to
    1161              :    think about this, though. */
    1162              : 
    1163              : /* Use an extra level of macroisation so as to ensure the soname/fnname
    1164              :    args are fully macro-expanded before pasting them together. */
    1165              : #define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
    1166              : 
    1167              : #define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
    1168              :    VG_CONCAT4(_vgw00000ZU_,soname,_,fnname)
    1169              : 
    1170              : #define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
    1171              :    VG_CONCAT4(_vgw00000ZZ_,soname,_,fnname)
    1172              : 
    1173              : /* Use this macro from within a wrapper function to collect the
    1174              :    context (address and possibly other info) of the original function.
    1175              :    Once you have that you can then use it in one of the CALL_FN_
    1176              :    macros.  The type of the argument _lval is OrigFn. */
    1177              : #define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
    1178              : 
    1179              : /* Also provide end-user facilities for function replacement, rather
    1180              :    than wrapping.  A replacement function differs from a wrapper in
    1181              :    that it has no way to get hold of the original function being
    1182              :    called, and hence no way to call onwards to it.  In a replacement
    1183              :    function, VALGRIND_GET_ORIG_FN always returns zero. */
    1184              : 
    1185              : #define I_REPLACE_SONAME_FNNAME_ZU(soname,fnname)                 \
    1186              :    VG_CONCAT4(_vgr00000ZU_,soname,_,fnname)
    1187              : 
    1188              : #define I_REPLACE_SONAME_FNNAME_ZZ(soname,fnname)                 \
    1189              :    VG_CONCAT4(_vgr00000ZZ_,soname,_,fnname)
    1190              : 
    1191              : /* Derivatives of the main macros below, for calling functions
    1192              :    returning void. */
    1193              : 
    1194              : #define CALL_FN_v_v(fnptr)                                        \
    1195              :    do { volatile unsigned long _junk;                             \
    1196              :         CALL_FN_W_v(_junk,fnptr); } while (0)
    1197              : 
    1198              : #define CALL_FN_v_W(fnptr, arg1)                                  \
    1199              :    do { volatile unsigned long _junk;                             \
    1200              :         CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
    1201              : 
    1202              : #define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
    1203              :    do { volatile unsigned long _junk;                             \
    1204              :         CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
    1205              : 
    1206              : #define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
    1207              :    do { volatile unsigned long _junk;                             \
    1208              :         CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
    1209              : 
    1210              : #define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4)                \
    1211              :    do { volatile unsigned long _junk;                             \
    1212              :         CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
    1213              : 
    1214              : #define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5)             \
    1215              :    do { volatile unsigned long _junk;                             \
    1216              :         CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
    1217              : 
    1218              : #define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6)        \
    1219              :    do { volatile unsigned long _junk;                             \
    1220              :         CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
    1221              : 
    1222              : #define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7)   \
    1223              :    do { volatile unsigned long _junk;                             \
    1224              :         CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
    1225              : 
    1226              : /* ----------------- x86-{linux,darwin,solaris} ---------------- */
    1227              : 
    1228              : #if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin) \
    1229              :     ||  defined(PLAT_x86_solaris)  || defined(PLAT_x86_freebsd)
    1230              : 
    1231              : /* These regs are trashed by the hidden call.  No need to mention eax
    1232              :    as gcc can already see that, plus causes gcc to bomb. */
    1233              : #define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
    1234              : 
    1235              : /* Macros to save and align the stack before making a function
    1236              :    call and restore it afterwards as gcc may not keep the stack
    1237              :    pointer aligned if it doesn't realise calls are being made
    1238              :    to other functions. */
    1239              : 
    1240              : #define VALGRIND_ALIGN_STACK               \
    1241              :       "movl %%esp,%%edi\n\t"               \
    1242              :       "andl $0xfffffff0,%%esp\n\t"
    1243              : #define VALGRIND_RESTORE_STACK             \
    1244              :       "movl %%edi,%%esp\n\t"
    1245              : 
    1246              : /* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
    1247              :    long) == 4. */
    1248              : 
    1249              : #define CALL_FN_W_v(lval, orig)                                   \
    1250              :    do {                                                           \
    1251              :       volatile OrigFn        _orig = (orig);                      \
    1252              :       volatile unsigned long _argvec[1];                          \
    1253              :       volatile unsigned long _res;                                \
    1254              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1255              :       __asm__ volatile(                                           \
    1256              :          VALGRIND_ALIGN_STACK                                     \
    1257              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1258              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1259              :          VALGRIND_RESTORE_STACK                                   \
    1260              :          : /*out*/   "=a" (_res)                                  \
    1261              :          : /*in*/    "a" (&_argvec[0])                            \
    1262              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1263              :       );                                                          \
    1264              :       lval = (__typeof__(lval)) _res;                             \
    1265              :    } while (0)
    1266              : 
    1267              : #define CALL_FN_W_W(lval, orig, arg1)                             \
    1268              :    do {                                                           \
    1269              :       volatile OrigFn        _orig = (orig);                      \
    1270              :       volatile unsigned long _argvec[2];                          \
    1271              :       volatile unsigned long _res;                                \
    1272              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1273              :       _argvec[1] = (unsigned long)(arg1);                         \
    1274              :       __asm__ volatile(                                           \
    1275              :          VALGRIND_ALIGN_STACK                                     \
    1276              :          "subl $12, %%esp\n\t"                                    \
    1277              :          "pushl 4(%%eax)\n\t"                                     \
    1278              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1279              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1280              :          VALGRIND_RESTORE_STACK                                   \
    1281              :          : /*out*/   "=a" (_res)                                  \
    1282              :          : /*in*/    "a" (&_argvec[0])                            \
    1283              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1284              :       );                                                          \
    1285              :       lval = (__typeof__(lval)) _res;                             \
    1286              :    } while (0)
    1287              : 
    1288              : #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
    1289              :    do {                                                           \
    1290              :       volatile OrigFn        _orig = (orig);                      \
    1291              :       volatile unsigned long _argvec[3];                          \
    1292              :       volatile unsigned long _res;                                \
    1293              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1294              :       _argvec[1] = (unsigned long)(arg1);                         \
    1295              :       _argvec[2] = (unsigned long)(arg2);                         \
    1296              :       __asm__ volatile(                                           \
    1297              :          VALGRIND_ALIGN_STACK                                     \
    1298              :          "subl $8, %%esp\n\t"                                     \
    1299              :          "pushl 8(%%eax)\n\t"                                     \
    1300              :          "pushl 4(%%eax)\n\t"                                     \
    1301              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1302              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1303              :          VALGRIND_RESTORE_STACK                                   \
    1304              :          : /*out*/   "=a" (_res)                                  \
    1305              :          : /*in*/    "a" (&_argvec[0])                            \
    1306              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1307              :       );                                                          \
    1308              :       lval = (__typeof__(lval)) _res;                             \
    1309              :    } while (0)
    1310              : 
    1311              : #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    1312              :    do {                                                           \
    1313              :       volatile OrigFn        _orig = (orig);                      \
    1314              :       volatile unsigned long _argvec[4];                          \
    1315              :       volatile unsigned long _res;                                \
    1316              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1317              :       _argvec[1] = (unsigned long)(arg1);                         \
    1318              :       _argvec[2] = (unsigned long)(arg2);                         \
    1319              :       _argvec[3] = (unsigned long)(arg3);                         \
    1320              :       __asm__ volatile(                                           \
    1321              :          VALGRIND_ALIGN_STACK                                     \
    1322              :          "subl $4, %%esp\n\t"                                     \
    1323              :          "pushl 12(%%eax)\n\t"                                    \
    1324              :          "pushl 8(%%eax)\n\t"                                     \
    1325              :          "pushl 4(%%eax)\n\t"                                     \
    1326              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1327              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1328              :          VALGRIND_RESTORE_STACK                                   \
    1329              :          : /*out*/   "=a" (_res)                                  \
    1330              :          : /*in*/    "a" (&_argvec[0])                            \
    1331              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1332              :       );                                                          \
    1333              :       lval = (__typeof__(lval)) _res;                             \
    1334              :    } while (0)
    1335              : 
    1336              : #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
    1337              :    do {                                                           \
    1338              :       volatile OrigFn        _orig = (orig);                      \
    1339              :       volatile unsigned long _argvec[5];                          \
    1340              :       volatile unsigned long _res;                                \
    1341              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1342              :       _argvec[1] = (unsigned long)(arg1);                         \
    1343              :       _argvec[2] = (unsigned long)(arg2);                         \
    1344              :       _argvec[3] = (unsigned long)(arg3);                         \
    1345              :       _argvec[4] = (unsigned long)(arg4);                         \
    1346              :       __asm__ volatile(                                           \
    1347              :          VALGRIND_ALIGN_STACK                                     \
    1348              :          "pushl 16(%%eax)\n\t"                                    \
    1349              :          "pushl 12(%%eax)\n\t"                                    \
    1350              :          "pushl 8(%%eax)\n\t"                                     \
    1351              :          "pushl 4(%%eax)\n\t"                                     \
    1352              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1353              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1354              :          VALGRIND_RESTORE_STACK                                   \
    1355              :          : /*out*/   "=a" (_res)                                  \
    1356              :          : /*in*/    "a" (&_argvec[0])                            \
    1357              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1358              :       );                                                          \
    1359              :       lval = (__typeof__(lval)) _res;                             \
    1360              :    } while (0)
    1361              : 
    1362              : #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
    1363              :    do {                                                           \
    1364              :       volatile OrigFn        _orig = (orig);                      \
    1365              :       volatile unsigned long _argvec[6];                          \
    1366              :       volatile unsigned long _res;                                \
    1367              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1368              :       _argvec[1] = (unsigned long)(arg1);                         \
    1369              :       _argvec[2] = (unsigned long)(arg2);                         \
    1370              :       _argvec[3] = (unsigned long)(arg3);                         \
    1371              :       _argvec[4] = (unsigned long)(arg4);                         \
    1372              :       _argvec[5] = (unsigned long)(arg5);                         \
    1373              :       __asm__ volatile(                                           \
    1374              :          VALGRIND_ALIGN_STACK                                     \
    1375              :          "subl $12, %%esp\n\t"                                    \
    1376              :          "pushl 20(%%eax)\n\t"                                    \
    1377              :          "pushl 16(%%eax)\n\t"                                    \
    1378              :          "pushl 12(%%eax)\n\t"                                    \
    1379              :          "pushl 8(%%eax)\n\t"                                     \
    1380              :          "pushl 4(%%eax)\n\t"                                     \
    1381              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1382              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1383              :          VALGRIND_RESTORE_STACK                                   \
    1384              :          : /*out*/   "=a" (_res)                                  \
    1385              :          : /*in*/    "a" (&_argvec[0])                            \
    1386              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1387              :       );                                                          \
    1388              :       lval = (__typeof__(lval)) _res;                             \
    1389              :    } while (0)
    1390              : 
    1391              : #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
    1392              :    do {                                                           \
    1393              :       volatile OrigFn        _orig = (orig);                      \
    1394              :       volatile unsigned long _argvec[7];                          \
    1395              :       volatile unsigned long _res;                                \
    1396              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1397              :       _argvec[1] = (unsigned long)(arg1);                         \
    1398              :       _argvec[2] = (unsigned long)(arg2);                         \
    1399              :       _argvec[3] = (unsigned long)(arg3);                         \
    1400              :       _argvec[4] = (unsigned long)(arg4);                         \
    1401              :       _argvec[5] = (unsigned long)(arg5);                         \
    1402              :       _argvec[6] = (unsigned long)(arg6);                         \
    1403              :       __asm__ volatile(                                           \
    1404              :          VALGRIND_ALIGN_STACK                                     \
    1405              :          "subl $8, %%esp\n\t"                                     \
    1406              :          "pushl 24(%%eax)\n\t"                                    \
    1407              :          "pushl 20(%%eax)\n\t"                                    \
    1408              :          "pushl 16(%%eax)\n\t"                                    \
    1409              :          "pushl 12(%%eax)\n\t"                                    \
    1410              :          "pushl 8(%%eax)\n\t"                                     \
    1411              :          "pushl 4(%%eax)\n\t"                                     \
    1412              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1413              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1414              :          VALGRIND_RESTORE_STACK                                   \
    1415              :          : /*out*/   "=a" (_res)                                  \
    1416              :          : /*in*/    "a" (&_argvec[0])                            \
    1417              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1418              :       );                                                          \
    1419              :       lval = (__typeof__(lval)) _res;                             \
    1420              :    } while (0)
    1421              : 
    1422              : #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    1423              :                                  arg7)                            \
    1424              :    do {                                                           \
    1425              :       volatile OrigFn        _orig = (orig);                      \
    1426              :       volatile unsigned long _argvec[8];                          \
    1427              :       volatile unsigned long _res;                                \
    1428              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1429              :       _argvec[1] = (unsigned long)(arg1);                         \
    1430              :       _argvec[2] = (unsigned long)(arg2);                         \
    1431              :       _argvec[3] = (unsigned long)(arg3);                         \
    1432              :       _argvec[4] = (unsigned long)(arg4);                         \
    1433              :       _argvec[5] = (unsigned long)(arg5);                         \
    1434              :       _argvec[6] = (unsigned long)(arg6);                         \
    1435              :       _argvec[7] = (unsigned long)(arg7);                         \
    1436              :       __asm__ volatile(                                           \
    1437              :          VALGRIND_ALIGN_STACK                                     \
    1438              :          "subl $4, %%esp\n\t"                                     \
    1439              :          "pushl 28(%%eax)\n\t"                                    \
    1440              :          "pushl 24(%%eax)\n\t"                                    \
    1441              :          "pushl 20(%%eax)\n\t"                                    \
    1442              :          "pushl 16(%%eax)\n\t"                                    \
    1443              :          "pushl 12(%%eax)\n\t"                                    \
    1444              :          "pushl 8(%%eax)\n\t"                                     \
    1445              :          "pushl 4(%%eax)\n\t"                                     \
    1446              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1447              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1448              :          VALGRIND_RESTORE_STACK                                   \
    1449              :          : /*out*/   "=a" (_res)                                  \
    1450              :          : /*in*/    "a" (&_argvec[0])                            \
    1451              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1452              :       );                                                          \
    1453              :       lval = (__typeof__(lval)) _res;                             \
    1454              :    } while (0)
    1455              : 
    1456              : #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    1457              :                                  arg7,arg8)                       \
    1458              :    do {                                                           \
    1459              :       volatile OrigFn        _orig = (orig);                      \
    1460              :       volatile unsigned long _argvec[9];                          \
    1461              :       volatile unsigned long _res;                                \
    1462              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1463              :       _argvec[1] = (unsigned long)(arg1);                         \
    1464              :       _argvec[2] = (unsigned long)(arg2);                         \
    1465              :       _argvec[3] = (unsigned long)(arg3);                         \
    1466              :       _argvec[4] = (unsigned long)(arg4);                         \
    1467              :       _argvec[5] = (unsigned long)(arg5);                         \
    1468              :       _argvec[6] = (unsigned long)(arg6);                         \
    1469              :       _argvec[7] = (unsigned long)(arg7);                         \
    1470              :       _argvec[8] = (unsigned long)(arg8);                         \
    1471              :       __asm__ volatile(                                           \
    1472              :          VALGRIND_ALIGN_STACK                                     \
    1473              :          "pushl 32(%%eax)\n\t"                                    \
    1474              :          "pushl 28(%%eax)\n\t"                                    \
    1475              :          "pushl 24(%%eax)\n\t"                                    \
    1476              :          "pushl 20(%%eax)\n\t"                                    \
    1477              :          "pushl 16(%%eax)\n\t"                                    \
    1478              :          "pushl 12(%%eax)\n\t"                                    \
    1479              :          "pushl 8(%%eax)\n\t"                                     \
    1480              :          "pushl 4(%%eax)\n\t"                                     \
    1481              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1482              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1483              :          VALGRIND_RESTORE_STACK                                   \
    1484              :          : /*out*/   "=a" (_res)                                  \
    1485              :          : /*in*/    "a" (&_argvec[0])                            \
    1486              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1487              :       );                                                          \
    1488              :       lval = (__typeof__(lval)) _res;                             \
    1489              :    } while (0)
    1490              : 
    1491              : #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    1492              :                                  arg7,arg8,arg9)                  \
    1493              :    do {                                                           \
    1494              :       volatile OrigFn        _orig = (orig);                      \
    1495              :       volatile unsigned long _argvec[10];                         \
    1496              :       volatile unsigned long _res;                                \
    1497              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1498              :       _argvec[1] = (unsigned long)(arg1);                         \
    1499              :       _argvec[2] = (unsigned long)(arg2);                         \
    1500              :       _argvec[3] = (unsigned long)(arg3);                         \
    1501              :       _argvec[4] = (unsigned long)(arg4);                         \
    1502              :       _argvec[5] = (unsigned long)(arg5);                         \
    1503              :       _argvec[6] = (unsigned long)(arg6);                         \
    1504              :       _argvec[7] = (unsigned long)(arg7);                         \
    1505              :       _argvec[8] = (unsigned long)(arg8);                         \
    1506              :       _argvec[9] = (unsigned long)(arg9);                         \
    1507              :       __asm__ volatile(                                           \
    1508              :          VALGRIND_ALIGN_STACK                                     \
    1509              :          "subl $12, %%esp\n\t"                                    \
    1510              :          "pushl 36(%%eax)\n\t"                                    \
    1511              :          "pushl 32(%%eax)\n\t"                                    \
    1512              :          "pushl 28(%%eax)\n\t"                                    \
    1513              :          "pushl 24(%%eax)\n\t"                                    \
    1514              :          "pushl 20(%%eax)\n\t"                                    \
    1515              :          "pushl 16(%%eax)\n\t"                                    \
    1516              :          "pushl 12(%%eax)\n\t"                                    \
    1517              :          "pushl 8(%%eax)\n\t"                                     \
    1518              :          "pushl 4(%%eax)\n\t"                                     \
    1519              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1520              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1521              :          VALGRIND_RESTORE_STACK                                   \
    1522              :          : /*out*/   "=a" (_res)                                  \
    1523              :          : /*in*/    "a" (&_argvec[0])                            \
    1524              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1525              :       );                                                          \
    1526              :       lval = (__typeof__(lval)) _res;                             \
    1527              :    } while (0)
    1528              : 
    1529              : #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    1530              :                                   arg7,arg8,arg9,arg10)           \
    1531              :    do {                                                           \
    1532              :       volatile OrigFn        _orig = (orig);                      \
    1533              :       volatile unsigned long _argvec[11];                         \
    1534              :       volatile unsigned long _res;                                \
    1535              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1536              :       _argvec[1] = (unsigned long)(arg1);                         \
    1537              :       _argvec[2] = (unsigned long)(arg2);                         \
    1538              :       _argvec[3] = (unsigned long)(arg3);                         \
    1539              :       _argvec[4] = (unsigned long)(arg4);                         \
    1540              :       _argvec[5] = (unsigned long)(arg5);                         \
    1541              :       _argvec[6] = (unsigned long)(arg6);                         \
    1542              :       _argvec[7] = (unsigned long)(arg7);                         \
    1543              :       _argvec[8] = (unsigned long)(arg8);                         \
    1544              :       _argvec[9] = (unsigned long)(arg9);                         \
    1545              :       _argvec[10] = (unsigned long)(arg10);                       \
    1546              :       __asm__ volatile(                                           \
    1547              :          VALGRIND_ALIGN_STACK                                     \
    1548              :          "subl $8, %%esp\n\t"                                     \
    1549              :          "pushl 40(%%eax)\n\t"                                    \
    1550              :          "pushl 36(%%eax)\n\t"                                    \
    1551              :          "pushl 32(%%eax)\n\t"                                    \
    1552              :          "pushl 28(%%eax)\n\t"                                    \
    1553              :          "pushl 24(%%eax)\n\t"                                    \
    1554              :          "pushl 20(%%eax)\n\t"                                    \
    1555              :          "pushl 16(%%eax)\n\t"                                    \
    1556              :          "pushl 12(%%eax)\n\t"                                    \
    1557              :          "pushl 8(%%eax)\n\t"                                     \
    1558              :          "pushl 4(%%eax)\n\t"                                     \
    1559              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1560              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1561              :          VALGRIND_RESTORE_STACK                                   \
    1562              :          : /*out*/   "=a" (_res)                                  \
    1563              :          : /*in*/    "a" (&_argvec[0])                            \
    1564              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1565              :       );                                                          \
    1566              :       lval = (__typeof__(lval)) _res;                             \
    1567              :    } while (0)
    1568              : 
    1569              : #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
    1570              :                                   arg6,arg7,arg8,arg9,arg10,      \
    1571              :                                   arg11)                          \
    1572              :    do {                                                           \
    1573              :       volatile OrigFn        _orig = (orig);                      \
    1574              :       volatile unsigned long _argvec[12];                         \
    1575              :       volatile unsigned long _res;                                \
    1576              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1577              :       _argvec[1] = (unsigned long)(arg1);                         \
    1578              :       _argvec[2] = (unsigned long)(arg2);                         \
    1579              :       _argvec[3] = (unsigned long)(arg3);                         \
    1580              :       _argvec[4] = (unsigned long)(arg4);                         \
    1581              :       _argvec[5] = (unsigned long)(arg5);                         \
    1582              :       _argvec[6] = (unsigned long)(arg6);                         \
    1583              :       _argvec[7] = (unsigned long)(arg7);                         \
    1584              :       _argvec[8] = (unsigned long)(arg8);                         \
    1585              :       _argvec[9] = (unsigned long)(arg9);                         \
    1586              :       _argvec[10] = (unsigned long)(arg10);                       \
    1587              :       _argvec[11] = (unsigned long)(arg11);                       \
    1588              :       __asm__ volatile(                                           \
    1589              :          VALGRIND_ALIGN_STACK                                     \
    1590              :          "subl $4, %%esp\n\t"                                     \
    1591              :          "pushl 44(%%eax)\n\t"                                    \
    1592              :          "pushl 40(%%eax)\n\t"                                    \
    1593              :          "pushl 36(%%eax)\n\t"                                    \
    1594              :          "pushl 32(%%eax)\n\t"                                    \
    1595              :          "pushl 28(%%eax)\n\t"                                    \
    1596              :          "pushl 24(%%eax)\n\t"                                    \
    1597              :          "pushl 20(%%eax)\n\t"                                    \
    1598              :          "pushl 16(%%eax)\n\t"                                    \
    1599              :          "pushl 12(%%eax)\n\t"                                    \
    1600              :          "pushl 8(%%eax)\n\t"                                     \
    1601              :          "pushl 4(%%eax)\n\t"                                     \
    1602              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1603              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1604              :          VALGRIND_RESTORE_STACK                                   \
    1605              :          : /*out*/   "=a" (_res)                                  \
    1606              :          : /*in*/    "a" (&_argvec[0])                            \
    1607              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1608              :       );                                                          \
    1609              :       lval = (__typeof__(lval)) _res;                             \
    1610              :    } while (0)
    1611              : 
    1612              : #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
    1613              :                                   arg6,arg7,arg8,arg9,arg10,      \
    1614              :                                   arg11,arg12)                    \
    1615              :    do {                                                           \
    1616              :       volatile OrigFn        _orig = (orig);                      \
    1617              :       volatile unsigned long _argvec[13];                         \
    1618              :       volatile unsigned long _res;                                \
    1619              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    1620              :       _argvec[1] = (unsigned long)(arg1);                         \
    1621              :       _argvec[2] = (unsigned long)(arg2);                         \
    1622              :       _argvec[3] = (unsigned long)(arg3);                         \
    1623              :       _argvec[4] = (unsigned long)(arg4);                         \
    1624              :       _argvec[5] = (unsigned long)(arg5);                         \
    1625              :       _argvec[6] = (unsigned long)(arg6);                         \
    1626              :       _argvec[7] = (unsigned long)(arg7);                         \
    1627              :       _argvec[8] = (unsigned long)(arg8);                         \
    1628              :       _argvec[9] = (unsigned long)(arg9);                         \
    1629              :       _argvec[10] = (unsigned long)(arg10);                       \
    1630              :       _argvec[11] = (unsigned long)(arg11);                       \
    1631              :       _argvec[12] = (unsigned long)(arg12);                       \
    1632              :       __asm__ volatile(                                           \
    1633              :          VALGRIND_ALIGN_STACK                                     \
    1634              :          "pushl 48(%%eax)\n\t"                                    \
    1635              :          "pushl 44(%%eax)\n\t"                                    \
    1636              :          "pushl 40(%%eax)\n\t"                                    \
    1637              :          "pushl 36(%%eax)\n\t"                                    \
    1638              :          "pushl 32(%%eax)\n\t"                                    \
    1639              :          "pushl 28(%%eax)\n\t"                                    \
    1640              :          "pushl 24(%%eax)\n\t"                                    \
    1641              :          "pushl 20(%%eax)\n\t"                                    \
    1642              :          "pushl 16(%%eax)\n\t"                                    \
    1643              :          "pushl 12(%%eax)\n\t"                                    \
    1644              :          "pushl 8(%%eax)\n\t"                                     \
    1645              :          "pushl 4(%%eax)\n\t"                                     \
    1646              :          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    1647              :          VALGRIND_CALL_NOREDIR_EAX                                \
    1648              :          VALGRIND_RESTORE_STACK                                   \
    1649              :          : /*out*/   "=a" (_res)                                  \
    1650              :          : /*in*/    "a" (&_argvec[0])                            \
    1651              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "edi"   \
    1652              :       );                                                          \
    1653              :       lval = (__typeof__(lval)) _res;                             \
    1654              :    } while (0)
    1655              : 
    1656              : #endif /* PLAT_x86_linux || PLAT_x86_darwin || PLAT_x86_solaris */
    1657              : 
    1658              : /* ---------------- amd64-{linux,darwin,solaris} --------------- */
    1659              : 
    1660              : #if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin) \
    1661              :     ||  defined(PLAT_amd64_solaris)  ||  defined(PLAT_amd64_freebsd)
    1662              : 
    1663              : /* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
    1664              : 
    1665              : /* These regs are trashed by the hidden call. */
    1666              : #define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
    1667              :                             "rdi", "r8", "r9", "r10", "r11"
    1668              : 
    1669              : /* This is all pretty complex.  It's so as to make stack unwinding
    1670              :    work reliably.  See bug 243270.  The basic problem is the sub and
    1671              :    add of 128 of %rsp in all of the following macros.  If gcc believes
    1672              :    the CFA is in %rsp, then unwinding may fail, because what's at the
    1673              :    CFA is not what gcc "expected" when it constructs the CFIs for the
    1674              :    places where the macros are instantiated.
    1675              : 
    1676              :    But we can't just add a CFI annotation to increase the CFA offset
    1677              :    by 128, to match the sub of 128 from %rsp, because we don't know
    1678              :    whether gcc has chosen %rsp as the CFA at that point, or whether it
    1679              :    has chosen some other register (eg, %rbp).  In the latter case,
    1680              :    adding a CFI annotation to change the CFA offset is simply wrong.
    1681              : 
    1682              :    So the solution is to get hold of the CFA using
    1683              :    __builtin_dwarf_cfa(), put it in a known register, and add a
    1684              :    CFI annotation to say what the register is.  We choose %rbp for
    1685              :    this (perhaps perversely), because:
    1686              : 
    1687              :    (1) %rbp is already subject to unwinding.  If a new register was
    1688              :        chosen then the unwinder would have to unwind it in all stack
    1689              :        traces, which is expensive, and
    1690              : 
    1691              :    (2) %rbp is already subject to precise exception updates in the
    1692              :        JIT.  If a new register was chosen, we'd have to have precise
    1693              :        exceptions for it too, which reduces performance of the
    1694              :        generated code.
    1695              : 
    1696              :    However .. one extra complication.  We can't just whack the result
    1697              :    of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
    1698              :    list of trashed registers at the end of the inline assembly
    1699              :    fragments; gcc won't allow %rbp to appear in that list.  Hence
    1700              :    instead we need to stash %rbp in %r15 for the duration of the asm,
    1701              :    and say that %r15 is trashed instead.  gcc seems happy to go with
    1702              :    that.
    1703              : 
    1704              :    Oh .. and this all needs to be conditionalised so that it is
    1705              :    unchanged from before this commit, when compiled with older gccs
    1706              :    that don't support __builtin_dwarf_cfa.  Furthermore, since
    1707              :    this header file is freestanding, it has to be independent of
    1708              :    config.h, and so the following conditionalisation cannot depend on
    1709              :    configure time checks.
    1710              : 
    1711              :    Although it's not clear from
    1712              :    'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
    1713              :    this expression excludes Darwin.
    1714              :    .cfi directives in Darwin assembly appear to be completely
    1715              :    different and I haven't investigated how they work.
    1716              : 
    1717              :    For even more entertainment value, note we have to use the
    1718              :    completely undocumented __builtin_dwarf_cfa(), which appears to
    1719              :    really compute the CFA, whereas __builtin_frame_address(0) claims
    1720              :    to but actually doesn't.  See
    1721              :    https://bugs.kde.org/show_bug.cgi?id=243270#c47
    1722              : */
    1723              : #if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
    1724              : #  define __FRAME_POINTER                                         \
    1725              :       ,"r"(__builtin_dwarf_cfa())
    1726              : #  define VALGRIND_CFI_PROLOGUE                                   \
    1727              :       "movq %%rbp, %%r15\n\t"                                     \
    1728              :       "movq %2, %%rbp\n\t"                                        \
    1729              :       ".cfi_remember_state\n\t"                                   \
    1730              :       ".cfi_def_cfa rbp, 0\n\t"
    1731              : #  define VALGRIND_CFI_EPILOGUE                                   \
    1732              :       "movq %%r15, %%rbp\n\t"                                     \
    1733              :       ".cfi_restore_state\n\t"
    1734              : #else
    1735              : #  define __FRAME_POINTER
    1736              : #  define VALGRIND_CFI_PROLOGUE
    1737              : #  define VALGRIND_CFI_EPILOGUE
    1738              : #endif
    1739              : 
    1740              : /* Macros to save and align the stack before making a function
    1741              :    call and restore it afterwards as gcc may not keep the stack
    1742              :    pointer aligned if it doesn't realise calls are being made
    1743              :    to other functions. */
    1744              : 
    1745              : #define VALGRIND_ALIGN_STACK               \
    1746              :       "movq %%rsp,%%r14\n\t"               \
    1747              :       "andq $0xfffffffffffffff0,%%rsp\n\t"
    1748              : #define VALGRIND_RESTORE_STACK             \
    1749              :       "movq %%r14,%%rsp\n\t"
    1750              : 
    1751              : /* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
    1752              :    long) == 8. */
    1753              : 
    1754              : /* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
    1755              :    macros.  In order not to trash the stack redzone, we need to drop
    1756              :    %rsp by 128 before the hidden call, and restore afterwards.  The
    1757              :    nastyness is that it is only by luck that the stack still appears
    1758              :    to be unwindable during the hidden call - since then the behaviour
    1759              :    of any routine using this macro does not match what the CFI data
    1760              :    says.  Sigh.
    1761              : 
    1762              :    Why is this important?  Imagine that a wrapper has a stack
    1763              :    allocated local, and passes to the hidden call, a pointer to it.
    1764              :    Because gcc does not know about the hidden call, it may allocate
    1765              :    that local in the redzone.  Unfortunately the hidden call may then
    1766              :    trash it before it comes to use it.  So we must step clear of the
    1767              :    redzone, for the duration of the hidden call, to make it safe.
    1768              : 
    1769              :    Probably the same problem afflicts the other redzone-style ABIs too
    1770              :    (ppc64-linux); but for those, the stack is
    1771              :    self describing (none of this CFI nonsense) so at least messing
    1772              :    with the stack pointer doesn't give a danger of non-unwindable
    1773              :    stack. */
    1774              : 
    1775              : #define CALL_FN_W_v(lval, orig)                                        \
    1776              :    do {                                                                \
    1777              :       volatile OrigFn        _orig = (orig);                           \
    1778              :       volatile unsigned long _argvec[1];                               \
    1779              :       volatile unsigned long _res;                                     \
    1780              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    1781              :       __asm__ volatile(                                                \
    1782              :          VALGRIND_CFI_PROLOGUE                                         \
    1783              :          VALGRIND_ALIGN_STACK                                          \
    1784              :          "subq $128,%%rsp\n\t"                                         \
    1785              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    1786              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    1787              :          VALGRIND_RESTORE_STACK                                        \
    1788              :          VALGRIND_CFI_EPILOGUE                                         \
    1789              :          : /*out*/   "=a" (_res)                                       \
    1790              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    1791              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    1792              :       );                                                               \
    1793              :       lval = (__typeof__(lval)) _res;                                  \
    1794              :    } while (0)
    1795              : 
    1796              : #define CALL_FN_W_W(lval, orig, arg1)                                  \
    1797              :    do {                                                                \
    1798              :       volatile OrigFn        _orig = (orig);                           \
    1799              :       volatile unsigned long _argvec[2];                               \
    1800              :       volatile unsigned long _res;                                     \
    1801              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    1802              :       _argvec[1] = (unsigned long)(arg1);                              \
    1803              :       __asm__ volatile(                                                \
    1804              :          VALGRIND_CFI_PROLOGUE                                         \
    1805              :          VALGRIND_ALIGN_STACK                                          \
    1806              :          "subq $128,%%rsp\n\t"                                         \
    1807              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    1808              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    1809              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    1810              :          VALGRIND_RESTORE_STACK                                        \
    1811              :          VALGRIND_CFI_EPILOGUE                                         \
    1812              :          : /*out*/   "=a" (_res)                                       \
    1813              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    1814              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    1815              :       );                                                               \
    1816              :       lval = (__typeof__(lval)) _res;                                  \
    1817              :    } while (0)
    1818              : 
    1819              : #define CALL_FN_W_WW(lval, orig, arg1,arg2)                            \
    1820              :    do {                                                                \
    1821              :       volatile OrigFn        _orig = (orig);                           \
    1822              :       volatile unsigned long _argvec[3];                               \
    1823              :       volatile unsigned long _res;                                     \
    1824              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    1825              :       _argvec[1] = (unsigned long)(arg1);                              \
    1826              :       _argvec[2] = (unsigned long)(arg2);                              \
    1827              :       __asm__ volatile(                                                \
    1828              :          VALGRIND_CFI_PROLOGUE                                         \
    1829              :          VALGRIND_ALIGN_STACK                                          \
    1830              :          "subq $128,%%rsp\n\t"                                         \
    1831              :          "movq 16(%%rax), %%rsi\n\t"                                   \
    1832              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    1833              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    1834              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    1835              :          VALGRIND_RESTORE_STACK                                        \
    1836              :          VALGRIND_CFI_EPILOGUE                                         \
    1837              :          : /*out*/   "=a" (_res)                                       \
    1838              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    1839              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    1840              :       );                                                               \
    1841              :       lval = (__typeof__(lval)) _res;                                  \
    1842              :    } while (0)
    1843              : 
    1844              : #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                      \
    1845              :    do {                                                                \
    1846              :       volatile OrigFn        _orig = (orig);                           \
    1847              :       volatile unsigned long _argvec[4];                               \
    1848              :       volatile unsigned long _res;                                     \
    1849              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    1850              :       _argvec[1] = (unsigned long)(arg1);                              \
    1851              :       _argvec[2] = (unsigned long)(arg2);                              \
    1852              :       _argvec[3] = (unsigned long)(arg3);                              \
    1853              :       __asm__ volatile(                                                \
    1854              :          VALGRIND_CFI_PROLOGUE                                         \
    1855              :          VALGRIND_ALIGN_STACK                                          \
    1856              :          "subq $128,%%rsp\n\t"                                         \
    1857              :          "movq 24(%%rax), %%rdx\n\t"                                   \
    1858              :          "movq 16(%%rax), %%rsi\n\t"                                   \
    1859              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    1860              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    1861              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    1862              :          VALGRIND_RESTORE_STACK                                        \
    1863              :          VALGRIND_CFI_EPILOGUE                                         \
    1864              :          : /*out*/   "=a" (_res)                                       \
    1865              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    1866              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    1867              :       );                                                               \
    1868              :       lval = (__typeof__(lval)) _res;                                  \
    1869              :    } while (0)
    1870              : 
    1871              : #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)                \
    1872              :    do {                                                                \
    1873              :       volatile OrigFn        _orig = (orig);                           \
    1874              :       volatile unsigned long _argvec[5];                               \
    1875              :       volatile unsigned long _res;                                     \
    1876              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    1877              :       _argvec[1] = (unsigned long)(arg1);                              \
    1878              :       _argvec[2] = (unsigned long)(arg2);                              \
    1879              :       _argvec[3] = (unsigned long)(arg3);                              \
    1880              :       _argvec[4] = (unsigned long)(arg4);                              \
    1881              :       __asm__ volatile(                                                \
    1882              :          VALGRIND_CFI_PROLOGUE                                         \
    1883              :          VALGRIND_ALIGN_STACK                                          \
    1884              :          "subq $128,%%rsp\n\t"                                         \
    1885              :          "movq 32(%%rax), %%rcx\n\t"                                   \
    1886              :          "movq 24(%%rax), %%rdx\n\t"                                   \
    1887              :          "movq 16(%%rax), %%rsi\n\t"                                   \
    1888              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    1889              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    1890              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    1891              :          VALGRIND_RESTORE_STACK                                        \
    1892              :          VALGRIND_CFI_EPILOGUE                                         \
    1893              :          : /*out*/   "=a" (_res)                                       \
    1894              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    1895              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    1896              :       );                                                               \
    1897              :       lval = (__typeof__(lval)) _res;                                  \
    1898              :    } while (0)
    1899              : 
    1900              : #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)             \
    1901              :    do {                                                                \
    1902              :       volatile OrigFn        _orig = (orig);                           \
    1903              :       volatile unsigned long _argvec[6];                               \
    1904              :       volatile unsigned long _res;                                     \
    1905              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    1906              :       _argvec[1] = (unsigned long)(arg1);                              \
    1907              :       _argvec[2] = (unsigned long)(arg2);                              \
    1908              :       _argvec[3] = (unsigned long)(arg3);                              \
    1909              :       _argvec[4] = (unsigned long)(arg4);                              \
    1910              :       _argvec[5] = (unsigned long)(arg5);                              \
    1911              :       __asm__ volatile(                                                \
    1912              :          VALGRIND_CFI_PROLOGUE                                         \
    1913              :          VALGRIND_ALIGN_STACK                                          \
    1914              :          "subq $128,%%rsp\n\t"                                         \
    1915              :          "movq 40(%%rax), %%r8\n\t"                                    \
    1916              :          "movq 32(%%rax), %%rcx\n\t"                                   \
    1917              :          "movq 24(%%rax), %%rdx\n\t"                                   \
    1918              :          "movq 16(%%rax), %%rsi\n\t"                                   \
    1919              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    1920              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    1921              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    1922              :          VALGRIND_RESTORE_STACK                                        \
    1923              :          VALGRIND_CFI_EPILOGUE                                         \
    1924              :          : /*out*/   "=a" (_res)                                       \
    1925              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    1926              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    1927              :       );                                                               \
    1928              :       lval = (__typeof__(lval)) _res;                                  \
    1929              :    } while (0)
    1930              : 
    1931              : #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)        \
    1932              :    do {                                                                \
    1933              :       volatile OrigFn        _orig = (orig);                           \
    1934              :       volatile unsigned long _argvec[7];                               \
    1935              :       volatile unsigned long _res;                                     \
    1936              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    1937              :       _argvec[1] = (unsigned long)(arg1);                              \
    1938              :       _argvec[2] = (unsigned long)(arg2);                              \
    1939              :       _argvec[3] = (unsigned long)(arg3);                              \
    1940              :       _argvec[4] = (unsigned long)(arg4);                              \
    1941              :       _argvec[5] = (unsigned long)(arg5);                              \
    1942              :       _argvec[6] = (unsigned long)(arg6);                              \
    1943              :       __asm__ volatile(                                                \
    1944              :          VALGRIND_CFI_PROLOGUE                                         \
    1945              :          VALGRIND_ALIGN_STACK                                          \
    1946              :          "subq $128,%%rsp\n\t"                                         \
    1947              :          "movq 48(%%rax), %%r9\n\t"                                    \
    1948              :          "movq 40(%%rax), %%r8\n\t"                                    \
    1949              :          "movq 32(%%rax), %%rcx\n\t"                                   \
    1950              :          "movq 24(%%rax), %%rdx\n\t"                                   \
    1951              :          "movq 16(%%rax), %%rsi\n\t"                                   \
    1952              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    1953              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    1954              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    1955              :          VALGRIND_RESTORE_STACK                                        \
    1956              :          VALGRIND_CFI_EPILOGUE                                         \
    1957              :          : /*out*/   "=a" (_res)                                       \
    1958              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    1959              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    1960              :       );                                                               \
    1961              :       lval = (__typeof__(lval)) _res;                                  \
    1962              :    } while (0)
    1963              : 
    1964              : #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
    1965              :                                  arg7)                                 \
    1966              :    do {                                                                \
    1967              :       volatile OrigFn        _orig = (orig);                           \
    1968              :       volatile unsigned long _argvec[8];                               \
    1969              :       volatile unsigned long _res;                                     \
    1970              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    1971              :       _argvec[1] = (unsigned long)(arg1);                              \
    1972              :       _argvec[2] = (unsigned long)(arg2);                              \
    1973              :       _argvec[3] = (unsigned long)(arg3);                              \
    1974              :       _argvec[4] = (unsigned long)(arg4);                              \
    1975              :       _argvec[5] = (unsigned long)(arg5);                              \
    1976              :       _argvec[6] = (unsigned long)(arg6);                              \
    1977              :       _argvec[7] = (unsigned long)(arg7);                              \
    1978              :       __asm__ volatile(                                                \
    1979              :          VALGRIND_CFI_PROLOGUE                                         \
    1980              :          VALGRIND_ALIGN_STACK                                          \
    1981              :          "subq $136,%%rsp\n\t"                                         \
    1982              :          "pushq 56(%%rax)\n\t"                                         \
    1983              :          "movq 48(%%rax), %%r9\n\t"                                    \
    1984              :          "movq 40(%%rax), %%r8\n\t"                                    \
    1985              :          "movq 32(%%rax), %%rcx\n\t"                                   \
    1986              :          "movq 24(%%rax), %%rdx\n\t"                                   \
    1987              :          "movq 16(%%rax), %%rsi\n\t"                                   \
    1988              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    1989              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    1990              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    1991              :          VALGRIND_RESTORE_STACK                                        \
    1992              :          VALGRIND_CFI_EPILOGUE                                         \
    1993              :          : /*out*/   "=a" (_res)                                       \
    1994              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    1995              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    1996              :       );                                                               \
    1997              :       lval = (__typeof__(lval)) _res;                                  \
    1998              :    } while (0)
    1999              : 
    2000              : #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
    2001              :                                  arg7,arg8)                            \
    2002              :    do {                                                                \
    2003              :       volatile OrigFn        _orig = (orig);                           \
    2004              :       volatile unsigned long _argvec[9];                               \
    2005              :       volatile unsigned long _res;                                     \
    2006              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    2007              :       _argvec[1] = (unsigned long)(arg1);                              \
    2008              :       _argvec[2] = (unsigned long)(arg2);                              \
    2009              :       _argvec[3] = (unsigned long)(arg3);                              \
    2010              :       _argvec[4] = (unsigned long)(arg4);                              \
    2011              :       _argvec[5] = (unsigned long)(arg5);                              \
    2012              :       _argvec[6] = (unsigned long)(arg6);                              \
    2013              :       _argvec[7] = (unsigned long)(arg7);                              \
    2014              :       _argvec[8] = (unsigned long)(arg8);                              \
    2015              :       __asm__ volatile(                                                \
    2016              :          VALGRIND_CFI_PROLOGUE                                         \
    2017              :          VALGRIND_ALIGN_STACK                                          \
    2018              :          "subq $128,%%rsp\n\t"                                         \
    2019              :          "pushq 64(%%rax)\n\t"                                         \
    2020              :          "pushq 56(%%rax)\n\t"                                         \
    2021              :          "movq 48(%%rax), %%r9\n\t"                                    \
    2022              :          "movq 40(%%rax), %%r8\n\t"                                    \
    2023              :          "movq 32(%%rax), %%rcx\n\t"                                   \
    2024              :          "movq 24(%%rax), %%rdx\n\t"                                   \
    2025              :          "movq 16(%%rax), %%rsi\n\t"                                   \
    2026              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    2027              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    2028              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    2029              :          VALGRIND_RESTORE_STACK                                        \
    2030              :          VALGRIND_CFI_EPILOGUE                                         \
    2031              :          : /*out*/   "=a" (_res)                                       \
    2032              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    2033              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    2034              :       );                                                               \
    2035              :       lval = (__typeof__(lval)) _res;                                  \
    2036              :    } while (0)
    2037              : 
    2038              : #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,        \
    2039              :                                  arg7,arg8,arg9)                       \
    2040              :    do {                                                                \
    2041              :       volatile OrigFn        _orig = (orig);                           \
    2042              :       volatile unsigned long _argvec[10];                              \
    2043              :       volatile unsigned long _res;                                     \
    2044              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    2045              :       _argvec[1] = (unsigned long)(arg1);                              \
    2046              :       _argvec[2] = (unsigned long)(arg2);                              \
    2047              :       _argvec[3] = (unsigned long)(arg3);                              \
    2048              :       _argvec[4] = (unsigned long)(arg4);                              \
    2049              :       _argvec[5] = (unsigned long)(arg5);                              \
    2050              :       _argvec[6] = (unsigned long)(arg6);                              \
    2051              :       _argvec[7] = (unsigned long)(arg7);                              \
    2052              :       _argvec[8] = (unsigned long)(arg8);                              \
    2053              :       _argvec[9] = (unsigned long)(arg9);                              \
    2054              :       __asm__ volatile(                                                \
    2055              :          VALGRIND_CFI_PROLOGUE                                         \
    2056              :          VALGRIND_ALIGN_STACK                                          \
    2057              :          "subq $136,%%rsp\n\t"                                         \
    2058              :          "pushq 72(%%rax)\n\t"                                         \
    2059              :          "pushq 64(%%rax)\n\t"                                         \
    2060              :          "pushq 56(%%rax)\n\t"                                         \
    2061              :          "movq 48(%%rax), %%r9\n\t"                                    \
    2062              :          "movq 40(%%rax), %%r8\n\t"                                    \
    2063              :          "movq 32(%%rax), %%rcx\n\t"                                   \
    2064              :          "movq 24(%%rax), %%rdx\n\t"                                   \
    2065              :          "movq 16(%%rax), %%rsi\n\t"                                   \
    2066              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    2067              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    2068              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    2069              :          VALGRIND_RESTORE_STACK                                        \
    2070              :          VALGRIND_CFI_EPILOGUE                                         \
    2071              :          : /*out*/   "=a" (_res)                                       \
    2072              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    2073              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    2074              :       );                                                               \
    2075              :       lval = (__typeof__(lval)) _res;                                  \
    2076              :    } while (0)
    2077              : 
    2078              : #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
    2079              :                                   arg7,arg8,arg9,arg10)                \
    2080              :    do {                                                                \
    2081              :       volatile OrigFn        _orig = (orig);                           \
    2082              :       volatile unsigned long _argvec[11];                              \
    2083              :       volatile unsigned long _res;                                     \
    2084              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    2085              :       _argvec[1] = (unsigned long)(arg1);                              \
    2086              :       _argvec[2] = (unsigned long)(arg2);                              \
    2087              :       _argvec[3] = (unsigned long)(arg3);                              \
    2088              :       _argvec[4] = (unsigned long)(arg4);                              \
    2089              :       _argvec[5] = (unsigned long)(arg5);                              \
    2090              :       _argvec[6] = (unsigned long)(arg6);                              \
    2091              :       _argvec[7] = (unsigned long)(arg7);                              \
    2092              :       _argvec[8] = (unsigned long)(arg8);                              \
    2093              :       _argvec[9] = (unsigned long)(arg9);                              \
    2094              :       _argvec[10] = (unsigned long)(arg10);                            \
    2095              :       __asm__ volatile(                                                \
    2096              :          VALGRIND_CFI_PROLOGUE                                         \
    2097              :          VALGRIND_ALIGN_STACK                                          \
    2098              :          "subq $128,%%rsp\n\t"                                         \
    2099              :          "pushq 80(%%rax)\n\t"                                         \
    2100              :          "pushq 72(%%rax)\n\t"                                         \
    2101              :          "pushq 64(%%rax)\n\t"                                         \
    2102              :          "pushq 56(%%rax)\n\t"                                         \
    2103              :          "movq 48(%%rax), %%r9\n\t"                                    \
    2104              :          "movq 40(%%rax), %%r8\n\t"                                    \
    2105              :          "movq 32(%%rax), %%rcx\n\t"                                   \
    2106              :          "movq 24(%%rax), %%rdx\n\t"                                   \
    2107              :          "movq 16(%%rax), %%rsi\n\t"                                   \
    2108              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    2109              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    2110              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    2111              :          VALGRIND_RESTORE_STACK                                        \
    2112              :          VALGRIND_CFI_EPILOGUE                                         \
    2113              :          : /*out*/   "=a" (_res)                                       \
    2114              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    2115              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    2116              :       );                                                               \
    2117              :       lval = (__typeof__(lval)) _res;                                  \
    2118              :    } while (0)
    2119              : 
    2120              : #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
    2121              :                                   arg7,arg8,arg9,arg10,arg11)          \
    2122              :    do {                                                                \
    2123              :       volatile OrigFn        _orig = (orig);                           \
    2124              :       volatile unsigned long _argvec[12];                              \
    2125              :       volatile unsigned long _res;                                     \
    2126              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    2127              :       _argvec[1] = (unsigned long)(arg1);                              \
    2128              :       _argvec[2] = (unsigned long)(arg2);                              \
    2129              :       _argvec[3] = (unsigned long)(arg3);                              \
    2130              :       _argvec[4] = (unsigned long)(arg4);                              \
    2131              :       _argvec[5] = (unsigned long)(arg5);                              \
    2132              :       _argvec[6] = (unsigned long)(arg6);                              \
    2133              :       _argvec[7] = (unsigned long)(arg7);                              \
    2134              :       _argvec[8] = (unsigned long)(arg8);                              \
    2135              :       _argvec[9] = (unsigned long)(arg9);                              \
    2136              :       _argvec[10] = (unsigned long)(arg10);                            \
    2137              :       _argvec[11] = (unsigned long)(arg11);                            \
    2138              :       __asm__ volatile(                                                \
    2139              :          VALGRIND_CFI_PROLOGUE                                         \
    2140              :          VALGRIND_ALIGN_STACK                                          \
    2141              :          "subq $136,%%rsp\n\t"                                         \
    2142              :          "pushq 88(%%rax)\n\t"                                         \
    2143              :          "pushq 80(%%rax)\n\t"                                         \
    2144              :          "pushq 72(%%rax)\n\t"                                         \
    2145              :          "pushq 64(%%rax)\n\t"                                         \
    2146              :          "pushq 56(%%rax)\n\t"                                         \
    2147              :          "movq 48(%%rax), %%r9\n\t"                                    \
    2148              :          "movq 40(%%rax), %%r8\n\t"                                    \
    2149              :          "movq 32(%%rax), %%rcx\n\t"                                   \
    2150              :          "movq 24(%%rax), %%rdx\n\t"                                   \
    2151              :          "movq 16(%%rax), %%rsi\n\t"                                   \
    2152              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    2153              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    2154              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    2155              :          VALGRIND_RESTORE_STACK                                        \
    2156              :          VALGRIND_CFI_EPILOGUE                                         \
    2157              :          : /*out*/   "=a" (_res)                                       \
    2158              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    2159              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    2160              :       );                                                               \
    2161              :       lval = (__typeof__(lval)) _res;                                  \
    2162              :    } while (0)
    2163              : 
    2164              : #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,       \
    2165              :                                 arg7,arg8,arg9,arg10,arg11,arg12)      \
    2166              :    do {                                                                \
    2167              :       volatile OrigFn        _orig = (orig);                           \
    2168              :       volatile unsigned long _argvec[13];                              \
    2169              :       volatile unsigned long _res;                                     \
    2170              :       _argvec[0] = (unsigned long)_orig.nraddr;                        \
    2171              :       _argvec[1] = (unsigned long)(arg1);                              \
    2172              :       _argvec[2] = (unsigned long)(arg2);                              \
    2173              :       _argvec[3] = (unsigned long)(arg3);                              \
    2174              :       _argvec[4] = (unsigned long)(arg4);                              \
    2175              :       _argvec[5] = (unsigned long)(arg5);                              \
    2176              :       _argvec[6] = (unsigned long)(arg6);                              \
    2177              :       _argvec[7] = (unsigned long)(arg7);                              \
    2178              :       _argvec[8] = (unsigned long)(arg8);                              \
    2179              :       _argvec[9] = (unsigned long)(arg9);                              \
    2180              :       _argvec[10] = (unsigned long)(arg10);                            \
    2181              :       _argvec[11] = (unsigned long)(arg11);                            \
    2182              :       _argvec[12] = (unsigned long)(arg12);                            \
    2183              :       __asm__ volatile(                                                \
    2184              :          VALGRIND_CFI_PROLOGUE                                         \
    2185              :          VALGRIND_ALIGN_STACK                                          \
    2186              :          "subq $128,%%rsp\n\t"                                         \
    2187              :          "pushq 96(%%rax)\n\t"                                         \
    2188              :          "pushq 88(%%rax)\n\t"                                         \
    2189              :          "pushq 80(%%rax)\n\t"                                         \
    2190              :          "pushq 72(%%rax)\n\t"                                         \
    2191              :          "pushq 64(%%rax)\n\t"                                         \
    2192              :          "pushq 56(%%rax)\n\t"                                         \
    2193              :          "movq 48(%%rax), %%r9\n\t"                                    \
    2194              :          "movq 40(%%rax), %%r8\n\t"                                    \
    2195              :          "movq 32(%%rax), %%rcx\n\t"                                   \
    2196              :          "movq 24(%%rax), %%rdx\n\t"                                   \
    2197              :          "movq 16(%%rax), %%rsi\n\t"                                   \
    2198              :          "movq 8(%%rax), %%rdi\n\t"                                    \
    2199              :          "movq (%%rax), %%rax\n\t"  /* target->%rax */                 \
    2200              :          VALGRIND_CALL_NOREDIR_RAX                                     \
    2201              :          VALGRIND_RESTORE_STACK                                        \
    2202              :          VALGRIND_CFI_EPILOGUE                                         \
    2203              :          : /*out*/   "=a" (_res)                                       \
    2204              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER                 \
    2205              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r14", "r15" \
    2206              :       );                                                               \
    2207              :       lval = (__typeof__(lval)) _res;                                  \
    2208              :    } while (0)
    2209              : 
    2210              : #endif /* PLAT_amd64_linux || PLAT_amd64_darwin || PLAT_amd64_solaris */
    2211              : 
    2212              : /* ------------------------ ppc32-linux ------------------------ */
    2213              : 
    2214              : #if defined(PLAT_ppc32_linux)
    2215              : 
    2216              : /* This is useful for finding out about the on-stack stuff:
    2217              : 
    2218              :    extern int f9  ( int,int,int,int,int,int,int,int,int );
    2219              :    extern int f10 ( int,int,int,int,int,int,int,int,int,int );
    2220              :    extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
    2221              :    extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
    2222              : 
    2223              :    int g9 ( void ) {
    2224              :       return f9(11,22,33,44,55,66,77,88,99);
    2225              :    }
    2226              :    int g10 ( void ) {
    2227              :       return f10(11,22,33,44,55,66,77,88,99,110);
    2228              :    }
    2229              :    int g11 ( void ) {
    2230              :       return f11(11,22,33,44,55,66,77,88,99,110,121);
    2231              :    }
    2232              :    int g12 ( void ) {
    2233              :       return f12(11,22,33,44,55,66,77,88,99,110,121,132);
    2234              :    }
    2235              : */
    2236              : 
    2237              : /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
    2238              : 
    2239              : /* These regs are trashed by the hidden call. */
    2240              : #define __CALLER_SAVED_REGS                                       \
    2241              :    "lr", "ctr", "xer",                                            \
    2242              :    "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
    2243              :    "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
    2244              :    "r11", "r12", "r13"
    2245              : 
    2246              : /* Macros to save and align the stack before making a function
    2247              :    call and restore it afterwards as gcc may not keep the stack
    2248              :    pointer aligned if it doesn't realise calls are being made
    2249              :    to other functions. */
    2250              : 
    2251              : #define VALGRIND_ALIGN_STACK               \
    2252              :       "mr 28,1\n\t"                        \
    2253              :       "rlwinm 1,1,0,0,27\n\t"
    2254              : #define VALGRIND_RESTORE_STACK             \
    2255              :       "mr 1,28\n\t"
    2256              : 
    2257              : /* These CALL_FN_ macros assume that on ppc32-linux, 
    2258              :    sizeof(unsigned long) == 4. */
    2259              : 
    2260              : #define CALL_FN_W_v(lval, orig)                                   \
    2261              :    do {                                                           \
    2262              :       volatile OrigFn        _orig = (orig);                      \
    2263              :       volatile unsigned long _argvec[1];                          \
    2264              :       volatile unsigned long _res;                                \
    2265              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2266              :       __asm__ volatile(                                           \
    2267              :          VALGRIND_ALIGN_STACK                                     \
    2268              :          "mr 11,%1\n\t"                                           \
    2269              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2270              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2271              :          VALGRIND_RESTORE_STACK                                   \
    2272              :          "mr %0,3"                                                \
    2273              :          : /*out*/   "=r" (_res)                                  \
    2274              :          : /*in*/    "r" (&_argvec[0])                            \
    2275              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2276              :       );                                                          \
    2277              :       lval = (__typeof__(lval)) _res;                             \
    2278              :    } while (0)
    2279              : 
    2280              : #define CALL_FN_W_W(lval, orig, arg1)                             \
    2281              :    do {                                                           \
    2282              :       volatile OrigFn        _orig = (orig);                      \
    2283              :       volatile unsigned long _argvec[2];                          \
    2284              :       volatile unsigned long _res;                                \
    2285              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2286              :       _argvec[1] = (unsigned long)arg1;                           \
    2287              :       __asm__ volatile(                                           \
    2288              :          VALGRIND_ALIGN_STACK                                     \
    2289              :          "mr 11,%1\n\t"                                           \
    2290              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2291              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2292              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2293              :          VALGRIND_RESTORE_STACK                                   \
    2294              :          "mr %0,3"                                                \
    2295              :          : /*out*/   "=r" (_res)                                  \
    2296              :          : /*in*/    "r" (&_argvec[0])                            \
    2297              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2298              :       );                                                          \
    2299              :       lval = (__typeof__(lval)) _res;                             \
    2300              :    } while (0)
    2301              : 
    2302              : #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
    2303              :    do {                                                           \
    2304              :       volatile OrigFn        _orig = (orig);                      \
    2305              :       volatile unsigned long _argvec[3];                          \
    2306              :       volatile unsigned long _res;                                \
    2307              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2308              :       _argvec[1] = (unsigned long)arg1;                           \
    2309              :       _argvec[2] = (unsigned long)arg2;                           \
    2310              :       __asm__ volatile(                                           \
    2311              :          VALGRIND_ALIGN_STACK                                     \
    2312              :          "mr 11,%1\n\t"                                           \
    2313              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2314              :          "lwz 4,8(11)\n\t"                                        \
    2315              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2316              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2317              :          VALGRIND_RESTORE_STACK                                   \
    2318              :          "mr %0,3"                                                \
    2319              :          : /*out*/   "=r" (_res)                                  \
    2320              :          : /*in*/    "r" (&_argvec[0])                            \
    2321              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2322              :       );                                                          \
    2323              :       lval = (__typeof__(lval)) _res;                             \
    2324              :    } while (0)
    2325              : 
    2326              : #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    2327              :    do {                                                           \
    2328              :       volatile OrigFn        _orig = (orig);                      \
    2329              :       volatile unsigned long _argvec[4];                          \
    2330              :       volatile unsigned long _res;                                \
    2331              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2332              :       _argvec[1] = (unsigned long)arg1;                           \
    2333              :       _argvec[2] = (unsigned long)arg2;                           \
    2334              :       _argvec[3] = (unsigned long)arg3;                           \
    2335              :       __asm__ volatile(                                           \
    2336              :          VALGRIND_ALIGN_STACK                                     \
    2337              :          "mr 11,%1\n\t"                                           \
    2338              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2339              :          "lwz 4,8(11)\n\t"                                        \
    2340              :          "lwz 5,12(11)\n\t"                                       \
    2341              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2342              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2343              :          VALGRIND_RESTORE_STACK                                   \
    2344              :          "mr %0,3"                                                \
    2345              :          : /*out*/   "=r" (_res)                                  \
    2346              :          : /*in*/    "r" (&_argvec[0])                            \
    2347              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2348              :       );                                                          \
    2349              :       lval = (__typeof__(lval)) _res;                             \
    2350              :    } while (0)
    2351              : 
    2352              : #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
    2353              :    do {                                                           \
    2354              :       volatile OrigFn        _orig = (orig);                      \
    2355              :       volatile unsigned long _argvec[5];                          \
    2356              :       volatile unsigned long _res;                                \
    2357              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2358              :       _argvec[1] = (unsigned long)arg1;                           \
    2359              :       _argvec[2] = (unsigned long)arg2;                           \
    2360              :       _argvec[3] = (unsigned long)arg3;                           \
    2361              :       _argvec[4] = (unsigned long)arg4;                           \
    2362              :       __asm__ volatile(                                           \
    2363              :          VALGRIND_ALIGN_STACK                                     \
    2364              :          "mr 11,%1\n\t"                                           \
    2365              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2366              :          "lwz 4,8(11)\n\t"                                        \
    2367              :          "lwz 5,12(11)\n\t"                                       \
    2368              :          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
    2369              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2370              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2371              :          VALGRIND_RESTORE_STACK                                   \
    2372              :          "mr %0,3"                                                \
    2373              :          : /*out*/   "=r" (_res)                                  \
    2374              :          : /*in*/    "r" (&_argvec[0])                            \
    2375              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2376              :       );                                                          \
    2377              :       lval = (__typeof__(lval)) _res;                             \
    2378              :    } while (0)
    2379              : 
    2380              : #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
    2381              :    do {                                                           \
    2382              :       volatile OrigFn        _orig = (orig);                      \
    2383              :       volatile unsigned long _argvec[6];                          \
    2384              :       volatile unsigned long _res;                                \
    2385              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2386              :       _argvec[1] = (unsigned long)arg1;                           \
    2387              :       _argvec[2] = (unsigned long)arg2;                           \
    2388              :       _argvec[3] = (unsigned long)arg3;                           \
    2389              :       _argvec[4] = (unsigned long)arg4;                           \
    2390              :       _argvec[5] = (unsigned long)arg5;                           \
    2391              :       __asm__ volatile(                                           \
    2392              :          VALGRIND_ALIGN_STACK                                     \
    2393              :          "mr 11,%1\n\t"                                           \
    2394              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2395              :          "lwz 4,8(11)\n\t"                                        \
    2396              :          "lwz 5,12(11)\n\t"                                       \
    2397              :          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
    2398              :          "lwz 7,20(11)\n\t"                                       \
    2399              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2400              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2401              :          VALGRIND_RESTORE_STACK                                   \
    2402              :          "mr %0,3"                                                \
    2403              :          : /*out*/   "=r" (_res)                                  \
    2404              :          : /*in*/    "r" (&_argvec[0])                            \
    2405              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2406              :       );                                                          \
    2407              :       lval = (__typeof__(lval)) _res;                             \
    2408              :    } while (0)
    2409              : 
    2410              : #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
    2411              :    do {                                                           \
    2412              :       volatile OrigFn        _orig = (orig);                      \
    2413              :       volatile unsigned long _argvec[7];                          \
    2414              :       volatile unsigned long _res;                                \
    2415              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2416              :       _argvec[1] = (unsigned long)arg1;                           \
    2417              :       _argvec[2] = (unsigned long)arg2;                           \
    2418              :       _argvec[3] = (unsigned long)arg3;                           \
    2419              :       _argvec[4] = (unsigned long)arg4;                           \
    2420              :       _argvec[5] = (unsigned long)arg5;                           \
    2421              :       _argvec[6] = (unsigned long)arg6;                           \
    2422              :       __asm__ volatile(                                           \
    2423              :          VALGRIND_ALIGN_STACK                                     \
    2424              :          "mr 11,%1\n\t"                                           \
    2425              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2426              :          "lwz 4,8(11)\n\t"                                        \
    2427              :          "lwz 5,12(11)\n\t"                                       \
    2428              :          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
    2429              :          "lwz 7,20(11)\n\t"                                       \
    2430              :          "lwz 8,24(11)\n\t"                                       \
    2431              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2432              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2433              :          VALGRIND_RESTORE_STACK                                   \
    2434              :          "mr %0,3"                                                \
    2435              :          : /*out*/   "=r" (_res)                                  \
    2436              :          : /*in*/    "r" (&_argvec[0])                            \
    2437              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2438              :       );                                                          \
    2439              :       lval = (__typeof__(lval)) _res;                             \
    2440              :    } while (0)
    2441              : 
    2442              : #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    2443              :                                  arg7)                            \
    2444              :    do {                                                           \
    2445              :       volatile OrigFn        _orig = (orig);                      \
    2446              :       volatile unsigned long _argvec[8];                          \
    2447              :       volatile unsigned long _res;                                \
    2448              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2449              :       _argvec[1] = (unsigned long)arg1;                           \
    2450              :       _argvec[2] = (unsigned long)arg2;                           \
    2451              :       _argvec[3] = (unsigned long)arg3;                           \
    2452              :       _argvec[4] = (unsigned long)arg4;                           \
    2453              :       _argvec[5] = (unsigned long)arg5;                           \
    2454              :       _argvec[6] = (unsigned long)arg6;                           \
    2455              :       _argvec[7] = (unsigned long)arg7;                           \
    2456              :       __asm__ volatile(                                           \
    2457              :          VALGRIND_ALIGN_STACK                                     \
    2458              :          "mr 11,%1\n\t"                                           \
    2459              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2460              :          "lwz 4,8(11)\n\t"                                        \
    2461              :          "lwz 5,12(11)\n\t"                                       \
    2462              :          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
    2463              :          "lwz 7,20(11)\n\t"                                       \
    2464              :          "lwz 8,24(11)\n\t"                                       \
    2465              :          "lwz 9,28(11)\n\t"                                       \
    2466              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2467              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2468              :          VALGRIND_RESTORE_STACK                                   \
    2469              :          "mr %0,3"                                                \
    2470              :          : /*out*/   "=r" (_res)                                  \
    2471              :          : /*in*/    "r" (&_argvec[0])                            \
    2472              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2473              :       );                                                          \
    2474              :       lval = (__typeof__(lval)) _res;                             \
    2475              :    } while (0)
    2476              : 
    2477              : #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    2478              :                                  arg7,arg8)                       \
    2479              :    do {                                                           \
    2480              :       volatile OrigFn        _orig = (orig);                      \
    2481              :       volatile unsigned long _argvec[9];                          \
    2482              :       volatile unsigned long _res;                                \
    2483              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2484              :       _argvec[1] = (unsigned long)arg1;                           \
    2485              :       _argvec[2] = (unsigned long)arg2;                           \
    2486              :       _argvec[3] = (unsigned long)arg3;                           \
    2487              :       _argvec[4] = (unsigned long)arg4;                           \
    2488              :       _argvec[5] = (unsigned long)arg5;                           \
    2489              :       _argvec[6] = (unsigned long)arg6;                           \
    2490              :       _argvec[7] = (unsigned long)arg7;                           \
    2491              :       _argvec[8] = (unsigned long)arg8;                           \
    2492              :       __asm__ volatile(                                           \
    2493              :          VALGRIND_ALIGN_STACK                                     \
    2494              :          "mr 11,%1\n\t"                                           \
    2495              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2496              :          "lwz 4,8(11)\n\t"                                        \
    2497              :          "lwz 5,12(11)\n\t"                                       \
    2498              :          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
    2499              :          "lwz 7,20(11)\n\t"                                       \
    2500              :          "lwz 8,24(11)\n\t"                                       \
    2501              :          "lwz 9,28(11)\n\t"                                       \
    2502              :          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
    2503              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2504              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2505              :          VALGRIND_RESTORE_STACK                                   \
    2506              :          "mr %0,3"                                                \
    2507              :          : /*out*/   "=r" (_res)                                  \
    2508              :          : /*in*/    "r" (&_argvec[0])                            \
    2509              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2510              :       );                                                          \
    2511              :       lval = (__typeof__(lval)) _res;                             \
    2512              :    } while (0)
    2513              : 
    2514              : #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    2515              :                                  arg7,arg8,arg9)                  \
    2516              :    do {                                                           \
    2517              :       volatile OrigFn        _orig = (orig);                      \
    2518              :       volatile unsigned long _argvec[10];                         \
    2519              :       volatile unsigned long _res;                                \
    2520              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2521              :       _argvec[1] = (unsigned long)arg1;                           \
    2522              :       _argvec[2] = (unsigned long)arg2;                           \
    2523              :       _argvec[3] = (unsigned long)arg3;                           \
    2524              :       _argvec[4] = (unsigned long)arg4;                           \
    2525              :       _argvec[5] = (unsigned long)arg5;                           \
    2526              :       _argvec[6] = (unsigned long)arg6;                           \
    2527              :       _argvec[7] = (unsigned long)arg7;                           \
    2528              :       _argvec[8] = (unsigned long)arg8;                           \
    2529              :       _argvec[9] = (unsigned long)arg9;                           \
    2530              :       __asm__ volatile(                                           \
    2531              :          VALGRIND_ALIGN_STACK                                     \
    2532              :          "mr 11,%1\n\t"                                           \
    2533              :          "addi 1,1,-16\n\t"                                       \
    2534              :          /* arg9 */                                               \
    2535              :          "lwz 3,36(11)\n\t"                                       \
    2536              :          "stw 3,8(1)\n\t"                                         \
    2537              :          /* args1-8 */                                            \
    2538              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2539              :          "lwz 4,8(11)\n\t"                                        \
    2540              :          "lwz 5,12(11)\n\t"                                       \
    2541              :          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
    2542              :          "lwz 7,20(11)\n\t"                                       \
    2543              :          "lwz 8,24(11)\n\t"                                       \
    2544              :          "lwz 9,28(11)\n\t"                                       \
    2545              :          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
    2546              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2547              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2548              :          VALGRIND_RESTORE_STACK                                   \
    2549              :          "mr %0,3"                                                \
    2550              :          : /*out*/   "=r" (_res)                                  \
    2551              :          : /*in*/    "r" (&_argvec[0])                            \
    2552              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2553              :       );                                                          \
    2554              :       lval = (__typeof__(lval)) _res;                             \
    2555              :    } while (0)
    2556              : 
    2557              : #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    2558              :                                   arg7,arg8,arg9,arg10)           \
    2559              :    do {                                                           \
    2560              :       volatile OrigFn        _orig = (orig);                      \
    2561              :       volatile unsigned long _argvec[11];                         \
    2562              :       volatile unsigned long _res;                                \
    2563              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2564              :       _argvec[1] = (unsigned long)arg1;                           \
    2565              :       _argvec[2] = (unsigned long)arg2;                           \
    2566              :       _argvec[3] = (unsigned long)arg3;                           \
    2567              :       _argvec[4] = (unsigned long)arg4;                           \
    2568              :       _argvec[5] = (unsigned long)arg5;                           \
    2569              :       _argvec[6] = (unsigned long)arg6;                           \
    2570              :       _argvec[7] = (unsigned long)arg7;                           \
    2571              :       _argvec[8] = (unsigned long)arg8;                           \
    2572              :       _argvec[9] = (unsigned long)arg9;                           \
    2573              :       _argvec[10] = (unsigned long)arg10;                         \
    2574              :       __asm__ volatile(                                           \
    2575              :          VALGRIND_ALIGN_STACK                                     \
    2576              :          "mr 11,%1\n\t"                                           \
    2577              :          "addi 1,1,-16\n\t"                                       \
    2578              :          /* arg10 */                                              \
    2579              :          "lwz 3,40(11)\n\t"                                       \
    2580              :          "stw 3,12(1)\n\t"                                        \
    2581              :          /* arg9 */                                               \
    2582              :          "lwz 3,36(11)\n\t"                                       \
    2583              :          "stw 3,8(1)\n\t"                                         \
    2584              :          /* args1-8 */                                            \
    2585              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2586              :          "lwz 4,8(11)\n\t"                                        \
    2587              :          "lwz 5,12(11)\n\t"                                       \
    2588              :          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
    2589              :          "lwz 7,20(11)\n\t"                                       \
    2590              :          "lwz 8,24(11)\n\t"                                       \
    2591              :          "lwz 9,28(11)\n\t"                                       \
    2592              :          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
    2593              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2594              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2595              :          VALGRIND_RESTORE_STACK                                   \
    2596              :          "mr %0,3"                                                \
    2597              :          : /*out*/   "=r" (_res)                                  \
    2598              :          : /*in*/    "r" (&_argvec[0])                            \
    2599              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2600              :       );                                                          \
    2601              :       lval = (__typeof__(lval)) _res;                             \
    2602              :    } while (0)
    2603              : 
    2604              : #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    2605              :                                   arg7,arg8,arg9,arg10,arg11)     \
    2606              :    do {                                                           \
    2607              :       volatile OrigFn        _orig = (orig);                      \
    2608              :       volatile unsigned long _argvec[12];                         \
    2609              :       volatile unsigned long _res;                                \
    2610              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2611              :       _argvec[1] = (unsigned long)arg1;                           \
    2612              :       _argvec[2] = (unsigned long)arg2;                           \
    2613              :       _argvec[3] = (unsigned long)arg3;                           \
    2614              :       _argvec[4] = (unsigned long)arg4;                           \
    2615              :       _argvec[5] = (unsigned long)arg5;                           \
    2616              :       _argvec[6] = (unsigned long)arg6;                           \
    2617              :       _argvec[7] = (unsigned long)arg7;                           \
    2618              :       _argvec[8] = (unsigned long)arg8;                           \
    2619              :       _argvec[9] = (unsigned long)arg9;                           \
    2620              :       _argvec[10] = (unsigned long)arg10;                         \
    2621              :       _argvec[11] = (unsigned long)arg11;                         \
    2622              :       __asm__ volatile(                                           \
    2623              :          VALGRIND_ALIGN_STACK                                     \
    2624              :          "mr 11,%1\n\t"                                           \
    2625              :          "addi 1,1,-32\n\t"                                       \
    2626              :          /* arg11 */                                              \
    2627              :          "lwz 3,44(11)\n\t"                                       \
    2628              :          "stw 3,16(1)\n\t"                                        \
    2629              :          /* arg10 */                                              \
    2630              :          "lwz 3,40(11)\n\t"                                       \
    2631              :          "stw 3,12(1)\n\t"                                        \
    2632              :          /* arg9 */                                               \
    2633              :          "lwz 3,36(11)\n\t"                                       \
    2634              :          "stw 3,8(1)\n\t"                                         \
    2635              :          /* args1-8 */                                            \
    2636              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2637              :          "lwz 4,8(11)\n\t"                                        \
    2638              :          "lwz 5,12(11)\n\t"                                       \
    2639              :          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
    2640              :          "lwz 7,20(11)\n\t"                                       \
    2641              :          "lwz 8,24(11)\n\t"                                       \
    2642              :          "lwz 9,28(11)\n\t"                                       \
    2643              :          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
    2644              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2645              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2646              :          VALGRIND_RESTORE_STACK                                   \
    2647              :          "mr %0,3"                                                \
    2648              :          : /*out*/   "=r" (_res)                                  \
    2649              :          : /*in*/    "r" (&_argvec[0])                            \
    2650              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2651              :       );                                                          \
    2652              :       lval = (__typeof__(lval)) _res;                             \
    2653              :    } while (0)
    2654              : 
    2655              : #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    2656              :                                 arg7,arg8,arg9,arg10,arg11,arg12) \
    2657              :    do {                                                           \
    2658              :       volatile OrigFn        _orig = (orig);                      \
    2659              :       volatile unsigned long _argvec[13];                         \
    2660              :       volatile unsigned long _res;                                \
    2661              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    2662              :       _argvec[1] = (unsigned long)arg1;                           \
    2663              :       _argvec[2] = (unsigned long)arg2;                           \
    2664              :       _argvec[3] = (unsigned long)arg3;                           \
    2665              :       _argvec[4] = (unsigned long)arg4;                           \
    2666              :       _argvec[5] = (unsigned long)arg5;                           \
    2667              :       _argvec[6] = (unsigned long)arg6;                           \
    2668              :       _argvec[7] = (unsigned long)arg7;                           \
    2669              :       _argvec[8] = (unsigned long)arg8;                           \
    2670              :       _argvec[9] = (unsigned long)arg9;                           \
    2671              :       _argvec[10] = (unsigned long)arg10;                         \
    2672              :       _argvec[11] = (unsigned long)arg11;                         \
    2673              :       _argvec[12] = (unsigned long)arg12;                         \
    2674              :       __asm__ volatile(                                           \
    2675              :          VALGRIND_ALIGN_STACK                                     \
    2676              :          "mr 11,%1\n\t"                                           \
    2677              :          "addi 1,1,-32\n\t"                                       \
    2678              :          /* arg12 */                                              \
    2679              :          "lwz 3,48(11)\n\t"                                       \
    2680              :          "stw 3,20(1)\n\t"                                        \
    2681              :          /* arg11 */                                              \
    2682              :          "lwz 3,44(11)\n\t"                                       \
    2683              :          "stw 3,16(1)\n\t"                                        \
    2684              :          /* arg10 */                                              \
    2685              :          "lwz 3,40(11)\n\t"                                       \
    2686              :          "stw 3,12(1)\n\t"                                        \
    2687              :          /* arg9 */                                               \
    2688              :          "lwz 3,36(11)\n\t"                                       \
    2689              :          "stw 3,8(1)\n\t"                                         \
    2690              :          /* args1-8 */                                            \
    2691              :          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
    2692              :          "lwz 4,8(11)\n\t"                                        \
    2693              :          "lwz 5,12(11)\n\t"                                       \
    2694              :          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
    2695              :          "lwz 7,20(11)\n\t"                                       \
    2696              :          "lwz 8,24(11)\n\t"                                       \
    2697              :          "lwz 9,28(11)\n\t"                                       \
    2698              :          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
    2699              :          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
    2700              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2701              :          VALGRIND_RESTORE_STACK                                   \
    2702              :          "mr %0,3"                                                \
    2703              :          : /*out*/   "=r" (_res)                                  \
    2704              :          : /*in*/    "r" (&_argvec[0])                            \
    2705              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2706              :       );                                                          \
    2707              :       lval = (__typeof__(lval)) _res;                             \
    2708              :    } while (0)
    2709              : 
    2710              : #endif /* PLAT_ppc32_linux */
    2711              : 
    2712              : /* ------------------------ ppc64-linux ------------------------ */
    2713              : 
    2714              : #if defined(PLAT_ppc64be_linux)
    2715              : 
    2716              : /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
    2717              : 
    2718              : /* These regs are trashed by the hidden call. */
    2719              : #define __CALLER_SAVED_REGS                                       \
    2720              :    "lr", "ctr", "xer",                                            \
    2721              :    "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
    2722              :    "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",         \
    2723              :    "r11", "r12", "r13"
    2724              : 
    2725              : /* Macros to save and align the stack before making a function
    2726              :    call and restore it afterwards as gcc may not keep the stack
    2727              :    pointer aligned if it doesn't realise calls are being made
    2728              :    to other functions. */
    2729              : 
    2730              : #define VALGRIND_ALIGN_STACK               \
    2731              :       "mr 28,1\n\t"                        \
    2732              :       "rldicr 1,1,0,59\n\t"
    2733              : #define VALGRIND_RESTORE_STACK             \
    2734              :       "mr 1,28\n\t"
    2735              : 
    2736              : /* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
    2737              :    long) == 8. */
    2738              : 
    2739              : #define CALL_FN_W_v(lval, orig)                                   \
    2740              :    do {                                                           \
    2741              :       volatile OrigFn        _orig = (orig);                      \
    2742              :       volatile unsigned long _argvec[3+0];                        \
    2743              :       volatile unsigned long _res;                                \
    2744              :       /* _argvec[0] holds current r2 across the call */           \
    2745              :       _argvec[1] = (unsigned long)_orig.r2;                       \
    2746              :       _argvec[2] = (unsigned long)_orig.nraddr;                   \
    2747              :       __asm__ volatile(                                           \
    2748              :          VALGRIND_ALIGN_STACK                                     \
    2749              :          "mr 11,%1\n\t"                                           \
    2750              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    2751              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    2752              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    2753              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2754              :          "mr 11,%1\n\t"                                           \
    2755              :          "mr %0,3\n\t"                                            \
    2756              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    2757              :          VALGRIND_RESTORE_STACK                                   \
    2758              :          : /*out*/   "=r" (_res)                                  \
    2759              :          : /*in*/    "r" (&_argvec[2])                            \
    2760              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2761              :       );                                                          \
    2762              :       lval = (__typeof__(lval)) _res;                             \
    2763              :    } while (0)
    2764              : 
    2765              : #define CALL_FN_W_W(lval, orig, arg1)                             \
    2766              :    do {                                                           \
    2767              :       volatile OrigFn        _orig = (orig);                      \
    2768              :       volatile unsigned long _argvec[3+1];                        \
    2769              :       volatile unsigned long _res;                                \
    2770              :       /* _argvec[0] holds current r2 across the call */           \
    2771              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    2772              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    2773              :       _argvec[2+1] = (unsigned long)arg1;                         \
    2774              :       __asm__ volatile(                                           \
    2775              :          VALGRIND_ALIGN_STACK                                     \
    2776              :          "mr 11,%1\n\t"                                           \
    2777              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    2778              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    2779              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    2780              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    2781              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2782              :          "mr 11,%1\n\t"                                           \
    2783              :          "mr %0,3\n\t"                                            \
    2784              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    2785              :          VALGRIND_RESTORE_STACK                                   \
    2786              :          : /*out*/   "=r" (_res)                                  \
    2787              :          : /*in*/    "r" (&_argvec[2])                            \
    2788              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2789              :       );                                                          \
    2790              :       lval = (__typeof__(lval)) _res;                             \
    2791              :    } while (0)
    2792              : 
    2793              : #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
    2794              :    do {                                                           \
    2795              :       volatile OrigFn        _orig = (orig);                      \
    2796              :       volatile unsigned long _argvec[3+2];                        \
    2797              :       volatile unsigned long _res;                                \
    2798              :       /* _argvec[0] holds current r2 across the call */           \
    2799              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    2800              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    2801              :       _argvec[2+1] = (unsigned long)arg1;                         \
    2802              :       _argvec[2+2] = (unsigned long)arg2;                         \
    2803              :       __asm__ volatile(                                           \
    2804              :          VALGRIND_ALIGN_STACK                                     \
    2805              :          "mr 11,%1\n\t"                                           \
    2806              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    2807              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    2808              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    2809              :          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
    2810              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    2811              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2812              :          "mr 11,%1\n\t"                                           \
    2813              :          "mr %0,3\n\t"                                            \
    2814              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    2815              :          VALGRIND_RESTORE_STACK                                   \
    2816              :          : /*out*/   "=r" (_res)                                  \
    2817              :          : /*in*/    "r" (&_argvec[2])                            \
    2818              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2819              :       );                                                          \
    2820              :       lval = (__typeof__(lval)) _res;                             \
    2821              :    } while (0)
    2822              : 
    2823              : #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    2824              :    do {                                                           \
    2825              :       volatile OrigFn        _orig = (orig);                      \
    2826              :       volatile unsigned long _argvec[3+3];                        \
    2827              :       volatile unsigned long _res;                                \
    2828              :       /* _argvec[0] holds current r2 across the call */           \
    2829              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    2830              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    2831              :       _argvec[2+1] = (unsigned long)arg1;                         \
    2832              :       _argvec[2+2] = (unsigned long)arg2;                         \
    2833              :       _argvec[2+3] = (unsigned long)arg3;                         \
    2834              :       __asm__ volatile(                                           \
    2835              :          VALGRIND_ALIGN_STACK                                     \
    2836              :          "mr 11,%1\n\t"                                           \
    2837              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    2838              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    2839              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    2840              :          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
    2841              :          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
    2842              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    2843              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2844              :          "mr 11,%1\n\t"                                           \
    2845              :          "mr %0,3\n\t"                                            \
    2846              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    2847              :          VALGRIND_RESTORE_STACK                                   \
    2848              :          : /*out*/   "=r" (_res)                                  \
    2849              :          : /*in*/    "r" (&_argvec[2])                            \
    2850              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2851              :       );                                                          \
    2852              :       lval = (__typeof__(lval)) _res;                             \
    2853              :    } while (0)
    2854              : 
    2855              : #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
    2856              :    do {                                                           \
    2857              :       volatile OrigFn        _orig = (orig);                      \
    2858              :       volatile unsigned long _argvec[3+4];                        \
    2859              :       volatile unsigned long _res;                                \
    2860              :       /* _argvec[0] holds current r2 across the call */           \
    2861              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    2862              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    2863              :       _argvec[2+1] = (unsigned long)arg1;                         \
    2864              :       _argvec[2+2] = (unsigned long)arg2;                         \
    2865              :       _argvec[2+3] = (unsigned long)arg3;                         \
    2866              :       _argvec[2+4] = (unsigned long)arg4;                         \
    2867              :       __asm__ volatile(                                           \
    2868              :          VALGRIND_ALIGN_STACK                                     \
    2869              :          "mr 11,%1\n\t"                                           \
    2870              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    2871              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    2872              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    2873              :          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
    2874              :          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
    2875              :          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
    2876              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    2877              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2878              :          "mr 11,%1\n\t"                                           \
    2879              :          "mr %0,3\n\t"                                            \
    2880              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    2881              :          VALGRIND_RESTORE_STACK                                   \
    2882              :          : /*out*/   "=r" (_res)                                  \
    2883              :          : /*in*/    "r" (&_argvec[2])                            \
    2884              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2885              :       );                                                          \
    2886              :       lval = (__typeof__(lval)) _res;                             \
    2887              :    } while (0)
    2888              : 
    2889              : #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
    2890              :    do {                                                           \
    2891              :       volatile OrigFn        _orig = (orig);                      \
    2892              :       volatile unsigned long _argvec[3+5];                        \
    2893              :       volatile unsigned long _res;                                \
    2894              :       /* _argvec[0] holds current r2 across the call */           \
    2895              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    2896              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    2897              :       _argvec[2+1] = (unsigned long)arg1;                         \
    2898              :       _argvec[2+2] = (unsigned long)arg2;                         \
    2899              :       _argvec[2+3] = (unsigned long)arg3;                         \
    2900              :       _argvec[2+4] = (unsigned long)arg4;                         \
    2901              :       _argvec[2+5] = (unsigned long)arg5;                         \
    2902              :       __asm__ volatile(                                           \
    2903              :          VALGRIND_ALIGN_STACK                                     \
    2904              :          "mr 11,%1\n\t"                                           \
    2905              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    2906              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    2907              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    2908              :          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
    2909              :          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
    2910              :          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
    2911              :          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
    2912              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    2913              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2914              :          "mr 11,%1\n\t"                                           \
    2915              :          "mr %0,3\n\t"                                            \
    2916              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    2917              :          VALGRIND_RESTORE_STACK                                   \
    2918              :          : /*out*/   "=r" (_res)                                  \
    2919              :          : /*in*/    "r" (&_argvec[2])                            \
    2920              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2921              :       );                                                          \
    2922              :       lval = (__typeof__(lval)) _res;                             \
    2923              :    } while (0)
    2924              : 
    2925              : #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
    2926              :    do {                                                           \
    2927              :       volatile OrigFn        _orig = (orig);                      \
    2928              :       volatile unsigned long _argvec[3+6];                        \
    2929              :       volatile unsigned long _res;                                \
    2930              :       /* _argvec[0] holds current r2 across the call */           \
    2931              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    2932              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    2933              :       _argvec[2+1] = (unsigned long)arg1;                         \
    2934              :       _argvec[2+2] = (unsigned long)arg2;                         \
    2935              :       _argvec[2+3] = (unsigned long)arg3;                         \
    2936              :       _argvec[2+4] = (unsigned long)arg4;                         \
    2937              :       _argvec[2+5] = (unsigned long)arg5;                         \
    2938              :       _argvec[2+6] = (unsigned long)arg6;                         \
    2939              :       __asm__ volatile(                                           \
    2940              :          VALGRIND_ALIGN_STACK                                     \
    2941              :          "mr 11,%1\n\t"                                           \
    2942              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    2943              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    2944              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    2945              :          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
    2946              :          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
    2947              :          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
    2948              :          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
    2949              :          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
    2950              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    2951              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2952              :          "mr 11,%1\n\t"                                           \
    2953              :          "mr %0,3\n\t"                                            \
    2954              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    2955              :          VALGRIND_RESTORE_STACK                                   \
    2956              :          : /*out*/   "=r" (_res)                                  \
    2957              :          : /*in*/    "r" (&_argvec[2])                            \
    2958              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    2959              :       );                                                          \
    2960              :       lval = (__typeof__(lval)) _res;                             \
    2961              :    } while (0)
    2962              : 
    2963              : #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    2964              :                                  arg7)                            \
    2965              :    do {                                                           \
    2966              :       volatile OrigFn        _orig = (orig);                      \
    2967              :       volatile unsigned long _argvec[3+7];                        \
    2968              :       volatile unsigned long _res;                                \
    2969              :       /* _argvec[0] holds current r2 across the call */           \
    2970              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    2971              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    2972              :       _argvec[2+1] = (unsigned long)arg1;                         \
    2973              :       _argvec[2+2] = (unsigned long)arg2;                         \
    2974              :       _argvec[2+3] = (unsigned long)arg3;                         \
    2975              :       _argvec[2+4] = (unsigned long)arg4;                         \
    2976              :       _argvec[2+5] = (unsigned long)arg5;                         \
    2977              :       _argvec[2+6] = (unsigned long)arg6;                         \
    2978              :       _argvec[2+7] = (unsigned long)arg7;                         \
    2979              :       __asm__ volatile(                                           \
    2980              :          VALGRIND_ALIGN_STACK                                     \
    2981              :          "mr 11,%1\n\t"                                           \
    2982              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    2983              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    2984              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    2985              :          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
    2986              :          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
    2987              :          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
    2988              :          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
    2989              :          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
    2990              :          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
    2991              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    2992              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    2993              :          "mr 11,%1\n\t"                                           \
    2994              :          "mr %0,3\n\t"                                            \
    2995              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    2996              :          VALGRIND_RESTORE_STACK                                   \
    2997              :          : /*out*/   "=r" (_res)                                  \
    2998              :          : /*in*/    "r" (&_argvec[2])                            \
    2999              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3000              :       );                                                          \
    3001              :       lval = (__typeof__(lval)) _res;                             \
    3002              :    } while (0)
    3003              : 
    3004              : #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    3005              :                                  arg7,arg8)                       \
    3006              :    do {                                                           \
    3007              :       volatile OrigFn        _orig = (orig);                      \
    3008              :       volatile unsigned long _argvec[3+8];                        \
    3009              :       volatile unsigned long _res;                                \
    3010              :       /* _argvec[0] holds current r2 across the call */           \
    3011              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3012              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3013              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3014              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3015              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3016              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3017              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3018              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3019              :       _argvec[2+7] = (unsigned long)arg7;                         \
    3020              :       _argvec[2+8] = (unsigned long)arg8;                         \
    3021              :       __asm__ volatile(                                           \
    3022              :          VALGRIND_ALIGN_STACK                                     \
    3023              :          "mr 11,%1\n\t"                                           \
    3024              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    3025              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    3026              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    3027              :          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
    3028              :          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
    3029              :          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
    3030              :          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
    3031              :          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
    3032              :          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
    3033              :          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
    3034              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    3035              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    3036              :          "mr 11,%1\n\t"                                           \
    3037              :          "mr %0,3\n\t"                                            \
    3038              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    3039              :          VALGRIND_RESTORE_STACK                                   \
    3040              :          : /*out*/   "=r" (_res)                                  \
    3041              :          : /*in*/    "r" (&_argvec[2])                            \
    3042              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3043              :       );                                                          \
    3044              :       lval = (__typeof__(lval)) _res;                             \
    3045              :    } while (0)
    3046              : 
    3047              : #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    3048              :                                  arg7,arg8,arg9)                  \
    3049              :    do {                                                           \
    3050              :       volatile OrigFn        _orig = (orig);                      \
    3051              :       volatile unsigned long _argvec[3+9];                        \
    3052              :       volatile unsigned long _res;                                \
    3053              :       /* _argvec[0] holds current r2 across the call */           \
    3054              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3055              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3056              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3057              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3058              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3059              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3060              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3061              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3062              :       _argvec[2+7] = (unsigned long)arg7;                         \
    3063              :       _argvec[2+8] = (unsigned long)arg8;                         \
    3064              :       _argvec[2+9] = (unsigned long)arg9;                         \
    3065              :       __asm__ volatile(                                           \
    3066              :          VALGRIND_ALIGN_STACK                                     \
    3067              :          "mr 11,%1\n\t"                                           \
    3068              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    3069              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    3070              :          "addi 1,1,-128\n\t"  /* expand stack frame */            \
    3071              :          /* arg9 */                                               \
    3072              :          "ld  3,72(11)\n\t"                                       \
    3073              :          "std 3,112(1)\n\t"                                       \
    3074              :          /* args1-8 */                                            \
    3075              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    3076              :          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
    3077              :          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
    3078              :          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
    3079              :          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
    3080              :          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
    3081              :          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
    3082              :          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
    3083              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    3084              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    3085              :          "mr 11,%1\n\t"                                           \
    3086              :          "mr %0,3\n\t"                                            \
    3087              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    3088              :          VALGRIND_RESTORE_STACK                                   \
    3089              :          : /*out*/   "=r" (_res)                                  \
    3090              :          : /*in*/    "r" (&_argvec[2])                            \
    3091              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3092              :       );                                                          \
    3093              :       lval = (__typeof__(lval)) _res;                             \
    3094              :    } while (0)
    3095              : 
    3096              : #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    3097              :                                   arg7,arg8,arg9,arg10)           \
    3098              :    do {                                                           \
    3099              :       volatile OrigFn        _orig = (orig);                      \
    3100              :       volatile unsigned long _argvec[3+10];                       \
    3101              :       volatile unsigned long _res;                                \
    3102              :       /* _argvec[0] holds current r2 across the call */           \
    3103              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3104              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3105              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3106              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3107              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3108              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3109              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3110              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3111              :       _argvec[2+7] = (unsigned long)arg7;                         \
    3112              :       _argvec[2+8] = (unsigned long)arg8;                         \
    3113              :       _argvec[2+9] = (unsigned long)arg9;                         \
    3114              :       _argvec[2+10] = (unsigned long)arg10;                       \
    3115              :       __asm__ volatile(                                           \
    3116              :          VALGRIND_ALIGN_STACK                                     \
    3117              :          "mr 11,%1\n\t"                                           \
    3118              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    3119              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    3120              :          "addi 1,1,-128\n\t"  /* expand stack frame */            \
    3121              :          /* arg10 */                                              \
    3122              :          "ld  3,80(11)\n\t"                                       \
    3123              :          "std 3,120(1)\n\t"                                       \
    3124              :          /* arg9 */                                               \
    3125              :          "ld  3,72(11)\n\t"                                       \
    3126              :          "std 3,112(1)\n\t"                                       \
    3127              :          /* args1-8 */                                            \
    3128              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    3129              :          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
    3130              :          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
    3131              :          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
    3132              :          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
    3133              :          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
    3134              :          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
    3135              :          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
    3136              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    3137              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    3138              :          "mr 11,%1\n\t"                                           \
    3139              :          "mr %0,3\n\t"                                            \
    3140              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    3141              :          VALGRIND_RESTORE_STACK                                   \
    3142              :          : /*out*/   "=r" (_res)                                  \
    3143              :          : /*in*/    "r" (&_argvec[2])                            \
    3144              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3145              :       );                                                          \
    3146              :       lval = (__typeof__(lval)) _res;                             \
    3147              :    } while (0)
    3148              : 
    3149              : #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    3150              :                                   arg7,arg8,arg9,arg10,arg11)     \
    3151              :    do {                                                           \
    3152              :       volatile OrigFn        _orig = (orig);                      \
    3153              :       volatile unsigned long _argvec[3+11];                       \
    3154              :       volatile unsigned long _res;                                \
    3155              :       /* _argvec[0] holds current r2 across the call */           \
    3156              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3157              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3158              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3159              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3160              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3161              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3162              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3163              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3164              :       _argvec[2+7] = (unsigned long)arg7;                         \
    3165              :       _argvec[2+8] = (unsigned long)arg8;                         \
    3166              :       _argvec[2+9] = (unsigned long)arg9;                         \
    3167              :       _argvec[2+10] = (unsigned long)arg10;                       \
    3168              :       _argvec[2+11] = (unsigned long)arg11;                       \
    3169              :       __asm__ volatile(                                           \
    3170              :          VALGRIND_ALIGN_STACK                                     \
    3171              :          "mr 11,%1\n\t"                                           \
    3172              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    3173              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    3174              :          "addi 1,1,-144\n\t"  /* expand stack frame */            \
    3175              :          /* arg11 */                                              \
    3176              :          "ld  3,88(11)\n\t"                                       \
    3177              :          "std 3,128(1)\n\t"                                       \
    3178              :          /* arg10 */                                              \
    3179              :          "ld  3,80(11)\n\t"                                       \
    3180              :          "std 3,120(1)\n\t"                                       \
    3181              :          /* arg9 */                                               \
    3182              :          "ld  3,72(11)\n\t"                                       \
    3183              :          "std 3,112(1)\n\t"                                       \
    3184              :          /* args1-8 */                                            \
    3185              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    3186              :          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
    3187              :          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
    3188              :          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
    3189              :          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
    3190              :          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
    3191              :          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
    3192              :          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
    3193              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    3194              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    3195              :          "mr 11,%1\n\t"                                           \
    3196              :          "mr %0,3\n\t"                                            \
    3197              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    3198              :          VALGRIND_RESTORE_STACK                                   \
    3199              :          : /*out*/   "=r" (_res)                                  \
    3200              :          : /*in*/    "r" (&_argvec[2])                            \
    3201              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3202              :       );                                                          \
    3203              :       lval = (__typeof__(lval)) _res;                             \
    3204              :    } while (0)
    3205              : 
    3206              : #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    3207              :                                 arg7,arg8,arg9,arg10,arg11,arg12) \
    3208              :    do {                                                           \
    3209              :       volatile OrigFn        _orig = (orig);                      \
    3210              :       volatile unsigned long _argvec[3+12];                       \
    3211              :       volatile unsigned long _res;                                \
    3212              :       /* _argvec[0] holds current r2 across the call */           \
    3213              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3214              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3215              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3216              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3217              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3218              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3219              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3220              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3221              :       _argvec[2+7] = (unsigned long)arg7;                         \
    3222              :       _argvec[2+8] = (unsigned long)arg8;                         \
    3223              :       _argvec[2+9] = (unsigned long)arg9;                         \
    3224              :       _argvec[2+10] = (unsigned long)arg10;                       \
    3225              :       _argvec[2+11] = (unsigned long)arg11;                       \
    3226              :       _argvec[2+12] = (unsigned long)arg12;                       \
    3227              :       __asm__ volatile(                                           \
    3228              :          VALGRIND_ALIGN_STACK                                     \
    3229              :          "mr 11,%1\n\t"                                           \
    3230              :          "std 2,-16(11)\n\t"  /* save tocptr */                   \
    3231              :          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
    3232              :          "addi 1,1,-144\n\t"  /* expand stack frame */            \
    3233              :          /* arg12 */                                              \
    3234              :          "ld  3,96(11)\n\t"                                       \
    3235              :          "std 3,136(1)\n\t"                                       \
    3236              :          /* arg11 */                                              \
    3237              :          "ld  3,88(11)\n\t"                                       \
    3238              :          "std 3,128(1)\n\t"                                       \
    3239              :          /* arg10 */                                              \
    3240              :          "ld  3,80(11)\n\t"                                       \
    3241              :          "std 3,120(1)\n\t"                                       \
    3242              :          /* arg9 */                                               \
    3243              :          "ld  3,72(11)\n\t"                                       \
    3244              :          "std 3,112(1)\n\t"                                       \
    3245              :          /* args1-8 */                                            \
    3246              :          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
    3247              :          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
    3248              :          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
    3249              :          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
    3250              :          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
    3251              :          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
    3252              :          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
    3253              :          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
    3254              :          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
    3255              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
    3256              :          "mr 11,%1\n\t"                                           \
    3257              :          "mr %0,3\n\t"                                            \
    3258              :          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
    3259              :          VALGRIND_RESTORE_STACK                                   \
    3260              :          : /*out*/   "=r" (_res)                                  \
    3261              :          : /*in*/    "r" (&_argvec[2])                            \
    3262              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3263              :       );                                                          \
    3264              :       lval = (__typeof__(lval)) _res;                             \
    3265              :    } while (0)
    3266              : 
    3267              : #endif /* PLAT_ppc64be_linux */
    3268              : 
    3269              : /* ------------------------- ppc64le-linux ----------------------- */
    3270              : #if defined(PLAT_ppc64le_linux)
    3271              : 
    3272              : /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
    3273              : 
    3274              : /* These regs are trashed by the hidden call. */
    3275              : #define __CALLER_SAVED_REGS                                       \
    3276              :    "lr", "ctr", "xer",                                            \
    3277              :    "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
    3278              :    "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",         \
    3279              :    "r11", "r12", "r13"
    3280              : 
    3281              : /* Macros to save and align the stack before making a function
    3282              :    call and restore it afterwards as gcc may not keep the stack
    3283              :    pointer aligned if it doesn't realise calls are being made
    3284              :    to other functions. */
    3285              : 
    3286              : #define VALGRIND_ALIGN_STACK               \
    3287              :       "mr 28,1\n\t"                        \
    3288              :       "rldicr 1,1,0,59\n\t"
    3289              : #define VALGRIND_RESTORE_STACK             \
    3290              :       "mr 1,28\n\t"
    3291              : 
    3292              : /* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
    3293              :    long) == 8. */
    3294              : 
    3295              : #define CALL_FN_W_v(lval, orig)                                   \
    3296              :    do {                                                           \
    3297              :       volatile OrigFn        _orig = (orig);                      \
    3298              :       volatile unsigned long _argvec[3+0];                        \
    3299              :       volatile unsigned long _res;                                \
    3300              :       /* _argvec[0] holds current r2 across the call */           \
    3301              :       _argvec[1] = (unsigned long)_orig.r2;                       \
    3302              :       _argvec[2] = (unsigned long)_orig.nraddr;                   \
    3303              :       __asm__ volatile(                                           \
    3304              :          VALGRIND_ALIGN_STACK                                     \
    3305              :          "mr 12,%1\n\t"                                           \
    3306              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3307              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3308              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3309              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3310              :          "mr 12,%1\n\t"                                           \
    3311              :          "mr %0,3\n\t"                                            \
    3312              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3313              :          VALGRIND_RESTORE_STACK                                   \
    3314              :          : /*out*/   "=r" (_res)                                  \
    3315              :          : /*in*/    "r" (&_argvec[2])                            \
    3316              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3317              :       );                                                          \
    3318              :       lval = (__typeof__(lval)) _res;                             \
    3319              :    } while (0)
    3320              : 
    3321              : #define CALL_FN_W_W(lval, orig, arg1)                             \
    3322              :    do {                                                           \
    3323              :       volatile OrigFn        _orig = (orig);                      \
    3324              :       volatile unsigned long _argvec[3+1];                        \
    3325              :       volatile unsigned long _res;                                \
    3326              :       /* _argvec[0] holds current r2 across the call */           \
    3327              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3328              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3329              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3330              :       __asm__ volatile(                                           \
    3331              :          VALGRIND_ALIGN_STACK                                     \
    3332              :          "mr 12,%1\n\t"                                           \
    3333              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3334              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3335              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3336              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3337              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3338              :          "mr 12,%1\n\t"                                           \
    3339              :          "mr %0,3\n\t"                                            \
    3340              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3341              :          VALGRIND_RESTORE_STACK                                   \
    3342              :          : /*out*/   "=r" (_res)                                  \
    3343              :          : /*in*/    "r" (&_argvec[2])                            \
    3344              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3345              :       );                                                          \
    3346              :       lval = (__typeof__(lval)) _res;                             \
    3347              :    } while (0)
    3348              : 
    3349              : #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
    3350              :    do {                                                           \
    3351              :       volatile OrigFn        _orig = (orig);                      \
    3352              :       volatile unsigned long _argvec[3+2];                        \
    3353              :       volatile unsigned long _res;                                \
    3354              :       /* _argvec[0] holds current r2 across the call */           \
    3355              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3356              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3357              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3358              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3359              :       __asm__ volatile(                                           \
    3360              :          VALGRIND_ALIGN_STACK                                     \
    3361              :          "mr 12,%1\n\t"                                           \
    3362              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3363              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3364              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3365              :          "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
    3366              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3367              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3368              :          "mr 12,%1\n\t"                                           \
    3369              :          "mr %0,3\n\t"                                            \
    3370              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3371              :          VALGRIND_RESTORE_STACK                                   \
    3372              :          : /*out*/   "=r" (_res)                                  \
    3373              :          : /*in*/    "r" (&_argvec[2])                            \
    3374              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3375              :       );                                                          \
    3376              :       lval = (__typeof__(lval)) _res;                             \
    3377              :    } while (0)
    3378              : 
    3379              : #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    3380              :    do {                                                           \
    3381              :       volatile OrigFn        _orig = (orig);                      \
    3382              :       volatile unsigned long _argvec[3+3];                        \
    3383              :       volatile unsigned long _res;                                \
    3384              :       /* _argvec[0] holds current r2 across the call */           \
    3385              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3386              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3387              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3388              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3389              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3390              :       __asm__ volatile(                                           \
    3391              :          VALGRIND_ALIGN_STACK                                     \
    3392              :          "mr 12,%1\n\t"                                           \
    3393              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3394              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3395              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3396              :          "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
    3397              :          "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
    3398              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3399              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3400              :          "mr 12,%1\n\t"                                           \
    3401              :          "mr %0,3\n\t"                                            \
    3402              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3403              :          VALGRIND_RESTORE_STACK                                   \
    3404              :          : /*out*/   "=r" (_res)                                  \
    3405              :          : /*in*/    "r" (&_argvec[2])                            \
    3406              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3407              :       );                                                          \
    3408              :       lval = (__typeof__(lval)) _res;                             \
    3409              :    } while (0)
    3410              : 
    3411              : #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
    3412              :    do {                                                           \
    3413              :       volatile OrigFn        _orig = (orig);                      \
    3414              :       volatile unsigned long _argvec[3+4];                        \
    3415              :       volatile unsigned long _res;                                \
    3416              :       /* _argvec[0] holds current r2 across the call */           \
    3417              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3418              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3419              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3420              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3421              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3422              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3423              :       __asm__ volatile(                                           \
    3424              :          VALGRIND_ALIGN_STACK                                     \
    3425              :          "mr 12,%1\n\t"                                           \
    3426              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3427              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3428              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3429              :          "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
    3430              :          "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
    3431              :          "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
    3432              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3433              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3434              :          "mr 12,%1\n\t"                                           \
    3435              :          "mr %0,3\n\t"                                            \
    3436              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3437              :          VALGRIND_RESTORE_STACK                                   \
    3438              :          : /*out*/   "=r" (_res)                                  \
    3439              :          : /*in*/    "r" (&_argvec[2])                            \
    3440              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3441              :       );                                                          \
    3442              :       lval = (__typeof__(lval)) _res;                             \
    3443              :    } while (0)
    3444              : 
    3445              : #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
    3446              :    do {                                                           \
    3447              :       volatile OrigFn        _orig = (orig);                      \
    3448              :       volatile unsigned long _argvec[3+5];                        \
    3449              :       volatile unsigned long _res;                                \
    3450              :       /* _argvec[0] holds current r2 across the call */           \
    3451              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3452              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3453              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3454              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3455              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3456              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3457              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3458              :       __asm__ volatile(                                           \
    3459              :          VALGRIND_ALIGN_STACK                                     \
    3460              :          "mr 12,%1\n\t"                                           \
    3461              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3462              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3463              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3464              :          "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
    3465              :          "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
    3466              :          "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
    3467              :          "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
    3468              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3469              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3470              :          "mr 12,%1\n\t"                                           \
    3471              :          "mr %0,3\n\t"                                            \
    3472              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3473              :          VALGRIND_RESTORE_STACK                                   \
    3474              :          : /*out*/   "=r" (_res)                                  \
    3475              :          : /*in*/    "r" (&_argvec[2])                            \
    3476              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3477              :       );                                                          \
    3478              :       lval = (__typeof__(lval)) _res;                             \
    3479              :    } while (0)
    3480              : 
    3481              : #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
    3482              :    do {                                                           \
    3483              :       volatile OrigFn        _orig = (orig);                      \
    3484              :       volatile unsigned long _argvec[3+6];                        \
    3485              :       volatile unsigned long _res;                                \
    3486              :       /* _argvec[0] holds current r2 across the call */           \
    3487              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3488              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3489              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3490              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3491              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3492              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3493              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3494              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3495              :       __asm__ volatile(                                           \
    3496              :          VALGRIND_ALIGN_STACK                                     \
    3497              :          "mr 12,%1\n\t"                                           \
    3498              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3499              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3500              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3501              :          "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
    3502              :          "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
    3503              :          "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
    3504              :          "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
    3505              :          "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
    3506              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3507              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3508              :          "mr 12,%1\n\t"                                           \
    3509              :          "mr %0,3\n\t"                                            \
    3510              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3511              :          VALGRIND_RESTORE_STACK                                   \
    3512              :          : /*out*/   "=r" (_res)                                  \
    3513              :          : /*in*/    "r" (&_argvec[2])                            \
    3514              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3515              :       );                                                          \
    3516              :       lval = (__typeof__(lval)) _res;                             \
    3517              :    } while (0)
    3518              : 
    3519              : #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    3520              :                                  arg7)                            \
    3521              :    do {                                                           \
    3522              :       volatile OrigFn        _orig = (orig);                      \
    3523              :       volatile unsigned long _argvec[3+7];                        \
    3524              :       volatile unsigned long _res;                                \
    3525              :       /* _argvec[0] holds current r2 across the call */           \
    3526              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3527              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3528              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3529              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3530              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3531              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3532              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3533              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3534              :       _argvec[2+7] = (unsigned long)arg7;                         \
    3535              :       __asm__ volatile(                                           \
    3536              :          VALGRIND_ALIGN_STACK                                     \
    3537              :          "mr 12,%1\n\t"                                           \
    3538              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3539              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3540              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3541              :          "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
    3542              :          "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
    3543              :          "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
    3544              :          "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
    3545              :          "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
    3546              :          "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
    3547              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3548              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3549              :          "mr 12,%1\n\t"                                           \
    3550              :          "mr %0,3\n\t"                                            \
    3551              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3552              :          VALGRIND_RESTORE_STACK                                   \
    3553              :          : /*out*/   "=r" (_res)                                  \
    3554              :          : /*in*/    "r" (&_argvec[2])                            \
    3555              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3556              :       );                                                          \
    3557              :       lval = (__typeof__(lval)) _res;                             \
    3558              :    } while (0)
    3559              : 
    3560              : #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    3561              :                                  arg7,arg8)                       \
    3562              :    do {                                                           \
    3563              :       volatile OrigFn        _orig = (orig);                      \
    3564              :       volatile unsigned long _argvec[3+8];                        \
    3565              :       volatile unsigned long _res;                                \
    3566              :       /* _argvec[0] holds current r2 across the call */           \
    3567              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3568              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3569              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3570              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3571              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3572              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3573              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3574              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3575              :       _argvec[2+7] = (unsigned long)arg7;                         \
    3576              :       _argvec[2+8] = (unsigned long)arg8;                         \
    3577              :       __asm__ volatile(                                           \
    3578              :          VALGRIND_ALIGN_STACK                                     \
    3579              :          "mr 12,%1\n\t"                                           \
    3580              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3581              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3582              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3583              :          "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
    3584              :          "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
    3585              :          "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
    3586              :          "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
    3587              :          "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
    3588              :          "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
    3589              :          "ld  10, 64(12)\n\t" /* arg8->r10 */                     \
    3590              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3591              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3592              :          "mr 12,%1\n\t"                                           \
    3593              :          "mr %0,3\n\t"                                            \
    3594              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3595              :          VALGRIND_RESTORE_STACK                                   \
    3596              :          : /*out*/   "=r" (_res)                                  \
    3597              :          : /*in*/    "r" (&_argvec[2])                            \
    3598              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3599              :       );                                                          \
    3600              :       lval = (__typeof__(lval)) _res;                             \
    3601              :    } while (0)
    3602              : 
    3603              : #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    3604              :                                  arg7,arg8,arg9)                  \
    3605              :    do {                                                           \
    3606              :       volatile OrigFn        _orig = (orig);                      \
    3607              :       volatile unsigned long _argvec[3+9];                        \
    3608              :       volatile unsigned long _res;                                \
    3609              :       /* _argvec[0] holds current r2 across the call */           \
    3610              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3611              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3612              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3613              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3614              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3615              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3616              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3617              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3618              :       _argvec[2+7] = (unsigned long)arg7;                         \
    3619              :       _argvec[2+8] = (unsigned long)arg8;                         \
    3620              :       _argvec[2+9] = (unsigned long)arg9;                         \
    3621              :       __asm__ volatile(                                           \
    3622              :          VALGRIND_ALIGN_STACK                                     \
    3623              :          "mr 12,%1\n\t"                                           \
    3624              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3625              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3626              :          "addi 1,1,-128\n\t"  /* expand stack frame */            \
    3627              :          /* arg9 */                                               \
    3628              :          "ld  3,72(12)\n\t"                                       \
    3629              :          "std 3,96(1)\n\t"                                        \
    3630              :          /* args1-8 */                                            \
    3631              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3632              :          "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
    3633              :          "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
    3634              :          "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
    3635              :          "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
    3636              :          "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
    3637              :          "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
    3638              :          "ld  10, 64(12)\n\t" /* arg8->r10 */                     \
    3639              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3640              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3641              :          "mr 12,%1\n\t"                                           \
    3642              :          "mr %0,3\n\t"                                            \
    3643              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3644              :          VALGRIND_RESTORE_STACK                                   \
    3645              :          : /*out*/   "=r" (_res)                                  \
    3646              :          : /*in*/    "r" (&_argvec[2])                            \
    3647              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3648              :       );                                                          \
    3649              :       lval = (__typeof__(lval)) _res;                             \
    3650              :    } while (0)
    3651              : 
    3652              : #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    3653              :                                   arg7,arg8,arg9,arg10)           \
    3654              :    do {                                                           \
    3655              :       volatile OrigFn        _orig = (orig);                      \
    3656              :       volatile unsigned long _argvec[3+10];                       \
    3657              :       volatile unsigned long _res;                                \
    3658              :       /* _argvec[0] holds current r2 across the call */           \
    3659              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3660              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3661              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3662              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3663              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3664              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3665              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3666              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3667              :       _argvec[2+7] = (unsigned long)arg7;                         \
    3668              :       _argvec[2+8] = (unsigned long)arg8;                         \
    3669              :       _argvec[2+9] = (unsigned long)arg9;                         \
    3670              :       _argvec[2+10] = (unsigned long)arg10;                       \
    3671              :       __asm__ volatile(                                           \
    3672              :          VALGRIND_ALIGN_STACK                                     \
    3673              :          "mr 12,%1\n\t"                                           \
    3674              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3675              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3676              :          "addi 1,1,-128\n\t"  /* expand stack frame */            \
    3677              :          /* arg10 */                                              \
    3678              :          "ld  3,80(12)\n\t"                                       \
    3679              :          "std 3,104(1)\n\t"                                       \
    3680              :          /* arg9 */                                               \
    3681              :          "ld  3,72(12)\n\t"                                       \
    3682              :          "std 3,96(1)\n\t"                                        \
    3683              :          /* args1-8 */                                            \
    3684              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3685              :          "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
    3686              :          "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
    3687              :          "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
    3688              :          "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
    3689              :          "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
    3690              :          "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
    3691              :          "ld  10, 64(12)\n\t" /* arg8->r10 */                     \
    3692              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3693              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3694              :          "mr 12,%1\n\t"                                           \
    3695              :          "mr %0,3\n\t"                                            \
    3696              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3697              :          VALGRIND_RESTORE_STACK                                   \
    3698              :          : /*out*/   "=r" (_res)                                  \
    3699              :          : /*in*/    "r" (&_argvec[2])                            \
    3700              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3701              :       );                                                          \
    3702              :       lval = (__typeof__(lval)) _res;                             \
    3703              :    } while (0)
    3704              : 
    3705              : #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    3706              :                                   arg7,arg8,arg9,arg10,arg11)     \
    3707              :    do {                                                           \
    3708              :       volatile OrigFn        _orig = (orig);                      \
    3709              :       volatile unsigned long _argvec[3+11];                       \
    3710              :       volatile unsigned long _res;                                \
    3711              :       /* _argvec[0] holds current r2 across the call */           \
    3712              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3713              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3714              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3715              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3716              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3717              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3718              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3719              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3720              :       _argvec[2+7] = (unsigned long)arg7;                         \
    3721              :       _argvec[2+8] = (unsigned long)arg8;                         \
    3722              :       _argvec[2+9] = (unsigned long)arg9;                         \
    3723              :       _argvec[2+10] = (unsigned long)arg10;                       \
    3724              :       _argvec[2+11] = (unsigned long)arg11;                       \
    3725              :       __asm__ volatile(                                           \
    3726              :          VALGRIND_ALIGN_STACK                                     \
    3727              :          "mr 12,%1\n\t"                                           \
    3728              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3729              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3730              :          "addi 1,1,-144\n\t"  /* expand stack frame */            \
    3731              :          /* arg11 */                                              \
    3732              :          "ld  3,88(12)\n\t"                                       \
    3733              :          "std 3,112(1)\n\t"                                       \
    3734              :          /* arg10 */                                              \
    3735              :          "ld  3,80(12)\n\t"                                       \
    3736              :          "std 3,104(1)\n\t"                                       \
    3737              :          /* arg9 */                                               \
    3738              :          "ld  3,72(12)\n\t"                                       \
    3739              :          "std 3,96(1)\n\t"                                        \
    3740              :          /* args1-8 */                                            \
    3741              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3742              :          "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
    3743              :          "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
    3744              :          "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
    3745              :          "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
    3746              :          "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
    3747              :          "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
    3748              :          "ld  10, 64(12)\n\t" /* arg8->r10 */                     \
    3749              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3750              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3751              :          "mr 12,%1\n\t"                                           \
    3752              :          "mr %0,3\n\t"                                            \
    3753              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3754              :          VALGRIND_RESTORE_STACK                                   \
    3755              :          : /*out*/   "=r" (_res)                                  \
    3756              :          : /*in*/    "r" (&_argvec[2])                            \
    3757              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3758              :       );                                                          \
    3759              :       lval = (__typeof__(lval)) _res;                             \
    3760              :    } while (0)
    3761              : 
    3762              : #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    3763              :                                 arg7,arg8,arg9,arg10,arg11,arg12) \
    3764              :    do {                                                           \
    3765              :       volatile OrigFn        _orig = (orig);                      \
    3766              :       volatile unsigned long _argvec[3+12];                       \
    3767              :       volatile unsigned long _res;                                \
    3768              :       /* _argvec[0] holds current r2 across the call */           \
    3769              :       _argvec[1]   = (unsigned long)_orig.r2;                     \
    3770              :       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
    3771              :       _argvec[2+1] = (unsigned long)arg1;                         \
    3772              :       _argvec[2+2] = (unsigned long)arg2;                         \
    3773              :       _argvec[2+3] = (unsigned long)arg3;                         \
    3774              :       _argvec[2+4] = (unsigned long)arg4;                         \
    3775              :       _argvec[2+5] = (unsigned long)arg5;                         \
    3776              :       _argvec[2+6] = (unsigned long)arg6;                         \
    3777              :       _argvec[2+7] = (unsigned long)arg7;                         \
    3778              :       _argvec[2+8] = (unsigned long)arg8;                         \
    3779              :       _argvec[2+9] = (unsigned long)arg9;                         \
    3780              :       _argvec[2+10] = (unsigned long)arg10;                       \
    3781              :       _argvec[2+11] = (unsigned long)arg11;                       \
    3782              :       _argvec[2+12] = (unsigned long)arg12;                       \
    3783              :       __asm__ volatile(                                           \
    3784              :          VALGRIND_ALIGN_STACK                                     \
    3785              :          "mr 12,%1\n\t"                                           \
    3786              :          "std 2,-16(12)\n\t"  /* save tocptr */                   \
    3787              :          "ld   2,-8(12)\n\t"  /* use nraddr's tocptr */           \
    3788              :          "addi 1,1,-144\n\t"  /* expand stack frame */            \
    3789              :          /* arg12 */                                              \
    3790              :          "ld  3,96(12)\n\t"                                       \
    3791              :          "std 3,120(1)\n\t"                                       \
    3792              :          /* arg11 */                                              \
    3793              :          "ld  3,88(12)\n\t"                                       \
    3794              :          "std 3,112(1)\n\t"                                       \
    3795              :          /* arg10 */                                              \
    3796              :          "ld  3,80(12)\n\t"                                       \
    3797              :          "std 3,104(1)\n\t"                                       \
    3798              :          /* arg9 */                                               \
    3799              :          "ld  3,72(12)\n\t"                                       \
    3800              :          "std 3,96(1)\n\t"                                        \
    3801              :          /* args1-8 */                                            \
    3802              :          "ld   3, 8(12)\n\t"  /* arg1->r3 */                      \
    3803              :          "ld   4, 16(12)\n\t" /* arg2->r4 */                      \
    3804              :          "ld   5, 24(12)\n\t" /* arg3->r5 */                      \
    3805              :          "ld   6, 32(12)\n\t" /* arg4->r6 */                      \
    3806              :          "ld   7, 40(12)\n\t" /* arg5->r7 */                      \
    3807              :          "ld   8, 48(12)\n\t" /* arg6->r8 */                      \
    3808              :          "ld   9, 56(12)\n\t" /* arg7->r9 */                      \
    3809              :          "ld  10, 64(12)\n\t" /* arg8->r10 */                     \
    3810              :          "ld  12, 0(12)\n\t"  /* target->r12 */                   \
    3811              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12                  \
    3812              :          "mr 12,%1\n\t"                                           \
    3813              :          "mr %0,3\n\t"                                            \
    3814              :          "ld 2,-16(12)\n\t" /* restore tocptr */                  \
    3815              :          VALGRIND_RESTORE_STACK                                   \
    3816              :          : /*out*/   "=r" (_res)                                  \
    3817              :          : /*in*/    "r" (&_argvec[2])                            \
    3818              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28"   \
    3819              :       );                                                          \
    3820              :       lval = (__typeof__(lval)) _res;                             \
    3821              :    } while (0)
    3822              : 
    3823              : #endif /* PLAT_ppc64le_linux */
    3824              : 
    3825              : /* ------------------------- arm-linux ------------------------- */
    3826              : 
    3827              : #if defined(PLAT_arm_linux)
    3828              : 
    3829              : /* These regs are trashed by the hidden call. */
    3830              : #define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4", "r12", "r14"
    3831              : 
    3832              : /* Macros to save and align the stack before making a function
    3833              :    call and restore it afterwards as gcc may not keep the stack
    3834              :    pointer aligned if it doesn't realise calls are being made
    3835              :    to other functions. */
    3836              : 
    3837              : /* This is a bit tricky.  We store the original stack pointer in r10
    3838              :    as it is callee-saves.  gcc doesn't allow the use of r11 for some
    3839              :    reason.  Also, we can't directly "bic" the stack pointer in thumb
    3840              :    mode since r13 isn't an allowed register number in that context.
    3841              :    So use r4 as a temporary, since that is about to get trashed
    3842              :    anyway, just after each use of this macro.  Side effect is we need
    3843              :    to be very careful about any future changes, since
    3844              :    VALGRIND_ALIGN_STACK simply assumes r4 is usable. */
    3845              : #define VALGRIND_ALIGN_STACK               \
    3846              :       "mov r10, sp\n\t"                    \
    3847              :       "mov r4,  sp\n\t"                    \
    3848              :       "bic r4,  r4, #7\n\t"                \
    3849              :       "mov sp,  r4\n\t"
    3850              : #define VALGRIND_RESTORE_STACK             \
    3851              :       "mov sp,  r10\n\t"
    3852              : 
    3853              : /* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
    3854              :    long) == 4. */
    3855              : 
    3856              : #define CALL_FN_W_v(lval, orig)                                   \
    3857              :    do {                                                           \
    3858              :       volatile OrigFn        _orig = (orig);                      \
    3859              :       volatile unsigned long _argvec[1];                          \
    3860              :       volatile unsigned long _res;                                \
    3861              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    3862              :       __asm__ volatile(                                           \
    3863              :          VALGRIND_ALIGN_STACK                                     \
    3864              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    3865              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    3866              :          VALGRIND_RESTORE_STACK                                   \
    3867              :          "mov %0, r0\n"                                           \
    3868              :          : /*out*/   "=r" (_res)                                  \
    3869              :          : /*in*/    "0" (&_argvec[0])                            \
    3870              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    3871              :       );                                                          \
    3872              :       lval = (__typeof__(lval)) _res;                             \
    3873              :    } while (0)
    3874              : 
    3875              : #define CALL_FN_W_W(lval, orig, arg1)                             \
    3876              :    do {                                                           \
    3877              :       volatile OrigFn        _orig = (orig);                      \
    3878              :       volatile unsigned long _argvec[2];                          \
    3879              :       volatile unsigned long _res;                                \
    3880              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    3881              :       _argvec[1] = (unsigned long)(arg1);                         \
    3882              :       __asm__ volatile(                                           \
    3883              :          VALGRIND_ALIGN_STACK                                     \
    3884              :          "ldr r0, [%1, #4] \n\t"                                  \
    3885              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    3886              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    3887              :          VALGRIND_RESTORE_STACK                                   \
    3888              :          "mov %0, r0\n"                                           \
    3889              :          : /*out*/   "=r" (_res)                                  \
    3890              :          : /*in*/    "0" (&_argvec[0])                            \
    3891              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    3892              :       );                                                          \
    3893              :       lval = (__typeof__(lval)) _res;                             \
    3894              :    } while (0)
    3895              : 
    3896              : #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
    3897              :    do {                                                           \
    3898              :       volatile OrigFn        _orig = (orig);                      \
    3899              :       volatile unsigned long _argvec[3];                          \
    3900              :       volatile unsigned long _res;                                \
    3901              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    3902              :       _argvec[1] = (unsigned long)(arg1);                         \
    3903              :       _argvec[2] = (unsigned long)(arg2);                         \
    3904              :       __asm__ volatile(                                           \
    3905              :          VALGRIND_ALIGN_STACK                                     \
    3906              :          "ldr r0, [%1, #4] \n\t"                                  \
    3907              :          "ldr r1, [%1, #8] \n\t"                                  \
    3908              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    3909              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    3910              :          VALGRIND_RESTORE_STACK                                   \
    3911              :          "mov %0, r0\n"                                           \
    3912              :          : /*out*/   "=r" (_res)                                  \
    3913              :          : /*in*/    "0" (&_argvec[0])                            \
    3914              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    3915              :       );                                                          \
    3916              :       lval = (__typeof__(lval)) _res;                             \
    3917              :    } while (0)
    3918              : 
    3919              : #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    3920              :    do {                                                           \
    3921              :       volatile OrigFn        _orig = (orig);                      \
    3922              :       volatile unsigned long _argvec[4];                          \
    3923              :       volatile unsigned long _res;                                \
    3924              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    3925              :       _argvec[1] = (unsigned long)(arg1);                         \
    3926              :       _argvec[2] = (unsigned long)(arg2);                         \
    3927              :       _argvec[3] = (unsigned long)(arg3);                         \
    3928              :       __asm__ volatile(                                           \
    3929              :          VALGRIND_ALIGN_STACK                                     \
    3930              :          "ldr r0, [%1, #4] \n\t"                                  \
    3931              :          "ldr r1, [%1, #8] \n\t"                                  \
    3932              :          "ldr r2, [%1, #12] \n\t"                                 \
    3933              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    3934              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    3935              :          VALGRIND_RESTORE_STACK                                   \
    3936              :          "mov %0, r0\n"                                           \
    3937              :          : /*out*/   "=r" (_res)                                  \
    3938              :          : /*in*/    "0" (&_argvec[0])                            \
    3939              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    3940              :       );                                                          \
    3941              :       lval = (__typeof__(lval)) _res;                             \
    3942              :    } while (0)
    3943              : 
    3944              : #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
    3945              :    do {                                                           \
    3946              :       volatile OrigFn        _orig = (orig);                      \
    3947              :       volatile unsigned long _argvec[5];                          \
    3948              :       volatile unsigned long _res;                                \
    3949              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    3950              :       _argvec[1] = (unsigned long)(arg1);                         \
    3951              :       _argvec[2] = (unsigned long)(arg2);                         \
    3952              :       _argvec[3] = (unsigned long)(arg3);                         \
    3953              :       _argvec[4] = (unsigned long)(arg4);                         \
    3954              :       __asm__ volatile(                                           \
    3955              :          VALGRIND_ALIGN_STACK                                     \
    3956              :          "ldr r0, [%1, #4] \n\t"                                  \
    3957              :          "ldr r1, [%1, #8] \n\t"                                  \
    3958              :          "ldr r2, [%1, #12] \n\t"                                 \
    3959              :          "ldr r3, [%1, #16] \n\t"                                 \
    3960              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    3961              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    3962              :          VALGRIND_RESTORE_STACK                                   \
    3963              :          "mov %0, r0"                                             \
    3964              :          : /*out*/   "=r" (_res)                                  \
    3965              :          : /*in*/    "0" (&_argvec[0])                            \
    3966              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    3967              :       );                                                          \
    3968              :       lval = (__typeof__(lval)) _res;                             \
    3969              :    } while (0)
    3970              : 
    3971              : #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
    3972              :    do {                                                           \
    3973              :       volatile OrigFn        _orig = (orig);                      \
    3974              :       volatile unsigned long _argvec[6];                          \
    3975              :       volatile unsigned long _res;                                \
    3976              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    3977              :       _argvec[1] = (unsigned long)(arg1);                         \
    3978              :       _argvec[2] = (unsigned long)(arg2);                         \
    3979              :       _argvec[3] = (unsigned long)(arg3);                         \
    3980              :       _argvec[4] = (unsigned long)(arg4);                         \
    3981              :       _argvec[5] = (unsigned long)(arg5);                         \
    3982              :       __asm__ volatile(                                           \
    3983              :          VALGRIND_ALIGN_STACK                                     \
    3984              :          "sub sp, sp, #4 \n\t"                                    \
    3985              :          "ldr r0, [%1, #20] \n\t"                                 \
    3986              :          "push {r0} \n\t"                                         \
    3987              :          "ldr r0, [%1, #4] \n\t"                                  \
    3988              :          "ldr r1, [%1, #8] \n\t"                                  \
    3989              :          "ldr r2, [%1, #12] \n\t"                                 \
    3990              :          "ldr r3, [%1, #16] \n\t"                                 \
    3991              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    3992              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    3993              :          VALGRIND_RESTORE_STACK                                   \
    3994              :          "mov %0, r0"                                             \
    3995              :          : /*out*/   "=r" (_res)                                  \
    3996              :          : /*in*/    "0" (&_argvec[0])                            \
    3997              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    3998              :       );                                                          \
    3999              :       lval = (__typeof__(lval)) _res;                             \
    4000              :    } while (0)
    4001              : 
    4002              : #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
    4003              :    do {                                                           \
    4004              :       volatile OrigFn        _orig = (orig);                      \
    4005              :       volatile unsigned long _argvec[7];                          \
    4006              :       volatile unsigned long _res;                                \
    4007              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4008              :       _argvec[1] = (unsigned long)(arg1);                         \
    4009              :       _argvec[2] = (unsigned long)(arg2);                         \
    4010              :       _argvec[3] = (unsigned long)(arg3);                         \
    4011              :       _argvec[4] = (unsigned long)(arg4);                         \
    4012              :       _argvec[5] = (unsigned long)(arg5);                         \
    4013              :       _argvec[6] = (unsigned long)(arg6);                         \
    4014              :       __asm__ volatile(                                           \
    4015              :          VALGRIND_ALIGN_STACK                                     \
    4016              :          "ldr r0, [%1, #20] \n\t"                                 \
    4017              :          "ldr r1, [%1, #24] \n\t"                                 \
    4018              :          "push {r0, r1} \n\t"                                     \
    4019              :          "ldr r0, [%1, #4] \n\t"                                  \
    4020              :          "ldr r1, [%1, #8] \n\t"                                  \
    4021              :          "ldr r2, [%1, #12] \n\t"                                 \
    4022              :          "ldr r3, [%1, #16] \n\t"                                 \
    4023              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    4024              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    4025              :          VALGRIND_RESTORE_STACK                                   \
    4026              :          "mov %0, r0"                                             \
    4027              :          : /*out*/   "=r" (_res)                                  \
    4028              :          : /*in*/    "0" (&_argvec[0])                            \
    4029              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    4030              :       );                                                          \
    4031              :       lval = (__typeof__(lval)) _res;                             \
    4032              :    } while (0)
    4033              : 
    4034              : #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    4035              :                                  arg7)                            \
    4036              :    do {                                                           \
    4037              :       volatile OrigFn        _orig = (orig);                      \
    4038              :       volatile unsigned long _argvec[8];                          \
    4039              :       volatile unsigned long _res;                                \
    4040              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4041              :       _argvec[1] = (unsigned long)(arg1);                         \
    4042              :       _argvec[2] = (unsigned long)(arg2);                         \
    4043              :       _argvec[3] = (unsigned long)(arg3);                         \
    4044              :       _argvec[4] = (unsigned long)(arg4);                         \
    4045              :       _argvec[5] = (unsigned long)(arg5);                         \
    4046              :       _argvec[6] = (unsigned long)(arg6);                         \
    4047              :       _argvec[7] = (unsigned long)(arg7);                         \
    4048              :       __asm__ volatile(                                           \
    4049              :          VALGRIND_ALIGN_STACK                                     \
    4050              :          "sub sp, sp, #4 \n\t"                                    \
    4051              :          "ldr r0, [%1, #20] \n\t"                                 \
    4052              :          "ldr r1, [%1, #24] \n\t"                                 \
    4053              :          "ldr r2, [%1, #28] \n\t"                                 \
    4054              :          "push {r0, r1, r2} \n\t"                                 \
    4055              :          "ldr r0, [%1, #4] \n\t"                                  \
    4056              :          "ldr r1, [%1, #8] \n\t"                                  \
    4057              :          "ldr r2, [%1, #12] \n\t"                                 \
    4058              :          "ldr r3, [%1, #16] \n\t"                                 \
    4059              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    4060              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    4061              :          VALGRIND_RESTORE_STACK                                   \
    4062              :          "mov %0, r0"                                             \
    4063              :          : /*out*/   "=r" (_res)                                  \
    4064              :          : /*in*/    "0" (&_argvec[0])                            \
    4065              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    4066              :       );                                                          \
    4067              :       lval = (__typeof__(lval)) _res;                             \
    4068              :    } while (0)
    4069              : 
    4070              : #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    4071              :                                  arg7,arg8)                       \
    4072              :    do {                                                           \
    4073              :       volatile OrigFn        _orig = (orig);                      \
    4074              :       volatile unsigned long _argvec[9];                          \
    4075              :       volatile unsigned long _res;                                \
    4076              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4077              :       _argvec[1] = (unsigned long)(arg1);                         \
    4078              :       _argvec[2] = (unsigned long)(arg2);                         \
    4079              :       _argvec[3] = (unsigned long)(arg3);                         \
    4080              :       _argvec[4] = (unsigned long)(arg4);                         \
    4081              :       _argvec[5] = (unsigned long)(arg5);                         \
    4082              :       _argvec[6] = (unsigned long)(arg6);                         \
    4083              :       _argvec[7] = (unsigned long)(arg7);                         \
    4084              :       _argvec[8] = (unsigned long)(arg8);                         \
    4085              :       __asm__ volatile(                                           \
    4086              :          VALGRIND_ALIGN_STACK                                     \
    4087              :          "ldr r0, [%1, #20] \n\t"                                 \
    4088              :          "ldr r1, [%1, #24] \n\t"                                 \
    4089              :          "ldr r2, [%1, #28] \n\t"                                 \
    4090              :          "ldr r3, [%1, #32] \n\t"                                 \
    4091              :          "push {r0, r1, r2, r3} \n\t"                             \
    4092              :          "ldr r0, [%1, #4] \n\t"                                  \
    4093              :          "ldr r1, [%1, #8] \n\t"                                  \
    4094              :          "ldr r2, [%1, #12] \n\t"                                 \
    4095              :          "ldr r3, [%1, #16] \n\t"                                 \
    4096              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    4097              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    4098              :          VALGRIND_RESTORE_STACK                                   \
    4099              :          "mov %0, r0"                                             \
    4100              :          : /*out*/   "=r" (_res)                                  \
    4101              :          : /*in*/    "0" (&_argvec[0])                            \
    4102              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    4103              :       );                                                          \
    4104              :       lval = (__typeof__(lval)) _res;                             \
    4105              :    } while (0)
    4106              : 
    4107              : #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    4108              :                                  arg7,arg8,arg9)                  \
    4109              :    do {                                                           \
    4110              :       volatile OrigFn        _orig = (orig);                      \
    4111              :       volatile unsigned long _argvec[10];                         \
    4112              :       volatile unsigned long _res;                                \
    4113              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4114              :       _argvec[1] = (unsigned long)(arg1);                         \
    4115              :       _argvec[2] = (unsigned long)(arg2);                         \
    4116              :       _argvec[3] = (unsigned long)(arg3);                         \
    4117              :       _argvec[4] = (unsigned long)(arg4);                         \
    4118              :       _argvec[5] = (unsigned long)(arg5);                         \
    4119              :       _argvec[6] = (unsigned long)(arg6);                         \
    4120              :       _argvec[7] = (unsigned long)(arg7);                         \
    4121              :       _argvec[8] = (unsigned long)(arg8);                         \
    4122              :       _argvec[9] = (unsigned long)(arg9);                         \
    4123              :       __asm__ volatile(                                           \
    4124              :          VALGRIND_ALIGN_STACK                                     \
    4125              :          "sub sp, sp, #4 \n\t"                                    \
    4126              :          "ldr r0, [%1, #20] \n\t"                                 \
    4127              :          "ldr r1, [%1, #24] \n\t"                                 \
    4128              :          "ldr r2, [%1, #28] \n\t"                                 \
    4129              :          "ldr r3, [%1, #32] \n\t"                                 \
    4130              :          "ldr r4, [%1, #36] \n\t"                                 \
    4131              :          "push {r0, r1, r2, r3, r4} \n\t"                         \
    4132              :          "ldr r0, [%1, #4] \n\t"                                  \
    4133              :          "ldr r1, [%1, #8] \n\t"                                  \
    4134              :          "ldr r2, [%1, #12] \n\t"                                 \
    4135              :          "ldr r3, [%1, #16] \n\t"                                 \
    4136              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    4137              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    4138              :          VALGRIND_RESTORE_STACK                                   \
    4139              :          "mov %0, r0"                                             \
    4140              :          : /*out*/   "=r" (_res)                                  \
    4141              :          : /*in*/    "0" (&_argvec[0])                            \
    4142              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    4143              :       );                                                          \
    4144              :       lval = (__typeof__(lval)) _res;                             \
    4145              :    } while (0)
    4146              : 
    4147              : #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    4148              :                                   arg7,arg8,arg9,arg10)           \
    4149              :    do {                                                           \
    4150              :       volatile OrigFn        _orig = (orig);                      \
    4151              :       volatile unsigned long _argvec[11];                         \
    4152              :       volatile unsigned long _res;                                \
    4153              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4154              :       _argvec[1] = (unsigned long)(arg1);                         \
    4155              :       _argvec[2] = (unsigned long)(arg2);                         \
    4156              :       _argvec[3] = (unsigned long)(arg3);                         \
    4157              :       _argvec[4] = (unsigned long)(arg4);                         \
    4158              :       _argvec[5] = (unsigned long)(arg5);                         \
    4159              :       _argvec[6] = (unsigned long)(arg6);                         \
    4160              :       _argvec[7] = (unsigned long)(arg7);                         \
    4161              :       _argvec[8] = (unsigned long)(arg8);                         \
    4162              :       _argvec[9] = (unsigned long)(arg9);                         \
    4163              :       _argvec[10] = (unsigned long)(arg10);                       \
    4164              :       __asm__ volatile(                                           \
    4165              :          VALGRIND_ALIGN_STACK                                     \
    4166              :          "ldr r0, [%1, #40] \n\t"                                 \
    4167              :          "push {r0} \n\t"                                         \
    4168              :          "ldr r0, [%1, #20] \n\t"                                 \
    4169              :          "ldr r1, [%1, #24] \n\t"                                 \
    4170              :          "ldr r2, [%1, #28] \n\t"                                 \
    4171              :          "ldr r3, [%1, #32] \n\t"                                 \
    4172              :          "ldr r4, [%1, #36] \n\t"                                 \
    4173              :          "push {r0, r1, r2, r3, r4} \n\t"                         \
    4174              :          "ldr r0, [%1, #4] \n\t"                                  \
    4175              :          "ldr r1, [%1, #8] \n\t"                                  \
    4176              :          "ldr r2, [%1, #12] \n\t"                                 \
    4177              :          "ldr r3, [%1, #16] \n\t"                                 \
    4178              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    4179              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    4180              :          VALGRIND_RESTORE_STACK                                   \
    4181              :          "mov %0, r0"                                             \
    4182              :          : /*out*/   "=r" (_res)                                  \
    4183              :          : /*in*/    "0" (&_argvec[0])                            \
    4184              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    4185              :       );                                                          \
    4186              :       lval = (__typeof__(lval)) _res;                             \
    4187              :    } while (0)
    4188              : 
    4189              : #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
    4190              :                                   arg6,arg7,arg8,arg9,arg10,      \
    4191              :                                   arg11)                          \
    4192              :    do {                                                           \
    4193              :       volatile OrigFn        _orig = (orig);                      \
    4194              :       volatile unsigned long _argvec[12];                         \
    4195              :       volatile unsigned long _res;                                \
    4196              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4197              :       _argvec[1] = (unsigned long)(arg1);                         \
    4198              :       _argvec[2] = (unsigned long)(arg2);                         \
    4199              :       _argvec[3] = (unsigned long)(arg3);                         \
    4200              :       _argvec[4] = (unsigned long)(arg4);                         \
    4201              :       _argvec[5] = (unsigned long)(arg5);                         \
    4202              :       _argvec[6] = (unsigned long)(arg6);                         \
    4203              :       _argvec[7] = (unsigned long)(arg7);                         \
    4204              :       _argvec[8] = (unsigned long)(arg8);                         \
    4205              :       _argvec[9] = (unsigned long)(arg9);                         \
    4206              :       _argvec[10] = (unsigned long)(arg10);                       \
    4207              :       _argvec[11] = (unsigned long)(arg11);                       \
    4208              :       __asm__ volatile(                                           \
    4209              :          VALGRIND_ALIGN_STACK                                     \
    4210              :          "sub sp, sp, #4 \n\t"                                    \
    4211              :          "ldr r0, [%1, #40] \n\t"                                 \
    4212              :          "ldr r1, [%1, #44] \n\t"                                 \
    4213              :          "push {r0, r1} \n\t"                                     \
    4214              :          "ldr r0, [%1, #20] \n\t"                                 \
    4215              :          "ldr r1, [%1, #24] \n\t"                                 \
    4216              :          "ldr r2, [%1, #28] \n\t"                                 \
    4217              :          "ldr r3, [%1, #32] \n\t"                                 \
    4218              :          "ldr r4, [%1, #36] \n\t"                                 \
    4219              :          "push {r0, r1, r2, r3, r4} \n\t"                         \
    4220              :          "ldr r0, [%1, #4] \n\t"                                  \
    4221              :          "ldr r1, [%1, #8] \n\t"                                  \
    4222              :          "ldr r2, [%1, #12] \n\t"                                 \
    4223              :          "ldr r3, [%1, #16] \n\t"                                 \
    4224              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    4225              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    4226              :          VALGRIND_RESTORE_STACK                                   \
    4227              :          "mov %0, r0"                                             \
    4228              :          : /*out*/   "=r" (_res)                                  \
    4229              :          : /*in*/    "0" (&_argvec[0])                            \
    4230              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    4231              :       );                                                          \
    4232              :       lval = (__typeof__(lval)) _res;                             \
    4233              :    } while (0)
    4234              : 
    4235              : #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
    4236              :                                   arg6,arg7,arg8,arg9,arg10,      \
    4237              :                                   arg11,arg12)                    \
    4238              :    do {                                                           \
    4239              :       volatile OrigFn        _orig = (orig);                      \
    4240              :       volatile unsigned long _argvec[13];                         \
    4241              :       volatile unsigned long _res;                                \
    4242              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4243              :       _argvec[1] = (unsigned long)(arg1);                         \
    4244              :       _argvec[2] = (unsigned long)(arg2);                         \
    4245              :       _argvec[3] = (unsigned long)(arg3);                         \
    4246              :       _argvec[4] = (unsigned long)(arg4);                         \
    4247              :       _argvec[5] = (unsigned long)(arg5);                         \
    4248              :       _argvec[6] = (unsigned long)(arg6);                         \
    4249              :       _argvec[7] = (unsigned long)(arg7);                         \
    4250              :       _argvec[8] = (unsigned long)(arg8);                         \
    4251              :       _argvec[9] = (unsigned long)(arg9);                         \
    4252              :       _argvec[10] = (unsigned long)(arg10);                       \
    4253              :       _argvec[11] = (unsigned long)(arg11);                       \
    4254              :       _argvec[12] = (unsigned long)(arg12);                       \
    4255              :       __asm__ volatile(                                           \
    4256              :          VALGRIND_ALIGN_STACK                                     \
    4257              :          "ldr r0, [%1, #40] \n\t"                                 \
    4258              :          "ldr r1, [%1, #44] \n\t"                                 \
    4259              :          "ldr r2, [%1, #48] \n\t"                                 \
    4260              :          "push {r0, r1, r2} \n\t"                                 \
    4261              :          "ldr r0, [%1, #20] \n\t"                                 \
    4262              :          "ldr r1, [%1, #24] \n\t"                                 \
    4263              :          "ldr r2, [%1, #28] \n\t"                                 \
    4264              :          "ldr r3, [%1, #32] \n\t"                                 \
    4265              :          "ldr r4, [%1, #36] \n\t"                                 \
    4266              :          "push {r0, r1, r2, r3, r4} \n\t"                         \
    4267              :          "ldr r0, [%1, #4] \n\t"                                  \
    4268              :          "ldr r1, [%1, #8] \n\t"                                  \
    4269              :          "ldr r2, [%1, #12] \n\t"                                 \
    4270              :          "ldr r3, [%1, #16] \n\t"                                 \
    4271              :          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
    4272              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
    4273              :          VALGRIND_RESTORE_STACK                                   \
    4274              :          "mov %0, r0"                                             \
    4275              :          : /*out*/   "=r" (_res)                                  \
    4276              :          : /*in*/    "0" (&_argvec[0])                            \
    4277              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r10"   \
    4278              :       );                                                          \
    4279              :       lval = (__typeof__(lval)) _res;                             \
    4280              :    } while (0)
    4281              : 
    4282              : #endif /* PLAT_arm_linux */
    4283              : 
    4284              : /* ------------------------ arm64-linux ------------------------ */
    4285              : 
    4286              : #if defined(PLAT_arm64_linux)
    4287              : 
    4288              : /* These regs are trashed by the hidden call. */
    4289              : #define __CALLER_SAVED_REGS \
    4290              :      "x0", "x1", "x2", "x3","x4", "x5", "x6", "x7", "x8", "x9",   \
    4291              :      "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17",      \
    4292              :      "x18", "x19", "x20", "x30",                                  \
    4293              :      "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",  \
    4294              :      "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17",      \
    4295              :      "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25",      \
    4296              :      "v26", "v27", "v28", "v29", "v30", "v31"
    4297              : 
    4298              : /* x21 is callee-saved, so we can use it to save and restore SP around
    4299              :    the hidden call. */
    4300              : #define VALGRIND_ALIGN_STACK               \
    4301              :       "mov x21, sp\n\t"                    \
    4302              :       "bic sp, x21, #15\n\t"
    4303              : #define VALGRIND_RESTORE_STACK             \
    4304              :       "mov sp,  x21\n\t"
    4305              : 
    4306              : /* These CALL_FN_ macros assume that on arm64-linux,
    4307              :    sizeof(unsigned long) == 8. */
    4308              : 
    4309              : #define CALL_FN_W_v(lval, orig)                                   \
    4310              :    do {                                                           \
    4311              :       volatile OrigFn        _orig = (orig);                      \
    4312              :       volatile unsigned long _argvec[1];                          \
    4313              :       volatile unsigned long _res;                                \
    4314              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4315              :       __asm__ volatile(                                           \
    4316              :          VALGRIND_ALIGN_STACK                                     \
    4317              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4318              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4319              :          VALGRIND_RESTORE_STACK                                   \
    4320              :          "mov %0, x0\n"                                           \
    4321              :          : /*out*/   "=r" (_res)                                  \
    4322              :          : /*in*/    "0" (&_argvec[0])                            \
    4323              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4324              :       );                                                          \
    4325              :       lval = (__typeof__(lval)) _res;                             \
    4326              :    } while (0)
    4327              : 
    4328              : #define CALL_FN_W_W(lval, orig, arg1)                             \
    4329              :    do {                                                           \
    4330              :       volatile OrigFn        _orig = (orig);                      \
    4331              :       volatile unsigned long _argvec[2];                          \
    4332              :       volatile unsigned long _res;                                \
    4333              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4334              :       _argvec[1] = (unsigned long)(arg1);                         \
    4335              :       __asm__ volatile(                                           \
    4336              :          VALGRIND_ALIGN_STACK                                     \
    4337              :          "ldr x0, [%1, #8] \n\t"                                  \
    4338              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4339              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4340              :          VALGRIND_RESTORE_STACK                                   \
    4341              :          "mov %0, x0\n"                                           \
    4342              :          : /*out*/   "=r" (_res)                                  \
    4343              :          : /*in*/    "0" (&_argvec[0])                            \
    4344              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4345              :       );                                                          \
    4346              :       lval = (__typeof__(lval)) _res;                             \
    4347              :    } while (0)
    4348              : 
    4349              : #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
    4350              :    do {                                                           \
    4351              :       volatile OrigFn        _orig = (orig);                      \
    4352              :       volatile unsigned long _argvec[3];                          \
    4353              :       volatile unsigned long _res;                                \
    4354              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4355              :       _argvec[1] = (unsigned long)(arg1);                         \
    4356              :       _argvec[2] = (unsigned long)(arg2);                         \
    4357              :       __asm__ volatile(                                           \
    4358              :          VALGRIND_ALIGN_STACK                                     \
    4359              :          "ldr x0, [%1, #8] \n\t"                                  \
    4360              :          "ldr x1, [%1, #16] \n\t"                                 \
    4361              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4362              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4363              :          VALGRIND_RESTORE_STACK                                   \
    4364              :          "mov %0, x0\n"                                           \
    4365              :          : /*out*/   "=r" (_res)                                  \
    4366              :          : /*in*/    "0" (&_argvec[0])                            \
    4367              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4368              :       );                                                          \
    4369              :       lval = (__typeof__(lval)) _res;                             \
    4370              :    } while (0)
    4371              : 
    4372              : #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    4373              :    do {                                                           \
    4374              :       volatile OrigFn        _orig = (orig);                      \
    4375              :       volatile unsigned long _argvec[4];                          \
    4376              :       volatile unsigned long _res;                                \
    4377              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4378              :       _argvec[1] = (unsigned long)(arg1);                         \
    4379              :       _argvec[2] = (unsigned long)(arg2);                         \
    4380              :       _argvec[3] = (unsigned long)(arg3);                         \
    4381              :       __asm__ volatile(                                           \
    4382              :          VALGRIND_ALIGN_STACK                                     \
    4383              :          "ldr x0, [%1, #8] \n\t"                                  \
    4384              :          "ldr x1, [%1, #16] \n\t"                                 \
    4385              :          "ldr x2, [%1, #24] \n\t"                                 \
    4386              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4387              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4388              :          VALGRIND_RESTORE_STACK                                   \
    4389              :          "mov %0, x0\n"                                           \
    4390              :          : /*out*/   "=r" (_res)                                  \
    4391              :          : /*in*/    "0" (&_argvec[0])                            \
    4392              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4393              :       );                                                          \
    4394              :       lval = (__typeof__(lval)) _res;                             \
    4395              :    } while (0)
    4396              : 
    4397              : #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
    4398              :    do {                                                           \
    4399              :       volatile OrigFn        _orig = (orig);                      \
    4400              :       volatile unsigned long _argvec[5];                          \
    4401              :       volatile unsigned long _res;                                \
    4402              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4403              :       _argvec[1] = (unsigned long)(arg1);                         \
    4404              :       _argvec[2] = (unsigned long)(arg2);                         \
    4405              :       _argvec[3] = (unsigned long)(arg3);                         \
    4406              :       _argvec[4] = (unsigned long)(arg4);                         \
    4407              :       __asm__ volatile(                                           \
    4408              :          VALGRIND_ALIGN_STACK                                     \
    4409              :          "ldr x0, [%1, #8] \n\t"                                  \
    4410              :          "ldr x1, [%1, #16] \n\t"                                 \
    4411              :          "ldr x2, [%1, #24] \n\t"                                 \
    4412              :          "ldr x3, [%1, #32] \n\t"                                 \
    4413              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4414              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4415              :          VALGRIND_RESTORE_STACK                                   \
    4416              :          "mov %0, x0"                                             \
    4417              :          : /*out*/   "=r" (_res)                                  \
    4418              :          : /*in*/    "0" (&_argvec[0])                            \
    4419              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4420              :       );                                                          \
    4421              :       lval = (__typeof__(lval)) _res;                             \
    4422              :    } while (0)
    4423              : 
    4424              : #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
    4425              :    do {                                                           \
    4426              :       volatile OrigFn        _orig = (orig);                      \
    4427              :       volatile unsigned long _argvec[6];                          \
    4428              :       volatile unsigned long _res;                                \
    4429              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4430              :       _argvec[1] = (unsigned long)(arg1);                         \
    4431              :       _argvec[2] = (unsigned long)(arg2);                         \
    4432              :       _argvec[3] = (unsigned long)(arg3);                         \
    4433              :       _argvec[4] = (unsigned long)(arg4);                         \
    4434              :       _argvec[5] = (unsigned long)(arg5);                         \
    4435              :       __asm__ volatile(                                           \
    4436              :          VALGRIND_ALIGN_STACK                                     \
    4437              :          "ldr x0, [%1, #8] \n\t"                                  \
    4438              :          "ldr x1, [%1, #16] \n\t"                                 \
    4439              :          "ldr x2, [%1, #24] \n\t"                                 \
    4440              :          "ldr x3, [%1, #32] \n\t"                                 \
    4441              :          "ldr x4, [%1, #40] \n\t"                                 \
    4442              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4443              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4444              :          VALGRIND_RESTORE_STACK                                   \
    4445              :          "mov %0, x0"                                             \
    4446              :          : /*out*/   "=r" (_res)                                  \
    4447              :          : /*in*/    "0" (&_argvec[0])                            \
    4448              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4449              :       );                                                          \
    4450              :       lval = (__typeof__(lval)) _res;                             \
    4451              :    } while (0)
    4452              : 
    4453              : #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
    4454              :    do {                                                           \
    4455              :       volatile OrigFn        _orig = (orig);                      \
    4456              :       volatile unsigned long _argvec[7];                          \
    4457              :       volatile unsigned long _res;                                \
    4458              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4459              :       _argvec[1] = (unsigned long)(arg1);                         \
    4460              :       _argvec[2] = (unsigned long)(arg2);                         \
    4461              :       _argvec[3] = (unsigned long)(arg3);                         \
    4462              :       _argvec[4] = (unsigned long)(arg4);                         \
    4463              :       _argvec[5] = (unsigned long)(arg5);                         \
    4464              :       _argvec[6] = (unsigned long)(arg6);                         \
    4465              :       __asm__ volatile(                                           \
    4466              :          VALGRIND_ALIGN_STACK                                     \
    4467              :          "ldr x0, [%1, #8] \n\t"                                  \
    4468              :          "ldr x1, [%1, #16] \n\t"                                 \
    4469              :          "ldr x2, [%1, #24] \n\t"                                 \
    4470              :          "ldr x3, [%1, #32] \n\t"                                 \
    4471              :          "ldr x4, [%1, #40] \n\t"                                 \
    4472              :          "ldr x5, [%1, #48] \n\t"                                 \
    4473              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4474              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4475              :          VALGRIND_RESTORE_STACK                                   \
    4476              :          "mov %0, x0"                                             \
    4477              :          : /*out*/   "=r" (_res)                                  \
    4478              :          : /*in*/    "0" (&_argvec[0])                            \
    4479              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4480              :       );                                                          \
    4481              :       lval = (__typeof__(lval)) _res;                             \
    4482              :    } while (0)
    4483              : 
    4484              : #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    4485              :                                  arg7)                            \
    4486              :    do {                                                           \
    4487              :       volatile OrigFn        _orig = (orig);                      \
    4488              :       volatile unsigned long _argvec[8];                          \
    4489              :       volatile unsigned long _res;                                \
    4490              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4491              :       _argvec[1] = (unsigned long)(arg1);                         \
    4492              :       _argvec[2] = (unsigned long)(arg2);                         \
    4493              :       _argvec[3] = (unsigned long)(arg3);                         \
    4494              :       _argvec[4] = (unsigned long)(arg4);                         \
    4495              :       _argvec[5] = (unsigned long)(arg5);                         \
    4496              :       _argvec[6] = (unsigned long)(arg6);                         \
    4497              :       _argvec[7] = (unsigned long)(arg7);                         \
    4498              :       __asm__ volatile(                                           \
    4499              :          VALGRIND_ALIGN_STACK                                     \
    4500              :          "ldr x0, [%1, #8] \n\t"                                  \
    4501              :          "ldr x1, [%1, #16] \n\t"                                 \
    4502              :          "ldr x2, [%1, #24] \n\t"                                 \
    4503              :          "ldr x3, [%1, #32] \n\t"                                 \
    4504              :          "ldr x4, [%1, #40] \n\t"                                 \
    4505              :          "ldr x5, [%1, #48] \n\t"                                 \
    4506              :          "ldr x6, [%1, #56] \n\t"                                 \
    4507              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4508              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4509              :          VALGRIND_RESTORE_STACK                                   \
    4510              :          "mov %0, x0"                                             \
    4511              :          : /*out*/   "=r" (_res)                                  \
    4512              :          : /*in*/    "0" (&_argvec[0])                            \
    4513              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4514              :       );                                                          \
    4515              :       lval = (__typeof__(lval)) _res;                             \
    4516              :    } while (0)
    4517              : 
    4518              : #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    4519              :                                  arg7,arg8)                       \
    4520              :    do {                                                           \
    4521              :       volatile OrigFn        _orig = (orig);                      \
    4522              :       volatile unsigned long _argvec[9];                          \
    4523              :       volatile unsigned long _res;                                \
    4524              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4525              :       _argvec[1] = (unsigned long)(arg1);                         \
    4526              :       _argvec[2] = (unsigned long)(arg2);                         \
    4527              :       _argvec[3] = (unsigned long)(arg3);                         \
    4528              :       _argvec[4] = (unsigned long)(arg4);                         \
    4529              :       _argvec[5] = (unsigned long)(arg5);                         \
    4530              :       _argvec[6] = (unsigned long)(arg6);                         \
    4531              :       _argvec[7] = (unsigned long)(arg7);                         \
    4532              :       _argvec[8] = (unsigned long)(arg8);                         \
    4533              :       __asm__ volatile(                                           \
    4534              :          VALGRIND_ALIGN_STACK                                     \
    4535              :          "ldr x0, [%1, #8] \n\t"                                  \
    4536              :          "ldr x1, [%1, #16] \n\t"                                 \
    4537              :          "ldr x2, [%1, #24] \n\t"                                 \
    4538              :          "ldr x3, [%1, #32] \n\t"                                 \
    4539              :          "ldr x4, [%1, #40] \n\t"                                 \
    4540              :          "ldr x5, [%1, #48] \n\t"                                 \
    4541              :          "ldr x6, [%1, #56] \n\t"                                 \
    4542              :          "ldr x7, [%1, #64] \n\t"                                 \
    4543              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4544              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4545              :          VALGRIND_RESTORE_STACK                                   \
    4546              :          "mov %0, x0"                                             \
    4547              :          : /*out*/   "=r" (_res)                                  \
    4548              :          : /*in*/    "0" (&_argvec[0])                            \
    4549              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4550              :       );                                                          \
    4551              :       lval = (__typeof__(lval)) _res;                             \
    4552              :    } while (0)
    4553              : 
    4554              : #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    4555              :                                  arg7,arg8,arg9)                  \
    4556              :    do {                                                           \
    4557              :       volatile OrigFn        _orig = (orig);                      \
    4558              :       volatile unsigned long _argvec[10];                         \
    4559              :       volatile unsigned long _res;                                \
    4560              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4561              :       _argvec[1] = (unsigned long)(arg1);                         \
    4562              :       _argvec[2] = (unsigned long)(arg2);                         \
    4563              :       _argvec[3] = (unsigned long)(arg3);                         \
    4564              :       _argvec[4] = (unsigned long)(arg4);                         \
    4565              :       _argvec[5] = (unsigned long)(arg5);                         \
    4566              :       _argvec[6] = (unsigned long)(arg6);                         \
    4567              :       _argvec[7] = (unsigned long)(arg7);                         \
    4568              :       _argvec[8] = (unsigned long)(arg8);                         \
    4569              :       _argvec[9] = (unsigned long)(arg9);                         \
    4570              :       __asm__ volatile(                                           \
    4571              :          VALGRIND_ALIGN_STACK                                     \
    4572              :          "sub sp, sp, #0x20 \n\t"                                 \
    4573              :          "ldr x0, [%1, #8] \n\t"                                  \
    4574              :          "ldr x1, [%1, #16] \n\t"                                 \
    4575              :          "ldr x2, [%1, #24] \n\t"                                 \
    4576              :          "ldr x3, [%1, #32] \n\t"                                 \
    4577              :          "ldr x4, [%1, #40] \n\t"                                 \
    4578              :          "ldr x5, [%1, #48] \n\t"                                 \
    4579              :          "ldr x6, [%1, #56] \n\t"                                 \
    4580              :          "ldr x7, [%1, #64] \n\t"                                 \
    4581              :          "ldr x8, [%1, #72] \n\t"                                 \
    4582              :          "str x8, [sp, #0]  \n\t"                                 \
    4583              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4584              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4585              :          VALGRIND_RESTORE_STACK                                   \
    4586              :          "mov %0, x0"                                             \
    4587              :          : /*out*/   "=r" (_res)                                  \
    4588              :          : /*in*/    "0" (&_argvec[0])                            \
    4589              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4590              :       );                                                          \
    4591              :       lval = (__typeof__(lval)) _res;                             \
    4592              :    } while (0)
    4593              : 
    4594              : #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    4595              :                                   arg7,arg8,arg9,arg10)           \
    4596              :    do {                                                           \
    4597              :       volatile OrigFn        _orig = (orig);                      \
    4598              :       volatile unsigned long _argvec[11];                         \
    4599              :       volatile unsigned long _res;                                \
    4600              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4601              :       _argvec[1] = (unsigned long)(arg1);                         \
    4602              :       _argvec[2] = (unsigned long)(arg2);                         \
    4603              :       _argvec[3] = (unsigned long)(arg3);                         \
    4604              :       _argvec[4] = (unsigned long)(arg4);                         \
    4605              :       _argvec[5] = (unsigned long)(arg5);                         \
    4606              :       _argvec[6] = (unsigned long)(arg6);                         \
    4607              :       _argvec[7] = (unsigned long)(arg7);                         \
    4608              :       _argvec[8] = (unsigned long)(arg8);                         \
    4609              :       _argvec[9] = (unsigned long)(arg9);                         \
    4610              :       _argvec[10] = (unsigned long)(arg10);                       \
    4611              :       __asm__ volatile(                                           \
    4612              :          VALGRIND_ALIGN_STACK                                     \
    4613              :          "sub sp, sp, #0x20 \n\t"                                 \
    4614              :          "ldr x0, [%1, #8] \n\t"                                  \
    4615              :          "ldr x1, [%1, #16] \n\t"                                 \
    4616              :          "ldr x2, [%1, #24] \n\t"                                 \
    4617              :          "ldr x3, [%1, #32] \n\t"                                 \
    4618              :          "ldr x4, [%1, #40] \n\t"                                 \
    4619              :          "ldr x5, [%1, #48] \n\t"                                 \
    4620              :          "ldr x6, [%1, #56] \n\t"                                 \
    4621              :          "ldr x7, [%1, #64] \n\t"                                 \
    4622              :          "ldr x8, [%1, #72] \n\t"                                 \
    4623              :          "str x8, [sp, #0]  \n\t"                                 \
    4624              :          "ldr x8, [%1, #80] \n\t"                                 \
    4625              :          "str x8, [sp, #8]  \n\t"                                 \
    4626              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4627              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4628              :          VALGRIND_RESTORE_STACK                                   \
    4629              :          "mov %0, x0"                                             \
    4630              :          : /*out*/   "=r" (_res)                                  \
    4631              :          : /*in*/    "0" (&_argvec[0])                            \
    4632              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4633              :       );                                                          \
    4634              :       lval = (__typeof__(lval)) _res;                             \
    4635              :    } while (0)
    4636              : 
    4637              : #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    4638              :                                   arg7,arg8,arg9,arg10,arg11)     \
    4639              :    do {                                                           \
    4640              :       volatile OrigFn        _orig = (orig);                      \
    4641              :       volatile unsigned long _argvec[12];                         \
    4642              :       volatile unsigned long _res;                                \
    4643              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4644              :       _argvec[1] = (unsigned long)(arg1);                         \
    4645              :       _argvec[2] = (unsigned long)(arg2);                         \
    4646              :       _argvec[3] = (unsigned long)(arg3);                         \
    4647              :       _argvec[4] = (unsigned long)(arg4);                         \
    4648              :       _argvec[5] = (unsigned long)(arg5);                         \
    4649              :       _argvec[6] = (unsigned long)(arg6);                         \
    4650              :       _argvec[7] = (unsigned long)(arg7);                         \
    4651              :       _argvec[8] = (unsigned long)(arg8);                         \
    4652              :       _argvec[9] = (unsigned long)(arg9);                         \
    4653              :       _argvec[10] = (unsigned long)(arg10);                       \
    4654              :       _argvec[11] = (unsigned long)(arg11);                       \
    4655              :       __asm__ volatile(                                           \
    4656              :          VALGRIND_ALIGN_STACK                                     \
    4657              :          "sub sp, sp, #0x30 \n\t"                                 \
    4658              :          "ldr x0, [%1, #8] \n\t"                                  \
    4659              :          "ldr x1, [%1, #16] \n\t"                                 \
    4660              :          "ldr x2, [%1, #24] \n\t"                                 \
    4661              :          "ldr x3, [%1, #32] \n\t"                                 \
    4662              :          "ldr x4, [%1, #40] \n\t"                                 \
    4663              :          "ldr x5, [%1, #48] \n\t"                                 \
    4664              :          "ldr x6, [%1, #56] \n\t"                                 \
    4665              :          "ldr x7, [%1, #64] \n\t"                                 \
    4666              :          "ldr x8, [%1, #72] \n\t"                                 \
    4667              :          "str x8, [sp, #0]  \n\t"                                 \
    4668              :          "ldr x8, [%1, #80] \n\t"                                 \
    4669              :          "str x8, [sp, #8]  \n\t"                                 \
    4670              :          "ldr x8, [%1, #88] \n\t"                                 \
    4671              :          "str x8, [sp, #16] \n\t"                                 \
    4672              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4673              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4674              :          VALGRIND_RESTORE_STACK                                   \
    4675              :          "mov %0, x0"                                             \
    4676              :          : /*out*/   "=r" (_res)                                  \
    4677              :          : /*in*/    "0" (&_argvec[0])                            \
    4678              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4679              :       );                                                          \
    4680              :       lval = (__typeof__(lval)) _res;                             \
    4681              :    } while (0)
    4682              : 
    4683              : #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    4684              :                                   arg7,arg8,arg9,arg10,arg11,     \
    4685              :                                   arg12)                          \
    4686              :    do {                                                           \
    4687              :       volatile OrigFn        _orig = (orig);                      \
    4688              :       volatile unsigned long _argvec[13];                         \
    4689              :       volatile unsigned long _res;                                \
    4690              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    4691              :       _argvec[1] = (unsigned long)(arg1);                         \
    4692              :       _argvec[2] = (unsigned long)(arg2);                         \
    4693              :       _argvec[3] = (unsigned long)(arg3);                         \
    4694              :       _argvec[4] = (unsigned long)(arg4);                         \
    4695              :       _argvec[5] = (unsigned long)(arg5);                         \
    4696              :       _argvec[6] = (unsigned long)(arg6);                         \
    4697              :       _argvec[7] = (unsigned long)(arg7);                         \
    4698              :       _argvec[8] = (unsigned long)(arg8);                         \
    4699              :       _argvec[9] = (unsigned long)(arg9);                         \
    4700              :       _argvec[10] = (unsigned long)(arg10);                       \
    4701              :       _argvec[11] = (unsigned long)(arg11);                       \
    4702              :       _argvec[12] = (unsigned long)(arg12);                       \
    4703              :       __asm__ volatile(                                           \
    4704              :          VALGRIND_ALIGN_STACK                                     \
    4705              :          "sub sp, sp, #0x30 \n\t"                                 \
    4706              :          "ldr x0, [%1, #8] \n\t"                                  \
    4707              :          "ldr x1, [%1, #16] \n\t"                                 \
    4708              :          "ldr x2, [%1, #24] \n\t"                                 \
    4709              :          "ldr x3, [%1, #32] \n\t"                                 \
    4710              :          "ldr x4, [%1, #40] \n\t"                                 \
    4711              :          "ldr x5, [%1, #48] \n\t"                                 \
    4712              :          "ldr x6, [%1, #56] \n\t"                                 \
    4713              :          "ldr x7, [%1, #64] \n\t"                                 \
    4714              :          "ldr x8, [%1, #72] \n\t"                                 \
    4715              :          "str x8, [sp, #0]  \n\t"                                 \
    4716              :          "ldr x8, [%1, #80] \n\t"                                 \
    4717              :          "str x8, [sp, #8]  \n\t"                                 \
    4718              :          "ldr x8, [%1, #88] \n\t"                                 \
    4719              :          "str x8, [sp, #16] \n\t"                                 \
    4720              :          "ldr x8, [%1, #96] \n\t"                                 \
    4721              :          "str x8, [sp, #24] \n\t"                                 \
    4722              :          "ldr x8, [%1] \n\t"  /* target->x8 */                    \
    4723              :          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_X8                   \
    4724              :          VALGRIND_RESTORE_STACK                                   \
    4725              :          "mov %0, x0"                                             \
    4726              :          : /*out*/   "=r" (_res)                                  \
    4727              :          : /*in*/    "0" (&_argvec[0])                            \
    4728              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "x21"   \
    4729              :       );                                                          \
    4730              :       lval = (__typeof__(lval)) _res;                             \
    4731              :    } while (0)
    4732              : 
    4733              : #endif /* PLAT_arm64_linux */
    4734              : 
    4735              : /* ------------------------- s390x-linux ------------------------- */
    4736              : 
    4737              : #if defined(PLAT_s390x_linux)
    4738              : 
    4739              : /* Similar workaround as amd64 (see above), but we use r11 as frame
    4740              :    pointer and save the old r11 in r7. r11 might be used for
    4741              :    argvec, therefore we copy argvec in r1 since r1 is clobbered
    4742              :    after the call anyway.  */
    4743              : #if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
    4744              : #  define __FRAME_POINTER                                         \
    4745              :       ,"d"(__builtin_dwarf_cfa())
    4746              : #  define VALGRIND_CFI_PROLOGUE                                   \
    4747              :       ".cfi_remember_state\n\t"                                   \
    4748              :       "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */          \
    4749              :       "lgr 7,11\n\t"                                              \
    4750              :       "lgr 11,%2\n\t"                                             \
    4751              :       ".cfi_def_cfa r11, 0\n\t"
    4752              : #  define VALGRIND_CFI_EPILOGUE                                   \
    4753              :       "lgr 11, 7\n\t"                                             \
    4754              :       ".cfi_restore_state\n\t"
    4755              : #else
    4756              : #  define __FRAME_POINTER
    4757              : #  define VALGRIND_CFI_PROLOGUE                                   \
    4758              :       "lgr 1,%1\n\t"
    4759              : #  define VALGRIND_CFI_EPILOGUE
    4760              : #endif
    4761              : 
    4762              : /* Nb: On s390 the stack pointer is properly aligned *at all times*
    4763              :    according to the s390 GCC maintainer. (The ABI specification is not
    4764              :    precise in this regard.) Therefore, VALGRIND_ALIGN_STACK and
    4765              :    VALGRIND_RESTORE_STACK are not defined here. */
    4766              : 
    4767              : /* These regs are trashed by the hidden call. Note that we overwrite
    4768              :    r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
    4769              :    function a proper return address. All others are ABI defined call
    4770              :    clobbers. */
    4771              : #if defined(__VX__) || defined(__S390_VX__)
    4772              : #define __CALLER_SAVED_REGS "0", "1", "2", "3", "4", "5", "14",   \
    4773              :       "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7",             \
    4774              :       "v8", "v9", "v10", "v11", "v12", "v13", "v14", "v15",       \
    4775              :       "v16", "v17", "v18", "v19", "v20", "v21", "v22", "v23",     \
    4776              :       "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31"
    4777              : #else
    4778              : #define __CALLER_SAVED_REGS "0", "1", "2", "3", "4", "5", "14",   \
    4779              :       "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7"
    4780              : #endif
    4781              : 
    4782              : /* Nb: Although r11 is modified in the asm snippets below (inside 
    4783              :    VALGRIND_CFI_PROLOGUE) it is not listed in the clobber section, for
    4784              :    two reasons:
    4785              :    (1) r11 is restored in VALGRIND_CFI_EPILOGUE, so effectively it is not
    4786              :        modified
    4787              :    (2) GCC will complain that r11 cannot appear inside a clobber section,
    4788              :        when compiled with -O -fno-omit-frame-pointer
    4789              :  */
    4790              : 
    4791              : #define CALL_FN_W_v(lval, orig)                                  \
    4792              :    do {                                                          \
    4793              :       volatile OrigFn        _orig = (orig);                     \
    4794              :       volatile unsigned long  _argvec[1];                        \
    4795              :       volatile unsigned long _res;                               \
    4796              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    4797              :       __asm__ volatile(                                          \
    4798              :          VALGRIND_CFI_PROLOGUE                                   \
    4799              :          "aghi 15,-160\n\t"                                      \
    4800              :          "lg 1, 0(1)\n\t"  /* target->r1 */                      \
    4801              :          VALGRIND_CALL_NOREDIR_R1                                \
    4802              :          "aghi 15,160\n\t"                                       \
    4803              :          VALGRIND_CFI_EPILOGUE                                   \
    4804              :          "lgr %0, 2\n\t"                                         \
    4805              :          : /*out*/   "=d" (_res)                                 \
    4806              :          : /*in*/    "d" (&_argvec[0]) __FRAME_POINTER           \
    4807              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
    4808              :       );                                                         \
    4809              :       lval = (__typeof__(lval)) _res;                            \
    4810              :    } while (0)
    4811              : 
    4812              : /* The call abi has the arguments in r2-r6 and stack */
    4813              : #define CALL_FN_W_W(lval, orig, arg1)                            \
    4814              :    do {                                                          \
    4815              :       volatile OrigFn        _orig = (orig);                     \
    4816              :       volatile unsigned long _argvec[2];                         \
    4817              :       volatile unsigned long _res;                               \
    4818              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    4819              :       _argvec[1] = (unsigned long)arg1;                          \
    4820              :       __asm__ volatile(                                          \
    4821              :          VALGRIND_CFI_PROLOGUE                                   \
    4822              :          "aghi 15,-160\n\t"                                      \
    4823              :          "lg 2, 8(1)\n\t"                                        \
    4824              :          "lg 1, 0(1)\n\t"                                        \
    4825              :          VALGRIND_CALL_NOREDIR_R1                                \
    4826              :          "aghi 15,160\n\t"                                       \
    4827              :          VALGRIND_CFI_EPILOGUE                                   \
    4828              :          "lgr %0, 2\n\t"                                         \
    4829              :          : /*out*/   "=d" (_res)                                 \
    4830              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    4831              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
    4832              :       );                                                         \
    4833              :       lval = (__typeof__(lval)) _res;                            \
    4834              :    } while (0)
    4835              : 
    4836              : #define CALL_FN_W_WW(lval, orig, arg1, arg2)                     \
    4837              :    do {                                                          \
    4838              :       volatile OrigFn        _orig = (orig);                     \
    4839              :       volatile unsigned long _argvec[3];                         \
    4840              :       volatile unsigned long _res;                               \
    4841              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    4842              :       _argvec[1] = (unsigned long)arg1;                          \
    4843              :       _argvec[2] = (unsigned long)arg2;                          \
    4844              :       __asm__ volatile(                                          \
    4845              :          VALGRIND_CFI_PROLOGUE                                   \
    4846              :          "aghi 15,-160\n\t"                                      \
    4847              :          "lg 2, 8(1)\n\t"                                        \
    4848              :          "lg 3,16(1)\n\t"                                        \
    4849              :          "lg 1, 0(1)\n\t"                                        \
    4850              :          VALGRIND_CALL_NOREDIR_R1                                \
    4851              :          "aghi 15,160\n\t"                                       \
    4852              :          VALGRIND_CFI_EPILOGUE                                   \
    4853              :          "lgr %0, 2\n\t"                                         \
    4854              :          : /*out*/   "=d" (_res)                                 \
    4855              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    4856              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
    4857              :       );                                                         \
    4858              :       lval = (__typeof__(lval)) _res;                            \
    4859              :    } while (0)
    4860              : 
    4861              : #define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3)              \
    4862              :    do {                                                          \
    4863              :       volatile OrigFn        _orig = (orig);                     \
    4864              :       volatile unsigned long _argvec[4];                         \
    4865              :       volatile unsigned long _res;                               \
    4866              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    4867              :       _argvec[1] = (unsigned long)arg1;                          \
    4868              :       _argvec[2] = (unsigned long)arg2;                          \
    4869              :       _argvec[3] = (unsigned long)arg3;                          \
    4870              :       __asm__ volatile(                                          \
    4871              :          VALGRIND_CFI_PROLOGUE                                   \
    4872              :          "aghi 15,-160\n\t"                                      \
    4873              :          "lg 2, 8(1)\n\t"                                        \
    4874              :          "lg 3,16(1)\n\t"                                        \
    4875              :          "lg 4,24(1)\n\t"                                        \
    4876              :          "lg 1, 0(1)\n\t"                                        \
    4877              :          VALGRIND_CALL_NOREDIR_R1                                \
    4878              :          "aghi 15,160\n\t"                                       \
    4879              :          VALGRIND_CFI_EPILOGUE                                   \
    4880              :          "lgr %0, 2\n\t"                                         \
    4881              :          : /*out*/   "=d" (_res)                                 \
    4882              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    4883              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
    4884              :       );                                                         \
    4885              :       lval = (__typeof__(lval)) _res;                            \
    4886              :    } while (0)
    4887              : 
    4888              : #define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4)       \
    4889              :    do {                                                          \
    4890              :       volatile OrigFn        _orig = (orig);                     \
    4891              :       volatile unsigned long _argvec[5];                         \
    4892              :       volatile unsigned long _res;                               \
    4893              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    4894              :       _argvec[1] = (unsigned long)arg1;                          \
    4895              :       _argvec[2] = (unsigned long)arg2;                          \
    4896              :       _argvec[3] = (unsigned long)arg3;                          \
    4897              :       _argvec[4] = (unsigned long)arg4;                          \
    4898              :       __asm__ volatile(                                          \
    4899              :          VALGRIND_CFI_PROLOGUE                                   \
    4900              :          "aghi 15,-160\n\t"                                      \
    4901              :          "lg 2, 8(1)\n\t"                                        \
    4902              :          "lg 3,16(1)\n\t"                                        \
    4903              :          "lg 4,24(1)\n\t"                                        \
    4904              :          "lg 5,32(1)\n\t"                                        \
    4905              :          "lg 1, 0(1)\n\t"                                        \
    4906              :          VALGRIND_CALL_NOREDIR_R1                                \
    4907              :          "aghi 15,160\n\t"                                       \
    4908              :          VALGRIND_CFI_EPILOGUE                                   \
    4909              :          "lgr %0, 2\n\t"                                         \
    4910              :          : /*out*/   "=d" (_res)                                 \
    4911              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    4912              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7"     \
    4913              :       );                                                         \
    4914              :       lval = (__typeof__(lval)) _res;                            \
    4915              :    } while (0)
    4916              : 
    4917              : #define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5)   \
    4918              :    do {                                                          \
    4919              :       volatile OrigFn        _orig = (orig);                     \
    4920              :       volatile unsigned long _argvec[6];                         \
    4921              :       volatile unsigned long _res;                               \
    4922              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    4923              :       _argvec[1] = (unsigned long)arg1;                          \
    4924              :       _argvec[2] = (unsigned long)arg2;                          \
    4925              :       _argvec[3] = (unsigned long)arg3;                          \
    4926              :       _argvec[4] = (unsigned long)arg4;                          \
    4927              :       _argvec[5] = (unsigned long)arg5;                          \
    4928              :       __asm__ volatile(                                          \
    4929              :          VALGRIND_CFI_PROLOGUE                                   \
    4930              :          "aghi 15,-160\n\t"                                      \
    4931              :          "lg 2, 8(1)\n\t"                                        \
    4932              :          "lg 3,16(1)\n\t"                                        \
    4933              :          "lg 4,24(1)\n\t"                                        \
    4934              :          "lg 5,32(1)\n\t"                                        \
    4935              :          "lg 6,40(1)\n\t"                                        \
    4936              :          "lg 1, 0(1)\n\t"                                        \
    4937              :          VALGRIND_CALL_NOREDIR_R1                                \
    4938              :          "aghi 15,160\n\t"                                       \
    4939              :          VALGRIND_CFI_EPILOGUE                                   \
    4940              :          "lgr %0, 2\n\t"                                         \
    4941              :          : /*out*/   "=d" (_res)                                 \
    4942              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    4943              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
    4944              :       );                                                         \
    4945              :       lval = (__typeof__(lval)) _res;                            \
    4946              :    } while (0)
    4947              : 
    4948              : #define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
    4949              :                      arg6)                                       \
    4950              :    do {                                                          \
    4951              :       volatile OrigFn        _orig = (orig);                     \
    4952              :       volatile unsigned long _argvec[7];                         \
    4953              :       volatile unsigned long _res;                               \
    4954              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    4955              :       _argvec[1] = (unsigned long)arg1;                          \
    4956              :       _argvec[2] = (unsigned long)arg2;                          \
    4957              :       _argvec[3] = (unsigned long)arg3;                          \
    4958              :       _argvec[4] = (unsigned long)arg4;                          \
    4959              :       _argvec[5] = (unsigned long)arg5;                          \
    4960              :       _argvec[6] = (unsigned long)arg6;                          \
    4961              :       __asm__ volatile(                                          \
    4962              :          VALGRIND_CFI_PROLOGUE                                   \
    4963              :          "aghi 15,-168\n\t"                                      \
    4964              :          "lg 2, 8(1)\n\t"                                        \
    4965              :          "lg 3,16(1)\n\t"                                        \
    4966              :          "lg 4,24(1)\n\t"                                        \
    4967              :          "lg 5,32(1)\n\t"                                        \
    4968              :          "lg 6,40(1)\n\t"                                        \
    4969              :          "mvc 160(8,15), 48(1)\n\t"                              \
    4970              :          "lg 1, 0(1)\n\t"                                        \
    4971              :          VALGRIND_CALL_NOREDIR_R1                                \
    4972              :          "aghi 15,168\n\t"                                       \
    4973              :          VALGRIND_CFI_EPILOGUE                                   \
    4974              :          "lgr %0, 2\n\t"                                         \
    4975              :          : /*out*/   "=d" (_res)                                 \
    4976              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    4977              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
    4978              :       );                                                         \
    4979              :       lval = (__typeof__(lval)) _res;                            \
    4980              :    } while (0)
    4981              : 
    4982              : #define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
    4983              :                      arg6, arg7)                                 \
    4984              :    do {                                                          \
    4985              :       volatile OrigFn        _orig = (orig);                     \
    4986              :       volatile unsigned long _argvec[8];                         \
    4987              :       volatile unsigned long _res;                               \
    4988              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    4989              :       _argvec[1] = (unsigned long)arg1;                          \
    4990              :       _argvec[2] = (unsigned long)arg2;                          \
    4991              :       _argvec[3] = (unsigned long)arg3;                          \
    4992              :       _argvec[4] = (unsigned long)arg4;                          \
    4993              :       _argvec[5] = (unsigned long)arg5;                          \
    4994              :       _argvec[6] = (unsigned long)arg6;                          \
    4995              :       _argvec[7] = (unsigned long)arg7;                          \
    4996              :       __asm__ volatile(                                          \
    4997              :          VALGRIND_CFI_PROLOGUE                                   \
    4998              :          "aghi 15,-176\n\t"                                      \
    4999              :          "lg 2, 8(1)\n\t"                                        \
    5000              :          "lg 3,16(1)\n\t"                                        \
    5001              :          "lg 4,24(1)\n\t"                                        \
    5002              :          "lg 5,32(1)\n\t"                                        \
    5003              :          "lg 6,40(1)\n\t"                                        \
    5004              :          "mvc 160(8,15), 48(1)\n\t"                              \
    5005              :          "mvc 168(8,15), 56(1)\n\t"                              \
    5006              :          "lg 1, 0(1)\n\t"                                        \
    5007              :          VALGRIND_CALL_NOREDIR_R1                                \
    5008              :          "aghi 15,176\n\t"                                       \
    5009              :          VALGRIND_CFI_EPILOGUE                                   \
    5010              :          "lgr %0, 2\n\t"                                         \
    5011              :          : /*out*/   "=d" (_res)                                 \
    5012              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    5013              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
    5014              :       );                                                         \
    5015              :       lval = (__typeof__(lval)) _res;                            \
    5016              :    } while (0)
    5017              : 
    5018              : #define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
    5019              :                      arg6, arg7 ,arg8)                           \
    5020              :    do {                                                          \
    5021              :       volatile OrigFn        _orig = (orig);                     \
    5022              :       volatile unsigned long _argvec[9];                         \
    5023              :       volatile unsigned long _res;                               \
    5024              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    5025              :       _argvec[1] = (unsigned long)arg1;                          \
    5026              :       _argvec[2] = (unsigned long)arg2;                          \
    5027              :       _argvec[3] = (unsigned long)arg3;                          \
    5028              :       _argvec[4] = (unsigned long)arg4;                          \
    5029              :       _argvec[5] = (unsigned long)arg5;                          \
    5030              :       _argvec[6] = (unsigned long)arg6;                          \
    5031              :       _argvec[7] = (unsigned long)arg7;                          \
    5032              :       _argvec[8] = (unsigned long)arg8;                          \
    5033              :       __asm__ volatile(                                          \
    5034              :          VALGRIND_CFI_PROLOGUE                                   \
    5035              :          "aghi 15,-184\n\t"                                      \
    5036              :          "lg 2, 8(1)\n\t"                                        \
    5037              :          "lg 3,16(1)\n\t"                                        \
    5038              :          "lg 4,24(1)\n\t"                                        \
    5039              :          "lg 5,32(1)\n\t"                                        \
    5040              :          "lg 6,40(1)\n\t"                                        \
    5041              :          "mvc 160(8,15), 48(1)\n\t"                              \
    5042              :          "mvc 168(8,15), 56(1)\n\t"                              \
    5043              :          "mvc 176(8,15), 64(1)\n\t"                              \
    5044              :          "lg 1, 0(1)\n\t"                                        \
    5045              :          VALGRIND_CALL_NOREDIR_R1                                \
    5046              :          "aghi 15,184\n\t"                                       \
    5047              :          VALGRIND_CFI_EPILOGUE                                   \
    5048              :          "lgr %0, 2\n\t"                                         \
    5049              :          : /*out*/   "=d" (_res)                                 \
    5050              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    5051              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
    5052              :       );                                                         \
    5053              :       lval = (__typeof__(lval)) _res;                            \
    5054              :    } while (0)
    5055              : 
    5056              : #define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5,   \
    5057              :                      arg6, arg7 ,arg8, arg9)                     \
    5058              :    do {                                                          \
    5059              :       volatile OrigFn        _orig = (orig);                     \
    5060              :       volatile unsigned long _argvec[10];                        \
    5061              :       volatile unsigned long _res;                               \
    5062              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    5063              :       _argvec[1] = (unsigned long)arg1;                          \
    5064              :       _argvec[2] = (unsigned long)arg2;                          \
    5065              :       _argvec[3] = (unsigned long)arg3;                          \
    5066              :       _argvec[4] = (unsigned long)arg4;                          \
    5067              :       _argvec[5] = (unsigned long)arg5;                          \
    5068              :       _argvec[6] = (unsigned long)arg6;                          \
    5069              :       _argvec[7] = (unsigned long)arg7;                          \
    5070              :       _argvec[8] = (unsigned long)arg8;                          \
    5071              :       _argvec[9] = (unsigned long)arg9;                          \
    5072              :       __asm__ volatile(                                          \
    5073              :          VALGRIND_CFI_PROLOGUE                                   \
    5074              :          "aghi 15,-192\n\t"                                      \
    5075              :          "lg 2, 8(1)\n\t"                                        \
    5076              :          "lg 3,16(1)\n\t"                                        \
    5077              :          "lg 4,24(1)\n\t"                                        \
    5078              :          "lg 5,32(1)\n\t"                                        \
    5079              :          "lg 6,40(1)\n\t"                                        \
    5080              :          "mvc 160(8,15), 48(1)\n\t"                              \
    5081              :          "mvc 168(8,15), 56(1)\n\t"                              \
    5082              :          "mvc 176(8,15), 64(1)\n\t"                              \
    5083              :          "mvc 184(8,15), 72(1)\n\t"                              \
    5084              :          "lg 1, 0(1)\n\t"                                        \
    5085              :          VALGRIND_CALL_NOREDIR_R1                                \
    5086              :          "aghi 15,192\n\t"                                       \
    5087              :          VALGRIND_CFI_EPILOGUE                                   \
    5088              :          "lgr %0, 2\n\t"                                         \
    5089              :          : /*out*/   "=d" (_res)                                 \
    5090              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    5091              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
    5092              :       );                                                         \
    5093              :       lval = (__typeof__(lval)) _res;                            \
    5094              :    } while (0)
    5095              : 
    5096              : #define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
    5097              :                      arg6, arg7 ,arg8, arg9, arg10)              \
    5098              :    do {                                                          \
    5099              :       volatile OrigFn        _orig = (orig);                     \
    5100              :       volatile unsigned long _argvec[11];                        \
    5101              :       volatile unsigned long _res;                               \
    5102              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    5103              :       _argvec[1] = (unsigned long)arg1;                          \
    5104              :       _argvec[2] = (unsigned long)arg2;                          \
    5105              :       _argvec[3] = (unsigned long)arg3;                          \
    5106              :       _argvec[4] = (unsigned long)arg4;                          \
    5107              :       _argvec[5] = (unsigned long)arg5;                          \
    5108              :       _argvec[6] = (unsigned long)arg6;                          \
    5109              :       _argvec[7] = (unsigned long)arg7;                          \
    5110              :       _argvec[8] = (unsigned long)arg8;                          \
    5111              :       _argvec[9] = (unsigned long)arg9;                          \
    5112              :       _argvec[10] = (unsigned long)arg10;                        \
    5113              :       __asm__ volatile(                                          \
    5114              :          VALGRIND_CFI_PROLOGUE                                   \
    5115              :          "aghi 15,-200\n\t"                                      \
    5116              :          "lg 2, 8(1)\n\t"                                        \
    5117              :          "lg 3,16(1)\n\t"                                        \
    5118              :          "lg 4,24(1)\n\t"                                        \
    5119              :          "lg 5,32(1)\n\t"                                        \
    5120              :          "lg 6,40(1)\n\t"                                        \
    5121              :          "mvc 160(8,15), 48(1)\n\t"                              \
    5122              :          "mvc 168(8,15), 56(1)\n\t"                              \
    5123              :          "mvc 176(8,15), 64(1)\n\t"                              \
    5124              :          "mvc 184(8,15), 72(1)\n\t"                              \
    5125              :          "mvc 192(8,15), 80(1)\n\t"                              \
    5126              :          "lg 1, 0(1)\n\t"                                        \
    5127              :          VALGRIND_CALL_NOREDIR_R1                                \
    5128              :          "aghi 15,200\n\t"                                       \
    5129              :          VALGRIND_CFI_EPILOGUE                                   \
    5130              :          "lgr %0, 2\n\t"                                         \
    5131              :          : /*out*/   "=d" (_res)                                 \
    5132              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    5133              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
    5134              :       );                                                         \
    5135              :       lval = (__typeof__(lval)) _res;                            \
    5136              :    } while (0)
    5137              : 
    5138              : #define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
    5139              :                      arg6, arg7 ,arg8, arg9, arg10, arg11)       \
    5140              :    do {                                                          \
    5141              :       volatile OrigFn        _orig = (orig);                     \
    5142              :       volatile unsigned long _argvec[12];                        \
    5143              :       volatile unsigned long _res;                               \
    5144              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    5145              :       _argvec[1] = (unsigned long)arg1;                          \
    5146              :       _argvec[2] = (unsigned long)arg2;                          \
    5147              :       _argvec[3] = (unsigned long)arg3;                          \
    5148              :       _argvec[4] = (unsigned long)arg4;                          \
    5149              :       _argvec[5] = (unsigned long)arg5;                          \
    5150              :       _argvec[6] = (unsigned long)arg6;                          \
    5151              :       _argvec[7] = (unsigned long)arg7;                          \
    5152              :       _argvec[8] = (unsigned long)arg8;                          \
    5153              :       _argvec[9] = (unsigned long)arg9;                          \
    5154              :       _argvec[10] = (unsigned long)arg10;                        \
    5155              :       _argvec[11] = (unsigned long)arg11;                        \
    5156              :       __asm__ volatile(                                          \
    5157              :          VALGRIND_CFI_PROLOGUE                                   \
    5158              :          "aghi 15,-208\n\t"                                      \
    5159              :          "lg 2, 8(1)\n\t"                                        \
    5160              :          "lg 3,16(1)\n\t"                                        \
    5161              :          "lg 4,24(1)\n\t"                                        \
    5162              :          "lg 5,32(1)\n\t"                                        \
    5163              :          "lg 6,40(1)\n\t"                                        \
    5164              :          "mvc 160(8,15), 48(1)\n\t"                              \
    5165              :          "mvc 168(8,15), 56(1)\n\t"                              \
    5166              :          "mvc 176(8,15), 64(1)\n\t"                              \
    5167              :          "mvc 184(8,15), 72(1)\n\t"                              \
    5168              :          "mvc 192(8,15), 80(1)\n\t"                              \
    5169              :          "mvc 200(8,15), 88(1)\n\t"                              \
    5170              :          "lg 1, 0(1)\n\t"                                        \
    5171              :          VALGRIND_CALL_NOREDIR_R1                                \
    5172              :          "aghi 15,208\n\t"                                       \
    5173              :          VALGRIND_CFI_EPILOGUE                                   \
    5174              :          "lgr %0, 2\n\t"                                         \
    5175              :          : /*out*/   "=d" (_res)                                 \
    5176              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    5177              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
    5178              :       );                                                         \
    5179              :       lval = (__typeof__(lval)) _res;                            \
    5180              :    } while (0)
    5181              : 
    5182              : #define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5,  \
    5183              :                      arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\
    5184              :    do {                                                          \
    5185              :       volatile OrigFn        _orig = (orig);                     \
    5186              :       volatile unsigned long _argvec[13];                        \
    5187              :       volatile unsigned long _res;                               \
    5188              :       _argvec[0] = (unsigned long)_orig.nraddr;                  \
    5189              :       _argvec[1] = (unsigned long)arg1;                          \
    5190              :       _argvec[2] = (unsigned long)arg2;                          \
    5191              :       _argvec[3] = (unsigned long)arg3;                          \
    5192              :       _argvec[4] = (unsigned long)arg4;                          \
    5193              :       _argvec[5] = (unsigned long)arg5;                          \
    5194              :       _argvec[6] = (unsigned long)arg6;                          \
    5195              :       _argvec[7] = (unsigned long)arg7;                          \
    5196              :       _argvec[8] = (unsigned long)arg8;                          \
    5197              :       _argvec[9] = (unsigned long)arg9;                          \
    5198              :       _argvec[10] = (unsigned long)arg10;                        \
    5199              :       _argvec[11] = (unsigned long)arg11;                        \
    5200              :       _argvec[12] = (unsigned long)arg12;                        \
    5201              :       __asm__ volatile(                                          \
    5202              :          VALGRIND_CFI_PROLOGUE                                   \
    5203              :          "aghi 15,-216\n\t"                                      \
    5204              :          "lg 2, 8(1)\n\t"                                        \
    5205              :          "lg 3,16(1)\n\t"                                        \
    5206              :          "lg 4,24(1)\n\t"                                        \
    5207              :          "lg 5,32(1)\n\t"                                        \
    5208              :          "lg 6,40(1)\n\t"                                        \
    5209              :          "mvc 160(8,15), 48(1)\n\t"                              \
    5210              :          "mvc 168(8,15), 56(1)\n\t"                              \
    5211              :          "mvc 176(8,15), 64(1)\n\t"                              \
    5212              :          "mvc 184(8,15), 72(1)\n\t"                              \
    5213              :          "mvc 192(8,15), 80(1)\n\t"                              \
    5214              :          "mvc 200(8,15), 88(1)\n\t"                              \
    5215              :          "mvc 208(8,15), 96(1)\n\t"                              \
    5216              :          "lg 1, 0(1)\n\t"                                        \
    5217              :          VALGRIND_CALL_NOREDIR_R1                                \
    5218              :          "aghi 15,216\n\t"                                       \
    5219              :          VALGRIND_CFI_EPILOGUE                                   \
    5220              :          "lgr %0, 2\n\t"                                         \
    5221              :          : /*out*/   "=d" (_res)                                 \
    5222              :          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER           \
    5223              :          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
    5224              :       );                                                         \
    5225              :       lval = (__typeof__(lval)) _res;                            \
    5226              :    } while (0)
    5227              : 
    5228              : 
    5229              : #endif /* PLAT_s390x_linux */
    5230              : 
    5231              : /* ------------------------- mips32-linux ----------------------- */
    5232              :  
    5233              : #if defined(PLAT_mips32_linux)
    5234              : 
    5235              : /* These regs are trashed by the hidden call. */
    5236              : #define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6",       \
    5237              : "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
    5238              : "$25", "$31"
    5239              : 
    5240              : /* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
    5241              :    long) == 4. */
    5242              : 
    5243              : #define CALL_FN_W_v(lval, orig)                                   \
    5244              :    do {                                                           \
    5245              :       volatile OrigFn        _orig = (orig);                      \
    5246              :       volatile unsigned long _argvec[1];                          \
    5247              :       volatile unsigned long _res;                                \
    5248              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5249              :       __asm__ volatile(                                           \
    5250              :          "subu $29, $29, 8 \n\t"                                  \
    5251              :          "sw $28, 0($29) \n\t"                                    \
    5252              :          "sw $31, 4($29) \n\t"                                    \
    5253              :          "subu $29, $29, 16 \n\t"                                 \
    5254              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5255              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5256              :          "addu $29, $29, 16\n\t"                                  \
    5257              :          "lw $28, 0($29) \n\t"                                    \
    5258              :          "lw $31, 4($29) \n\t"                                    \
    5259              :          "addu $29, $29, 8 \n\t"                                  \
    5260              :          "move %0, $2\n"                                          \
    5261              :          : /*out*/   "=r" (_res)                                  \
    5262              :          : /*in*/    "0" (&_argvec[0])                            \
    5263              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5264              :       );                                                          \
    5265              :       lval = (__typeof__(lval)) _res;                             \
    5266              :    } while (0)
    5267              : 
    5268              : #define CALL_FN_W_W(lval, orig, arg1)                             \
    5269              :    do {                                                           \
    5270              :       volatile OrigFn        _orig = (orig);                      \
    5271              :      volatile unsigned long _argvec[2];                           \
    5272              :       volatile unsigned long _res;                                \
    5273              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5274              :       _argvec[1] = (unsigned long)(arg1);                         \
    5275              :       __asm__ volatile(                                           \
    5276              :          "subu $29, $29, 8 \n\t"                                  \
    5277              :          "sw $28, 0($29) \n\t"                                    \
    5278              :          "sw $31, 4($29) \n\t"                                    \
    5279              :          "subu $29, $29, 16 \n\t"                                 \
    5280              :          "lw $4, 4(%1) \n\t"   /* arg1*/                          \
    5281              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5282              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5283              :          "addu $29, $29, 16 \n\t"                                 \
    5284              :          "lw $28, 0($29) \n\t"                                    \
    5285              :          "lw $31, 4($29) \n\t"                                    \
    5286              :          "addu $29, $29, 8 \n\t"                                  \
    5287              :          "move %0, $2\n"                                          \
    5288              :          : /*out*/   "=r" (_res)                                  \
    5289              :          : /*in*/    "0" (&_argvec[0])                            \
    5290              :          : /*trash*/ "memory",  __CALLER_SAVED_REGS               \
    5291              :       );                                                          \
    5292              :       lval = (__typeof__(lval)) _res;                             \
    5293              :    } while (0)
    5294              : 
    5295              : #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
    5296              :    do {                                                           \
    5297              :       volatile OrigFn        _orig = (orig);                      \
    5298              :       volatile unsigned long _argvec[3];                          \
    5299              :       volatile unsigned long _res;                                \
    5300              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5301              :       _argvec[1] = (unsigned long)(arg1);                         \
    5302              :       _argvec[2] = (unsigned long)(arg2);                         \
    5303              :       __asm__ volatile(                                           \
    5304              :          "subu $29, $29, 8 \n\t"                                  \
    5305              :          "sw $28, 0($29) \n\t"                                    \
    5306              :          "sw $31, 4($29) \n\t"                                    \
    5307              :          "subu $29, $29, 16 \n\t"                                 \
    5308              :          "lw $4, 4(%1) \n\t"                                      \
    5309              :          "lw $5, 8(%1) \n\t"                                      \
    5310              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5311              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5312              :          "addu $29, $29, 16 \n\t"                                 \
    5313              :          "lw $28, 0($29) \n\t"                                    \
    5314              :          "lw $31, 4($29) \n\t"                                    \
    5315              :          "addu $29, $29, 8 \n\t"                                  \
    5316              :          "move %0, $2\n"                                          \
    5317              :          : /*out*/   "=r" (_res)                                  \
    5318              :          : /*in*/    "0" (&_argvec[0])                            \
    5319              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5320              :       );                                                          \
    5321              :       lval = (__typeof__(lval)) _res;                             \
    5322              :    } while (0)
    5323              : 
    5324              : #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    5325              :    do {                                                           \
    5326              :       volatile OrigFn        _orig = (orig);                      \
    5327              :       volatile unsigned long _argvec[4];                          \
    5328              :       volatile unsigned long _res;                                \
    5329              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5330              :       _argvec[1] = (unsigned long)(arg1);                         \
    5331              :       _argvec[2] = (unsigned long)(arg2);                         \
    5332              :       _argvec[3] = (unsigned long)(arg3);                         \
    5333              :       __asm__ volatile(                                           \
    5334              :          "subu $29, $29, 8 \n\t"                                  \
    5335              :          "sw $28, 0($29) \n\t"                                    \
    5336              :          "sw $31, 4($29) \n\t"                                    \
    5337              :          "subu $29, $29, 16 \n\t"                                 \
    5338              :          "lw $4, 4(%1) \n\t"                                      \
    5339              :          "lw $5, 8(%1) \n\t"                                      \
    5340              :          "lw $6, 12(%1) \n\t"                                     \
    5341              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5342              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5343              :          "addu $29, $29, 16 \n\t"                                 \
    5344              :          "lw $28, 0($29) \n\t"                                    \
    5345              :          "lw $31, 4($29) \n\t"                                    \
    5346              :          "addu $29, $29, 8 \n\t"                                  \
    5347              :          "move %0, $2\n"                                          \
    5348              :          : /*out*/   "=r" (_res)                                  \
    5349              :          : /*in*/    "0" (&_argvec[0])                            \
    5350              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5351              :       );                                                          \
    5352              :       lval = (__typeof__(lval)) _res;                             \
    5353              :    } while (0)
    5354              : 
    5355              : #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
    5356              :    do {                                                           \
    5357              :       volatile OrigFn        _orig = (orig);                      \
    5358              :       volatile unsigned long _argvec[5];                          \
    5359              :       volatile unsigned long _res;                                \
    5360              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5361              :       _argvec[1] = (unsigned long)(arg1);                         \
    5362              :       _argvec[2] = (unsigned long)(arg2);                         \
    5363              :       _argvec[3] = (unsigned long)(arg3);                         \
    5364              :       _argvec[4] = (unsigned long)(arg4);                         \
    5365              :       __asm__ volatile(                                           \
    5366              :          "subu $29, $29, 8 \n\t"                                  \
    5367              :          "sw $28, 0($29) \n\t"                                    \
    5368              :          "sw $31, 4($29) \n\t"                                    \
    5369              :          "subu $29, $29, 16 \n\t"                                 \
    5370              :          "lw $4, 4(%1) \n\t"                                      \
    5371              :          "lw $5, 8(%1) \n\t"                                      \
    5372              :          "lw $6, 12(%1) \n\t"                                     \
    5373              :          "lw $7, 16(%1) \n\t"                                     \
    5374              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5375              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5376              :          "addu $29, $29, 16 \n\t"                                 \
    5377              :          "lw $28, 0($29) \n\t"                                    \
    5378              :          "lw $31, 4($29) \n\t"                                    \
    5379              :          "addu $29, $29, 8 \n\t"                                  \
    5380              :          "move %0, $2\n"                                          \
    5381              :          : /*out*/   "=r" (_res)                                  \
    5382              :          : /*in*/    "0" (&_argvec[0])                            \
    5383              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5384              :       );                                                          \
    5385              :       lval = (__typeof__(lval)) _res;                             \
    5386              :    } while (0)
    5387              : 
    5388              : #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
    5389              :    do {                                                           \
    5390              :       volatile OrigFn        _orig = (orig);                      \
    5391              :       volatile unsigned long _argvec[6];                          \
    5392              :       volatile unsigned long _res;                                \
    5393              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5394              :       _argvec[1] = (unsigned long)(arg1);                         \
    5395              :       _argvec[2] = (unsigned long)(arg2);                         \
    5396              :       _argvec[3] = (unsigned long)(arg3);                         \
    5397              :       _argvec[4] = (unsigned long)(arg4);                         \
    5398              :       _argvec[5] = (unsigned long)(arg5);                         \
    5399              :       __asm__ volatile(                                           \
    5400              :          "subu $29, $29, 8 \n\t"                                  \
    5401              :          "sw $28, 0($29) \n\t"                                    \
    5402              :          "sw $31, 4($29) \n\t"                                    \
    5403              :          "lw $4, 20(%1) \n\t"                                     \
    5404              :          "subu $29, $29, 24\n\t"                                  \
    5405              :          "sw $4, 16($29) \n\t"                                    \
    5406              :          "lw $4, 4(%1) \n\t"                                      \
    5407              :          "lw $5, 8(%1) \n\t"                                      \
    5408              :          "lw $6, 12(%1) \n\t"                                     \
    5409              :          "lw $7, 16(%1) \n\t"                                     \
    5410              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5411              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5412              :          "addu $29, $29, 24 \n\t"                                 \
    5413              :          "lw $28, 0($29) \n\t"                                    \
    5414              :          "lw $31, 4($29) \n\t"                                    \
    5415              :          "addu $29, $29, 8 \n\t"                                  \
    5416              :          "move %0, $2\n"                                          \
    5417              :          : /*out*/   "=r" (_res)                                  \
    5418              :          : /*in*/    "0" (&_argvec[0])                            \
    5419              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5420              :       );                                                          \
    5421              :       lval = (__typeof__(lval)) _res;                             \
    5422              :    } while (0)
    5423              : #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
    5424              :    do {                                                           \
    5425              :       volatile OrigFn        _orig = (orig);                      \
    5426              :       volatile unsigned long _argvec[7];                          \
    5427              :       volatile unsigned long _res;                                \
    5428              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5429              :       _argvec[1] = (unsigned long)(arg1);                         \
    5430              :       _argvec[2] = (unsigned long)(arg2);                         \
    5431              :       _argvec[3] = (unsigned long)(arg3);                         \
    5432              :       _argvec[4] = (unsigned long)(arg4);                         \
    5433              :       _argvec[5] = (unsigned long)(arg5);                         \
    5434              :       _argvec[6] = (unsigned long)(arg6);                         \
    5435              :       __asm__ volatile(                                           \
    5436              :          "subu $29, $29, 8 \n\t"                                  \
    5437              :          "sw $28, 0($29) \n\t"                                    \
    5438              :          "sw $31, 4($29) \n\t"                                    \
    5439              :          "lw $4, 20(%1) \n\t"                                     \
    5440              :          "subu $29, $29, 32\n\t"                                  \
    5441              :          "sw $4, 16($29) \n\t"                                    \
    5442              :          "lw $4, 24(%1) \n\t"                                     \
    5443              :          "nop\n\t"                                                \
    5444              :          "sw $4, 20($29) \n\t"                                    \
    5445              :          "lw $4, 4(%1) \n\t"                                      \
    5446              :          "lw $5, 8(%1) \n\t"                                      \
    5447              :          "lw $6, 12(%1) \n\t"                                     \
    5448              :          "lw $7, 16(%1) \n\t"                                     \
    5449              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5450              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5451              :          "addu $29, $29, 32 \n\t"                                 \
    5452              :          "lw $28, 0($29) \n\t"                                    \
    5453              :          "lw $31, 4($29) \n\t"                                    \
    5454              :          "addu $29, $29, 8 \n\t"                                  \
    5455              :          "move %0, $2\n"                                          \
    5456              :          : /*out*/   "=r" (_res)                                  \
    5457              :          : /*in*/    "0" (&_argvec[0])                            \
    5458              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5459              :       );                                                          \
    5460              :       lval = (__typeof__(lval)) _res;                             \
    5461              :    } while (0)
    5462              : 
    5463              : #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    5464              :                                  arg7)                            \
    5465              :    do {                                                           \
    5466              :       volatile OrigFn        _orig = (orig);                      \
    5467              :       volatile unsigned long _argvec[8];                          \
    5468              :       volatile unsigned long _res;                                \
    5469              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5470              :       _argvec[1] = (unsigned long)(arg1);                         \
    5471              :       _argvec[2] = (unsigned long)(arg2);                         \
    5472              :       _argvec[3] = (unsigned long)(arg3);                         \
    5473              :       _argvec[4] = (unsigned long)(arg4);                         \
    5474              :       _argvec[5] = (unsigned long)(arg5);                         \
    5475              :       _argvec[6] = (unsigned long)(arg6);                         \
    5476              :       _argvec[7] = (unsigned long)(arg7);                         \
    5477              :       __asm__ volatile(                                           \
    5478              :          "subu $29, $29, 8 \n\t"                                  \
    5479              :          "sw $28, 0($29) \n\t"                                    \
    5480              :          "sw $31, 4($29) \n\t"                                    \
    5481              :          "lw $4, 20(%1) \n\t"                                     \
    5482              :          "subu $29, $29, 32\n\t"                                  \
    5483              :          "sw $4, 16($29) \n\t"                                    \
    5484              :          "lw $4, 24(%1) \n\t"                                     \
    5485              :          "sw $4, 20($29) \n\t"                                    \
    5486              :          "lw $4, 28(%1) \n\t"                                     \
    5487              :          "sw $4, 24($29) \n\t"                                    \
    5488              :          "lw $4, 4(%1) \n\t"                                      \
    5489              :          "lw $5, 8(%1) \n\t"                                      \
    5490              :          "lw $6, 12(%1) \n\t"                                     \
    5491              :          "lw $7, 16(%1) \n\t"                                     \
    5492              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5493              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5494              :          "addu $29, $29, 32 \n\t"                                 \
    5495              :          "lw $28, 0($29) \n\t"                                    \
    5496              :          "lw $31, 4($29) \n\t"                                    \
    5497              :          "addu $29, $29, 8 \n\t"                                  \
    5498              :          "move %0, $2\n"                                          \
    5499              :          : /*out*/   "=r" (_res)                                  \
    5500              :          : /*in*/    "0" (&_argvec[0])                            \
    5501              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5502              :       );                                                          \
    5503              :       lval = (__typeof__(lval)) _res;                             \
    5504              :    } while (0)
    5505              : 
    5506              : #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    5507              :                                  arg7,arg8)                       \
    5508              :    do {                                                           \
    5509              :       volatile OrigFn        _orig = (orig);                      \
    5510              :       volatile unsigned long _argvec[9];                          \
    5511              :       volatile unsigned long _res;                                \
    5512              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5513              :       _argvec[1] = (unsigned long)(arg1);                         \
    5514              :       _argvec[2] = (unsigned long)(arg2);                         \
    5515              :       _argvec[3] = (unsigned long)(arg3);                         \
    5516              :       _argvec[4] = (unsigned long)(arg4);                         \
    5517              :       _argvec[5] = (unsigned long)(arg5);                         \
    5518              :       _argvec[6] = (unsigned long)(arg6);                         \
    5519              :       _argvec[7] = (unsigned long)(arg7);                         \
    5520              :       _argvec[8] = (unsigned long)(arg8);                         \
    5521              :       __asm__ volatile(                                           \
    5522              :          "subu $29, $29, 8 \n\t"                                  \
    5523              :          "sw $28, 0($29) \n\t"                                    \
    5524              :          "sw $31, 4($29) \n\t"                                    \
    5525              :          "lw $4, 20(%1) \n\t"                                     \
    5526              :          "subu $29, $29, 40\n\t"                                  \
    5527              :          "sw $4, 16($29) \n\t"                                    \
    5528              :          "lw $4, 24(%1) \n\t"                                     \
    5529              :          "sw $4, 20($29) \n\t"                                    \
    5530              :          "lw $4, 28(%1) \n\t"                                     \
    5531              :          "sw $4, 24($29) \n\t"                                    \
    5532              :          "lw $4, 32(%1) \n\t"                                     \
    5533              :          "sw $4, 28($29) \n\t"                                    \
    5534              :          "lw $4, 4(%1) \n\t"                                      \
    5535              :          "lw $5, 8(%1) \n\t"                                      \
    5536              :          "lw $6, 12(%1) \n\t"                                     \
    5537              :          "lw $7, 16(%1) \n\t"                                     \
    5538              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5539              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5540              :          "addu $29, $29, 40 \n\t"                                 \
    5541              :          "lw $28, 0($29) \n\t"                                    \
    5542              :          "lw $31, 4($29) \n\t"                                    \
    5543              :          "addu $29, $29, 8 \n\t"                                  \
    5544              :          "move %0, $2\n"                                          \
    5545              :          : /*out*/   "=r" (_res)                                  \
    5546              :          : /*in*/    "0" (&_argvec[0])                            \
    5547              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5548              :       );                                                          \
    5549              :       lval = (__typeof__(lval)) _res;                             \
    5550              :    } while (0)
    5551              : 
    5552              : #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    5553              :                                  arg7,arg8,arg9)                  \
    5554              :    do {                                                           \
    5555              :       volatile OrigFn        _orig = (orig);                      \
    5556              :       volatile unsigned long _argvec[10];                         \
    5557              :       volatile unsigned long _res;                                \
    5558              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5559              :       _argvec[1] = (unsigned long)(arg1);                         \
    5560              :       _argvec[2] = (unsigned long)(arg2);                         \
    5561              :       _argvec[3] = (unsigned long)(arg3);                         \
    5562              :       _argvec[4] = (unsigned long)(arg4);                         \
    5563              :       _argvec[5] = (unsigned long)(arg5);                         \
    5564              :       _argvec[6] = (unsigned long)(arg6);                         \
    5565              :       _argvec[7] = (unsigned long)(arg7);                         \
    5566              :       _argvec[8] = (unsigned long)(arg8);                         \
    5567              :       _argvec[9] = (unsigned long)(arg9);                         \
    5568              :       __asm__ volatile(                                           \
    5569              :          "subu $29, $29, 8 \n\t"                                  \
    5570              :          "sw $28, 0($29) \n\t"                                    \
    5571              :          "sw $31, 4($29) \n\t"                                    \
    5572              :          "lw $4, 20(%1) \n\t"                                     \
    5573              :          "subu $29, $29, 40\n\t"                                  \
    5574              :          "sw $4, 16($29) \n\t"                                    \
    5575              :          "lw $4, 24(%1) \n\t"                                     \
    5576              :          "sw $4, 20($29) \n\t"                                    \
    5577              :          "lw $4, 28(%1) \n\t"                                     \
    5578              :          "sw $4, 24($29) \n\t"                                    \
    5579              :          "lw $4, 32(%1) \n\t"                                     \
    5580              :          "sw $4, 28($29) \n\t"                                    \
    5581              :          "lw $4, 36(%1) \n\t"                                     \
    5582              :          "sw $4, 32($29) \n\t"                                    \
    5583              :          "lw $4, 4(%1) \n\t"                                      \
    5584              :          "lw $5, 8(%1) \n\t"                                      \
    5585              :          "lw $6, 12(%1) \n\t"                                     \
    5586              :          "lw $7, 16(%1) \n\t"                                     \
    5587              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5588              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5589              :          "addu $29, $29, 40 \n\t"                                 \
    5590              :          "lw $28, 0($29) \n\t"                                    \
    5591              :          "lw $31, 4($29) \n\t"                                    \
    5592              :          "addu $29, $29, 8 \n\t"                                  \
    5593              :          "move %0, $2\n"                                          \
    5594              :          : /*out*/   "=r" (_res)                                  \
    5595              :          : /*in*/    "0" (&_argvec[0])                            \
    5596              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5597              :       );                                                          \
    5598              :       lval = (__typeof__(lval)) _res;                             \
    5599              :    } while (0)
    5600              : 
    5601              : #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    5602              :                                   arg7,arg8,arg9,arg10)           \
    5603              :    do {                                                           \
    5604              :       volatile OrigFn        _orig = (orig);                      \
    5605              :       volatile unsigned long _argvec[11];                         \
    5606              :       volatile unsigned long _res;                                \
    5607              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5608              :       _argvec[1] = (unsigned long)(arg1);                         \
    5609              :       _argvec[2] = (unsigned long)(arg2);                         \
    5610              :       _argvec[3] = (unsigned long)(arg3);                         \
    5611              :       _argvec[4] = (unsigned long)(arg4);                         \
    5612              :       _argvec[5] = (unsigned long)(arg5);                         \
    5613              :       _argvec[6] = (unsigned long)(arg6);                         \
    5614              :       _argvec[7] = (unsigned long)(arg7);                         \
    5615              :       _argvec[8] = (unsigned long)(arg8);                         \
    5616              :       _argvec[9] = (unsigned long)(arg9);                         \
    5617              :       _argvec[10] = (unsigned long)(arg10);                       \
    5618              :       __asm__ volatile(                                           \
    5619              :          "subu $29, $29, 8 \n\t"                                  \
    5620              :          "sw $28, 0($29) \n\t"                                    \
    5621              :          "sw $31, 4($29) \n\t"                                    \
    5622              :          "lw $4, 20(%1) \n\t"                                     \
    5623              :          "subu $29, $29, 48\n\t"                                  \
    5624              :          "sw $4, 16($29) \n\t"                                    \
    5625              :          "lw $4, 24(%1) \n\t"                                     \
    5626              :          "sw $4, 20($29) \n\t"                                    \
    5627              :          "lw $4, 28(%1) \n\t"                                     \
    5628              :          "sw $4, 24($29) \n\t"                                    \
    5629              :          "lw $4, 32(%1) \n\t"                                     \
    5630              :          "sw $4, 28($29) \n\t"                                    \
    5631              :          "lw $4, 36(%1) \n\t"                                     \
    5632              :          "sw $4, 32($29) \n\t"                                    \
    5633              :          "lw $4, 40(%1) \n\t"                                     \
    5634              :          "sw $4, 36($29) \n\t"                                    \
    5635              :          "lw $4, 4(%1) \n\t"                                      \
    5636              :          "lw $5, 8(%1) \n\t"                                      \
    5637              :          "lw $6, 12(%1) \n\t"                                     \
    5638              :          "lw $7, 16(%1) \n\t"                                     \
    5639              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5640              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5641              :          "addu $29, $29, 48 \n\t"                                 \
    5642              :          "lw $28, 0($29) \n\t"                                    \
    5643              :          "lw $31, 4($29) \n\t"                                    \
    5644              :          "addu $29, $29, 8 \n\t"                                  \
    5645              :          "move %0, $2\n"                                          \
    5646              :          : /*out*/   "=r" (_res)                                  \
    5647              :          : /*in*/    "0" (&_argvec[0])                            \
    5648              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5649              :       );                                                          \
    5650              :       lval = (__typeof__(lval)) _res;                             \
    5651              :    } while (0)
    5652              : 
    5653              : #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
    5654              :                                   arg6,arg7,arg8,arg9,arg10,      \
    5655              :                                   arg11)                          \
    5656              :    do {                                                           \
    5657              :       volatile OrigFn        _orig = (orig);                      \
    5658              :       volatile unsigned long _argvec[12];                         \
    5659              :       volatile unsigned long _res;                                \
    5660              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5661              :       _argvec[1] = (unsigned long)(arg1);                         \
    5662              :       _argvec[2] = (unsigned long)(arg2);                         \
    5663              :       _argvec[3] = (unsigned long)(arg3);                         \
    5664              :       _argvec[4] = (unsigned long)(arg4);                         \
    5665              :       _argvec[5] = (unsigned long)(arg5);                         \
    5666              :       _argvec[6] = (unsigned long)(arg6);                         \
    5667              :       _argvec[7] = (unsigned long)(arg7);                         \
    5668              :       _argvec[8] = (unsigned long)(arg8);                         \
    5669              :       _argvec[9] = (unsigned long)(arg9);                         \
    5670              :       _argvec[10] = (unsigned long)(arg10);                       \
    5671              :       _argvec[11] = (unsigned long)(arg11);                       \
    5672              :       __asm__ volatile(                                           \
    5673              :          "subu $29, $29, 8 \n\t"                                  \
    5674              :          "sw $28, 0($29) \n\t"                                    \
    5675              :          "sw $31, 4($29) \n\t"                                    \
    5676              :          "lw $4, 20(%1) \n\t"                                     \
    5677              :          "subu $29, $29, 48\n\t"                                  \
    5678              :          "sw $4, 16($29) \n\t"                                    \
    5679              :          "lw $4, 24(%1) \n\t"                                     \
    5680              :          "sw $4, 20($29) \n\t"                                    \
    5681              :          "lw $4, 28(%1) \n\t"                                     \
    5682              :          "sw $4, 24($29) \n\t"                                    \
    5683              :          "lw $4, 32(%1) \n\t"                                     \
    5684              :          "sw $4, 28($29) \n\t"                                    \
    5685              :          "lw $4, 36(%1) \n\t"                                     \
    5686              :          "sw $4, 32($29) \n\t"                                    \
    5687              :          "lw $4, 40(%1) \n\t"                                     \
    5688              :          "sw $4, 36($29) \n\t"                                    \
    5689              :          "lw $4, 44(%1) \n\t"                                     \
    5690              :          "sw $4, 40($29) \n\t"                                    \
    5691              :          "lw $4, 4(%1) \n\t"                                      \
    5692              :          "lw $5, 8(%1) \n\t"                                      \
    5693              :          "lw $6, 12(%1) \n\t"                                     \
    5694              :          "lw $7, 16(%1) \n\t"                                     \
    5695              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5696              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5697              :          "addu $29, $29, 48 \n\t"                                 \
    5698              :          "lw $28, 0($29) \n\t"                                    \
    5699              :          "lw $31, 4($29) \n\t"                                    \
    5700              :          "addu $29, $29, 8 \n\t"                                  \
    5701              :          "move %0, $2\n"                                          \
    5702              :          : /*out*/   "=r" (_res)                                  \
    5703              :          : /*in*/    "0" (&_argvec[0])                            \
    5704              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5705              :       );                                                          \
    5706              :       lval = (__typeof__(lval)) _res;                             \
    5707              :    } while (0)
    5708              : 
    5709              : #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
    5710              :                                   arg6,arg7,arg8,arg9,arg10,      \
    5711              :                                   arg11,arg12)                    \
    5712              :    do {                                                           \
    5713              :       volatile OrigFn        _orig = (orig);                      \
    5714              :       volatile unsigned long _argvec[13];                         \
    5715              :       volatile unsigned long _res;                                \
    5716              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5717              :       _argvec[1] = (unsigned long)(arg1);                         \
    5718              :       _argvec[2] = (unsigned long)(arg2);                         \
    5719              :       _argvec[3] = (unsigned long)(arg3);                         \
    5720              :       _argvec[4] = (unsigned long)(arg4);                         \
    5721              :       _argvec[5] = (unsigned long)(arg5);                         \
    5722              :       _argvec[6] = (unsigned long)(arg6);                         \
    5723              :       _argvec[7] = (unsigned long)(arg7);                         \
    5724              :       _argvec[8] = (unsigned long)(arg8);                         \
    5725              :       _argvec[9] = (unsigned long)(arg9);                         \
    5726              :       _argvec[10] = (unsigned long)(arg10);                       \
    5727              :       _argvec[11] = (unsigned long)(arg11);                       \
    5728              :       _argvec[12] = (unsigned long)(arg12);                       \
    5729              :       __asm__ volatile(                                           \
    5730              :          "subu $29, $29, 8 \n\t"                                  \
    5731              :          "sw $28, 0($29) \n\t"                                    \
    5732              :          "sw $31, 4($29) \n\t"                                    \
    5733              :          "lw $4, 20(%1) \n\t"                                     \
    5734              :          "subu $29, $29, 56\n\t"                                  \
    5735              :          "sw $4, 16($29) \n\t"                                    \
    5736              :          "lw $4, 24(%1) \n\t"                                     \
    5737              :          "sw $4, 20($29) \n\t"                                    \
    5738              :          "lw $4, 28(%1) \n\t"                                     \
    5739              :          "sw $4, 24($29) \n\t"                                    \
    5740              :          "lw $4, 32(%1) \n\t"                                     \
    5741              :          "sw $4, 28($29) \n\t"                                    \
    5742              :          "lw $4, 36(%1) \n\t"                                     \
    5743              :          "sw $4, 32($29) \n\t"                                    \
    5744              :          "lw $4, 40(%1) \n\t"                                     \
    5745              :          "sw $4, 36($29) \n\t"                                    \
    5746              :          "lw $4, 44(%1) \n\t"                                     \
    5747              :          "sw $4, 40($29) \n\t"                                    \
    5748              :          "lw $4, 48(%1) \n\t"                                     \
    5749              :          "sw $4, 44($29) \n\t"                                    \
    5750              :          "lw $4, 4(%1) \n\t"                                      \
    5751              :          "lw $5, 8(%1) \n\t"                                      \
    5752              :          "lw $6, 12(%1) \n\t"                                     \
    5753              :          "lw $7, 16(%1) \n\t"                                     \
    5754              :          "lw $25, 0(%1) \n\t"  /* target->t9 */                   \
    5755              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5756              :          "addu $29, $29, 56 \n\t"                                 \
    5757              :          "lw $28, 0($29) \n\t"                                    \
    5758              :          "lw $31, 4($29) \n\t"                                    \
    5759              :          "addu $29, $29, 8 \n\t"                                  \
    5760              :          "move %0, $2\n"                                          \
    5761              :          : /*out*/   "=r" (_res)                                  \
    5762              :          : /*in*/    "r" (&_argvec[0])                            \
    5763              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5764              :       );                                                          \
    5765              :       lval = (__typeof__(lval)) _res;                             \
    5766              :    } while (0)
    5767              : 
    5768              : #endif /* PLAT_mips32_linux */
    5769              : 
    5770              : /* ------------------------- nanomips-linux -------------------- */
    5771              : 
    5772              : #if defined(PLAT_nanomips_linux)
    5773              : 
    5774              : /* These regs are trashed by the hidden call. */
    5775              : #define __CALLER_SAVED_REGS "$t4", "$t5", "$a0", "$a1", "$a2",     \
    5776              : "$a3", "$a4", "$a5", "$a6", "$a7", "$t0", "$t1", "$t2", "$t3",     \
    5777              : "$t8","$t9", "$at"
    5778              : 
    5779              : /* These CALL_FN_ macros assume that on mips-linux, sizeof(unsigned
    5780              :    long) == 4. */
    5781              : 
    5782              : #define CALL_FN_W_v(lval, orig)                                   \
    5783              :    do {                                                           \
    5784              :       volatile OrigFn        _orig = (orig);                      \
    5785              :       volatile unsigned long _argvec[1];                          \
    5786              :       volatile unsigned long _res;                                \
    5787              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5788              :       __asm__ volatile(                                           \
    5789              :          "lw $t9, 0(%1)\n\t"                                      \
    5790              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5791              :          "move %0, $a0\n"                                         \
    5792              :          : /*out*/   "=r" (_res)                                  \
    5793              :          : /*in*/    "r" (&_argvec[0])                            \
    5794              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5795              :       );                                                          \
    5796              :       lval = (__typeof__(lval)) _res;                             \
    5797              :    } while (0)
    5798              : 
    5799              : #define CALL_FN_W_W(lval, orig, arg1)                             \
    5800              :    do {                                                           \
    5801              :       volatile OrigFn        _orig = (orig);                      \
    5802              :       volatile unsigned long _argvec[2];                          \
    5803              :       volatile unsigned long _res;                                \
    5804              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5805              :       _argvec[1] = (unsigned long)(arg1);                         \
    5806              :       __asm__ volatile(                                           \
    5807              :          "lw $t9, 0(%1)\n\t"                                      \
    5808              :          "lw $a0, 4(%1)\n\t"                                      \
    5809              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5810              :          "move %0, $a0\n"                                         \
    5811              :          : /*out*/   "=r" (_res)                                  \
    5812              :          : /*in*/    "r" (&_argvec[0])                            \
    5813              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5814              :       );                                                          \
    5815              :       lval = (__typeof__(lval)) _res;                             \
    5816              :    } while (0)
    5817              : 
    5818              : #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
    5819              :    do {                                                           \
    5820              :       volatile OrigFn        _orig = (orig);                      \
    5821              :       volatile unsigned long _argvec[3];                          \
    5822              :       volatile unsigned long _res;                                \
    5823              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5824              :       _argvec[1] = (unsigned long)(arg1);                         \
    5825              :       _argvec[2] = (unsigned long)(arg2);                         \
    5826              :       __asm__ volatile(                                           \
    5827              :          "lw $t9, 0(%1)\n\t"                                      \
    5828              :          "lw $a0, 4(%1)\n\t"                                      \
    5829              :          "lw $a1, 8(%1)\n\t"                                      \
    5830              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5831              :          "move %0, $a0\n"                                         \
    5832              :          : /*out*/   "=r" (_res)                                  \
    5833              :          : /*in*/    "r" (&_argvec[0])                            \
    5834              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5835              :       );                                                          \
    5836              :       lval = (__typeof__(lval)) _res;                             \
    5837              :    } while (0)
    5838              : 
    5839              : #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    5840              :    do {                                                           \
    5841              :       volatile OrigFn        _orig = (orig);                      \
    5842              :       volatile unsigned long _argvec[4];                          \
    5843              :       volatile unsigned long _res;                                \
    5844              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5845              :       _argvec[1] = (unsigned long)(arg1);                         \
    5846              :       _argvec[2] = (unsigned long)(arg2);                         \
    5847              :       _argvec[3] = (unsigned long)(arg3);                         \
    5848              :       __asm__ volatile(                                           \
    5849              :          "lw $t9, 0(%1)\n\t"                                      \
    5850              :          "lw $a0, 4(%1)\n\t"                                      \
    5851              :          "lw $a1, 8(%1)\n\t"                                      \
    5852              :          "lw $a2,12(%1)\n\t"                                      \
    5853              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5854              :          "move %0, $a0\n"                                         \
    5855              :          : /*out*/   "=r" (_res)                                  \
    5856              :          : /*in*/    "r" (&_argvec[0])                            \
    5857              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5858              :       );                                                          \
    5859              :       lval = (__typeof__(lval)) _res;                             \
    5860              :    } while (0)
    5861              : 
    5862              : #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
    5863              :    do {                                                           \
    5864              :       volatile OrigFn        _orig = (orig);                      \
    5865              :       volatile unsigned long _argvec[5];                          \
    5866              :       volatile unsigned long _res;                                \
    5867              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5868              :       _argvec[1] = (unsigned long)(arg1);                         \
    5869              :       _argvec[2] = (unsigned long)(arg2);                         \
    5870              :       _argvec[3] = (unsigned long)(arg3);                         \
    5871              :       _argvec[4] = (unsigned long)(arg4);                         \
    5872              :       __asm__ volatile(                                           \
    5873              :          "lw $t9, 0(%1)\n\t"                                      \
    5874              :          "lw $a0, 4(%1)\n\t"                                      \
    5875              :          "lw $a1, 8(%1)\n\t"                                      \
    5876              :          "lw $a2,12(%1)\n\t"                                      \
    5877              :          "lw $a3,16(%1)\n\t"                                      \
    5878              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5879              :          "move %0, $a0\n"                                         \
    5880              :          : /*out*/   "=r" (_res)                                  \
    5881              :          : /*in*/    "r" (&_argvec[0])                            \
    5882              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5883              :       );                                                          \
    5884              :       lval = (__typeof__(lval)) _res;                             \
    5885              :    } while (0)
    5886              : 
    5887              : #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
    5888              :    do {                                                           \
    5889              :       volatile OrigFn        _orig = (orig);                      \
    5890              :       volatile unsigned long _argvec[6];                          \
    5891              :       volatile unsigned long _res;                                \
    5892              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5893              :       _argvec[1] = (unsigned long)(arg1);                         \
    5894              :       _argvec[2] = (unsigned long)(arg2);                         \
    5895              :       _argvec[3] = (unsigned long)(arg3);                         \
    5896              :       _argvec[4] = (unsigned long)(arg4);                         \
    5897              :       _argvec[5] = (unsigned long)(arg5);                         \
    5898              :       __asm__ volatile(                                           \
    5899              :          "lw $t9, 0(%1)\n\t"                                      \
    5900              :          "lw $a0, 4(%1)\n\t"                                      \
    5901              :          "lw $a1, 8(%1)\n\t"                                      \
    5902              :          "lw $a2,12(%1)\n\t"                                      \
    5903              :          "lw $a3,16(%1)\n\t"                                      \
    5904              :          "lw $a4,20(%1)\n\t"                                      \
    5905              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5906              :          "move %0, $a0\n"                                         \
    5907              :          : /*out*/   "=r" (_res)                                  \
    5908              :          : /*in*/    "r" (&_argvec[0])                            \
    5909              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5910              :       );                                                          \
    5911              :       lval = (__typeof__(lval)) _res;                             \
    5912              :    } while (0)
    5913              : #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
    5914              :    do {                                                           \
    5915              :       volatile OrigFn        _orig = (orig);                      \
    5916              :       volatile unsigned long _argvec[7];                          \
    5917              :       volatile unsigned long _res;                                \
    5918              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5919              :       _argvec[1] = (unsigned long)(arg1);                         \
    5920              :       _argvec[2] = (unsigned long)(arg2);                         \
    5921              :       _argvec[3] = (unsigned long)(arg3);                         \
    5922              :       _argvec[4] = (unsigned long)(arg4);                         \
    5923              :       _argvec[5] = (unsigned long)(arg5);                         \
    5924              :       _argvec[6] = (unsigned long)(arg6);                         \
    5925              :       __asm__ volatile(                                           \
    5926              :          "lw $t9, 0(%1)\n\t"                                      \
    5927              :          "lw $a0, 4(%1)\n\t"                                      \
    5928              :          "lw $a1, 8(%1)\n\t"                                      \
    5929              :          "lw $a2,12(%1)\n\t"                                      \
    5930              :          "lw $a3,16(%1)\n\t"                                      \
    5931              :          "lw $a4,20(%1)\n\t"                                      \
    5932              :          "lw $a5,24(%1)\n\t"                                      \
    5933              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5934              :          "move %0, $a0\n"                                         \
    5935              :          : /*out*/   "=r" (_res)                                  \
    5936              :          : /*in*/    "r" (&_argvec[0])                            \
    5937              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5938              :       );                                                          \
    5939              :       lval = (__typeof__(lval)) _res;                             \
    5940              :    } while (0)
    5941              : 
    5942              : #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    5943              :                                  arg7)                            \
    5944              :    do {                                                           \
    5945              :       volatile OrigFn        _orig = (orig);                      \
    5946              :       volatile unsigned long _argvec[8];                          \
    5947              :       volatile unsigned long _res;                                \
    5948              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5949              :       _argvec[1] = (unsigned long)(arg1);                         \
    5950              :       _argvec[2] = (unsigned long)(arg2);                         \
    5951              :       _argvec[3] = (unsigned long)(arg3);                         \
    5952              :       _argvec[4] = (unsigned long)(arg4);                         \
    5953              :       _argvec[5] = (unsigned long)(arg5);                         \
    5954              :       _argvec[6] = (unsigned long)(arg6);                         \
    5955              :       _argvec[7] = (unsigned long)(arg7);                         \
    5956              :       __asm__ volatile(                                           \
    5957              :          "lw $t9, 0(%1)\n\t"                                      \
    5958              :          "lw $a0, 4(%1)\n\t"                                      \
    5959              :          "lw $a1, 8(%1)\n\t"                                      \
    5960              :          "lw $a2,12(%1)\n\t"                                      \
    5961              :          "lw $a3,16(%1)\n\t"                                      \
    5962              :          "lw $a4,20(%1)\n\t"                                      \
    5963              :          "lw $a5,24(%1)\n\t"                                      \
    5964              :          "lw $a6,28(%1)\n\t"                                      \
    5965              :          VALGRIND_CALL_NOREDIR_T9                                 \
    5966              :          "move %0, $a0\n"                                         \
    5967              :          : /*out*/   "=r" (_res)                                  \
    5968              :          : /*in*/    "r" (&_argvec[0])                            \
    5969              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    5970              :       );                                                          \
    5971              :       lval = (__typeof__(lval)) _res;                             \
    5972              :    } while (0)
    5973              : 
    5974              : #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    5975              :                                  arg7,arg8)                       \
    5976              :    do {                                                           \
    5977              :       volatile OrigFn        _orig = (orig);                      \
    5978              :       volatile unsigned long _argvec[9];                          \
    5979              :       volatile unsigned long _res;                                \
    5980              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    5981              :       _argvec[1] = (unsigned long)(arg1);                         \
    5982              :       _argvec[2] = (unsigned long)(arg2);                         \
    5983              :       _argvec[3] = (unsigned long)(arg3);                         \
    5984              :       _argvec[4] = (unsigned long)(arg4);                         \
    5985              :       _argvec[5] = (unsigned long)(arg5);                         \
    5986              :       _argvec[6] = (unsigned long)(arg6);                         \
    5987              :       _argvec[7] = (unsigned long)(arg7);                         \
    5988              :       _argvec[8] = (unsigned long)(arg8);                         \
    5989              :       __asm__ volatile(                                           \
    5990              :          "lw $t9, 0(%1)\n\t"                                      \
    5991              :          "lw $a0, 4(%1)\n\t"                                      \
    5992              :          "lw $a1, 8(%1)\n\t"                                      \
    5993              :          "lw $a2,12(%1)\n\t"                                      \
    5994              :          "lw $a3,16(%1)\n\t"                                      \
    5995              :          "lw $a4,20(%1)\n\t"                                      \
    5996              :          "lw $a5,24(%1)\n\t"                                      \
    5997              :          "lw $a6,28(%1)\n\t"                                      \
    5998              :          "lw $a7,32(%1)\n\t"                                      \
    5999              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6000              :          "move %0, $a0\n"                                         \
    6001              :          : /*out*/   "=r" (_res)                                  \
    6002              :          : /*in*/    "r" (&_argvec[0])                            \
    6003              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6004              :       );                                                          \
    6005              :       lval = (__typeof__(lval)) _res;                             \
    6006              :    } while (0)
    6007              : 
    6008              : #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    6009              :                                  arg7,arg8,arg9)                  \
    6010              :    do {                                                           \
    6011              :       volatile OrigFn        _orig = (orig);                      \
    6012              :       volatile unsigned long _argvec[10];                         \
    6013              :       volatile unsigned long _res;                                \
    6014              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    6015              :       _argvec[1] = (unsigned long)(arg1);                         \
    6016              :       _argvec[2] = (unsigned long)(arg2);                         \
    6017              :       _argvec[3] = (unsigned long)(arg3);                         \
    6018              :       _argvec[4] = (unsigned long)(arg4);                         \
    6019              :       _argvec[5] = (unsigned long)(arg5);                         \
    6020              :       _argvec[6] = (unsigned long)(arg6);                         \
    6021              :       _argvec[7] = (unsigned long)(arg7);                         \
    6022              :       _argvec[8] = (unsigned long)(arg8);                         \
    6023              :       _argvec[9] = (unsigned long)(arg9);                         \
    6024              :       __asm__ volatile(                                           \
    6025              :          "addiu $sp, $sp, -16  \n\t"                              \
    6026              :          "lw $t9,36(%1)        \n\t"                              \
    6027              :          "sw $t9, 0($sp)       \n\t"                              \
    6028              :          "lw $t9, 0(%1)        \n\t"                              \
    6029              :          "lw $a0, 4(%1)        \n\t"                              \
    6030              :          "lw $a1, 8(%1)        \n\t"                              \
    6031              :          "lw $a2,12(%1)        \n\t"                              \
    6032              :          "lw $a3,16(%1)        \n\t"                              \
    6033              :          "lw $a4,20(%1)        \n\t"                              \
    6034              :          "lw $a5,24(%1)        \n\t"                              \
    6035              :          "lw $a6,28(%1)        \n\t"                              \
    6036              :          "lw $a7,32(%1)        \n\t"                              \
    6037              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6038              :          "move %0, $a0         \n\t"                              \
    6039              :          "addiu $sp, $sp, 16   \n\t"                              \
    6040              :          : /*out*/   "=r" (_res)                                  \
    6041              :          : /*in*/    "r" (&_argvec[0])                            \
    6042              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6043              :       );                                                          \
    6044              :       lval = (__typeof__(lval)) _res;                             \
    6045              :    } while (0)
    6046              : 
    6047              : #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    6048              :                                   arg7,arg8,arg9,arg10)           \
    6049              :    do {                                                           \
    6050              :       volatile OrigFn        _orig = (orig);                      \
    6051              :       volatile unsigned long _argvec[11];                         \
    6052              :       volatile unsigned long _res;                                \
    6053              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    6054              :       _argvec[1] = (unsigned long)(arg1);                         \
    6055              :       _argvec[2] = (unsigned long)(arg2);                         \
    6056              :       _argvec[3] = (unsigned long)(arg3);                         \
    6057              :       _argvec[4] = (unsigned long)(arg4);                         \
    6058              :       _argvec[5] = (unsigned long)(arg5);                         \
    6059              :       _argvec[6] = (unsigned long)(arg6);                         \
    6060              :       _argvec[7] = (unsigned long)(arg7);                         \
    6061              :       _argvec[8] = (unsigned long)(arg8);                         \
    6062              :       _argvec[9] = (unsigned long)(arg9);                         \
    6063              :       _argvec[10] = (unsigned long)(arg10);                       \
    6064              :       __asm__ volatile(                                           \
    6065              :          "addiu $sp, $sp, -16  \n\t"                              \
    6066              :          "lw $t9,36(%1)        \n\t"                              \
    6067              :          "sw $t9, 0($sp)       \n\t"                              \
    6068              :          "lw $t9,40(%1)        \n\t"                              \
    6069              :          "sw $t9, 4($sp)       \n\t"                              \
    6070              :          "lw $t9, 0(%1)        \n\t"                              \
    6071              :          "lw $a0, 4(%1)        \n\t"                              \
    6072              :          "lw $a1, 8(%1)        \n\t"                              \
    6073              :          "lw $a2,12(%1)        \n\t"                              \
    6074              :          "lw $a3,16(%1)        \n\t"                              \
    6075              :          "lw $a4,20(%1)        \n\t"                              \
    6076              :          "lw $a5,24(%1)        \n\t"                              \
    6077              :          "lw $a6,28(%1)        \n\t"                              \
    6078              :          "lw $a7,32(%1)        \n\t"                              \
    6079              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6080              :          "move %0, $a0         \n\t"                              \
    6081              :          "addiu $sp, $sp, 16   \n\t"                              \
    6082              :          : /*out*/   "=r" (_res)                                  \
    6083              :          : /*in*/    "r" (&_argvec[0])                            \
    6084              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6085              :       );                                                          \
    6086              :       lval = (__typeof__(lval)) _res;                             \
    6087              :    } while (0)
    6088              : 
    6089              : #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
    6090              :                                   arg6,arg7,arg8,arg9,arg10,      \
    6091              :                                   arg11)                          \
    6092              :    do {                                                           \
    6093              :       volatile OrigFn        _orig = (orig);                      \
    6094              :       volatile unsigned long _argvec[12];                         \
    6095              :       volatile unsigned long _res;                                \
    6096              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    6097              :       _argvec[1] = (unsigned long)(arg1);                         \
    6098              :       _argvec[2] = (unsigned long)(arg2);                         \
    6099              :       _argvec[3] = (unsigned long)(arg3);                         \
    6100              :       _argvec[4] = (unsigned long)(arg4);                         \
    6101              :       _argvec[5] = (unsigned long)(arg5);                         \
    6102              :       _argvec[6] = (unsigned long)(arg6);                         \
    6103              :       _argvec[7] = (unsigned long)(arg7);                         \
    6104              :       _argvec[8] = (unsigned long)(arg8);                         \
    6105              :       _argvec[9] = (unsigned long)(arg9);                         \
    6106              :       _argvec[10] = (unsigned long)(arg10);                       \
    6107              :       _argvec[11] = (unsigned long)(arg11);                       \
    6108              :       __asm__ volatile(                                           \
    6109              :          "addiu $sp, $sp, -16  \n\t"                              \
    6110              :          "lw $t9,36(%1)        \n\t"                              \
    6111              :          "sw $t9, 0($sp)       \n\t"                              \
    6112              :          "lw $t9,40(%1)        \n\t"                              \
    6113              :          "sw $t9, 4($sp)       \n\t"                              \
    6114              :          "lw $t9,44(%1)        \n\t"                              \
    6115              :          "sw $t9, 8($sp)       \n\t"                              \
    6116              :          "lw $t9, 0(%1)        \n\t"                              \
    6117              :          "lw $a0, 4(%1)        \n\t"                              \
    6118              :          "lw $a1, 8(%1)        \n\t"                              \
    6119              :          "lw $a2,12(%1)        \n\t"                              \
    6120              :          "lw $a3,16(%1)        \n\t"                              \
    6121              :          "lw $a4,20(%1)        \n\t"                              \
    6122              :          "lw $a5,24(%1)        \n\t"                              \
    6123              :          "lw $a6,28(%1)        \n\t"                              \
    6124              :          "lw $a7,32(%1)        \n\t"                              \
    6125              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6126              :          "move %0, $a0         \n\t"                              \
    6127              :          "addiu $sp, $sp, 16   \n\t"                              \
    6128              :          : /*out*/   "=r" (_res)                                  \
    6129              :          : /*in*/    "r" (&_argvec[0])                            \
    6130              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6131              :       );                                                          \
    6132              :       lval = (__typeof__(lval)) _res;                             \
    6133              :    } while (0)
    6134              : 
    6135              : #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
    6136              :                                   arg6,arg7,arg8,arg9,arg10,      \
    6137              :                                   arg11,arg12)                    \
    6138              :    do {                                                           \
    6139              :       volatile OrigFn        _orig = (orig);                      \
    6140              :       volatile unsigned long _argvec[13];                         \
    6141              :       volatile unsigned long _res;                                \
    6142              :       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    6143              :       _argvec[1] = (unsigned long)(arg1);                         \
    6144              :       _argvec[2] = (unsigned long)(arg2);                         \
    6145              :       _argvec[3] = (unsigned long)(arg3);                         \
    6146              :       _argvec[4] = (unsigned long)(arg4);                         \
    6147              :       _argvec[5] = (unsigned long)(arg5);                         \
    6148              :       _argvec[6] = (unsigned long)(arg6);                         \
    6149              :       _argvec[7] = (unsigned long)(arg7);                         \
    6150              :       _argvec[8] = (unsigned long)(arg8);                         \
    6151              :       _argvec[9] = (unsigned long)(arg9);                         \
    6152              :       _argvec[10] = (unsigned long)(arg10);                       \
    6153              :       _argvec[11] = (unsigned long)(arg11);                       \
    6154              :       _argvec[12] = (unsigned long)(arg12);                       \
    6155              :       __asm__ volatile(                                           \
    6156              :          "addiu $sp, $sp, -16  \n\t"                              \
    6157              :          "lw $t9,36(%1)        \n\t"                              \
    6158              :          "sw $t9, 0($sp)       \n\t"                              \
    6159              :          "lw $t9,40(%1)        \n\t"                              \
    6160              :          "sw $t9, 4($sp)       \n\t"                              \
    6161              :          "lw $t9,44(%1)        \n\t"                              \
    6162              :          "sw $t9, 8($sp)       \n\t"                              \
    6163              :          "lw $t9,48(%1)        \n\t"                              \
    6164              :          "sw $t9,12($sp)       \n\t"                              \
    6165              :          "lw $t9, 0(%1)        \n\t"                              \
    6166              :          "lw $a0, 4(%1)        \n\t"                              \
    6167              :          "lw $a1, 8(%1)        \n\t"                              \
    6168              :          "lw $a2,12(%1)        \n\t"                              \
    6169              :          "lw $a3,16(%1)        \n\t"                              \
    6170              :          "lw $a4,20(%1)        \n\t"                              \
    6171              :          "lw $a5,24(%1)        \n\t"                              \
    6172              :          "lw $a6,28(%1)        \n\t"                              \
    6173              :          "lw $a7,32(%1)        \n\t"                              \
    6174              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6175              :          "move %0, $a0         \n\t"                              \
    6176              :          "addiu $sp, $sp, 16   \n\t"                              \
    6177              :          : /*out*/   "=r" (_res)                                  \
    6178              :          : /*in*/    "r" (&_argvec[0])                            \
    6179              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6180              :       );                                                          \
    6181              :       lval = (__typeof__(lval)) _res;                             \
    6182              :    } while (0)
    6183              : 
    6184              : #endif /* PLAT_nanomips_linux */
    6185              : 
    6186              : /* ------------------------- mips64-linux ------------------------- */
    6187              : 
    6188              : #if defined(PLAT_mips64_linux)
    6189              : 
    6190              : /* These regs are trashed by the hidden call. */
    6191              : #define __CALLER_SAVED_REGS "$2", "$3", "$4", "$5", "$6",       \
    6192              : "$7", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \
    6193              : "$25", "$31"
    6194              : 
    6195              : /* These CALL_FN_ macros assume that on mips64-linux,
    6196              :    sizeof(long long) == 8. */
    6197              : 
    6198              : #define MIPS64_LONG2REG_CAST(x) ((long long)(long)x)
    6199              : 
    6200              : #define CALL_FN_W_v(lval, orig)                                   \
    6201              :    do {                                                           \
    6202              :       volatile OrigFn        _orig = (orig);                      \
    6203              :       volatile unsigned long long _argvec[1];                     \
    6204              :       volatile unsigned long long _res;                           \
    6205              :       _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr);            \
    6206              :       __asm__ volatile(                                           \
    6207              :          "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
    6208              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6209              :          "move %0, $2\n"                                          \
    6210              :          : /*out*/   "=r" (_res)                                  \
    6211              :          : /*in*/    "0" (&_argvec[0])                            \
    6212              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6213              :       );                                                          \
    6214              :       lval = (__typeof__(lval)) (long)_res;                       \
    6215              :    } while (0)
    6216              : 
    6217              : #define CALL_FN_W_W(lval, orig, arg1)                             \
    6218              :    do {                                                           \
    6219              :       volatile OrigFn        _orig = (orig);                      \
    6220              :       volatile unsigned long long _argvec[2];                     \
    6221              :       volatile unsigned long long  _res;                          \
    6222              :       _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr);            \
    6223              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6224              :       __asm__ volatile(                                           \
    6225              :          "ld $4, 8(%1)\n\t"   /* arg1*/                           \
    6226              :          "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
    6227              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6228              :          "move %0, $2\n"                                          \
    6229              :          : /*out*/   "=r" (_res)                                  \
    6230              :          : /*in*/    "r" (&_argvec[0])                            \
    6231              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6232              :       );                                                          \
    6233              :       lval = (__typeof__(lval)) (long)_res;                       \
    6234              :    } while (0)
    6235              : 
    6236              : #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
    6237              :    do {                                                           \
    6238              :       volatile OrigFn        _orig = (orig);                      \
    6239              :       volatile unsigned long long _argvec[3];                     \
    6240              :       volatile unsigned long long _res;                           \
    6241              :       _argvec[0] = _orig.nraddr;                                  \
    6242              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6243              :       _argvec[2] = MIPS64_LONG2REG_CAST(arg2);                    \
    6244              :       __asm__ volatile(                                           \
    6245              :          "ld $4, 8(%1)\n\t"                                       \
    6246              :          "ld $5, 16(%1)\n\t"                                      \
    6247              :          "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
    6248              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6249              :          "move %0, $2\n"                                          \
    6250              :          : /*out*/   "=r" (_res)                                  \
    6251              :          : /*in*/    "r" (&_argvec[0])                            \
    6252              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6253              :       );                                                          \
    6254              :       lval = (__typeof__(lval)) (long)_res;                       \
    6255              :    } while (0)
    6256              : 
    6257              : 
    6258              : #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    6259              :    do {                                                           \
    6260              :       volatile OrigFn        _orig = (orig);                      \
    6261              :       volatile unsigned long long _argvec[4];                     \
    6262              :       volatile unsigned long long _res;                           \
    6263              :       _argvec[0] = _orig.nraddr;                                  \
    6264              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6265              :       _argvec[2] = MIPS64_LONG2REG_CAST(arg2);                    \
    6266              :       _argvec[3] = MIPS64_LONG2REG_CAST(arg3);                    \
    6267              :       __asm__ volatile(                                           \
    6268              :          "ld $4, 8(%1)\n\t"                                       \
    6269              :          "ld $5, 16(%1)\n\t"                                      \
    6270              :          "ld $6, 24(%1)\n\t"                                      \
    6271              :          "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
    6272              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6273              :          "move %0, $2\n"                                          \
    6274              :          : /*out*/   "=r" (_res)                                  \
    6275              :          : /*in*/    "r" (&_argvec[0])                            \
    6276              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6277              :       );                                                          \
    6278              :       lval = (__typeof__(lval)) (long)_res;                       \
    6279              :    } while (0)
    6280              : 
    6281              : #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
    6282              :    do {                                                           \
    6283              :       volatile OrigFn        _orig = (orig);                      \
    6284              :       volatile unsigned long long _argvec[5];                     \
    6285              :       volatile unsigned long long _res;                           \
    6286              :       _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr);            \
    6287              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6288              :       _argvec[2] = MIPS64_LONG2REG_CAST(arg2);                    \
    6289              :       _argvec[3] = MIPS64_LONG2REG_CAST(arg3);                    \
    6290              :       _argvec[4] = MIPS64_LONG2REG_CAST(arg4);                    \
    6291              :       __asm__ volatile(                                           \
    6292              :          "ld $4, 8(%1)\n\t"                                       \
    6293              :          "ld $5, 16(%1)\n\t"                                      \
    6294              :          "ld $6, 24(%1)\n\t"                                      \
    6295              :          "ld $7, 32(%1)\n\t"                                      \
    6296              :          "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
    6297              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6298              :          "move %0, $2\n"                                          \
    6299              :          : /*out*/   "=r" (_res)                                  \
    6300              :          : /*in*/    "r" (&_argvec[0])                            \
    6301              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6302              :       );                                                          \
    6303              :       lval = (__typeof__(lval)) (long)_res;                       \
    6304              :    } while (0)
    6305              : 
    6306              : #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
    6307              :    do {                                                           \
    6308              :       volatile OrigFn        _orig = (orig);                      \
    6309              :       volatile unsigned long long _argvec[6];                     \
    6310              :       volatile unsigned long long _res;                           \
    6311              :       _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr);            \
    6312              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6313              :       _argvec[2] = MIPS64_LONG2REG_CAST(arg2);                    \
    6314              :       _argvec[3] = MIPS64_LONG2REG_CAST(arg3);                    \
    6315              :       _argvec[4] = MIPS64_LONG2REG_CAST(arg4);                    \
    6316              :       _argvec[5] = MIPS64_LONG2REG_CAST(arg5);                    \
    6317              :       __asm__ volatile(                                           \
    6318              :          "ld $4, 8(%1)\n\t"                                       \
    6319              :          "ld $5, 16(%1)\n\t"                                      \
    6320              :          "ld $6, 24(%1)\n\t"                                      \
    6321              :          "ld $7, 32(%1)\n\t"                                      \
    6322              :          "ld $8, 40(%1)\n\t"                                      \
    6323              :          "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
    6324              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6325              :          "move %0, $2\n"                                          \
    6326              :          : /*out*/   "=r" (_res)                                  \
    6327              :          : /*in*/    "r" (&_argvec[0])                            \
    6328              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6329              :       );                                                          \
    6330              :       lval = (__typeof__(lval)) (long)_res;                       \
    6331              :    } while (0)
    6332              : 
    6333              : #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
    6334              :    do {                                                           \
    6335              :       volatile OrigFn        _orig = (orig);                      \
    6336              :       volatile unsigned long long _argvec[7];                     \
    6337              :       volatile unsigned long long _res;                           \
    6338              :       _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr);            \
    6339              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6340              :       _argvec[2] = MIPS64_LONG2REG_CAST(arg2);                    \
    6341              :       _argvec[3] = MIPS64_LONG2REG_CAST(arg3);                    \
    6342              :       _argvec[4] = MIPS64_LONG2REG_CAST(arg4);                    \
    6343              :       _argvec[5] = MIPS64_LONG2REG_CAST(arg5);                    \
    6344              :       _argvec[6] = MIPS64_LONG2REG_CAST(arg6);                    \
    6345              :       __asm__ volatile(                                           \
    6346              :          "ld $4, 8(%1)\n\t"                                       \
    6347              :          "ld $5, 16(%1)\n\t"                                      \
    6348              :          "ld $6, 24(%1)\n\t"                                      \
    6349              :          "ld $7, 32(%1)\n\t"                                      \
    6350              :          "ld $8, 40(%1)\n\t"                                      \
    6351              :          "ld $9, 48(%1)\n\t"                                      \
    6352              :          "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
    6353              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6354              :          "move %0, $2\n"                                          \
    6355              :          : /*out*/   "=r" (_res)                                  \
    6356              :          : /*in*/    "r" (&_argvec[0])                            \
    6357              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6358              :       );                                                          \
    6359              :       lval = (__typeof__(lval)) (long)_res;                       \
    6360              :    } while (0)
    6361              : 
    6362              : #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    6363              :                                  arg7)                            \
    6364              :    do {                                                           \
    6365              :       volatile OrigFn        _orig = (orig);                      \
    6366              :       volatile unsigned long long _argvec[8];                     \
    6367              :       volatile unsigned long long _res;                           \
    6368              :       _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr);            \
    6369              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6370              :       _argvec[2] = MIPS64_LONG2REG_CAST(arg2);                    \
    6371              :       _argvec[3] = MIPS64_LONG2REG_CAST(arg3);                    \
    6372              :       _argvec[4] = MIPS64_LONG2REG_CAST(arg4);                    \
    6373              :       _argvec[5] = MIPS64_LONG2REG_CAST(arg5);                    \
    6374              :       _argvec[6] = MIPS64_LONG2REG_CAST(arg6);                    \
    6375              :       _argvec[7] = MIPS64_LONG2REG_CAST(arg7);                    \
    6376              :       __asm__ volatile(                                           \
    6377              :          "ld $4, 8(%1)\n\t"                                       \
    6378              :          "ld $5, 16(%1)\n\t"                                      \
    6379              :          "ld $6, 24(%1)\n\t"                                      \
    6380              :          "ld $7, 32(%1)\n\t"                                      \
    6381              :          "ld $8, 40(%1)\n\t"                                      \
    6382              :          "ld $9, 48(%1)\n\t"                                      \
    6383              :          "ld $10, 56(%1)\n\t"                                     \
    6384              :          "ld $25, 0(%1) \n\t"  /* target->t9 */                   \
    6385              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6386              :          "move %0, $2\n"                                          \
    6387              :          : /*out*/   "=r" (_res)                                  \
    6388              :          : /*in*/    "r" (&_argvec[0])                            \
    6389              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6390              :       );                                                          \
    6391              :       lval = (__typeof__(lval)) (long)_res;                       \
    6392              :    } while (0)
    6393              : 
    6394              : #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    6395              :                                  arg7,arg8)                       \
    6396              :    do {                                                           \
    6397              :       volatile OrigFn        _orig = (orig);                      \
    6398              :       volatile unsigned long long _argvec[9];                     \
    6399              :       volatile unsigned long long _res;                           \
    6400              :       _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr);            \
    6401              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6402              :       _argvec[2] = MIPS64_LONG2REG_CAST(arg2);                    \
    6403              :       _argvec[3] = MIPS64_LONG2REG_CAST(arg3);                    \
    6404              :       _argvec[4] = MIPS64_LONG2REG_CAST(arg4);                    \
    6405              :       _argvec[5] = MIPS64_LONG2REG_CAST(arg5);                    \
    6406              :       _argvec[6] = MIPS64_LONG2REG_CAST(arg6);                    \
    6407              :       _argvec[7] = MIPS64_LONG2REG_CAST(arg7);                    \
    6408              :       _argvec[8] = MIPS64_LONG2REG_CAST(arg8);                    \
    6409              :       __asm__ volatile(                                           \
    6410              :          "ld $4, 8(%1)\n\t"                                       \
    6411              :          "ld $5, 16(%1)\n\t"                                      \
    6412              :          "ld $6, 24(%1)\n\t"                                      \
    6413              :          "ld $7, 32(%1)\n\t"                                      \
    6414              :          "ld $8, 40(%1)\n\t"                                      \
    6415              :          "ld $9, 48(%1)\n\t"                                      \
    6416              :          "ld $10, 56(%1)\n\t"                                     \
    6417              :          "ld $11, 64(%1)\n\t"                                     \
    6418              :          "ld $25, 0(%1) \n\t"  /* target->t9 */                   \
    6419              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6420              :          "move %0, $2\n"                                          \
    6421              :          : /*out*/   "=r" (_res)                                  \
    6422              :          : /*in*/    "r" (&_argvec[0])                            \
    6423              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6424              :       );                                                          \
    6425              :       lval = (__typeof__(lval)) (long)_res;                       \
    6426              :    } while (0)
    6427              : 
    6428              : #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    6429              :                                  arg7,arg8,arg9)                  \
    6430              :    do {                                                           \
    6431              :       volatile OrigFn        _orig = (orig);                      \
    6432              :       volatile unsigned long long _argvec[10];                    \
    6433              :       volatile unsigned long long _res;                           \
    6434              :       _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr);            \
    6435              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6436              :       _argvec[2] = MIPS64_LONG2REG_CAST(arg2);                    \
    6437              :       _argvec[3] = MIPS64_LONG2REG_CAST(arg3);                    \
    6438              :       _argvec[4] = MIPS64_LONG2REG_CAST(arg4);                    \
    6439              :       _argvec[5] = MIPS64_LONG2REG_CAST(arg5);                    \
    6440              :       _argvec[6] = MIPS64_LONG2REG_CAST(arg6);                    \
    6441              :       _argvec[7] = MIPS64_LONG2REG_CAST(arg7);                    \
    6442              :       _argvec[8] = MIPS64_LONG2REG_CAST(arg8);                    \
    6443              :       _argvec[9] = MIPS64_LONG2REG_CAST(arg9);                    \
    6444              :       __asm__ volatile(                                           \
    6445              :          "dsubu $29, $29, 8\n\t"                                  \
    6446              :          "ld $4, 72(%1)\n\t"                                      \
    6447              :          "sd $4, 0($29)\n\t"                                      \
    6448              :          "ld $4, 8(%1)\n\t"                                       \
    6449              :          "ld $5, 16(%1)\n\t"                                      \
    6450              :          "ld $6, 24(%1)\n\t"                                      \
    6451              :          "ld $7, 32(%1)\n\t"                                      \
    6452              :          "ld $8, 40(%1)\n\t"                                      \
    6453              :          "ld $9, 48(%1)\n\t"                                      \
    6454              :          "ld $10, 56(%1)\n\t"                                     \
    6455              :          "ld $11, 64(%1)\n\t"                                     \
    6456              :          "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
    6457              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6458              :          "daddu $29, $29, 8\n\t"                                  \
    6459              :          "move %0, $2\n"                                          \
    6460              :          : /*out*/   "=r" (_res)                                  \
    6461              :          : /*in*/    "r" (&_argvec[0])                            \
    6462              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6463              :       );                                                          \
    6464              :       lval = (__typeof__(lval)) (long)_res;                       \
    6465              :    } while (0)
    6466              : 
    6467              : #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
    6468              :                                   arg7,arg8,arg9,arg10)           \
    6469              :    do {                                                           \
    6470              :       volatile OrigFn        _orig = (orig);                      \
    6471              :       volatile unsigned long long _argvec[11];                    \
    6472              :       volatile unsigned long long _res;                           \
    6473              :       _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr);            \
    6474              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6475              :       _argvec[2] = MIPS64_LONG2REG_CAST(arg2);                    \
    6476              :       _argvec[3] = MIPS64_LONG2REG_CAST(arg3);                    \
    6477              :       _argvec[4] = MIPS64_LONG2REG_CAST(arg4);                    \
    6478              :       _argvec[5] = MIPS64_LONG2REG_CAST(arg5);                    \
    6479              :       _argvec[6] = MIPS64_LONG2REG_CAST(arg6);                    \
    6480              :       _argvec[7] = MIPS64_LONG2REG_CAST(arg7);                    \
    6481              :       _argvec[8] = MIPS64_LONG2REG_CAST(arg8);                    \
    6482              :       _argvec[9] = MIPS64_LONG2REG_CAST(arg9);                    \
    6483              :       _argvec[10] = MIPS64_LONG2REG_CAST(arg10);                  \
    6484              :       __asm__ volatile(                                           \
    6485              :          "dsubu $29, $29, 16\n\t"                                 \
    6486              :          "ld $4, 72(%1)\n\t"                                      \
    6487              :          "sd $4, 0($29)\n\t"                                      \
    6488              :          "ld $4, 80(%1)\n\t"                                      \
    6489              :          "sd $4, 8($29)\n\t"                                      \
    6490              :          "ld $4, 8(%1)\n\t"                                       \
    6491              :          "ld $5, 16(%1)\n\t"                                      \
    6492              :          "ld $6, 24(%1)\n\t"                                      \
    6493              :          "ld $7, 32(%1)\n\t"                                      \
    6494              :          "ld $8, 40(%1)\n\t"                                      \
    6495              :          "ld $9, 48(%1)\n\t"                                      \
    6496              :          "ld $10, 56(%1)\n\t"                                     \
    6497              :          "ld $11, 64(%1)\n\t"                                     \
    6498              :          "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
    6499              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6500              :          "daddu $29, $29, 16\n\t"                                 \
    6501              :          "move %0, $2\n"                                          \
    6502              :          : /*out*/   "=r" (_res)                                  \
    6503              :          : /*in*/    "r" (&_argvec[0])                            \
    6504              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6505              :       );                                                          \
    6506              :       lval = (__typeof__(lval)) (long)_res;                       \
    6507              :    } while (0)
    6508              : 
    6509              : #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
    6510              :                                   arg6,arg7,arg8,arg9,arg10,      \
    6511              :                                   arg11)                          \
    6512              :    do {                                                           \
    6513              :       volatile OrigFn        _orig = (orig);                      \
    6514              :       volatile unsigned long long _argvec[12];                    \
    6515              :       volatile unsigned long long _res;                           \
    6516              :       _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr);            \
    6517              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6518              :       _argvec[2] = MIPS64_LONG2REG_CAST(arg2);                    \
    6519              :       _argvec[3] = MIPS64_LONG2REG_CAST(arg3);                    \
    6520              :       _argvec[4] = MIPS64_LONG2REG_CAST(arg4);                    \
    6521              :       _argvec[5] = MIPS64_LONG2REG_CAST(arg5);                    \
    6522              :       _argvec[6] = MIPS64_LONG2REG_CAST(arg6);                    \
    6523              :       _argvec[7] = MIPS64_LONG2REG_CAST(arg7);                    \
    6524              :       _argvec[8] = MIPS64_LONG2REG_CAST(arg8);                    \
    6525              :       _argvec[9] = MIPS64_LONG2REG_CAST(arg9);                    \
    6526              :       _argvec[10] = MIPS64_LONG2REG_CAST(arg10);                  \
    6527              :       _argvec[11] = MIPS64_LONG2REG_CAST(arg11);                  \
    6528              :       __asm__ volatile(                                           \
    6529              :          "dsubu $29, $29, 24\n\t"                                 \
    6530              :          "ld $4, 72(%1)\n\t"                                      \
    6531              :          "sd $4, 0($29)\n\t"                                      \
    6532              :          "ld $4, 80(%1)\n\t"                                      \
    6533              :          "sd $4, 8($29)\n\t"                                      \
    6534              :          "ld $4, 88(%1)\n\t"                                      \
    6535              :          "sd $4, 16($29)\n\t"                                     \
    6536              :          "ld $4, 8(%1)\n\t"                                       \
    6537              :          "ld $5, 16(%1)\n\t"                                      \
    6538              :          "ld $6, 24(%1)\n\t"                                      \
    6539              :          "ld $7, 32(%1)\n\t"                                      \
    6540              :          "ld $8, 40(%1)\n\t"                                      \
    6541              :          "ld $9, 48(%1)\n\t"                                      \
    6542              :          "ld $10, 56(%1)\n\t"                                     \
    6543              :          "ld $11, 64(%1)\n\t"                                     \
    6544              :          "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
    6545              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6546              :          "daddu $29, $29, 24\n\t"                                 \
    6547              :          "move %0, $2\n"                                          \
    6548              :          : /*out*/   "=r" (_res)                                  \
    6549              :          : /*in*/    "r" (&_argvec[0])                            \
    6550              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6551              :       );                                                          \
    6552              :       lval = (__typeof__(lval)) (long)_res;                       \
    6553              :    } while (0)
    6554              : 
    6555              : #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
    6556              :                                   arg6,arg7,arg8,arg9,arg10,      \
    6557              :                                   arg11,arg12)                    \
    6558              :    do {                                                           \
    6559              :       volatile OrigFn        _orig = (orig);                      \
    6560              :       volatile unsigned long long _argvec[13];                    \
    6561              :       volatile unsigned long long _res;                           \
    6562              :       _argvec[0] = MIPS64_LONG2REG_CAST(_orig.nraddr);            \
    6563              :       _argvec[1] = MIPS64_LONG2REG_CAST(arg1);                    \
    6564              :       _argvec[2] = MIPS64_LONG2REG_CAST(arg2);                    \
    6565              :       _argvec[3] = MIPS64_LONG2REG_CAST(arg3);                    \
    6566              :       _argvec[4] = MIPS64_LONG2REG_CAST(arg4);                    \
    6567              :       _argvec[5] = MIPS64_LONG2REG_CAST(arg5);                    \
    6568              :       _argvec[6] = MIPS64_LONG2REG_CAST(arg6);                    \
    6569              :       _argvec[7] = MIPS64_LONG2REG_CAST(arg7);                    \
    6570              :       _argvec[8] = MIPS64_LONG2REG_CAST(arg8);                    \
    6571              :       _argvec[9] = MIPS64_LONG2REG_CAST(arg9);                    \
    6572              :       _argvec[10] = MIPS64_LONG2REG_CAST(arg10);                  \
    6573              :       _argvec[11] = MIPS64_LONG2REG_CAST(arg11);                  \
    6574              :       _argvec[12] = MIPS64_LONG2REG_CAST(arg12);                  \
    6575              :       __asm__ volatile(                                           \
    6576              :          "dsubu $29, $29, 32\n\t"                                 \
    6577              :          "ld $4, 72(%1)\n\t"                                      \
    6578              :          "sd $4, 0($29)\n\t"                                      \
    6579              :          "ld $4, 80(%1)\n\t"                                      \
    6580              :          "sd $4, 8($29)\n\t"                                      \
    6581              :          "ld $4, 88(%1)\n\t"                                      \
    6582              :          "sd $4, 16($29)\n\t"                                     \
    6583              :          "ld $4, 96(%1)\n\t"                                      \
    6584              :          "sd $4, 24($29)\n\t"                                     \
    6585              :          "ld $4, 8(%1)\n\t"                                       \
    6586              :          "ld $5, 16(%1)\n\t"                                      \
    6587              :          "ld $6, 24(%1)\n\t"                                      \
    6588              :          "ld $7, 32(%1)\n\t"                                      \
    6589              :          "ld $8, 40(%1)\n\t"                                      \
    6590              :          "ld $9, 48(%1)\n\t"                                      \
    6591              :          "ld $10, 56(%1)\n\t"                                     \
    6592              :          "ld $11, 64(%1)\n\t"                                     \
    6593              :          "ld $25, 0(%1)\n\t"  /* target->t9 */                    \
    6594              :          VALGRIND_CALL_NOREDIR_T9                                 \
    6595              :          "daddu $29, $29, 32\n\t"                                 \
    6596              :          "move %0, $2\n"                                          \
    6597              :          : /*out*/   "=r" (_res)                                  \
    6598              :          : /*in*/    "r" (&_argvec[0])                            \
    6599              :          : /*trash*/ "memory", __CALLER_SAVED_REGS                \
    6600              :       );                                                          \
    6601              :       lval = (__typeof__(lval)) (long)_res;                       \
    6602              :    } while (0)
    6603              : 
    6604              : #endif /* PLAT_mips64_linux */
    6605              : 
    6606              : /* ------------------------------------------------------------------ */
    6607              : /* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
    6608              : /*                                                                    */
    6609              : /* ------------------------------------------------------------------ */
    6610              : 
    6611              : /* Some request codes.  There are many more of these, but most are not
    6612              :    exposed to end-user view.  These are the public ones, all of the
    6613              :    form 0x1000 + small_number.
    6614              : 
    6615              :    Core ones are in the range 0x00000000--0x0000ffff.  The non-public
    6616              :    ones start at 0x2000.
    6617              : */
    6618              : 
    6619              : /* These macros are used by tools -- they must be public, but don't
    6620              :    embed them into other programs. */
    6621              : #define VG_USERREQ_TOOL_BASE(a,b) \
    6622              :    ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
    6623              : #define VG_IS_TOOL_USERREQ(a, b, v) \
    6624              :    (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
    6625              : 
    6626              : /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !! 
    6627              :    This enum comprises an ABI exported by Valgrind to programs
    6628              :    which use client requests.  DO NOT CHANGE THE NUMERIC VALUES OF THESE
    6629              :    ENTRIES, NOR DELETE ANY -- add new ones at the end of the most
    6630              :    relevant group. */
    6631              : typedef
    6632              :    enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
    6633              :           VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
    6634              : 
    6635              :           /* These allow any function to be called from the simulated
    6636              :              CPU but run on the real CPU.  Nb: the first arg passed to
    6637              :              the function is always the ThreadId of the running
    6638              :              thread!  So CLIENT_CALL0 actually requires a 1 arg
    6639              :              function, etc. */
    6640              :           VG_USERREQ__CLIENT_CALL0 = 0x1101,
    6641              :           VG_USERREQ__CLIENT_CALL1 = 0x1102,
    6642              :           VG_USERREQ__CLIENT_CALL2 = 0x1103,
    6643              :           VG_USERREQ__CLIENT_CALL3 = 0x1104,
    6644              : 
    6645              :           /* Can be useful in regression testing suites -- eg. can
    6646              :              send Valgrind's output to /dev/null and still count
    6647              :              errors. */
    6648              :           VG_USERREQ__COUNT_ERRORS = 0x1201,
    6649              : 
    6650              :           /* Allows the client program and/or gdbserver to execute a monitor
    6651              :              command. */
    6652              :           VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,
    6653              : 
    6654              :           /* Allows the client program to change a dynamic command line
    6655              :              option.  */
    6656              :           VG_USERREQ__CLO_CHANGE = 0x1203,
    6657              : 
    6658              :           /* These are useful and can be interpreted by any tool that
    6659              :              tracks malloc() et al, by using vg_replace_malloc.c. */
    6660              :           VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
    6661              :           VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b,
    6662              :           VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
    6663              :           /* Memory pool support. */
    6664              :           VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
    6665              :           VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
    6666              :           VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
    6667              :           VG_USERREQ__MEMPOOL_FREE     = 0x1306,
    6668              :           VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
    6669              :           VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
    6670              :           VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
    6671              :           VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
    6672              : 
    6673              :           /* Allow printfs to valgrind log. */
    6674              :           /* The first two pass the va_list argument by value, which
    6675              :              assumes it is the same size as or smaller than a UWord,
    6676              :              which generally isn't the case.  Hence are deprecated.
    6677              :              The second two pass the vargs by reference and so are
    6678              :              immune to this problem. */
    6679              :           /* both :: char* fmt, va_list vargs (DEPRECATED) */
    6680              :           VG_USERREQ__PRINTF           = 0x1401,
    6681              :           VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
    6682              :           /* both :: char* fmt, va_list* vargs */
    6683              :           VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
    6684              :           VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,
    6685              : 
    6686              :           /* Stack support. */
    6687              :           VG_USERREQ__STACK_REGISTER   = 0x1501,
    6688              :           VG_USERREQ__STACK_DEREGISTER = 0x1502,
    6689              :           VG_USERREQ__STACK_CHANGE     = 0x1503,
    6690              : 
    6691              :           /* Wine support */
    6692              :           VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601,
    6693              : 
    6694              :           /* Querying of debug info. */
    6695              :           VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701,
    6696              : 
    6697              :           /* Disable/enable error reporting level.  Takes a single
    6698              :              Word arg which is the delta to this thread's error
    6699              :              disablement indicator.  Hence 1 disables or further
    6700              :              disables errors, and -1 moves back towards enablement.
    6701              :              Other values are not allowed. */
    6702              :           VG_USERREQ__CHANGE_ERR_DISABLEMENT = 0x1801,
    6703              : 
    6704              :           /* Some requests used for Valgrind internal, such as
    6705              :              self-test or self-hosting. */
    6706              :           /* Initialise IR injection */
    6707              :           VG_USERREQ__VEX_INIT_FOR_IRI = 0x1901,
    6708              :           /* Used by Inner Valgrind to inform Outer Valgrind where to
    6709              :              find the list of inner guest threads */
    6710              :           VG_USERREQ__INNER_THREADS    = 0x1902
    6711              :    } Vg_ClientRequest;
    6712              : 
    6713              : #if !defined(__GNUC__)
    6714              : #  define __extension__ /* */
    6715              : #endif
    6716              : 
    6717              : 
    6718              : /* Returns the number of Valgrinds this code is running under.  That
    6719              :    is, 0 if running natively, 1 if running under Valgrind, 2 if
    6720              :    running under Valgrind which is running under another Valgrind,
    6721              :    etc. */
    6722              : #define RUNNING_ON_VALGRIND                                           \
    6723              :     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */,         \
    6724              :                                     VG_USERREQ__RUNNING_ON_VALGRIND,  \
    6725              :                                     0, 0, 0, 0, 0)                    \
    6726              : 
    6727              : 
    6728              : /* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
    6729              :    _qzz_len - 1].  Useful if you are debugging a JITter or some such,
    6730              :    since it provides a way to make sure valgrind will retranslate the
    6731              :    invalidated area.  Returns no value. */
    6732              : #define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)              \
    6733              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DISCARD_TRANSLATIONS,  \
    6734              :                                     _qzz_addr, _qzz_len, 0, 0, 0)
    6735              : 
    6736              : #define VALGRIND_INNER_THREADS(_qzz_addr)                               \
    6737              :    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__INNER_THREADS,           \
    6738              :                                    _qzz_addr, 0, 0, 0, 0)
    6739              : 
    6740              : 
    6741              : /* These requests are for getting Valgrind itself to print something.
    6742              :    Possibly with a backtrace.  This is a really ugly hack.  The return value
    6743              :    is the number of characters printed, excluding the "**<pid>** " part at the
    6744              :    start and the backtrace (if present). */
    6745              : 
    6746              : #if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
    6747              : /* Modern GCC will optimize the static routine out if unused,
    6748              :    and unused attribute will shut down warnings about it.  */
    6749              : static int VALGRIND_PRINTF(const char *format, ...)
    6750              :    __attribute__((format(__printf__, 1, 2), __unused__));
    6751              : #endif
    6752              : static int
    6753              : #if defined(_MSC_VER)
    6754              : __inline
    6755              : #endif
    6756            0 : VALGRIND_PRINTF(const char *format, ...)
    6757              : {
    6758              : #if defined(NVALGRIND)
    6759              :    (void)format;
    6760              :    return 0;
    6761              : #else /* NVALGRIND */
    6762              : #if defined(_MSC_VER) || defined(__MINGW64__)
    6763              :    uintptr_t _qzz_res;
    6764              : #else
    6765              :    unsigned long _qzz_res;
    6766              : #endif
    6767              :    va_list vargs;
    6768            0 :    va_start(vargs, format);
    6769              : #if defined(_MSC_VER) || defined(__MINGW64__)
    6770              :    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
    6771              :                               VG_USERREQ__PRINTF_VALIST_BY_REF,
    6772              :                               (uintptr_t)format,
    6773              :                               (uintptr_t)&vargs,
    6774              :                               0, 0, 0);
    6775              : #else
    6776            0 :    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
    6777              :                               VG_USERREQ__PRINTF_VALIST_BY_REF,
    6778              :                               (unsigned long)format,
    6779              :                               (unsigned long)&vargs, 
    6780              :                               0, 0, 0);
    6781              : #endif
    6782            0 :    va_end(vargs);
    6783            0 :    return (int)_qzz_res;
    6784              : #endif /* NVALGRIND */
    6785              : }
    6786              : 
    6787              : #if defined(__GNUC__) || defined(__INTEL_COMPILER) && !defined(_MSC_VER)
    6788              : static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
    6789              :    __attribute__((format(__printf__, 1, 2), __unused__));
    6790              : #endif
    6791              : static int
    6792              : #if defined(_MSC_VER)
    6793              : __inline
    6794              : #endif
    6795            0 : VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
    6796              : {
    6797              : #if defined(NVALGRIND)
    6798              :    (void)format;
    6799              :    return 0;
    6800              : #else /* NVALGRIND */
    6801              : #if defined(_MSC_VER) || defined(__MINGW64__)
    6802              :    uintptr_t _qzz_res;
    6803              : #else
    6804              :    unsigned long _qzz_res;
    6805              : #endif
    6806              :    va_list vargs;
    6807            0 :    va_start(vargs, format);
    6808              : #if defined(_MSC_VER) || defined(__MINGW64__)
    6809              :    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
    6810              :                               VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
    6811              :                               (uintptr_t)format,
    6812              :                               (uintptr_t)&vargs,
    6813              :                               0, 0, 0);
    6814              : #else
    6815            0 :    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
    6816              :                               VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
    6817              :                               (unsigned long)format,
    6818              :                               (unsigned long)&vargs, 
    6819              :                               0, 0, 0);
    6820              : #endif
    6821            0 :    va_end(vargs);
    6822            0 :    return (int)_qzz_res;
    6823              : #endif /* NVALGRIND */
    6824              : }
    6825              : 
    6826              : 
    6827              : /* These requests allow control to move from the simulated CPU to the
    6828              :    real CPU, calling an arbitrary function.
    6829              :    
    6830              :    Note that the current ThreadId is inserted as the first argument.
    6831              :    So this call:
    6832              : 
    6833              :      VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
    6834              : 
    6835              :    requires f to have this signature:
    6836              : 
    6837              :      Word f(Word tid, Word arg1, Word arg2)
    6838              : 
    6839              :    where "Word" is a word-sized type.
    6840              : 
    6841              :    Note that these client requests are not entirely reliable.  For example,
    6842              :    if you call a function with them that subsequently calls printf(),
    6843              :    there's a high chance Valgrind will crash.  Generally, your prospects of
    6844              :    these working are made higher if the called function does not refer to
    6845              :    any global variables, and does not refer to any libc or other functions
    6846              :    (printf et al).  Any kind of entanglement with libc or dynamic linking is
    6847              :    likely to have a bad outcome, for tricky reasons which we've grappled
    6848              :    with a lot in the past.
    6849              : */
    6850              : #define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
    6851              :     VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,       \
    6852              :                                     VG_USERREQ__CLIENT_CALL0,     \
    6853              :                                     _qyy_fn,                      \
    6854              :                                     0, 0, 0, 0)
    6855              : 
    6856              : #define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)                    \
    6857              :     VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
    6858              :                                     VG_USERREQ__CLIENT_CALL1,          \
    6859              :                                     _qyy_fn,                           \
    6860              :                                     _qyy_arg1, 0, 0, 0)
    6861              : 
    6862              : #define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)         \
    6863              :     VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,            \
    6864              :                                     VG_USERREQ__CLIENT_CALL2,          \
    6865              :                                     _qyy_fn,                           \
    6866              :                                     _qyy_arg1, _qyy_arg2, 0, 0)
    6867              : 
    6868              : #define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
    6869              :     VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */,             \
    6870              :                                     VG_USERREQ__CLIENT_CALL3,           \
    6871              :                                     _qyy_fn,                            \
    6872              :                                     _qyy_arg1, _qyy_arg2,               \
    6873              :                                     _qyy_arg3, 0)
    6874              : 
    6875              : 
    6876              : /* Counts the number of errors that have been recorded by a tool.  Nb:
    6877              :    the tool must record the errors with VG_(maybe_record_error)() or
    6878              :    VG_(unique_error)() for them to be counted. */
    6879              : #define VALGRIND_COUNT_ERRORS                                     \
    6880              :     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(                    \
    6881              :                                0 /* default return */,            \
    6882              :                                VG_USERREQ__COUNT_ERRORS,          \
    6883              :                                0, 0, 0, 0, 0)
    6884              : 
    6885              : /* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
    6886              :    when heap blocks are allocated in order to give accurate results.  This
    6887              :    happens automatically for the standard allocator functions such as
    6888              :    malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
    6889              :    delete[], etc.
    6890              : 
    6891              :    But if your program uses a custom allocator, this doesn't automatically
    6892              :    happen, and Valgrind will not do as well.  For example, if you allocate
    6893              :    superblocks with mmap() and then allocates chunks of the superblocks, all
    6894              :    Valgrind's observations will be at the mmap() level and it won't know that
    6895              :    the chunks should be considered separate entities.  In Memcheck's case,
    6896              :    that means you probably won't get heap block overrun detection (because
    6897              :    there won't be redzones marked as unaddressable) and you definitely won't
    6898              :    get any leak detection.
    6899              : 
    6900              :    The following client requests allow a custom allocator to be annotated so
    6901              :    that it can be handled accurately by Valgrind.
    6902              : 
    6903              :    VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
    6904              :    by a malloc()-like function.  For Memcheck (an illustrative case), this
    6905              :    does two things:
    6906              : 
    6907              :    - It records that the block has been allocated.  This means any addresses
    6908              :      within the block mentioned in error messages will be
    6909              :      identified as belonging to the block.  It also means that if the block
    6910              :      isn't freed it will be detected by the leak checker.
    6911              : 
    6912              :    - It marks the block as being addressable and undefined (if 'is_zeroed' is
    6913              :      not set), or addressable and defined (if 'is_zeroed' is set).  This
    6914              :      controls how accesses to the block by the program are handled.
    6915              :    
    6916              :    'addr' is the start of the usable block (ie. after any
    6917              :    redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
    6918              :    can apply redzones -- these are blocks of padding at the start and end of
    6919              :    each block.  Adding redzones is recommended as it makes it much more likely
    6920              :    Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
    6921              :    zeroed (or filled with another predictable value), as is the case for
    6922              :    calloc().
    6923              :    
    6924              :    VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
    6925              :    heap block -- that will be used by the client program -- is allocated.
    6926              :    It's best to put it at the outermost level of the allocator if possible;
    6927              :    for example, if you have a function my_alloc() which calls
    6928              :    internal_alloc(), and the client request is put inside internal_alloc(),
    6929              :    stack traces relating to the heap block will contain entries for both
    6930              :    my_alloc() and internal_alloc(), which is probably not what you want.
    6931              : 
    6932              :    For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
    6933              :    custom blocks from within a heap block, B, that has been allocated with
    6934              :    malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
    6935              :    -- the custom blocks will take precedence.
    6936              : 
    6937              :    VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK.  For
    6938              :    Memcheck, it does two things:
    6939              : 
    6940              :    - It records that the block has been deallocated.  This assumes that the
    6941              :      block was annotated as having been allocated via
    6942              :      VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
    6943              : 
    6944              :    - It marks the block as being unaddressable.
    6945              : 
    6946              :    VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
    6947              :    heap block is deallocated.
    6948              : 
    6949              :    VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For
    6950              :    Memcheck, it does four things:
    6951              : 
    6952              :    - It records that the size of a block has been changed.  This assumes that
    6953              :      the block was annotated as having been allocated via
    6954              :      VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
    6955              : 
    6956              :    - If the block shrunk, it marks the freed memory as being unaddressable.
    6957              : 
    6958              :    - If the block grew, it marks the new area as undefined and defines a red
    6959              :      zone past the end of the new block.
    6960              : 
    6961              :    - The V-bits of the overlap between the old and the new block are preserved.
    6962              : 
    6963              :    VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block
    6964              :    and before deallocation of the old block.
    6965              : 
    6966              :    In many cases, these three client requests will not be enough to get your
    6967              :    allocator working well with Memcheck.  More specifically, if your allocator
    6968              :    writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
    6969              :    will be necessary to mark the memory as addressable just before the zeroing
    6970              :    occurs, otherwise you'll get a lot of invalid write errors.  For example,
    6971              :    you'll need to do this if your allocator recycles freed blocks, but it
    6972              :    zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
    6973              :    Alternatively, if your allocator reuses freed blocks for allocator-internal
    6974              :    data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
    6975              : 
    6976              :    Really, what's happening is a blurring of the lines between the client
    6977              :    program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
    6978              :    memory should be considered unaddressable to the client program, but the
    6979              :    allocator knows more than the rest of the client program and so may be able
    6980              :    to safely access it.  Extra client requests are necessary for Valgrind to
    6981              :    understand the distinction between the allocator and the rest of the
    6982              :    program.
    6983              : 
    6984              :    Ignored if addr == 0.
    6985              : */
    6986              : #define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)          \
    6987              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MALLOCLIKE_BLOCK,       \
    6988              :                                     addr, sizeB, rzB, is_zeroed, 0)
    6989              : 
    6990              : /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
    6991              :    Ignored if addr == 0.
    6992              : */
    6993              : #define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB)     \
    6994              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__RESIZEINPLACE_BLOCK,    \
    6995              :                                     addr, oldSizeB, newSizeB, rzB, 0)
    6996              : 
    6997              : /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
    6998              :    Ignored if addr == 0.
    6999              : */
    7000              : #define VALGRIND_FREELIKE_BLOCK(addr, rzB)                              \
    7001              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__FREELIKE_BLOCK,         \
    7002              :                                     addr, rzB, 0, 0, 0)
    7003              : 
    7004              : /* Create a memory pool. */
    7005              : #define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
    7006              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL,   \
    7007              :                                     pool, rzB, is_zeroed, 0, 0)
    7008              : 
    7009              : /* Create a memory pool with some flags specifying extended behaviour.
    7010              :    When flags is zero, the behaviour is identical to VALGRIND_CREATE_MEMPOOL.
    7011              :    
    7012              :    The flag VALGRIND_MEMPOOL_METAPOOL specifies that the pieces of memory 
    7013              :    associated with the pool using VALGRIND_MEMPOOL_ALLOC  will be used
    7014              :    by the application as superblocks to dole out MALLOC_LIKE blocks using
    7015              :    VALGRIND_MALLOCLIKE_BLOCK. In other words, a meta pool is a "2 levels"
    7016              :    pool : first level is the blocks described by VALGRIND_MEMPOOL_ALLOC.
    7017              :    The second level blocks are described using VALGRIND_MALLOCLIKE_BLOCK.
    7018              :    Note that the association between the pool and the second level blocks
    7019              :    is implicit : second level blocks will be located inside first level
    7020              :    blocks. It is necessary to use the VALGRIND_MEMPOOL_METAPOOL flag
    7021              :    for such 2 levels pools, as otherwise valgrind will detect overlapping
    7022              :    memory blocks, and will abort execution (e.g. during leak search).
    7023              : 
    7024              :    Such a meta pool can also be marked as an 'auto free' pool using the flag
    7025              :    VALGRIND_MEMPOOL_AUTO_FREE, which must be OR-ed together with the
    7026              :    VALGRIND_MEMPOOL_METAPOOL. For an 'auto free' pool, VALGRIND_MEMPOOL_FREE
    7027              :    will automatically free the second level blocks that are contained
    7028              :    inside the first level block freed with VALGRIND_MEMPOOL_FREE.
    7029              :    In other words, calling VALGRIND_MEMPOOL_FREE will cause implicit calls
    7030              :    to VALGRIND_FREELIKE_BLOCK for all the second level blocks included
    7031              :    in the first level block.
    7032              :    Note: it is an error to use the VALGRIND_MEMPOOL_AUTO_FREE flag
    7033              :    without the VALGRIND_MEMPOOL_METAPOOL flag.
    7034              : */
    7035              : #define VALGRIND_MEMPOOL_AUTO_FREE  1
    7036              : #define VALGRIND_MEMPOOL_METAPOOL   2
    7037              : #define VALGRIND_CREATE_MEMPOOL_EXT(pool, rzB, is_zeroed, flags)        \
    7038              :    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CREATE_MEMPOOL,          \
    7039              :                                    pool, rzB, is_zeroed, flags, 0)
    7040              : 
    7041              : /* Destroy a memory pool. */
    7042              : #define VALGRIND_DESTROY_MEMPOOL(pool)                            \
    7043              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DESTROY_MEMPOOL,  \
    7044              :                                     pool, 0, 0, 0, 0)
    7045              : 
    7046              : /* Associate a piece of memory with a memory pool. */
    7047              : #define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
    7048              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_ALLOC,    \
    7049              :                                     pool, addr, size, 0, 0)
    7050              : 
    7051              : /* Disassociate a piece of memory from a memory pool. */
    7052              : #define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
    7053              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_FREE,     \
    7054              :                                     pool, addr, 0, 0, 0)
    7055              : 
    7056              : /* Disassociate any pieces outside a particular range. */
    7057              : #define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
    7058              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_TRIM,     \
    7059              :                                     pool, addr, size, 0, 0)
    7060              : 
    7061              : /* Resize and/or move a piece associated with a memory pool. */
    7062              : #define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
    7063              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MOVE_MEMPOOL,     \
    7064              :                                     poolA, poolB, 0, 0, 0)
    7065              : 
    7066              : /* Resize and/or move a piece associated with a memory pool. */
    7067              : #define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
    7068              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__MEMPOOL_CHANGE,   \
    7069              :                                     pool, addrA, addrB, size, 0)
    7070              : 
    7071              : /* Return 1 if a mempool exists, else 0. */
    7072              : #define VALGRIND_MEMPOOL_EXISTS(pool)                             \
    7073              :     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
    7074              :                                VG_USERREQ__MEMPOOL_EXISTS,        \
    7075              :                                pool, 0, 0, 0, 0)
    7076              : 
    7077              : /* Mark a piece of memory as being a stack. Returns a stack id.
    7078              :    start is the lowest addressable stack byte, end is the highest
    7079              :    addressable stack byte. */
    7080              : #define VALGRIND_STACK_REGISTER(start, end)                       \
    7081              :     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
    7082              :                                VG_USERREQ__STACK_REGISTER,        \
    7083              :                                start, end, 0, 0, 0)
    7084              : 
    7085              : /* Unmark the piece of memory associated with a stack id as being a
    7086              :    stack. */
    7087              : #define VALGRIND_STACK_DEREGISTER(id)                             \
    7088              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_DEREGISTER, \
    7089              :                                     id, 0, 0, 0, 0)
    7090              : 
    7091              : /* Change the start and end address of the stack id.
    7092              :    start is the new lowest addressable stack byte, end is the new highest
    7093              :    addressable stack byte. */
    7094              : #define VALGRIND_STACK_CHANGE(id, start, end)                     \
    7095              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__STACK_CHANGE,     \
    7096              :                                     id, start, end, 0, 0)
    7097              : 
    7098              : /* Load PDB debug info for Wine PE image_map. */
    7099              : #define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)     \
    7100              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__LOAD_PDB_DEBUGINFO, \
    7101              :                                     fd, ptr, total_size, delta, 0)
    7102              : 
    7103              : /* Map a code address to a source file name and line number.  buf64
    7104              :    must point to a 64-byte buffer in the caller's address space.  The
    7105              :    result will be dumped in there and is guaranteed to be zero
    7106              :    terminated.  If no info is found, the first byte is set to zero. */
    7107              : #define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64)                    \
    7108              :     (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0,                  \
    7109              :                                VG_USERREQ__MAP_IP_TO_SRCLOC,      \
    7110              :                                addr, buf64, 0, 0, 0)
    7111              : 
    7112              : /* Disable error reporting for this thread.  Behaves in a stack like
    7113              :    way, so you can safely call this multiple times provided that
    7114              :    VALGRIND_ENABLE_ERROR_REPORTING is called the same number of times
    7115              :    to re-enable reporting.  The first call of this macro disables
    7116              :    reporting.  Subsequent calls have no effect except to increase the
    7117              :    number of VALGRIND_ENABLE_ERROR_REPORTING calls needed to re-enable
    7118              :    reporting.  Child threads do not inherit this setting from their
    7119              :    parents -- they are always created with reporting enabled. */
    7120              : #define VALGRIND_DISABLE_ERROR_REPORTING                                \
    7121              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
    7122              :                                     1, 0, 0, 0, 0)
    7123              : 
    7124              : /* Re-enable error reporting, as per comments on
    7125              :    VALGRIND_DISABLE_ERROR_REPORTING. */
    7126              : #define VALGRIND_ENABLE_ERROR_REPORTING                                 \
    7127              :     VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CHANGE_ERR_DISABLEMENT, \
    7128              :                                     -1, 0, 0, 0, 0)
    7129              : 
    7130              : /* Execute a monitor command from the client program.
    7131              :    If a connection is opened with GDB, the output will be sent
    7132              :    according to the output mode set for vgdb.
    7133              :    If no connection is opened, output will go to the log output.
    7134              :    Returns 1 if command not recognised, 0 otherwise. */
    7135              : #define VALGRIND_MONITOR_COMMAND(command)                               \
    7136              :    VALGRIND_DO_CLIENT_REQUEST_EXPR(0, VG_USERREQ__GDB_MONITOR_COMMAND, \
    7137              :                                    command, 0, 0, 0, 0)
    7138              : 
    7139              : 
    7140              : /* Change the value of a dynamic command line option.
    7141              :    Note that unknown or not dynamically changeable options
    7142              :    will cause a warning message to be output.  */
    7143              : #define VALGRIND_CLO_CHANGE(option)                           \
    7144              :    VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__CLO_CHANGE, \
    7145              :                                    option, 0, 0, 0, 0)
    7146              : 
    7147              : 
    7148              : #undef PLAT_x86_darwin
    7149              : #undef PLAT_amd64_darwin
    7150              : #undef PLAT_x86_win32
    7151              : #undef PLAT_amd64_win64
    7152              : #undef PLAT_x86_linux
    7153              : #undef PLAT_amd64_linux
    7154              : #undef PLAT_ppc32_linux
    7155              : #undef PLAT_ppc64be_linux
    7156              : #undef PLAT_ppc64le_linux
    7157              : #undef PLAT_arm_linux
    7158              : #undef PLAT_s390x_linux
    7159              : #undef PLAT_mips32_linux
    7160              : #undef PLAT_mips64_linux
    7161              : #undef PLAT_nanomips_linux
    7162              : #undef PLAT_x86_solaris
    7163              : #undef PLAT_amd64_solaris
    7164              : 
    7165              : #endif   /* __VALGRIND_H */
        

Generated by: LCOV version 2.0-1