On 04/05/16 19:40, Segher Boessenkool wrote:
On Wed, May 04, 2016 at 07:30:03PM +0100, Mark Cave-Ayland wrote:
On 04/05/16 16:31, Segher Boessenkool wrote:
Can you explain further? The v2 patch uses a single register marked as clobber for mflr/mtlr and the volatile modifier for __context ensures that the old value being written to the stack doesn't get optimised away by the compiler. What else am I missing?
A normal (ABI-following) function can clobber all of r9..r12, so that "bl" instruction can, too. If the function it calls is special (so at least written as assembler), things are different of course.
[ r3..r12, I can't type ]
Right, we're talking about this section of code in the caller:
asm __volatile__ ("mflr %%r9\n\t" "stw %%r9, %0\n\t" "bl __switch_context\n\t" "lwz %%r9, %0\n\t" "mtlr %%r9\n\t" : "=m" (lr) : "m" (lr) : "%r9" );
The mflr/mtlr are being used to preserve the original link register before branching to the assembler routine at __switch_context which does all the hard work.
And the bl clobbers at least r4,r5.
I'm sorry but I still don't understand? __switch_context loads a completely new CPU state from the stack in order to switch context so actually every single register gets clobbered. But we preserve the original link register in a local variable to ensure that we can jump back to where we were upon return.
ATB,
Mark.