diff options
Diffstat (limited to 'libc/sysdeps/linux/sh')
| -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; | 
