except.c (use_eh_context): Don't copy_rtx a REG.

* except.c (use_eh_context): Don't copy_rtx a REG.
	(emit_throw): Lose old unwinder support.
	(expand_internal_throw): Likewise.
	* libgcc2.c (struct eh_context): Likewise.
	(new_eh_context): Likewise.
	(__get_eh_info): Lose redundant cast.
	(__get_dynamic_handler_chain): Likewise.
	(__get_saved_pc): Lose.
	Lose all old unwinder support code.

	* decl2.c (finish_file): Lose call to expand_builtin_throw.
	* except.c (expand_builtin_throw): Remove.
	* cp-tree.h: Remove ptr_ptr_type_node.
	* decl.c: Likewise.

From-SVN: r17054
This commit is contained in:
Jason Merrill 1997-12-12 05:15:30 +00:00 committed by Jason Merrill
parent c404fea226
commit 0776059ee0
8 changed files with 26 additions and 419 deletions

View File

@ -1,3 +1,15 @@
Thu Dec 11 21:08:48 1997 Jason Merrill <jason@yorick.cygnus.com>
* except.c (use_eh_context): Don't copy_rtx a REG.
(emit_throw): Lose old unwinder support.
(expand_internal_throw): Likewise.
* libgcc2.c (struct eh_context): Likewise.
(new_eh_context): Likewise.
(__get_eh_info): Lose redundant cast.
(__get_dynamic_handler_chain): Likewise.
(__get_saved_pc): Lose.
Lose all old unwinder support code.
Thu Dec 11 20:42:18 1997 Teemu Torma <tot@trema.com>
Thread-safe EH support for pthreads, DCE threads and Solaris threads.

View File

@ -1,3 +1,10 @@
Thu Dec 11 21:12:09 1997 Jason Merrill <jason@yorick.cygnus.com>
* decl2.c (finish_file): Lose call to expand_builtin_throw.
* except.c (expand_builtin_throw): Remove.
* cp-tree.h: Remove ptr_ptr_type_node.
* decl.c: Likewise.
Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com>
* decl.c (ptr_ptr_type_node): Define.

View File

@ -1511,7 +1511,7 @@ extern tree vt_off_identifier;
/* A node that is a list (length 1) of error_mark_nodes. */
extern tree error_mark_list;
extern tree ptr_type_node, ptr_ptr_type_node;
extern tree ptr_type_node;
extern tree class_type_node, record_type_node, union_type_node, enum_type_node;
extern tree unknown_type_node;
extern tree opaque_type_node, signature_type_node;

View File

@ -241,10 +241,6 @@ tree void_zero_node;
tree ptr_type_node;
tree const_ptr_type_node;
/* Node for type `void **'. */
tree ptr_ptr_type_node;
/* Nodes for types `char *' and `const char *'. */
tree string_type_node, const_string_type_node;
@ -5069,7 +5065,6 @@ init_decl_processing ()
ptr_type_node = build_pointer_type (void_type_node);
const_ptr_type_node
= build_pointer_type (build_type_variant (void_type_node, 1, 0));
ptr_ptr_type_node = build_pointer_type (ptr_type_node);
#if 0
record_builtin_type (RID_MAX, NULL_PTR, ptr_type_node);
#endif

View File

@ -3166,8 +3166,6 @@ finish_file ()
assemble_constructor (IDENTIFIER_POINTER (fnname));
}
expand_builtin_throw ();
permanent_allocation (1);
/* Done with C language context needs. */

View File

