https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78095
--- Comment #3 from Markus Trippelsdorf <trippels at gcc dot gnu.org> --- include/valgrind.h: 3263 /* These regs are trashed by the hidden call. */ 3264 #define __CALLER_SAVED_REGS \ 3265 "lr", "ctr", "xer", \ 3266 "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \ 3267 "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \ 3268 "r11", "r12", "r13" 3269 3270 /* Macros to save and align the stack before making a function 3271 call and restore it afterwards as gcc may not keep the stack 3272 pointer aligned if it doesn't realise calls are being made 3273 to other functions. */ 3274 3275 #define VALGRIND_ALIGN_STACK \ 3276 "mr 28,1\n\t" \ 3277 "rldicr 1,1,0,59\n\t" 3278 #define VALGRIND_RESTORE_STACK \ 3279 "mr 1,28\n\t" 3280 3281 /* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned 3282 long) == 8. */ 3283 3284 #define CALL_FN_W_v(lval, orig) \ 3285 do { \ 3286 volatile OrigFn _orig = (orig); \ 3287 volatile unsigned long _argvec[3+0]; \ 3288 volatile unsigned long _res; \ 3289 /* _argvec[0] holds current r2 across the call */ \ 3290 _argvec[1] = (unsigned long)_orig.r2; \ 3291 _argvec[2] = (unsigned long)_orig.nraddr; \ 3292 __asm__ volatile( \ 3293 VALGRIND_ALIGN_STACK \ 3294 "mr 12,%1\n\t" \ 3295 "std 2,-16(12)\n\t" /* save tocptr */ \ 3296 "ld 2,-8(12)\n\t" /* use nraddr's tocptr */ \ 3297 "ld 12, 0(12)\n\t" /* target->r12 */ \ 3298 VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R12 \ 3299 "mr 12,%1\n\t" \ 3300 "mr %0,3\n\t" \ 3301 "ld 2,-16(12)\n\t" /* restore tocptr */ \ 3302 VALGRIND_RESTORE_STACK \ 3303 : /*out*/ "=r" (_res) \ 3304 : /*in*/ "r" (&_argvec[2]) \ 3305 : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r28" \ 3306 ); \ 3307 lval = (__typeof__(lval)) _res; \ 3308 } while (0)