Fix setjmp()/longjmp() to save FP registers on ARMv7.
Change-Id: I8ec684c8f8ca1ae58c8feb330b97d1e2b81caeef
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index a9f6ea4..59aff66 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -3,6 +3,7 @@
/*
* Copyright (c) 1997 Mark Brinicombe
+ * Copyright (c) 2010 Android Open Source Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -35,6 +36,7 @@
#include <machine/asm.h>
#include <machine/setjmp.h>
+#include <machine/cpu-features.h>
/*
* C library -- setjmp, longjmp
@@ -57,24 +59,26 @@
ldmfd sp!, {r0, r14}
/* Store signal mask */
- str r1, [r0, #(25 * 4)]
+ str r1, [r0, #(_JB_SIGMASK * 4)]
ldr r1, .Lsetjmp_magic
- str r1, [r0], #4
+ str r1, [r0, #(_JB_MAGIC * 4)]
-#ifdef SOFTFLOAT
- add r0, r0, #52
-#else
- /* Store fp registers */
- sfm f4, 4, [r0], #48
- /* Store fpsr */
- rfs r1
- str r1, [r0], #0x0004
-#endif /*SOFTFLOAT*/
- /* Store integer registers */
- stmia r0, {r4-r14}
- mov r0, #0x00000000
- bx lr
+ /* Store core registers */
+ add r1, r0, #(_JB_CORE_BASE * 4)
+ stmia r1, {r4-r14}
+
+#ifdef __ARM_HAVE_VFP
+ /* Store floating-point registers */
+ add r1, r0, #(_JB_FLOAT_BASE * 4)
+ vstmia r1, {d8-d15}
+ /* Store floating-point state */
+ fmrx r1, fpscr
+ str r1, [r0, #(_JB_FLOAT_STATE * 4)]
+#endif /* __ARM_HAVE_VFP */
+
+ mov r0, #0x00000000
+ bx lr
.Lsetjmp_magic:
.word _JB_MAGIC_SETJMP
@@ -82,12 +86,12 @@
ENTRY(longjmp)
ldr r2, .Lsetjmp_magic
- ldr r3, [r0]
+ ldr r3, [r0, #(_JB_MAGIC * 4)]
teq r2, r3
bne botch
/* Fetch signal mask */
- ldr r2, [r0, #(25 * 4)]
+ ldr r2, [r0, #(_JB_SIGMASK * 4)]
/* Set signal mask */
stmfd sp!, {r0, r1, r14}
@@ -99,18 +103,18 @@
add sp, sp, #4 /* unalign the stack */
ldmfd sp!, {r0, r1, r14}
- add r0, r0, #4
-#ifdef SOFTFLOAT
- add r0, r0, #52
-#else
- /* Restore fp registers */
- lfm f4, 4, [r0], #48
- /* Restore FPSR */
- ldr r4, [r0], #0x0004
- wfs r4
-#endif /* SOFTFLOAT */
- /* Restore integer registers */
- ldmia r0, {r4-r14}
+#ifdef __ARM_HAVE_VFP
+ /* Restore floating-point registers */
+ add r2, r0, #(_JB_FLOAT_BASE * 4)
+ vldmia r2, {d8-d15}
+ /* Restore floating-point state */
+ ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
+ fmxr fpscr, r2
+#endif /* __ARM_HAVE_VFP */
+
+ /* Restore core registers */
+ add r2, r0, #(_JB_CORE_BASE * 4)
+ ldmia r2, {r4-r14}
/* Validate sp and r14 */
teq sp, #0