From fe7fa0baffe2cbc282eb3108be53762b919396c1 Mon Sep 17 00:00:00 2001 From: David Tardon Date: Mon, 27 Apr 2015 11:37:07 -0400 Subject: [PATCH] ppc64: do not use asm block to retrieve args Some versions of gcc clobber one of the registries that are used to pass arguments in the function's prologue, like: Dump of assembler code for function (anonymous namespace)::privateSnippetExecutor(): 510 { 0x00003fffaffe8454 <+0>: mflr r0 0x00003fffaffe8458 <+4>: std r0,16(r1) 0x00003fffaffe845c <+8>: std r29,-24(r1) 0x00003fffaffe8460 <+12>: std r30,-16(r1) 0x00003fffaffe8464 <+16>: std r31,-8(r1) 0x00003fffaffe8468 <+20>: stdu r1,-352(r1) 0x00003fffaffe846c <+24>: mr r31,r1 => 0x00003fffaffe8470 <+28>: ld r8,-28688(r13) 0x00003fffaffe8474 <+32>: std r8,312(r31) 0x00003fffaffe8478 <+36>: li r8,0 Reading the registries through variables makes gcc aware that they are used, so it does not touch them. It has got no negative effect on performance, as it produces the same object code as the current asm block. Change-Id: I3b99b0aa9944f9f33de9a42508e9d4dd23cec5e0 --- .../cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx | 65 ++++++++++------------ 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx index 0748d24..6b58246 100644 --- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx @@ -510,49 +510,42 @@ static typelib_TypeClass cpp_mediate( extern "C" void privateSnippetExecutor( ... ) { sal_uInt64 gpreg[ppc64::MAX_GPR_REGS]; + + register long r3 asm("r3"); gpreg[0] = r3; + register long r4 asm("r4"); gpreg[1] = r4; + register long r5 asm("r5"); gpreg[2] = r5; + register long r6 asm("r6"); gpreg[3] = r6; + register long r7 asm("r7"); gpreg[4] = r7; + register long r8 asm("r8"); gpreg[5] = r8; + register long r9 asm("r9"); gpreg[6] = r9; + register long r10 asm("r10"); gpreg[7] = r10; + double fpreg[ppc64::MAX_SSE_REGS]; __asm__ __volatile__ ( - "std 3, 0(%0)\t\n" - "std 4, 8(%0)\t\n" - "std 5, 16(%0)\t\n" - "std 6, 24(%0)\t\n" - "std 7, 32(%0)\t\n" - "std 8, 40(%0)\t\n" - "std 9, 48(%0)\t\n" - "std 10, 56(%0)\t\n" - "stfd 1, 0(%1)\t\n" - "stfd 2, 8(%1)\t\n" - "stfd 3, 16(%1)\t\n" - "stfd 4, 24(%1)\t\n" - "stfd 5, 32(%1)\t\n" - "stfd 6, 40(%1)\t\n" - "stfd 7, 48(%1)\t\n" - "stfd 8, 56(%1)\t\n" - "stfd 9, 64(%1)\t\n" - "stfd 10, 72(%1)\t\n" - "stfd 11, 80(%1)\t\n" - "stfd 12, 88(%1)\t\n" - "stfd 13, 96(%1)\t\n" - : : "r" (gpreg), "r" (fpreg) - : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", - "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9", + "stfd 1, 0(%0)\t\n" + "stfd 2, 8(%0)\t\n" + "stfd 3, 16(%0)\t\n" + "stfd 4, 24(%0)\t\n" + "stfd 5, 32(%0)\t\n" + "stfd 6, 40(%0)\t\n" + "stfd 7, 48(%0)\t\n" + "stfd 8, 56(%0)\t\n" + "stfd 9, 64(%0)\t\n" + "stfd 10, 72(%0)\t\n" + "stfd 11, 80(%0)\t\n" + "stfd 12, 88(%0)\t\n" + "stfd 13, 96(%0)\t\n" + : : "r" (fpreg) + : "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", "fr8", "fr9", "fr10", "fr11", "fr12", "fr13" ); - volatile long nOffsetAndIndex; - - //mr %r3, %r11 # move into arg1 the 64bit value passed from OOo - __asm__ __volatile__ ( - "mr %0, 11\n\t" - : "=r" (nOffsetAndIndex) : ); - - volatile long sp; + register long r11 asm("r11"); + const long nOffsetAndIndex = r11; - //stack pointer - __asm__ __volatile__ ( - "mr %0, 1\n\t" - : "=r" (sp) : ); + register long r1 asm("r1"); + const long sp = r1; #if defined(_CALL_ELF) && _CALL_ELF == 2 volatile long nRegReturn[2]; -- 2.3.5