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