summaryrefslogtreecommitdiff
path: root/gcc/libgcc2.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2000-08-08 09:08:55 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2000-08-08 09:08:55 +0000
commit70009d12bcfeaf2f2e2a61e66aaa31dd575b4d30 (patch)
treea56e49b5ea637aa6a95652c40bb2747a9110ca5d /gcc/libgcc2.c
parent5490c1ec0c96ff8638d4b622a6acb3dbd86e40bf (diff)
downloadgcc-70009d12bcfeaf2f2e2a61e66aaa31dd575b4d30.tar.gz
* frame.h (ia64_frame_state): Add my_psp.
* libgcc2.c (ia64_throw_helper): Add throw_sp argument. (__throw): Pass it in. Don't clobber r7. * config/ia64/frame-ia64.c (init_ia64_reg_loc): Mark inline. (execute_one_ia64_descriptor) [mem_stack_v]: Sets psp.when and nothing to do with sp. (normalize_reg_loc): Use frame->my_psp. (frame_translate): Handle frame-pointer-less functions. Set spill_base correctly, in absence of being told. (__build_ia64_frame_state): New sp argument. Fill in frame->my_sp. (__ia64_backtrace_helper): New sp argument. Use builtin_return_address instead of label addresses. (print_record) [mem_stack_v]: No size member. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@35565 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/libgcc2.c')
-rw-r--r--gcc/libgcc2.c33
1 files changed, 16 insertions, 17 deletions
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index 6403676adb4..61633861381 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -4046,10 +4046,8 @@ __ia64_personality_v1 (void *pc, old_exception_table *table)
}
static void
-ia64_throw_helper (throw_frame, caller, throw_bsp)
- ia64_frame_state *throw_frame;
- ia64_frame_state *caller;
- void *throw_bsp;
+ia64_throw_helper (ia64_frame_state *throw_frame, ia64_frame_state *caller,
+ void *throw_bsp, void *throw_sp)
{
void *throw_pc = __builtin_return_address (0);
unwind_info_ptr *info;
@@ -4061,7 +4059,8 @@ ia64_throw_helper (throw_frame, caller, throw_bsp)
__builtin_ia64_flushrs (); /* Make the local register stacks available. */
/* Start at our stack frame, get our state. */
- __build_ia64_frame_state (throw_pc, throw_frame, throw_bsp, &pc_base);
+ __build_ia64_frame_state (throw_pc, throw_frame, throw_bsp, throw_sp,
+ &pc_base);
/* Now we have to find the proper frame for pc, and see if there
is a handler for it. if not, we keep going back frames until
@@ -4078,8 +4077,10 @@ ia64_throw_helper (throw_frame, caller, throw_bsp)
/* We only care about the RP right now, so we dont need to keep
any other information about a call frame right now. */
pc = __get_real_reg_value (&caller->rp) - 1;
- bsp = __calc_caller_bsp ((long)__get_real_reg_value (&caller->pfs), caller->my_bsp);
- info = __build_ia64_frame_state (pc, caller, bsp, &pc_base);
+ bsp = __calc_caller_bsp ((long)__get_real_reg_value (&caller->pfs),
+ caller->my_bsp);
+ info = __build_ia64_frame_state (pc, caller, bsp, caller->my_psp,
+ &pc_base);
/* If we couldn't find the next frame, we lose. */
if (! info)
@@ -4099,7 +4100,7 @@ ia64_throw_helper (throw_frame, caller, throw_bsp)
}
if (!handler)
- __terminate ();
+ __terminate ();
/* Handler is a segment relative address, so we must adjust it here. */
handler += (long) pc_base;
@@ -4116,8 +4117,9 @@ ia64_throw_helper (throw_frame, caller, throw_bsp)
for ( ; frame_count > 0; frame_count--)
{
pc = __get_real_reg_value (&caller->rp) - 1;
- bsp = __calc_caller_bsp ((long)__get_real_reg_value (&caller->pfs), caller->my_bsp);
- __build_ia64_frame_state (pc, caller, bsp, &pc_base);
+ bsp = __calc_caller_bsp ((long)__get_real_reg_value (&caller->pfs),
+ caller->my_bsp);
+ __build_ia64_frame_state (pc, caller, bsp, caller->my_psp, &pc_base);
/* Any regs that were saved can be put in the throw frame now. */
/* We don't want to copy any saved register from the
target destination, but we do want to load up it's frame. */
@@ -4130,12 +4132,13 @@ ia64_throw_helper (throw_frame, caller, throw_bsp)
/* TODO, do we need to do anything to make the values we wrote 'stick'? */
/* DO we need to go through the whole loadrs seqeunce? */
-
}
+
void
__throw ()
{
+ register void *stack_pointer __asm__("r12");
struct eh_context *eh = (*get_eh_context) ();
ia64_frame_state my_frame;
ia64_frame_state originator; /* For the context handler is in. */
@@ -4149,6 +4152,7 @@ __throw ()
__terminate ();
__builtin_unwind_init ();
+
/* We have to call another routine to actually process the frame
information, which will force all of __throw's local registers into
backing store. */
@@ -4156,7 +4160,7 @@ __throw ()
/* Get the value of ar.bsp while we're here. */
bsp = __builtin_ia64_bsp ();
- ia64_throw_helper (&my_frame, &originator, bsp);
+ ia64_throw_helper (&my_frame, &originator, bsp, stack_pointer);
/* Now we have to fudge the bsp by the amount in our (__throw)
frame marker, since the return is going to adjust it by that much. */
@@ -4166,11 +4170,6 @@ __throw ()
offset = (char *)my_frame.my_bsp - (char *)tmp_bsp;
tmp_bsp = (char *)originator.my_bsp + offset;
- /* A throw handler is trated like a non-local goto, which is architeched
- to set the FP (or PSP) in r7 before branching. gr[0-3] map to
- r4-r7, so we want gr[3]. */
- __set_real_reg_value (&my_frame.gr[3], __get_real_reg_value (&originator.psp));
-
__builtin_eh_return (tmp_bsp, offset, originator.my_sp);
/* The return address was already set by throw_helper. */