switch_dsp56k.c

Go to the documentation of this file.
00001 
00038 void asm_switch_context(void ** new_sp /* R2 */, void ** save_sp /* R3 */);
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 }