2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
6 #include <aros/arm/asm.h>
10 .globl AROS_SLIB_ENTRY(StackSwap,Exec,122)
12 AROS_SLIB_ENTRY(StackSwap,Exec,122):
14 // r0 contains parameter 'newStack'
15 // r1 contains ExecBase
16 // lr contains the return address
18 mov r3, r0 // newstack to r3
19 ldr r2, [r1, ThisTask] // r2 contains pointer to current task
21 /* Disable interrupts */
22 stmfd sp!, {r0, r1, r2, r3, lr}
23 ldr ip, [r1, Disable] // ip = GETVECADDR(Disable)
24 mov r0, r1 // One argument = SysBase
26 ldmfd sp!, {r0, r1, r2, r3, lr}
28 /* Swap Lower boundaries, use ip as scratch register (r1 holds SysBase!!!!) */
29 ldr r0, [r2, tc_SPLower] // r0 holds old contents of tc_SPLower
30 ldr ip, [r3, stk_Lower] // ip holds new contents of tc_SPLower
31 str ip, [r2, tc_SPLower] // write new contents
32 str r0, [r3, stk_Lower] // save old contents back into passed struct
35 /* Swap higher boundaries */
36 ldr r0, [r2, tc_SPUpper] // r0 holds old contents of tc_SPHigher
37 ldr ip, [r3, stk_Upper] // ip holds new contents of tc_SPHigher
38 str ip, [r2, tc_SPUpper] // write new contents
39 str r0, [r3, stk_Upper] // save old contents back into passed struct
41 /* Swap stackpointers */
42 mov r0, sp // current stack pointer to r0
43 ldr sp, [r3, stk_Pointer] // get desired stack pointer
44 str r0, [r3, stk_Pointer] // save old stack pointer
46 /* Enable interupts */
47 stmfd sp!, {r0, r1, lr}
48 ldr ip, [r1, Enable] // ip = GETVECADDR(Enable)
49 mov r0, r1 // One argument = SysBase
51 ldmfd sp!, {r0, r1, lr}
53 /* Return from this function. There's no 'rts' instruction...*/