diff options
Diffstat (limited to 'libc/sysdeps/linux/sh/setjmp.S')
-rw-r--r-- | libc/sysdeps/linux/sh/setjmp.S | 71 |
1 files changed, 61 insertions, 10 deletions
diff --git a/libc/sysdeps/linux/sh/setjmp.S b/libc/sysdeps/linux/sh/setjmp.S index 3d41876d3..c9fa3b1fb 100644 --- a/libc/sysdeps/linux/sh/setjmp.S +++ b/libc/sysdeps/linux/sh/setjmp.S @@ -17,17 +17,54 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <features.h> #define _SETJMP_H #define _ASM #include <bits/setjmp.h> -.text -.align 4 -.type __sigsetjmp,@function -.globl __sigsetjmp; + .text + +/* This just does a tail-call to `__sigsetjmp (ARG, 0)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + + .align 4 + .type _setjmp,@function + .globl _setjmp; +_setjmp: + bra __sigsetjmp_intern + mov #0, r1 + .size _setjmp,.-_setjmp; + +/* This just does a tail-call to `__sigsetjmp (ARG, 1)'. + We cannot do it in C because it must be a tail-call, so frame-unwinding + in setjmp doesn't clobber the state restored by longjmp. */ + + .align 4 + .type setjmp,@function + .globl setjmp; +setjmp: + bra __sigsetjmp_intern + mov #1, r1 + .size setjmp,.-setjmp; + + .align 4 + .type __sigsetjmp,@function + .globl __sigsetjmp; __sigsetjmp: + mov r0, r1 +__sigsetjmp_intern: /* Save registers */ +#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__ + add #(JB_SIZE*4), r4 + fmov.s fr15, @-r4 + fmov.s fr14, @-r4 + fmov.s fr13, @-r4 + fmov.s fr12, @-r4 + sts.l fpscr, @-r4 +#else add #(JB_SIZE-5*4), r4 /* this code doesn't do FP yet */ +#endif stc.l gbr, @-r4 sts.l pr, @-r4 mov.l r15, @-r4 @@ -39,12 +76,26 @@ __sigsetjmp: mov.l r9, @-r4 mov.l r8, @-r4 +#if defined __HAVE_ELF__ && defined __HAVE_SHARED__ + mov.l .LG, r12 + mova .LG, r0 + add r0, r12 + /* Make a tail call to __sigjmp_save; it takes the same args. */ + mov.l .L1, r0 + mov.l @(r0,r12),r0 + jmp @r0 + mov r1, r0 + .align 2 +.LG: .long _GLOBAL_OFFSET_TABLE_ +.L1: .long __sigjmp_save@GOT +#else /* Make a tail call to __sigjmp_save; it takes the same args. */ - mov.l .L1, r1 - jmp @r1 - nop + mov.l .L1, r0 + braf r0 + mov r1, r0 +.jmp_loc: .align 2 -.L1: - .long __sigjmp_save -.size __sigsetjmp,.-__sigsetjmp; +.L1: .long __sigjmp_save - .jmp_loc +#endif + .size __sigsetjmp,.-__sigsetjmp; |