Fix setjmp()/longjmp() to save FP registers on ARMv7.

Change-Id: I8ec684c8f8ca1ae58c8feb330b97d1e2b81caeef
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/arch-arm/include/machine/cpu-features.h
index ecf6ff6..abf226a 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/arch-arm/include/machine/cpu-features.h
@@ -156,6 +156,19 @@
 #  define _ARM_HAVE_LDREX_STREX
 #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 */
 
diff --git a/libc/arch-arm/include/machine/setjmp.h b/libc/arch-arm/include/machine/setjmp.h
index f20cab2..0941202 100644
--- a/libc/arch-arm/include/machine/setjmp.h
+++ b/libc/arch-arm/include/machine/setjmp.h
@@ -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.
  */
 
-#ifdef __ELF__
-#define	_JBLEN	64		/* size, in longs, of a jmp_buf */
-#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 !).
+/* _JBLEN is the size of a jmp_buf in longs.
+ * Do not modify this value or you will break the ABI !
  *
- * Description of the setjmp buffer
- *
- * 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.
+ * This value comes from the original OpenBSD ARM-specific header
+ * that was replaced by this one.
  */
+#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	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