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, 2009 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 3, or (at your option) any
12 * This file is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * Under Section 7 of GPL version 3, you are granted additional
18 * permissions described in the GCC Runtime Library Exception, version
19 * 3.1, as published by the Free Software Foundation.
21 * You should have received a copy of the GNU General Public License and
22 * a copy of the GCC Runtime Library Exception along with this program;
23 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 * <http://www.gnu.org/licenses/>.
33 .non_lazy_symbol_pointer
34 L_has_vec$non_lazy_ptr:
35 .indirect_symbol __cpu_has_altivec
44 /* For static, "pretend" we have a non-lazy-pointer. */
46 L_has_vec$non_lazy_ptr:
47 .long __cpu_has_altivec
55 /* save_world and rest_world save/restore F14-F31 and possibly V20-V31
56 (assuming you have a CPU with vector registers; we use a global var
57 provided by the System Framework to determine this.)
59 SAVE_WORLD takes R0 (the caller`s caller`s return address) and R11
60 (the stack frame size) as parameters. It returns VRsave in R0 if
61 we`re on a CPU with vector regs.
63 With gcc3, we now need to save and restore CR as well, since gcc3's
64 scheduled prologs can cause comparisons to be moved before calls to
69 .private_extern save_world
75 addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Ls$pb)
76 lwz r12,lo16(L_has_vec$non_lazy_ptr-Ls$pb)(r12)
104 /* set R12 pointing at Vector Reg save area */
106 /* allocate stack frame */
108 /* ...but return if HAS_VEC is zero */
110 /* Not forgetting to restore CR. */
115 /* We're saving Vector regs too. */
116 /* Restore CR from R0. No More Branches! */
119 /* We should really use VRSAVE to figure out which vector regs
120 we actually need to save and restore. Some other time :-/ */
147 /* VRsave lives at -224(R1) */
152 /* eh_rest_world_r10 is jumped to, not called, so no need to worry about LR.
153 R10 is the C++ EH stack adjust parameter, we return to the caller`s caller.
155 USES: R0 R10 R11 R12 and R7 R8
156 RETURNS: C++ EH Data registers (R3 - R6.)
158 We now set up R7/R8 and jump to rest_world_eh_r7r8.
160 rest_world doesn't use the R10 stack adjust parameter, nor does it
161 pick up the R3-R6 exception handling stuff. */
163 .private_extern rest_world
165 /* Pickup previous SP */
172 .private_extern eh_rest_world_r10
174 /* Pickup previous SP */
178 /* pickup the C++ EH data regs (R3 - R6.) */
186 /* rest_world_eh_r7r8 is jumped to -- not called! -- when we're doing
187 the exception-handling epilog. R7 contains the offset to add to
188 the SP, and R8 contains the 'real' return address.
190 USES: R0 R11 R12 [R7/R8]
191 RETURNS: C++ EH Data registers (R3 - R6.) */
197 /* R11 := previous SP */
198 addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Lr7r8$pb)
199 lwz r12,lo16(L_has_vec$non_lazy_ptr-Lr7r8$pb)(r12)
207 beq L.rest_world_fp_eh
208 /* restore VRsave and V20..V31 */
254 /* R8 is the exception-handler's address */
257 /* set SP to original value + R7 offset */