summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-07-23 17:52:06 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-07-23 17:52:06 -0600
commit0d5c6f5ba0e21048316e15c63ae4c7eeca269ba0 (patch)
treed58f3643565c971c233e6e9d12718570b18a8500 /nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S
parent01282438eedb355172c734726723549d6f767bc1 (diff)
downloadpx4-nuttx-0d5c6f5ba0e21048316e15c63ae4c7eeca269ba0.tar.gz
px4-nuttx-0d5c6f5ba0e21048316e15c63ae4c7eeca269ba0.tar.bz2
px4-nuttx-0d5c6f5ba0e21048316e15c63ae4c7eeca269ba0.zip
Improve some ARMv7-A/M floating point register save time; Add floating point register save logic for ARMv7-A
Diffstat (limited to 'nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S')
-rw-r--r--nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S49
1 files changed, 36 insertions, 13 deletions
diff --git a/nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S b/nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S
index 427a08765..bdf16a7a9 100644
--- a/nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S
+++ b/nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S
@@ -68,24 +68,23 @@
* Public Functions
****************************************************************************/
+ .text
+
/****************************************************************************
* Name: up_saveusercontext
****************************************************************************/
- .text
.globl up_saveusercontext
.type up_saveusercontext, function
+
up_saveusercontext:
- /* On entry, a1 (r0) holds address of struct xcptcontext.
- * Offset to the user region.
- */
- /* Make sure that the return value will be non-zero (the
- * value of the other volatile registers don't matter --
- * r1-r3, ip). This function is called throught the
- * normal C calling conventions and the values of these
- * registers cannot be assumed at the point of setjmp
- * return.
+ /* On entry, a1 (r0) holds address of struct xcptcontext */
+
+ /* Make sure that the return value will be non-zero (the value of the
+ * other volatile registers don't matter -- r1-r3, ip). This function
+ * is called through the normal C calling conventions and the values of
+ * these registers cannot be assumed at the point of setjmp return.
*/
mov ip, #1
@@ -104,14 +103,38 @@ up_saveusercontext:
add r1, r0, #(4*REG_CPSR)
str r2, [r1]
- /* Finally save the return address as the PC so that we
- * return to the exit from this function.
+ /* Save the return address as the PC so that we return to the exit from
+ * this function.
*/
add r1, r0, #(4*REG_PC)
str lr, [r1]
- /* Return 0 */
+ /* Save the floating point registers.
+ * REVISIT: Not all of the floating point registers need to be saved.
+ * Some are volatile and need not be preserved across functions calls.
+ * But right now, I can't find the definitive list of the volatile
+ * floating point registers.
+ */
+
+#ifdef CONFIG_ARCH_FPU
+ add r1, r0, #(4*REG_S0) /* R1=Address of FP register storage */
+
+ /* Store all floating point registers. Registers are stored in numeric order,
+ * s0, s1, ... in increasing address order.
+ */
+
+ vstmia r1!, {s0-s31} /* Save the full FP context */
+
+ /* Store the floating point control and status register. At the end of the
+ * vstmia, r1 will point to the FPCSR storage location.
+ */
+
+ vmrs r2, fpscr /* Fetch the FPCSR */
+ str r2, [r1], #4 /* Save the floating point control and status register */
+#endif
+
+ /* Return 0 now indicating that this return is not a context switch */
mov r0, #0 /* Return value == 0 */
mov pc, lr /* Return */