blob: ef6c3326e09283353d2c46e9c767bfb738705439 [file] [log] [blame]
/*
* typedef void (*PushAllRegistersCallback)(ThreadState*, intptr_t*);
* extern "C" void PushAllRegisters(ThreadState*, PushAllRegistersCallback)
*/
.type PushAllRegisters, %function
.global PushAllRegisters
.hidden PushAllRegisters
PushAllRegisters:
// Push all callee-saves registers to get them
// on the stack for conservative stack scanning.
// Reserve space for callee-saved registers and minimal stack frame.
mflr 0
std 0,16(1)
stdu 1,-176(1) // 3218*8 = min stack non-volatile registers
// Save the callee-saved register
std 31,168(1)
std 30,160(1)
std 29,152(1)
std 28,144(1)
std 27,136(1)
std 26,128(1)
std 25,120(1)
std 24,112(1)
std 23,104(1)
std 22,96(1)
std 21,88(1)
std 20,80(1)
std 19,72(1)
std 18,64(1)
std 17,56(1)
std 16,48(1)
std 15,40(1)
std 14,32(1)
// Note: the callee-saved floating point registers do not need to be
// copied to the stack, because fp registers never hold heap pointers
// and so do not need to be kept visible to the garbage collector.
// Pass the first argument untouched in r3 and the
// stack pointer to the callback.
std 2, 24(1)
mtctr 4
mr 12, 4
mr 4, 1
bctrl
ld 2, 24(1)
// Adjust stack, restore return address and return.
// Note: the copied registers do not need to be reloaded here,
// because they were preserved by the called routine.
addi 1,1,176
ld 0,16(1)
mtlr 0
blr