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 */