revert between 56095 -> 55830 in arch
[AROS.git] / arch / m68k-mac / exec / stackswap.S
blob7ee923828f50d15f500e4d99a106d38db6200463
1 /*
2     Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3     $Id$
4 */
6 /*****************************************************************************
7  
8     NAME
9  
10         AROS_LH1(void, StackSwap,
12     SYNOPSIS
13         AROS_LHA(struct StackSwapStruct *, newStack, A0),
15     LOCATION
16         struct ExecBase *, SysBase, 122, Exec)
18     FUNCTION
19         This function switches to the new stack given by the parameters in the
20         stackswapstruct structure. The old stack parameters are returned in
21         the same structure so that the stack can be restored later
23     INPUTS
24         newStack - parameters for the new stack
26     RESULT
28     NOTES
30     EXAMPLE
32     BUGS
34     SEE ALSO
36     INTERNALS
38     HISTORY
40 ******************************************************************************/
42         #include "aros/m68k/asm.h"
44         .text
45         .balign 4
46         .globl  AROS_SLIB_ENTRY(StackSwap,Exec,122)
48 AROS_SLIB_ENTRY(StackSwap,Exec,122):
50         // Here's how the stack looks right now
51         // 0(%sp) : Return Address
52 #ifndef DoRegisterCalls
53         // 4(%sp) : pointer to StackSwap structure
54 #endif
56         /* Preserve returnaddress and fix sp */
57         move.l  (%sp)+,%d1       // d1 contains return address
58 #ifndef DoRegisterCalls
59         move.l  (%sp)+,%a0       // a0 holds param to this function
60 #endif
61                                  // now the stack is 'clean'
63         move.l  %a6,-(%sp)       // save contents of %a6
65         /* Get pointer to tc_SPLower in a1 (tc_SPUpper is next) */
66         move.l  0x4,%a6          // execbase to a6
67         bsr     get_offsetof_ThisTask
68         move.l  (%a6,%d0),%a1
69         bsr     get_offsetof_tc_SPLower
70         lea.l   (%a1,%d0),%a1
72         move.l  %d1,%d0          // d0 contains return address now
75         movem.l %d0/%a0/%a1,-(%sp) // d0: save return address on stack
76                                    // a0: param to this function onto stack
77                                    // a1: address of tc_SPLower to stack
78         move.l  %a6,-(%sp)         // a6: Execbase onto stack
79         
80         /* Just to be sure interrupts always find a good stackframe */
81         jsr     Disable(%a6)     // disable interrupts
83         move.l  (%sp)+,%a6       // a6: Execbase from stack
84         movem.l (%sp)+,%d0/%a0/%a1  // a1 holds address of tc_SPlower
85                                     // a0 holds param to this function
86                                     // d0 holds return address
87         
88         move.l  (%sp)+,%a6       // original a6 from stack
90         /* Swap Lower boundaries */
91         move.l  (%a1),%d1        // d1 holds content of tc_SPLower
92         move.l  (%a0),(%a1)+     // write the content of the first param in
93                                  // the structure to this function to tc_SPlower
94         move.l  %d1,(%a0)+       // write d1 back to structure
96         /* Swap higher boundaries */
97         move.l  (%a1),%d1        // d1 holds content of tc_SPHigher (???? check)
98         move.l  (%a0),(%a1)      // write the content of the 2nd param in
99                                  // the structure to this function to tc_SPHigher (??? check)
100         move.l  %d1,(%a0)+       // write d1 back to structure
102         /* Swap stackpointers */
103         move.l  %sp,%d1          // current stack pointer to d1
104         move.l  (%a0),%sp        // desired stack pointer to sp
105         move.l  %d1,(%a0)        // old stack pointer back into the structure
107         movem.l %d0/%a6,-(%sp)   // save %d0 onto stack
108                                  // save %a6 onto stack
109         
110         /* Reenable interrupts. */
111         move.l  0x4,%a6          // get ExecBase
112         move.l  %a6,-(%sp)       // ExecBase onto stack
113         jsr     Enable(%a6)      // Enable interrupts
114         move.l  (%sp)+,%a6       // dummy
116         movem.l (%sp)+,%d0/%a6       // restore orig. content of %a6 register
117                                      // restore return address to d0
119 #ifndef DoRegisterCalls
120         move.l  #0,-(%sp)        // write fake parameter to this function
121                                  // onto stack
122 #endif
123         /* Restore returnaddress and return */
124         move.l  %d0,-(%sp)       // return address onto stack 
126         // Here's how the stack looks right now
127         // 0(%sp) : Return Address
128         // 4(%sp) : fake pointer to StackSwap structure
129         rts