1/* setjmp for ARM.
2   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
3   This file is part of the GNU C Library.
4
5   The GNU C Library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9
10   The GNU C Library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14
15   You should have received a copy of the GNU Lesser General Public
16   License along with the GNU C Library; if not, see
17   <http://www.gnu.org/licenses/>.  */
18
19#include <features.h>
20#include <bits/arm_asm.h>
21
22.global __sigsetjmp
23.type __sigsetjmp,%function
24.align 2
25#if defined(THUMB1_ONLY)
26.thumb_func
27__sigsetjmp:
28	push	{r3, r4, r5, r6, r7, lr}
29	mov	ip, r0
30	stmia	r0!, {r4, r5, r6, r7}
31	mov	r2, r8
32	mov	r3, r9
33	mov	r4, sl
34	mov	r5, fp
35	add	r6, sp, #(6 * 4)
36	mov	r7, lr
37	stmia	r0!, {r2, r3, r4, r5, r6, r7}
38
39	mov	r0, ip
40	bl	__sigjmp_save
41	pop	{r3, r4, r5, r6, r7, pc}
42
43#else
44__sigsetjmp:
45	/* Save registers */
46	mov	ip, r0
47#if defined(__thumb2__)
48	stmia	ip!, {v1-v6, sl, fp}
49	mov	r2, sp
50	stmia	ip!, {r2, lr}
51#else
52	/* Save registers */
53	stmia	ip!, {v1-v6, sl, fp, sp, lr}
54#endif
55#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
56# ifdef __VFP_FP__
57#  if __ARM_ARCH >= 8
58	/* Store the VFP registers.  */
59	fstmiax ip!, {d8-d15}
60	/* Store the floating-point status register.  */
61	fmrx    r2, fpscr
62	str     r2, [ip], #4
63#  else
64	/* Store the VFP registers.  */
65	/* Following instruction is fstmiax ip!, {d8-d15}.  */
66	stc	p11, cr8, [r12], #68
67	/* Store the floating-point status register.  */
68	/* Following instruction is fmrx r2, fpscr.  */
69	mrc	p10, 7, r2, cr1, cr0, 0
70	str	r2, [ip], #4
71#  endif
72# elif defined __MAVERICK__
73	cfstrd	mvd4,  [ip], #8 ; nop
74	cfstrd	mvd5,  [ip], #8 ; nop
75	cfstrd	mvd6,  [ip], #8 ; nop
76	cfstrd	mvd7,  [ip], #8 ; nop
77	cfstrd	mvd8,  [ip], #8 ; nop
78	cfstrd	mvd9,  [ip], #8 ; nop
79	cfstrd	mvd10, [ip], #8 ; nop
80	cfstrd	mvd11, [ip], #8 ; nop
81	cfstrd	mvd12, [ip], #8 ; nop
82	cfstrd	mvd13, [ip], #8 ; nop
83	cfstrd	mvd14, [ip], #8 ; nop
84	cfstrd	mvd15, [ip], #8
85# else
86	sfmea   f4, 4, [ip]!
87# endif
88#endif
89#ifdef __IWMMXT__
90	/* Save the call-preserved iWMMXt registers.  */
91	/* Following instructions are wstrd wr10, [ip], #8 (etc.)  */
92	stcl	p1, cr10, [r12], #8
93	stcl	p1, cr11, [r12], #8
94	stcl	p1, cr12, [r12], #8
95	stcl	p1, cr13, [r12], #8
96	stcl	p1, cr14, [r12], #8
97	stcl	p1, cr15, [r12], #8
98#endif
99
100	/* Make a tail call to __sigjmp_save; it takes the same args.  */
101#ifdef __PIC__
102	B	__sigjmp_save(PLT)
103#else
104	B	__sigjmp_save
105#endif
106#endif
107
108.size __sigsetjmp,.-__sigsetjmp
109