enter_context_arm32_sysv_elf.s 2.18 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
	.arm
	.text
	.global	__cs_enter_context
	.type	__cs_enter_context, %function

__cs_enter_context:
        /* Parameter List (in order)
        * r0 = new stack pointer
        * r1 = first parameter to callback
        * r2 = callback function pointer
        * r3 = new stack limit (not used on most platforms)
        *
        * Return
        * r0 = continuation that returned control back to the caller (null if fallthrough)
        *
        * Variables
        * r4 = temporary for the old stack pointer */

        /* ========== Save State ========== */
        /* store programm counter for later return */
        push {lr}
        /* store callee saved registers */
        push {r4-r12,lr}
        /* store floating point extension registers */
        #if (defined(__VFP_FP__) && !defined(__SOFTFP__))
        sub sp, sp, #64
        vstmia sp, {d8-d15}
        #endif
        /* ========== Save State ========== */

        /* Perform change to new stack */
        /* Keep old stack as second parameter to our callback function. */
        mov r4, sp
        /* Make sure that stack start is properly aligned. */
        and r0, r0, #-16
        /* Switch to new stack pointer. */
        mov sp, r0

        /* Perform actual function call, this will now be on the new stack */
        /* r0 = first parametor to callback (continuation) */
        /* r1 = second parameter to callback (arbetary pointer) */
        mov r0, r4
        blx r2

        /* Restore state of returned continuation. */
        /* To do so we first reset the stack pointer (which we get returned in r0). */
        /* After that we execute our standard restore procedere to pop the state from the stack. */
        mov sp, r0

        /* ========== Restore State ========== */
        /* restore floating point extension registers */
        #if (defined(__VFP_FP__) && !defined(__SOFTFP__))
        vldmia sp, {d8-d15}
        add sp, sp, #64
        #endif
        /* restore callee saved registers */
        pop {r4-r12,lr}
        /* ========== Restore State ========== */

        /* Just return back from the call. */
        /* This is the end of a fiber, so we have no continuation. */
        eor r0, r0, r0
        pop {pc}