[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