added concrete implementations of putc(), getc(), getchar() and gets()
[tangerine.git] / arch / ppc-sam440 / exec / stackswap.c
blobb818d1f039c706c26ea45f78265c5a7aa12b9502
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: StackSwap() - Swap the stack of a task.
6 Lang: english
7 */
9 /*****************************************************************************
11 NAME */
12 #include <exec/tasks.h>
13 #include <proto/exec.h>
15 AROS_LH1(void, StackSwap,
17 /* SYNOPSIS */
18 AROS_LHA(struct StackSwapStruct *, sss, A0),
20 /* LOCATION */
21 struct ExecBase *, SysBase, 122, Exec)
23 /* FUNCTION
24 Changes the stack used by a task. The StackSwapStruct will contain
25 the value of the old stack such that the stack can be reset to the
26 previous version by another call to StackSwap().
28 When the stack is swapped, the data on the stack(s) will not be
29 altered, so the stack may not be set up for you. It is generally
30 required that you replace your stack before exiting from the
31 current stack frame (procedure, function call etc.).
33 INPUTS
34 sss - A structure containing the values for the upper, lower
35 and current bounds of the stack you wish to use. The
36 values will be replaced by the current values and you
37 can restore the values later.
39 RESULT
40 The program will be running on a new stack and sss will contain
41 the old stack.
43 Calling StackSwap() twice consequtively will effectively do
44 nothing.
46 NOTES
47 Returning from the function that you call StackSwap() in can have
48 unexpected results.
50 EXAMPLE
52 BUGS
54 SEE ALSO
55 AddTask(), RemTask()
57 INTERNALS
58 This function MUST be replaced in $(KERNEL) or $(ARCH).
60 ******************************************************************************/
62 AROS_LIBFUNC_INIT
63 register IPTR real_sp asm("r1");
64 IPTR *sp;
65 IPTR *src;
66 IPTR *dst;
67 struct Task *thisTask = FindTask(NULL);
68 APTR tmp;
70 dst = sss->stk_Pointer;
72 Disable();
74 /* Get the real stack pointer */
75 asm volatile ("mr %0,%1":"=r"(sp):"r"(real_sp));
77 /* Go one stack frame upper - now src points to the stackframe of caller */
78 src = (IPTR*)*sp;
80 /* Go one more stack frame up. Now you may copy from src to dst (src - sp) IPTR's */
81 src = (IPTR*)*src;
83 /* Copy the two stack frames */
84 while (src != sp)
86 *--dst = *--src;
89 sss->stk_Pointer = dst;
91 tmp = thisTask->tc_SPLower;
92 thisTask->tc_SPLower = sss->stk_Lower;
93 sss->stk_Lower = tmp;
95 tmp = thisTask->tc_SPUpper;
96 thisTask->tc_SPUpper = sss->stk_Upper;
97 sss->stk_Upper = tmp;
99 tmp = thisTask->tc_SPReg;
100 thisTask->tc_SPReg = sss->stk_Pointer;
101 sss->stk_Pointer = tmp;
103 asm volatile("mr %0,%1"::"r"(real_sp),"r"(dst));
105 Enable();
107 AROS_LIBFUNC_EXIT
108 } /* StackSwap() */