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