powerpc: Update ulps
[glibc.git] / sysdeps / powerpc / powerpc64 / setjmp-common.S
blobd677741a818c3beb80eb48735403228313ec4d2c
1 /* setjmp for PowerPC64.
2    Copyright (C) 1995-2024 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 #include <sysdep.h>
20 #include <pointer_guard.h>
21 #include <stap-probe.h>
22 #define _ASM
23 #ifdef __NO_VMX__
24 #include <novmxsetjmp.h>
25 #else
26 #include <jmpbuf-offsets.h>
27 #endif
29 #ifndef __NO_VMX__
30         .section        ".toc","aw"
31 .LC__dl_hwcap:
32 # ifdef SHARED
33 #  if IS_IN (rtld)
34         /* Inside ld.so we use the local alias to avoid runtime GOT
35            relocations.  */
36         .tc _rtld_local_ro[TC],_rtld_local_ro
37 #  else
38         .tc _rtld_global_ro[TC],_rtld_global_ro
39 #  endif
40 # else
41         .tc _dl_hwcap[TC],_dl_hwcap
42 # endif
43         .section ".text"
44 #endif
46         .machine        "altivec"
47 ENTRY (setjmp_symbol)
48         CALL_MCOUNT 1
49         li r4,1                 /* Set second argument to 1.  */
50         b JUMPTARGET (GLUE(__sigsetjmp_symbol,_ent))
51 END (setjmp_symbol)
53 #if defined SHARED && !IS_IN (rtld) && !defined __NO_VMX__
54 /* When called from within libc we need a special version of _setjmp
55    that saves r2 since the call won't go via a plt call stub.  See
56    bugz #269.  __GI__setjmp is used in csu/libc-start.c when
57    HAVE_CLEANUP_JMP_BUF is defined.  */
58 ENTRY (__GI__setjmp)
59         std r2,FRAME_TOC_SAVE(r1)               /* Save the callers TOC in the save area.  */
60         CALL_MCOUNT 1
61         li r4,0                 /* Set second argument to 0.  */
62         b JUMPTARGET (GLUE(__sigsetjmp_symbol,_ent))
63 END (__GI__setjmp)
64 #endif
66 ENTRY (_setjmp_symbol)
67         CALL_MCOUNT 1
68         li r4,0                 /* Set second argument to 0.  */
69         b JUMPTARGET (GLUE(__sigsetjmp_symbol,_ent))
70 END (_setjmp_symbol)
71 libc_hidden_def (_setjmp_symbol)
73 ENTRY (__sigsetjmp_symbol)
74         CALL_MCOUNT 2
75 JUMPTARGET(GLUE(__sigsetjmp_symbol,_ent)):
76 #ifdef PTR_MANGLE
77         mr   r5, r1
78         PTR_MANGLE (r5, r6)
79         std  r5,(JB_GPR1*8)(3)
80 #else
81         std  r1,(JB_GPR1*8)(3)
82 #endif
83         mflr r0
84 #if defined SHARED && !IS_IN (rtld)
85         ld   r5,FRAME_TOC_SAVE(r1)      /* Retrieve the callers TOC.  */
86         std  r5,(JB_GPR2*8)(3)
87 #else
88         std  r2,(JB_GPR2*8)(3)
89 #endif
90         /* setjmp probe expects longjmp first argument (8@3), second argument
91            (-4@4), and target address (8@0), respectively.  */
92         LIBC_PROBE (setjmp, 3, 8@3, -4@4, 8@0)
93         std  r14,((JB_GPRS+0)*8)(3)
94         stfd fp14,((JB_FPRS+0)*8)(3)
95 #ifdef PTR_MANGLE
96         PTR_MANGLE2 (r0, r6)
97 #endif
98         std  r0,(JB_LR*8)(3)
99         std  r15,((JB_GPRS+1)*8)(3)
100         stfd fp15,((JB_FPRS+1)*8)(3)
101         mfcr r0
102         std  r16,((JB_GPRS+2)*8)(3)
103         stfd fp16,((JB_FPRS+2)*8)(3)
104         stw  r0,((JB_CR*8)+4)(3)        /* 32-bit CR.  */
105         std  r17,((JB_GPRS+3)*8)(3)
106         stfd fp17,((JB_FPRS+3)*8)(3)
107         std  r18,((JB_GPRS+4)*8)(3)
108         stfd fp18,((JB_FPRS+4)*8)(3)
109         std  r19,((JB_GPRS+5)*8)(3)
110         stfd fp19,((JB_FPRS+5)*8)(3)
111         std  r20,((JB_GPRS+6)*8)(3)
112         stfd fp20,((JB_FPRS+6)*8)(3)
113         std  r21,((JB_GPRS+7)*8)(3)
114         stfd fp21,((JB_FPRS+7)*8)(3)
115         std  r22,((JB_GPRS+8)*8)(3)
116         stfd fp22,((JB_FPRS+8)*8)(3)
117         std  r23,((JB_GPRS+9)*8)(3)
118         stfd fp23,((JB_FPRS+9)*8)(3)
119         std  r24,((JB_GPRS+10)*8)(3)
120         stfd fp24,((JB_FPRS+10)*8)(3)
121         std  r25,((JB_GPRS+11)*8)(3)
122         stfd fp25,((JB_FPRS+11)*8)(3)
123         std  r26,((JB_GPRS+12)*8)(3)
124         stfd fp26,((JB_FPRS+12)*8)(3)
125         std  r27,((JB_GPRS+13)*8)(3)
126         stfd fp27,((JB_FPRS+13)*8)(3)
127         std  r28,((JB_GPRS+14)*8)(3)
128         stfd fp28,((JB_FPRS+14)*8)(3)
129         std  r29,((JB_GPRS+15)*8)(3)
130         stfd fp29,((JB_FPRS+15)*8)(3)
131         std  r30,((JB_GPRS+16)*8)(3)
132         stfd fp30,((JB_FPRS+16)*8)(3)
133         std  r31,((JB_GPRS+17)*8)(3)
134         stfd fp31,((JB_FPRS+17)*8)(3)
135 #ifndef __NO_VMX__
136         addis   r6,r2,.LC__dl_hwcap@toc@ha
137         ld      r6,.LC__dl_hwcap@toc@l(r6)
138 # ifdef SHARED
139         /* Load _rtld-global._dl_hwcap.  */
140         ld      r6,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r6)
141 # else
142         /* Load extern _dl_hwcap.  */
143         ld      r6,0(r6)
144 # endif
145         andis.  r6,r6,(PPC_FEATURE_HAS_ALTIVEC >> 16)
146         beq     L(no_vmx)
147         la      r5,((JB_VRS)*8)(3)
148         andi.   r6,r5,0xf
149         mfspr   r0,VRSAVE
150         stw     r0,((JB_VRSAVE)*8)(3)   /* 32-bit VRSAVE.  */
151         addi    r6,r5,16
152         beq+    L(aligned_save_vmx)
154         lvsr    v0,0,r5
155         lvsl    v1,0,r5
156         addi    r6,r5,-16
158 # define save_misaligned_vmx(savevr,prevvr,shiftvr,tmpvr,savegpr,addgpr) \
159         addi    addgpr,addgpr,32;                                        \
160         vperm   tmpvr,prevvr,savevr,shiftvr;                             \
161         stvx    tmpvr,0,savegpr
163         /*
164          * We have to be careful not to corrupt the data below v20 and
165          * above v31. To keep things simple we just rotate both ends in
166          * the opposite direction to our main permute so we can use
167          * the common macro.
168          */
170         /* load and rotate data below v20 */
171         lvx     v2,0,r5
172         vperm   v2,v2,v2,v1
173         save_misaligned_vmx(v20,v2,v0,v3,r5,r6)
174         save_misaligned_vmx(v21,v20,v0,v3,r6,r5)
175         save_misaligned_vmx(v22,v21,v0,v3,r5,r6)
176         save_misaligned_vmx(v23,v22,v0,v3,r6,r5)
177         save_misaligned_vmx(v24,v23,v0,v3,r5,r6)
178         save_misaligned_vmx(v25,v24,v0,v3,r6,r5)
179         save_misaligned_vmx(v26,v25,v0,v3,r5,r6)
180         save_misaligned_vmx(v27,v26,v0,v3,r6,r5)
181         save_misaligned_vmx(v28,v27,v0,v3,r5,r6)
182         save_misaligned_vmx(v29,v28,v0,v3,r6,r5)
183         save_misaligned_vmx(v30,v29,v0,v3,r5,r6)
184         save_misaligned_vmx(v31,v30,v0,v3,r6,r5)
185         /* load and rotate data above v31 */
186         lvx     v2,0,r6
187         vperm   v2,v2,v2,v1
188         save_misaligned_vmx(v2,v31,v0,v3,r5,r6)
190         b       L(no_vmx)
192 L(aligned_save_vmx):
193         stvx    20,0,r5
194         addi    r5,r5,32
195         stvx    21,0,r6
196         addi    r6,r6,32
197         stvx    22,0,r5
198         addi    r5,r5,32
199         stvx    23,0,r6
200         addi    r6,r6,32
201         stvx    24,0,r5
202         addi    r5,r5,32
203         stvx    25,0,r6
204         addi    r6,r6,32
205         stvx    26,0,r5
206         addi    r5,r5,32
207         stvx    27,0,r6
208         addi    r6,r6,32
209         stvx    28,0,r5
210         addi    r5,r5,32
211         stvx    29,0,r6
212         addi    r6,r6,32
213         stvx    30,0,r5
214         stvx    31,0,r6
215 L(no_vmx):
216 #else
217         li      r6,0
218 #endif
219 #if IS_IN (rtld)
220         li      r3,0
221         blr
222 #elif defined SHARED
223         b       JUMPTARGET (NOTOC (__sigjmp_save_symbol))
224 #else
225         mflr    r0
226         std     r0,FRAME_LR_SAVE(r1)
227         stdu    r1,-FRAME_MIN_SIZE(r1)
228         cfi_adjust_cfa_offset(FRAME_MIN_SIZE)
229         cfi_offset(lr,FRAME_LR_SAVE)
230         bl      JUMPTARGET (__sigjmp_save_symbol)
231         nop
232         ld      r0,FRAME_MIN_SIZE+FRAME_LR_SAVE(r1)
233         addi    r1,r1,FRAME_MIN_SIZE
234         mtlr    r0
235         blr
236 #endif
237 END (__sigsetjmp_symbol)
239 #if defined SHARED && !IS_IN (rtld) && !defined __NO_VMX__
240 /* When called from within libc we need a special version of __sigsetjmp
241    that saves r2 since the call won't go via a plt call stub.  See
242    bugz #269.  */
243 ENTRY (__GI___sigsetjmp)
244         std r2,FRAME_TOC_SAVE(r1) /* Save the callers TOC in the save area.  */
245         CALL_MCOUNT 1
246         b JUMPTARGET (GLUE(__sigsetjmp_symbol,_ent))
247 END (__GI___sigsetjmp)
248 #endif