Module Name:    src
Committed By:   matt
Date:           Tue Jan 29 19:23:09 UTC 2013

Modified Files:
        src/lib/libc/arch/arm/gen: _setjmp.S setjmp.S

Log Message:
AAPCS (EABI) requires that VFP D8-D15 are always saved, regardless whether
the soft float or hard float ABI is being used.  However, if there isn't a
FPU that can't be done.  So only save/restore them if a FPU is present. When
libc initializes, it does a sysctl to determine if there is a FPU and stores
the result which _setjmp/setjmp uses.  If there was a FPU, the magic in the
jmp_buf is changed to reflect that the VFP registers were saved.  longjmp uses
the magic to determine if it needs to restore the VFP registers.


To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 src/lib/libc/arch/arm/gen/_setjmp.S
cvs rdiff -u -r1.11 -r1.12 src/lib/libc/arch/arm/gen/setjmp.S

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/arch/arm/gen/_setjmp.S
diff -u src/lib/libc/arch/arm/gen/_setjmp.S:1.9 src/lib/libc/arch/arm/gen/_setjmp.S:1.10
--- src/lib/libc/arch/arm/gen/_setjmp.S:1.9	Fri Jan 25 08:52:16 2013
+++ src/lib/libc/arch/arm/gen/_setjmp.S	Tue Jan 29 19:23:09 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: _setjmp.S,v 1.9 2013/01/25 08:52:16 matt Exp $	*/
+/*	$NetBSD: _setjmp.S,v 1.10 2013/01/29 19:23:09 matt Exp $	*/
 
 /*
  * Copyright (c) 1997 Mark Brinicombe
@@ -36,6 +36,10 @@
 #error FPA is not supported anymore
 #endif
 
+#ifdef __ARM_EABI__
+	.fpu	vfp
+#endif
+
 #include <machine/asm.h>
 #include <machine/setjmp.h>
 
@@ -49,19 +53,33 @@
  * The previous signal state is NOT restored.
  *
  * Note: r0 is the return value
- *       r1-r3 are scratch registers in functions
+ *       r1-r3,ip are scratch registers in functions
  */
 
 ENTRY(_setjmp)
 	ldr	r1, .L_setjmp_magic
-	str	r1, [r0]
 
