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 | |
51 | ENTRY(__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 |
179 | END(__getcontext) |
180 | |
181 | weak_alias (__getcontext, getcontext) |
182 | |