]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc32 / setcontext-common.S
1 /* Jump to a new context powerpc32 common.
2 Copyright (C) 2005-2019 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 /* This is the common implementation of setcontext for powerpc32.
20 It not complete in itself should be included in to a framework that
21 defines:
22 __CONTEXT_FUNC_NAME
23 and if appropriate:
24 __CONTEXT_ENABLE_FPRS
25 __CONTEXT_ENABLE_VRS
26 Any architecture that implements the Vector unit is assumed to also
27 implement the floating unit. */
28
29 /* Stack frame offsets. */
30 #define _FRAME_BACKCHAIN 0
31 #define _FRAME_LR_SAVE 4
32 #define _FRAME_PARM_SAVE1 8
33 #define _FRAME_PARM_SAVE2 12
34 #define _FRAME_PARM_SAVE3 16
35 #define _FRAME_PARM_SAVE4 20
36
37 #ifdef __CONTEXT_ENABLE_VRS
38 .machine "altivec"
39 #endif
40 ENTRY(__CONTEXT_FUNC_NAME)
41 mflr r0
42 stwu r1,-16(r1)
43 cfi_adjust_cfa_offset (16)
44 stw r0,20(r1)
45 cfi_offset (lr, _FRAME_LR_SAVE)
46 stw r31,12(r1)
47 cfi_offset(r31,-4)
48 lwz r31,_UC_REGS_PTR(r3)
49
50 /* Restore the signal mask */
51 li r5,0
52 addi r4,r3,_UC_SIGMASK
53 li r3,SIG_SETMASK
54 bl __sigprocmask@local
55 cmpwi r3,0
56 bne 3f /* L(error_exit) */
57
58 #ifdef PIC
59 mflr r8
60 # define got_label GENERATE_GOT_LABEL (__CONTEXT_FUNC_NAME)
61 SETUP_GOT_ACCESS(r7,got_label)
62 addis r7,r7,_GLOBAL_OFFSET_TABLE_-got_label@ha
63 addi r7,r7,_GLOBAL_OFFSET_TABLE_-got_label@l
64 # ifdef SHARED
65 lwz r7,_rtld_global_ro@got(r7)
66 mtlr r8
67 lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r7)
68 # else
69 lwz r7,_dl_hwcap@got(r7)
70 mtlr r8
71 lwz r7,LOWORD(r7)
72 # endif
73 #else
74 lis r7,(_dl_hwcap+LOWORD)@ha
75 lwz r7,(_dl_hwcap+LOWORD)@l(r7)
76 #endif
77
78 #ifdef __CONTEXT_ENABLE_FPRS
79 # ifdef __CONTEXT_ENABLE_VRS
80 andis. r6,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
81 la r10,(_UC_VREGS)(r31)
82 beq 2f /* L(has_no_vec) */
83
84 lwz r0,(32*16)(r10)
85 li r9,(32*16)
86 cmpwi r0,0
87 mtspr VRSAVE,r0
88 beq 2f /* L(has_no_vec) */
89
90 lvx v19,r9,r10
91 la r9,(16)(r10)
92
93 lvx v0,0,r10
94 lvx v1,0,r9
95 addi r10,r10,32
96 addi r9,r9,32
97
98 mtvscr v19
99 lvx v2,0,r10
100 lvx v3,0,r9
101 addi r10,r10,32
102 addi r9,r9,32
103
104 lvx v4,0,r10
105 lvx v5,0,r9
106 addi r10,r10,32
107 addi r9,r9,32
108
109 lvx v6,0,r10
110 lvx v7,0,r9
111 addi r10,r10,32
112 addi r9,r9,32
113
114 lvx v8,0,r10
115 lvx v9,0,r9
116 addi r10,r10,32
117 addi r9,r9,32
118
119 lvx v10,0,r10
120 lvx v11,0,r9
121 addi r10,r10,32
122 addi r9,r9,32
123
124 lvx v12,0,r10
125 lvx v13,0,r9
126 addi r10,r10,32
127 addi r9,r9,32
128
129 lvx v14,0,r10
130 lvx v15,0,r9
131 addi r10,r10,32
132 addi r9,r9,32
133
134 lvx v16,0,r10
135 lvx v17,0,r9
136 addi r10,r10,32
137 addi r9,r9,32
138
139 lvx v18,0,r10
140 lvx v19,0,r9
141 addi r10,r10,32
142 addi r9,r9,32
143
144 lvx v20,0,r10
145 lvx v21,0,r9
146 addi r10,r10,32
147 addi r9,r9,32
148
149 lvx v22,0,r10
150 lvx v23,0,r9
151 addi r10,r10,32
152 addi r9,r9,32
153
154 lvx v24,0,r10
155 lvx v25,0,r9
156 addi r10,r10,32
157 addi r9,r9,32
158
159 lvx v26,0,r10
160 lvx v27,0,r9
161 addi r10,r10,32
162 addi r9,r9,32
163
164 lvx v28,0,r10
165 lvx v29,0,r9
166 addi r10,r10,32
167 addi r9,r9,32
168
169 lvx v30,0,r10
170 lvx v31,0,r9
171 addi r10,r10,32
172 addi r9,r9,32
173
174 lvx v10,0,r10
175 lvx v11,0,r9
176
177 2: /* L(has_no_vec): */
178 # endif /* __CONTEXT_ENABLE_VRS */
179 /* Restore the floating-point registers */
180 lfd fp31,_UC_FREGS+(32*8)(r31)
181 lfd fp0,_UC_FREGS+(0*8)(r31)
182 # ifdef _ARCH_PWR6
183 /* Use the extended four-operand version of the mtfsf insn. */
184 mtfsf 0xff,fp31,1,0
185 # else
186 .machine push
187 .machine "power6"
188 /* Availability of DFP indicates a 64-bit FPSCR. */
189 andi. r6,r7,PPC_FEATURE_HAS_DFP
190 beq 7f
191 /* Use the extended four-operand version of the mtfsf insn. */
192 mtfsf 0xff,fp31,1,0
193 b 8f
194 /* Continue to operate on the FPSCR as if it were 32-bits. */
195 7: mtfsf 0xff,fp31
196 8: .machine pop
197 # endif /* _ARCH_PWR6 */
198 lfd fp1,_UC_FREGS+(1*8)(r31)
199 lfd fp2,_UC_FREGS+(2*8)(r31)
200 lfd fp3,_UC_FREGS+(3*8)(r31)
201 lfd fp4,_UC_FREGS+(4*8)(r31)
202 lfd fp5,_UC_FREGS+(5*8)(r31)
203 lfd fp6,_UC_FREGS+(6*8)(r31)
204 lfd fp7,_UC_FREGS+(7*8)(r31)
205 lfd fp8,_UC_FREGS+(8*8)(r31)
206 lfd fp9,_UC_FREGS+(9*8)(r31)
207 lfd fp10,_UC_FREGS+(10*8)(r31)
208 lfd fp11,_UC_FREGS+(11*8)(r31)
209 lfd fp12,_UC_FREGS+(12*8)(r31)
210 lfd fp13,_UC_FREGS+(13*8)(r31)
211 lfd fp14,_UC_FREGS+(14*8)(r31)
212 lfd fp15,_UC_FREGS+(15*8)(r31)
213 lfd fp16,_UC_FREGS+(16*8)(r31)
214 lfd fp17,_UC_FREGS+(17*8)(r31)
215 lfd fp18,_UC_FREGS+(18*8)(r31)
216 lfd fp19,_UC_FREGS+(19*8)(r31)
217 lfd fp20,_UC_FREGS+(20*8)(r31)
218 lfd fp21,_UC_FREGS+(21*8)(r31)
219 lfd fp22,_UC_FREGS+(22*8)(r31)
220 lfd fp23,_UC_FREGS+(23*8)(r31)
221 lfd fp24,_UC_FREGS+(24*8)(r31)
222 lfd fp25,_UC_FREGS+(25*8)(r31)
223 lfd fp26,_UC_FREGS+(26*8)(r31)
224 lfd fp27,_UC_FREGS+(27*8)(r31)
225 lfd fp28,_UC_FREGS+(28*8)(r31)
226 lfd fp29,_UC_FREGS+(29*8)(r31)
227 lfd fp30,_UC_FREGS+(30*8)(r31)
228 lfd fp31,_UC_FREGS+(31*8)(r31)
229 #endif /* __CONTEXT_ENABLE_FPRS */
230
231 /* Restore LR and CCR, and set CTR to the NIP value */
232 lwz r3,_UC_GREGS+(PT_LNK*4)(r31)
233 lwz r4,_UC_GREGS+(PT_NIP*4)(r31)
234 lwz r5,_UC_GREGS+(PT_CCR*4)(r31)
235 mtlr r3
236 mtctr r4
237 mtcr r5
238
239 /* Restore the general registers */
240 lwz r1,_UC_GREGS+(PT_R1*4)(r31)
241 lwz r3,_UC_GREGS+(PT_R3*4)(r31)
242 lwz r4,_UC_GREGS+(PT_R4*4)(r31)
243 lwz r5,_UC_GREGS+(PT_R5*4)(r31)
244 lwz r6,_UC_GREGS+(PT_R6*4)(r31)
245 lwz r7,_UC_GREGS+(PT_R7*4)(r31)
246 lwz r8,_UC_GREGS+(PT_R8*4)(r31)
247 lwz r9,_UC_GREGS+(PT_R9*4)(r31)
248 lwz r10,_UC_GREGS+(PT_R10*4)(r31)
249 lwz r11,_UC_GREGS+(PT_R11*4)(r31)
250 lwz r12,_UC_GREGS+(PT_R12*4)(r31)
251 lwz r13,_UC_GREGS+(PT_R13*4)(r31)
252 lwz r14,_UC_GREGS+(PT_R14*4)(r31)
253 lwz r15,_UC_GREGS+(PT_R15*4)(r31)
254 lwz r16,_UC_GREGS+(PT_R16*4)(r31)
255 lwz r17,_UC_GREGS+(PT_R17*4)(r31)
256 lwz r18,_UC_GREGS+(PT_R18*4)(r31)
257 lwz r19,_UC_GREGS+(PT_R19*4)(r31)
258 lwz r20,_UC_GREGS+(PT_R20*4)(r31)
259 lwz r21,_UC_GREGS+(PT_R21*4)(r31)
260 lwz r22,_UC_GREGS+(PT_R22*4)(r31)
261 lwz r23,_UC_GREGS+(PT_R23*4)(r31)
262 lwz r24,_UC_GREGS+(PT_R24*4)(r31)
263 lwz r25,_UC_GREGS+(PT_R25*4)(r31)
264 lwz r26,_UC_GREGS+(PT_R26*4)(r31)
265 lwz r27,_UC_GREGS+(PT_R27*4)(r31)
266 lwz r28,_UC_GREGS+(PT_R28*4)(r31)
267 lwz r29,_UC_GREGS+(PT_R29*4)(r31)
268 lwz r30,_UC_GREGS+(PT_R30*4)(r31)
269 lwz r31,_UC_GREGS+(PT_R31*4)(r31)
270
271 bctr
272
273 3: /* L(error_exit): */
274 lwz r31,12(r1)
275 lwz r0,20(r1)
276 addi r1,r1,16
277 mtlr r0
278 blr
279
280 END (__CONTEXT_FUNC_NAME)