-#ifdef __ARM_PCS_VFP
-	add	r1, r0, #(_JB_REG_D8 * 4)
-	vstmia	r1, {d8-d15}
-	vmrs	r1, fpscr
-	str	r1, [r0, #(_JB_REG_FPSCR * 4)]
-#endif /* __ARM_PCS_VFP */
+#ifdef __ARM_EABI__
+	ldr	r2, .Lfpu_present
+#ifdef PIC
+	GOT_INIT(r3, .L_setjmp_got, .L_setjmp_gotinit)
+	ldr	r2, [r2, r3]
+#else
+	ldr	r2, [r2]
+#endif
+	teq	r2, #0		/* do we have a FPU? */
+	beq	1f		/*   no, don't save VFP registers */
+
+	orr	r1, r1, #(_JB_MAGIC__SETJMP ^ _JB_MAGIC__SETJMP_VFP)
+				/* change magic to VFP magic */
+	add	r2, r0, #(_JB_REG_D8 * 4)
+	vstmia	r2, {d8-d15}
+	vmrs	r2, fpscr
+	str	r2, [r0, #(_JB_REG_FPSCR * 4)]
+1:
+#endif /* __ARM_EABI__ */
+
+	str	r1, [r0]
 
 	add	r0, r0, #(_JB_REG_R4 * 4)
 	/* Store integer registers */
@@ -71,24 +89,30 @@ ENTRY(_setjmp)
         RET
 
 .L_setjmp_magic:
-#ifdef __ARM_PCS_VFP
-	.word	_JB_MAGIC__SETJMP_VFP
-#else
 	.word	_JB_MAGIC__SETJMP
-#endif
+#ifdef __ARM_EABI__
+	GOT_INITSYM(.L_setjmp_got, .L_setjmp_gotinit)
+.Lfpu_present:
+	.word	PIC_SYM(_libc_arm_fpu_present, GOTOFF)
+#endif /* __ARM_EABI__ */
 
 ENTRY(_longjmp)
-	ldr	r2, .L_setjmp_magic
-	ldr	r3, [r0]
-	teq	r2, r3
-	bne	botch
-
-#ifdef __ARM_PCS_VFP
+	ldr	r2, [r0]			/* get magic from jmp_buf */
+	bic	r3, r2, #(_JB_MAGIC__SETJMP ^ _JB_MAGIC__SETJMP_VFP)
+						/* ignore VFP-ness of magic */
+	ldr	ip, .L_setjmp_magic		/* load magic */
+	teq	ip, r3				/* magic correct? */
+	bne	botch				/*   no, botch */
+
+#ifdef __ARM_EABI__
+	teq	r3, r2				/* did magic change? */
+	beq	1f				/*   no, don't restore VFP */
 	add	r1, r0, #(_JB_REG_D8 * 4)
 	vldmia	r1, {d8-d15}
 	ldr	r1, [r0, #(_JB_REG_FPSCR * 4)]
 	vmsr	fpscr, r1
-#endif /* __ARM_PCS_VFP */
+1:
+#endif /* __ARM_EABI__ */
 
 	add	r0, r0, #(_JB_REG_R4 * 4)
        	/* Restore integer registers */

Index: src/lib/libc/arch/arm/gen/setjmp.S
diff -u src/lib/libc/arch/arm/gen/setjmp.S:1.11 src/lib/libc/arch/arm/gen/setjmp.S:1.12
--- src/lib/libc/arch/arm/gen/setjmp.S:1.11	Fri Jan 25 08:52:16 2013
+++ src/lib/libc/arch/arm/gen/setjmp.S	Tue Jan 29 19:23:09 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: setjmp.S,v 1.11 2013/01/25 08:52:16 matt Exp $	*/
+/*	$NetBSD: setjmp.S,v 1.12 2013/01/29 19:23:09 matt Exp $	*/
 
 /*
  * Copyright (c) 1997 Mark Brinicombe
@@ -36,6 +36,10 @@
 #error FPA is not supported anymore
 #endif
 
+#ifdef __ARM_EABI__
+	.fpu	vfp
+#endif
+
 #include <machine/asm.h>
 #include <machine/setjmp.h>
 
@@ -59,14 +63,28 @@ ENTRY(__setjmp14)
 	ldmfd	sp!, {r0-r2, r14}
 
 	ldr	r1, .Lsetjmp_magic
-	str	r1, [r0]
 
-#ifdef __ARM_PCS_VFP
-	add	r1, r0, #(_JB_REG_D8 * 4)
-	vstmia	r1, {d8-d15}
-	vmrs	r1, fpscr
-	str	r1, [r0, #(_JB_REG_FPSCR * 4)]
-#endif /* __ARM_PCS_VFP */
+#ifdef __ARM_EABI__
+	ldr	r2, .Lfpu_present
+#ifdef PIC
+	GOT_INIT(r3, .Lsetjmp_got, .Lsetjmp_gotinit)
+	ldr	r2, [r2, r3]
+#else
+	ldr	r2, [r2]
+#endif
+	teq	r2, #0		/* do we have a FPU? */
+	beq	1f		/*   no, don't save VFP registers */
+
+	orr	r1, r1, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
+				/* change magic to VFP magic */
+	add	r2, r0, #(_JB_REG_D8 * 4)
+	vstmia	r2, {d8-d15}
+	vmrs	r2, fpscr
+	str	r2, [r0, #(_JB_REG_FPSCR * 4)]
+1:
+#endif /* __ARM_EABI__ */
+
+	str	r1, [r0]		/* store magic */
 
 	/* Store integer registers */
 	add	r0, r0, #(_JB_REG_R4 * 4)
@@ -75,18 +93,18 @@ ENTRY(__setjmp14)
         RET
 
 .Lsetjmp_magic:
-#ifdef __ARM_PCS_VFP
-	.word	_JB_MAGIC_SETJMP_VFP
-#else
 	.word	_JB_MAGIC_SETJMP
-#endif
-
+#ifdef __ARM_EABI__
+	GOT_INITSYM(.Lsetjmp_got, .Lsetjmp_gotinit)
+.Lfpu_present:
+	.word	PIC_SYM(_libc_arm_fpu_present, GOTOFF)
+#endif /* __ARM_EABI__ */
 
 ENTRY(__longjmp14)
-	ldr	r2, .Lsetjmp_magic
-	ldr	r3, [r0]
-	teq	r2, r3
-	bne	.Lbotch
+	ldr	r2, [r0]
+	ldr	ip, .Lsetjmp_magic
+	bic	r3, r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
+	teq	r3, ip
 
 	/* Restore the signal mask. */
 	stmfd	sp!, {r0-r2, r14}
@@ -96,12 +114,16 @@ ENTRY(__longjmp14)
 	bl	PIC_SYM(_C_LABEL(__sigprocmask14), PLT)
 	ldmfd	sp!, {r0-r2, r14}
 
-#ifdef __ARM_PCS_VFP
+#ifdef __ARM_EABI__
+	tst	r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
+						/* is this a VFP magic? */
+	beq	1f				/*   no, don't restore VFP */
 	add	r1, r0, #(_JB_REG_D8 * 4)
 	vldmia	r1, {d8-d15}
 	ldr	r1, [r0, #(_JB_REG_FPSCR * 4)]
 	vmsr	fpscr, r1
-#endif /* __ARM_PCS_VFP */
+1:
+#endif /* __ARM_EABI__ */
 
 	add	r0, r0, #(_JB_REG_R4 * 4)
 	/* Restore integer registers */

Reply via email to