From 0d5c6f5ba0e21048316e15c63ae4c7eeca269ba0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 23 Jul 2013 17:52:06 -0600 Subject: Improve some ARMv7-A/M floating point register save time; Add floating point register save logic for ARMv7-A --- nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S | 49 +++++++++++++++++------- 1 file changed, 36 insertions(+), 13 deletions(-) (limited to 'nuttx/arch/arm/src/armv7-a/arm_saveusercontext.S') 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 */ -- cgit v1.2.3