Update copyright dates with scripts/update-copyrights
[glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc32 / setcontext-common.S
blob4130223acf831157a30bbfb1571bd3e516e5bb59
1 /* Jump to a new context powerpc32 common.
2    Copyright (C) 2005-2023 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
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.
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.
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/>.  */
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.  */
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
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)
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) */
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
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) */
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) */
90         lvx   v19,r9,r10
91         la    r9,(16)(r10)
93         lvx   v0,0,r10
94         lvx   v1,0,r9
95         addi  r10,r10,32
96         addi  r9,r9,32
98         mtvscr  v19
99         lvx   v2,0,r10
100         lvx   v3,0,r9
101         addi  r10,r10,32
102         addi  r9,r9,32
104         lvx   v4,0,r10
105         lvx   v5,0,r9
106         addi  r10,r10,32
107         addi  r9,r9,32
109         lvx   v6,0,r10
110         lvx   v7,0,r9
111         addi  r10,r10,32
112         addi  r9,r9,32
114         lvx   v8,0,r10
115         lvx   v9,0,r9
116         addi  r10,r10,32
117         addi  r9,r9,32
119         lvx   v10,0,r10
120         lvx   v11,0,r9
121         addi  r10,r10,32
122         addi  r9,r9,32
124         lvx   v12,0,r10
125         lvx   v13,0,r9
126         addi  r10,r10,32
127         addi  r9,r9,32
129         lvx   v14,0,r10
130         lvx   v15,0,r9
131         addi  r10,r10,32
132         addi  r9,r9,32
134         lvx   v16,0,r10
135         lvx   v17,0,r9
136         addi  r10,r10,32
137         addi  r9,r9,32
139         lvx   v18,0,r10
140         lvx   v19,0,r9
141         addi  r10,r10,32
142         addi  r9,r9,32
144         lvx   v20,0,r10
145         lvx   v21,0,r9
146         addi  r10,r10,32
147         addi  r9,r9,32
149         lvx   v22,0,r10
150         lvx   v23,0,r9
151         addi  r10,r10,32
152         addi  r9,r9,32
154         lvx   v24,0,r10
155         lvx   v25,0,r9
156         addi  r10,r10,32
157         addi  r9,r9,32
159         lvx   v26,0,r10
160         lvx   v27,0,r9
161         addi  r10,r10,32
162         addi  r9,r9,32
164         lvx   v28,0,r10
165         lvx   v29,0,r9
166         addi  r10,r10,32
167         addi  r9,r9,32
169         lvx   v30,0,r10
170         lvx   v31,0,r9
171         addi  r10,r10,32
172         addi  r9,r9,32
174         lvx   v10,0,r10
175         lvx   v11,0,r9
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 */
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
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)
271         bctr
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
280 END (__CONTEXT_FUNC_NAME)