@ -185,10 +185,6 @@ static tree Unwind;
========================================================================= */
#ifndef DWARF2_UNWIND_INFO
extern int throw_used;
#endif
extern rtx catch_clauses;
extern tree const_ptr_type_node;
@ -734,224 +730,6 @@ do_unwind (inner_throw_label)
}
/* Is called from expand_exception_blocks to generate the code in a function
to "throw" if anything in the function needs to perform a throw.
expands "throw" as the following pseudo code:
throw:
eh = find_first_exception_match (saved_pc);
if (!eh) goto gotta_rethrow_it;
goto eh;
gotta_rethrow_it:
saved_pc = __builtin_return_address (0);
pop_to_previous_level ();
goto throw; */
void
expand_builtin_throw ()
{
#ifndef DWARF2_UNWIND_INFO
tree fcall;
tree params;
rtx handler;
rtx saved_pcnthrow;
rtx next_pc;
rtx gotta_rethrow_it;
rtx gotta_call_terminate;
rtx after_unwind;
rtx top_of_loop;
tree t;
rtx x;
if (! doing_eh (0))
return;
if (! throw_used)
return;
params = void_list_node;
t = make_call_declarator (get_identifier ("__throw"), params, NULL_TREE,
NULL_TREE);
start_function (decl_tree_cons (NULL_TREE,
get_identifier ("void"),
decl_tree_cons (NULL_TREE,
get_identifier ("static"),
NULL_TREE)),
t, NULL_TREE, 0);
store_parm_decls ();
pushlevel (0);
clear_last_expr ();
push_momentary ();
expand_start_bindings (0);
gotta_rethrow_it = gen_label_rtx ();
gotta_call_terminate = gen_label_rtx ();
/* These two can be frontend specific. If wanted, they can go in
expand_throw. */
/* Do we have a valid object we are throwing? */
t = call_eh_info ();
emit_cmp_insn (expand_expr (t, NULL_RTX, Pmode, 0),
const0_rtx, EQ, NULL_RTX,
GET_MODE (DECL_RTL (t)), 0, 0);
emit_jump_insn (gen_beq (gotta_call_terminate));
/* search for an exception handler for the saved_pc */
handler = do_function_call (FirstExceptionMatch,
expr_tree_cons (NULL_TREE,
make_tree (ptr_ptr_type_node,
get_saved_pc_ref ()),
NULL_TREE),
ptr_type_node);
/* did we find one? */
emit_cmp_insn (handler, const0_rtx, EQ, NULL_RTX,
GET_MODE (handler), 0, 0);
/* if not, jump to gotta_rethrow_it */
emit_jump_insn (gen_beq (gotta_rethrow_it));
{
rtx ret_val, x;
ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
0, hard_frame_pointer_rtx);
/* Set it up so that we continue at the handler. */
emit_move_insn (ret_val, handler);
#ifdef RETURN_ADDR_OFFSET
x = plus_constant (ret_val, -RETURN_ADDR_OFFSET);
if (x != ret_val)
emit_move_insn (ret_val, x);
#endif
expand_null_return ();
}
top_of_loop = gen_label_rtx ();
emit_label (top_of_loop);
#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE
if (DONT_ACCESS_GBLS_AFTER_EPILOGUE)
{
saved_pcnthrow = gen_reg_rtx (Pmode);
emit_move_insn (saved_pcnthrow, hard_function_value (ptr_type_node,
NULL_TREE));
}
#endif
/* Call to __builtin_return_address. */
#if defined (ARM_FRAME_RTX) /* was __arm */
/* This should be moved into arm.h:RETURN_ADDR_RTX */
/* This replaces a 'call' to __builtin_return_address */
next_pc = gen_reg_rtx (Pmode);
emit_move_insn (next_pc,
gen_rtx (MEM, Pmode, plus_constant (hard_frame_pointer_rtx, -4)));
#else
params = expr_tree_cons (NULL_TREE, integer_zero_node, NULL_TREE);
fcall = build_function_call (builtin_return_address_fndecl, params);
next_pc = expand_expr (fcall, NULL_RTX, Pmode, 0);
#endif
/* Did __builtin_return_address return a valid address? */
emit_cmp_insn (next_pc, const0_rtx, EQ, NULL_RTX,
GET_MODE (next_pc), 0, 0);
emit_jump_insn (gen_beq (gotta_call_terminate));
next_pc = eh_outer_context (next_pc);
/* Yes it did. */
#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE
if (DONT_ACCESS_GBLS_AFTER_EPILOGUE)
{
rtx x;
x = validize_mem (gen_rtx (MEM, Pmode, saved_pcnthrow));
emit_move_insn (validize_mem (gen_rtx (MEM, Pmode, x)),
next_pc);
#ifdef FUNCTION_OUTGOING_VALUE
emit_move_insn (FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE),
validize_mem (gen_rtx (MEM, Pmode,
plus_constant (saved_pcnthrow,
GET_MODE_SIZE (Pmode)))));
emit_insn (gen_rtx (USE, VOIDmode,
FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE)));
#endif
}
else
#endif
emit_move_insn (get_saved_pc_ref (), next_pc);
after_unwind = gen_label_rtx ();
do_unwind (gen_rtx (LABEL_REF, Pmode, after_unwind));
emit_label (after_unwind);
#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE
if (DONT_ACCESS_GBLS_AFTER_EPILOGUE)
{
t = build_function_type (void_type_node, void_list_node);
t = make_tree (build_pointer_type (t),
hard_function_value (ptr_type_node,
NULL_TREE));
t = build_function_call (t, NULL_TREE);
expand_expr (t, const0_rtx, VOIDmode, 0);
}
else
#endif
emit_throw ();
/* no it didn't --> therefore we need to call terminate */
emit_label (gotta_call_terminate);
do_function_call (Terminate, NULL_TREE, NULL_TREE);
{
rtx ret_val, x;
/* code to deal with unwinding and looking for it again */
emit_label (gotta_rethrow_it);
ret_val = expand_builtin_return_addr (BUILT_IN_RETURN_ADDRESS,
0, hard_frame_pointer_rtx);
/* Set it up so that we continue inside, at the top of the loop. */
emit_move_insn (ret_val, gen_rtx (LABEL_REF, Pmode, top_of_loop));
#ifdef RETURN_ADDR_OFFSET
x = plus_constant (ret_val, -RETURN_ADDR_OFFSET);
if (x != ret_val)
emit_move_insn (ret_val, x);
#endif
#ifdef DONT_ACCESS_GBLS_AFTER_EPILOGUE
if (DONT_ACCESS_GBLS_AFTER_EPILOGUE)
{
rtx x = emit_library_call_value (gen_rtx (SYMBOL_REF, Pmode,
"__eh_pcnthrow"),
NULL_RTX, 1,
Pmode, 0);
/* This is to get a version of throw that will throw properly. */
emit_move_insn (validize_mem (gen_rtx (MEM, Pmode,
plus_constant (x, GET_MODE_SIZE (Pmode)))),
throw_libfunc);
#ifdef FUNCTION_OUTGOING_VALUE
emit_move_insn (FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE),
x);
emit_insn (gen_rtx (USE, VOIDmode, FUNCTION_OUTGOING_VALUE (ptr_type_node, NULL_TREE)));
#endif
}
#endif
/* Fall into epilogue to unwind prologue. */
}
expand_end_bindings (getdecls (), 1, 0);
poplevel (1, 0, 0);
pop_momentary ();
finish_function (lineno, 0, 0);
#endif /* DWARF2_UNWIND_INFO */
}
/* An exception spec is implemented more or less like:
try {

View File

@ -774,12 +774,12 @@ use_eh_context ()
insn = gen_rtx (USE,
GET_MODE (current_function_ehc),
copy_rtx (current_function_ehc));
current_function_ehc);
insn = emit_insn_before (insn, get_first_nonparm_insn ());
REG_NOTES (insn)
= gen_rtx (EXPR_LIST,
REG_EH_CONTEXT, copy_rtx (current_function_ehc),
REG_EH_CONTEXT, current_function_ehc,
REG_NOTES (insn));
}
return current_function_ehc;
@ -1272,10 +1272,6 @@ emit_throw ()
#ifdef JUMP_TO_THROW
emit_indirect_jump (throw_libfunc);
#else
#ifndef DWARF2_UNWIND_INFO
/* Prevent assemble_external from doing anything with this symbol. */
SYMBOL_REF_USED (throw_libfunc) = 1;
#endif
emit_library_call (throw_libfunc, 0, VOIDmode, 0);
#endif
throw_used = 1;
@ -1289,15 +1285,6 @@ emit_throw ()
void
expand_internal_throw ()
{
#ifndef DWARF2_UNWIND_INFO
if (! exceptions_via_longjmp)
{
rtx label = gen_label_rtx ();
emit_label (label);
label = gen_rtx (LABEL_REF, Pmode, label);
emit_move_insn (get_saved_pc_ref (), label);
}
#endif
emit_throw ();
}

