diff --git a/sysdeps/mach/hurd/mips/sigreturn.c b/sysdeps/mach/hurd/mips/sigreturn.c index 4df311253e..147243f5b9 100644 --- a/sysdeps/mach/hurd/mips/sigreturn.c +++ b/sysdeps/mach/hurd/mips/sigreturn.c @@ -16,6 +16,8 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +register int sp asm ("$29"), fp asm ("$30"); + #include #include #include @@ -49,42 +51,53 @@ __sigreturn (const struct sigcontext *scp) /* Restore registers. */ #define restore_gpr(n) \ - asm volatile ("lw $" #n ",%0" : : "m"(at->sc_gpr[(n)])) + asm volatile ("lw $" #n ",%0" : : "m" (scpreg->sc_gpr[n])) asm volatile (".set noreorder; .set noat;"); { - register const struct sigcontext *at asm ("$1") = scp; + register const struct sigcontext *const scpreg asm ("$1") = scp; - restore_gpr(2); - restore_gpr(3); - restore_gpr(4); - restore_gpr(5); - restore_gpr(6); - restore_gpr(7); - restore_gpr(8); - restore_gpr(9); - restore_gpr(10); - restore_gpr(11); - restore_gpr(12); - restore_gpr(13); - restore_gpr(14); - restore_gpr(15); - restore_gpr(16); - restore_gpr(17); - restore_gpr(18); - restore_gpr(19); - restore_gpr(20); - restore_gpr(21); - restore_gpr(22); - restore_gpr(23); - restore_gpr(24); - restore_gpr(25); - restore_gpr(28); - asm volatile ("lw $29,%0" : : "m"(scp->sc_sp)); - asm volatile ("lw $30,%0" : : "m"(scp->sc_fp)); - asm volatile ("lw $31,%0" : : "m"(scp->sc_pc)); - asm volatile ("j $31"); - restore_gpr(1); + /* Load the general-purpose registers from the sigcontext. */ + restore_gpr (2); + restore_gpr (3); + restore_gpr (4); + restore_gpr (5); + restore_gpr (6); + restore_gpr (7); + restore_gpr (8); + restore_gpr (9); + restore_gpr (10); + restore_gpr (11); + restore_gpr (12); + restore_gpr (13); + restore_gpr (14); + restore_gpr (15); + restore_gpr (16); + restore_gpr (17); + restore_gpr (18); + restore_gpr (19); + restore_gpr (20); + restore_gpr (21); + restore_gpr (22); + restore_gpr (23); + restore_gpr (24); + restore_gpr (25); + /* Registers 26-27 are kernel-only. */ + restore_gpr (28); + + /* Now the special-purpose registers. */ + sp = scpreg->sc_sp; /* Stack pointer. */ + fp = scpreg->sc_fp; /* Frame pointer. */ + restore_gpr (31); /* Return address. */ + + /* Now jump to the saved PC. */ + asm volatile ("lw $24, %0\n" /* Load saved PC into temporary $t8. */ + "j $24\n" /* Jump to the saved PC value. */ + "lw $1, %1\n" /* Restore $at in delay slot. */ + : : + "m" (scpreg->sc_pc), + "m" (scpreg->sc_r1) /* $at */ + : "$24"); /* XXX clobbers $24 (aka $t8)!! */ asm volatile (".set reorder; .set at;"); }