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 */