Commit a1622f83 by Andrew MacLeod Committed by Andrew Macleod

[multiple changes]

Thu Jun  8 14:16:15 EDT 1998  Andrew MacLeod  <amacleod@cygnus.com>
	* eh-common.h: Remove NEW_EH_MODEL compile time flag, and replace with
	flag_new_exceptions runtime flag.
	(struct old_exception_table): New struct which represents what
	the exception table looks like without the new model.
	(NEW_EH_RUNTIME): New value used as a tag in the exception table to
	flag that this is a new style table.
	* except.h: Remove compile time flag NEW_EH_MODEL.
	(expand_builtin_eh_stub_old): New prototype.
	* tree.h (enum built_in_function): Add BUILT_IN_EH_STUB_OLD.
	* expr.c (expand_builtin): New builtin func BUILT_IN_EH_STUB_OLD.
	* c-decl.c (init_decl_processing): Add new builtin function
	__builtin_eh_stub_old.
	* final.c (final_scan_insn): Replace compile time flag NEW_EH_MODEL.
	* flags.h (flag_new_exceptions): New runtime flag.
	* toplev.c (flag_new_exceptions): Initialize default to 0,
	-fnew-exceptions sets to 1.
	* except.c (output_exception_table_entry): Output New style exception
	identifier into table, and replace compile time flag NEW_EH_MODEL
	with runtime flag flag_new_exceptions.
	(output_exception_table): Replace compile time flag NEW_EH_MODEL.
	(expand_builtin_eh_stub_old): Duplicates original functionality of
	expand_builtin_eh_stub.
	(expand_builtin_eh_stub): Replace compile time flag NEW_EH_MODEL.
	* libgcc2.c (find_exception_handler): Remove NEW_EH_MODEL #ifdefs.
	(old_find_exception_handler): New func, same as find_exception_handler
	except it works on the old style exception table.
	(__throw): Replace NEW_EH_MODEL. Detect new model based on presence
	of identifier in the exception table, and call appropriate routines.
1998-06-08  Andrew MacLeod  <amacleod@cygnus.com>
	* except.c (init_exception_processing): Remove NEW_EH_MODEL compile
	time flag.  Call __cp_eh_info instead of __cp_exception_info.
	* exception.cc (struct cp_eh_info): Remove NEW_EH_MODEL flag.
	(__cp_exception_info): Return offset into cp_eh_info structure to
	match what use to be the start of this structure.
	(__cp_eh_info): New function to return a pointer to cp_eh_info struct.
	(__cplus_type_matcher, __cp_push_exception): Remove NEW_EH_MODEL
	compile time flag.
	(__uncatch_exception, __check_eh_spec, std::uncaught_exception): Call
	__cp_eh_info instead of __cp_exception_info.

