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.
5 * Copyright (C) 2004 Free Software Foundation, Inc.
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
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.)
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.
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.
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.
43 .non_lazy_symbol_pointer
44 L_has_vec$non_lazy_ptr:
45 .indirect_symbol __cpu_has_altivec
54 /* For static, "pretend" we have a non-lazy-pointer. */
56 L_has_vec$non_lazy_ptr:
57 .long __cpu_has_altivec
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.)
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.
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
79 .private_extern save_world
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)
114 /* set R12 pointing at Vector Reg save area */
116 /* allocate stack frame */
118 /* ...but return if HAS_VEC is zero */
120 /* Not forgetting to restore CR. */
125 /* We're saving Vector regs too. */
126 /* Restore CR from R0. No More Branches! */
129 /* We should really use VRSAVE to figure out which vector regs
130 we actually need to save and restore. Some other time :-/ */
157 /* VRsave lives at -224(R1) */
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.
165 USES: R0 R10 R11 R12 and R7 R8
166 RETURNS: C++ EH Data registers (R3 - R6.)
168 We now set up R7/R8 and jump to rest_world_eh_r7r8.
170 rest_world doesn't use the R10 stack adjust parameter, nor does it
171 pick up the R3-R6 exception handling stuff. */
173 .private_extern rest_world
175 /* Pickup previous SP */
182 .private_extern eh_rest_world_r10
184 /* Pickup previous SP */
188 /* pickup the C++ EH data regs (R3 - R6.) */
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.
200 USES: R0 R11 R12 [R7/R8]
201 RETURNS: C++ EH Data registers (R3 - R6.) */
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)
217 beq L.rest_world_fp_eh
218 /* restore VRsave and V20..V31 */
264 /* R8 is the exception-handler's address */
267 /* set SP to original value + R7 offset */