Browse Source

Stefan Allius writes:

    Hi Erik,

    I added the FPU support for the setjmp/longjmp stuff.

    This patch also moves the code from the bsd*.S files to the setjmp.S file, so
    we can use simple branch instructions instead of referencing over the
    .GOT/.PLT section. This makes the PIC code much easier, smaller and faster.
    (The idea comes from the SPARC target)

    Bye Stefan
Eric Andersen 22 years ago
parent
commit
bb9393fa99
3 changed files with 78 additions and 11 deletions
  1. 1 1
      libc/sysdeps/linux/sh/Makefile
  2. 16 0
      libc/sysdeps/linux/sh/__longjmp.S
  3. 61 10
      libc/sysdeps/linux/sh/setjmp.S

+ 1 - 1
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

+ 16 - 0
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;
 

+ 61 - 10
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;