]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/hppa/setcontext.S
5e9dfe15147534a6048e97a108cb22336383d2c2
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / hppa / setcontext.S
1 /* Install given context.
2 Copyright (C) 2008-2020 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Helge Deller <deller@gmx.de>, 2008.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library. If not, see
18 <https://www.gnu.org/licenses/>. */
19
20 #include <sysdep.h>
21 #include <libc-symbols.h>
22
23 #include "ucontext_i.h"
24
25
26 ENTRY(__setcontext)
27 /* Prologue */
28 stw %r2, -20(%sp)
29 .cfi_offset 2, -20
30 stwm %r3, 64(%sp)
31 .cfi_def_cfa_offset -64
32 .cfi_offset 3, 0
33 #ifdef PIC
34 stw %r19, -32(%sp)
35 .cfi_offset 19, 32
36 #endif
37
38 /* Save ucp. */
39 copy %r26, %r3
40
41 .Lagain:
42 /* Set the current signal mask. */
43 /* sigprocmask(SIG_BLOCK, &ucp->uc_sigmask, NULL); */
44 copy %r0, %r24
45 ldo oSIGMASK(%r3), %r25
46 bl __sigprocmask, %r2
47 ldi SIG_SETMASK, %r26
48
49 comib,<>,n 0,%ret0,.Lerror
50
51 /* Save %sp, %dp. */
52 copy %sp, %r4
53 copy %dp, %r5
54 copy %r19, %r6
55
56 /* Get the registers. */
57 ldw oR1(%r3), %r1
58 ldw oR2(%r3), %r2
59 /* ldw oR3(%r3), %r3 - used for ucp pointer. */
60 /* ldw oR4(%r3), %r4 - used for original %sp. */
61 /* ldw oR5(%r3), %r5 - used for %dp / %r27. */
62 /* ldw oR6(%r3), %r6 - used for %r19. */
63 ldw oR7(%r3), %r7
64 ldw oR8(%r3), %r8
65 ldw oR9(%r3), %r9
66 ldw oR10(%r3), %r10
67 ldw oR11(%r3), %r11
68 ldw oR12(%r3), %r12
69 ldw oR13(%r3), %r13
70 ldw oR14(%r3), %r14
71 ldw oR15(%r3), %r15
72 ldw oR16(%r3), %r16
73 ldw oR17(%r3), %r17
74 ldw oR18(%r3), %r18
75 ldw oR19(%r3), %r19
76 ldw oR20(%r3), %r20
77 ldw oR21(%r3), %r21
78 /* ldw oR22(%r3), %r22 - dyncall arg. */
79 ldw oR23(%r3), %r23
80 ldw oR24(%r3), %r24
81 ldw oR25(%r3), %r25
82 ldw oR26(%r3), %r26
83 ldw oR27(%r3), %r27
84 ldw oR28(%r3), %r28
85 ldw oR29(%r3), %r29
86 ldw oR30(%r3), %sp
87 /* ldw oR31(%r3), %r31 - dyncall scratch register */
88
89 /* Restore floating-point registers. */
90 ldo oFPREGS31(%r3), %r22
91 fldds 0(%r22), %fr31
92 fldds,mb -8(%r22), %fr30
93 fldds,mb -8(%r22), %fr29
94 fldds,mb -8(%r22), %fr28
95 fldds,mb -8(%r22), %fr27
96 fldds,mb -8(%r22), %fr26
97 fldds,mb -8(%r22), %fr25
98 fldds,mb -8(%r22), %fr24
99 fldds,mb -8(%r22), %fr23
100 fldds,mb -8(%r22), %fr22
101 fldds,mb -8(%r22), %fr21
102 fldds,mb -8(%r22), %fr20
103 fldds,mb -8(%r22), %fr19
104 fldds,mb -8(%r22), %fr18
105 fldds,mb -8(%r22), %fr17
106 fldds,mb -8(%r22), %fr16
107 fldds,mb -8(%r22), %fr15
108 fldds,mb -8(%r22), %fr14
109 fldds,mb -8(%r22), %fr13
110 fldds,mb -8(%r22), %fr12
111 fldds,mb -8(%r22), %fr11
112 fldds,mb -8(%r22), %fr10
113 fldds,mb -8(%r22), %fr9
114 fldds,mb -8(%r22), %fr8
115 fldds,mb -8(%r22), %fr7
116 fldds,mb -8(%r22), %fr6
117 fldds,mb -8(%r22), %fr5
118 fldds,mb -8(%r22), %fr4
119 fldds,mb -8(%r22), %fr3
120 fldds,mb -8(%r22), %fr2
121 fldds,mb -8(%r22), %fr1
122 fldds,mb -8(%r22), %fr0
123
124 /* Do not load oSS_SP into %sp. The value of oSS_SP indicates
125 the start of the user allocated stack, but not the sp that
126 should be used by the new context. In fact makecontext
127 will create a frame, and adjust sp as required. We do not
128 support calling getcontext and modifying ss_sp without
129 a call to makecontext to synchronize ss_sp into the machine
130 context. */
131
132 /* Call external function. */
133 copy %r2, %r22
134 bl $$dyncall, %r31
135 copy %r31, %r2
136
137 /* We return here. Get new ucp in %r3, reload %sp. */
138 ldw oUC_LINK(%r3), %r3
139 copy %r4, %sp
140 copy %r5, %dp
141 copy %r6, %r19
142
143 /* Continue until ucp == NULL. */
144 comib,<> 0,%r3,.Lagain
145 nop
146
147 /* No further context available. Exit now. */
148 bl HIDDEN_JUMPTARGET(exit), %r2
149 ldi 0, %r26
150
151
152 .Lerror:
153 /* Epilogue */
154 ldw -84(%r30), %r2
155 #ifdef PIC
156 ldw -32(%r30), %r19
157 #endif
158 bv %r0(%r2)
159 ldwm -64(%r30), %r3
160 L(pseudo_end):
161 PSEUDO_END(__setcontext)
162
163 weak_alias(__setcontext, setcontext)