Home | History | Annotate | Download | only in valgrind
      1 #ifdef ANDROID
      2   #include "include/valgrind.h"
      3 #else
      4 /* -*- c -*-
      5    ----------------------------------------------------------------
      6 
      7    Notice that the following BSD-style license applies to this one
      8    file (valgrind.h) only.  The rest of Valgrind is licensed under the
      9    terms of the GNU General Public License, version 2, unless
     10    otherwise indicated.  See the COPYING file in the source
     11    distribution for details.
     12 
     13    ----------------------------------------------------------------
     14 
     15    This file is part of Valgrind, a dynamic binary instrumentation
     16    framework.
     17 
     18    Copyright (C) 2000-2010 Julian Seward.  All rights reserved.
     19 
     20    Redistribution and use in source and binary forms, with or without
     21    modification, are permitted provided that the following conditions
     22    are met:
     23 
     24    1. Redistributions of source code must retain the above copyright
     25       notice, this list of conditions and the following disclaimer.
     26 
     27    2. The origin of this software must not be misrepresented; you must
     28       not claim that you wrote the original software.  If you use this
     29       software in a product, an acknowledgment in the product
     30       documentation would be appreciated but is not required.
     31 
     32    3. Altered source versions must be plainly marked as such, and must
     33       not be misrepresented as being the original software.
     34 
     35    4. The name of the author may not be used to endorse or promote
     36       products derived from this software without specific prior written
     37       permission.
     38 
     39    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     40    OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     41    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     42    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
     43    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     44    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     45    GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     46    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     47    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     48    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     49    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     50 
     51    ----------------------------------------------------------------
     52 
     53    Notice that the above BSD-style license applies to this one file
     54    (valgrind.h) only.  The entire rest of Valgrind is licensed under
     55    the terms of the GNU General Public License, version 2.  See the
     56    COPYING file in the source distribution for details.
     57 
     58    ----------------------------------------------------------------
     59 */
     60 
     61 
     62 /* This file is for inclusion into client (your!) code.
     63 
     64    You can use these macros to manipulate and query Valgrind's
     65    execution inside your own programs.
     66 
     67    The resulting executables will still run without Valgrind, just a
     68    little bit more slowly than they otherwise would, but otherwise
     69    unchanged.  When not running on valgrind, each client request
     70    consumes very few (eg. 7) instructions, so the resulting performance
     71    loss is negligible unless you plan to execute client requests
     72    millions of times per second.  Nevertheless, if that is still a
     73    problem, you can compile with the NVALGRIND symbol defined (gcc
     74    -DNVALGRIND) so that client requests are not even compiled in.  */
     75 
     76 #ifndef __VALGRIND_H
     77 #define __VALGRIND_H
     78 
     79 
     80 /* ------------------------------------------------------------------ */
     81 /* VERSION NUMBER OF VALGRIND                                         */
     82 /* ------------------------------------------------------------------ */
     83 
     84 /* Specify Valgrind's version number, so that user code can
     85    conditionally compile based on our version number.  Note that these
     86    were introduced at version 3.6 and so do not exist in version 3.5
     87    or earlier.  The recommended way to use them to check for "version
     88    X.Y or later" is (eg)
     89 
     90 #if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__)   \
     91     && (__VALGRIND_MAJOR__ > 3                                   \
     92         || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
     93 */
     94 #define __VALGRIND_MAJOR__    3
     95 #define __VALGRIND_MINOR__    6
     96 
     97 
     98 #include <stdarg.h>
     99 
    100 /* Nb: this file might be included in a file compiled with -ansi.  So
    101    we can't use C++ style "//" comments nor the "asm" keyword (instead
    102    use "__asm__"). */
    103 
    104 /* Derive some tags indicating what the target platform is.  Note
    105    that in this file we're using the compiler's CPP symbols for
    106    identifying architectures, which are different to the ones we use
    107    within the rest of Valgrind.  Note, __powerpc__ is active for both
    108    32 and 64-bit PPC, whereas __powerpc64__ is only active for the
    109    latter (on Linux, that is).
    110 
    111    Misc note: how to find out what's predefined in gcc by default:
    112    gcc -Wp,-dM somefile.c
    113 */
    114 #undef PLAT_ppc64_aix5
    115 #undef PLAT_ppc32_aix5
    116 #undef PLAT_x86_darwin
    117 #undef PLAT_amd64_darwin
    118 #undef PLAT_x86_win32
    119 #undef PLAT_x86_linux
    120 #undef PLAT_amd64_linux
    121 #undef PLAT_ppc32_linux
    122 #undef PLAT_ppc64_linux
    123 #undef PLAT_arm_linux
    124 
    125 #if defined(_AIX) && defined(__64BIT__)
    126 #  define PLAT_ppc64_aix5 1
    127 #elif defined(_AIX) && !defined(__64BIT__)
    128 #  define PLAT_ppc32_aix5 1
    129 #elif defined(__APPLE__) && defined(__i386__)
    130 #  define PLAT_x86_darwin 1
    131 #elif defined(__APPLE__) && defined(__x86_64__)
    132 #  define PLAT_amd64_darwin 1
    133 #elif defined(__MINGW32__) || defined(__CYGWIN32__) || defined(_WIN32) && defined(_M_IX86)
    134 #  define PLAT_x86_win32 1
    135 #elif defined(__linux__) && defined(__i386__)
    136 #  define PLAT_x86_linux 1
    137 #elif defined(__linux__) && defined(__x86_64__)
    138 #  define PLAT_amd64_linux 1
    139 #elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
    140 #  define PLAT_ppc32_linux 1
    141 #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
    142 #  define PLAT_ppc64_linux 1
    143 #elif defined(__linux__) && defined(__arm__)
    144 #  define PLAT_arm_linux 1
    145 #else
    146 /* If we're not compiling for our target platform, don't generate
    147    any inline asms.  */
    148 #  if !defined(NVALGRIND)
    149 #    define NVALGRIND 1
    150 #  endif
    151 #endif
    152 
    153 
    154 /* ------------------------------------------------------------------ */
    155 /* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS.  There is nothing */
    156 /* in here of use to end-users -- skip to the next section.           */
    157 /* ------------------------------------------------------------------ */
    158 
    159 #if defined(NVALGRIND)
    160 
    161 /* Define NVALGRIND to completely remove the Valgrind magic sequence
    162    from the compiled code (analogous to NDEBUG's effects on
    163    assert()) */
    164 #define VALGRIND_DO_CLIENT_REQUEST(                               \
    165         _zzq_rlval, _zzq_default, _zzq_request,                   \
    166         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
    167    {                                                              \
    168       (_zzq_rlval) = (_zzq_default);                              \
    169    }
    170 
    171 #else  /* ! NVALGRIND */
    172 
    173 /* The following defines the magic code sequences which the JITter
    174    spots and handles magically.  Don't look too closely at them as
    175    they will rot your brain.
    176 
    177    The assembly code sequences for all architectures is in this one
    178    file.  This is because this file must be stand-alone, and we don't
    179    want to have multiple files.
    180 
    181    For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
    182    value gets put in the return slot, so that everything works when
    183    this is executed not under Valgrind.  Args are passed in a memory
    184    block, and so there's no intrinsic limit to the number that could
    185    be passed, but it's currently five.
    186 
    187    The macro args are:
    188       _zzq_rlval    result lvalue
    189       _zzq_default  default value (result returned when running on real CPU)
    190       _zzq_request  request code
    191       _zzq_arg1..5  request params
    192 
    193    The other two macros are used to support function wrapping, and are
    194    a lot simpler.  VALGRIND_GET_NR_CONTEXT returns the value of the
    195    guest's NRADDR pseudo-register and whatever other information is
    196    needed to safely run the call original from the wrapper: on
    197    ppc64-linux, the R2 value at the divert point is also needed.  This
    198    information is abstracted into a user-visible type, OrigFn.
    199 
    200    VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
    201    guest, but guarantees that the branch instruction will not be
    202    redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
    203    branch-and-link-to-r11.  VALGRIND_CALL_NOREDIR is just text, not a
    204    complete inline asm, since it needs to be combined with more magic
    205    inline asm stuff to be useful.
    206 */
    207 
    208 /* ------------------------- x86-{linux,darwin} ---------------- */
    209 
    210 #if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)  \
    211     ||  (defined(PLAT_x86_win32) && defined(__GNUC__))
    212 
    213 typedef
    214    struct {
    215       unsigned int nraddr; /* where's the code? */
    216    }
    217    OrigFn;
    218 
    219 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
    220                      "roll $3,  %%edi ; roll $13, %%edi\n\t"      \
    221                      "roll $29, %%edi ; roll $19, %%edi\n\t"
    222 
    223 #define VALGRIND_DO_CLIENT_REQUEST(                               \
    224         _zzq_rlval, _zzq_default, _zzq_request,                   \
    225         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
    226   { volatile unsigned int _zzq_args[6];                           \
    227     volatile unsigned int _zzq_result;                            \
    228     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
    229     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
    230     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
    231     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
    232     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
    233     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
    234     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    235                      /* %EDX = client_request ( %EAX ) */         \
    236                      "xchgl %%ebx,%%ebx"                          \
    237                      : "=d" (_zzq_result)                         \
    238                      : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
    239                      : "cc", "memory"                             \
    240                     );                                            \
    241     _zzq_rlval = _zzq_result;                                     \
    242   }
    243 
    244 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
    245   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    246     volatile unsigned int __addr;                                 \
    247     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    248                      /* %EAX = guest_NRADDR */                    \
    249                      "xchgl %%ecx,%%ecx"                          \
    250                      : "=a" (__addr)                              \
    251                      :                                            \
    252                      : "cc", "memory"                             \
    253                     );                                            \
    254     _zzq_orig->nraddr = __addr;                                   \
    255   }
    256 
    257 #define VALGRIND_CALL_NOREDIR_EAX                                 \
    258                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    259                      /* call-noredir *%EAX */                     \
    260                      "xchgl %%edx,%%edx\n\t"
    261 #endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */
    262 
    263 /* ------------------------- x86-Win32 ------------------------- */
    264 
    265 #if defined(PLAT_x86_win32) && !defined(__GNUC__)
    266 
    267 typedef
    268    struct {
    269       unsigned int nraddr; /* where's the code? */
    270    }
    271    OrigFn;
    272 
    273 #if defined(_MSC_VER)
    274 
    275 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
    276                      __asm rol edi, 3  __asm rol edi, 13          \
    277                      __asm rol edi, 29 __asm rol edi, 19
    278 
    279 #define VALGRIND_DO_CLIENT_REQUEST(                               \
    280         _zzq_rlval, _zzq_default, _zzq_request,                   \
    281         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
    282   { volatile uintptr_t _zzq_args[6];                              \
    283     volatile unsigned int _zzq_result;                            \
    284     _zzq_args[0] = (uintptr_t)(_zzq_request);                     \
    285     _zzq_args[1] = (uintptr_t)(_zzq_arg1);                        \
    286     _zzq_args[2] = (uintptr_t)(_zzq_arg2);                        \
    287     _zzq_args[3] = (uintptr_t)(_zzq_arg3);                        \
    288     _zzq_args[4] = (uintptr_t)(_zzq_arg4);                        \
    289     _zzq_args[5] = (uintptr_t)(_zzq_arg5);                        \
    290     __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default  \
    291             __SPECIAL_INSTRUCTION_PREAMBLE                        \
    292             /* %EDX = client_request ( %EAX ) */                  \
    293             __asm xchg ebx,ebx                                    \
    294             __asm mov _zzq_result, edx                            \
    295     }                                                             \
    296     _zzq_rlval = _zzq_result;                                     \
    297   }
    298 
    299 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
    300   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    301     volatile unsigned int __addr;                                 \
    302     __asm { __SPECIAL_INSTRUCTION_PREAMBLE                        \
    303             /* %EAX = guest_NRADDR */                             \
    304             __asm xchg ecx,ecx                                    \
    305             __asm mov __addr, eax                                 \
    306     }                                                             \
    307     _zzq_orig->nraddr = __addr;                                   \
    308   }
    309 
    310 #define VALGRIND_CALL_NOREDIR_EAX ERROR
    311 
    312 #else
    313 #error Unsupported compiler.
    314 #endif
    315 
    316 #endif /* PLAT_x86_win32 */
    317 
    318 /* ------------------------ amd64-{linux,darwin} --------------- */
    319 
    320 #if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
    321 
    322 typedef
    323    struct {
    324       unsigned long long int nraddr; /* where's the code? */
    325    }
    326    OrigFn;
    327 
    328 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
    329                      "rolq $3,  %%rdi ; rolq $13, %%rdi\n\t"      \
    330                      "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
    331 
    332 #define VALGRIND_DO_CLIENT_REQUEST(                               \
    333         _zzq_rlval, _zzq_default, _zzq_request,                   \
    334         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
    335   { volatile unsigned long long int _zzq_args[6];                 \
    336     volatile unsigned long long int _zzq_result;                  \
    337     _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
    338     _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
    339     _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
    340     _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
    341     _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
    342     _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
    343     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    344                      /* %RDX = client_request ( %RAX ) */         \
    345                      "xchgq %%rbx,%%rbx"                          \
    346                      : "=d" (_zzq_result)                         \
    347                      : "a" (&_zzq_args[0]), "0" (_zzq_default)    \
    348                      : "cc", "memory"                             \
    349                     );                                            \
    350     _zzq_rlval = _zzq_result;                                     \
    351   }
    352 
    353 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
    354   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    355     volatile unsigned long long int __addr;                       \
    356     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    357                      /* %RAX = guest_NRADDR */                    \
    358                      "xchgq %%rcx,%%rcx"                          \
    359                      : "=a" (__addr)                              \
    360                      :                                            \
    361                      : "cc", "memory"                             \
    362                     );                                            \
    363     _zzq_orig->nraddr = __addr;                                   \
    364   }
    365 
    366 #define VALGRIND_CALL_NOREDIR_RAX                                 \
    367                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    368                      /* call-noredir *%RAX */                     \
    369                      "xchgq %%rdx,%%rdx\n\t"
    370 #endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
    371 
    372 /* ------------------------ ppc32-linux ------------------------ */
    373 
    374 #if defined(PLAT_ppc32_linux)
    375 
    376 typedef
    377    struct {
    378       unsigned int nraddr; /* where's the code? */
    379    }
    380    OrigFn;
    381 
    382 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
    383                      "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
    384                      "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
    385 
    386 #define VALGRIND_DO_CLIENT_REQUEST(                               \
    387         _zzq_rlval, _zzq_default, _zzq_request,                   \
    388         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
    389                                                                   \
    390   {          unsigned int  _zzq_args[6];                          \
    391              unsigned int  _zzq_result;                           \
    392              unsigned int* _zzq_ptr;                              \
    393     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
    394     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
    395     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
    396     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
    397     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
    398     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
    399     _zzq_ptr = _zzq_args;                                         \
    400     __asm__ volatile("mr 3,%1\n\t" /*default*/                    \
    401                      "mr 4,%2\n\t" /*ptr*/                        \
    402                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    403                      /* %R3 = client_request ( %R4 ) */           \
    404                      "or 1,1,1\n\t"                               \
    405                      "mr %0,3"     /*result*/                     \
    406                      : "=b" (_zzq_result)                         \
    407                      : "b" (_zzq_default), "b" (_zzq_ptr)         \
    408                      : "cc", "memory", "r3", "r4");               \
    409     _zzq_rlval = _zzq_result;                                     \
    410   }
    411 
    412 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
    413   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    414     unsigned int __addr;                                          \
    415     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    416                      /* %R3 = guest_NRADDR */                     \
    417                      "or 2,2,2\n\t"                               \
    418                      "mr %0,3"                                    \
    419                      : "=b" (__addr)                              \
    420                      :                                            \
    421                      : "cc", "memory", "r3"                       \
    422                     );                                            \
    423     _zzq_orig->nraddr = __addr;                                   \
    424   }
    425 
    426 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
    427                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    428                      /* branch-and-link-to-noredir *%R11 */       \
    429                      "or 3,3,3\n\t"
    430 #endif /* PLAT_ppc32_linux */
    431 
    432 /* ------------------------ ppc64-linux ------------------------ */
    433 
    434 #if defined(PLAT_ppc64_linux)
    435 
    436 typedef
    437    struct {
    438       unsigned long long int nraddr; /* where's the code? */
    439       unsigned long long int r2;  /* what tocptr do we need? */
    440    }
    441    OrigFn;
    442 
    443 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
    444                      "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
    445                      "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
    446 
    447 #define VALGRIND_DO_CLIENT_REQUEST(                               \
    448         _zzq_rlval, _zzq_default, _zzq_request,                   \
    449         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
    450                                                                   \
    451   {          unsigned long long int  _zzq_args[6];                \
    452     register unsigned long long int  _zzq_result __asm__("r3");   \
    453     register unsigned long long int* _zzq_ptr __asm__("r4");      \
    454     _zzq_args[0] = (unsigned long long int)(_zzq_request);        \
    455     _zzq_args[1] = (unsigned long long int)(_zzq_arg1);           \
    456     _zzq_args[2] = (unsigned long long int)(_zzq_arg2);           \
    457     _zzq_args[3] = (unsigned long long int)(_zzq_arg3);           \
    458     _zzq_args[4] = (unsigned long long int)(_zzq_arg4);           \
    459     _zzq_args[5] = (unsigned long long int)(_zzq_arg5);           \
    460     _zzq_ptr = _zzq_args;                                         \
    461     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    462                      /* %R3 = client_request ( %R4 ) */           \
    463                      "or 1,1,1"                                   \
    464                      : "=r" (_zzq_result)                         \
    465                      : "0" (_zzq_default), "r" (_zzq_ptr)         \
    466                      : "cc", "memory");                           \
    467     _zzq_rlval = _zzq_result;                                     \
    468   }
    469 
    470 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
    471   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    472     register unsigned long long int __addr __asm__("r3");         \
    473     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    474                      /* %R3 = guest_NRADDR */                     \
    475                      "or 2,2,2"                                   \
    476                      : "=r" (__addr)                              \
    477                      :                                            \
    478                      : "cc", "memory"                             \
    479                     );                                            \
    480     _zzq_orig->nraddr = __addr;                                   \
    481     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    482                      /* %R3 = guest_NRADDR_GPR2 */                \
    483                      "or 4,4,4"                                   \
    484                      : "=r" (__addr)                              \
    485                      :                                            \
    486                      : "cc", "memory"                             \
    487                     );                                            \
    488     _zzq_orig->r2 = __addr;                                       \
    489   }
    490 
    491 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
    492                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    493                      /* branch-and-link-to-noredir *%R11 */       \
    494                      "or 3,3,3\n\t"
    495 
    496 #endif /* PLAT_ppc64_linux */
    497 
    498 /* ------------------------- arm-linux ------------------------- */
    499 
    500 #if defined(PLAT_arm_linux)
    501 
    502 typedef
    503    struct {
    504       unsigned int nraddr; /* where's the code? */
    505    }
    506    OrigFn;
    507 
    508 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
    509             "mov r12, r12, ror #3  ; mov r12, r12, ror #13 \n\t"  \
    510             "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
    511 
    512 #define VALGRIND_DO_CLIENT_REQUEST(                               \
    513         _zzq_rlval, _zzq_default, _zzq_request,                   \
    514         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
    515                                                                   \
    516   { volatile unsigned int  _zzq_args[6];                          \
    517     volatile unsigned int  _zzq_result;                           \
    518     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
    519     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
    520     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
    521     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
    522     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
    523     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
    524     __asm__ volatile("mov r3, %1\n\t" /*default*/                 \
    525                      "mov r4, %2\n\t" /*ptr*/                     \
    526                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    527                      /* R3 = client_request ( R4 ) */             \
    528                      "orr r10, r10, r10\n\t"                      \
    529                      "mov %0, r3"     /*result*/                  \
    530                      : "=r" (_zzq_result)                         \
    531                      : "r" (_zzq_default), "r" (&_zzq_args[0])    \
    532                      : "cc","memory", "r3", "r4");                \
    533     _zzq_rlval = _zzq_result;                                     \
    534   }
    535 
    536 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
    537   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    538     unsigned int __addr;                                          \
    539     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    540                      /* R3 = guest_NRADDR */                      \
    541                      "orr r11, r11, r11\n\t"                      \
    542                      "mov %0, r3"                                 \
    543                      : "=r" (__addr)                              \
    544                      :                                            \
    545                      : "cc", "memory", "r3"                       \
    546                     );                                            \
    547     _zzq_orig->nraddr = __addr;                                   \
    548   }
    549 
    550 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                    \
    551                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    552                      /* branch-and-link-to-noredir *%R4 */        \
    553                      "orr r12, r12, r12\n\t"
    554 
    555 #endif /* PLAT_arm_linux */
    556 
    557 /* ------------------------ ppc32-aix5 ------------------------- */
    558 
    559 #if defined(PLAT_ppc32_aix5)
    560 
    561 typedef
    562    struct {
    563       unsigned int nraddr; /* where's the code? */
    564       unsigned int r2;  /* what tocptr do we need? */
    565    }
    566    OrigFn;
    567 
    568 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
    569                      "rlwinm 0,0,3,0,0  ; rlwinm 0,0,13,0,0\n\t"  \
    570                      "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
    571 
    572 #define VALGRIND_DO_CLIENT_REQUEST(                               \
    573         _zzq_rlval, _zzq_default, _zzq_request,                   \
    574         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
    575                                                                   \
    576   {          unsigned int  _zzq_args[7];                          \
    577     register unsigned int  _zzq_result;                           \
    578     register unsigned int* _zzq_ptr;                              \
    579     _zzq_args[0] = (unsigned int)(_zzq_request);                  \
    580     _zzq_args[1] = (unsigned int)(_zzq_arg1);                     \
    581     _zzq_args[2] = (unsigned int)(_zzq_arg2);                     \
    582     _zzq_args[3] = (unsigned int)(_zzq_arg3);                     \
    583     _zzq_args[4] = (unsigned int)(_zzq_arg4);                     \
    584     _zzq_args[5] = (unsigned int)(_zzq_arg5);                     \
    585     _zzq_args[6] = (unsigned int)(_zzq_default);                  \
    586     _zzq_ptr = _zzq_args;                                         \
    587     __asm__ volatile("mr 4,%1\n\t"                                \
    588                      "lwz 3, 24(4)\n\t"                           \
    589                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    590                      /* %R3 = client_request ( %R4 ) */           \
    591                      "or 1,1,1\n\t"                               \
    592                      "mr %0,3"                                    \
    593                      : "=b" (_zzq_result)                         \
    594                      : "b" (_zzq_ptr)                             \
    595                      : "r3", "r4", "cc", "memory");               \
    596     _zzq_rlval = _zzq_result;                                     \
    597   }
    598 
    599 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
    600   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    601     register unsigned int __addr;                                 \
    602     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    603                      /* %R3 = guest_NRADDR */                     \
    604                      "or 2,2,2\n\t"                               \
    605                      "mr %0,3"                                    \
    606                      : "=b" (__addr)                              \
    607                      :                                            \
    608                      : "r3", "cc", "memory"                       \
    609                     );                                            \
    610     _zzq_orig->nraddr = __addr;                                   \
    611     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    612                      /* %R3 = guest_NRADDR_GPR2 */                \
    613                      "or 4,4,4\n\t"                               \
    614                      "mr %0,3"                                    \
    615                      : "=b" (__addr)                              \
    616                      :                                            \
    617                      : "r3", "cc", "memory"                       \
    618                     );                                            \
    619     _zzq_orig->r2 = __addr;                                       \
    620   }
    621 
    622 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
    623                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    624                      /* branch-and-link-to-noredir *%R11 */       \
    625                      "or 3,3,3\n\t"
    626 
    627 #endif /* PLAT_ppc32_aix5 */
    628 
    629 /* ------------------------ ppc64-aix5 ------------------------- */
    630 
    631 #if defined(PLAT_ppc64_aix5)
    632 
    633 typedef
    634    struct {
    635       unsigned long long int nraddr; /* where's the code? */
    636       unsigned long long int r2;  /* what tocptr do we need? */
    637    }
    638    OrigFn;
    639 
    640 #define __SPECIAL_INSTRUCTION_PREAMBLE                            \
    641                      "rotldi 0,0,3  ; rotldi 0,0,13\n\t"          \
    642                      "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
    643 
    644 #define VALGRIND_DO_CLIENT_REQUEST(                               \
    645         _zzq_rlval, _zzq_default, _zzq_request,                   \
    646         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)    \
    647                                                                   \
    648   {          unsigned long long int  _zzq_args[7];                \
    649     register unsigned long long int  _zzq_result;                 \
    650     register unsigned long long int* _zzq_ptr;                    \
    651     _zzq_args[0] = (unsigned int long long)(_zzq_request);        \
    652     _zzq_args[1] = (unsigned int long long)(_zzq_arg1);           \
    653     _zzq_args[2] = (unsigned int long long)(_zzq_arg2);           \
    654     _zzq_args[3] = (unsigned int long long)(_zzq_arg3);           \
    655     _zzq_args[4] = (unsigned int long long)(_zzq_arg4);           \
    656     _zzq_args[5] = (unsigned int long long)(_zzq_arg5);           \
    657     _zzq_args[6] = (unsigned int long long)(_zzq_default);        \
    658     _zzq_ptr = _zzq_args;                                         \
    659     __asm__ volatile("mr 4,%1\n\t"                                \
    660                      "ld 3, 48(4)\n\t"                            \
    661                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    662                      /* %R3 = client_request ( %R4 ) */           \
    663                      "or 1,1,1\n\t"                               \
    664                      "mr %0,3"                                    \
    665                      : "=b" (_zzq_result)                         \
    666                      : "b" (_zzq_ptr)                             \
    667                      : "r3", "r4", "cc", "memory");               \
    668     _zzq_rlval = _zzq_result;                                     \
    669   }
    670 
    671 #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval)                       \
    672   { volatile OrigFn* _zzq_orig = &(_zzq_rlval);                   \
    673     register unsigned long long int __addr;                       \
    674     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    675                      /* %R3 = guest_NRADDR */                     \
    676                      "or 2,2,2\n\t"                               \
    677                      "mr %0,3"                                    \
    678                      : "=b" (__addr)                              \
    679                      :                                            \
    680                      : "r3", "cc", "memory"                       \
    681                     );                                            \
    682     _zzq_orig->nraddr = __addr;                                   \
    683     __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE               \
    684                      /* %R3 = guest_NRADDR_GPR2 */                \
    685                      "or 4,4,4\n\t"                               \
    686                      "mr %0,3"                                    \
    687                      : "=b" (__addr)                              \
    688                      :                                            \
    689                      : "r3", "cc", "memory"                       \
    690                     );                                            \
    691     _zzq_orig->r2 = __addr;                                       \
    692   }
    693 
    694 #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                   \
    695                      __SPECIAL_INSTRUCTION_PREAMBLE               \
    696                      /* branch-and-link-to-noredir *%R11 */       \
    697                      "or 3,3,3\n\t"
    698 
    699 #endif /* PLAT_ppc64_aix5 */
    700 
    701 /* Insert assembly code for other platforms here... */
    702 
    703 #endif /* NVALGRIND */
    704 
    705 
    706 /* ------------------------------------------------------------------ */
    707 /* PLATFORM SPECIFICS for FUNCTION WRAPPING.  This is all very        */
    708 /* ugly.  It's the least-worst tradeoff I can think of.               */
    709 /* ------------------------------------------------------------------ */
    710 
    711 /* This section defines magic (a.k.a appalling-hack) macros for doing
    712    guaranteed-no-redirection macros, so as to get from function
    713    wrappers to the functions they are wrapping.  The whole point is to
    714    construct standard call sequences, but to do the call itself with a
    715    special no-redirect call pseudo-instruction that the JIT
    716    understands and handles specially.  This section is long and
    717    repetitious, and I can't see a way to make it shorter.
    718 
    719    The naming scheme is as follows:
    720 
    721       CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
    722 
    723    'W' stands for "word" and 'v' for "void".  Hence there are
    724    different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
    725    and for each, the possibility of returning a word-typed result, or
    726    no result.
    727 */
    728 
    729 /* Use these to write the name of your wrapper.  NOTE: duplicates
    730    VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
    731 
    732 /* Use an extra level of macroisation so as to ensure the soname/fnname
    733    args are fully macro-expanded before pasting them together. */
    734 #define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
    735 
    736 #define I_WRAP_SONAME_FNNAME_ZU(soname,fnname)                    \
    737    VG_CONCAT4(_vgwZU_,soname,_,fnname)
    738 
    739 #define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname)                    \
    740    VG_CONCAT4(_vgwZZ_,soname,_,fnname)
    741 
    742 /* Use this macro from within a wrapper function to collect the
    743    context (address and possibly other info) of the original function.
    744    Once you have that you can then use it in one of the CALL_FN_
    745    macros.  The type of the argument _lval is OrigFn. */
    746 #define VALGRIND_GET_ORIG_FN(_lval)  VALGRIND_GET_NR_CONTEXT(_lval)
    747 
    748 /* Derivatives of the main macros below, for calling functions
    749    returning void. */
    750 
    751 #define CALL_FN_v_v(fnptr)                                        \
    752    do { volatile unsigned long _junk;                             \
    753         CALL_FN_W_v(_junk,fnptr); } while (0)
    754 
    755 #define CALL_FN_v_W(fnptr, arg1)                                  \
    756    do { volatile unsigned long _junk;                             \
    757         CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
    758 
    759 #define CALL_FN_v_WW(fnptr, arg1,arg2)                            \
    760    do { volatile unsigned long _junk;                             \
    761         CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
    762 
    763 #define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3)                      \
    764    do { volatile unsigned long _junk;                             \
    765         CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
    766 
    767 #define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4)                \
    768    do { volatile unsigned long _junk;                             \
    769         CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
    770 
    771 #define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5)             \
    772    do { volatile unsigned long _junk;                             \
    773         CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
    774 
    775 #define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6)        \
    776    do { volatile unsigned long _junk;                             \
    777         CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
    778 
    779 #define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7)   \
    780    do { volatile unsigned long _junk;                             \
    781         CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
    782 
    783 /* ------------------------- x86-{linux,darwin} ---------------- */
    784 
    785 #if defined(PLAT_x86_linux)  ||  defined(PLAT_x86_darwin)
    786 
    787 /* These regs are trashed by the hidden call.  No need to mention eax
    788    as gcc can already see that, plus causes gcc to bomb. */
    789 #define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
    790 
    791 /* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
    792    long) == 4. */
    793 
    794 #define CALL_FN_W_v(lval, orig)                                   \
    795    do {                                                           \
    796       volatile OrigFn        _orig = (orig);                      \
    797       volatile unsigned long _argvec[1];                          \
    798       volatile unsigned long _res;                                \
    799       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    800       __asm__ volatile(                                           \
    801          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    802          VALGRIND_CALL_NOREDIR_EAX                                \
    803          : /*out*/   "=a" (_res)                                  \
    804          : /*in*/    "a" (&_argvec[0])                            \
    805          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
    806       );                                                          \
    807       lval = (__typeof__(lval)) _res;                             \
    808    } while (0)
    809 
    810 #define CALL_FN_W_W(lval, orig, arg1)                             \
    811    do {                                                           \
    812       volatile OrigFn        _orig = (orig);                      \
    813       volatile unsigned long _argvec[2];                          \
    814       volatile unsigned long _res;                                \
    815       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    816       _argvec[1] = (unsigned long)(arg1);                         \
    817       __asm__ volatile(                                           \
    818          "subl $12, %%esp\n\t"                                    \
    819          "pushl 4(%%eax)\n\t"                                     \
    820          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    821          VALGRIND_CALL_NOREDIR_EAX                                \
    822          "addl $16, %%esp\n"                                      \
    823          : /*out*/   "=a" (_res)                                  \
    824          : /*in*/    "a" (&_argvec[0])                            \
    825          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
    826       );                                                          \
    827       lval = (__typeof__(lval)) _res;                             \
    828    } while (0)
    829 
    830 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
    831    do {                                                           \
    832       volatile OrigFn        _orig = (orig);                      \
    833       volatile unsigned long _argvec[3];                          \
    834       volatile unsigned long _res;                                \
    835       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    836       _argvec[1] = (unsigned long)(arg1);                         \
    837       _argvec[2] = (unsigned long)(arg2);                         \
    838       __asm__ volatile(                                           \
    839          "subl $8, %%esp\n\t"                                     \
    840          "pushl 8(%%eax)\n\t"                                     \
    841          "pushl 4(%%eax)\n\t"                                     \
    842          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    843          VALGRIND_CALL_NOREDIR_EAX                                \
    844          "addl $16, %%esp\n"                                      \
    845          : /*out*/   "=a" (_res)                                  \
    846          : /*in*/    "a" (&_argvec[0])                            \
    847          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
    848       );                                                          \
    849       lval = (__typeof__(lval)) _res;                             \
    850    } while (0)
    851 
    852 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
    853    do {                                                           \
    854       volatile OrigFn        _orig = (orig);                      \
    855       volatile unsigned long _argvec[4];                          \
    856       volatile unsigned long _res;                                \
    857       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    858       _argvec[1] = (unsigned long)(arg1);                         \
    859       _argvec[2] = (unsigned long)(arg2);                         \
    860       _argvec[3] = (unsigned long)(arg3);                         \
    861       __asm__ volatile(                                           \
    862          "subl $4, %%esp\n\t"                                     \
    863          "pushl 12(%%eax)\n\t"                                    \
    864          "pushl 8(%%eax)\n\t"                                     \
    865          "pushl 4(%%eax)\n\t"                                     \
    866          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    867          VALGRIND_CALL_NOREDIR_EAX                                \
    868          "addl $16, %%esp\n"                                      \
    869          : /*out*/   "=a" (_res)                                  \
    870          : /*in*/    "a" (&_argvec[0])                            \
    871          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
    872       );                                                          \
    873       lval = (__typeof__(lval)) _res;                             \
    874    } while (0)
    875 
    876 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
    877    do {                                                           \
    878       volatile OrigFn        _orig = (orig);                      \
    879       volatile unsigned long _argvec[5];                          \
    880       volatile unsigned long _res;                                \
    881       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    882       _argvec[1] = (unsigned long)(arg1);                         \
    883       _argvec[2] = (unsigned long)(arg2);                         \
    884       _argvec[3] = (unsigned long)(arg3);                         \
    885       _argvec[4] = (unsigned long)(arg4);                         \
    886       __asm__ volatile(                                           \
    887          "pushl 16(%%eax)\n\t"                                    \
    888          "pushl 12(%%eax)\n\t"                                    \
    889          "pushl 8(%%eax)\n\t"                                     \
    890          "pushl 4(%%eax)\n\t"                                     \
    891          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    892          VALGRIND_CALL_NOREDIR_EAX                                \
    893          "addl $16, %%esp\n"                                      \
    894          : /*out*/   "=a" (_res)                                  \
    895          : /*in*/    "a" (&_argvec[0])                            \
    896          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
    897       );                                                          \
    898       lval = (__typeof__(lval)) _res;                             \
    899    } while (0)
    900 
    901 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
    902    do {                                                           \
    903       volatile OrigFn        _orig = (orig);                      \
    904       volatile unsigned long _argvec[6];                          \
    905       volatile unsigned long _res;                                \
    906       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    907       _argvec[1] = (unsigned long)(arg1);                         \
    908       _argvec[2] = (unsigned long)(arg2);                         \
    909       _argvec[3] = (unsigned long)(arg3);                         \
    910       _argvec[4] = (unsigned long)(arg4);                         \
    911       _argvec[5] = (unsigned long)(arg5);                         \
    912       __asm__ volatile(                                           \
    913          "subl $12, %%esp\n\t"                                    \
    914          "pushl 20(%%eax)\n\t"                                    \
    915          "pushl 16(%%eax)\n\t"                                    \
    916          "pushl 12(%%eax)\n\t"                                    \
    917          "pushl 8(%%eax)\n\t"                                     \
    918          "pushl 4(%%eax)\n\t"                                     \
    919          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    920          VALGRIND_CALL_NOREDIR_EAX                                \
    921          "addl $32, %%esp\n"                                      \
    922          : /*out*/   "=a" (_res)                                  \
    923          : /*in*/    "a" (&_argvec[0])                            \
    924          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
    925       );                                                          \
    926       lval = (__typeof__(lval)) _res;                             \
    927    } while (0)
    928 
    929 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
    930    do {                                                           \
    931       volatile OrigFn        _orig = (orig);                      \
    932       volatile unsigned long _argvec[7];                          \
    933       volatile unsigned long _res;                                \
    934       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    935       _argvec[1] = (unsigned long)(arg1);                         \
    936       _argvec[2] = (unsigned long)(arg2);                         \
    937       _argvec[3] = (unsigned long)(arg3);                         \
    938       _argvec[4] = (unsigned long)(arg4);                         \
    939       _argvec[5] = (unsigned long)(arg5);                         \
    940       _argvec[6] = (unsigned long)(arg6);                         \
    941       __asm__ volatile(                                           \
    942          "subl $8, %%esp\n\t"                                     \
    943          "pushl 24(%%eax)\n\t"                                    \
    944          "pushl 20(%%eax)\n\t"                                    \
    945          "pushl 16(%%eax)\n\t"                                    \
    946          "pushl 12(%%eax)\n\t"                                    \
    947          "pushl 8(%%eax)\n\t"                                     \
    948          "pushl 4(%%eax)\n\t"                                     \
    949          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    950          VALGRIND_CALL_NOREDIR_EAX                                \
    951          "addl $32, %%esp\n"                                      \
    952          : /*out*/   "=a" (_res)                                  \
    953          : /*in*/    "a" (&_argvec[0])                            \
    954          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
    955       );                                                          \
    956       lval = (__typeof__(lval)) _res;                             \
    957    } while (0)
    958 
    959 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    960                                  arg7)                            \
    961    do {                                                           \
    962       volatile OrigFn        _orig = (orig);                      \
    963       volatile unsigned long _argvec[8];                          \
    964       volatile unsigned long _res;                                \
    965       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    966       _argvec[1] = (unsigned long)(arg1);                         \
    967       _argvec[2] = (unsigned long)(arg2);                         \
    968       _argvec[3] = (unsigned long)(arg3);                         \
    969       _argvec[4] = (unsigned long)(arg4);                         \
    970       _argvec[5] = (unsigned long)(arg5);                         \
    971       _argvec[6] = (unsigned long)(arg6);                         \
    972       _argvec[7] = (unsigned long)(arg7);                         \
    973       __asm__ volatile(                                           \
    974          "subl $4, %%esp\n\t"                                     \
    975          "pushl 28(%%eax)\n\t"                                    \
    976          "pushl 24(%%eax)\n\t"                                    \
    977          "pushl 20(%%eax)\n\t"                                    \
    978          "pushl 16(%%eax)\n\t"                                    \
    979          "pushl 12(%%eax)\n\t"                                    \
    980          "pushl 8(%%eax)\n\t"                                     \
    981          "pushl 4(%%eax)\n\t"                                     \
    982          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
    983          VALGRIND_CALL_NOREDIR_EAX                                \
    984          "addl $32, %%esp\n"                                      \
    985          : /*out*/   "=a" (_res)                                  \
    986          : /*in*/    "a" (&_argvec[0])                            \
    987          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
    988       );                                                          \
    989       lval = (__typeof__(lval)) _res;                             \
    990    } while (0)
    991 
    992 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
    993                                  arg7,arg8)                       \
    994    do {                                                           \
    995       volatile OrigFn        _orig = (orig);                      \
    996       volatile unsigned long _argvec[9];                          \
    997       volatile unsigned long _res;                                \
    998       _argvec[0] = (unsigned long)_orig.nraddr;                   \
    999       _argvec[1] = (unsigned long)(arg1);                         \
   1000       _argvec[2] = (unsigned long)(arg2);                         \
   1001       _argvec[3] = (unsigned long)(arg3);                         \
   1002       _argvec[4] = (unsigned long)(arg4);                         \
   1003       _argvec[5] = (unsigned long)(arg5);                         \
   1004       _argvec[6] = (unsigned long)(arg6);                         \
   1005       _argvec[7] = (unsigned long)(arg7);                         \
   1006       _argvec[8] = (unsigned long)(arg8);                         \
   1007       __asm__ volatile(                                           \
   1008          "pushl 32(%%eax)\n\t"                                    \
   1009          "pushl 28(%%eax)\n\t"                                    \
   1010          "pushl 24(%%eax)\n\t"                                    \
   1011          "pushl 20(%%eax)\n\t"                                    \
   1012          "pushl 16(%%eax)\n\t"                                    \
   1013          "pushl 12(%%eax)\n\t"                                    \
   1014          "pushl 8(%%eax)\n\t"                                     \
   1015          "pushl 4(%%eax)\n\t"                                     \
   1016          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
   1017          VALGRIND_CALL_NOREDIR_EAX                                \
   1018          "addl $32, %%esp\n"                                      \
   1019          : /*out*/   "=a" (_res)                                  \
   1020          : /*in*/    "a" (&_argvec[0])                            \
   1021          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1022       );                                                          \
   1023       lval = (__typeof__(lval)) _res;                             \
   1024    } while (0)
   1025 
   1026 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   1027                                  arg7,arg8,arg9)                  \
   1028    do {                                                           \
   1029       volatile OrigFn        _orig = (orig);                      \
   1030       volatile unsigned long _argvec[10];                         \
   1031       volatile unsigned long _res;                                \
   1032       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1033       _argvec[1] = (unsigned long)(arg1);                         \
   1034       _argvec[2] = (unsigned long)(arg2);                         \
   1035       _argvec[3] = (unsigned long)(arg3);                         \
   1036       _argvec[4] = (unsigned long)(arg4);                         \
   1037       _argvec[5] = (unsigned long)(arg5);                         \
   1038       _argvec[6] = (unsigned long)(arg6);                         \
   1039       _argvec[7] = (unsigned long)(arg7);                         \
   1040       _argvec[8] = (unsigned long)(arg8);                         \
   1041       _argvec[9] = (unsigned long)(arg9);                         \
   1042       __asm__ volatile(                                           \
   1043          "subl $12, %%esp\n\t"                                    \
   1044          "pushl 36(%%eax)\n\t"                                    \
   1045          "pushl 32(%%eax)\n\t"                                    \
   1046          "pushl 28(%%eax)\n\t"                                    \
   1047          "pushl 24(%%eax)\n\t"                                    \
   1048          "pushl 20(%%eax)\n\t"                                    \
   1049          "pushl 16(%%eax)\n\t"                                    \
   1050          "pushl 12(%%eax)\n\t"                                    \
   1051          "pushl 8(%%eax)\n\t"                                     \
   1052          "pushl 4(%%eax)\n\t"                                     \
   1053          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
   1054          VALGRIND_CALL_NOREDIR_EAX                                \
   1055          "addl $48, %%esp\n"                                      \
   1056          : /*out*/   "=a" (_res)                                  \
   1057          : /*in*/    "a" (&_argvec[0])                            \
   1058          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1059       );                                                          \
   1060       lval = (__typeof__(lval)) _res;                             \
   1061    } while (0)
   1062 
   1063 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   1064                                   arg7,arg8,arg9,arg10)           \
   1065    do {                                                           \
   1066       volatile OrigFn        _orig = (orig);                      \
   1067       volatile unsigned long _argvec[11];                         \
   1068       volatile unsigned long _res;                                \
   1069       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1070       _argvec[1] = (unsigned long)(arg1);                         \
   1071       _argvec[2] = (unsigned long)(arg2);                         \
   1072       _argvec[3] = (unsigned long)(arg3);                         \
   1073       _argvec[4] = (unsigned long)(arg4);                         \
   1074       _argvec[5] = (unsigned long)(arg5);                         \
   1075       _argvec[6] = (unsigned long)(arg6);                         \
   1076       _argvec[7] = (unsigned long)(arg7);                         \
   1077       _argvec[8] = (unsigned long)(arg8);                         \
   1078       _argvec[9] = (unsigned long)(arg9);                         \
   1079       _argvec[10] = (unsigned long)(arg10);                       \
   1080       __asm__ volatile(                                           \
   1081          "subl $8, %%esp\n\t"                                     \
   1082          "pushl 40(%%eax)\n\t"                                    \
   1083          "pushl 36(%%eax)\n\t"                                    \
   1084          "pushl 32(%%eax)\n\t"                                    \
   1085          "pushl 28(%%eax)\n\t"                                    \
   1086          "pushl 24(%%eax)\n\t"                                    \
   1087          "pushl 20(%%eax)\n\t"                                    \
   1088          "pushl 16(%%eax)\n\t"                                    \
   1089          "pushl 12(%%eax)\n\t"                                    \
   1090          "pushl 8(%%eax)\n\t"                                     \
   1091          "pushl 4(%%eax)\n\t"                                     \
   1092          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
   1093          VALGRIND_CALL_NOREDIR_EAX                                \
   1094          "addl $48, %%esp\n"                                      \
   1095          : /*out*/   "=a" (_res)                                  \
   1096          : /*in*/    "a" (&_argvec[0])                            \
   1097          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1098       );                                                          \
   1099       lval = (__typeof__(lval)) _res;                             \
   1100    } while (0)
   1101 
   1102 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
   1103                                   arg6,arg7,arg8,arg9,arg10,      \
   1104                                   arg11)                          \
   1105    do {                                                           \
   1106       volatile OrigFn        _orig = (orig);                      \
   1107       volatile unsigned long _argvec[12];                         \
   1108       volatile unsigned long _res;                                \
   1109       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1110       _argvec[1] = (unsigned long)(arg1);                         \
   1111       _argvec[2] = (unsigned long)(arg2);                         \
   1112       _argvec[3] = (unsigned long)(arg3);                         \
   1113       _argvec[4] = (unsigned long)(arg4);                         \
   1114       _argvec[5] = (unsigned long)(arg5);                         \
   1115       _argvec[6] = (unsigned long)(arg6);                         \
   1116       _argvec[7] = (unsigned long)(arg7);                         \
   1117       _argvec[8] = (unsigned long)(arg8);                         \
   1118       _argvec[9] = (unsigned long)(arg9);                         \
   1119       _argvec[10] = (unsigned long)(arg10);                       \
   1120       _argvec[11] = (unsigned long)(arg11);                       \
   1121       __asm__ volatile(                                           \
   1122          "subl $4, %%esp\n\t"                                     \
   1123          "pushl 44(%%eax)\n\t"                                    \
   1124          "pushl 40(%%eax)\n\t"                                    \
   1125          "pushl 36(%%eax)\n\t"                                    \
   1126          "pushl 32(%%eax)\n\t"                                    \
   1127          "pushl 28(%%eax)\n\t"                                    \
   1128          "pushl 24(%%eax)\n\t"                                    \
   1129          "pushl 20(%%eax)\n\t"                                    \
   1130          "pushl 16(%%eax)\n\t"                                    \
   1131          "pushl 12(%%eax)\n\t"                                    \
   1132          "pushl 8(%%eax)\n\t"                                     \
   1133          "pushl 4(%%eax)\n\t"                                     \
   1134          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
   1135          VALGRIND_CALL_NOREDIR_EAX                                \
   1136          "addl $48, %%esp\n"                                      \
   1137          : /*out*/   "=a" (_res)                                  \
   1138          : /*in*/    "a" (&_argvec[0])                            \
   1139          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1140       );                                                          \
   1141       lval = (__typeof__(lval)) _res;                             \
   1142    } while (0)
   1143 
   1144 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
   1145                                   arg6,arg7,arg8,arg9,arg10,      \
   1146                                   arg11,arg12)                    \
   1147    do {                                                           \
   1148       volatile OrigFn        _orig = (orig);                      \
   1149       volatile unsigned long _argvec[13];                         \
   1150       volatile unsigned long _res;                                \
   1151       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1152       _argvec[1] = (unsigned long)(arg1);                         \
   1153       _argvec[2] = (unsigned long)(arg2);                         \
   1154       _argvec[3] = (unsigned long)(arg3);                         \
   1155       _argvec[4] = (unsigned long)(arg4);                         \
   1156       _argvec[5] = (unsigned long)(arg5);                         \
   1157       _argvec[6] = (unsigned long)(arg6);                         \
   1158       _argvec[7] = (unsigned long)(arg7);                         \
   1159       _argvec[8] = (unsigned long)(arg8);                         \
   1160       _argvec[9] = (unsigned long)(arg9);                         \
   1161       _argvec[10] = (unsigned long)(arg10);                       \
   1162       _argvec[11] = (unsigned long)(arg11);                       \
   1163       _argvec[12] = (unsigned long)(arg12);                       \
   1164       __asm__ volatile(                                           \
   1165          "pushl 48(%%eax)\n\t"                                    \
   1166          "pushl 44(%%eax)\n\t"                                    \
   1167          "pushl 40(%%eax)\n\t"                                    \
   1168          "pushl 36(%%eax)\n\t"                                    \
   1169          "pushl 32(%%eax)\n\t"                                    \
   1170          "pushl 28(%%eax)\n\t"                                    \
   1171          "pushl 24(%%eax)\n\t"                                    \
   1172          "pushl 20(%%eax)\n\t"                                    \
   1173          "pushl 16(%%eax)\n\t"                                    \
   1174          "pushl 12(%%eax)\n\t"                                    \
   1175          "pushl 8(%%eax)\n\t"                                     \
   1176          "pushl 4(%%eax)\n\t"                                     \
   1177          "movl (%%eax), %%eax\n\t"  /* target->%eax */            \
   1178          VALGRIND_CALL_NOREDIR_EAX                                \
   1179          "addl $48, %%esp\n"                                      \
   1180          : /*out*/   "=a" (_res)                                  \
   1181          : /*in*/    "a" (&_argvec[0])                            \
   1182          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1183       );                                                          \
   1184       lval = (__typeof__(lval)) _res;                             \
   1185    } while (0)
   1186 
   1187 #endif /* PLAT_x86_linux || PLAT_x86_darwin */
   1188 
   1189 /* ------------------------ amd64-{linux,darwin} --------------- */
   1190 
   1191 #if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
   1192 
   1193 /* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
   1194 
   1195 /* These regs are trashed by the hidden call. */
   1196 #define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi",       \
   1197                             "rdi", "r8", "r9", "r10", "r11"
   1198 
   1199 /* This is all pretty complex.  It's so as to make stack unwinding
   1200    work reliably.  See bug 243270.  The basic problem is the sub and
   1201    add of 128 of %rsp in all of the following macros.  If gcc believes
   1202    the CFA is in %rsp, then unwinding may fail, because what's at the
   1203    CFA is not what gcc "expected" when it constructs the CFIs for the
   1204    places where the macros are instantiated.
   1205 
   1206    But we can't just add a CFI annotation to increase the CFA offset
   1207    by 128, to match the sub of 128 from %rsp, because we don't know
   1208    whether gcc has chosen %rsp as the CFA at that point, or whether it
   1209    has chosen some other register (eg, %rbp).  In the latter case,
   1210    adding a CFI annotation to change the CFA offset is simply wrong.
   1211 
   1212    So the solution is to get hold of the CFA using
   1213    __builtin_dwarf_cfa(), put it in a known register, and add a
   1214    CFI annotation to say what the register is.  We choose %rbp for
   1215    this (perhaps perversely), because:
   1216 
   1217    (1) %rbp is already subject to unwinding.  If a new register was
   1218        chosen then the unwinder would have to unwind it in all stack
   1219        traces, which is expensive, and
   1220 
   1221    (2) %rbp is already subject to precise exception updates in the
   1222        JIT.  If a new register was chosen, we'd have to have precise
   1223        exceptions for it too, which reduces performance of the
   1224        generated code.
   1225 
   1226    However .. one extra complication.  We can't just whack the result
   1227    of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
   1228    list of trashed registers at the end of the inline assembly
   1229    fragments; gcc won't allow %rbp to appear in that list.  Hence
   1230    instead we need to stash %rbp in %r15 for the duration of the asm,
   1231    and say that %r15 is trashed instead.  gcc seems happy to go with
   1232    that.
   1233 
   1234    Oh .. and this all needs to be conditionalised so that it is
   1235    unchanged from before this commit, when compiled with older gccs
   1236    that don't support __builtin_dwarf_cfa.  Furthermore, since
   1237    this header file is freestanding, it has to be independent of
   1238    config.h, and so the following conditionalisation cannot depend on
   1239    configure time checks.
   1240 
   1241    Although it's not clear from
   1242    'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
   1243    this expression excludes Darwin.
   1244    .cfi directives in Darwin assembly appear to be completely
   1245    different and I haven't investigated how they work.
   1246 
   1247    For even more entertainment value, note we have to use the
   1248    completely undocumented __builtin_dwarf_cfa(), which appears to
   1249    really compute the CFA, whereas __builtin_frame_address(0) claims
   1250    to but actually doesn't.  See
   1251    https://bugs.kde.org/show_bug.cgi?id=243270#c47
   1252 */
   1253 #if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
   1254 #  define __FRAME_POINTER                                         \
   1255       ,"r"(__builtin_dwarf_cfa())
   1256 #  define VALGRIND_CFI_PROLOGUE                                   \
   1257       "movq %%rbp, %%r15\n\t"                                     \
   1258       "movq %2, %%rbp\n\t"                                        \
   1259       ".cfi_remember_state\n\t"                                   \
   1260       ".cfi_def_cfa rbp, 0\n\t"
   1261 #  define VALGRIND_CFI_EPILOGUE                                   \
   1262       "movq %%r15, %%rbp\n\t"                                     \
   1263       ".cfi_restore_state\n\t"
   1264 #else
   1265 #  define __FRAME_POINTER
   1266 #  define VALGRIND_CFI_PROLOGUE
   1267 #  define VALGRIND_CFI_EPILOGUE
   1268 #endif
   1269 
   1270 
   1271 /* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
   1272    long) == 8. */
   1273 
   1274 /* NB 9 Sept 07.  There is a nasty kludge here in all these CALL_FN_
   1275    macros.  In order not to trash the stack redzone, we need to drop
   1276    %rsp by 128 before the hidden call, and restore afterwards.  The
   1277    nastyness is that it is only by luck that the stack still appears
   1278    to be unwindable during the hidden call - since then the behaviour
   1279    of any routine using this macro does not match what the CFI data
   1280    says.  Sigh.
   1281 
   1282    Why is this important?  Imagine that a wrapper has a stack
   1283    allocated local, and passes to the hidden call, a pointer to it.
   1284    Because gcc does not know about the hidden call, it may allocate
   1285    that local in the redzone.  Unfortunately the hidden call may then
   1286    trash it before it comes to use it.  So we must step clear of the
   1287    redzone, for the duration of the hidden call, to make it safe.
   1288 
   1289    Probably the same problem afflicts the other redzone-style ABIs too
   1290    (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is
   1291    self describing (none of this CFI nonsense) so at least messing
   1292    with the stack pointer doesn't give a danger of non-unwindable
   1293    stack. */
   1294 
   1295 #define CALL_FN_W_v(lval, orig)                                   \
   1296    do {                                                           \
   1297       volatile OrigFn        _orig = (orig);                      \
   1298       volatile unsigned long _argvec[1];                          \
   1299       volatile unsigned long _res;                                \
   1300       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1301       __asm__ volatile(                                           \
   1302          VALGRIND_CFI_PROLOGUE                                    \
   1303          "subq $128,%%rsp\n\t"                                    \
   1304          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1305          VALGRIND_CALL_NOREDIR_RAX                                \
   1306          "addq $128,%%rsp\n\t"                                    \
   1307          VALGRIND_CFI_EPILOGUE                                    \
   1308          : /*out*/   "=a" (_res)                                  \
   1309          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1310          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1311       );                                                          \
   1312       lval = (__typeof__(lval)) _res;                             \
   1313    } while (0)
   1314 
   1315 #define CALL_FN_W_W(lval, orig, arg1)                             \
   1316    do {                                                           \
   1317       volatile OrigFn        _orig = (orig);                      \
   1318       volatile unsigned long _argvec[2];                          \
   1319       volatile unsigned long _res;                                \
   1320       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1321       _argvec[1] = (unsigned long)(arg1);                         \
   1322       __asm__ volatile(                                           \
   1323          VALGRIND_CFI_PROLOGUE                                    \
   1324          "subq $128,%%rsp\n\t"                                    \
   1325          "movq 8(%%rax), %%rdi\n\t"                               \
   1326          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1327          VALGRIND_CALL_NOREDIR_RAX                                \
   1328          "addq $128,%%rsp\n\t"                                    \
   1329          VALGRIND_CFI_EPILOGUE                                    \
   1330          : /*out*/   "=a" (_res)                                  \
   1331          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1332          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1333       );                                                          \
   1334       lval = (__typeof__(lval)) _res;                             \
   1335    } while (0)
   1336 
   1337 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   1338    do {                                                           \
   1339       volatile OrigFn        _orig = (orig);                      \
   1340       volatile unsigned long _argvec[3];                          \
   1341       volatile unsigned long _res;                                \
   1342       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1343       _argvec[1] = (unsigned long)(arg1);                         \
   1344       _argvec[2] = (unsigned long)(arg2);                         \
   1345       __asm__ volatile(                                           \
   1346          VALGRIND_CFI_PROLOGUE                                    \
   1347          "subq $128,%%rsp\n\t"                                    \
   1348          "movq 16(%%rax), %%rsi\n\t"                              \
   1349          "movq 8(%%rax), %%rdi\n\t"                               \
   1350          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1351          VALGRIND_CALL_NOREDIR_RAX                                \
   1352          "addq $128,%%rsp\n\t"                                    \
   1353          VALGRIND_CFI_EPILOGUE                                    \
   1354          : /*out*/   "=a" (_res)                                  \
   1355          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1356          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1357       );                                                          \
   1358       lval = (__typeof__(lval)) _res;                             \
   1359    } while (0)
   1360 
   1361 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   1362    do {                                                           \
   1363       volatile OrigFn        _orig = (orig);                      \
   1364       volatile unsigned long _argvec[4];                          \
   1365       volatile unsigned long _res;                                \
   1366       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1367       _argvec[1] = (unsigned long)(arg1);                         \
   1368       _argvec[2] = (unsigned long)(arg2);                         \
   1369       _argvec[3] = (unsigned long)(arg3);                         \
   1370       __asm__ volatile(                                           \
   1371          VALGRIND_CFI_PROLOGUE                                    \
   1372          "subq $128,%%rsp\n\t"                                    \
   1373          "movq 24(%%rax), %%rdx\n\t"                              \
   1374          "movq 16(%%rax), %%rsi\n\t"                              \
   1375          "movq 8(%%rax), %%rdi\n\t"                               \
   1376          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1377          VALGRIND_CALL_NOREDIR_RAX                                \
   1378          "addq $128,%%rsp\n\t"                                    \
   1379          VALGRIND_CFI_EPILOGUE                                    \
   1380          : /*out*/   "=a" (_res)                                  \
   1381          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1382          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1383       );                                                          \
   1384       lval = (__typeof__(lval)) _res;                             \
   1385    } while (0)
   1386 
   1387 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   1388    do {                                                           \
   1389       volatile OrigFn        _orig = (orig);                      \
   1390       volatile unsigned long _argvec[5];                          \
   1391       volatile unsigned long _res;                                \
   1392       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1393       _argvec[1] = (unsigned long)(arg1);                         \
   1394       _argvec[2] = (unsigned long)(arg2);                         \
   1395       _argvec[3] = (unsigned long)(arg3);                         \
   1396       _argvec[4] = (unsigned long)(arg4);                         \
   1397       __asm__ volatile(                                           \
   1398          VALGRIND_CFI_PROLOGUE                                    \
   1399          "subq $128,%%rsp\n\t"                                    \
   1400          "movq 32(%%rax), %%rcx\n\t"                              \
   1401          "movq 24(%%rax), %%rdx\n\t"                              \
   1402          "movq 16(%%rax), %%rsi\n\t"                              \
   1403          "movq 8(%%rax), %%rdi\n\t"                               \
   1404          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1405          VALGRIND_CALL_NOREDIR_RAX                                \
   1406          "addq $128,%%rsp\n\t"                                    \
   1407          VALGRIND_CFI_EPILOGUE                                    \
   1408          : /*out*/   "=a" (_res)                                  \
   1409          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1410          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1411       );                                                          \
   1412       lval = (__typeof__(lval)) _res;                             \
   1413    } while (0)
   1414 
   1415 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   1416    do {                                                           \
   1417       volatile OrigFn        _orig = (orig);                      \
   1418       volatile unsigned long _argvec[6];                          \
   1419       volatile unsigned long _res;                                \
   1420       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1421       _argvec[1] = (unsigned long)(arg1);                         \
   1422       _argvec[2] = (unsigned long)(arg2);                         \
   1423       _argvec[3] = (unsigned long)(arg3);                         \
   1424       _argvec[4] = (unsigned long)(arg4);                         \
   1425       _argvec[5] = (unsigned long)(arg5);                         \
   1426       __asm__ volatile(                                           \
   1427          VALGRIND_CFI_PROLOGUE                                    \
   1428          "subq $128,%%rsp\n\t"                                    \
   1429          "movq 40(%%rax), %%r8\n\t"                               \
   1430          "movq 32(%%rax), %%rcx\n\t"                              \
   1431          "movq 24(%%rax), %%rdx\n\t"                              \
   1432          "movq 16(%%rax), %%rsi\n\t"                              \
   1433          "movq 8(%%rax), %%rdi\n\t"                               \
   1434          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1435          VALGRIND_CALL_NOREDIR_RAX                                \
   1436          "addq $128,%%rsp\n\t"                                    \
   1437          VALGRIND_CFI_EPILOGUE                                    \
   1438          : /*out*/   "=a" (_res)                                  \
   1439          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1440          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1441       );                                                          \
   1442       lval = (__typeof__(lval)) _res;                             \
   1443    } while (0)
   1444 
   1445 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   1446    do {                                                           \
   1447       volatile OrigFn        _orig = (orig);                      \
   1448       volatile unsigned long _argvec[7];                          \
   1449       volatile unsigned long _res;                                \
   1450       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1451       _argvec[1] = (unsigned long)(arg1);                         \
   1452       _argvec[2] = (unsigned long)(arg2);                         \
   1453       _argvec[3] = (unsigned long)(arg3);                         \
   1454       _argvec[4] = (unsigned long)(arg4);                         \
   1455       _argvec[5] = (unsigned long)(arg5);                         \
   1456       _argvec[6] = (unsigned long)(arg6);                         \
   1457       __asm__ volatile(                                           \
   1458          VALGRIND_CFI_PROLOGUE                                    \
   1459          "subq $128,%%rsp\n\t"                                    \
   1460          "movq 48(%%rax), %%r9\n\t"                               \
   1461          "movq 40(%%rax), %%r8\n\t"                               \
   1462          "movq 32(%%rax), %%rcx\n\t"                              \
   1463          "movq 24(%%rax), %%rdx\n\t"                              \
   1464          "movq 16(%%rax), %%rsi\n\t"                              \
   1465          "movq 8(%%rax), %%rdi\n\t"                               \
   1466          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1467          VALGRIND_CALL_NOREDIR_RAX                                \
   1468          "addq $128,%%rsp\n\t"                                    \
   1469          VALGRIND_CFI_EPILOGUE                                    \
   1470          : /*out*/   "=a" (_res)                                  \
   1471          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1472          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1473       );                                                          \
   1474       lval = (__typeof__(lval)) _res;                             \
   1475    } while (0)
   1476 
   1477 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   1478                                  arg7)                            \
   1479    do {                                                           \
   1480       volatile OrigFn        _orig = (orig);                      \
   1481       volatile unsigned long _argvec[8];                          \
   1482       volatile unsigned long _res;                                \
   1483       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1484       _argvec[1] = (unsigned long)(arg1);                         \
   1485       _argvec[2] = (unsigned long)(arg2);                         \
   1486       _argvec[3] = (unsigned long)(arg3);                         \
   1487       _argvec[4] = (unsigned long)(arg4);                         \
   1488       _argvec[5] = (unsigned long)(arg5);                         \
   1489       _argvec[6] = (unsigned long)(arg6);                         \
   1490       _argvec[7] = (unsigned long)(arg7);                         \
   1491       __asm__ volatile(                                           \
   1492          VALGRIND_CFI_PROLOGUE                                    \
   1493          "subq $136,%%rsp\n\t"                                    \
   1494          "pushq 56(%%rax)\n\t"                                    \
   1495          "movq 48(%%rax), %%r9\n\t"                               \
   1496          "movq 40(%%rax), %%r8\n\t"                               \
   1497          "movq 32(%%rax), %%rcx\n\t"                              \
   1498          "movq 24(%%rax), %%rdx\n\t"                              \
   1499          "movq 16(%%rax), %%rsi\n\t"                              \
   1500          "movq 8(%%rax), %%rdi\n\t"                               \
   1501          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1502          VALGRIND_CALL_NOREDIR_RAX                                \
   1503          "addq $8, %%rsp\n"                                       \
   1504          "addq $136,%%rsp\n\t"                                    \
   1505          VALGRIND_CFI_EPILOGUE                                    \
   1506          : /*out*/   "=a" (_res)                                  \
   1507          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1508          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1509       );                                                          \
   1510       lval = (__typeof__(lval)) _res;                             \
   1511    } while (0)
   1512 
   1513 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   1514                                  arg7,arg8)                       \
   1515    do {                                                           \
   1516       volatile OrigFn        _orig = (orig);                      \
   1517       volatile unsigned long _argvec[9];                          \
   1518       volatile unsigned long _res;                                \
   1519       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1520       _argvec[1] = (unsigned long)(arg1);                         \
   1521       _argvec[2] = (unsigned long)(arg2);                         \
   1522       _argvec[3] = (unsigned long)(arg3);                         \
   1523       _argvec[4] = (unsigned long)(arg4);                         \
   1524       _argvec[5] = (unsigned long)(arg5);                         \
   1525       _argvec[6] = (unsigned long)(arg6);                         \
   1526       _argvec[7] = (unsigned long)(arg7);                         \
   1527       _argvec[8] = (unsigned long)(arg8);                         \
   1528       __asm__ volatile(                                           \
   1529          VALGRIND_CFI_PROLOGUE                                    \
   1530          "subq $128,%%rsp\n\t"                                    \
   1531          "pushq 64(%%rax)\n\t"                                    \
   1532          "pushq 56(%%rax)\n\t"                                    \
   1533          "movq 48(%%rax), %%r9\n\t"                               \
   1534          "movq 40(%%rax), %%r8\n\t"                               \
   1535          "movq 32(%%rax), %%rcx\n\t"                              \
   1536          "movq 24(%%rax), %%rdx\n\t"                              \
   1537          "movq 16(%%rax), %%rsi\n\t"                              \
   1538          "movq 8(%%rax), %%rdi\n\t"                               \
   1539          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1540          VALGRIND_CALL_NOREDIR_RAX                                \
   1541          "addq $16, %%rsp\n"                                      \
   1542          "addq $128,%%rsp\n\t"                                    \
   1543          VALGRIND_CFI_EPILOGUE                                    \
   1544          : /*out*/   "=a" (_res)                                  \
   1545          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1546          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1547       );                                                          \
   1548       lval = (__typeof__(lval)) _res;                             \
   1549    } while (0)
   1550 
   1551 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   1552                                  arg7,arg8,arg9)                  \
   1553    do {                                                           \
   1554       volatile OrigFn        _orig = (orig);                      \
   1555       volatile unsigned long _argvec[10];                         \
   1556       volatile unsigned long _res;                                \
   1557       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1558       _argvec[1] = (unsigned long)(arg1);                         \
   1559       _argvec[2] = (unsigned long)(arg2);                         \
   1560       _argvec[3] = (unsigned long)(arg3);                         \
   1561       _argvec[4] = (unsigned long)(arg4);                         \
   1562       _argvec[5] = (unsigned long)(arg5);                         \
   1563       _argvec[6] = (unsigned long)(arg6);                         \
   1564       _argvec[7] = (unsigned long)(arg7);                         \
   1565       _argvec[8] = (unsigned long)(arg8);                         \
   1566       _argvec[9] = (unsigned long)(arg9);                         \
   1567       __asm__ volatile(                                           \
   1568          VALGRIND_CFI_PROLOGUE                                    \
   1569          "subq $136,%%rsp\n\t"                                    \
   1570          "pushq 72(%%rax)\n\t"                                    \
   1571          "pushq 64(%%rax)\n\t"                                    \
   1572          "pushq 56(%%rax)\n\t"                                    \
   1573          "movq 48(%%rax), %%r9\n\t"                               \
   1574          "movq 40(%%rax), %%r8\n\t"                               \
   1575          "movq 32(%%rax), %%rcx\n\t"                              \
   1576          "movq 24(%%rax), %%rdx\n\t"                              \
   1577          "movq 16(%%rax), %%rsi\n\t"                              \
   1578          "movq 8(%%rax), %%rdi\n\t"                               \
   1579          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1580          VALGRIND_CALL_NOREDIR_RAX                                \
   1581          "addq $24, %%rsp\n"                                      \
   1582          "addq $136,%%rsp\n\t"                                    \
   1583          VALGRIND_CFI_EPILOGUE                                    \
   1584          : /*out*/   "=a" (_res)                                  \
   1585          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1586          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1587       );                                                          \
   1588       lval = (__typeof__(lval)) _res;                             \
   1589    } while (0)
   1590 
   1591 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   1592                                   arg7,arg8,arg9,arg10)           \
   1593    do {                                                           \
   1594       volatile OrigFn        _orig = (orig);                      \
   1595       volatile unsigned long _argvec[11];                         \
   1596       volatile unsigned long _res;                                \
   1597       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1598       _argvec[1] = (unsigned long)(arg1);                         \
   1599       _argvec[2] = (unsigned long)(arg2);                         \
   1600       _argvec[3] = (unsigned long)(arg3);                         \
   1601       _argvec[4] = (unsigned long)(arg4);                         \
   1602       _argvec[5] = (unsigned long)(arg5);                         \
   1603       _argvec[6] = (unsigned long)(arg6);                         \
   1604       _argvec[7] = (unsigned long)(arg7);                         \
   1605       _argvec[8] = (unsigned long)(arg8);                         \
   1606       _argvec[9] = (unsigned long)(arg9);                         \
   1607       _argvec[10] = (unsigned long)(arg10);                       \
   1608       __asm__ volatile(                                           \
   1609          VALGRIND_CFI_PROLOGUE                                    \
   1610          "subq $128,%%rsp\n\t"                                    \
   1611          "pushq 80(%%rax)\n\t"                                    \
   1612          "pushq 72(%%rax)\n\t"                                    \
   1613          "pushq 64(%%rax)\n\t"                                    \
   1614          "pushq 56(%%rax)\n\t"                                    \
   1615          "movq 48(%%rax), %%r9\n\t"                               \
   1616          "movq 40(%%rax), %%r8\n\t"                               \
   1617          "movq 32(%%rax), %%rcx\n\t"                              \
   1618          "movq 24(%%rax), %%rdx\n\t"                              \
   1619          "movq 16(%%rax), %%rsi\n\t"                              \
   1620          "movq 8(%%rax), %%rdi\n\t"                               \
   1621          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1622          VALGRIND_CALL_NOREDIR_RAX                                \
   1623          "addq $32, %%rsp\n"                                      \
   1624          "addq $128,%%rsp\n\t"                                    \
   1625          VALGRIND_CFI_EPILOGUE                                    \
   1626          : /*out*/   "=a" (_res)                                  \
   1627          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1628          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1629       );                                                          \
   1630       lval = (__typeof__(lval)) _res;                             \
   1631    } while (0)
   1632 
   1633 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   1634                                   arg7,arg8,arg9,arg10,arg11)     \
   1635    do {                                                           \
   1636       volatile OrigFn        _orig = (orig);                      \
   1637       volatile unsigned long _argvec[12];                         \
   1638       volatile unsigned long _res;                                \
   1639       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1640       _argvec[1] = (unsigned long)(arg1);                         \
   1641       _argvec[2] = (unsigned long)(arg2);                         \
   1642       _argvec[3] = (unsigned long)(arg3);                         \
   1643       _argvec[4] = (unsigned long)(arg4);                         \
   1644       _argvec[5] = (unsigned long)(arg5);                         \
   1645       _argvec[6] = (unsigned long)(arg6);                         \
   1646       _argvec[7] = (unsigned long)(arg7);                         \
   1647       _argvec[8] = (unsigned long)(arg8);                         \
   1648       _argvec[9] = (unsigned long)(arg9);                         \
   1649       _argvec[10] = (unsigned long)(arg10);                       \
   1650       _argvec[11] = (unsigned long)(arg11);                       \
   1651       __asm__ volatile(                                           \
   1652          VALGRIND_CFI_PROLOGUE                                    \
   1653          "subq $136,%%rsp\n\t"                                    \
   1654          "pushq 88(%%rax)\n\t"                                    \
   1655          "pushq 80(%%rax)\n\t"                                    \
   1656          "pushq 72(%%rax)\n\t"                                    \
   1657          "pushq 64(%%rax)\n\t"                                    \
   1658          "pushq 56(%%rax)\n\t"                                    \
   1659          "movq 48(%%rax), %%r9\n\t"                               \
   1660          "movq 40(%%rax), %%r8\n\t"                               \
   1661          "movq 32(%%rax), %%rcx\n\t"                              \
   1662          "movq 24(%%rax), %%rdx\n\t"                              \
   1663          "movq 16(%%rax), %%rsi\n\t"                              \
   1664          "movq 8(%%rax), %%rdi\n\t"                               \
   1665          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1666          VALGRIND_CALL_NOREDIR_RAX                                \
   1667          "addq $40, %%rsp\n"                                      \
   1668          "addq $136,%%rsp\n\t"                                    \
   1669          VALGRIND_CFI_EPILOGUE                                    \
   1670          : /*out*/   "=a" (_res)                                  \
   1671          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1672          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1673       );                                                          \
   1674       lval = (__typeof__(lval)) _res;                             \
   1675    } while (0)
   1676 
   1677 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   1678                                 arg7,arg8,arg9,arg10,arg11,arg12) \
   1679    do {                                                           \
   1680       volatile OrigFn        _orig = (orig);                      \
   1681       volatile unsigned long _argvec[13];                         \
   1682       volatile unsigned long _res;                                \
   1683       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1684       _argvec[1] = (unsigned long)(arg1);                         \
   1685       _argvec[2] = (unsigned long)(arg2);                         \
   1686       _argvec[3] = (unsigned long)(arg3);                         \
   1687       _argvec[4] = (unsigned long)(arg4);                         \
   1688       _argvec[5] = (unsigned long)(arg5);                         \
   1689       _argvec[6] = (unsigned long)(arg6);                         \
   1690       _argvec[7] = (unsigned long)(arg7);                         \
   1691       _argvec[8] = (unsigned long)(arg8);                         \
   1692       _argvec[9] = (unsigned long)(arg9);                         \
   1693       _argvec[10] = (unsigned long)(arg10);                       \
   1694       _argvec[11] = (unsigned long)(arg11);                       \
   1695       _argvec[12] = (unsigned long)(arg12);                       \
   1696       __asm__ volatile(                                           \
   1697          VALGRIND_CFI_PROLOGUE                                    \
   1698          "subq $128,%%rsp\n\t"                                    \
   1699          "pushq 96(%%rax)\n\t"                                    \
   1700          "pushq 88(%%rax)\n\t"                                    \
   1701          "pushq 80(%%rax)\n\t"                                    \
   1702          "pushq 72(%%rax)\n\t"                                    \
   1703          "pushq 64(%%rax)\n\t"                                    \
   1704          "pushq 56(%%rax)\n\t"                                    \
   1705          "movq 48(%%rax), %%r9\n\t"                               \
   1706          "movq 40(%%rax), %%r8\n\t"                               \
   1707          "movq 32(%%rax), %%rcx\n\t"                              \
   1708          "movq 24(%%rax), %%rdx\n\t"                              \
   1709          "movq 16(%%rax), %%rsi\n\t"                              \
   1710          "movq 8(%%rax), %%rdi\n\t"                               \
   1711          "movq (%%rax), %%rax\n\t"  /* target->%rax */            \
   1712          VALGRIND_CALL_NOREDIR_RAX                                \
   1713          "addq $48, %%rsp\n"                                      \
   1714          "addq $128,%%rsp\n\t"                                    \
   1715          VALGRIND_CFI_EPILOGUE                                    \
   1716          : /*out*/   "=a" (_res)                                  \
   1717          : /*in*/    "a" (&_argvec[0]) __FRAME_POINTER            \
   1718          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15"   \
   1719       );                                                          \
   1720       lval = (__typeof__(lval)) _res;                             \
   1721    } while (0)
   1722 
   1723 #endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
   1724 
   1725 /* ------------------------ ppc32-linux ------------------------ */
   1726 
   1727 #if defined(PLAT_ppc32_linux)
   1728 
   1729 /* This is useful for finding out about the on-stack stuff:
   1730 
   1731    extern int f9  ( int,int,int,int,int,int,int,int,int );
   1732    extern int f10 ( int,int,int,int,int,int,int,int,int,int );
   1733    extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
   1734    extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
   1735 
   1736    int g9 ( void ) {
   1737       return f9(11,22,33,44,55,66,77,88,99);
   1738    }
   1739    int g10 ( void ) {
   1740       return f10(11,22,33,44,55,66,77,88,99,110);
   1741    }
   1742    int g11 ( void ) {
   1743       return f11(11,22,33,44,55,66,77,88,99,110,121);
   1744    }
   1745    int g12 ( void ) {
   1746       return f12(11,22,33,44,55,66,77,88,99,110,121,132);
   1747    }
   1748 */
   1749 
   1750 /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
   1751 
   1752 /* These regs are trashed by the hidden call. */
   1753 #define __CALLER_SAVED_REGS                                       \
   1754    "lr", "ctr", "xer",                                            \
   1755    "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
   1756    "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
   1757    "r11", "r12", "r13"
   1758 
   1759 /* These CALL_FN_ macros assume that on ppc32-linux,
   1760    sizeof(unsigned long) == 4. */
   1761 
   1762 #define CALL_FN_W_v(lval, orig)                                   \
   1763    do {                                                           \
   1764       volatile OrigFn        _orig = (orig);                      \
   1765       volatile unsigned long _argvec[1];                          \
   1766       volatile unsigned long _res;                                \
   1767       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1768       __asm__ volatile(                                           \
   1769          "mr 11,%1\n\t"                                           \
   1770          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   1771          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   1772          "mr %0,3"                                                \
   1773          : /*out*/   "=r" (_res)                                  \
   1774          : /*in*/    "r" (&_argvec[0])                            \
   1775          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1776       );                                                          \
   1777       lval = (__typeof__(lval)) _res;                             \
   1778    } while (0)
   1779 
   1780 #define CALL_FN_W_W(lval, orig, arg1)                             \
   1781    do {                                                           \
   1782       volatile OrigFn        _orig = (orig);                      \
   1783       volatile unsigned long _argvec[2];                          \
   1784       volatile unsigned long _res;                                \
   1785       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1786       _argvec[1] = (unsigned long)arg1;                           \
   1787       __asm__ volatile(                                           \
   1788          "mr 11,%1\n\t"                                           \
   1789          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   1790          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   1791          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   1792          "mr %0,3"                                                \
   1793          : /*out*/   "=r" (_res)                                  \
   1794          : /*in*/    "r" (&_argvec[0])                            \
   1795          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1796       );                                                          \
   1797       lval = (__typeof__(lval)) _res;                             \
   1798    } while (0)
   1799 
   1800 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   1801    do {                                                           \
   1802       volatile OrigFn        _orig = (orig);                      \
   1803       volatile unsigned long _argvec[3];                          \
   1804       volatile unsigned long _res;                                \
   1805       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1806       _argvec[1] = (unsigned long)arg1;                           \
   1807       _argvec[2] = (unsigned long)arg2;                           \
   1808       __asm__ volatile(                                           \
   1809          "mr 11,%1\n\t"                                           \
   1810          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   1811          "lwz 4,8(11)\n\t"                                        \
   1812          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   1813          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   1814          "mr %0,3"                                                \
   1815          : /*out*/   "=r" (_res)                                  \
   1816          : /*in*/    "r" (&_argvec[0])                            \
   1817          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1818       );                                                          \
   1819       lval = (__typeof__(lval)) _res;                             \
   1820    } while (0)
   1821 
   1822 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   1823    do {                                                           \
   1824       volatile OrigFn        _orig = (orig);                      \
   1825       volatile unsigned long _argvec[4];                          \
   1826       volatile unsigned long _res;                                \
   1827       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1828       _argvec[1] = (unsigned long)arg1;                           \
   1829       _argvec[2] = (unsigned long)arg2;                           \
   1830       _argvec[3] = (unsigned long)arg3;                           \
   1831       __asm__ volatile(                                           \
   1832          "mr 11,%1\n\t"                                           \
   1833          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   1834          "lwz 4,8(11)\n\t"                                        \
   1835          "lwz 5,12(11)\n\t"                                       \
   1836          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   1837          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   1838          "mr %0,3"                                                \
   1839          : /*out*/   "=r" (_res)                                  \
   1840          : /*in*/    "r" (&_argvec[0])                            \
   1841          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1842       );                                                          \
   1843       lval = (__typeof__(lval)) _res;                             \
   1844    } while (0)
   1845 
   1846 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   1847    do {                                                           \
   1848       volatile OrigFn        _orig = (orig);                      \
   1849       volatile unsigned long _argvec[5];                          \
   1850       volatile unsigned long _res;                                \
   1851       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1852       _argvec[1] = (unsigned long)arg1;                           \
   1853       _argvec[2] = (unsigned long)arg2;                           \
   1854       _argvec[3] = (unsigned long)arg3;                           \
   1855       _argvec[4] = (unsigned long)arg4;                           \
   1856       __asm__ volatile(                                           \
   1857          "mr 11,%1\n\t"                                           \
   1858          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   1859          "lwz 4,8(11)\n\t"                                        \
   1860          "lwz 5,12(11)\n\t"                                       \
   1861          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
   1862          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   1863          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   1864          "mr %0,3"                                                \
   1865          : /*out*/   "=r" (_res)                                  \
   1866          : /*in*/    "r" (&_argvec[0])                            \
   1867          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1868       );                                                          \
   1869       lval = (__typeof__(lval)) _res;                             \
   1870    } while (0)
   1871 
   1872 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   1873    do {                                                           \
   1874       volatile OrigFn        _orig = (orig);                      \
   1875       volatile unsigned long _argvec[6];                          \
   1876       volatile unsigned long _res;                                \
   1877       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1878       _argvec[1] = (unsigned long)arg1;                           \
   1879       _argvec[2] = (unsigned long)arg2;                           \
   1880       _argvec[3] = (unsigned long)arg3;                           \
   1881       _argvec[4] = (unsigned long)arg4;                           \
   1882       _argvec[5] = (unsigned long)arg5;                           \
   1883       __asm__ volatile(                                           \
   1884          "mr 11,%1\n\t"                                           \
   1885          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   1886          "lwz 4,8(11)\n\t"                                        \
   1887          "lwz 5,12(11)\n\t"                                       \
   1888          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
   1889          "lwz 7,20(11)\n\t"                                       \
   1890          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   1891          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   1892          "mr %0,3"                                                \
   1893          : /*out*/   "=r" (_res)                                  \
   1894          : /*in*/    "r" (&_argvec[0])                            \
   1895          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1896       );                                                          \
   1897       lval = (__typeof__(lval)) _res;                             \
   1898    } while (0)
   1899 
   1900 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   1901    do {                                                           \
   1902       volatile OrigFn        _orig = (orig);                      \
   1903       volatile unsigned long _argvec[7];                          \
   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       _argvec[6] = (unsigned long)arg6;                           \
   1912       __asm__ volatile(                                           \
   1913          "mr 11,%1\n\t"                                           \
   1914          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   1915          "lwz 4,8(11)\n\t"                                        \
   1916          "lwz 5,12(11)\n\t"                                       \
   1917          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
   1918          "lwz 7,20(11)\n\t"                                       \
   1919          "lwz 8,24(11)\n\t"                                       \
   1920          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   1921          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   1922          "mr %0,3"                                                \
   1923          : /*out*/   "=r" (_res)                                  \
   1924          : /*in*/    "r" (&_argvec[0])                            \
   1925          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1926       );                                                          \
   1927       lval = (__typeof__(lval)) _res;                             \
   1928    } while (0)
   1929 
   1930 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   1931                                  arg7)                            \
   1932    do {                                                           \
   1933       volatile OrigFn        _orig = (orig);                      \
   1934       volatile unsigned long _argvec[8];                          \
   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       _argvec[7] = (unsigned long)arg7;                           \
   1944       __asm__ volatile(                                           \
   1945          "mr 11,%1\n\t"                                           \
   1946          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   1947          "lwz 4,8(11)\n\t"                                        \
   1948          "lwz 5,12(11)\n\t"                                       \
   1949          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
   1950          "lwz 7,20(11)\n\t"                                       \
   1951          "lwz 8,24(11)\n\t"                                       \
   1952          "lwz 9,28(11)\n\t"                                       \
   1953          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   1954          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   1955          "mr %0,3"                                                \
   1956          : /*out*/   "=r" (_res)                                  \
   1957          : /*in*/    "r" (&_argvec[0])                            \
   1958          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1959       );                                                          \
   1960       lval = (__typeof__(lval)) _res;                             \
   1961    } while (0)
   1962 
   1963 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   1964                                  arg7,arg8)                       \
   1965    do {                                                           \
   1966       volatile OrigFn        _orig = (orig);                      \
   1967       volatile unsigned long _argvec[9];                          \
   1968       volatile unsigned long _res;                                \
   1969       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   1970       _argvec[1] = (unsigned long)arg1;                           \
   1971       _argvec[2] = (unsigned long)arg2;                           \
   1972       _argvec[3] = (unsigned long)arg3;                           \
   1973       _argvec[4] = (unsigned long)arg4;                           \
   1974       _argvec[5] = (unsigned long)arg5;                           \
   1975       _argvec[6] = (unsigned long)arg6;                           \
   1976       _argvec[7] = (unsigned long)arg7;                           \
   1977       _argvec[8] = (unsigned long)arg8;                           \
   1978       __asm__ volatile(                                           \
   1979          "mr 11,%1\n\t"                                           \
   1980          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   1981          "lwz 4,8(11)\n\t"                                        \
   1982          "lwz 5,12(11)\n\t"                                       \
   1983          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
   1984          "lwz 7,20(11)\n\t"                                       \
   1985          "lwz 8,24(11)\n\t"                                       \
   1986          "lwz 9,28(11)\n\t"                                       \
   1987          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
   1988          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   1989          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   1990          "mr %0,3"                                                \
   1991          : /*out*/   "=r" (_res)                                  \
   1992          : /*in*/    "r" (&_argvec[0])                            \
   1993          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   1994       );                                                          \
   1995       lval = (__typeof__(lval)) _res;                             \
   1996    } while (0)
   1997 
   1998 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   1999                                  arg7,arg8,arg9)                  \
   2000    do {                                                           \
   2001       volatile OrigFn        _orig = (orig);                      \
   2002       volatile unsigned long _argvec[10];                         \
   2003       volatile unsigned long _res;                                \
   2004       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2005       _argvec[1] = (unsigned long)arg1;                           \
   2006       _argvec[2] = (unsigned long)arg2;                           \
   2007       _argvec[3] = (unsigned long)arg3;                           \
   2008       _argvec[4] = (unsigned long)arg4;                           \
   2009       _argvec[5] = (unsigned long)arg5;                           \
   2010       _argvec[6] = (unsigned long)arg6;                           \
   2011       _argvec[7] = (unsigned long)arg7;                           \
   2012       _argvec[8] = (unsigned long)arg8;                           \
   2013       _argvec[9] = (unsigned long)arg9;                           \
   2014       __asm__ volatile(                                           \
   2015          "mr 11,%1\n\t"                                           \
   2016          "addi 1,1,-16\n\t"                                       \
   2017          /* arg9 */                                               \
   2018          "lwz 3,36(11)\n\t"                                       \
   2019          "stw 3,8(1)\n\t"                                         \
   2020          /* args1-8 */                                            \
   2021          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   2022          "lwz 4,8(11)\n\t"                                        \
   2023          "lwz 5,12(11)\n\t"                                       \
   2024          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
   2025          "lwz 7,20(11)\n\t"                                       \
   2026          "lwz 8,24(11)\n\t"                                       \
   2027          "lwz 9,28(11)\n\t"                                       \
   2028          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
   2029          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   2030          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2031          "addi 1,1,16\n\t"                                        \
   2032          "mr %0,3"                                                \
   2033          : /*out*/   "=r" (_res)                                  \
   2034          : /*in*/    "r" (&_argvec[0])                            \
   2035          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2036       );                                                          \
   2037       lval = (__typeof__(lval)) _res;                             \
   2038    } while (0)
   2039 
   2040 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   2041                                   arg7,arg8,arg9,arg10)           \
   2042    do {                                                           \
   2043       volatile OrigFn        _orig = (orig);                      \
   2044       volatile unsigned long _argvec[11];                         \
   2045       volatile unsigned long _res;                                \
   2046       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2047       _argvec[1] = (unsigned long)arg1;                           \
   2048       _argvec[2] = (unsigned long)arg2;                           \
   2049       _argvec[3] = (unsigned long)arg3;                           \
   2050       _argvec[4] = (unsigned long)arg4;                           \
   2051       _argvec[5] = (unsigned long)arg5;                           \
   2052       _argvec[6] = (unsigned long)arg6;                           \
   2053       _argvec[7] = (unsigned long)arg7;                           \
   2054       _argvec[8] = (unsigned long)arg8;                           \
   2055       _argvec[9] = (unsigned long)arg9;                           \
   2056       _argvec[10] = (unsigned long)arg10;                         \
   2057       __asm__ volatile(                                           \
   2058          "mr 11,%1\n\t"                                           \
   2059          "addi 1,1,-16\n\t"                                       \
   2060          /* arg10 */                                              \
   2061          "lwz 3,40(11)\n\t"                                       \
   2062          "stw 3,12(1)\n\t"                                        \
   2063          /* arg9 */                                               \
   2064          "lwz 3,36(11)\n\t"                                       \
   2065          "stw 3,8(1)\n\t"                                         \
   2066          /* args1-8 */                                            \
   2067          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   2068          "lwz 4,8(11)\n\t"                                        \
   2069          "lwz 5,12(11)\n\t"                                       \
   2070          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
   2071          "lwz 7,20(11)\n\t"                                       \
   2072          "lwz 8,24(11)\n\t"                                       \
   2073          "lwz 9,28(11)\n\t"                                       \
   2074          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
   2075          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   2076          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2077          "addi 1,1,16\n\t"                                        \
   2078          "mr %0,3"                                                \
   2079          : /*out*/   "=r" (_res)                                  \
   2080          : /*in*/    "r" (&_argvec[0])                            \
   2081          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2082       );                                                          \
   2083       lval = (__typeof__(lval)) _res;                             \
   2084    } while (0)
   2085 
   2086 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   2087                                   arg7,arg8,arg9,arg10,arg11)     \
   2088    do {                                                           \
   2089       volatile OrigFn        _orig = (orig);                      \
   2090       volatile unsigned long _argvec[12];                         \
   2091       volatile unsigned long _res;                                \
   2092       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2093       _argvec[1] = (unsigned long)arg1;                           \
   2094       _argvec[2] = (unsigned long)arg2;                           \
   2095       _argvec[3] = (unsigned long)arg3;                           \
   2096       _argvec[4] = (unsigned long)arg4;                           \
   2097       _argvec[5] = (unsigned long)arg5;                           \
   2098       _argvec[6] = (unsigned long)arg6;                           \
   2099       _argvec[7] = (unsigned long)arg7;                           \
   2100       _argvec[8] = (unsigned long)arg8;                           \
   2101       _argvec[9] = (unsigned long)arg9;                           \
   2102       _argvec[10] = (unsigned long)arg10;                         \
   2103       _argvec[11] = (unsigned long)arg11;                         \
   2104       __asm__ volatile(                                           \
   2105          "mr 11,%1\n\t"                                           \
   2106          "addi 1,1,-32\n\t"                                       \
   2107          /* arg11 */                                              \
   2108          "lwz 3,44(11)\n\t"                                       \
   2109          "stw 3,16(1)\n\t"                                        \
   2110          /* arg10 */                                              \
   2111          "lwz 3,40(11)\n\t"                                       \
   2112          "stw 3,12(1)\n\t"                                        \
   2113          /* arg9 */                                               \
   2114          "lwz 3,36(11)\n\t"                                       \
   2115          "stw 3,8(1)\n\t"                                         \
   2116          /* args1-8 */                                            \
   2117          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   2118          "lwz 4,8(11)\n\t"                                        \
   2119          "lwz 5,12(11)\n\t"                                       \
   2120          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
   2121          "lwz 7,20(11)\n\t"                                       \
   2122          "lwz 8,24(11)\n\t"                                       \
   2123          "lwz 9,28(11)\n\t"                                       \
   2124          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
   2125          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   2126          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2127          "addi 1,1,32\n\t"                                        \
   2128          "mr %0,3"                                                \
   2129          : /*out*/   "=r" (_res)                                  \
   2130          : /*in*/    "r" (&_argvec[0])                            \
   2131          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2132       );                                                          \
   2133       lval = (__typeof__(lval)) _res;                             \
   2134    } while (0)
   2135 
   2136 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   2137                                 arg7,arg8,arg9,arg10,arg11,arg12) \
   2138    do {                                                           \
   2139       volatile OrigFn        _orig = (orig);                      \
   2140       volatile unsigned long _argvec[13];                         \
   2141       volatile unsigned long _res;                                \
   2142       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2143       _argvec[1] = (unsigned long)arg1;                           \
   2144       _argvec[2] = (unsigned long)arg2;                           \
   2145       _argvec[3] = (unsigned long)arg3;                           \
   2146       _argvec[4] = (unsigned long)arg4;                           \
   2147       _argvec[5] = (unsigned long)arg5;                           \
   2148       _argvec[6] = (unsigned long)arg6;                           \
   2149       _argvec[7] = (unsigned long)arg7;                           \
   2150       _argvec[8] = (unsigned long)arg8;                           \
   2151       _argvec[9] = (unsigned long)arg9;                           \
   2152       _argvec[10] = (unsigned long)arg10;                         \
   2153       _argvec[11] = (unsigned long)arg11;                         \
   2154       _argvec[12] = (unsigned long)arg12;                         \
   2155       __asm__ volatile(                                           \
   2156          "mr 11,%1\n\t"                                           \
   2157          "addi 1,1,-32\n\t"                                       \
   2158          /* arg12 */                                              \
   2159          "lwz 3,48(11)\n\t"                                       \
   2160          "stw 3,20(1)\n\t"                                        \
   2161          /* arg11 */                                              \
   2162          "lwz 3,44(11)\n\t"                                       \
   2163          "stw 3,16(1)\n\t"                                        \
   2164          /* arg10 */                                              \
   2165          "lwz 3,40(11)\n\t"                                       \
   2166          "stw 3,12(1)\n\t"                                        \
   2167          /* arg9 */                                               \
   2168          "lwz 3,36(11)\n\t"                                       \
   2169          "stw 3,8(1)\n\t"                                         \
   2170          /* args1-8 */                                            \
   2171          "lwz 3,4(11)\n\t"   /* arg1->r3 */                       \
   2172          "lwz 4,8(11)\n\t"                                        \
   2173          "lwz 5,12(11)\n\t"                                       \
   2174          "lwz 6,16(11)\n\t"  /* arg4->r6 */                       \
   2175          "lwz 7,20(11)\n\t"                                       \
   2176          "lwz 8,24(11)\n\t"                                       \
   2177          "lwz 9,28(11)\n\t"                                       \
   2178          "lwz 10,32(11)\n\t" /* arg8->r10 */                      \
   2179          "lwz 11,0(11)\n\t"  /* target->r11 */                    \
   2180          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2181          "addi 1,1,32\n\t"                                        \
   2182          "mr %0,3"                                                \
   2183          : /*out*/   "=r" (_res)                                  \
   2184          : /*in*/    "r" (&_argvec[0])                            \
   2185          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2186       );                                                          \
   2187       lval = (__typeof__(lval)) _res;                             \
   2188    } while (0)
   2189 
   2190 #endif /* PLAT_ppc32_linux */
   2191 
   2192 /* ------------------------ ppc64-linux ------------------------ */
   2193 
   2194 #if defined(PLAT_ppc64_linux)
   2195 
   2196 /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
   2197 
   2198 /* These regs are trashed by the hidden call. */
   2199 #define __CALLER_SAVED_REGS                                       \
   2200    "lr", "ctr", "xer",                                            \
   2201    "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
   2202    "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
   2203    "r11", "r12", "r13"
   2204 
   2205 /* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
   2206    long) == 8. */
   2207 
   2208 #define CALL_FN_W_v(lval, orig)                                   \
   2209    do {                                                           \
   2210       volatile OrigFn        _orig = (orig);                      \
   2211       volatile unsigned long _argvec[3+0];                        \
   2212       volatile unsigned long _res;                                \
   2213       /* _argvec[0] holds current r2 across the call */           \
   2214       _argvec[1] = (unsigned long)_orig.r2;                       \
   2215       _argvec[2] = (unsigned long)_orig.nraddr;                   \
   2216       __asm__ volatile(                                           \
   2217          "mr 11,%1\n\t"                                           \
   2218          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2219          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2220          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2221          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2222          "mr 11,%1\n\t"                                           \
   2223          "mr %0,3\n\t"                                            \
   2224          "ld 2,-16(11)" /* restore tocptr */                      \
   2225          : /*out*/   "=r" (_res)                                  \
   2226          : /*in*/    "r" (&_argvec[2])                            \
   2227          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2228       );                                                          \
   2229       lval = (__typeof__(lval)) _res;                             \
   2230    } while (0)
   2231 
   2232 #define CALL_FN_W_W(lval, orig, arg1)                             \
   2233    do {                                                           \
   2234       volatile OrigFn        _orig = (orig);                      \
   2235       volatile unsigned long _argvec[3+1];                        \
   2236       volatile unsigned long _res;                                \
   2237       /* _argvec[0] holds current r2 across the call */           \
   2238       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2239       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2240       _argvec[2+1] = (unsigned long)arg1;                         \
   2241       __asm__ volatile(                                           \
   2242          "mr 11,%1\n\t"                                           \
   2243          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2244          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2245          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2246          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2247          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2248          "mr 11,%1\n\t"                                           \
   2249          "mr %0,3\n\t"                                            \
   2250          "ld 2,-16(11)" /* restore tocptr */                      \
   2251          : /*out*/   "=r" (_res)                                  \
   2252          : /*in*/    "r" (&_argvec[2])                            \
   2253          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2254       );                                                          \
   2255       lval = (__typeof__(lval)) _res;                             \
   2256    } while (0)
   2257 
   2258 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   2259    do {                                                           \
   2260       volatile OrigFn        _orig = (orig);                      \
   2261       volatile unsigned long _argvec[3+2];                        \
   2262       volatile unsigned long _res;                                \
   2263       /* _argvec[0] holds current r2 across the call */           \
   2264       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2265       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2266       _argvec[2+1] = (unsigned long)arg1;                         \
   2267       _argvec[2+2] = (unsigned long)arg2;                         \
   2268       __asm__ volatile(                                           \
   2269          "mr 11,%1\n\t"                                           \
   2270          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2271          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2272          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2273          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   2274          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2275          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2276          "mr 11,%1\n\t"                                           \
   2277          "mr %0,3\n\t"                                            \
   2278          "ld 2,-16(11)" /* restore tocptr */                      \
   2279          : /*out*/   "=r" (_res)                                  \
   2280          : /*in*/    "r" (&_argvec[2])                            \
   2281          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2282       );                                                          \
   2283       lval = (__typeof__(lval)) _res;                             \
   2284    } while (0)
   2285 
   2286 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   2287    do {                                                           \
   2288       volatile OrigFn        _orig = (orig);                      \
   2289       volatile unsigned long _argvec[3+3];                        \
   2290       volatile unsigned long _res;                                \
   2291       /* _argvec[0] holds current r2 across the call */           \
   2292       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2293       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2294       _argvec[2+1] = (unsigned long)arg1;                         \
   2295       _argvec[2+2] = (unsigned long)arg2;                         \
   2296       _argvec[2+3] = (unsigned long)arg3;                         \
   2297       __asm__ volatile(                                           \
   2298          "mr 11,%1\n\t"                                           \
   2299          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2300          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2301          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2302          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   2303          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   2304          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2305          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2306          "mr 11,%1\n\t"                                           \
   2307          "mr %0,3\n\t"                                            \
   2308          "ld 2,-16(11)" /* restore tocptr */                      \
   2309          : /*out*/   "=r" (_res)                                  \
   2310          : /*in*/    "r" (&_argvec[2])                            \
   2311          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2312       );                                                          \
   2313       lval = (__typeof__(lval)) _res;                             \
   2314    } while (0)
   2315 
   2316 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   2317    do {                                                           \
   2318       volatile OrigFn        _orig = (orig);                      \
   2319       volatile unsigned long _argvec[3+4];                        \
   2320       volatile unsigned long _res;                                \
   2321       /* _argvec[0] holds current r2 across the call */           \
   2322       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2323       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2324       _argvec[2+1] = (unsigned long)arg1;                         \
   2325       _argvec[2+2] = (unsigned long)arg2;                         \
   2326       _argvec[2+3] = (unsigned long)arg3;                         \
   2327       _argvec[2+4] = (unsigned long)arg4;                         \
   2328       __asm__ volatile(                                           \
   2329          "mr 11,%1\n\t"                                           \
   2330          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2331          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2332          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2333          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   2334          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   2335          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   2336          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2337          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2338          "mr 11,%1\n\t"                                           \
   2339          "mr %0,3\n\t"                                            \
   2340          "ld 2,-16(11)" /* restore tocptr */                      \
   2341          : /*out*/   "=r" (_res)                                  \
   2342          : /*in*/    "r" (&_argvec[2])                            \
   2343          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2344       );                                                          \
   2345       lval = (__typeof__(lval)) _res;                             \
   2346    } while (0)
   2347 
   2348 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   2349    do {                                                           \
   2350       volatile OrigFn        _orig = (orig);                      \
   2351       volatile unsigned long _argvec[3+5];                        \
   2352       volatile unsigned long _res;                                \
   2353       /* _argvec[0] holds current r2 across the call */           \
   2354       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2355       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2356       _argvec[2+1] = (unsigned long)arg1;                         \
   2357       _argvec[2+2] = (unsigned long)arg2;                         \
   2358       _argvec[2+3] = (unsigned long)arg3;                         \
   2359       _argvec[2+4] = (unsigned long)arg4;                         \
   2360       _argvec[2+5] = (unsigned long)arg5;                         \
   2361       __asm__ volatile(                                           \
   2362          "mr 11,%1\n\t"                                           \
   2363          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2364          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2365          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2366          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   2367          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   2368          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   2369          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   2370          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2371          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2372          "mr 11,%1\n\t"                                           \
   2373          "mr %0,3\n\t"                                            \
   2374          "ld 2,-16(11)" /* restore tocptr */                      \
   2375          : /*out*/   "=r" (_res)                                  \
   2376          : /*in*/    "r" (&_argvec[2])                            \
   2377          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2378       );                                                          \
   2379       lval = (__typeof__(lval)) _res;                             \
   2380    } while (0)
   2381 
   2382 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   2383    do {                                                           \
   2384       volatile OrigFn        _orig = (orig);                      \
   2385       volatile unsigned long _argvec[3+6];                        \
   2386       volatile unsigned long _res;                                \
   2387       /* _argvec[0] holds current r2 across the call */           \
   2388       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2389       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2390       _argvec[2+1] = (unsigned long)arg1;                         \
   2391       _argvec[2+2] = (unsigned long)arg2;                         \
   2392       _argvec[2+3] = (unsigned long)arg3;                         \
   2393       _argvec[2+4] = (unsigned long)arg4;                         \
   2394       _argvec[2+5] = (unsigned long)arg5;                         \
   2395       _argvec[2+6] = (unsigned long)arg6;                         \
   2396       __asm__ volatile(                                           \
   2397          "mr 11,%1\n\t"                                           \
   2398          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2399          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2400          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2401          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   2402          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   2403          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   2404          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   2405          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   2406          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2407          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2408          "mr 11,%1\n\t"                                           \
   2409          "mr %0,3\n\t"                                            \
   2410          "ld 2,-16(11)" /* restore tocptr */                      \
   2411          : /*out*/   "=r" (_res)                                  \
   2412          : /*in*/    "r" (&_argvec[2])                            \
   2413          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2414       );                                                          \
   2415       lval = (__typeof__(lval)) _res;                             \
   2416    } while (0)
   2417 
   2418 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   2419                                  arg7)                            \
   2420    do {                                                           \
   2421       volatile OrigFn        _orig = (orig);                      \
   2422       volatile unsigned long _argvec[3+7];                        \
   2423       volatile unsigned long _res;                                \
   2424       /* _argvec[0] holds current r2 across the call */           \
   2425       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2426       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2427       _argvec[2+1] = (unsigned long)arg1;                         \
   2428       _argvec[2+2] = (unsigned long)arg2;                         \
   2429       _argvec[2+3] = (unsigned long)arg3;                         \
   2430       _argvec[2+4] = (unsigned long)arg4;                         \
   2431       _argvec[2+5] = (unsigned long)arg5;                         \
   2432       _argvec[2+6] = (unsigned long)arg6;                         \
   2433       _argvec[2+7] = (unsigned long)arg7;                         \
   2434       __asm__ volatile(                                           \
   2435          "mr 11,%1\n\t"                                           \
   2436          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2437          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2438          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2439          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   2440          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   2441          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   2442          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   2443          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   2444          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   2445          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2446          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2447          "mr 11,%1\n\t"                                           \
   2448          "mr %0,3\n\t"                                            \
   2449          "ld 2,-16(11)" /* restore tocptr */                      \
   2450          : /*out*/   "=r" (_res)                                  \
   2451          : /*in*/    "r" (&_argvec[2])                            \
   2452          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2453       );                                                          \
   2454       lval = (__typeof__(lval)) _res;                             \
   2455    } while (0)
   2456 
   2457 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   2458                                  arg7,arg8)                       \
   2459    do {                                                           \
   2460       volatile OrigFn        _orig = (orig);                      \
   2461       volatile unsigned long _argvec[3+8];                        \
   2462       volatile unsigned long _res;                                \
   2463       /* _argvec[0] holds current r2 across the call */           \
   2464       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2465       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2466       _argvec[2+1] = (unsigned long)arg1;                         \
   2467       _argvec[2+2] = (unsigned long)arg2;                         \
   2468       _argvec[2+3] = (unsigned long)arg3;                         \
   2469       _argvec[2+4] = (unsigned long)arg4;                         \
   2470       _argvec[2+5] = (unsigned long)arg5;                         \
   2471       _argvec[2+6] = (unsigned long)arg6;                         \
   2472       _argvec[2+7] = (unsigned long)arg7;                         \
   2473       _argvec[2+8] = (unsigned long)arg8;                         \
   2474       __asm__ volatile(                                           \
   2475          "mr 11,%1\n\t"                                           \
   2476          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2477          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2478          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2479          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   2480          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   2481          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   2482          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   2483          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   2484          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   2485          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
   2486          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2487          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2488          "mr 11,%1\n\t"                                           \
   2489          "mr %0,3\n\t"                                            \
   2490          "ld 2,-16(11)" /* restore tocptr */                      \
   2491          : /*out*/   "=r" (_res)                                  \
   2492          : /*in*/    "r" (&_argvec[2])                            \
   2493          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2494       );                                                          \
   2495       lval = (__typeof__(lval)) _res;                             \
   2496    } while (0)
   2497 
   2498 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   2499                                  arg7,arg8,arg9)                  \
   2500    do {                                                           \
   2501       volatile OrigFn        _orig = (orig);                      \
   2502       volatile unsigned long _argvec[3+9];                        \
   2503       volatile unsigned long _res;                                \
   2504       /* _argvec[0] holds current r2 across the call */           \
   2505       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2506       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2507       _argvec[2+1] = (unsigned long)arg1;                         \
   2508       _argvec[2+2] = (unsigned long)arg2;                         \
   2509       _argvec[2+3] = (unsigned long)arg3;                         \
   2510       _argvec[2+4] = (unsigned long)arg4;                         \
   2511       _argvec[2+5] = (unsigned long)arg5;                         \
   2512       _argvec[2+6] = (unsigned long)arg6;                         \
   2513       _argvec[2+7] = (unsigned long)arg7;                         \
   2514       _argvec[2+8] = (unsigned long)arg8;                         \
   2515       _argvec[2+9] = (unsigned long)arg9;                         \
   2516       __asm__ volatile(                                           \
   2517          "mr 11,%1\n\t"                                           \
   2518          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2519          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2520          "addi 1,1,-128\n\t"  /* expand stack frame */            \
   2521          /* arg9 */                                               \
   2522          "ld  3,72(11)\n\t"                                       \
   2523          "std 3,112(1)\n\t"                                       \
   2524          /* args1-8 */                                            \
   2525          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2526          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   2527          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   2528          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   2529          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   2530          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   2531          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   2532          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
   2533          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2534          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2535          "mr 11,%1\n\t"                                           \
   2536          "mr %0,3\n\t"                                            \
   2537          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
   2538          "addi 1,1,128"     /* restore frame */                   \
   2539          : /*out*/   "=r" (_res)                                  \
   2540          : /*in*/    "r" (&_argvec[2])                            \
   2541          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2542       );                                                          \
   2543       lval = (__typeof__(lval)) _res;                             \
   2544    } while (0)
   2545 
   2546 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   2547                                   arg7,arg8,arg9,arg10)           \
   2548    do {                                                           \
   2549       volatile OrigFn        _orig = (orig);                      \
   2550       volatile unsigned long _argvec[3+10];                       \
   2551       volatile unsigned long _res;                                \
   2552       /* _argvec[0] holds current r2 across the call */           \
   2553       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2554       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2555       _argvec[2+1] = (unsigned long)arg1;                         \
   2556       _argvec[2+2] = (unsigned long)arg2;                         \
   2557       _argvec[2+3] = (unsigned long)arg3;                         \
   2558       _argvec[2+4] = (unsigned long)arg4;                         \
   2559       _argvec[2+5] = (unsigned long)arg5;                         \
   2560       _argvec[2+6] = (unsigned long)arg6;                         \
   2561       _argvec[2+7] = (unsigned long)arg7;                         \
   2562       _argvec[2+8] = (unsigned long)arg8;                         \
   2563       _argvec[2+9] = (unsigned long)arg9;                         \
   2564       _argvec[2+10] = (unsigned long)arg10;                       \
   2565       __asm__ volatile(                                           \
   2566          "mr 11,%1\n\t"                                           \
   2567          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2568          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2569          "addi 1,1,-128\n\t"  /* expand stack frame */            \
   2570          /* arg10 */                                              \
   2571          "ld  3,80(11)\n\t"                                       \
   2572          "std 3,120(1)\n\t"                                       \
   2573          /* arg9 */                                               \
   2574          "ld  3,72(11)\n\t"                                       \
   2575          "std 3,112(1)\n\t"                                       \
   2576          /* args1-8 */                                            \
   2577          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2578          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   2579          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   2580          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   2581          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   2582          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   2583          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   2584          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
   2585          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2586          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2587          "mr 11,%1\n\t"                                           \
   2588          "mr %0,3\n\t"                                            \
   2589          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
   2590          "addi 1,1,128"     /* restore frame */                   \
   2591          : /*out*/   "=r" (_res)                                  \
   2592          : /*in*/    "r" (&_argvec[2])                            \
   2593          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2594       );                                                          \
   2595       lval = (__typeof__(lval)) _res;                             \
   2596    } while (0)
   2597 
   2598 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   2599                                   arg7,arg8,arg9,arg10,arg11)     \
   2600    do {                                                           \
   2601       volatile OrigFn        _orig = (orig);                      \
   2602       volatile unsigned long _argvec[3+11];                       \
   2603       volatile unsigned long _res;                                \
   2604       /* _argvec[0] holds current r2 across the call */           \
   2605       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2606       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2607       _argvec[2+1] = (unsigned long)arg1;                         \
   2608       _argvec[2+2] = (unsigned long)arg2;                         \
   2609       _argvec[2+3] = (unsigned long)arg3;                         \
   2610       _argvec[2+4] = (unsigned long)arg4;                         \
   2611       _argvec[2+5] = (unsigned long)arg5;                         \
   2612       _argvec[2+6] = (unsigned long)arg6;                         \
   2613       _argvec[2+7] = (unsigned long)arg7;                         \
   2614       _argvec[2+8] = (unsigned long)arg8;                         \
   2615       _argvec[2+9] = (unsigned long)arg9;                         \
   2616       _argvec[2+10] = (unsigned long)arg10;                       \
   2617       _argvec[2+11] = (unsigned long)arg11;                       \
   2618       __asm__ volatile(                                           \
   2619          "mr 11,%1\n\t"                                           \
   2620          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2621          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2622          "addi 1,1,-144\n\t"  /* expand stack frame */            \
   2623          /* arg11 */                                              \
   2624          "ld  3,88(11)\n\t"                                       \
   2625          "std 3,128(1)\n\t"                                       \
   2626          /* arg10 */                                              \
   2627          "ld  3,80(11)\n\t"                                       \
   2628          "std 3,120(1)\n\t"                                       \
   2629          /* arg9 */                                               \
   2630          "ld  3,72(11)\n\t"                                       \
   2631          "std 3,112(1)\n\t"                                       \
   2632          /* args1-8 */                                            \
   2633          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2634          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   2635          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   2636          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   2637          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   2638          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   2639          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   2640          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
   2641          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2642          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2643          "mr 11,%1\n\t"                                           \
   2644          "mr %0,3\n\t"                                            \
   2645          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
   2646          "addi 1,1,144"     /* restore frame */                   \
   2647          : /*out*/   "=r" (_res)                                  \
   2648          : /*in*/    "r" (&_argvec[2])                            \
   2649          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2650       );                                                          \
   2651       lval = (__typeof__(lval)) _res;                             \
   2652    } while (0)
   2653 
   2654 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   2655                                 arg7,arg8,arg9,arg10,arg11,arg12) \
   2656    do {                                                           \
   2657       volatile OrigFn        _orig = (orig);                      \
   2658       volatile unsigned long _argvec[3+12];                       \
   2659       volatile unsigned long _res;                                \
   2660       /* _argvec[0] holds current r2 across the call */           \
   2661       _argvec[1]   = (unsigned long)_orig.r2;                     \
   2662       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   2663       _argvec[2+1] = (unsigned long)arg1;                         \
   2664       _argvec[2+2] = (unsigned long)arg2;                         \
   2665       _argvec[2+3] = (unsigned long)arg3;                         \
   2666       _argvec[2+4] = (unsigned long)arg4;                         \
   2667       _argvec[2+5] = (unsigned long)arg5;                         \
   2668       _argvec[2+6] = (unsigned long)arg6;                         \
   2669       _argvec[2+7] = (unsigned long)arg7;                         \
   2670       _argvec[2+8] = (unsigned long)arg8;                         \
   2671       _argvec[2+9] = (unsigned long)arg9;                         \
   2672       _argvec[2+10] = (unsigned long)arg10;                       \
   2673       _argvec[2+11] = (unsigned long)arg11;                       \
   2674       _argvec[2+12] = (unsigned long)arg12;                       \
   2675       __asm__ volatile(                                           \
   2676          "mr 11,%1\n\t"                                           \
   2677          "std 2,-16(11)\n\t"  /* save tocptr */                   \
   2678          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   2679          "addi 1,1,-144\n\t"  /* expand stack frame */            \
   2680          /* arg12 */                                              \
   2681          "ld  3,96(11)\n\t"                                       \
   2682          "std 3,136(1)\n\t"                                       \
   2683          /* arg11 */                                              \
   2684          "ld  3,88(11)\n\t"                                       \
   2685          "std 3,128(1)\n\t"                                       \
   2686          /* arg10 */                                              \
   2687          "ld  3,80(11)\n\t"                                       \
   2688          "std 3,120(1)\n\t"                                       \
   2689          /* arg9 */                                               \
   2690          "ld  3,72(11)\n\t"                                       \
   2691          "std 3,112(1)\n\t"                                       \
   2692          /* args1-8 */                                            \
   2693          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   2694          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   2695          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   2696          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   2697          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   2698          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   2699          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   2700          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
   2701          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   2702          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   2703          "mr 11,%1\n\t"                                           \
   2704          "mr %0,3\n\t"                                            \
   2705          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
   2706          "addi 1,1,144"     /* restore frame */                   \
   2707          : /*out*/   "=r" (_res)                                  \
   2708          : /*in*/    "r" (&_argvec[2])                            \
   2709          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2710       );                                                          \
   2711       lval = (__typeof__(lval)) _res;                             \
   2712    } while (0)
   2713 
   2714 #endif /* PLAT_ppc64_linux */
   2715 
   2716 /* ------------------------- arm-linux ------------------------- */
   2717 
   2718 #if defined(PLAT_arm_linux)
   2719 
   2720 /* These regs are trashed by the hidden call. */
   2721 #define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
   2722 
   2723 /* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
   2724    long) == 4. */
   2725 
   2726 #define CALL_FN_W_v(lval, orig)                                   \
   2727    do {                                                           \
   2728       volatile OrigFn        _orig = (orig);                      \
   2729       volatile unsigned long _argvec[1];                          \
   2730       volatile unsigned long _res;                                \
   2731       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2732       __asm__ volatile(                                           \
   2733          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   2734          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   2735          "mov %0, r0\n"                                           \
   2736          : /*out*/   "=r" (_res)                                  \
   2737          : /*in*/    "0" (&_argvec[0])                            \
   2738          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2739       );                                                          \
   2740       lval = (__typeof__(lval)) _res;                             \
   2741    } while (0)
   2742 
   2743 #define CALL_FN_W_W(lval, orig, arg1)                             \
   2744    do {                                                           \
   2745       volatile OrigFn        _orig = (orig);                      \
   2746       volatile unsigned long _argvec[2];                          \
   2747       volatile unsigned long _res;                                \
   2748       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2749       _argvec[1] = (unsigned long)(arg1);                         \
   2750       __asm__ volatile(                                           \
   2751          "ldr r0, [%1, #4] \n\t"                                  \
   2752          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   2753          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   2754          "mov %0, r0\n"                                           \
   2755          : /*out*/   "=r" (_res)                                  \
   2756          : /*in*/    "0" (&_argvec[0])                            \
   2757          : /*trash*/ "cc", "memory",  __CALLER_SAVED_REGS         \
   2758       );                                                          \
   2759       lval = (__typeof__(lval)) _res;                             \
   2760    } while (0)
   2761 
   2762 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   2763    do {                                                           \
   2764       volatile OrigFn        _orig = (orig);                      \
   2765       volatile unsigned long _argvec[3];                          \
   2766       volatile unsigned long _res;                                \
   2767       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2768       _argvec[1] = (unsigned long)(arg1);                         \
   2769       _argvec[2] = (unsigned long)(arg2);                         \
   2770       __asm__ volatile(                                           \
   2771          "ldr r0, [%1, #4] \n\t"                                  \
   2772          "ldr r1, [%1, #8] \n\t"                                  \
   2773          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   2774          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   2775          "mov %0, r0\n"                                           \
   2776          : /*out*/   "=r" (_res)                                  \
   2777          : /*in*/    "0" (&_argvec[0])                            \
   2778          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2779       );                                                          \
   2780       lval = (__typeof__(lval)) _res;                             \
   2781    } while (0)
   2782 
   2783 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   2784    do {                                                           \
   2785       volatile OrigFn        _orig = (orig);                      \
   2786       volatile unsigned long _argvec[4];                          \
   2787       volatile unsigned long _res;                                \
   2788       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2789       _argvec[1] = (unsigned long)(arg1);                         \
   2790       _argvec[2] = (unsigned long)(arg2);                         \
   2791       _argvec[3] = (unsigned long)(arg3);                         \
   2792       __asm__ volatile(                                           \
   2793          "ldr r0, [%1, #4] \n\t"                                  \
   2794          "ldr r1, [%1, #8] \n\t"                                  \
   2795          "ldr r2, [%1, #12] \n\t"                                 \
   2796          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   2797          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   2798          "mov %0, r0\n"                                           \
   2799          : /*out*/   "=r" (_res)                                  \
   2800          : /*in*/    "0" (&_argvec[0])                            \
   2801          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2802       );                                                          \
   2803       lval = (__typeof__(lval)) _res;                             \
   2804    } while (0)
   2805 
   2806 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   2807    do {                                                           \
   2808       volatile OrigFn        _orig = (orig);                      \
   2809       volatile unsigned long _argvec[5];                          \
   2810       volatile unsigned long _res;                                \
   2811       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2812       _argvec[1] = (unsigned long)(arg1);                         \
   2813       _argvec[2] = (unsigned long)(arg2);                         \
   2814       _argvec[3] = (unsigned long)(arg3);                         \
   2815       _argvec[4] = (unsigned long)(arg4);                         \
   2816       __asm__ volatile(                                           \
   2817          "ldr r0, [%1, #4] \n\t"                                  \
   2818          "ldr r1, [%1, #8] \n\t"                                  \
   2819          "ldr r2, [%1, #12] \n\t"                                 \
   2820          "ldr r3, [%1, #16] \n\t"                                 \
   2821          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   2822          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   2823          "mov %0, r0"                                             \
   2824          : /*out*/   "=r" (_res)                                  \
   2825          : /*in*/    "0" (&_argvec[0])                            \
   2826          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2827       );                                                          \
   2828       lval = (__typeof__(lval)) _res;                             \
   2829    } while (0)
   2830 
   2831 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   2832    do {                                                           \
   2833       volatile OrigFn        _orig = (orig);                      \
   2834       volatile unsigned long _argvec[6];                          \
   2835       volatile unsigned long _res;                                \
   2836       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2837       _argvec[1] = (unsigned long)(arg1);                         \
   2838       _argvec[2] = (unsigned long)(arg2);                         \
   2839       _argvec[3] = (unsigned long)(arg3);                         \
   2840       _argvec[4] = (unsigned long)(arg4);                         \
   2841       _argvec[5] = (unsigned long)(arg5);                         \
   2842       __asm__ volatile(                                           \
   2843          "ldr r0, [%1, #20] \n\t"                                 \
   2844          "push {r0} \n\t"                                         \
   2845          "ldr r0, [%1, #4] \n\t"                                  \
   2846          "ldr r1, [%1, #8] \n\t"                                  \
   2847          "ldr r2, [%1, #12] \n\t"                                 \
   2848          "ldr r3, [%1, #16] \n\t"                                 \
   2849          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   2850          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   2851          "add sp, sp, #4 \n\t"                                    \
   2852          "mov %0, r0"                                             \
   2853          : /*out*/   "=r" (_res)                                  \
   2854          : /*in*/    "0" (&_argvec[0])                            \
   2855          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2856       );                                                          \
   2857       lval = (__typeof__(lval)) _res;                             \
   2858    } while (0)
   2859 
   2860 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   2861    do {                                                           \
   2862       volatile OrigFn        _orig = (orig);                      \
   2863       volatile unsigned long _argvec[7];                          \
   2864       volatile unsigned long _res;                                \
   2865       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2866       _argvec[1] = (unsigned long)(arg1);                         \
   2867       _argvec[2] = (unsigned long)(arg2);                         \
   2868       _argvec[3] = (unsigned long)(arg3);                         \
   2869       _argvec[4] = (unsigned long)(arg4);                         \
   2870       _argvec[5] = (unsigned long)(arg5);                         \
   2871       _argvec[6] = (unsigned long)(arg6);                         \
   2872       __asm__ volatile(                                           \
   2873          "ldr r0, [%1, #20] \n\t"                                 \
   2874          "ldr r1, [%1, #24] \n\t"                                 \
   2875          "push {r0, r1} \n\t"                                     \
   2876          "ldr r0, [%1, #4] \n\t"                                  \
   2877          "ldr r1, [%1, #8] \n\t"                                  \
   2878          "ldr r2, [%1, #12] \n\t"                                 \
   2879          "ldr r3, [%1, #16] \n\t"                                 \
   2880          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   2881          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   2882          "add sp, sp, #8 \n\t"                                    \
   2883          "mov %0, r0"                                             \
   2884          : /*out*/   "=r" (_res)                                  \
   2885          : /*in*/    "0" (&_argvec[0])                            \
   2886          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2887       );                                                          \
   2888       lval = (__typeof__(lval)) _res;                             \
   2889    } while (0)
   2890 
   2891 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   2892                                  arg7)                            \
   2893    do {                                                           \
   2894       volatile OrigFn        _orig = (orig);                      \
   2895       volatile unsigned long _argvec[8];                          \
   2896       volatile unsigned long _res;                                \
   2897       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2898       _argvec[1] = (unsigned long)(arg1);                         \
   2899       _argvec[2] = (unsigned long)(arg2);                         \
   2900       _argvec[3] = (unsigned long)(arg3);                         \
   2901       _argvec[4] = (unsigned long)(arg4);                         \
   2902       _argvec[5] = (unsigned long)(arg5);                         \
   2903       _argvec[6] = (unsigned long)(arg6);                         \
   2904       _argvec[7] = (unsigned long)(arg7);                         \
   2905       __asm__ volatile(                                           \
   2906          "ldr r0, [%1, #20] \n\t"                                 \
   2907          "ldr r1, [%1, #24] \n\t"                                 \
   2908          "ldr r2, [%1, #28] \n\t"                                 \
   2909          "push {r0, r1, r2} \n\t"                                 \
   2910          "ldr r0, [%1, #4] \n\t"                                  \
   2911          "ldr r1, [%1, #8] \n\t"                                  \
   2912          "ldr r2, [%1, #12] \n\t"                                 \
   2913          "ldr r3, [%1, #16] \n\t"                                 \
   2914          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   2915          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   2916          "add sp, sp, #12 \n\t"                                   \
   2917          "mov %0, r0"                                             \
   2918          : /*out*/   "=r" (_res)                                  \
   2919          : /*in*/    "0" (&_argvec[0])                            \
   2920          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2921       );                                                          \
   2922       lval = (__typeof__(lval)) _res;                             \
   2923    } while (0)
   2924 
   2925 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   2926                                  arg7,arg8)                       \
   2927    do {                                                           \
   2928       volatile OrigFn        _orig = (orig);                      \
   2929       volatile unsigned long _argvec[9];                          \
   2930       volatile unsigned long _res;                                \
   2931       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2932       _argvec[1] = (unsigned long)(arg1);                         \
   2933       _argvec[2] = (unsigned long)(arg2);                         \
   2934       _argvec[3] = (unsigned long)(arg3);                         \
   2935       _argvec[4] = (unsigned long)(arg4);                         \
   2936       _argvec[5] = (unsigned long)(arg5);                         \
   2937       _argvec[6] = (unsigned long)(arg6);                         \
   2938       _argvec[7] = (unsigned long)(arg7);                         \
   2939       _argvec[8] = (unsigned long)(arg8);                         \
   2940       __asm__ volatile(                                           \
   2941          "ldr r0, [%1, #20] \n\t"                                 \
   2942          "ldr r1, [%1, #24] \n\t"                                 \
   2943          "ldr r2, [%1, #28] \n\t"                                 \
   2944          "ldr r3, [%1, #32] \n\t"                                 \
   2945          "push {r0, r1, r2, r3} \n\t"                             \
   2946          "ldr r0, [%1, #4] \n\t"                                  \
   2947          "ldr r1, [%1, #8] \n\t"                                  \
   2948          "ldr r2, [%1, #12] \n\t"                                 \
   2949          "ldr r3, [%1, #16] \n\t"                                 \
   2950          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   2951          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   2952          "add sp, sp, #16 \n\t"                                   \
   2953          "mov %0, r0"                                             \
   2954          : /*out*/   "=r" (_res)                                  \
   2955          : /*in*/    "0" (&_argvec[0])                            \
   2956          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2957       );                                                          \
   2958       lval = (__typeof__(lval)) _res;                             \
   2959    } while (0)
   2960 
   2961 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   2962                                  arg7,arg8,arg9)                  \
   2963    do {                                                           \
   2964       volatile OrigFn        _orig = (orig);                      \
   2965       volatile unsigned long _argvec[10];                         \
   2966       volatile unsigned long _res;                                \
   2967       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   2968       _argvec[1] = (unsigned long)(arg1);                         \
   2969       _argvec[2] = (unsigned long)(arg2);                         \
   2970       _argvec[3] = (unsigned long)(arg3);                         \
   2971       _argvec[4] = (unsigned long)(arg4);                         \
   2972       _argvec[5] = (unsigned long)(arg5);                         \
   2973       _argvec[6] = (unsigned long)(arg6);                         \
   2974       _argvec[7] = (unsigned long)(arg7);                         \
   2975       _argvec[8] = (unsigned long)(arg8);                         \
   2976       _argvec[9] = (unsigned long)(arg9);                         \
   2977       __asm__ volatile(                                           \
   2978          "ldr r0, [%1, #20] \n\t"                                 \
   2979          "ldr r1, [%1, #24] \n\t"                                 \
   2980          "ldr r2, [%1, #28] \n\t"                                 \
   2981          "ldr r3, [%1, #32] \n\t"                                 \
   2982          "ldr r4, [%1, #36] \n\t"                                 \
   2983          "push {r0, r1, r2, r3, r4} \n\t"                         \
   2984          "ldr r0, [%1, #4] \n\t"                                  \
   2985          "ldr r1, [%1, #8] \n\t"                                  \
   2986          "ldr r2, [%1, #12] \n\t"                                 \
   2987          "ldr r3, [%1, #16] \n\t"                                 \
   2988          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   2989          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   2990          "add sp, sp, #20 \n\t"                                   \
   2991          "mov %0, r0"                                             \
   2992          : /*out*/   "=r" (_res)                                  \
   2993          : /*in*/    "0" (&_argvec[0])                            \
   2994          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   2995       );                                                          \
   2996       lval = (__typeof__(lval)) _res;                             \
   2997    } while (0)
   2998 
   2999 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   3000                                   arg7,arg8,arg9,arg10)           \
   3001    do {                                                           \
   3002       volatile OrigFn        _orig = (orig);                      \
   3003       volatile unsigned long _argvec[11];                         \
   3004       volatile unsigned long _res;                                \
   3005       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   3006       _argvec[1] = (unsigned long)(arg1);                         \
   3007       _argvec[2] = (unsigned long)(arg2);                         \
   3008       _argvec[3] = (unsigned long)(arg3);                         \
   3009       _argvec[4] = (unsigned long)(arg4);                         \
   3010       _argvec[5] = (unsigned long)(arg5);                         \
   3011       _argvec[6] = (unsigned long)(arg6);                         \
   3012       _argvec[7] = (unsigned long)(arg7);                         \
   3013       _argvec[8] = (unsigned long)(arg8);                         \
   3014       _argvec[9] = (unsigned long)(arg9);                         \
   3015       _argvec[10] = (unsigned long)(arg10);                       \
   3016       __asm__ volatile(                                           \
   3017          "ldr r0, [%1, #40] \n\t"                                 \
   3018          "push {r0} \n\t"                                         \
   3019          "ldr r0, [%1, #20] \n\t"                                 \
   3020          "ldr r1, [%1, #24] \n\t"                                 \
   3021          "ldr r2, [%1, #28] \n\t"                                 \
   3022          "ldr r3, [%1, #32] \n\t"                                 \
   3023          "ldr r4, [%1, #36] \n\t"                                 \
   3024          "push {r0, r1, r2, r3, r4} \n\t"                         \
   3025          "ldr r0, [%1, #4] \n\t"                                  \
   3026          "ldr r1, [%1, #8] \n\t"                                  \
   3027          "ldr r2, [%1, #12] \n\t"                                 \
   3028          "ldr r3, [%1, #16] \n\t"                                 \
   3029          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   3030          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   3031          "add sp, sp, #24 \n\t"                                   \
   3032          "mov %0, r0"                                             \
   3033          : /*out*/   "=r" (_res)                                  \
   3034          : /*in*/    "0" (&_argvec[0])                            \
   3035          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3036       );                                                          \
   3037       lval = (__typeof__(lval)) _res;                             \
   3038    } while (0)
   3039 
   3040 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
   3041                                   arg6,arg7,arg8,arg9,arg10,      \
   3042                                   arg11)                          \
   3043    do {                                                           \
   3044       volatile OrigFn        _orig = (orig);                      \
   3045       volatile unsigned long _argvec[12];                         \
   3046       volatile unsigned long _res;                                \
   3047       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   3048       _argvec[1] = (unsigned long)(arg1);                         \
   3049       _argvec[2] = (unsigned long)(arg2);                         \
   3050       _argvec[3] = (unsigned long)(arg3);                         \
   3051       _argvec[4] = (unsigned long)(arg4);                         \
   3052       _argvec[5] = (unsigned long)(arg5);                         \
   3053       _argvec[6] = (unsigned long)(arg6);                         \
   3054       _argvec[7] = (unsigned long)(arg7);                         \
   3055       _argvec[8] = (unsigned long)(arg8);                         \
   3056       _argvec[9] = (unsigned long)(arg9);                         \
   3057       _argvec[10] = (unsigned long)(arg10);                       \
   3058       _argvec[11] = (unsigned long)(arg11);                       \
   3059       __asm__ volatile(                                           \
   3060          "ldr r0, [%1, #40] \n\t"                                 \
   3061          "ldr r1, [%1, #44] \n\t"                                 \
   3062          "push {r0, r1} \n\t"                                     \
   3063          "ldr r0, [%1, #20] \n\t"                                 \
   3064          "ldr r1, [%1, #24] \n\t"                                 \
   3065          "ldr r2, [%1, #28] \n\t"                                 \
   3066          "ldr r3, [%1, #32] \n\t"                                 \
   3067          "ldr r4, [%1, #36] \n\t"                                 \
   3068          "push {r0, r1, r2, r3, r4} \n\t"                         \
   3069          "ldr r0, [%1, #4] \n\t"                                  \
   3070          "ldr r1, [%1, #8] \n\t"                                  \
   3071          "ldr r2, [%1, #12] \n\t"                                 \
   3072          "ldr r3, [%1, #16] \n\t"                                 \
   3073          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   3074          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   3075          "add sp, sp, #28 \n\t"                                   \
   3076          "mov %0, r0"                                             \
   3077          : /*out*/   "=r" (_res)                                  \
   3078          : /*in*/    "0" (&_argvec[0])                            \
   3079          : /*trash*/ "cc", "memory",__CALLER_SAVED_REGS           \
   3080       );                                                          \
   3081       lval = (__typeof__(lval)) _res;                             \
   3082    } while (0)
   3083 
   3084 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,       \
   3085                                   arg6,arg7,arg8,arg9,arg10,      \
   3086                                   arg11,arg12)                    \
   3087    do {                                                           \
   3088       volatile OrigFn        _orig = (orig);                      \
   3089       volatile unsigned long _argvec[13];                         \
   3090       volatile unsigned long _res;                                \
   3091       _argvec[0] = (unsigned long)_orig.nraddr;                   \
   3092       _argvec[1] = (unsigned long)(arg1);                         \
   3093       _argvec[2] = (unsigned long)(arg2);                         \
   3094       _argvec[3] = (unsigned long)(arg3);                         \
   3095       _argvec[4] = (unsigned long)(arg4);                         \
   3096       _argvec[5] = (unsigned long)(arg5);                         \
   3097       _argvec[6] = (unsigned long)(arg6);                         \
   3098       _argvec[7] = (unsigned long)(arg7);                         \
   3099       _argvec[8] = (unsigned long)(arg8);                         \
   3100       _argvec[9] = (unsigned long)(arg9);                         \
   3101       _argvec[10] = (unsigned long)(arg10);                       \
   3102       _argvec[11] = (unsigned long)(arg11);                       \
   3103       _argvec[12] = (unsigned long)(arg12);                       \
   3104       __asm__ volatile(                                           \
   3105          "ldr r0, [%1, #40] \n\t"                                 \
   3106          "ldr r1, [%1, #44] \n\t"                                 \
   3107          "ldr r2, [%1, #48] \n\t"                                 \
   3108          "push {r0, r1, r2} \n\t"                                 \
   3109          "ldr r0, [%1, #20] \n\t"                                 \
   3110          "ldr r1, [%1, #24] \n\t"                                 \
   3111          "ldr r2, [%1, #28] \n\t"                                 \
   3112          "ldr r3, [%1, #32] \n\t"                                 \
   3113          "ldr r4, [%1, #36] \n\t"                                 \
   3114          "push {r0, r1, r2, r3, r4} \n\t"                         \
   3115          "ldr r0, [%1, #4] \n\t"                                  \
   3116          "ldr r1, [%1, #8] \n\t"                                  \
   3117          "ldr r2, [%1, #12] \n\t"                                 \
   3118          "ldr r3, [%1, #16] \n\t"                                 \
   3119          "ldr r4, [%1] \n\t"  /* target->r4 */                    \
   3120          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4                   \
   3121          "add sp, sp, #32 \n\t"                                   \
   3122          "mov %0, r0"                                             \
   3123          : /*out*/   "=r" (_res)                                  \
   3124          : /*in*/    "0" (&_argvec[0])                            \
   3125          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3126       );                                                          \
   3127       lval = (__typeof__(lval)) _res;                             \
   3128    } while (0)
   3129 
   3130 #endif /* PLAT_arm_linux */
   3131 
   3132 /* ------------------------ ppc32-aix5 ------------------------- */
   3133 
   3134 #if defined(PLAT_ppc32_aix5)
   3135 
   3136 /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
   3137 
   3138 /* These regs are trashed by the hidden call. */
   3139 #define __CALLER_SAVED_REGS                                       \
   3140    "lr", "ctr", "xer",                                            \
   3141    "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
   3142    "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
   3143    "r11", "r12", "r13"
   3144 
   3145 /* Expand the stack frame, copying enough info that unwinding
   3146    still works.  Trashes r3. */
   3147 
   3148 #define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
   3149          "addi 1,1,-" #_n_fr "\n\t"                               \
   3150          "lwz  3," #_n_fr "(1)\n\t"                               \
   3151          "stw  3,0(1)\n\t"
   3152 
   3153 #define VG_CONTRACT_FRAME_BY(_n_fr)                               \
   3154          "addi 1,1," #_n_fr "\n\t"
   3155 
   3156 /* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned
   3157    long) == 4. */
   3158 
   3159 #define CALL_FN_W_v(lval, orig)                                   \
   3160    do {                                                           \
   3161       volatile OrigFn        _orig = (orig);                      \
   3162       volatile unsigned long _argvec[3+0];                        \
   3163       volatile unsigned long _res;                                \
   3164       /* _argvec[0] holds current r2 across the call */           \
   3165       _argvec[1] = (unsigned long)_orig.r2;                       \
   3166       _argvec[2] = (unsigned long)_orig.nraddr;                   \
   3167       __asm__ volatile(                                           \
   3168          "mr 11,%1\n\t"                                           \
   3169          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3170          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3171          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3172          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3173          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3174          "mr 11,%1\n\t"                                           \
   3175          "mr %0,3\n\t"                                            \
   3176          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3177          VG_CONTRACT_FRAME_BY(512)                                \
   3178          : /*out*/   "=r" (_res)                                  \
   3179          : /*in*/    "r" (&_argvec[2])                            \
   3180          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3181       );                                                          \
   3182       lval = (__typeof__(lval)) _res;                             \
   3183    } while (0)
   3184 
   3185 #define CALL_FN_W_W(lval, orig, arg1)                             \
   3186    do {                                                           \
   3187       volatile OrigFn        _orig = (orig);                      \
   3188       volatile unsigned long _argvec[3+1];                        \
   3189       volatile unsigned long _res;                                \
   3190       /* _argvec[0] holds current r2 across the call */           \
   3191       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3192       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3193       _argvec[2+1] = (unsigned long)arg1;                         \
   3194       __asm__ volatile(                                           \
   3195          "mr 11,%1\n\t"                                           \
   3196          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3197          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3198          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3199          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3200          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3201          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3202          "mr 11,%1\n\t"                                           \
   3203          "mr %0,3\n\t"                                            \
   3204          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3205          VG_CONTRACT_FRAME_BY(512)                                \
   3206          : /*out*/   "=r" (_res)                                  \
   3207          : /*in*/    "r" (&_argvec[2])                            \
   3208          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3209       );                                                          \
   3210       lval = (__typeof__(lval)) _res;                             \
   3211    } while (0)
   3212 
   3213 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   3214    do {                                                           \
   3215       volatile OrigFn        _orig = (orig);                      \
   3216       volatile unsigned long _argvec[3+2];                        \
   3217       volatile unsigned long _res;                                \
   3218       /* _argvec[0] holds current r2 across the call */           \
   3219       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3220       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3221       _argvec[2+1] = (unsigned long)arg1;                         \
   3222       _argvec[2+2] = (unsigned long)arg2;                         \
   3223       __asm__ volatile(                                           \
   3224          "mr 11,%1\n\t"                                           \
   3225          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3226          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3227          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3228          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3229          "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
   3230          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3231          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3232          "mr 11,%1\n\t"                                           \
   3233          "mr %0,3\n\t"                                            \
   3234          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3235          VG_CONTRACT_FRAME_BY(512)                                \
   3236          : /*out*/   "=r" (_res)                                  \
   3237          : /*in*/    "r" (&_argvec[2])                            \
   3238          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3239       );                                                          \
   3240       lval = (__typeof__(lval)) _res;                             \
   3241    } while (0)
   3242 
   3243 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   3244    do {                                                           \
   3245       volatile OrigFn        _orig = (orig);                      \
   3246       volatile unsigned long _argvec[3+3];                        \
   3247       volatile unsigned long _res;                                \
   3248       /* _argvec[0] holds current r2 across the call */           \
   3249       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3250       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3251       _argvec[2+1] = (unsigned long)arg1;                         \
   3252       _argvec[2+2] = (unsigned long)arg2;                         \
   3253       _argvec[2+3] = (unsigned long)arg3;                         \
   3254       __asm__ volatile(                                           \
   3255          "mr 11,%1\n\t"                                           \
   3256          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3257          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3258          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3259          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3260          "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
   3261          "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
   3262          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3263          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3264          "mr 11,%1\n\t"                                           \
   3265          "mr %0,3\n\t"                                            \
   3266          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3267          VG_CONTRACT_FRAME_BY(512)                                \
   3268          : /*out*/   "=r" (_res)                                  \
   3269          : /*in*/    "r" (&_argvec[2])                            \
   3270          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3271       );                                                          \
   3272       lval = (__typeof__(lval)) _res;                             \
   3273    } while (0)
   3274 
   3275 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   3276    do {                                                           \
   3277       volatile OrigFn        _orig = (orig);                      \
   3278       volatile unsigned long _argvec[3+4];                        \
   3279       volatile unsigned long _res;                                \
   3280       /* _argvec[0] holds current r2 across the call */           \
   3281       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3282       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3283       _argvec[2+1] = (unsigned long)arg1;                         \
   3284       _argvec[2+2] = (unsigned long)arg2;                         \
   3285       _argvec[2+3] = (unsigned long)arg3;                         \
   3286       _argvec[2+4] = (unsigned long)arg4;                         \
   3287       __asm__ volatile(                                           \
   3288          "mr 11,%1\n\t"                                           \
   3289          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3290          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3291          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3292          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3293          "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
   3294          "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
   3295          "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
   3296          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3297          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3298          "mr 11,%1\n\t"                                           \
   3299          "mr %0,3\n\t"                                            \
   3300          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3301          VG_CONTRACT_FRAME_BY(512)                                \
   3302          : /*out*/   "=r" (_res)                                  \
   3303          : /*in*/    "r" (&_argvec[2])                            \
   3304          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3305       );                                                          \
   3306       lval = (__typeof__(lval)) _res;                             \
   3307    } while (0)
   3308 
   3309 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   3310    do {                                                           \
   3311       volatile OrigFn        _orig = (orig);                      \
   3312       volatile unsigned long _argvec[3+5];                        \
   3313       volatile unsigned long _res;                                \
   3314       /* _argvec[0] holds current r2 across the call */           \
   3315       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3316       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3317       _argvec[2+1] = (unsigned long)arg1;                         \
   3318       _argvec[2+2] = (unsigned long)arg2;                         \
   3319       _argvec[2+3] = (unsigned long)arg3;                         \
   3320       _argvec[2+4] = (unsigned long)arg4;                         \
   3321       _argvec[2+5] = (unsigned long)arg5;                         \
   3322       __asm__ volatile(                                           \
   3323          "mr 11,%1\n\t"                                           \
   3324          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3325          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3326          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3327          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3328          "lwz  4, 8(11)\n\t" /* arg2->r4 */                       \
   3329          "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
   3330          "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
   3331          "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
   3332          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3333          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3334          "mr 11,%1\n\t"                                           \
   3335          "mr %0,3\n\t"                                            \
   3336          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3337          VG_CONTRACT_FRAME_BY(512)                                \
   3338          : /*out*/   "=r" (_res)                                  \
   3339          : /*in*/    "r" (&_argvec[2])                            \
   3340          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3341       );                                                          \
   3342       lval = (__typeof__(lval)) _res;                             \
   3343    } while (0)
   3344 
   3345 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   3346    do {                                                           \
   3347       volatile OrigFn        _orig = (orig);                      \
   3348       volatile unsigned long _argvec[3+6];                        \
   3349       volatile unsigned long _res;                                \
   3350       /* _argvec[0] holds current r2 across the call */           \
   3351       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3352       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3353       _argvec[2+1] = (unsigned long)arg1;                         \
   3354       _argvec[2+2] = (unsigned long)arg2;                         \
   3355       _argvec[2+3] = (unsigned long)arg3;                         \
   3356       _argvec[2+4] = (unsigned long)arg4;                         \
   3357       _argvec[2+5] = (unsigned long)arg5;                         \
   3358       _argvec[2+6] = (unsigned long)arg6;                         \
   3359       __asm__ volatile(                                           \
   3360          "mr 11,%1\n\t"                                           \
   3361          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3362          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3363          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3364          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3365          "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
   3366          "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
   3367          "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
   3368          "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
   3369          "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
   3370          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3371          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3372          "mr 11,%1\n\t"                                           \
   3373          "mr %0,3\n\t"                                            \
   3374          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3375          VG_CONTRACT_FRAME_BY(512)                                \
   3376          : /*out*/   "=r" (_res)                                  \
   3377          : /*in*/    "r" (&_argvec[2])                            \
   3378          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3379       );                                                          \
   3380       lval = (__typeof__(lval)) _res;                             \
   3381    } while (0)
   3382 
   3383 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   3384                                  arg7)                            \
   3385    do {                                                           \
   3386       volatile OrigFn        _orig = (orig);                      \
   3387       volatile unsigned long _argvec[3+7];                        \
   3388       volatile unsigned long _res;                                \
   3389       /* _argvec[0] holds current r2 across the call */           \
   3390       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3391       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3392       _argvec[2+1] = (unsigned long)arg1;                         \
   3393       _argvec[2+2] = (unsigned long)arg2;                         \
   3394       _argvec[2+3] = (unsigned long)arg3;                         \
   3395       _argvec[2+4] = (unsigned long)arg4;                         \
   3396       _argvec[2+5] = (unsigned long)arg5;                         \
   3397       _argvec[2+6] = (unsigned long)arg6;                         \
   3398       _argvec[2+7] = (unsigned long)arg7;                         \
   3399       __asm__ volatile(                                           \
   3400          "mr 11,%1\n\t"                                           \
   3401          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3402          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3403          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3404          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3405          "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
   3406          "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
   3407          "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
   3408          "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
   3409          "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
   3410          "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
   3411          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3412          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3413          "mr 11,%1\n\t"                                           \
   3414          "mr %0,3\n\t"                                            \
   3415          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3416          VG_CONTRACT_FRAME_BY(512)                                \
   3417          : /*out*/   "=r" (_res)                                  \
   3418          : /*in*/    "r" (&_argvec[2])                            \
   3419          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3420       );                                                          \
   3421       lval = (__typeof__(lval)) _res;                             \
   3422    } while (0)
   3423 
   3424 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   3425                                  arg7,arg8)                       \
   3426    do {                                                           \
   3427       volatile OrigFn        _orig = (orig);                      \
   3428       volatile unsigned long _argvec[3+8];                        \
   3429       volatile unsigned long _res;                                \
   3430       /* _argvec[0] holds current r2 across the call */           \
   3431       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3432       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3433       _argvec[2+1] = (unsigned long)arg1;                         \
   3434       _argvec[2+2] = (unsigned long)arg2;                         \
   3435       _argvec[2+3] = (unsigned long)arg3;                         \
   3436       _argvec[2+4] = (unsigned long)arg4;                         \
   3437       _argvec[2+5] = (unsigned long)arg5;                         \
   3438       _argvec[2+6] = (unsigned long)arg6;                         \
   3439       _argvec[2+7] = (unsigned long)arg7;                         \
   3440       _argvec[2+8] = (unsigned long)arg8;                         \
   3441       __asm__ volatile(                                           \
   3442          "mr 11,%1\n\t"                                           \
   3443          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3444          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3445          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3446          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3447          "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
   3448          "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
   3449          "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
   3450          "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
   3451          "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
   3452          "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
   3453          "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
   3454          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3455          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3456          "mr 11,%1\n\t"                                           \
   3457          "mr %0,3\n\t"                                            \
   3458          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3459          VG_CONTRACT_FRAME_BY(512)                                \
   3460          : /*out*/   "=r" (_res)                                  \
   3461          : /*in*/    "r" (&_argvec[2])                            \
   3462          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3463       );                                                          \
   3464       lval = (__typeof__(lval)) _res;                             \
   3465    } while (0)
   3466 
   3467 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   3468                                  arg7,arg8,arg9)                  \
   3469    do {                                                           \
   3470       volatile OrigFn        _orig = (orig);                      \
   3471       volatile unsigned long _argvec[3+9];                        \
   3472       volatile unsigned long _res;                                \
   3473       /* _argvec[0] holds current r2 across the call */           \
   3474       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3475       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3476       _argvec[2+1] = (unsigned long)arg1;                         \
   3477       _argvec[2+2] = (unsigned long)arg2;                         \
   3478       _argvec[2+3] = (unsigned long)arg3;                         \
   3479       _argvec[2+4] = (unsigned long)arg4;                         \
   3480       _argvec[2+5] = (unsigned long)arg5;                         \
   3481       _argvec[2+6] = (unsigned long)arg6;                         \
   3482       _argvec[2+7] = (unsigned long)arg7;                         \
   3483       _argvec[2+8] = (unsigned long)arg8;                         \
   3484       _argvec[2+9] = (unsigned long)arg9;                         \
   3485       __asm__ volatile(                                           \
   3486          "mr 11,%1\n\t"                                           \
   3487          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3488          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3489          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3490          VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
   3491          /* arg9 */                                               \
   3492          "lwz 3,36(11)\n\t"                                       \
   3493          "stw 3,56(1)\n\t"                                        \
   3494          /* args1-8 */                                            \
   3495          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3496          "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
   3497          "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
   3498          "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
   3499          "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
   3500          "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
   3501          "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
   3502          "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
   3503          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3504          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3505          "mr 11,%1\n\t"                                           \
   3506          "mr %0,3\n\t"                                            \
   3507          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3508          VG_CONTRACT_FRAME_BY(64)                                 \
   3509          VG_CONTRACT_FRAME_BY(512)                                \
   3510          : /*out*/   "=r" (_res)                                  \
   3511          : /*in*/    "r" (&_argvec[2])                            \
   3512          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3513       );                                                          \
   3514       lval = (__typeof__(lval)) _res;                             \
   3515    } while (0)
   3516 
   3517 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   3518                                   arg7,arg8,arg9,arg10)           \
   3519    do {                                                           \
   3520       volatile OrigFn        _orig = (orig);                      \
   3521       volatile unsigned long _argvec[3+10];                       \
   3522       volatile unsigned long _res;                                \
   3523       /* _argvec[0] holds current r2 across the call */           \
   3524       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3525       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3526       _argvec[2+1] = (unsigned long)arg1;                         \
   3527       _argvec[2+2] = (unsigned long)arg2;                         \
   3528       _argvec[2+3] = (unsigned long)arg3;                         \
   3529       _argvec[2+4] = (unsigned long)arg4;                         \
   3530       _argvec[2+5] = (unsigned long)arg5;                         \
   3531       _argvec[2+6] = (unsigned long)arg6;                         \
   3532       _argvec[2+7] = (unsigned long)arg7;                         \
   3533       _argvec[2+8] = (unsigned long)arg8;                         \
   3534       _argvec[2+9] = (unsigned long)arg9;                         \
   3535       _argvec[2+10] = (unsigned long)arg10;                       \
   3536       __asm__ volatile(                                           \
   3537          "mr 11,%1\n\t"                                           \
   3538          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3539          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3540          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3541          VG_EXPAND_FRAME_BY_trashes_r3(64)                        \
   3542          /* arg10 */                                              \
   3543          "lwz 3,40(11)\n\t"                                       \
   3544          "stw 3,60(1)\n\t"                                        \
   3545          /* arg9 */                                               \
   3546          "lwz 3,36(11)\n\t"                                       \
   3547          "stw 3,56(1)\n\t"                                        \
   3548          /* args1-8 */                                            \
   3549          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3550          "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
   3551          "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
   3552          "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
   3553          "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
   3554          "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
   3555          "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
   3556          "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
   3557          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3558          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3559          "mr 11,%1\n\t"                                           \
   3560          "mr %0,3\n\t"                                            \
   3561          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3562          VG_CONTRACT_FRAME_BY(64)                                 \
   3563          VG_CONTRACT_FRAME_BY(512)                                \
   3564          : /*out*/   "=r" (_res)                                  \
   3565          : /*in*/    "r" (&_argvec[2])                            \
   3566          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3567       );                                                          \
   3568       lval = (__typeof__(lval)) _res;                             \
   3569    } while (0)
   3570 
   3571 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   3572                                   arg7,arg8,arg9,arg10,arg11)     \
   3573    do {                                                           \
   3574       volatile OrigFn        _orig = (orig);                      \
   3575       volatile unsigned long _argvec[3+11];                       \
   3576       volatile unsigned long _res;                                \
   3577       /* _argvec[0] holds current r2 across the call */           \
   3578       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3579       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3580       _argvec[2+1] = (unsigned long)arg1;                         \
   3581       _argvec[2+2] = (unsigned long)arg2;                         \
   3582       _argvec[2+3] = (unsigned long)arg3;                         \
   3583       _argvec[2+4] = (unsigned long)arg4;                         \
   3584       _argvec[2+5] = (unsigned long)arg5;                         \
   3585       _argvec[2+6] = (unsigned long)arg6;                         \
   3586       _argvec[2+7] = (unsigned long)arg7;                         \
   3587       _argvec[2+8] = (unsigned long)arg8;                         \
   3588       _argvec[2+9] = (unsigned long)arg9;                         \
   3589       _argvec[2+10] = (unsigned long)arg10;                       \
   3590       _argvec[2+11] = (unsigned long)arg11;                       \
   3591       __asm__ volatile(                                           \
   3592          "mr 11,%1\n\t"                                           \
   3593          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3594          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3595          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3596          VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
   3597          /* arg11 */                                              \
   3598          "lwz 3,44(11)\n\t"                                       \
   3599          "stw 3,64(1)\n\t"                                        \
   3600          /* arg10 */                                              \
   3601          "lwz 3,40(11)\n\t"                                       \
   3602          "stw 3,60(1)\n\t"                                        \
   3603          /* arg9 */                                               \
   3604          "lwz 3,36(11)\n\t"                                       \
   3605          "stw 3,56(1)\n\t"                                        \
   3606          /* args1-8 */                                            \
   3607          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3608          "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
   3609          "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
   3610          "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
   3611          "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
   3612          "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
   3613          "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
   3614          "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
   3615          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3616          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3617          "mr 11,%1\n\t"                                           \
   3618          "mr %0,3\n\t"                                            \
   3619          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3620          VG_CONTRACT_FRAME_BY(72)                                 \
   3621          VG_CONTRACT_FRAME_BY(512)                                \
   3622          : /*out*/   "=r" (_res)                                  \
   3623          : /*in*/    "r" (&_argvec[2])                            \
   3624          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3625       );                                                          \
   3626       lval = (__typeof__(lval)) _res;                             \
   3627    } while (0)
   3628 
   3629 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   3630                                 arg7,arg8,arg9,arg10,arg11,arg12) \
   3631    do {                                                           \
   3632       volatile OrigFn        _orig = (orig);                      \
   3633       volatile unsigned long _argvec[3+12];                       \
   3634       volatile unsigned long _res;                                \
   3635       /* _argvec[0] holds current r2 across the call */           \
   3636       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3637       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3638       _argvec[2+1] = (unsigned long)arg1;                         \
   3639       _argvec[2+2] = (unsigned long)arg2;                         \
   3640       _argvec[2+3] = (unsigned long)arg3;                         \
   3641       _argvec[2+4] = (unsigned long)arg4;                         \
   3642       _argvec[2+5] = (unsigned long)arg5;                         \
   3643       _argvec[2+6] = (unsigned long)arg6;                         \
   3644       _argvec[2+7] = (unsigned long)arg7;                         \
   3645       _argvec[2+8] = (unsigned long)arg8;                         \
   3646       _argvec[2+9] = (unsigned long)arg9;                         \
   3647       _argvec[2+10] = (unsigned long)arg10;                       \
   3648       _argvec[2+11] = (unsigned long)arg11;                       \
   3649       _argvec[2+12] = (unsigned long)arg12;                       \
   3650       __asm__ volatile(                                           \
   3651          "mr 11,%1\n\t"                                           \
   3652          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3653          "stw  2,-8(11)\n\t"  /* save tocptr */                   \
   3654          "lwz  2,-4(11)\n\t"  /* use nraddr's tocptr */           \
   3655          VG_EXPAND_FRAME_BY_trashes_r3(72)                        \
   3656          /* arg12 */                                              \
   3657          "lwz 3,48(11)\n\t"                                       \
   3658          "stw 3,68(1)\n\t"                                        \
   3659          /* arg11 */                                              \
   3660          "lwz 3,44(11)\n\t"                                       \
   3661          "stw 3,64(1)\n\t"                                        \
   3662          /* arg10 */                                              \
   3663          "lwz 3,40(11)\n\t"                                       \
   3664          "stw 3,60(1)\n\t"                                        \
   3665          /* arg9 */                                               \
   3666          "lwz 3,36(11)\n\t"                                       \
   3667          "stw 3,56(1)\n\t"                                        \
   3668          /* args1-8 */                                            \
   3669          "lwz  3, 4(11)\n\t"  /* arg1->r3 */                      \
   3670          "lwz  4, 8(11)\n\t"  /* arg2->r4 */                      \
   3671          "lwz  5, 12(11)\n\t" /* arg3->r5 */                      \
   3672          "lwz  6, 16(11)\n\t" /* arg4->r6 */                      \
   3673          "lwz  7, 20(11)\n\t" /* arg5->r7 */                      \
   3674          "lwz  8, 24(11)\n\t" /* arg6->r8 */                      \
   3675          "lwz  9, 28(11)\n\t" /* arg7->r9 */                      \
   3676          "lwz 10, 32(11)\n\t" /* arg8->r10 */                     \
   3677          "lwz 11, 0(11)\n\t"  /* target->r11 */                   \
   3678          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3679          "mr 11,%1\n\t"                                           \
   3680          "mr %0,3\n\t"                                            \
   3681          "lwz 2,-8(11)\n\t" /* restore tocptr */                  \
   3682          VG_CONTRACT_FRAME_BY(72)                                 \
   3683          VG_CONTRACT_FRAME_BY(512)                                \
   3684          : /*out*/   "=r" (_res)                                  \
   3685          : /*in*/    "r" (&_argvec[2])                            \
   3686          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3687       );                                                          \
   3688       lval = (__typeof__(lval)) _res;                             \
   3689    } while (0)
   3690 
   3691 #endif /* PLAT_ppc32_aix5 */
   3692 
   3693 /* ------------------------ ppc64-aix5 ------------------------- */
   3694 
   3695 #if defined(PLAT_ppc64_aix5)
   3696 
   3697 /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
   3698 
   3699 /* These regs are trashed by the hidden call. */
   3700 #define __CALLER_SAVED_REGS                                       \
   3701    "lr", "ctr", "xer",                                            \
   3702    "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",        \
   3703    "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",   \
   3704    "r11", "r12", "r13"
   3705 
   3706 /* Expand the stack frame, copying enough info that unwinding
   3707    still works.  Trashes r3. */
   3708 
   3709 #define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr)                      \
   3710          "addi 1,1,-" #_n_fr "\n\t"                               \
   3711          "ld   3," #_n_fr "(1)\n\t"                               \
   3712          "std  3,0(1)\n\t"
   3713 
   3714 #define VG_CONTRACT_FRAME_BY(_n_fr)                               \
   3715          "addi 1,1," #_n_fr "\n\t"
   3716 
   3717 /* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned
   3718    long) == 8. */
   3719 
   3720 #define CALL_FN_W_v(lval, orig)                                   \
   3721    do {                                                           \
   3722       volatile OrigFn        _orig = (orig);                      \
   3723       volatile unsigned long _argvec[3+0];                        \
   3724       volatile unsigned long _res;                                \
   3725       /* _argvec[0] holds current r2 across the call */           \
   3726       _argvec[1] = (unsigned long)_orig.r2;                       \
   3727       _argvec[2] = (unsigned long)_orig.nraddr;                   \
   3728       __asm__ volatile(                                           \
   3729          "mr 11,%1\n\t"                                           \
   3730          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3731          "std  2,-16(11)\n\t" /* save tocptr */                   \
   3732          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   3733          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   3734          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3735          "mr 11,%1\n\t"                                           \
   3736          "mr %0,3\n\t"                                            \
   3737          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
   3738          VG_CONTRACT_FRAME_BY(512)                                \
   3739          : /*out*/   "=r" (_res)                                  \
   3740          : /*in*/    "r" (&_argvec[2])                            \
   3741          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3742       );                                                          \
   3743       lval = (__typeof__(lval)) _res;                             \
   3744    } while (0)
   3745 
   3746 #define CALL_FN_W_W(lval, orig, arg1)                             \
   3747    do {                                                           \
   3748       volatile OrigFn        _orig = (orig);                      \
   3749       volatile unsigned long _argvec[3+1];                        \
   3750       volatile unsigned long _res;                                \
   3751       /* _argvec[0] holds current r2 across the call */           \
   3752       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3753       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3754       _argvec[2+1] = (unsigned long)arg1;                         \
   3755       __asm__ volatile(                                           \
   3756          "mr 11,%1\n\t"                                           \
   3757          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3758          "std  2,-16(11)\n\t" /* save tocptr */                   \
   3759          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   3760          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   3761          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   3762          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3763          "mr 11,%1\n\t"                                           \
   3764          "mr %0,3\n\t"                                            \
   3765          "ld 2,-16(11)\n\t" /* restore tocptr */                  \
   3766          VG_CONTRACT_FRAME_BY(512)                                \
   3767          : /*out*/   "=r" (_res)                                  \
   3768          : /*in*/    "r" (&_argvec[2])                            \
   3769          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3770       );                                                          \
   3771       lval = (__typeof__(lval)) _res;                             \
   3772    } while (0)
   3773 
   3774 #define CALL_FN_W_WW(lval, orig, arg1,arg2)                       \
   3775    do {                                                           \
   3776       volatile OrigFn        _orig = (orig);                      \
   3777       volatile unsigned long _argvec[3+2];                        \
   3778       volatile unsigned long _res;                                \
   3779       /* _argvec[0] holds current r2 across the call */           \
   3780       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3781       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3782       _argvec[2+1] = (unsigned long)arg1;                         \
   3783       _argvec[2+2] = (unsigned long)arg2;                         \
   3784       __asm__ volatile(                                           \
   3785          "mr 11,%1\n\t"                                           \
   3786          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3787          "std  2,-16(11)\n\t" /* save tocptr */                   \
   3788          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   3789          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   3790          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   3791          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   3792          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3793          "mr 11,%1\n\t"                                           \
   3794          "mr %0,3\n\t"                                            \
   3795          "ld  2,-16(11)\n\t" /* restore tocptr */                 \
   3796          VG_CONTRACT_FRAME_BY(512)                                \
   3797          : /*out*/   "=r" (_res)                                  \
   3798          : /*in*/    "r" (&_argvec[2])                            \
   3799          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3800       );                                                          \
   3801       lval = (__typeof__(lval)) _res;                             \
   3802    } while (0)
   3803 
   3804 #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3)                 \
   3805    do {                                                           \
   3806       volatile OrigFn        _orig = (orig);                      \
   3807       volatile unsigned long _argvec[3+3];                        \
   3808       volatile unsigned long _res;                                \
   3809       /* _argvec[0] holds current r2 across the call */           \
   3810       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3811       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3812       _argvec[2+1] = (unsigned long)arg1;                         \
   3813       _argvec[2+2] = (unsigned long)arg2;                         \
   3814       _argvec[2+3] = (unsigned long)arg3;                         \
   3815       __asm__ volatile(                                           \
   3816          "mr 11,%1\n\t"                                           \
   3817          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3818          "std  2,-16(11)\n\t" /* save tocptr */                   \
   3819          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   3820          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   3821          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   3822          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   3823          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   3824          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3825          "mr 11,%1\n\t"                                           \
   3826          "mr %0,3\n\t"                                            \
   3827          "ld  2,-16(11)\n\t" /* restore tocptr */                 \
   3828          VG_CONTRACT_FRAME_BY(512)                                \
   3829          : /*out*/   "=r" (_res)                                  \
   3830          : /*in*/    "r" (&_argvec[2])                            \
   3831          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3832       );                                                          \
   3833       lval = (__typeof__(lval)) _res;                             \
   3834    } while (0)
   3835 
   3836 #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4)           \
   3837    do {                                                           \
   3838       volatile OrigFn        _orig = (orig);                      \
   3839       volatile unsigned long _argvec[3+4];                        \
   3840       volatile unsigned long _res;                                \
   3841       /* _argvec[0] holds current r2 across the call */           \
   3842       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3843       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3844       _argvec[2+1] = (unsigned long)arg1;                         \
   3845       _argvec[2+2] = (unsigned long)arg2;                         \
   3846       _argvec[2+3] = (unsigned long)arg3;                         \
   3847       _argvec[2+4] = (unsigned long)arg4;                         \
   3848       __asm__ volatile(                                           \
   3849          "mr 11,%1\n\t"                                           \
   3850          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3851          "std  2,-16(11)\n\t" /* save tocptr */                   \
   3852          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   3853          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   3854          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   3855          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   3856          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   3857          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   3858          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3859          "mr 11,%1\n\t"                                           \
   3860          "mr %0,3\n\t"                                            \
   3861          "ld  2,-16(11)\n\t" /* restore tocptr */                 \
   3862          VG_CONTRACT_FRAME_BY(512)                                \
   3863          : /*out*/   "=r" (_res)                                  \
   3864          : /*in*/    "r" (&_argvec[2])                            \
   3865          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3866       );                                                          \
   3867       lval = (__typeof__(lval)) _res;                             \
   3868    } while (0)
   3869 
   3870 #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5)        \
   3871    do {                                                           \
   3872       volatile OrigFn        _orig = (orig);                      \
   3873       volatile unsigned long _argvec[3+5];                        \
   3874       volatile unsigned long _res;                                \
   3875       /* _argvec[0] holds current r2 across the call */           \
   3876       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3877       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3878       _argvec[2+1] = (unsigned long)arg1;                         \
   3879       _argvec[2+2] = (unsigned long)arg2;                         \
   3880       _argvec[2+3] = (unsigned long)arg3;                         \
   3881       _argvec[2+4] = (unsigned long)arg4;                         \
   3882       _argvec[2+5] = (unsigned long)arg5;                         \
   3883       __asm__ volatile(                                           \
   3884          "mr 11,%1\n\t"                                           \
   3885          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3886          "std  2,-16(11)\n\t" /* save tocptr */                   \
   3887          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   3888          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   3889          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   3890          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   3891          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   3892          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   3893          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   3894          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3895          "mr 11,%1\n\t"                                           \
   3896          "mr %0,3\n\t"                                            \
   3897          "ld  2,-16(11)\n\t" /* restore tocptr */                 \
   3898          VG_CONTRACT_FRAME_BY(512)                                \
   3899          : /*out*/   "=r" (_res)                                  \
   3900          : /*in*/    "r" (&_argvec[2])                            \
   3901          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3902       );                                                          \
   3903       lval = (__typeof__(lval)) _res;                             \
   3904    } while (0)
   3905 
   3906 #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6)   \
   3907    do {                                                           \
   3908       volatile OrigFn        _orig = (orig);                      \
   3909       volatile unsigned long _argvec[3+6];                        \
   3910       volatile unsigned long _res;                                \
   3911       /* _argvec[0] holds current r2 across the call */           \
   3912       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3913       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3914       _argvec[2+1] = (unsigned long)arg1;                         \
   3915       _argvec[2+2] = (unsigned long)arg2;                         \
   3916       _argvec[2+3] = (unsigned long)arg3;                         \
   3917       _argvec[2+4] = (unsigned long)arg4;                         \
   3918       _argvec[2+5] = (unsigned long)arg5;                         \
   3919       _argvec[2+6] = (unsigned long)arg6;                         \
   3920       __asm__ volatile(                                           \
   3921          "mr 11,%1\n\t"                                           \
   3922          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3923          "std  2,-16(11)\n\t" /* save tocptr */                   \
   3924          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   3925          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   3926          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   3927          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   3928          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   3929          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   3930          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   3931          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   3932          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3933          "mr 11,%1\n\t"                                           \
   3934          "mr %0,3\n\t"                                            \
   3935          "ld  2,-16(11)\n\t" /* restore tocptr */                 \
   3936          VG_CONTRACT_FRAME_BY(512)                                \
   3937          : /*out*/   "=r" (_res)                                  \
   3938          : /*in*/    "r" (&_argvec[2])                            \
   3939          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3940       );                                                          \
   3941       lval = (__typeof__(lval)) _res;                             \
   3942    } while (0)
   3943 
   3944 #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   3945                                  arg7)                            \
   3946    do {                                                           \
   3947       volatile OrigFn        _orig = (orig);                      \
   3948       volatile unsigned long _argvec[3+7];                        \
   3949       volatile unsigned long _res;                                \
   3950       /* _argvec[0] holds current r2 across the call */           \
   3951       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3952       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3953       _argvec[2+1] = (unsigned long)arg1;                         \
   3954       _argvec[2+2] = (unsigned long)arg2;                         \
   3955       _argvec[2+3] = (unsigned long)arg3;                         \
   3956       _argvec[2+4] = (unsigned long)arg4;                         \
   3957       _argvec[2+5] = (unsigned long)arg5;                         \
   3958       _argvec[2+6] = (unsigned long)arg6;                         \
   3959       _argvec[2+7] = (unsigned long)arg7;                         \
   3960       __asm__ volatile(                                           \
   3961          "mr 11,%1\n\t"                                           \
   3962          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   3963          "std  2,-16(11)\n\t" /* save tocptr */                   \
   3964          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   3965          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   3966          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   3967          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   3968          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   3969          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   3970          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   3971          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   3972          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   3973          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   3974          "mr 11,%1\n\t"                                           \
   3975          "mr %0,3\n\t"                                            \
   3976          "ld  2,-16(11)\n\t" /* restore tocptr */                 \
   3977          VG_CONTRACT_FRAME_BY(512)                                \
   3978          : /*out*/   "=r" (_res)                                  \
   3979          : /*in*/    "r" (&_argvec[2])                            \
   3980          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   3981       );                                                          \
   3982       lval = (__typeof__(lval)) _res;                             \
   3983    } while (0)
   3984 
   3985 #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   3986                                  arg7,arg8)                       \
   3987    do {                                                           \
   3988       volatile OrigFn        _orig = (orig);                      \
   3989       volatile unsigned long _argvec[3+8];                        \
   3990       volatile unsigned long _res;                                \
   3991       /* _argvec[0] holds current r2 across the call */           \
   3992       _argvec[1]   = (unsigned long)_orig.r2;                     \
   3993       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   3994       _argvec[2+1] = (unsigned long)arg1;                         \
   3995       _argvec[2+2] = (unsigned long)arg2;                         \
   3996       _argvec[2+3] = (unsigned long)arg3;                         \
   3997       _argvec[2+4] = (unsigned long)arg4;                         \
   3998       _argvec[2+5] = (unsigned long)arg5;                         \
   3999       _argvec[2+6] = (unsigned long)arg6;                         \
   4000       _argvec[2+7] = (unsigned long)arg7;                         \
   4001       _argvec[2+8] = (unsigned long)arg8;                         \
   4002       __asm__ volatile(                                           \
   4003          "mr 11,%1\n\t"                                           \
   4004          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   4005          "std  2,-16(11)\n\t" /* save tocptr */                   \
   4006          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   4007          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   4008          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   4009          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   4010          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   4011          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   4012          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   4013          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   4014          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
   4015          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   4016          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   4017          "mr 11,%1\n\t"                                           \
   4018          "mr %0,3\n\t"                                            \
   4019          "ld  2,-16(11)\n\t" /* restore tocptr */                 \
   4020          VG_CONTRACT_FRAME_BY(512)                                \
   4021          : /*out*/   "=r" (_res)                                  \
   4022          : /*in*/    "r" (&_argvec[2])                            \
   4023          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   4024       );                                                          \
   4025       lval = (__typeof__(lval)) _res;                             \
   4026    } while (0)
   4027 
   4028 #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,   \
   4029                                  arg7,arg8,arg9)                  \
   4030    do {                                                           \
   4031       volatile OrigFn        _orig = (orig);                      \
   4032       volatile unsigned long _argvec[3+9];                        \
   4033       volatile unsigned long _res;                                \
   4034       /* _argvec[0] holds current r2 across the call */           \
   4035       _argvec[1]   = (unsigned long)_orig.r2;                     \
   4036       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   4037       _argvec[2+1] = (unsigned long)arg1;                         \
   4038       _argvec[2+2] = (unsigned long)arg2;                         \
   4039       _argvec[2+3] = (unsigned long)arg3;                         \
   4040       _argvec[2+4] = (unsigned long)arg4;                         \
   4041       _argvec[2+5] = (unsigned long)arg5;                         \
   4042       _argvec[2+6] = (unsigned long)arg6;                         \
   4043       _argvec[2+7] = (unsigned long)arg7;                         \
   4044       _argvec[2+8] = (unsigned long)arg8;                         \
   4045       _argvec[2+9] = (unsigned long)arg9;                         \
   4046       __asm__ volatile(                                           \
   4047          "mr 11,%1\n\t"                                           \
   4048          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   4049          "std  2,-16(11)\n\t" /* save tocptr */                   \
   4050          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   4051          VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
   4052          /* arg9 */                                               \
   4053          "ld  3,72(11)\n\t"                                       \
   4054          "std 3,112(1)\n\t"                                       \
   4055          /* args1-8 */                                            \
   4056          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   4057          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   4058          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   4059          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   4060          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   4061          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   4062          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   4063          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
   4064          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   4065          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   4066          "mr 11,%1\n\t"                                           \
   4067          "mr %0,3\n\t"                                            \
   4068          "ld  2,-16(11)\n\t" /* restore tocptr */                 \
   4069          VG_CONTRACT_FRAME_BY(128)                                \
   4070          VG_CONTRACT_FRAME_BY(512)                                \
   4071          : /*out*/   "=r" (_res)                                  \
   4072          : /*in*/    "r" (&_argvec[2])                            \
   4073          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   4074       );                                                          \
   4075       lval = (__typeof__(lval)) _res;                             \
   4076    } while (0)
   4077 
   4078 #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   4079                                   arg7,arg8,arg9,arg10)           \
   4080    do {                                                           \
   4081       volatile OrigFn        _orig = (orig);                      \
   4082       volatile unsigned long _argvec[3+10];                       \
   4083       volatile unsigned long _res;                                \
   4084       /* _argvec[0] holds current r2 across the call */           \
   4085       _argvec[1]   = (unsigned long)_orig.r2;                     \
   4086       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   4087       _argvec[2+1] = (unsigned long)arg1;                         \
   4088       _argvec[2+2] = (unsigned long)arg2;                         \
   4089       _argvec[2+3] = (unsigned long)arg3;                         \
   4090       _argvec[2+4] = (unsigned long)arg4;                         \
   4091       _argvec[2+5] = (unsigned long)arg5;                         \
   4092       _argvec[2+6] = (unsigned long)arg6;                         \
   4093       _argvec[2+7] = (unsigned long)arg7;                         \
   4094       _argvec[2+8] = (unsigned long)arg8;                         \
   4095       _argvec[2+9] = (unsigned long)arg9;                         \
   4096       _argvec[2+10] = (unsigned long)arg10;                       \
   4097       __asm__ volatile(                                           \
   4098          "mr 11,%1\n\t"                                           \
   4099          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   4100          "std  2,-16(11)\n\t" /* save tocptr */                   \
   4101          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   4102          VG_EXPAND_FRAME_BY_trashes_r3(128)                       \
   4103          /* arg10 */                                              \
   4104          "ld  3,80(11)\n\t"                                       \
   4105          "std 3,120(1)\n\t"                                       \
   4106          /* arg9 */                                               \
   4107          "ld  3,72(11)\n\t"                                       \
   4108          "std 3,112(1)\n\t"                                       \
   4109          /* args1-8 */                                            \
   4110          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   4111          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   4112          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   4113          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   4114          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   4115          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   4116          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   4117          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
   4118          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   4119          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   4120          "mr 11,%1\n\t"                                           \
   4121          "mr %0,3\n\t"                                            \
   4122          "ld  2,-16(11)\n\t" /* restore tocptr */                 \
   4123          VG_CONTRACT_FRAME_BY(128)                                \
   4124          VG_CONTRACT_FRAME_BY(512)                                \
   4125          : /*out*/   "=r" (_res)                                  \
   4126          : /*in*/    "r" (&_argvec[2])                            \
   4127          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   4128       );                                                          \
   4129       lval = (__typeof__(lval)) _res;                             \
   4130    } while (0)
   4131 
   4132 #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   4133                                   arg7,arg8,arg9,arg10,arg11)     \
   4134    do {                                                           \
   4135       volatile OrigFn        _orig = (orig);                      \
   4136       volatile unsigned long _argvec[3+11];                       \
   4137       volatile unsigned long _res;                                \
   4138       /* _argvec[0] holds current r2 across the call */           \
   4139       _argvec[1]   = (unsigned long)_orig.r2;                     \
   4140       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   4141       _argvec[2+1] = (unsigned long)arg1;                         \
   4142       _argvec[2+2] = (unsigned long)arg2;                         \
   4143       _argvec[2+3] = (unsigned long)arg3;                         \
   4144       _argvec[2+4] = (unsigned long)arg4;                         \
   4145       _argvec[2+5] = (unsigned long)arg5;                         \
   4146       _argvec[2+6] = (unsigned long)arg6;                         \
   4147       _argvec[2+7] = (unsigned long)arg7;                         \
   4148       _argvec[2+8] = (unsigned long)arg8;                         \
   4149       _argvec[2+9] = (unsigned long)arg9;                         \
   4150       _argvec[2+10] = (unsigned long)arg10;                       \
   4151       _argvec[2+11] = (unsigned long)arg11;                       \
   4152       __asm__ volatile(                                           \
   4153          "mr 11,%1\n\t"                                           \
   4154          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   4155          "std  2,-16(11)\n\t" /* save tocptr */                   \
   4156          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   4157          VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
   4158          /* arg11 */                                              \
   4159          "ld  3,88(11)\n\t"                                       \
   4160          "std 3,128(1)\n\t"                                       \
   4161          /* arg10 */                                              \
   4162          "ld  3,80(11)\n\t"                                       \
   4163          "std 3,120(1)\n\t"                                       \
   4164          /* arg9 */                                               \
   4165          "ld  3,72(11)\n\t"                                       \
   4166          "std 3,112(1)\n\t"                                       \
   4167          /* args1-8 */                                            \
   4168          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   4169          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   4170          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   4171          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   4172          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   4173          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   4174          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   4175          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
   4176          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   4177          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   4178          "mr 11,%1\n\t"                                           \
   4179          "mr %0,3\n\t"                                            \
   4180          "ld  2,-16(11)\n\t" /* restore tocptr */                 \
   4181          VG_CONTRACT_FRAME_BY(144)                                \
   4182          VG_CONTRACT_FRAME_BY(512)                                \
   4183          : /*out*/   "=r" (_res)                                  \
   4184          : /*in*/    "r" (&_argvec[2])                            \
   4185          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   4186       );                                                          \
   4187       lval = (__typeof__(lval)) _res;                             \
   4188    } while (0)
   4189 
   4190 #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6,  \
   4191                                 arg7,arg8,arg9,arg10,arg11,arg12) \
   4192    do {                                                           \
   4193       volatile OrigFn        _orig = (orig);                      \
   4194       volatile unsigned long _argvec[3+12];                       \
   4195       volatile unsigned long _res;                                \
   4196       /* _argvec[0] holds current r2 across the call */           \
   4197       _argvec[1]   = (unsigned long)_orig.r2;                     \
   4198       _argvec[2]   = (unsigned long)_orig.nraddr;                 \
   4199       _argvec[2+1] = (unsigned long)arg1;                         \
   4200       _argvec[2+2] = (unsigned long)arg2;                         \
   4201       _argvec[2+3] = (unsigned long)arg3;                         \
   4202       _argvec[2+4] = (unsigned long)arg4;                         \
   4203       _argvec[2+5] = (unsigned long)arg5;                         \
   4204       _argvec[2+6] = (unsigned long)arg6;                         \
   4205       _argvec[2+7] = (unsigned long)arg7;                         \
   4206       _argvec[2+8] = (unsigned long)arg8;                         \
   4207       _argvec[2+9] = (unsigned long)arg9;                         \
   4208       _argvec[2+10] = (unsigned long)arg10;                       \
   4209       _argvec[2+11] = (unsigned long)arg11;                       \
   4210       _argvec[2+12] = (unsigned long)arg12;                       \
   4211       __asm__ volatile(                                           \
   4212          "mr 11,%1\n\t"                                           \
   4213          VG_EXPAND_FRAME_BY_trashes_r3(512)                       \
   4214          "std  2,-16(11)\n\t" /* save tocptr */                   \
   4215          "ld   2,-8(11)\n\t"  /* use nraddr's tocptr */           \
   4216          VG_EXPAND_FRAME_BY_trashes_r3(144)                       \
   4217          /* arg12 */                                              \
   4218          "ld  3,96(11)\n\t"                                       \
   4219          "std 3,136(1)\n\t"                                       \
   4220          /* arg11 */                                              \
   4221          "ld  3,88(11)\n\t"                                       \
   4222          "std 3,128(1)\n\t"                                       \
   4223          /* arg10 */                                              \
   4224          "ld  3,80(11)\n\t"                                       \
   4225          "std 3,120(1)\n\t"                                       \
   4226          /* arg9 */                                               \
   4227          "ld  3,72(11)\n\t"                                       \
   4228          "std 3,112(1)\n\t"                                       \
   4229          /* args1-8 */                                            \
   4230          "ld   3, 8(11)\n\t"  /* arg1->r3 */                      \
   4231          "ld   4, 16(11)\n\t" /* arg2->r4 */                      \
   4232          "ld   5, 24(11)\n\t" /* arg3->r5 */                      \
   4233          "ld   6, 32(11)\n\t" /* arg4->r6 */                      \
   4234          "ld   7, 40(11)\n\t" /* arg5->r7 */                      \
   4235          "ld   8, 48(11)\n\t" /* arg6->r8 */                      \
   4236          "ld   9, 56(11)\n\t" /* arg7->r9 */                      \
   4237          "ld  10, 64(11)\n\t" /* arg8->r10 */                     \
   4238          "ld  11, 0(11)\n\t"  /* target->r11 */                   \
   4239          VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11                  \
   4240          "mr 11,%1\n\t"                                           \
   4241          "mr %0,3\n\t"                                            \
   4242          "ld  2,-16(11)\n\t" /* restore tocptr */                 \
   4243          VG_CONTRACT_FRAME_BY(144)                                \
   4244          VG_CONTRACT_FRAME_BY(512)                                \
   4245          : /*out*/   "=r" (_res)                                  \
   4246          : /*in*/    "r" (&_argvec[2])                            \
   4247          : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS          \
   4248       );                                                          \
   4249       lval = (__typeof__(lval)) _res;                             \
   4250    } while (0)
   4251 
   4252 #endif /* PLAT_ppc64_aix5 */
   4253 
   4254 
   4255 /* ------------------------------------------------------------------ */
   4256 /* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS.               */
   4257 /*                                                                    */
   4258 /* ------------------------------------------------------------------ */
   4259 
   4260 /* Some request codes.  There are many more of these, but most are not
   4261    exposed to end-user view.  These are the public ones, all of the
   4262    form 0x1000 + small_number.
   4263 
   4264    Core ones are in the range 0x00000000--0x0000ffff.  The non-public
   4265    ones start at 0x2000.
   4266 */
   4267 
   4268 /* These macros are used by tools -- they must be public, but don't
   4269    embed them into other programs. */
   4270 #define VG_USERREQ_TOOL_BASE(a,b) \
   4271    ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
   4272 #define VG_IS_TOOL_USERREQ(a, b, v) \
   4273    (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
   4274 
   4275 /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
   4276    This enum comprises an ABI exported by Valgrind to programs
   4277    which use client requests.  DO NOT CHANGE THE ORDER OF THESE
   4278    ENTRIES, NOR DELETE ANY -- add new ones at the end. */
   4279 typedef
   4280    enum { VG_USERREQ__RUNNING_ON_VALGRIND  = 0x1001,
   4281           VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
   4282 
   4283           /* These allow any function to be called from the simulated
   4284              CPU but run on the real CPU.  Nb: the first arg passed to
   4285              the function is always the ThreadId of the running
   4286              thread!  So CLIENT_CALL0 actually requires a 1 arg
   4287              function, etc. */
   4288           VG_USERREQ__CLIENT_CALL0 = 0x1101,
   4289           VG_USERREQ__CLIENT_CALL1 = 0x1102,
   4290           VG_USERREQ__CLIENT_CALL2 = 0x1103,
   4291           VG_USERREQ__CLIENT_CALL3 = 0x1104,
   4292 
   4293           /* Can be useful in regression testing suites -- eg. can
   4294              send Valgrind's output to /dev/null and still count
   4295              errors. */
   4296           VG_USERREQ__COUNT_ERRORS = 0x1201,
   4297 
   4298           /* These are useful and can be interpreted by any tool that
   4299              tracks malloc() et al, by using vg_replace_malloc.c. */
   4300           VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
   4301           VG_USERREQ__FREELIKE_BLOCK   = 0x1302,
   4302           /* Memory pool support. */
   4303           VG_USERREQ__CREATE_MEMPOOL   = 0x1303,
   4304           VG_USERREQ__DESTROY_MEMPOOL  = 0x1304,
   4305           VG_USERREQ__MEMPOOL_ALLOC    = 0x1305,
   4306           VG_USERREQ__MEMPOOL_FREE     = 0x1306,
   4307           VG_USERREQ__MEMPOOL_TRIM     = 0x1307,
   4308           VG_USERREQ__MOVE_MEMPOOL     = 0x1308,
   4309           VG_USERREQ__MEMPOOL_CHANGE   = 0x1309,
   4310           VG_USERREQ__MEMPOOL_EXISTS   = 0x130a,
   4311 
   4312           /* Allow printfs to valgrind log. */
   4313           /* The first two pass the va_list argument by value, which
   4314              assumes it is the same size as or smaller than a UWord,
   4315              which generally isn't the case.  Hence are deprecated.
   4316              The second two pass the vargs by reference and so are
   4317              immune to this problem. */
   4318           /* both :: char* fmt, va_list vargs (DEPRECATED) */
   4319           VG_USERREQ__PRINTF           = 0x1401,
   4320           VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
   4321           /* both :: char* fmt, va_list* vargs */
   4322           VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
   4323           VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,
   4324 
   4325           /* Stack support. */
   4326           VG_USERREQ__STACK_REGISTER   = 0x1501,
   4327           VG_USERREQ__STACK_DEREGISTER = 0x1502,
   4328           VG_USERREQ__STACK_CHANGE     = 0x1503,
   4329 
   4330           /* Wine support */
   4331           VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601,
   4332 
   4333           /* Querying of debug info. */
   4334           VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701
   4335    } Vg_ClientRequest;
   4336 
   4337 #if !defined(__GNUC__)
   4338 #  define __extension__ /* */
   4339 #endif
   4340 
   4341 
   4342 /*
   4343  * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
   4344  * client request and whose value equals the client request result.
   4345  */
   4346 
   4347 #if defined(NVALGRIND)
   4348 
   4349 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                               \
   4350         _zzq_default, _zzq_request,                                    \
   4351         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)         \
   4352    (_zzq_default)
   4353 
   4354 #else /*defined(NVALGRIND)*/
   4355 
   4356 #if defined(_MSC_VER)
   4357 
   4358 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                                \
   4359         _zzq_default, _zzq_request,                                     \
   4360         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)          \
   4361    (vg_VALGRIND_DO_CLIENT_REQUEST_EXPR((uintptr_t)(_zzq_default),       \
   4362         (_zzq_request), (uintptr_t)(_zzq_arg1), (uintptr_t)(_zzq_arg2), \
   4363         (uintptr_t)(_zzq_arg3), (uintptr_t)(_zzq_arg4),                 \
   4364         (uintptr_t)(_zzq_arg5)))
   4365 
   4366 static __inline unsigned
   4367 vg_VALGRIND_DO_CLIENT_REQUEST_EXPR(uintptr_t _zzq_default,
   4368                                    unsigned _zzq_request, uintptr_t _zzq_arg1,
   4369                                    uintptr_t _zzq_arg2, uintptr_t _zzq_arg3,
   4370                                    uintptr_t _zzq_arg4, uintptr_t _zzq_arg5)
   4371 {
   4372     unsigned _zzq_rlval;
   4373     VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, _zzq_request,
   4374                       _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5);
   4375     return _zzq_rlval;
   4376 }
   4377 
   4378 #else /*defined(_MSC_VER)*/
   4379 
   4380 #define VALGRIND_DO_CLIENT_REQUEST_EXPR(                               \
   4381         _zzq_default, _zzq_request,                                    \
   4382         _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5)         \
   4383    (__extension__({unsigned int _zzq_rlval;                            \
   4384     VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, _zzq_request, \
   4385                 _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
   4386     _zzq_rlval;                                                        \
   4387    }))
   4388 
   4389 #endif /*defined(_MSC_VER)*/
   4390 
   4391 #endif /*defined(NVALGRIND)*/
   4392 
   4393 
   4394 /* Returns the number of Valgrinds this code is running under.  That
   4395    is, 0 if running natively, 1 if running under Valgrind, 2 if
   4396    running under Valgrind which is running under another Valgrind,
   4397    etc. */
   4398 #define RUNNING_ON_VALGRIND                                           \
   4399     VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */,                   \
   4400                                     VG_USERREQ__RUNNING_ON_VALGRIND,  \
   4401                                     0, 0, 0, 0, 0)                    \
   4402 
   4403 
   4404 /* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
   4405    _qzz_len - 1].  Useful if you are debugging a JITter or some such,
   4406    since it provides a way to make sure valgrind will retranslate the
   4407    invalidated area.  Returns no value. */
   4408 #define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len)         \
   4409    {unsigned int _qzz_res;                                        \
   4410     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4411                                VG_USERREQ__DISCARD_TRANSLATIONS,  \
   4412                                _qzz_addr, _qzz_len, 0, 0, 0);     \
   4413    }
   4414 
   4415 
   4416 /* These requests are for getting Valgrind itself to print something.
   4417    Possibly with a backtrace.  This is a really ugly hack.  The return value
   4418    is the number of characters printed, excluding the "**<pid>** " part at the
   4419    start and the backtrace (if present). */
   4420 
   4421 #if defined(NVALGRIND)
   4422 
   4423 #  define VALGRIND_PRINTF(...)
   4424 #  define VALGRIND_PRINTF_BACKTRACE(...)
   4425 
   4426 #else /* NVALGRIND */
   4427 
   4428 #if !defined(_MSC_VER)
   4429 /* Modern GCC will optimize the static routine out if unused,
   4430    and unused attribute will shut down warnings about it.  */
   4431 static int VALGRIND_PRINTF(const char *format, ...)
   4432    __attribute__((format(__printf__, 1, 2), __unused__));
   4433 #endif
   4434 static int
   4435 #if defined(_MSC_VER)
   4436 __inline
   4437 #endif
   4438 VALGRIND_PRINTF(const char *format, ...)
   4439 {
   4440    unsigned long _qzz_res;
   4441    va_list vargs;
   4442    va_start(vargs, format);
   4443 #if defined(_MSC_VER)
   4444    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,
   4445                               VG_USERREQ__PRINTF_VALIST_BY_REF,
   4446                               (uintptr_t)format,
   4447                               (uintptr_t)&vargs,
   4448                               0, 0, 0);
   4449 #else
   4450    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,
   4451                               VG_USERREQ__PRINTF_VALIST_BY_REF,
   4452                               (unsigned long)format,
   4453                               (unsigned long)&vargs,
   4454                               0, 0, 0);
   4455 #endif
   4456    va_end(vargs);
   4457    return (int)_qzz_res;
   4458 }
   4459 
   4460 #if !defined(_MSC_VER)
   4461 static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
   4462    __attribute__((format(__printf__, 1, 2), __unused__));
   4463 #endif
   4464 static int
   4465 #if defined(_MSC_VER)
   4466 __inline
   4467 #endif
   4468 VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
   4469 {
   4470    unsigned long _qzz_res;
   4471    va_list vargs;
   4472    va_start(vargs, format);
   4473 #if defined(_MSC_VER)
   4474    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,
   4475                               VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
   4476                               (uintptr_t)format,
   4477                               (uintptr_t)&vargs,
   4478                               0, 0, 0);
   4479 #else
   4480    VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,
   4481                               VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
   4482                               (unsigned long)format,
   4483                               (unsigned long)&vargs,
   4484                               0, 0, 0);
   4485 #endif
   4486    va_end(vargs);
   4487    return (int)_qzz_res;
   4488 }
   4489 
   4490 #endif /* NVALGRIND */
   4491 
   4492 
   4493 /* These requests allow control to move from the simulated CPU to the
   4494    real CPU, calling an arbitary function.
   4495 
   4496    Note that the current ThreadId is inserted as the first argument.
   4497    So this call:
   4498 
   4499      VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
   4500 
   4501    requires f to have this signature:
   4502 
   4503      Word f(Word tid, Word arg1, Word arg2)
   4504 
   4505    where "Word" is a word-sized type.
   4506 
   4507    Note that these client requests are not entirely reliable.  For example,
   4508    if you call a function with them that subsequently calls printf(),
   4509    there's a high chance Valgrind will crash.  Generally, your prospects of
   4510    these working are made higher if the called function does not refer to
   4511    any global variables, and does not refer to any libc or other functions
   4512    (printf et al).  Any kind of entanglement with libc or dynamic linking is
   4513    likely to have a bad outcome, for tricky reasons which we've grappled
   4514    with a lot in the past.
   4515 */
   4516 #define VALGRIND_NON_SIMD_CALL0(_qyy_fn)                          \
   4517    __extension__                                                  \
   4518    ({unsigned long _qyy_res;                                      \
   4519     VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
   4520                                VG_USERREQ__CLIENT_CALL0,          \
   4521                                _qyy_fn,                           \
   4522                                0, 0, 0, 0);                       \
   4523     _qyy_res;                                                     \
   4524    })
   4525 
   4526 #define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1)               \
   4527    __extension__                                                  \
   4528    ({unsigned long _qyy_res;                                      \
   4529     VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
   4530                                VG_USERREQ__CLIENT_CALL1,          \
   4531                                _qyy_fn,                           \
   4532                                _qyy_arg1, 0, 0, 0);               \
   4533     _qyy_res;                                                     \
   4534    })
   4535 
   4536 #define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2)    \
   4537    __extension__                                                  \
   4538    ({unsigned long _qyy_res;                                      \
   4539     VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
   4540                                VG_USERREQ__CLIENT_CALL2,          \
   4541                                _qyy_fn,                           \
   4542                                _qyy_arg1, _qyy_arg2, 0, 0);       \
   4543     _qyy_res;                                                     \
   4544    })
   4545 
   4546 #define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
   4547    __extension__                                                  \
   4548    ({unsigned long _qyy_res;                                      \
   4549     VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
   4550                                VG_USERREQ__CLIENT_CALL3,          \
   4551                                _qyy_fn,                           \
   4552                                _qyy_arg1, _qyy_arg2,              \
   4553                                _qyy_arg3, 0);                     \
   4554     _qyy_res;                                                     \
   4555    })
   4556 
   4557 
   4558 /* Counts the number of errors that have been recorded by a tool.  Nb:
   4559    the tool must record the errors with VG_(maybe_record_error)() or
   4560    VG_(unique_error)() for them to be counted. */
   4561 #define VALGRIND_COUNT_ERRORS                                     \
   4562    __extension__                                                  \
   4563    ({unsigned int _qyy_res;                                       \
   4564     VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */,  \
   4565                                VG_USERREQ__COUNT_ERRORS,          \
   4566                                0, 0, 0, 0, 0);                    \
   4567     _qyy_res;                                                     \
   4568    })
   4569 
   4570 /* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
   4571    when heap blocks are allocated in order to give accurate results.  This
   4572    happens automatically for the standard allocator functions such as
   4573    malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
   4574    delete[], etc.
   4575 
   4576    But if your program uses a custom allocator, this doesn't automatically
   4577    happen, and Valgrind will not do as well.  For example, if you allocate
   4578    superblocks with mmap() and then allocates chunks of the superblocks, all
   4579    Valgrind's observations will be at the mmap() level and it won't know that
   4580    the chunks should be considered separate entities.  In Memcheck's case,
   4581    that means you probably won't get heap block overrun detection (because
   4582    there won't be redzones marked as unaddressable) and you definitely won't
   4583    get any leak detection.
   4584 
   4585    The following client requests allow a custom allocator to be annotated so
   4586    that it can be handled accurately by Valgrind.
   4587 
   4588    VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
   4589    by a malloc()-like function.  For Memcheck (an illustrative case), this
   4590    does two things:
   4591 
   4592    - It records that the block has been allocated.  This means any addresses
   4593      within the block mentioned in error messages will be
   4594      identified as belonging to the block.  It also means that if the block
   4595      isn't freed it will be detected by the leak checker.
   4596 
   4597    - It marks the block as being addressable and undefined (if 'is_zeroed' is
   4598      not set), or addressable and defined (if 'is_zeroed' is set).  This
   4599      controls how accesses to the block by the program are handled.
   4600 
   4601    'addr' is the start of the usable block (ie. after any
   4602    redzone), 'sizeB' is its size.  'rzB' is the redzone size if the allocator
   4603    can apply redzones -- these are blocks of padding at the start and end of
   4604    each block.  Adding redzones is recommended as it makes it much more likely
   4605    Valgrind will spot block overruns.  `is_zeroed' indicates if the memory is
   4606    zeroed (or filled with another predictable value), as is the case for
   4607    calloc().
   4608 
   4609    VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
   4610    heap block -- that will be used by the client program -- is allocated.
   4611    It's best to put it at the outermost level of the allocator if possible;
   4612    for example, if you have a function my_alloc() which calls
   4613    internal_alloc(), and the client request is put inside internal_alloc(),
   4614    stack traces relating to the heap block will contain entries for both
   4615    my_alloc() and internal_alloc(), which is probably not what you want.
   4616 
   4617    For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
   4618    custom blocks from within a heap block, B, that has been allocated with
   4619    malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
   4620    -- the custom blocks will take precedence.
   4621 
   4622    VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK.  For
   4623    Memcheck, it does two things:
   4624 
   4625    - It records that the block has been deallocated.  This assumes that the
   4626      block was annotated as having been allocated via
   4627      VALGRIND_MALLOCLIKE_BLOCK.  Otherwise, an error will be issued.
   4628 
   4629    - It marks the block as being unaddressable.
   4630 
   4631    VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
   4632    heap block is deallocated.
   4633 
   4634    In many cases, these two client requests will not be enough to get your
   4635    allocator working well with Memcheck.  More specifically, if your allocator
   4636    writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
   4637    will be necessary to mark the memory as addressable just before the zeroing
   4638    occurs, otherwise you'll get a lot of invalid write errors.  For example,
   4639    you'll need to do this if your allocator recycles freed blocks, but it
   4640    zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
   4641    Alternatively, if your allocator reuses freed blocks for allocator-internal
   4642    data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
   4643 
   4644    Really, what's happening is a blurring of the lines between the client
   4645    program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
   4646    memory should be considered unaddressable to the client program, but the
   4647    allocator knows more than the rest of the client program and so may be able
   4648    to safely access it.  Extra client requests are necessary for Valgrind to
   4649    understand the distinction between the allocator and the rest of the
   4650    program.
   4651 
   4652    Note: there is currently no VALGRIND_REALLOCLIKE_BLOCK client request;  it
   4653    has to be emulated with MALLOCLIKE/FREELIKE and memory copying.
   4654 
   4655    Ignored if addr == 0.
   4656 */
   4657 #define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed)    \
   4658    {unsigned int _qzz_res;                                        \
   4659     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4660                                VG_USERREQ__MALLOCLIKE_BLOCK,      \
   4661                                addr, sizeB, rzB, is_zeroed, 0);   \
   4662    }
   4663 
   4664 /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
   4665    Ignored if addr == 0.
   4666 */
   4667 #define VALGRIND_FREELIKE_BLOCK(addr, rzB)                        \
   4668    {unsigned int _qzz_res;                                        \
   4669     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4670                                VG_USERREQ__FREELIKE_BLOCK,        \
   4671                                addr, rzB, 0, 0, 0);               \
   4672    }
   4673 
   4674 /* Create a memory pool. */
   4675 #define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed)             \
   4676    {unsigned int _qzz_res;                                        \
   4677     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4678                                VG_USERREQ__CREATE_MEMPOOL,        \
   4679                                pool, rzB, is_zeroed, 0, 0);       \
   4680    }
   4681 
   4682 /* Destroy a memory pool. */
   4683 #define VALGRIND_DESTROY_MEMPOOL(pool)                            \
   4684    {unsigned int _qzz_res;                                        \
   4685     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4686                                VG_USERREQ__DESTROY_MEMPOOL,       \
   4687                                pool, 0, 0, 0, 0);                 \
   4688    }
   4689 
   4690 /* Associate a piece of memory with a memory pool. */
   4691 #define VALGRIND_MEMPOOL_ALLOC(pool, addr, size)                  \
   4692    {unsigned int _qzz_res;                                        \
   4693     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4694                                VG_USERREQ__MEMPOOL_ALLOC,         \
   4695                                pool, addr, size, 0, 0);           \
   4696    }
   4697 
   4698 /* Disassociate a piece of memory from a memory pool. */
   4699 #define VALGRIND_MEMPOOL_FREE(pool, addr)                         \
   4700    {unsigned int _qzz_res;                                        \
   4701     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4702                                VG_USERREQ__MEMPOOL_FREE,          \
   4703                                pool, addr, 0, 0, 0);              \
   4704    }
   4705 
   4706 /* Disassociate any pieces outside a particular range. */
   4707 #define VALGRIND_MEMPOOL_TRIM(pool, addr, size)                   \
   4708    {unsigned int _qzz_res;                                        \
   4709     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4710                                VG_USERREQ__MEMPOOL_TRIM,          \
   4711                                pool, addr, size, 0, 0);           \
   4712    }
   4713 
   4714 /* Resize and/or move a piece associated with a memory pool. */
   4715 #define VALGRIND_MOVE_MEMPOOL(poolA, poolB)                       \
   4716    {unsigned int _qzz_res;                                        \
   4717     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4718                                VG_USERREQ__MOVE_MEMPOOL,          \
   4719                                poolA, poolB, 0, 0, 0);            \
   4720    }
   4721 
   4722 /* Resize and/or move a piece associated with a memory pool. */
   4723 #define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size)         \
   4724    {unsigned int _qzz_res;                                        \
   4725     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4726                                VG_USERREQ__MEMPOOL_CHANGE,        \
   4727                                pool, addrA, addrB, size, 0);      \
   4728    }
   4729 
   4730 /* Return 1 if a mempool exists, else 0. */
   4731 #define VALGRIND_MEMPOOL_EXISTS(pool)                             \
   4732    __extension__                                                  \
   4733    ({unsigned int _qzz_res;                                       \
   4734     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4735                                VG_USERREQ__MEMPOOL_EXISTS,        \
   4736                                pool, 0, 0, 0, 0);                 \
   4737     _qzz_res;                                                     \
   4738    })
   4739 
   4740 /* Mark a piece of memory as being a stack. Returns a stack id. */
   4741 #define VALGRIND_STACK_REGISTER(start, end)                       \
   4742    __extension__                                                  \
   4743    ({unsigned int _qzz_res;                                       \
   4744     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4745                                VG_USERREQ__STACK_REGISTER,        \
   4746                                start, end, 0, 0, 0);              \
   4747     _qzz_res;                                                     \
   4748    })
   4749 
   4750 /* Unmark the piece of memory associated with a stack id as being a
   4751    stack. */
   4752 #define VALGRIND_STACK_DEREGISTER(id)                             \
   4753    {unsigned int _qzz_res;                                        \
   4754     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4755                                VG_USERREQ__STACK_DEREGISTER,      \
   4756                                id, 0, 0, 0, 0);                   \
   4757    }
   4758 
   4759 /* Change the start and end address of the stack id. */
   4760 #define VALGRIND_STACK_CHANGE(id, start, end)                     \
   4761    {unsigned int _qzz_res;                                        \
   4762     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4763                                VG_USERREQ__STACK_CHANGE,          \
   4764                                id, start, end, 0, 0);             \
   4765    }
   4766 
   4767 /* Load PDB debug info for Wine PE image_map. */
   4768 #define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta)   \
   4769    {unsigned int _qzz_res;                                        \
   4770     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4771                                VG_USERREQ__LOAD_PDB_DEBUGINFO,    \
   4772                                fd, ptr, total_size, delta, 0);    \
   4773    }
   4774 
   4775 /* Map a code address to a source file name and line number.  buf64
   4776    must point to a 64-byte buffer in the caller's address space.  The
   4777    result will be dumped in there and is guaranteed to be zero
   4778    terminated.  If no info is found, the first byte is set to zero. */
   4779 #define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64)                    \
   4780    {unsigned int _qzz_res;                                        \
   4781     VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0,                       \
   4782                                VG_USERREQ__MAP_IP_TO_SRCLOC,      \
   4783                                addr, buf64, 0, 0, 0);             \
   4784    }
   4785 
   4786 
   4787 #undef PLAT_x86_linux
   4788 #undef PLAT_amd64_linux
   4789 #undef PLAT_ppc32_linux
   4790 #undef PLAT_ppc64_linux
   4791 #undef PLAT_arm_linux
   4792 #undef PLAT_ppc32_aix5
   4793 #undef PLAT_ppc64_aix5
   4794 
   4795 #endif   /* __VALGRIND_H */
   4796 
   4797 #endif
   4798