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