@ The stack switching logic for the arm thumb instruction set. @ Written by Richard Tew, 2nd May 2006. @ @ It is not possible to do this as inline assembler as gcc generates functions @ where the stack register is preserved, so any changes we make to it will be @ discarded. However, any stack copying we have done is left in place, which @ results in corrupt state. @ @ This adapts the MASM approach written by Kristjan Jonsson, where early @ returns from SLP_SAVE_STATE (within slp_save_state) are flagged by setting @ the low bit of the return value. This either indicates that there was an @ error (-1) or that we do not need to restore the stack (1) as we are only @ here to save the current one. @ @ I know little arm thumb assembly, so in case anyone else wants to know the @ approach I took, I will document it here. The first uncertainty was which @ registers should be saved. I took this section of code from the assembler @ generated by gcc with a command line of: @ gcc -mthumb -S slp_transfer.c @ where slp_transfer included the inline version of slp_switch for the arm @ thumb. Another initial uncertainty were the instructions needed to: @ a) obtain the stack pointer. (mov r0, sp) @ b) restore the stack pointer. (add sp, sp, r0) @ which were used in the original inlined assembly. The rest of the code was @ just patched together based on Kristjan's existing masm source code. @ (int) slp_switch (void); .thumb .align 2 .global slp_switch .type slp_switch, %function @ Apparently useful for .map files. .thumb_func slp_switch: push {r4, r5, r6, r7, lr} mov r7, fp mov r6, sl mov r5, r9 mov r4, r8 push {r4, r5, r6, r7} mov r0, sp bl slp_save_state @ diff = slp_save_state([r0]stackref) mov r1, #0 @ r1 = -1 mvn r1, r1 cmp r0, r1 @ if (diff == -1) beq .exit @ return -1; cmp r0, #1 @ if (diff == 1) beq .no_restore @ return 0; .restore: add sp, sp, r0 @ Adjust the stack pointer for the state we are restoring. bl slp_restore_state @ slp_restore_state() .no_restore: mov r0, #0 @ Switch successful (whether we restored or not). .exit: pop {r2, r3, r4, r5} mov r8, r2 mov r9, r3 mov sl, r4 mov fp, r5 pop {r4, r5, r6, r7, pc} .size slp_switch, .-slp_switch @ Apparently useful for .map files.