1/* Copyright (C) 1999-2022 Free Software Foundation, Inc.
2
3   The GNU C Library is free software; you can redistribute it and/or
4   modify it under the terms of the GNU Lesser General Public
5   License as published by the Free Software Foundation; either
6   version 2.1 of the License, or (at your option) any later version.
7
8   The GNU C Library is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11   Lesser General Public License for more details.
12
13   You should have received a copy of the GNU Lesser General Public
14   License along with the GNU C Library; if not, see
15   <https://www.gnu.org/licenses/>.
16
17   The layout of the jmp_buf is as follows.  This is subject to change
18   and user-code should never depend on the particular layout of
19   jmp_buf!
20
21
22	offset:	description:
23	-------	------------
24	0x000	stack pointer (r12)	; unchangeable (see _JMPBUF_UNWINDS)
25	0x008	r1 (gp)
26	0x010	caller's unat
27	0x018	fpsr			; disabled per the C standard; BZ 16379
28	0x020	r4
29	0x028	r5
30	0x030	r6
31	0x038	r7
32	0x040	rp (b0)
33	0x048	b1
34	0x050	b2
35	0x058	b3
36	0x060	b4
37	0x068	b5
38	0x070	ar.pfs
39	0x078	ar.lc
40	0x080	pr
41	0x088	ar.bsp			; unchangeable (see __longjmp.S)
42	0x090	ar.unat
43	0x098	&__jmp_buf	; address of the jmpbuf (needed to locate NaT bits in unat)
44	0x0a0	 f2
45	0x0b0	 f3
46	0x0c0	 f4
47	0x0d0	 f5
48	0x0e0	f16
49	0x0f0	f17
50	0x100	f18
51	0x110	f19
52	0x120	f20
53	0x130	f21
54	0x130	f22
55	0x140	f23
56	0x150	f24
57	0x160	f25
58	0x170	f26
59	0x180	f27
60	0x190	f28
61	0x1a0	f29
62	0x1b0	f30
63	0x1c0	f31 */
64
65#include <sysdep.h>
66#include <features.h>
67
68	/* The following two entry points are the traditional entry points: */
69
70LEAF(setjmp)
71	alloc r8=ar.pfs,2,0,0,0
72	mov in1=1
73	br.cond.sptk.many HIDDEN_JUMPTARGET(__sigsetjmp)
74END(setjmp)
75
76LEAF(_setjmp)
77	alloc r8=ar.pfs,2,0,0,0
78	mov in1=0
79	br.cond.sptk.many HIDDEN_JUMPTARGET(__sigsetjmp)
80END(_setjmp)
81libc_hidden_def (_setjmp)
82
83	/* __sigsetjmp(__jmp_buf buf, int savemask) */
84
85ENTRY(__sigsetjmp)
86	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2)
87	alloc loc1=ar.pfs,2,5,2,0
88	.save ar.unat, loc2
89	mov loc2=ar.unat
90	;;
91//	mov r17=ar.fpsr
92	mov r2=in0
93	add r3=8,in0
94	;;
95.mem.offset 8,0;	st8.spill.nta [r2]=sp,16	// r12 (sp)
96.mem.offset 0,0;	st8.spill.nta [r3]=gp,32	// r1 (gp)
97	;;
98	st8.nta [r2]=loc2,16		// save caller's unat
99//	st8.nta [r3]=r17,16		// save fpsr
100	add r8=0xa0,in0
101	;;
102.mem.offset 8,0;	st8.spill.nta [r2]=r4,16	// r4
103.mem.offset 0,0;	st8.spill.nta [r3]=r5,16	// r5
104	add r9=0xb0,in0
105	;;
106	stf.spill.nta [r8]=f2,32
107	stf.spill.nta [r9]=f3,32
108	mov loc0=rp
109	.body
110	;;
111	stf.spill.nta [r8]=f4,32
112	stf.spill.nta [r9]=f5,32
113	mov r17=b1
114	;;
115	stf.spill.nta [r8]=f16,32
116	stf.spill.nta [r9]=f17,32
117	mov r18=b2
118	;;
119	stf.spill.nta [r8]=f18,32
120	stf.spill.nta [r9]=f19,32
121	mov r19=b3
122	;;
123	stf.spill.nta [r8]=f20,32
124	stf.spill.nta [r9]=f21,32
125	mov r20=b4
126	;;
127	stf.spill.nta [r8]=f22,32
128	stf.spill.nta [r9]=f23,32
129	mov r21=b5
130	;;
131	stf.spill.nta [r8]=f24,32
132	stf.spill.nta [r9]=f25,32
133	mov r22=ar.lc
134	;;
135	stf.spill.nta [r8]=f26,32
136	stf.spill.nta [r9]=f27,32
137	mov r24=pr
138	;;
139	stf.spill.nta [r8]=f28,32
140	stf.spill.nta [r9]=f29,32
141#ifdef PTR_MANGLE
142	mov loc3=loc0
143	;;
144	PTR_MANGLE (loc3, loc4)
145#else
146	;;
147#endif
148	stf.spill.nta [r8]=f30
149	stf.spill.nta [r9]=f31
150
151.mem.offset 8,0;	st8.spill.nta [r2]=r6,16	// r6
152.mem.offset 0,0;	st8.spill.nta [r3]=r7,16	// r7
153	;;
154	mov r23=ar.bsp
155	mov r25=ar.unat
156	mov out0=in0
157
158#ifdef PTR_MANGLE
159	st8.nta [r2]=loc3,16		// b0
160#else
161	st8.nta [r2]=loc0,16		// b0
162#endif
163	st8.nta [r3]=r17,16		// b1
164	mov out1=in1
165	;;
166	st8.nta [r2]=r18,16		// b2
167	st8.nta [r3]=r19,16		// b3
168	;;
169	st8.nta [r2]=r20,16		// b4
170	st8.nta [r3]=r21,16		// b5
171	;;
172	st8.nta [r2]=loc1,16		// ar.pfs
173	st8.nta [r3]=r22,16		// ar.lc
174	;;
175	st8.nta [r2]=r24,16		// pr
176	st8.nta [r3]=r23,16		// ar.bsp
177	;;
178	st8.nta [r2]=r25		// ar.unat
179	st8.nta [r3]=in0		// &__jmp_buf
180#if IS_IN (rtld)
181	/* In ld.so we never save the signal mask.  */
182	;;
183#else
184	br.call.dpnt.few rp=__sigjmp_save
185#endif
186.ret0:					// force a new bundle ::q
187	mov.m ar.unat=loc2		// restore caller's unat
188	mov rp=loc0
189	mov ar.pfs=loc1
190	mov r8=0
191	ret
192END(__sigsetjmp)
193libc_hidden_def (__sigsetjmp)
194rtld_hidden_def (__sigsetjmp)
195
196weak_extern(_setjmp)
197weak_extern(setjmp)
198