am b8e6c50c: Fix setjmp()/longjmp() to save FP registers on ARMv7. - DO NOT MERGE

This commit is contained in:
David 'Digit' Turner 2010-06-09 13:21:51 -07:00 committed by Android Git Automerger
commit 8946da4fe1
5 changed files with 149 additions and 130 deletions

View File

@ -3,6 +3,7 @@
/* /*
* Copyright (c) 1997 Mark Brinicombe * Copyright (c) 1997 Mark Brinicombe
* Copyright (c) 2010 Android Open Source Project.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -35,6 +36,7 @@
#include <machine/asm.h> #include <machine/asm.h>
#include <machine/setjmp.h> #include <machine/setjmp.h>
#include <machine/cpu-features.h>
/* /*
* C library -- _setjmp, _longjmp * C library -- _setjmp, _longjmp
@ -51,18 +53,20 @@
ENTRY(_setjmp) ENTRY(_setjmp)
ldr r1, .L_setjmp_magic ldr r1, .L_setjmp_magic
str r1, [r0], #4 str r1, [r0, #(_JB_MAGIC * 4)]
#ifdef SOFTFLOAT
add r0, r0, #52 /* Store core registers */
#else add r1, r0, #(_JB_CORE_BASE * 4)
/* Store fp registers */ stmia r1, {r4-r14}
sfm f4, 4, [r0], #48
/* Store fpsr */ #ifdef __ARM_HAVE_VFP
rfs r1 /* Store floating-point registers */
str r1, [r0], #0x0004 add r1, r0, #(_JB_FLOAT_BASE * 4)
#endif /* SOFTFLOAT */ vstmia r1, {d8-d15}
/* Store integer registers */ /* Store floating-point state */
stmia r0, {r4-r14} fmrx r1, fpscr
str r1, [r0, #(_JB_FLOAT_STATE * 4)]
#endif /* __ARM_HAVE_VFP */
mov r0, #0x00000000 mov r0, #0x00000000
bx lr bx lr
@ -72,21 +76,22 @@ ENTRY(_setjmp)
ENTRY(_longjmp) ENTRY(_longjmp)
ldr r2, .L_setjmp_magic ldr r2, .L_setjmp_magic
ldr r3, [r0], #4 ldr r3, [r0, #(_JB_MAGIC * 4)]
teq r2, r3 teq r2, r3
bne botch bne botch
#ifdef SOFTFLOAT #ifdef __ARM_HAVE_VFP
add r0, r0, #52 /* Restore floating-point registers */
#else add r2, r0, #(_JB_FLOAT_BASE * 4)
/* Restore fp registers */ vldmia r2, {d8-d15}
lfm f4, 4, [r0], #48 /* Restore floating-point state */
/* Restore fpsr */ ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
ldr r4, [r0], #0x0004 fmxr fpscr, r2
wfs r4 #endif /* __ARM_HAVE_VFP */
#endif /* SOFTFLOAT */
/* Restore integer registers */ /* Restore core registers */
ldmia r0, {r4-r14} add r2, r0, #(_JB_CORE_BASE * 4)
ldmia r2, {r4-r14}
/* Validate sp and r14 */ /* Validate sp and r14 */
teq sp, #0 teq sp, #0

View File

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

View File

@ -170,6 +170,19 @@
# define __ARM_HAVE_LDREXD # define __ARM_HAVE_LDREXD
#endif #endif
/* define _ARM_HAVE_VFP if we have VFPv3
*/
#if __ARM_ARCH__ >= 7 && defined __VFP_FP__
# define __ARM_HAVE_VFP
#endif
/* define _ARM_HAVE_NEON for ARMv7 architecture if we support the
* Neon SIMD instruction set extensions. This also implies
* that VFPv3-D32 is supported.
*/
#if __ARM_ARCH__ >= 7 && defined __ARM_NEON__
# define __ARM_HAVE_NEON
#endif
/* Assembly-only macros */ /* Assembly-only macros */

View File

@ -1,87 +1,82 @@
/* $OpenBSD: setjmp.h,v 1.1 2004/02/01 05:09:49 drahn Exp $ */ /*
/* $NetBSD: setjmp.h,v 1.2 2001/08/25 14:45:59 bjh21 Exp $ */ * Copyright (C) 2010 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* /*
* machine/setjmp.h: machine dependent setjmp-related information. * machine/setjmp.h: machine dependent setjmp-related information.
*/ */
#ifdef __ELF__ /* _JBLEN is the size of a jmp_buf in longs.
#define _JBLEN 64 /* size, in longs, of a jmp_buf */ * Do not modify this value or you will break the ABI !
#else
#define _JBLEN 29 /* size, in longs, of a jmp_buf */
#endif
/*
* NOTE: The internal structure of a jmp_buf is *PRIVATE*
* This information is provided as there is software
* that fiddles with this with obtain the stack pointer
* (yes really ! and its commercial !).
* *
* Description of the setjmp buffer * This value comes from the original OpenBSD ARM-specific header
* * that was replaced by this one.
* word 0 magic number (dependant on creator)
* 1 - 3 f4 fp register 4
* 4 - 6 f5 fp register 5
* 7 - 9 f6 fp register 6
* 10 - 12 f7 fp register 7
* 13 fpsr fp status register
* 14 r4 register 4
* 15 r5 register 5
* 16 r6 register 6
* 17 r7 register 7
* 18 r8 register 8
* 19 r9 register 9
* 20 r10 register 10 (sl)
* 21 r11 register 11 (fp)
* 22 r12 register 12 (ip)
* 23 r13 register 13 (sp)
* 24 r14 register 14 (lr)
* 25 signal mask (dependant on magic)
* 26 (con't)
* 27 (con't)
* 28 (con't)
*
* The magic number number identifies the jmp_buf and
* how the buffer was created as well as providing
* a sanity check
*
* A side note I should mention - Please do not tamper
* with the floating point fields. While they are
* always saved and restored at the moment this cannot
* be garenteed especially if the compiler happens
* to be generating soft-float code so no fp
* registers will be used.
*
* Whilst this can be seen an encouraging people to
* use the setjmp buffer in this way I think that it
* is for the best then if changes occur compiles will
* break rather than just having new builds falling over
* mysteriously.
*/ */
#define _JBLEN 64
/* According to the ARM AAPCS document, we only need to save
* the following registers:
*
* Core r4-r14
*
* VFP d8-d15 (see section 5.1.2.1)
*
* Registers s16-s31 (d8-d15, q4-q7) must be preserved across subroutine
* calls; registers s0-s15 (d0-d7, q0-q3) do not need to be preserved
* (and can be used for passing arguments or returning results in standard
* procedure-call variants). Registers d16-d31 (q8-q15), if present, do
* not need to be preserved.
*
* FPSCR saved because GLibc does saves it too.
*
*/
/* The internal structure of a jmp_buf is totally private.
* Current layout (may change in the future):
*
* word name description
* 0 magic magic number
* 1 sigmask signal mask (not used with _setjmp / _longjmp)
* 2 float_base base of float registers (d8 to d15)
* 18 float_state floating-point status and control register
* 19 core_base base of core registers (r4 to r14)
* 30 reserved reserved entries (room to grow)
* 64
*
* NOTE: float_base must be at an even word index, since the
* FP registers will be loaded/stored with instructions
* that expect 8-byte alignment.
*/
#define _JB_MAGIC 0
#define _JB_SIGMASK (_JB_MAGIC+1)
#define _JB_FLOAT_BASE (_JB_SIGMASK+1)
#define _JB_FLOAT_STATE (_JB_FLOAT_BASE + (15-8+1)*2)
#define _JB_CORE_BASE (_JB_FLOAT_STATE+1)
#define _JB_MAGIC__SETJMP 0x4278f500 #define _JB_MAGIC__SETJMP 0x4278f500
#define _JB_MAGIC_SETJMP 0x4278f501 #define _JB_MAGIC_SETJMP 0x4278f501
/* Valid for all jmp_buf's */
#define _JB_MAGIC 0
#define _JB_REG_F4 1
#define _JB_REG_F5 4
#define _JB_REG_F6 7
#define _JB_REG_F7 10
#define _JB_REG_FPSR 13
#define _JB_REG_R4 14
#define _JB_REG_R5 15
#define _JB_REG_R6 16
#define _JB_REG_R7 17
#define _JB_REG_R8 18
#define _JB_REG_R9 19
#define _JB_REG_R10 20
#define _JB_REG_R11 21
#define _JB_REG_R12 22
#define _JB_REG_R13 23
#define _JB_REG_R14 24
/* Only valid with the _JB_MAGIC_SETJMP magic */
#define _JB_SIGMASK 25

View File

@ -14,6 +14,8 @@ Differences between current and Android 2.2:
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Differences between Android 2.2. and Android 2.1: Differences between Android 2.2. and Android 2.1:
- Support FP register save/load in setjmp()/longjmp() on ARMv7 builds.
- Add support for SH-4 CPU architecture ! - Add support for SH-4 CPU architecture !
- __atomic_swap(): use LDREX/STREX CPU instructions on ARMv6 and higher. - __atomic_swap(): use LDREX/STREX CPU instructions on ARMv6 and higher.