LCOV - code coverage report
Current view: top level - testing - valgrind.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 10 0.0 %
Date: 2025-06-05 21:03:14 Functions: 0 2 0.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 1.16