diff options
author | Eric Andersen <andersen@codepoet.org> | 2006-11-04 19:50:20 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2006-11-04 19:50:20 +0000 |
commit | cb12600bc59ec9211ecb5be3083e66f7c6c6d9ef (patch) | |
tree | ad8ca820494baaeaada85b9d30a702d68b461936 /libc/sysdeps/linux/mips/__longjmp.c | |
parent | 141da0f0b098b17499c6c6e02a7d2cacc1d6d3ba (diff) |
mips64 patch from Atsushi Nemoto:
The mips64 N32/N64 ABI have a bit different register usage convention.
Also the register size for these ABI is 8 byte. Use ld/sd for them.
Diffstat (limited to 'libc/sysdeps/linux/mips/__longjmp.c')
-rw-r--r-- | libc/sysdeps/linux/mips/__longjmp.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/mips/__longjmp.c b/libc/sysdeps/linux/mips/__longjmp.c index ee9c455cc..9dc09f27a 100644 --- a/libc/sysdeps/linux/mips/__longjmp.c +++ b/libc/sysdeps/linux/mips/__longjmp.c @@ -20,6 +20,7 @@ #include <features.h> #include <setjmp.h> #include <stdlib.h> +#include <sgidefs.h> #ifndef __GNUC__ #error This file uses GNU C extensions; you must compile with GCC. @@ -38,12 +39,23 @@ void __longjmp (__jmp_buf env, int val_arg) /* Pull back the floating point callee-saved registers. */ #if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__ +#if _MIPS_SIM == _MIPS_SIM_ABI64 + __asm__ __volatile__ ("l.d $f24, %0" : : "m" (env[0].__fpregs[0])); + __asm__ __volatile__ ("l.d $f25, %0" : : "m" (env[0].__fpregs[1])); + __asm__ __volatile__ ("l.d $f26, %0" : : "m" (env[0].__fpregs[2])); + __asm__ __volatile__ ("l.d $f27, %0" : : "m" (env[0].__fpregs[3])); + __asm__ __volatile__ ("l.d $f28, %0" : : "m" (env[0].__fpregs[4])); + __asm__ __volatile__ ("l.d $f29, %0" : : "m" (env[0].__fpregs[5])); + __asm__ __volatile__ ("l.d $f30, %0" : : "m" (env[0].__fpregs[6])); + __asm__ __volatile__ ("l.d $f31, %0" : : "m" (env[0].__fpregs[7])); +#else /* O32 || N32 */ __asm__ __volatile__ ("l.d $f20, %0" : : "m" (env[0].__fpregs[0])); __asm__ __volatile__ ("l.d $f22, %0" : : "m" (env[0].__fpregs[1])); __asm__ __volatile__ ("l.d $f24, %0" : : "m" (env[0].__fpregs[2])); __asm__ __volatile__ ("l.d $f26, %0" : : "m" (env[0].__fpregs[3])); __asm__ __volatile__ ("l.d $f28, %0" : : "m" (env[0].__fpregs[4])); __asm__ __volatile__ ("l.d $f30, %0" : : "m" (env[0].__fpregs[5])); +#endif /* O32 || N32 */ /* Get and reconstruct the floating point csr. */ __asm__ __volatile__ ("lw $2, %0" : : "m" (env[0].__fpc_csr)); @@ -51,9 +63,14 @@ void __longjmp (__jmp_buf env, int val_arg) #endif /* Get the GP. */ +#if _MIPS_SIM == _MIPS_SIM_ABI64 + __asm__ __volatile__ ("ld $gp, %0" : : "m" (env[0].__gp)); +#else /* O32 || N32 */ __asm__ __volatile__ ("lw $gp, %0" : : "m" (env[0].__gp)); +#endif /* O32 || N32 */ /* Get the callee-saved registers. */ +#if _MIPS_SIM == _MIPS_SIM_ABI32 __asm__ __volatile__ ("lw $16, %0" : : "m" (env[0].__regs[0])); __asm__ __volatile__ ("lw $17, %0" : : "m" (env[0].__regs[1])); __asm__ __volatile__ ("lw $18, %0" : : "m" (env[0].__regs[2])); @@ -62,15 +79,36 @@ void __longjmp (__jmp_buf env, int val_arg) __asm__ __volatile__ ("lw $21, %0" : : "m" (env[0].__regs[5])); __asm__ __volatile__ ("lw $22, %0" : : "m" (env[0].__regs[6])); __asm__ __volatile__ ("lw $23, %0" : : "m" (env[0].__regs[7])); +#else /* N32 || N64 */ + __asm__ __volatile__ ("ld $16, %0" : : "m" (env[0].__regs[0])); + __asm__ __volatile__ ("ld $17, %0" : : "m" (env[0].__regs[1])); + __asm__ __volatile__ ("ld $18, %0" : : "m" (env[0].__regs[2])); + __asm__ __volatile__ ("ld $19, %0" : : "m" (env[0].__regs[3])); + __asm__ __volatile__ ("ld $20, %0" : : "m" (env[0].__regs[4])); + __asm__ __volatile__ ("ld $21, %0" : : "m" (env[0].__regs[5])); + __asm__ __volatile__ ("ld $22, %0" : : "m" (env[0].__regs[6])); + __asm__ __volatile__ ("ld $23, %0" : : "m" (env[0].__regs[7])); +#endif /* N32 || N64 */ /* Get the PC. */ +#if _MIPS_SIM == _MIPS_SIM_ABI32 __asm__ __volatile__ ("lw $25, %0" : : "m" (env[0].__pc)); +#elif _MIPS_SIM == _MIPS_SIM_NABI32 + __asm__ __volatile__ ("lw $31, %0" : : "m" (env[0].__pc)); +#else /* N64 */ + __asm__ __volatile__ ("ld $31, %0" : : "m" (env[0].__pc)); +#endif /* N64 */ /* Restore the stack pointer and the FP. They have to be restored last and in a single asm as gcc, depending on options used, may use either of them to access env. */ +#if _MIPS_SIM == _MIPS_SIM_ABI64 + __asm__ __volatile__ ("ld $29, %0\n\t" + "ld $30, %1\n\t" : : "m" (env[0].__sp), "m" (env[0].__fp)); +#else /* O32 || N32 */ __asm__ __volatile__ ("lw $29, %0\n\t" "lw $30, %1\n\t" : : "m" (env[0].__sp), "m" (env[0].__fp)); +#endif /* O32 || N32 */ /* Give setjmp 1 if given a 0, or what they gave us if non-zero. */ if (val == 0) @@ -78,7 +116,11 @@ void __longjmp (__jmp_buf env, int val_arg) else __asm__ __volatile__ ("move $2, %0" : : "r" (val)); +#if _MIPS_SIM == _MIPS_SIM_ABI32 __asm__ __volatile__ ("jr $25"); +#else /* N32 || N64 */ + __asm__ __volatile__ ("jr $31"); +#endif /* N32 || N64 */ /* Avoid `volatile function does return' warnings. */ for (;;); |