+ This code is jumped to from the replacement-out stubs that are executed
+ when a thread reaches an activated replacement point.
+
+ The purpose of asm_replacement_out is to read out the parts of the
+ execution state that cannot be accessed from C code, store this state,
+ and then call the C function replace_me.
+
+ Stack layout:
+ 4 start of stack inside method to replace
+ 0 rplpoint * info on the replacement point that was reached
+
+*******************************************************************************/
+
+/* some room to accomodate changes of the stack frame size during replacement */
+ /* XXX we should find a cleaner solution here */
+#define REPLACEMENT_ROOM 512
+
+asm_replacement_out:
+ /* create stack frame */
+ sub $(sizeexecutionstate + REPLACEMENT_ROOM),sp
+
+ /* save registers in execution state */
+ mov %eax,(EAX*8+offes_intregs)(sp)
+ mov %ebx,(EBX*8+offes_intregs)(sp)
+ mov %ecx,(ECX*8+offes_intregs)(sp)
+ mov %edx,(EDX*8+offes_intregs)(sp)
+ mov %esi,(ESI*8+offes_intregs)(sp)
+ mov %edi,(EDI*8+offes_intregs)(sp)
+ mov %ebp,(EBP*8+offes_intregs)(sp)
+ movl $0 ,(ESP*8+offes_intregs)(sp) /* not used */
+
+#ifndef NDEBUG
+ /* clear high 32bit */
+ movl $0,(4+0*8+offes_intregs)(sp)
+ movl $0,(4+1*8+offes_intregs)(sp)
+ movl $0,(4+2*8+offes_intregs)(sp)
+ movl $0,(4+3*8+offes_intregs)(sp)
+ movl $0,(4+4*8+offes_intregs)(sp)
+ movl $0,(4+5*8+offes_intregs)(sp)
+ movl $0,(4+6*8+offes_intregs)(sp)
+ movl $0,(4+7*8+offes_intregs)(sp)
+#endif
+
+ /* calculate sp of method */
+ mov sp,itmp1
+ add $(sizeexecutionstate + REPLACEMENT_ROOM + 4),itmp1
+ mov itmp1,(offes_sp)(sp)
+
+ /* pv must be looked up via AVL tree */
+ movl $0,(offes_pv)(sp)
+
+ /* call replace_me */
+ mov -4(itmp1),itmp1 /* rplpoint * */
+ push sp /* arg1: execution state */
+ push itmp1 /* arg0: replacement point */
+ call replace_me /* call C function replace_me */
+ call abort /* NEVER REACHED */
+
+/* asm_replacement_in **********************************************************
+
+ This code writes the given execution state and jumps to the replacement
+ code.
+
+ This function never returns!
+
+ C prototype:
+ void asm_replacement_in(executionstate *es);
+
+*******************************************************************************/
+
+asm_replacement_in:
+ mov 4(sp),%ebp /* executionstate *es */
+
+ /* set new sp */
+ mov (offes_sp)(%ebp),%esp
+
+ /* store address of new code */
+ push (offes_pc)(%ebp)
+
+ /* copy registers from execution state */
+ mov (EAX*8+offes_intregs)(%ebp),%eax
+ mov (EBX*8+offes_intregs)(%ebp),%ebx
+ mov (ECX*8+offes_intregs)(%ebp),%ecx
+ mov (EDX*8+offes_intregs)(%ebp),%edx
+ mov (ESI*8+offes_intregs)(%ebp),%esi
+ mov (EDI*8+offes_intregs)(%ebp),%edi
+
+ mov (EBP*8+offes_intregs)(%ebp),%ebp
+
+ /* jump to new code */
+ ret