diff options
-rw-r--r-- | libc/sysdeps/linux/sh/Makefile | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/sh/__longjmp.S | 16 | ||||
-rw-r--r-- | libc/sysdeps/linux/sh/setjmp.S | 71 |
3 files changed, 78 insertions, 11 deletions
diff --git a/libc/sysdeps/linux/sh/Makefile b/libc/sysdeps/linux/sh/Makefile index c9cec02c1..e17838db9 100644 --- a/libc/sysdeps/linux/sh/Makefile +++ b/libc/sysdeps/linux/sh/Makefile @@ -32,7 +32,7 @@ TARGET_MACHINE_TYPE=$(shell $(CC) -dumpmachine) CRT0=crt0.S CRT0_OBJ=$(patsubst %.S,%.o, $(CRT0)) -SSRC=setjmp.S bsd-setjmp.S bsd-_setjmp.S __longjmp.S vfork.S clone.S +SSRC=setjmp.S __longjmp.S vfork.S clone.S SOBJS=$(patsubst %.S,%.o, $(SSRC)) CSRC=_mmap.c longjmp.c pipe.c __init_brk.c brk.c sbrk.c diff --git a/libc/sysdeps/linux/sh/__longjmp.S b/libc/sysdeps/linux/sh/__longjmp.S index 163801969..7e2b0b16d 100644 --- a/libc/sysdeps/linux/sh/__longjmp.S +++ b/libc/sysdeps/linux/sh/__longjmp.S @@ -36,6 +36,21 @@ __longjmp: mov.l @r4+, r13 mov.l @r4+, r14 mov.l @r4+, r15 +#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__ + lds.l @r4+, pr + ldc.l @r4+, gbr + lds.l @r4+, fpscr + fmov.s @r4+, fr12 + fmov.s @r4+, fr13 + mov r5, r0 /* get the return value in place */ + tst r0, r0 + bf.s 1f + fmov.s @r4+, fr14 + mov #1,r0 /* can't let setjmp() return zero! */ +1: + rts + fmov.s @r4+, fr15 +#else mov r5, r0 /* get the return value in place */ tst r0, r0 bf.s 1f @@ -44,5 +59,6 @@ __longjmp: 1: rts ldc.l @r4+, gbr +#endif .size __longjmp,.-__longjmp; 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; |