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