aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/arm/gen/setjmp.S
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/arm/gen/setjmp.S')
-rw-r--r--lib/libc/arm/gen/setjmp.S111
1 files changed, 67 insertions, 44 deletions
diff --git a/lib/libc/arm/gen/setjmp.S b/lib/libc/arm/gen/setjmp.S
index e5f581f0e3f2..b7af33b8856a 100644
--- a/lib/libc/arm/gen/setjmp.S
+++ b/lib/libc/arm/gen/setjmp.S
@@ -1,4 +1,4 @@
-/* $NetBSD: setjmp.S,v 1.5 2003/04/05 23:08:51 bjh21 Exp $ */
+/* $NetBSD: setjmp.S,v 1.14 2013/04/19 13:45:45 matt Exp $ */
/*
* Copyright (c) 1997 Mark Brinicombe
@@ -32,8 +32,19 @@
* SUCH DAMAGE.
*/
+#if !defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__ARM_PCS)
+#error FPA is not supported anymore
+#endif
+
+#ifdef __ARM_EABI__
+ .fpu vfp
+#endif
+
#include <machine/asm.h>
+#include <machine/setjmp.h>
+
__FBSDID("$FreeBSD$");
+
/*
* C library -- setjmp, longjmp
*
@@ -47,83 +58,95 @@ __FBSDID("$FreeBSD$");
ENTRY(setjmp)
/* Block all signals and retrieve the old signal mask */
stmfd sp!, {r0, r14}
- add r2, r0, #(25 * 4) /* oset */
- mov r0, #0x00000001 /* SIG_BLOCK */
- mov r1, #0 /* set */
-
+ add r2, r0, #(_JB_SIGMASK * 4) /* oset */
+ mov r1, #0x00000000 /* set */
+ mov r0, #0x00000001 /* SIG_BLOCK */
bl PIC_SYM(_C_LABEL(sigprocmask), PLT)
-
ldmfd sp!, {r0, r14}
ldr r1, .Lsetjmp_magic
- str r1, [r0], #4
-#ifdef __SOFTFP__
- add r0, r0, #52
+#ifdef __ARM_EABI__
+ ldr r2, .Lfpu_present
+#ifdef PIC
+ GOT_INIT(r3, .Lsetjmp_got, .Lsetjmp_gotinit)
+ ldr r2, [r2, r3]
#else
- /* Store fp registers */
- sfm f4, 4, [r0], #48
- /* Store fpsr */
- rfs r1
- str r1, [r0], #0x0004
-#endif /* __SOFTFP__ */
+ 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)
stmia r0, {r4-r14}
mov r0, #0x00000000
RET
.Lsetjmp_magic:
.word _JB_MAGIC_SETJMP
+#ifdef __ARM_EABI__
+ GOT_INITSYM(.Lsetjmp_got, .Lsetjmp_gotinit)
+.Lfpu_present:
+ .word PIC_SYM(_libc_arm_fpu_present, GOTOFF)
+#endif /* __ARM_EABI__ */
.weak _C_LABEL(longjmp)
.set _C_LABEL(longjmp), _C_LABEL(__longjmp)
ENTRY(__longjmp)
- ldr r2, .Lsetjmp_magic
- ldr r3, [r0]
- teq r2, r3
- bne botch
-
+ ldr r2, [r0]
+ ldr ip, .Lsetjmp_magic
+ bic r3, r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
+ teq r3, ip
+ bne .Lbotch
- /* Set signal mask */
- stmfd sp!, {r0, r1, r14}
- sub sp, sp, #4 /* align the stack */
-
- add r1, r0, #(25 * 4) /* Signal mask */
- mov r0, #3 /* SIG_SETMASK */
- mov r2, #0
+ /* Restore the signal mask. */
+ stmfd sp!, {r0-r2, r14}
+ mov r2, #0x00000000
+ add r1, r0, #(_JB_SIGMASK * 4) /* Signal mask */
+ mov r0, #3 /* SIG_SETMASK */
bl PIC_SYM(_C_LABEL(sigprocmask), PLT)
+ ldmfd sp!, {r0-r2, r14}
- add sp, sp, #4 /* unalign the stack */
- ldmfd sp!, {r0, r1, r14}
+#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 ip, r0, #(_JB_REG_D8 * 4)
+ vldmia ip, {d8-d15}
+ ldr ip, [r0, #(_JB_REG_FPSCR * 4)]
+ vmsr fpscr, ip
+1:
+#endif /* __ARM_EABI__ */
- add r0, r0, #4
-#ifdef __SOFTFP__
- add r0, r0, #52
-#else
- /* Restore fp registers */
- lfm f4, 4, [r0], #48
- /* Restore FPSR */
- ldr r4, [r0], #0x0004
- wfs r4
-#endif /* __SOFTFP__ */
+ add r0, r0, #(_JB_REG_R4 * 4)
/* Restore integer registers */
ldmia r0, {r4-r14}
/* Validate sp and r14 */
teq sp, #0
teqne r14, #0
- beq botch
+ beq .Lbotch
/* Set return value */
-
- mov r0, r1
- teq r0, #0x00000000
+ movs r0, r1
moveq r0, #0x00000001
RET
/* validation failed, die die die. */
-botch:
+.Lbotch:
bl PIC_SYM(_C_LABEL(longjmperror), PLT)
bl PIC_SYM(_C_LABEL(abort), PLT)
b . - 8 /* Cannot get here */