View File

@ -3002,10 +3002,6 @@ __empty ()
struct eh_context
{
void **dynamic_handler_chain;
void *saved_pc;
#ifndef DWARF2_UNWIND_INFO
void *buf[2];
#endif
/* This is language dependent part of the eh context. */
void *info;
};
@ -3028,10 +3024,6 @@ new_eh_context ()
memset (eh, 0, sizeof *eh);
eh->dynamic_handler_chain = top_elt;
#ifndef DWARF2_UNWIND_INFO
eh->buf[0] = &eh->saved_pc;
eh->buf[1] = &__throw;
#endif
return eh;
}
@ -3073,7 +3065,7 @@ void **
__get_eh_info ()
{
struct eh_context *eh = (*get_eh_context) ();
return (void **) &eh->info;
return &eh->info;
}
#if __GTHREADS
@ -3158,14 +3150,7 @@ void ***
__get_dynamic_handler_chain ()
{
struct eh_context *eh = (*get_eh_context) ();
return (void ***) &eh->dynamic_handler_chain;
}
void **
__get_saved_pc ()
{
struct eh_context *eh = (*get_eh_context) ();
return (void **) &eh->saved_pc;
return &eh->dynamic_handler_chain;
}
/* This is used to throw an exception when the setjmp/longjmp codegen
@ -3364,162 +3349,7 @@ find_exception_handler (void *pc, exception_table *table)
}
#endif /* EH_TABLE_LOOKUP */
#ifndef DWARF2_UNWIND_INFO
/* Support code for exception handling using inline unwinders or
__unwind_function. */
void *__eh_pc;
#ifndef EH_TABLE_LOOKUP
typedef struct exception_table_node {
exception_table *table;
void *start;
void *end;
struct exception_table_node *next;
} exception_table_node;
static struct exception_table_node *exception_table_list;
void *
__find_first_exception_table_match (void *pc)
{
register exception_table_node *tnp;
for (tnp = exception_table_list; tnp != 0; tnp = tnp->next)
{
if (tnp->start <= pc && tnp->end >= pc)
return find_exception_handler (pc, tnp->table);
}
return (void *) 0;
}
void
__register_exceptions (exception_table *table)
{
exception_table_node *node;
exception_table *range = table + 1;
if (range->start == (void *) -1)
return;
node = (exception_table_node *) malloc (sizeof (exception_table_node));
node->table = table;
/* This look can be optimized away either if the table
is sorted, or if we pass in extra parameters. */
node->start = range->start;
node->end = range->end;
for (range++ ; range->start != (void *) (-1); range++)
{
if (range->start < node->start)
node->start = range->start;
if (range->end > node->end)
node->end = range->end;
}
node->next = exception_table_list;
exception_table_list = node;
}
#endif /* !EH_TABLE_LOOKUP */
/* Throw stub routine.
This is work in progress, but not completed yet. */
void
__throw ()
{
abort ();
}
/* See expand_builtin_throw for details. */
void **__eh_pcnthrow () {
struct eh_context *eh = (*get_eh_context) ();
return &eh->buf[0];
}
#if #machine(i386)
void
__unwind_function(void *ptr)
{
asm("movl 8(%esp),%ecx");
/* Undo current frame */
asm("movl %ebp,%esp");
asm("popl %ebp");
/* like ret, but stay here */
asm("addl $4,%esp");
/* Now, undo previous frame. */
/* This is a test routine, as we have to dynamically probe to find out
what to pop for certain, this is just a guess. */
asm("leal -16(%ebp),%esp");
asm("pop %ebx");
asm("pop %esi");
asm("pop %edi");
asm("movl %ebp,%esp");
asm("popl %ebp");
asm("movl %ecx,0(%esp)");
asm("ret");
}
#elif #machine(rs6000) && !defined _ARCH_PPC
__unwind_function(void *ptr)
{
asm("mr 31,1");
asm("l 1,0(1)");
asm("l 31,-4(1)");
asm("# br");
asm("mr 31,1");
asm("l 1,0(1)");
/* use 31 as a scratch register to restore the link register. */
asm("l 31, 8(1);mtlr 31 # l lr,8(1)");
asm("l 31,-4(1)");
asm("# br");
asm("mtctr 3;bctr # b 3");
}
#elif (#machine(rs6000) || #machine(powerpc)) && defined _ARCH_PPC
__unwind_function(void *ptr)
{
asm("mr 31,1");
asm("lwz 1,0(1)");
asm("lwz 31,-4(1)");
asm("# br");
asm("mr 31,1");
asm("lwz 1,0(1)");
/* use 31 as a scratch register to restore the link register. */
asm("lwz 31, 8(1);mtlr 31 # l lr,8(1)");
asm("lwz 31,-4(1)");
asm("# br");
asm("mtctr 3;bctr # b 3");
}
#elif #machine(vax)
__unwind_function(void *ptr)
{
__label__ return_again;
/* Replace our frame's return address with the label below.
During execution, we will first return here instead of to
caller, then second return takes caller's frame off the stack.
Two returns matches two actual calls, so is less likely to
confuse debuggers. `16' corresponds to RETURN_ADDRESS_OFFSET. */
__asm ("movl %0,16(fp)" : : "p" (&& return_again));
return;
return_again:
return;
}
#else
__unwind_function(void *ptr)
{
abort ();
}
#endif /* powerpc */
#else /* DWARF2_UNWIND_INFO */
#ifdef DWARF2_UNWIND_INFO
/* Support code for exception handling using static unwind information. */
#include "frame.h"
@ -3793,7 +3623,7 @@ label:
/* Epilogue: restore the handler frame's register values and return
to the stub. */
}
#endif /* !DWARF2_UNWIND_INFO */
#endif /* DWARF2_UNWIND_INFO */
#endif /* L_eh */