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