From-SVN: r20336
parent aeb302bb
Mon Jun 8 14:16:15 EDT 1998 Andrew MacLeod <amacleod@cygnus.com>
* eh-common.h: Remove NEW_EH_MODEL compile time flag, and replace with
flag_new_exceptions runtime flag.
(struct old_exception_table): New struct which represents what
the exception table looks like without the new model.
(NEW_EH_RUNTIME): New value used as a tag in the exception table to
flag that this is a new style table.
* except.h: Remove compile time flag NEW_EH_MODEL.
(expand_builtin_eh_stub_old): New prototype.
* tree.h (enum built_in_function): Add BUILT_IN_EH_STUB_OLD.
* expr.c (expand_builtin): New builtin func BUILT_IN_EH_STUB_OLD.
* c-decl.c (init_decl_processing): Add new builtin function
__builtin_eh_stub_old.
* final.c (final_scan_insn): Replace compile time flag NEW_EH_MODEL.
* flags.h (flag_new_exceptions): New runtime flag.
* toplev.c (flag_new_exceptions): Initialize default to 0,
-fnew-exceptions sets to 1.
* except.c (output_exception_table_entry): Output New style exception
identifier into table, and replace compile time flag NEW_EH_MODEL
with runtime flag flag_new_exceptions.
(output_exception_table): Replace compile time flag NEW_EH_MODEL.
(expand_builtin_eh_stub_old): Duplicates original functionality of
expand_builtin_eh_stub.
(expand_builtin_eh_stub): Replace compile time flag NEW_EH_MODEL.
* libgcc2.c (find_exception_handler): Remove NEW_EH_MODEL #ifdefs.
(old_find_exception_handler): New func, same as find_exception_handler
except it works on the old style exception table.
(__throw): Replace NEW_EH_MODEL. Detect new model based on presence
of identifier in the exception table, and call appropriate routines.
Mon Jun 8 01:21:13 1998 Jason Merrill <jason@yorick.cygnus.com> Mon Jun 8 01:21:13 1998 Jason Merrill <jason@yorick.cygnus.com>
* function.c: Define current_function_cannot_inline. * function.c: Define current_function_cannot_inline.
......
...@@ -3260,6 +3260,8 @@ init_decl_processing () ...@@ -3260,6 +3260,8 @@ init_decl_processing ()
ptr_type_node, ptr_type_node,
endlink)), endlink)),
BUILT_IN_SET_RETURN_ADDR_REG, NULL_PTR); BUILT_IN_SET_RETURN_ADDR_REG, NULL_PTR);
builtin_function ("__builtin_eh_stub_old", ptr_ftype_void,
BUILT_IN_EH_STUB_OLD, NULL_PTR);
builtin_function ("__builtin_eh_stub", ptr_ftype_void, builtin_function ("__builtin_eh_stub", ptr_ftype_void,
BUILT_IN_EH_STUB, NULL_PTR); BUILT_IN_EH_STUB, NULL_PTR);
builtin_function builtin_function
......
1998-06-08 Andrew MacLeod <amacleod@cygnus.com>
* except.c (init_exception_processing): Remove NEW_EH_MODEL compile
time flag. Call __cp_eh_info instead of __cp_exception_info.
* exception.cc (struct cp_eh_info): Remove NEW_EH_MODEL flag.
(__cp_exception_info): Return offset into cp_eh_info structure to
match what use to be the start of this structure.
(__cp_eh_info): New function to return a pointer to cp_eh_info struct.
(__cplus_type_matcher, __cp_push_exception): Remove NEW_EH_MODEL
compile time flag.
(__uncatch_exception, __check_eh_spec, std::uncaught_exception): Call
__cp_eh_info instead of __cp_exception_info.
1998-06-08 Jason Merrill <jason@yorick.cygnus.com> 1998-06-08 Jason Merrill <jason@yorick.cygnus.com>
* decl.c (cp_finish_decl): Disable inlining of extern inlines * decl.c (cp_finish_decl): Disable inlining of extern inlines
......
...@@ -203,10 +203,8 @@ init_exception_processing () ...@@ -203,10 +203,8 @@ init_exception_processing ()
push_lang_context (lang_name_c); push_lang_context (lang_name_c);
#ifdef NEW_EH_MODEL
set_exception_lang_code (EH_LANG_C_plus_plus); set_exception_lang_code (EH_LANG_C_plus_plus);
set_exception_version_code (1); set_exception_version_code (1);
#endif
CatchMatch CatchMatch
= builtin_function (flag_rtti = builtin_function (flag_rtti
...@@ -245,25 +243,20 @@ call_eh_info () ...@@ -245,25 +243,20 @@ call_eh_info ()
{ {
tree fn; tree fn;
fn = get_identifier ("__cp_exception_info"); fn = get_identifier ("__cp_eh_info");
if (IDENTIFIER_GLOBAL_VALUE (fn)) if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn); fn = IDENTIFIER_GLOBAL_VALUE (fn);
else else
{ {
#ifdef NEW_EH_MODEL tree t1, t, fields[7];
tree t1;
#endif
tree t, fields[7];
int fo = 0;
/* Declare cp_eh_info * __cp_exception_info (void), /* Declare cp_eh_info * __cp_eh_info (void),
as defined in exception.cc. */ as defined in exception.cc. */
push_obstacks_nochange (); push_obstacks_nochange ();
end_temporary_allocation (); end_temporary_allocation ();
/* struct cp_eh_info. This must match exception.cc. Note that this /* struct cp_eh_info. This must match exception.cc. Note that this
type is not pushed anywhere. */ type is not pushed anywhere. */
#ifdef NEW_EH_MODEL
t1= make_lang_type (RECORD_TYPE); t1= make_lang_type (RECORD_TYPE);
fields[0] = build_lang_field_decl (FIELD_DECL, fields[0] = build_lang_field_decl (FIELD_DECL,
get_identifier ("handler_label"), ptr_type_node); get_identifier ("handler_label"), ptr_type_node);
...@@ -288,31 +281,27 @@ call_eh_info () ...@@ -288,31 +281,27 @@ call_eh_info ()
/* N.B.: The fourth field LEN is expected to be /* N.B.: The fourth field LEN is expected to be
the number of fields - 1, not the total number of fields. */ the number of fields - 1, not the total number of fields. */
finish_builtin_type (t1, "__eh_info", fields, 3, ptr_type_node); finish_builtin_type (t1, "__eh_info", fields, 3, ptr_type_node);
fo = 1;
#endif
t = make_lang_type (RECORD_TYPE); t = make_lang_type (RECORD_TYPE);
#ifdef NEW_EH_MODEL fields[0] = build_lang_field_decl (FIELD_DECL,
fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("eh_info"), get_identifier ("eh_info"), t1);
t1); fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("value"),
#endif
fields[0+fo] = build_lang_field_decl (FIELD_DECL, get_identifier ("value"),
ptr_type_node); ptr_type_node);
fields[1+fo] = build_lang_field_decl (FIELD_DECL, get_identifier ("type"), fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("type"),
ptr_type_node); ptr_type_node);
fields[2+fo] = build_lang_field_decl fields[3] = build_lang_field_decl
(FIELD_DECL, get_identifier ("cleanup"), (FIELD_DECL, get_identifier ("cleanup"),
build_pointer_type (build_function_type build_pointer_type (build_function_type
(ptr_type_node, tree_cons (ptr_type_node, tree_cons
(NULL_TREE, ptr_type_node, void_list_node)))); (NULL_TREE, ptr_type_node, void_list_node))));
fields[3+fo] = build_lang_field_decl (FIELD_DECL, get_identifier ("caught"), fields[4] = build_lang_field_decl (FIELD_DECL, get_identifier ("caught"),
boolean_type_node); boolean_type_node);
fields[4+fo] = build_lang_field_decl (FIELD_DECL, get_identifier ("next"), fields[5] = build_lang_field_decl (FIELD_DECL, get_identifier ("next"),
build_pointer_type (t)); build_pointer_type (t));
fields[5+fo] = build_lang_field_decl fields[6] = build_lang_field_decl
(FIELD_DECL, get_identifier ("handlers"), long_integer_type_node); (FIELD_DECL, get_identifier ("handlers"), long_integer_type_node);
/* N.B.: The fourth field LEN is expected to be /* N.B.: The fourth field LEN is expected to be
the number of fields - 1, not the total number of fields. */ the number of fields - 1, not the total number of fields. */
finish_builtin_type (t, "cp_eh_info", fields, 5+fo, ptr_type_node); finish_builtin_type (t, "cp_eh_info", fields, 6, ptr_type_node);
t = build_pointer_type (t); t = build_pointer_type (t);
/* And now the function. */ /* And now the function. */
......
...@@ -86,9 +86,7 @@ std::unexpected () ...@@ -86,9 +86,7 @@ std::unexpected ()
struct cp_eh_info struct cp_eh_info
{ {
#ifdef NEW_EH_MODEL
__eh_info eh_info; __eh_info eh_info;
#endif
void *value; void *value;
void *type; void *type;
void (*cleanup)(void *, int); void (*cleanup)(void *, int);
...@@ -105,11 +103,23 @@ extern "C" cp_eh_info **__get_eh_info (); // actually void ** ...@@ -105,11 +103,23 @@ extern "C" cp_eh_info **__get_eh_info (); // actually void **
extern bool __is_pointer (void *); extern bool __is_pointer (void *);
/* OLD Compiler hook to return a pointer to the info for the current exception.
Used by get_eh_info (). This fudges the actualy returned value to
point to the beginning of what USE to be the cp_eh_info structure.
THis is so that old code that dereferences this pointer will find
things where it expects it to be.*/
extern "C" void *
__cp_exception_info (void)
{
return &((*__get_eh_info ())->value);
}
/* Compiler hook to return a pointer to the info for the current exception. /* Compiler hook to return a pointer to the info for the current exception.
Used by get_eh_info (). */ Used by get_eh_info (). */
extern "C" cp_eh_info * extern "C" cp_eh_info *
__cp_exception_info (void) __cp_eh_info (void)
{ {
return *__get_eh_info (); return *__get_eh_info ();
} }
...@@ -138,8 +148,6 @@ __eh_free (void *p) ...@@ -138,8 +148,6 @@ __eh_free (void *p)
} }
#ifdef NEW_EH_MODEL
typedef void * (* rtimetype) (void); typedef void * (* rtimetype) (void);
extern "C" void * extern "C" void *
...@@ -157,7 +165,6 @@ __cplus_type_matcher (cp_eh_info *info, exception_table *matching_info, ...@@ -157,7 +165,6 @@ __cplus_type_matcher (cp_eh_info *info, exception_table *matching_info,
ret = __throw_type_match_rtti (match_type, info->type, info->value); ret = __throw_type_match_rtti (match_type, info->type, info->value);
return ret; return ret;
} }
#endif
/* Compiler hook to push a new exception onto the stack. /* Compiler hook to push a new exception onto the stack.
...@@ -174,12 +181,10 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int)) ...@@ -174,12 +181,10 @@ __cp_push_exception (void *value, void *type, void (*cleanup)(void *, int))
p->handlers = 0; p->handlers = 0;
p->caught = false; p->caught = false;
#ifdef NEW_EH_MODEL
p->eh_info.match_function = __cplus_type_matcher; p->eh_info.match_function = __cplus_type_matcher;
p->eh_info.language = EH_LANG_C_plus_plus; p->eh_info.language = EH_LANG_C_plus_plus;
p->eh_info.version = 1; p->eh_info.version = 1;
p->eh_info.coerced_value = NULL; p->eh_info.coerced_value = NULL;
#endif
cp_eh_info **q = __get_eh_info (); cp_eh_info **q = __get_eh_info ();
...@@ -227,7 +232,7 @@ __cp_pop_exception (cp_eh_info *p) ...@@ -227,7 +232,7 @@ __cp_pop_exception (cp_eh_info *p)
extern "C" void extern "C" void
__uncatch_exception (void) __uncatch_exception (void)
{ {
cp_eh_info *p = __cp_exception_info (); cp_eh_info *p = __cp_eh_info ();
if (p == 0) if (p == 0)
terminate (); terminate ();
p->caught = false; p->caught = false;
...@@ -248,7 +253,7 @@ __uncatch_exception (void) ...@@ -248,7 +253,7 @@ __uncatch_exception (void)
extern "C" void extern "C" void
__check_eh_spec (int n, const void **spec) __check_eh_spec (int n, const void **spec)
{ {
cp_eh_info *p = __cp_exception_info (); cp_eh_info *p = __cp_eh_info ();
for (int i = 0; i < n; ++i) for (int i = 0; i < n; ++i)
{ {
...@@ -301,7 +306,7 @@ __throw_bad_typeid (void) ...@@ -301,7 +306,7 @@ __throw_bad_typeid (void)
bool bool
std::uncaught_exception () std::uncaught_exception ()
{ {
cp_eh_info *p = __cp_exception_info (); cp_eh_info *p = __cp_eh_info ();
return p && ! p->caught; return p && ! p->caught;
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
independant exception handling model. Both the static compiler and independant exception handling model. Both the static compiler and
the runtime library share this file. */ the runtime library share this file. */
/* The compiler flag NEW_EH_MODEL is used to determine whether the /* The runtime flag flag_new_exceptions is used to determine whether the
compiler supports the new runtime typechecking mechanism or not. Under compiler supports the new runtime typechecking mechanism or not. Under
the new model, runtime info is contained in the exception table, and the new model, runtime info is contained in the exception table, and
the __throw() library routine determines which handler to call based the __throw() library routine determines which handler to call based
...@@ -18,17 +18,6 @@ ...@@ -18,17 +18,6 @@
#include "gansidecl.h" #include "gansidecl.h"
#ifndef NEW_EH_MODEL
struct eh_context
{
void **dynamic_handler_chain;
/* This is language dependent part of the eh context. */
void *info;
};
#else
/* The handler_label field MUST be the first field in this structure. The /* The handler_label field MUST be the first field in this structure. The
__throw() library routine expects uses __eh_stub() from except.c, which __throw() library routine expects uses __eh_stub() from except.c, which
simply dereferences the context pointer to get the handler */ simply dereferences the context pointer to get the handler */
...@@ -41,23 +30,14 @@ struct eh_context ...@@ -41,23 +30,14 @@ struct eh_context
void *info; void *info;
}; };
#endif
#ifndef EH_TABLE_LOOKUP #ifndef EH_TABLE_LOOKUP
#ifndef NEW_EH_MODEL typedef struct old_exception_table
typedef struct exception_table
{ {
void *start_region; void *start_region;
void *end_region; void *end_region;
void *exception_handler; void *exception_handler;
} exception_table; } old_exception_table;
typedef exception_table exception_descriptor;
#else
typedef struct exception_table typedef struct exception_table
{ {
...@@ -76,11 +56,18 @@ typedef struct exception_lang_info ...@@ -76,11 +56,18 @@ typedef struct exception_lang_info
short version; short version;
} exception_lang_info; } exception_lang_info;
/* This value in the first field of the exception descriptor
identifies the descriptor as the new model format. This value would never
be present in this location under the old model */
#define NEW_EH_RUNTIME ((void *) -2)
/* Each function has an exception_descriptor which contains the /* Each function has an exception_descriptor which contains the
language info, and a table of exception ranges and handlers */ language info, and a table of exception ranges and handlers */
typedef struct exception_descriptor typedef struct exception_descriptor
{ {
void *runtime_id_field;
exception_lang_info lang; exception_lang_info lang;
exception_table table[1]; exception_table table[1];
} exception_descriptor; } exception_descriptor;
...@@ -126,8 +113,6 @@ enum exception_source_language ...@@ -126,8 +113,6 @@ enum exception_source_language
EH_LANG_Mips_Assembler = 0x8001 EH_LANG_Mips_Assembler = 0x8001
}; };
#endif
#endif /* EH_TABLE_LOOKUP */ #endif /* EH_TABLE_LOOKUP */
...@@ -1842,23 +1842,20 @@ output_exception_table_entry (file, n) ...@@ -1842,23 +1842,20 @@ output_exception_table_entry (file, n)
assemble_integer (handler->handler_label, assemble_integer (handler->handler_label,
POINTER_SIZE / BITS_PER_UNIT, 1); POINTER_SIZE / BITS_PER_UNIT, 1);
#ifdef NEW_EH_MODEL if (flag_new_exceptions)
/* for now make sure the sizes match */ {
if (handler->type_info == NULL) if (handler->type_info == NULL)
assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
else else
output_constant ((tree)(handler->type_info), output_constant ((tree)(handler->type_info),
POINTER_SIZE / BITS_PER_UNIT); POINTER_SIZE / BITS_PER_UNIT);
#endif }
putc ('\n', file); /* blank line */ putc ('\n', file); /* blank line */
} }
} }
/* Output the exception table if we have and need one. */ /* Output the exception table if we have and need one. */
#ifdef NEW_EH_MODEL
static short language_code = 0; static short language_code = 0;
static short version_code = 0; static short version_code = 0;
...@@ -1876,7 +1873,6 @@ void set_exception_version_code (code) ...@@ -1876,7 +1873,6 @@ void set_exception_version_code (code)
version_code = code; version_code = code;
} }
#endif
void void
output_exception_table () output_exception_table ()
...@@ -1893,17 +1889,20 @@ output_exception_table () ...@@ -1893,17 +1889,20 @@ output_exception_table ()
assemble_align (GET_MODE_ALIGNMENT (ptr_mode)); assemble_align (GET_MODE_ALIGNMENT (ptr_mode));
assemble_label ("__EXCEPTION_TABLE__"); assemble_label ("__EXCEPTION_TABLE__");
#ifdef NEW_EH_MODEL if (flag_new_exceptions)
assemble_integer (GEN_INT (language_code), 2 , 1); {
assemble_integer (GEN_INT (version_code), 2 , 1); assemble_integer (GEN_INT (NEW_EH_RUNTIME),
POINTER_SIZE / BITS_PER_UNIT, 1);
/* Add enough padding to make sure table aligns on a pointer boundry. */ assemble_integer (GEN_INT (language_code), 2 , 1);
i = GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT - 4; assemble_integer (GEN_INT (version_code), 2 , 1);
for ( ; i < 0; i = i + GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT)
; /* Add enough padding to make sure table aligns on a pointer boundry. */
if (i != 0) i = GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT - 4;
assemble_integer (const0_rtx, i , 1); for ( ; i < 0; i = i + GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT)
#endif ;
if (i != 0)
assemble_integer (const0_rtx, i , 1);
}
for (i = 0; i < eh_table_size; ++i) for (i = 0; i < eh_table_size; ++i)
output_exception_table_entry (asm_out_file, eh_table[i]); output_exception_table_entry (asm_out_file, eh_table[i]);
...@@ -1913,11 +1912,12 @@ output_exception_table () ...@@ -1913,11 +1912,12 @@ output_exception_table ()
/* Ending marker for table. */ /* Ending marker for table. */
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
#ifndef NEW_EH_MODEL
/* for binary compatability, the old __throw checked the second /* for binary compatability, the old __throw checked the second
position for a -1, so we should output at least 2 -1's */ position for a -1, so we should output at least 2 -1's */
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1); if (! flag_new_exceptions)
#endif assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
putc ('\n', asm_out_file); /* blank line */ putc ('\n', asm_out_file); /* blank line */
} }
...@@ -2424,11 +2424,30 @@ get_reg_for_handler () ...@@ -2424,11 +2424,30 @@ get_reg_for_handler ()
and then return to the stub. */ and then return to the stub. */
rtx rtx
expand_builtin_eh_stub_old ()
{
rtx stub_start = gen_label_rtx ();
rtx after_stub = gen_label_rtx ();
rtx handler, offset;
emit_jump (after_stub);
emit_label (stub_start);
eh_regs (&handler, &offset, 0);
adjust_stack (offset);
emit_indirect_jump (handler);
emit_label (after_stub);
return gen_rtx_LABEL_REF (Pmode, stub_start);
}
rtx
expand_builtin_eh_stub () expand_builtin_eh_stub ()
{ {
rtx stub_start = gen_label_rtx (); rtx stub_start = gen_label_rtx ();
rtx after_stub = gen_label_rtx (); rtx after_stub = gen_label_rtx ();
rtx handler, offset; rtx handler, offset;
rtx jump_to, temp;
emit_jump (after_stub); emit_jump (after_stub);
emit_label (stub_start); emit_label (stub_start);
...@@ -2436,28 +2455,19 @@ expand_builtin_eh_stub () ...@@ -2436,28 +2455,19 @@ expand_builtin_eh_stub ()
eh_regs (&handler, &offset, 0); eh_regs (&handler, &offset, 0);
adjust_stack (offset); adjust_stack (offset);
#ifdef NEW_EH_MODEL
/* Handler is in fact a pointer to the _eh_context structure, we need /* Handler is in fact a pointer to the _eh_context structure, we need
to pick out the handler field (first element), and jump to there, to pick out the handler field (first element), and jump to there,
leaving the pointer to _eh_conext in the same hardware register. */ leaving the pointer to _eh_conext in the same hardware register. */
{
rtx jump_to, temp;
temp = gen_rtx_MEM (Pmode, handler); temp = gen_rtx_MEM (Pmode, handler);
MEM_IN_STRUCT_P (temp) = 1; MEM_IN_STRUCT_P (temp) = 1;
RTX_UNCHANGING_P (temp) = 1; RTX_UNCHANGING_P (temp) = 1;
emit_insn (gen_rtx_SET (Pmode, offset, temp)); emit_insn (gen_rtx_SET (Pmode, offset, temp));
emit_insn (gen_rtx_USE (Pmode, handler)); emit_insn (gen_rtx_USE (Pmode, handler));
emit_indirect_jump (offset); emit_indirect_jump (offset);
}
#else
emit_indirect_jump (handler);
#endif
emit_label (after_stub); emit_label (after_stub);
return gen_rtx_LABEL_REF (Pmode, stub_start); return gen_rtx_LABEL_REF (Pmode, stub_start);
} }
......
...@@ -149,13 +149,9 @@ extern int doing_eh PROTO ((int)); ...@@ -149,13 +149,9 @@ extern int doing_eh PROTO ((int));
/* Toplevel initialization for EH. */ /* Toplevel initialization for EH. */
#ifdef NEW_EH_MODEL
void set_exception_lang_code PROTO((short)); void set_exception_lang_code PROTO((short));
void set_exception_version_code PROTO((short)); void set_exception_version_code PROTO((short));
#endif
/* A list of handlers asocciated with an exception region. HANDLER_LABEL /* A list of handlers asocciated with an exception region. HANDLER_LABEL
is the the label that control should be transfered to if the data is the the label that control should be transfered to if the data
in TYPE_INFO matches an exception. a value of NULL_TREE for TYPE_INFO in TYPE_INFO matches an exception. a value of NULL_TREE for TYPE_INFO
...@@ -381,6 +377,7 @@ extern void expand_fixup_region_end PROTO((tree)); ...@@ -381,6 +377,7 @@ extern void expand_fixup_region_end PROTO((tree));
void expand_builtin_unwind_init PROTO((void)); void expand_builtin_unwind_init PROTO((void));
rtx expand_builtin_dwarf_fp_regnum PROTO((void)); rtx expand_builtin_dwarf_fp_regnum PROTO((void));
rtx expand_builtin_eh_stub PROTO((void)); rtx expand_builtin_eh_stub PROTO((void));
rtx expand_builtin_eh_stub_old PROTO((void));
#ifdef TREE_CODE #ifdef TREE_CODE
rtx expand_builtin_frob_return_addr PROTO((tree)); rtx expand_builtin_frob_return_addr PROTO((tree));
rtx expand_builtin_extract_return_addr PROTO((tree)); rtx expand_builtin_extract_return_addr PROTO((tree));
......
...@@ -8954,6 +8954,8 @@ expand_builtin (exp, target, subtarget, mode, ignore) ...@@ -8954,6 +8954,8 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_SET_RETURN_ADDR_REG: case BUILT_IN_SET_RETURN_ADDR_REG:
expand_builtin_set_return_addr_reg (TREE_VALUE (arglist)); expand_builtin_set_return_addr_reg (TREE_VALUE (arglist));
return const0_rtx; return const0_rtx;
case BUILT_IN_EH_STUB_OLD:
return expand_builtin_eh_stub_old ();
case BUILT_IN_EH_STUB: case BUILT_IN_EH_STUB:
return expand_builtin_eh_stub (); return expand_builtin_eh_stub ();
case BUILT_IN_SET_EH_REGS: case BUILT_IN_SET_EH_REGS:
......
...@@ -2057,9 +2057,8 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes) ...@@ -2057,9 +2057,8 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
&& ! exceptions_via_longjmp) && ! exceptions_via_longjmp)
{ {
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_BLOCK_NUMBER (insn)); ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_BLOCK_NUMBER (insn));
#ifndef NEW_EH_MODEL if (! flag_new_exceptions)
add_eh_table_entry (NOTE_BLOCK_NUMBER (insn)); add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
#endif
#ifdef ASM_OUTPUT_EH_REGION_BEG #ifdef ASM_OUTPUT_EH_REGION_BEG
ASM_OUTPUT_EH_REGION_BEG (file, NOTE_BLOCK_NUMBER (insn)); ASM_OUTPUT_EH_REGION_BEG (file, NOTE_BLOCK_NUMBER (insn));
#endif #endif
...@@ -2070,9 +2069,8 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes) ...@@ -2070,9 +2069,8 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
&& ! exceptions_via_longjmp) && ! exceptions_via_longjmp)
{ {
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_BLOCK_NUMBER (insn)); ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_BLOCK_NUMBER (insn));
#ifdef NEW_EH_MODEL if (flag_new_exceptions)
add_eh_table_entry (NOTE_BLOCK_NUMBER (insn)); add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
#endif
#ifdef ASM_OUTPUT_EH_REGION_END #ifdef ASM_OUTPUT_EH_REGION_END
ASM_OUTPUT_EH_REGION_END (file, NOTE_BLOCK_NUMBER (insn)); ASM_OUTPUT_EH_REGION_END (file, NOTE_BLOCK_NUMBER (insn));
#endif #endif
......
...@@ -377,6 +377,11 @@ extern int flag_pic; ...@@ -377,6 +377,11 @@ extern int flag_pic;
extern int flag_exceptions; extern int flag_exceptions;
/* Nonzero means use the new model for exception handling. Replaces
-DNEW_EH_MODEL as a compile option. */
extern int flag_new_exceptions;
/* Nonzero means don't place uninitialized global data in common storage /* Nonzero means don't place uninitialized global data in common storage
by default. */ by default. */
......
...@@ -3367,11 +3367,41 @@ EH_TABLE_LOOKUP ...@@ -3367,11 +3367,41 @@ EH_TABLE_LOOKUP
an inner block. */ an inner block. */
static void * static void *
old_find_exception_handler (void *pc, old_exception_table *table)
{
if (table)
{
int pos;
int best = -1;
/* We can't do a binary search because the table isn't guaranteed
to be sorted from function to function. */
for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
{
if (table[pos].start_region <= pc && table[pos].end_region > pc)
{
/* This can apply. Make sure it is at least as small as
the previous best. */
if (best == -1 || (table[pos].end_region <= table[best].end_region
&& table[pos].start_region >= table[best].start_region))
best = pos;
}
/* But it is sorted by starting PC within a function. */
else if (best >= 0 && table[pos].start_region > pc)
break;
}
if (best != -1)
return table[best].exception_handler;
}
return (void *) 0;
}
static void *
find_exception_handler (void *pc, exception_descriptor *table, void *eh_info) find_exception_handler (void *pc, exception_descriptor *table, void *eh_info)
{ {
if (table) if (table)
{ {
#ifdef NEW_EH_MODEL
/* The new model assumed the table is sorted inner-most out so the /* The new model assumed the table is sorted inner-most out so the
first region we find which matches is the correct one */ first region we find which matches is the correct one */
...@@ -3406,29 +3436,6 @@ find_exception_handler (void *pc, exception_descriptor *table, void *eh_info) ...@@ -3406,29 +3436,6 @@ find_exception_handler (void *pc, exception_descriptor *table, void *eh_info)
return tab[pos].exception_handler; return tab[pos].exception_handler;
} }
} }
#else
int pos;
int best = -1;
/* We can't do a binary search because the table isn't guaranteed
to be sorted from function to function. */
for (pos = 0; table[pos].start_region != (void *) -1; ++pos)
{
if (table[pos].start_region <= pc && table[pos].end_region > pc)
{
/* This can apply. Make sure it is at least as small as
the previous best. */
if (best == -1 || (table[pos].end_region <= table[best].end_region
&& table[pos].start_region >= table[best].start_region))
best = pos;
}
/* But it is sorted by starting PC within a function. */
else if (best >= 0 && table[pos].start_region > pc)
break;
}
if (best != -1)
return table[best].exception_handler;
#endif
} }
return (void *) 0; return (void *) 0;
...@@ -3568,6 +3575,7 @@ __throw () ...@@ -3568,6 +3575,7 @@ __throw ()
frame_state *sub_udata = &ustruct2; frame_state *sub_udata = &ustruct2;
frame_state my_ustruct, *my_udata = &my_ustruct; frame_state my_ustruct, *my_udata = &my_ustruct;
long args_size; long args_size;
int new_exception_model;
/* This is required for C++ semantics. We must call terminate if we /* This is required for C++ semantics. We must call terminate if we
try and rethrow an exception, when there is no exception currently try and rethrow an exception, when there is no exception currently
...@@ -3611,7 +3619,16 @@ label: ...@@ -3611,7 +3619,16 @@ label:
if (! udata) if (! udata)
break; break;
handler = find_exception_handler (pc, udata->eh_ptr, eh->info); if (udata->eh_ptr == NULL)
new_exception_model = 0;
else
new_exception_model = (((exception_descriptor *)(udata->eh_ptr))->
runtime_id_field == NEW_EH_RUNTIME);
if (new_exception_model)
handler = find_exception_handler (pc, udata->eh_ptr, eh->info);
else
handler = old_find_exception_handler (pc, udata->eh_ptr);
/* If we found one, we can stop searching. */ /* If we found one, we can stop searching. */
if (handler) if (handler)
...@@ -3630,9 +3647,7 @@ label: ...@@ -3630,9 +3647,7 @@ label:
if (! handler) if (! handler)
__terminate (); __terminate ();
#ifdef NEW_EH_MODEL
eh->handler_label = handler; eh->handler_label = handler;
#endif
if (pc == saved_pc) if (pc == saved_pc)
/* We found a handler in the throw context, no need to unwind. */ /* We found a handler in the throw context, no need to unwind. */
...@@ -3691,7 +3706,10 @@ label: ...@@ -3691,7 +3706,10 @@ label:
/* udata now refers to the frame called by the handler frame. */ /* udata now refers to the frame called by the handler frame. */
/* Emit the stub to adjust sp and jump to the handler. */ /* Emit the stub to adjust sp and jump to the handler. */
retaddr = __builtin_eh_stub (); if (new_exception_model)
retaddr = __builtin_eh_stub ();
else
retaddr = __builtin_eh_stub_old ();
/* And then set our return address to point to the stub. */ /* And then set our return address to point to the stub. */
if (my_udata->saved[my_udata->retaddr_column] == REG_SAVED_OFFSET) if (my_udata->saved[my_udata->retaddr_column] == REG_SAVED_OFFSET)
...@@ -3702,19 +3720,23 @@ label: ...@@ -3702,19 +3720,23 @@ label:
/* Set up the registers we use to communicate with the stub. /* Set up the registers we use to communicate with the stub.
We check STACK_GROWS_DOWNWARD so the stub can use adjust_stack. */ We check STACK_GROWS_DOWNWARD so the stub can use adjust_stack. */
#ifdef NEW_EH_MODEL if (new_exception_model)
__builtin_set_eh_regs ((void *)eh, __builtin_set_eh_regs ((void *)eh,
#ifdef STACK_GROWS_DOWNWARD
udata->cfa - my_udata->cfa
#else #else
__builtin_set_eh_regs (handler, my_udata->cfa - udata->cfa
#endif #endif
+ args_size);
else
__builtin_set_eh_regs (handler,
#ifdef STACK_GROWS_DOWNWARD #ifdef STACK_GROWS_DOWNWARD
udata->cfa - my_udata->cfa udata->cfa - my_udata->cfa
#else #else
my_udata->cfa - udata->cfa my_udata->cfa - udata->cfa
#endif #endif
+ args_size + args_size);
);
/* Epilogue: restore the handler frame's register values and return /* Epilogue: restore the handler frame's register values and return
to the stub. */ to the stub. */
......
...@@ -600,6 +600,11 @@ int flag_pic; ...@@ -600,6 +600,11 @@ int flag_pic;
int flag_exceptions; int flag_exceptions;
/* Nonzero means use the new model for exception handling. Replaces
-DNEW_EH_MODEL as a compile option. */
extern int flag_new_exceptions = 0;
/* Nonzero means don't place uninitialized global data in common storage /* Nonzero means don't place uninitialized global data in common storage
by default. */ by default. */
...@@ -759,6 +764,7 @@ struct { char *string; int *variable; int on_value;} f_options[] = ...@@ -759,6 +764,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
{"pic", &flag_pic, 1}, {"pic", &flag_pic, 1},
{"PIC", &flag_pic, 2}, {"PIC", &flag_pic, 2},
{"exceptions", &flag_exceptions, 1}, {"exceptions", &flag_exceptions, 1},
{"new-exceptions", &flag_new_exceptions, 1},
{"sjlj-exceptions", &exceptions_via_longjmp, 1}, {"sjlj-exceptions", &exceptions_via_longjmp, 1},
{"asynchronous-exceptions", &asynchronous_exceptions, 1}, {"asynchronous-exceptions", &asynchronous_exceptions, 1},
{"profile-arcs", &profile_arc_flag, 1}, {"profile-arcs", &profile_arc_flag, 1},
......
...@@ -116,6 +116,7 @@ enum built_in_function ...@@ -116,6 +116,7 @@ enum built_in_function
BUILT_IN_FROB_RETURN_ADDR, BUILT_IN_FROB_RETURN_ADDR,
BUILT_IN_EXTRACT_RETURN_ADDR, BUILT_IN_EXTRACT_RETURN_ADDR,
BUILT_IN_SET_RETURN_ADDR_REG, BUILT_IN_SET_RETURN_ADDR_REG,
BUILT_IN_EH_STUB_OLD,
BUILT_IN_EH_STUB, BUILT_IN_EH_STUB,
BUILT_IN_SET_EH_REGS, BUILT_IN_SET_EH_REGS,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment