فهرست منبع

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 23 سال پیش
والد
کامیت
bb9393fa99
3فایلهای تغییر یافته به همراه78 افزوده شده و 11 حذف شده
  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;