1/* Get current user context.
2   Copyright (C) 2008-2022 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   <https://www.gnu.org/licenses/>.  */
18
19#include <sysdep.h>
20
21#include "ucontext_i.h"
22
23
24	/* Trampoline function.  Non-standard calling ABI.  */
25	/* Can not use ENTRY(__getcontext_ret) here.  */
26	.type	__getcontext_ret, @function
27	.hidden	__getcontext_ret
28__getcontext_ret:
29	.proc
30	.callinfo FRAME=0,NO_CALLS
31	/* Because setcontext does not reload r3-r6 (it's using them
32	   as temporaries), we must load them ourself.  */
33	ldw	oR3(%r26), %r3
34	ldw	oR4(%r26), %r4
35	ldw	oR5(%r26), %r5
36	ldw	oR6(%r26), %r6
37
38	/* Also reload registers clobbered by $$dyncall.  */
39	ldw	oR21(%r26), %r21
40	ldw	oR22(%r26), %r22
41	ldw	oR31(%r26), %r31
42
43	/* oR0 contains original return pointer.  */
44	ldw	oR0(%r26), %rp
45	bv	0(%rp)
46	copy	%r0, %ret0
47	.procend
48	.size	__getcontext_ret, .-__getcontext_ret
49
50
51ENTRY(__getcontext)
52	/* Save the registers.  */
53	stw	%r0, oR0(%r26)
54	stw	%r1, oR1(%r26)
55	/* stw	%r2, oR2(%r26) - used for trampoline.  */
56	stw	%r3, oR3(%r26)
57	stw	%r4, oR4(%r26)
58	stw	%r5, oR5(%r26)
59	stw	%r6, oR6(%r26)
60	stw	%r7, oR7(%r26)
61	stw	%r8, oR8(%r26)
62	stw	%r9, oR9(%r26)
63	stw	%r10, oR10(%r26)
64	stw	%r11, oR11(%r26)
65	stw	%r12, oR12(%r26)
66	stw	%r13, oR13(%r26)
67	stw	%r14, oR14(%r26)
68	stw	%r15, oR15(%r26)
69	stw	%r16, oR16(%r26)
70	stw	%r17, oR17(%r26)
71	stw	%r18, oR18(%r26)
72	stw	%r19, oR19(%r26)
73	stw	%r20, oR20(%r26)
74	stw	%r21, oR21(%r26)
75	stw	%r22, oR22(%r26)
76	stw	%r23, oR23(%r26)
77	stw	%r24, oR24(%r26)
78	stw	%r25, oR25(%r26)
79	stw	%r26, oR26(%r26)
80	stw	%r27, oR27(%r26)
81	stw	%r28, oR28(%r26)
82	stw	%r29, oR29(%r26)
83	stw	%sp, oR30(%r26)
84	stw	%r31, oR31(%r26)
85
86	stw	%r0, oUC_FLAGS(%r26)
87	/* stw	%r0, oUC_LINK(%r26) - Do not overwrite.  */
88	stw	%sp, oSS_SP(%r26)
89	stw	%r0, oSS_FLAGS(%r26)
90	stw	%r0, oSS_SIZE(%r26)
91
92	stw	%r0, oSC_FLAGS(%r26)
93
94	stw	%r0, oIASQ0(%r26)
95	stw	%r0, oIASQ1(%r26)
96	stw	%r0, oIAOQ0(%r26)
97	stw	%r0, oIAOQ1(%r26)
98
99	/* Save SAR register.  */
100	mfctl	%sar, %r1
101	stw	%r1, oSAR(%r26) /* MSB used as flag in swapcontext().  */
102
103
104	/* Store floating-point regs.  */
105	ldo	oFPREGS0(%r26),%r1
106	fstds,ma %fr0, 8(%r1)
107	fstds,ma %fr1, 8(%r1)
108	fstds,ma %fr2, 8(%r1)
109	fstds,ma %fr3, 8(%r1)
110	fstds,ma %fr4, 8(%r1)
111	fstds,ma %fr5, 8(%r1)
112	fstds,ma %fr6, 8(%r1)
113	fstds,ma %fr7, 8(%r1)
114	fstds,ma %fr8, 8(%r1)
115	fstds,ma %fr9, 8(%r1)
116	fstds,ma %fr10, 8(%r1)
117	fstds,ma %fr11, 8(%r1)
118	fstds,ma %fr12, 8(%r1)
119	fstds,ma %fr13, 8(%r1)
120	fstds,ma %fr14, 8(%r1)
121	fstds,ma %fr15, 8(%r1)
122	fstds,ma %fr16, 8(%r1)
123	fstds,ma %fr17, 8(%r1)
124	fstds,ma %fr18, 8(%r1)
125	fstds,ma %fr19, 8(%r1)
126	fstds,ma %fr20, 8(%r1)
127	fstds,ma %fr21, 8(%r1)
128	fstds,ma %fr22, 8(%r1)
129	fstds,ma %fr23, 8(%r1)
130	fstds,ma %fr24, 8(%r1)
131	fstds,ma %fr25, 8(%r1)
132	fstds,ma %fr26, 8(%r1)
133	fstds,ma %fr27, 8(%r1)
134	fstds,ma %fr28, 8(%r1)
135	fstds,ma %fr29, 8(%r1)
136	fstds,ma %fr30, 8(%r1)
137	fstds	 %fr31, 0(%r1)
138
139	/* Prologue */
140	stw	%r2, -20(%sp)
141	.cfi_offset 2, -20
142	stwm	%r4, 64(%sp)
143	.cfi_def_cfa_offset -64
144	.cfi_offset 4, 0
145#ifdef PIC
146	stw	%r19, -32(%sp)
147	.cfi_offset 19, 32
148#endif
149	stw	%ret1, -60(%sp)
150	.cfi_offset 29, 4
151
152	/* Set up the trampoline registers.
153	   Use oR0 context slot to save return value.  */
154	stw	%r2, oR0(%r26)
155#ifdef PIC
156	addil	LT%__getcontext_ret, %r19
157	ldw     RT%__getcontext_ret(%r1), %r1
158#else
159	ldil	L%__getcontext_ret, %r1
160	ldo     R%__getcontext_ret(%r1), %r1
161#endif
162	stw	%r1, oR2(%r26)
163
164	/* Save the current signal mask.  */
165	/* sigprocmask(SIG_BLOCK, NULL, &ucp->uc_sigmask);  */
166	ldo	oSIGMASK(%r26), %r24
167	copy	%r0, %r25
168	bl	__sigprocmask, %r2
169	ldi	SIG_BLOCK, %r26
170
171	/* Epilogue */
172	ldw	-84(%sp), %r2
173#ifdef PIC
174	ldw	-32(%sp), %r19
175#endif
176	ldw	-60(%sp), %ret1
177	bv	%r0(%r2)
178	ldwm	-64(%sp), %r4
179END(__getcontext)
180
181weak_alias (__getcontext, getcontext)
182