]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/gcc/config/rs6000/darwin-world.asm
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / gcc / config / rs6000 / darwin-world.asm
1 /*  This file contains the exception-handling save_world and
2  *  restore_world routines, which need to do a run-time check to see if
3  *  they should save and restore the vector registers.
4  *
5  *   Copyright (C) 2004 Free Software Foundation, Inc.
6  * 
7  * This file is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation; either version 2, or (at your option) any
10  * later version.
11  * 
12  * In addition to the permissions in the GNU General Public License, the
13  * Free Software Foundation gives you unlimited permission to link the
14  * compiled version of this file with other programs, and to distribute
15  * those programs without any restriction coming from the use of this
16  * file.  (The General Public License restrictions do apply in other
17  * respects; for example, they cover modification of the file, and
18  * distribution when not linked into another program.)
19  * 
20  * This file is distributed in the hope that it will be useful, but
21  * WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  * General Public License for more details.
24  * 
25  * You should have received a copy of the GNU General Public License
26  * along with this program; see the file COPYING.  If not, write to
27  * the Free Software Foundation, 51 Franklin Street, Fifth Floor,
28  * Boston, MA 02110-1301, USA.
29  * 
30  *  As a special exception, if you link this library with files
31  *  compiled with GCC to produce an executable, this does not cause the
32  *  resulting executable to be covered by the GNU General Public License.
33  *  This exception does not however invalidate any other reasons why the
34  *  executable file might be covered by the GNU General Public License.
35  */ 
36
37         .machine ppc7400
38 .data
39         .align 2
40
41 #ifdef __DYNAMIC__
42
43 .non_lazy_symbol_pointer
44 L_has_vec$non_lazy_ptr:
45         .indirect_symbol __cpu_has_altivec
46 #ifdef __ppc64__
47         .quad   0
48 #else
49         .long   0
50 #endif
51
52 #else
53
54 /* For static, "pretend" we have a non-lazy-pointer.  */
55
56 L_has_vec$non_lazy_ptr:
57         .long __cpu_has_altivec
58
59 #endif
60
61
62 .text
63         .align 2
64
65 /* save_world and rest_world save/restore F14-F31 and possibly V20-V31
66    (assuming you have a CPU with vector registers; we use a global var
67    provided by the System Framework to determine this.)
68
69    SAVE_WORLD takes R0 (the caller`s caller`s return address) and R11
70    (the stack frame size) as parameters.  It returns VRsave in R0 if
71    we`re on a CPU with vector regs.
72
73    With gcc3, we now need to save and restore CR as well, since gcc3's
74    scheduled prologs can cause comparisons to be moved before calls to
75    save_world!
76
77    USES: R0 R11 R12  */
78
79 .private_extern save_world
80 save_world:
81         stw r0,8(r1)
82         mflr r0
83         bcl 20,31,Ls$pb
84 Ls$pb:  mflr r12
85         addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Ls$pb)
86         lwz r12,lo16(L_has_vec$non_lazy_ptr-Ls$pb)(r12)
87         mtlr r0
88         lwz r12,0(r12)
89                                 /* grab CR  */
90         mfcr r0 
91                                 /* test HAS_VEC  */
92         cmpwi r12,0
93         stfd f14,-144(r1)
94         stfd f15,-136(r1)
95         stfd f16,-128(r1)
96         stfd f17,-120(r1)
97         stfd f18,-112(r1)
98         stfd f19,-104(r1)
99         stfd f20,-96(r1)
100         stfd f21,-88(r1)
101         stfd f22,-80(r1)
102         stfd f23,-72(r1)
103         stfd f24,-64(r1)
104         stfd f25,-56(r1)
105         stfd f26,-48(r1)
106         stfd f27,-40(r1)
107         stfd f28,-32(r1)
108         stfd f29,-24(r1)
109         stfd f30,-16(r1)
110         stfd f31,-8(r1)
111         stmw r13,-220(r1)
112                                 /* stash CR  */
113         stw r0,4(r1)
114                                 /* set R12 pointing at Vector Reg save area  */
115         addi r12,r1,-224
116                                 /* allocate stack frame  */
117         stwux r1,r1,r11
118                                 /* ...but return if HAS_VEC is zero   */
119         bne+ L$saveVMX
120                                 /* Not forgetting to restore CR.  */
121         mtcr r0
122         blr
123
124 L$saveVMX:
125                                 /* We're saving Vector regs too.  */
126                                 /* Restore CR from R0.  No More Branches!  */
127         mtcr r0
128
129         /* We should really use VRSAVE to figure out which vector regs
130            we actually need to save and restore.  Some other time :-/  */
131
132         li r11,-192
133         stvx v20,r11,r12
134         li r11,-176
135         stvx v21,r11,r12
136         li r11,-160
137         stvx v22,r11,r12
138         li r11,-144
139         stvx v23,r11,r12
140         li r11,-128
141         stvx v24,r11,r12
142         li r11,-112
143         stvx v25,r11,r12
144         li r11,-96
145         stvx v26,r11,r12
146         li r11,-80
147         stvx v27,r11,r12
148         li r11,-64
149         stvx v28,r11,r12
150         li r11,-48
151         stvx v29,r11,r12
152         li r11,-32
153         stvx v30,r11,r12
154         mfspr r0,VRsave
155         li r11,-16
156         stvx v31,r11,r12
157                                 /* VRsave lives at -224(R1)  */
158         stw r0,0(r12)
159         blr
160
161
162 /* eh_rest_world_r10 is jumped to, not called, so no need to worry about LR.
163    R10 is the C++ EH stack adjust parameter, we return to the caller`s caller.
164
165    USES: R0 R10 R11 R12   and R7 R8
166    RETURNS: C++ EH Data registers (R3 - R6.)
167
168    We now set up R7/R8 and jump to rest_world_eh_r7r8.
169
170    rest_world doesn't use the R10 stack adjust parameter, nor does it
171    pick up the R3-R6 exception handling stuff.  */
172
173 .private_extern rest_world
174 rest_world:
175                                 /* Pickup previous SP  */
176         lwz r11, 0(r1)
177         li r7, 0
178         lwz r8, 8(r11)
179         li r10, 0
180         b rest_world_eh_r7r8
181
182 .private_extern eh_rest_world_r10
183 eh_rest_world_r10:
184                                 /* Pickup previous SP  */
185         lwz r11, 0(r1)
186         mr  r7,r10
187         lwz r8, 8(r11)
188                         /* pickup the C++ EH data regs (R3 - R6.)  */
189         lwz r6,-420(r11)
190         lwz r5,-424(r11)
191         lwz r4,-428(r11)
192         lwz r3,-432(r11)
193
194         b rest_world_eh_r7r8
195
196 /* rest_world_eh_r7r8 is jumped to -- not called! -- when we're doing
197    the exception-handling epilog.  R7 contains the offset to add to
198    the SP, and R8 contains the 'real' return address.
199
200    USES: R0 R11 R12  [R7/R8]
201    RETURNS: C++ EH Data registers (R3 - R6.)  */
202
203 rest_world_eh_r7r8:
204         bcl 20,31,Lr7r8$pb
205 Lr7r8$pb: mflr r12
206         lwz r11,0(r1)
207                                 /* R11 := previous SP  */
208         addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Lr7r8$pb)
209         lwz r12,lo16(L_has_vec$non_lazy_ptr-Lr7r8$pb)(r12)
210         lwz r0,4(r11)
211                                 /* R0 := old CR  */
212         lwz r12,0(r12)
213                                 /* R12 := HAS_VEC  */
214         mtcr r0 
215         cmpwi r12,0
216         lmw r13,-220(r11)
217         beq L.rest_world_fp_eh
218                                 /* restore VRsave and V20..V31  */
219         lwz r0,-224(r11)
220         li r12,-416
221         mtspr VRsave,r0
222         lvx v20,r11,r12
223         li r12,-400
224         lvx v21,r11,r12
225         li r12,-384
226         lvx v22,r11,r12
227         li r12,-368
228         lvx v23,r11,r12
229         li r12,-352
230         lvx v24,r11,r12
231         li r12,-336
232         lvx v25,r11,r12
233         li r12,-320
234         lvx v26,r11,r12
235         li r12,-304
236         lvx v27,r11,r12
237         li r12,-288
238         lvx v28,r11,r12
239         li r12,-272
240         lvx v29,r11,r12
241         li r12,-256
242         lvx v30,r11,r12
243         li r12,-240
244         lvx v31,r11,r12
245
246 L.rest_world_fp_eh:
247         lfd f14,-144(r11)
248         lfd f15,-136(r11)
249         lfd f16,-128(r11)
250         lfd f17,-120(r11)
251         lfd f18,-112(r11)
252         lfd f19,-104(r11)
253         lfd f20,-96(r11)
254         lfd f21,-88(r11)
255         lfd f22,-80(r11)
256         lfd f23,-72(r11)
257         lfd f24,-64(r11)
258         lfd f25,-56(r11)
259         lfd f26,-48(r11)
260         lfd f27,-40(r11)
261         lfd f28,-32(r11)
262         lfd f29,-24(r11)
263         lfd f30,-16(r11)
264                         /* R8 is the exception-handler's address  */
265         mtctr r8
266         lfd f31,-8(r11)
267                         /* set SP to original value + R7 offset  */
268         add r1,r11,r7
269         bctr