PowerPC: Enable POWER8 platform sans hwcap bits.
[glibc.git] / sysdeps / powerpc / powerpc64 / setjmp-common.S
blobbf8bb76f980679629fbafbb5685e8486b95beaf6
1 /* setjmp for PowerPC64.
2    Copyright (C) 1995-2012 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 #define _ASM
21 #ifdef __NO_VMX__
22 #include <novmxsetjmp.h>
23 #else
24 #include <jmpbuf-offsets.h>
25 #endif
26 #include <bp-sym.h>
27 #include <bp-asm.h>
29 #ifndef __NO_VMX__
30         .section        ".toc","aw"
31 .LC__dl_hwcap:
32 # ifdef SHARED
33 #  ifdef 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)
48         CALL_MCOUNT 1
49         li r4,1                 /* Set second argument to 1.  */
50         b JUMPTARGET (GLUE(__sigsetjmp,_ent))
51 END (setjmp)
53 #if defined SHARED && !defined 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 (BP_SYM (__GI__setjmp))
59         std r2,40(r1)           /* Save the callers TOC in the save area.  */
60         cfi_endproc
61 END_2 (BP_SYM (__GI__setjmp))
62 /* Fall thru. */
63 #endif
65 ENTRY (BP_SYM (_setjmp))
66         CALL_MCOUNT 1
67         li r4,0                 /* Set second argument to 0.  */
68         b JUMPTARGET (GLUE(__sigsetjmp,_ent))
69 END (BP_SYM (_setjmp))
70 libc_hidden_def (_setjmp)
72 ENTRY (BP_SYM (__sigsetjmp))
73         CALL_MCOUNT 2
74 JUMPTARGET(GLUE(__sigsetjmp,_ent)):
75         CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
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 && !defined IS_IN_rtld
85         ld   r5,40(r1)  /* Retrieve the callers TOC.  */
86         std  r5,(JB_GPR2*8)(3)
87 #else
88         std  r2,(JB_GPR2*8)(3)
89 #endif
90         std  r14,((JB_GPRS+0)*8)(3)
91         stfd fp14,((JB_FPRS+0)*8)(3)
92 #ifdef PTR_MANGLE
93         PTR_MANGLE2 (r0, r6)
94 #endif
95         std  r0,(JB_LR*8)(3)
96         std  r15,((JB_GPRS+1)*8)(3)
97         stfd fp15,((JB_FPRS+1)*8)(3)
98         mfcr r0
99         std  r16,((JB_GPRS+2)*8)(3)
100         stfd fp16,((JB_FPRS+2)*8)(3)
101         std  r0,(JB_CR*8)(3)
102         std  r17,((JB_GPRS+3)*8)(3)
103         stfd fp17,((JB_FPRS+3)*8)(3)
104         std  r18,((JB_GPRS+4)*8)(3)
105         stfd fp18,((JB_FPRS+4)*8)(3)
106         std  r19,((JB_GPRS+5)*8)(3)
107         stfd fp19,((JB_FPRS+5)*8)(3)
108         std  r20,((JB_GPRS+6)*8)(3)
109         stfd fp20,((JB_FPRS+6)*8)(3)
110         std  r21,((JB_GPRS+7)*8)(3)
111         stfd fp21,((JB_FPRS+7)*8)(3)
112         std  r22,((JB_GPRS+8)*8)(3)
113         stfd fp22,((JB_FPRS+8)*8)(3)
114         std  r23,((JB_GPRS+9)*8)(3)
115         stfd fp23,((JB_FPRS+9)*8)(3)
116         std  r24,((JB_GPRS+10)*8)(3)
117         stfd fp24,((JB_FPRS+10)*8)(3)
118         std  r25,((JB_GPRS+11)*8)(3)
119         stfd fp25,((JB_FPRS+11)*8)(3)
120         std  r26,((JB_GPRS+12)*8)(3)
121         stfd fp26,((JB_FPRS+12)*8)(3)
122         std  r27,((JB_GPRS+13)*8)(3)
123         stfd fp27,((JB_FPRS+13)*8)(3)
124         std  r28,((JB_GPRS+14)*8)(3)
125         stfd fp28,((JB_FPRS+14)*8)(3)
126         std  r29,((JB_GPRS+15)*8)(3)
127         stfd fp29,((JB_FPRS+15)*8)(3)
128         std  r30,((JB_GPRS+16)*8)(3)
129         stfd fp30,((JB_FPRS+16)*8)(3)
130         std  r31,((JB_GPRS+17)*8)(3)
131         stfd fp31,((JB_FPRS+17)*8)(3)
132 #ifndef __NO_VMX__
133         ld    r6,.LC__dl_hwcap@toc(r2)
134 # ifdef SHARED
135         /* Load _rtld-global._dl_hwcap.  */
136         ld    r6,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r6)
137 # else
138         ld    r6,0(r6) /* Load extern _dl_hwcap.  */
139 # endif
140         andis.  r6,r6,(PPC_FEATURE_HAS_ALTIVEC >> 16)
141         beq     L(no_vmx)
142         la      r5,((JB_VRS)*8)(3)
143         andi.   r6,r5,0xf
144         mfspr   r0,VRSAVE
145         stw     r0,((JB_VRSAVE)*8)(3)
146         addi    r6,r5,16
147         beq+    L(aligned_save_vmx)
148         lvsr    v0,0,r5
149         vspltisb v1,-1         /* set v1 to all 1's */
150         vspltisb v2,0          /* set v2 to all 0's */
151         vperm   v3,v2,v1,v0   /* v3 contains shift mask with num all 1 bytes
152                                  on left = misalignment  */
155         /* Special case for v20 we need to preserve what is in save area
156            below v20 before obliterating it */
157         lvx     v5,0,r5
158         vperm   v20,v20,v20,v0
159         vsel    v5,v5,v20,v3
160         vsel    v20,v20,v2,v3
161         stvx    v5,0,r5
163 # define save_2vmx_partial(savevr,prev_savevr,hivr,shiftvr,maskvr,savegpr,addgpr) \
164         addi    addgpr,addgpr,32; \
165         vperm   savevr,savevr,savevr,shiftvr; \
166         vsel    hivr,prev_savevr,savevr,maskvr; \
167         stvx    hivr,0,savegpr;
169         save_2vmx_partial(v21,v20,v5,v0,v3,r6,r5)
170         save_2vmx_partial(v22,v21,v5,v0,v3,r5,r6)
171         save_2vmx_partial(v23,v22,v5,v0,v3,r6,r5)
172         save_2vmx_partial(v24,v23,v5,v0,v3,r5,r6)
173         save_2vmx_partial(v25,v24,v5,v0,v3,r6,r5)
174         save_2vmx_partial(v26,v25,v5,v0,v3,r5,r6)
175         save_2vmx_partial(v27,v26,v5,v0,v3,r6,r5)
176         save_2vmx_partial(v28,v27,v5,v0,v3,r5,r6)
177         save_2vmx_partial(v29,v28,v5,v0,v3,r6,r5)
178         save_2vmx_partial(v30,v29,v5,v0,v3,r5,r6)
180         /* Special case for r31 we need to preserve what is in save area
181            above v31 before obliterating it */
182         addi    r5,r5,32
183         vperm   v31,v31,v31,v0
184         lvx     v4,0,r5
185         vsel    v5,v30,v31,v3
186         stvx    v5,0,r6
187         vsel    v4,v31,v4,v3
188         stvx    v4,0,r5
189         b       L(no_vmx)
191 L(aligned_save_vmx):
192         stvx    20,0,r5
193         addi    r5,r5,32
194         stvx    21,0,r6
195         addi    r6,r6,32
196         stvx    22,0,r5
197         addi    r5,r5,32
198         stvx    23,0,r6
199         addi    r6,r6,32
200         stvx    24,0,r5
201         addi    r5,r5,32
202         stvx    25,0,r6
203         addi    r6,r6,32
204         stvx    26,0,r5
205         addi    r5,r5,32
206         stvx    27,0,r6
207         addi    r6,r6,32
208         stvx    28,0,r5
209         addi    r5,r5,32
210         stvx    29,0,r6
211         addi    r6,r6,32
212         stvx    30,0,r5
213         stvx    31,0,r6
214 L(no_vmx):
215 #else
216         li      r6,0
217 #endif
218 #if defined NOT_IN_libc && defined IS_IN_rtld
219         li      r3,0
220         blr
221 #elif defined SHARED
222         b       JUMPTARGET (BP_SYM (__sigjmp_save))
223 #else
224         mflr    r0
225         std     r0,16(r1)
226         stdu    r1,-112(r1)
227         cfi_adjust_cfa_offset(112)
228         cfi_offset(lr,16)
229         bl      JUMPTARGET (BP_SYM (__sigjmp_save))
230         nop
231         ld      r0,112+16(r1)
232         addi    r1,r1,112
233         mtlr    r0
234         blr
235 #endif
236 END (BP_SYM (__sigsetjmp))