1/* Install given 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#include <libc-symbols.h>
21
22#include "ucontext_i.h"
23
24
25ENTRY(__setcontext)
26 /* Prologue */
27 stw %r2, -20(%sp)
28 .cfi_offset 2, -20
29 stwm %r3, 64(%sp)
30 .cfi_def_cfa_offset -64
31 .cfi_offset 3, 0
32#ifdef PIC
33 stw %r19, -32(%sp)
34 .cfi_offset 19, 32
35#endif
36 stw %ret1, -60(%sp)
37 .cfi_offset 29, 4
38
39 /* Save ucp. */
40 copy %r26, %r3
41
42.Lagain:
43 /* Set the current signal mask. */
44 /* sigprocmask(SIG_BLOCK, &ucp->uc_sigmask, NULL); */
45 copy %r0, %r24
46 ldo oSIGMASK(%r3), %r25
47 bl __sigprocmask, %r2
48 ldi SIG_SETMASK, %r26
49
50 comib,<>,n 0,%ret0,.Lerror
51
52 /* Save %sp, %dp. */
53 copy %sp, %r4
54 copy %dp, %r5
55 copy %r19, %r6
56
57 /* Get the registers. */
58 ldw oR1(%r3), %r1
59 ldw oR2(%r3), %r2
60 /* ldw oR3(%r3), %r3 - used for ucp pointer. */
61 /* ldw oR4(%r3), %r4 - used for original %sp. */
62 /* ldw oR5(%r3), %r5 - used for %dp / %r27. */
63 /* ldw oR6(%r3), %r6 - used for %r19. */
64 ldw oR7(%r3), %r7
65 ldw oR8(%r3), %r8
66 ldw oR9(%r3), %r9
67 ldw oR10(%r3), %r10
68 ldw oR11(%r3), %r11
69 ldw oR12(%r3), %r12
70 ldw oR13(%r3), %r13
71 ldw oR14(%r3), %r14
72 ldw oR15(%r3), %r15
73 ldw oR16(%r3), %r16
74 ldw oR17(%r3), %r17
75 ldw oR18(%r3), %r18
76 ldw oR19(%r3), %r19
77 ldw oR20(%r3), %r20
78 ldw oR21(%r3), %r21 /* maybe clobbered by dyncall */
79 /* ldw oR22(%r3), %r22 - dyncall arg. */
80 ldw oR23(%r3), %r23
81 ldw oR24(%r3), %r24
82 ldw oR25(%r3), %r25
83 ldw oR26(%r3), %r26
84 ldw oR27(%r3), %r27
85 ldw oR28(%r3), %r28
86 ldw oR29(%r3), %r29
87 ldw oR30(%r3), %sp
88 /* ldw oR31(%r3), %r31 - dyncall scratch register */
89
90 /* Restore SAR register. */
91 ldw oSAR(%r3), %r22
92 mtsar %r22
93
94 /* Restore floating-point registers. */
95 ldo oFPREGS31(%r3), %r22
96 fldds 0(%r22), %fr31
97 fldds,mb -8(%r22), %fr30
98 fldds,mb -8(%r22), %fr29
99 fldds,mb -8(%r22), %fr28
100 fldds,mb -8(%r22), %fr27
101 fldds,mb -8(%r22), %fr26
102 fldds,mb -8(%r22), %fr25
103 fldds,mb -8(%r22), %fr24
104 fldds,mb -8(%r22), %fr23
105 fldds,mb -8(%r22), %fr22
106 fldds,mb -8(%r22), %fr21
107 fldds,mb -8(%r22), %fr20
108 fldds,mb -8(%r22), %fr19
109 fldds,mb -8(%r22), %fr18
110 fldds,mb -8(%r22), %fr17
111 fldds,mb -8(%r22), %fr16
112 fldds,mb -8(%r22), %fr15
113 fldds,mb -8(%r22), %fr14
114 fldds,mb -8(%r22), %fr13
115 fldds,mb -8(%r22), %fr12
116 fldds,mb -8(%r22), %fr11
117 fldds,mb -8(%r22), %fr10
118 fldds,mb -8(%r22), %fr9
119 fldds,mb -8(%r22), %fr8
120 fldds,mb -8(%r22), %fr7
121 fldds,mb -8(%r22), %fr6
122 fldds,mb -8(%r22), %fr5
123 fldds,mb -8(%r22), %fr4
124 fldds,mb -8(%r22), %fr3
125 fldds,mb -8(%r22), %fr2
126 fldds,mb -8(%r22), %fr1
127 fldds,mb -8(%r22), %fr0
128
129 /* Do not load oSS_SP into %sp. The value of oSS_SP indicates
130 the start of the user allocated stack, but not the sp that
131 should be used by the new context. In fact makecontext
132 will create a frame, and adjust sp as required. We do not
133 support calling getcontext and modifying ss_sp without
134 a call to makecontext to synchronize ss_sp into the machine
135 context. */
136
137 /* Call external function. */
138 copy %r2, %r22
139 bl $$dyncall, %r31
140 copy %r31, %r2
141
142 /* We return here. Get new ucp in %r3, reload %sp. */
143 ldw oUC_LINK(%r3), %r3
144 copy %r4, %sp
145 copy %r5, %dp
146 copy %r6, %r19
147
148 /* Continue until ucp == NULL. */
149 comib,<> 0,%r3,.Lagain
150 nop
151
152 /* No further context available. Exit now. */
153 bl HIDDEN_JUMPTARGET(exit), %r2
154 ldi 0, %r26
155
156
157.Lerror:
158 /* Epilogue */
159 ldw -84(%r30), %r2
160#ifdef PIC
161 ldw -32(%r30), %r19
162#endif
163 ldw -60(%r30), %ret1
164 bv %r0(%r2)
165 ldwm -64(%r30), %r3
166L(pseudo_end):
167PSEUDO_END(__setcontext)
168
169weak_alias(__setcontext, setcontext)
170

source code of glibc/sysdeps/unix/sysv/linux/hppa/setcontext.S