switch_dsp56k.c
Go to the documentation of this file.00001
00037 void asm_switch_context(void ** new_sp , void ** save_sp );
00038 asm void asm_switch_context(void ** new_sp, void ** save_sp)
00039 {
00040 lea (SP)+
00041
00042 ; From the manual:
00043 ; The compiler uses page 0 address locations X: 0x0030 - 0x003F as register
00044 ; variables. Frequently accessed local variables are assigned to the page 0
00045 ; registers instead of to stack locations so that load and store instructions
00046 ; are shortened. Addresses X: 0x0030 - 0x0037 (page 0 registers MR0-MR7) are
00047 ; volatile registers and can be overwritten. The remaining registers (page 0
00048 ; registers MR8-MR15) are treated as non-volatile and, if used by a routine,
00049 ; must be saved on entry and restored on exit.
00050 ;
00051 ; So, register 0x30-0x37 are caller-save, while 0x38-0x3F are callee-save.
00052 move x:<$38,y1
00053 move y1,x:(SP)+
00054 move x:<$39,y1
00055 move y1,x:(SP)+
00056 move x:<$3A,y1
00057 move y1,x:(SP)+
00058 move x:<$3B,y1
00059 move y1,x:(SP)+
00060 move x:<$3C,y1
00061 move y1,x:(SP)+
00062 move x:<$3D,y1
00063 move y1,x:(SP)+
00064 move x:<$3E,y1
00065 move y1,x:(SP)+
00066 move x:<$3F,y1
00067 move y1,x:(SP)
00068
00069 ;
00070 ; Switch stacks
00071 nop
00072 move SP, x:(R3)
00073 nop
00074 move x:(R2), SP
00075 nop
00076
00077 ;
00078 ; restore all saved registers
00079 ;
00080 pop y1
00081 move y1,x:<$3F
00082 pop y1
00083 move y1,x:<$3E
00084 pop y1
00085 move y1,x:<$3D
00086 pop y1
00087 move y1,x:<$3C
00088 pop y1
00089 move y1,x:<$3B
00090 pop y1
00091 move y1,x:<$3A
00092 pop y1
00093 move y1,x:<$39
00094 pop y1
00095 move y1,x:<$38
00096
00097 ; SR is already pushed on the stack (normal call context). Use RTI to restore
00098 ; it, so that interrupt status is preserved across the tasks.
00099 rti
00100 }