[SLOF] [PATCH 3/4] fbuffer: Implement MRMOVE as an accelerated primitive
Thomas Huth
thuth at redhat.com
Mon Sep 14 20:27:01 AEST 2015
On 12/09/15 07:28, Benjamin Herrenschmidt wrote:
> On Sat, 2015-09-12 at 00:41 +0200, Thomas Huth wrote:
>
>> register unsigned long r5 asm("r5") = arg2.u;
>> register unsigned long r6 = entry.u ;
>>
>> - asm volatile("mflr 31 ; mtctr %4 ; bctrl ; mtlr 31"
>> + asm volatile(" mtctr %4 ; bctrl "
>> : "=r" (r3)
>> : "r" (r3), "r" (r4), "r" (r5), "r" (r6)
>> : "ctr", "r6", "r7", "r8", "r9", "r10", "r11",
>> - "r12", "r13", "r31", "lr", "cc");
>> + "r12", "r13", "lr", "cc");
>>
>> return r3;
>> }
>
> That looks completely bogus. gcc has no idea that this is calling out
> and thus requires creation of a stack frame. Any reason why you can't
> just do a normal function pointer call ? (Maybe creating a little OPD
> on the stack).
This seems to work:
static unsigned long __attribute__((noinline))
call_c(cell arg0, cell arg1, cell arg2, cell entry)
{
unsigned long (*fp)(cell a0, cell a1, cell a2);
unsigned long desc[3];
desc[0] = entry.u;
desc[1] = desc[2] = 0;
barrier();
fp = (unsigned long (*)(cell a0, cell a1, cell a2))desc;
return fp(arg0, arg1, arg2);
}
But it also contains a small hack: I need the barrier() in between
(which is a asm volatile("":::"memory) call) or the compiler will not
recognize fp as being set (even though we compile with
-fno-strict-aliasing ?!?). I also tried using a union, but that did not
work out very well, somehow the compiler then tried to be really smart
and treated entry.u as pointer to a function descriptor, not a pointer
to the function code ... really strange (or I did something very wrong).
Do you think the above code is acceptable? If yes, I'll send a proper
patch for this, if not, I think I'll have a try with one of Segher's
suggestions.
Thomas
More information about the SLOF
mailing list