aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew MacLeod <amacleod@cygnus.com>1998-06-08 12:43:28 +0000
committerAndrew Macleod <amacleod@gcc.gnu.org>1998-06-08 12:43:28 +0000
commita1622f838f1188fca74ba0186300882f33006ae7 (patch)
tree8c6db0a08fe59e66faaa88318e5d8e194578463d
parentaeb302bbec86aff44fadaad0c9c9bf5e59cbe3f5 (diff)
downloadgcc-a1622f838f1188fca74ba0186300882f33006ae7.zip
gcc-a1622f838f1188fca74ba0186300882f33006ae7.tar.gz
gcc-a1622f838f1188fca74ba0186300882f33006ae7.tar.bz2
[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
-rw-r--r--gcc/ChangeLog31
-rw-r--r--gcc/c-decl.c2
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/except.c35
-rw-r--r--gcc/cp/exception.cc27
-rw-r--r--gcc/eh-common.h35
-rw-r--r--gcc/except.c90
-rw-r--r--gcc/except.h5
-rw-r--r--gcc/expr.c2
-rw-r--r--gcc/final.c10
-rw-r--r--gcc/flags.h5
-rw-r--r--gcc/libgcc2.c88
-rw-r--r--gcc/toplev.c6
-rw-r--r--gcc/tree.h1
14 files changed, 208 insertions, 142 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 07b0a2b..b879382 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,34 @@
+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>
* function.c: Define current_function_cannot_inline.
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 6a0e0ea..bc8f617 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -3260,6 +3260,8 @@ init_decl_processing ()
ptr_type_node,
endlink)),
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,
BUILT_IN_EH_STUB, NULL_PTR);
builtin_function
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 912b332..f426641 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,16 @@
+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>
* decl.c (cp_finish_decl): Disable inlining of extern inlines
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index 89dee7e..44e250c 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -203,10 +203,8 @@ init_exception_processing ()
push_lang_context (lang_name_c);
-#ifdef NEW_EH_MODEL
set_exception_lang_code (EH_LANG_C_plus_plus);
set_exception_version_code (1);
-#endif
CatchMatch
= builtin_function (flag_rtti
@@ -245,25 +243,20 @@ call_eh_info ()
{
tree fn;
- fn = get_identifier ("__cp_exception_info");
+ fn = get_identifier ("__cp_eh_info");
if (IDENTIFIER_GLOBAL_VALUE (fn))
fn = IDENTIFIER_GLOBAL_VALUE (fn);
else
{
-#ifdef NEW_EH_MODEL
- tree t1;
-#endif
- tree t, fields[7];
- int fo = 0;
+ tree t1, t, fields[7];
- /* Declare cp_eh_info * __cp_exception_info (void),
+ /* Declare cp_eh_info * __cp_eh_info (void),
as defined in exception.cc. */
push_obstacks_nochange ();
end_temporary_allocation ();
/* struct cp_eh_info. This must match exception.cc. Note that this
type is not pushed anywhere. */
-#ifdef NEW_EH_MODEL
t1= make_lang_type (RECORD_TYPE);
fields[0] = build_lang_field_decl (FIELD_DECL,
get_identifier ("handler_label"), ptr_type_node);
@@ -288,31 +281,27 @@ call_eh_info ()
/* N.B.: The fourth field LEN is expected to be
the number of fields - 1, not the total number of fields. */
finish_builtin_type (t1, "__eh_info", fields, 3, ptr_type_node);
- fo = 1;
-#endif
t = make_lang_type (RECORD_TYPE);
-#ifdef NEW_EH_MODEL
- fields[0] = build_lang_field_decl (FIELD_DECL, get_identifier ("eh_info"),
- t1);
-#endif
- fields[0+fo] = build_lang_field_decl (FIELD_DECL, get_identifier ("value"),
+ fields[0] = build_lang_field_decl (FIELD_DECL,
+ get_identifier ("eh_info"), t1);
+ fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("value"),
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);
- fields[2+fo] = build_lang_field_decl
+ fields[3] = build_lang_field_decl
(FIELD_DECL, get_identifier ("cleanup"),
build_pointer_type (build_function_type
(ptr_type_node, tree_cons
(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);
- 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));
- fields[5+fo] = build_lang_field_decl
+ fields[6] = build_lang_field_decl
(FIELD_DECL, get_identifier ("handlers"), long_integer_type_node);
/* N.B.: The fourth field LEN is expected to be
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);
/* And now the function. */
diff --git a/gcc/cp/exception.cc b/gcc/cp/exception.cc
index 461dba4..b081fa7 100644
--- a/gcc/cp/exception.cc
+++ b/gcc/cp/exception.cc
@@ -86,9 +86,7 @@ std::unexpected ()
struct cp_eh_info
{
-#ifdef NEW_EH_MODEL
__eh_info eh_info;
-#endif
void *value;
void *type;
void (*cleanup)(void *, int);
@@ -105,11 +103,23 @@ extern "C" cp_eh_info **__get_eh_info (); // actually 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.
Used by get_eh_info (). */
extern "C" cp_eh_info *
-__cp_exception_info (void)
+__cp_eh_info (void)
{
return *__get_eh_info ();
}
@@ -138,8 +148,6 @@ __eh_free (void *p)
}
-#ifdef NEW_EH_MODEL
-
typedef void * (* rtimetype) (void);
extern "C" void *
@@ -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);
return ret;
}
-#endif
/* 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))
p->handlers = 0;
p->caught = false;
-#ifdef NEW_EH_MODEL
p->eh_info.match_function = __cplus_type_matcher;
p->eh_info.language = EH_LANG_C_plus_plus;
p->eh_info.version = 1;
p->eh_info.coerced_value = NULL;
-#endif
cp_eh_info **q = __get_eh_info ();
@@ -227,7 +232,7 @@ __cp_pop_exception (cp_eh_info *p)
extern "C" void
__uncatch_exception (void)
{
- cp_eh_info *p = __cp_exception_info ();
+ cp_eh_info *p = __cp_eh_info ();
if (p == 0)
terminate ();
p->caught = false;
@@ -248,7 +253,7 @@ __uncatch_exception (void)
extern "C" void
__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)
{
@@ -301,7 +306,7 @@ __throw_bad_typeid (void)
bool
std::uncaught_exception ()
{
- cp_eh_info *p = __cp_exception_info ();
+ cp_eh_info *p = __cp_eh_info ();
return p && ! p->caught;
}
diff --git a/gcc/eh-common.h b/gcc/eh-common.h
index 708946b..51ecf31 100644
--- a/gcc/eh-common.h
+++ b/gcc/eh-common.h
@@ -5,7 +5,7 @@
independant exception handling model. Both the static compiler and
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
the new model, runtime info is contained in the exception table, and
the __throw() library routine determines which handler to call based
@@ -18,17 +18,6 @@
#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
__throw() library routine expects uses __eh_stub() from except.c, which
simply dereferences the context pointer to get the handler */
@@ -41,23 +30,14 @@ struct eh_context
void *info;
};
-#endif
-
-
#ifndef EH_TABLE_LOOKUP
-#ifndef NEW_EH_MODEL
-
-typedef struct exception_table
+typedef struct old_exception_table
{
void *start_region;
void *end_region;
void *exception_handler;
-} exception_table;
-
-typedef exception_table exception_descriptor;
-
-#else
+} old_exception_table;
typedef struct exception_table
{
@@ -76,11 +56,18 @@ typedef struct exception_lang_info
short version;
} 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
language info, and a table of exception ranges and handlers */
typedef struct exception_descriptor
{
+ void *runtime_id_field;
exception_lang_info lang;
exception_table table[1];
} exception_descriptor;
@@ -126,8 +113,6 @@ enum exception_source_language
EH_LANG_Mips_Assembler = 0x8001
};
-#endif
-
#endif /* EH_TABLE_LOOKUP */
diff --git a/gcc/except.c b/gcc/except.c
index 5881e22..b3cb9cd 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1842,23 +1842,20 @@ output_exception_table_entry (file, n)
assemble_integer (handler->handler_label,
POINTER_SIZE / BITS_PER_UNIT, 1);
-#ifdef NEW_EH_MODEL
- /* for now make sure the sizes match */
- if (handler->type_info == NULL)
- assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
- else
- output_constant ((tree)(handler->type_info),
+ if (flag_new_exceptions)
+ {
+ if (handler->type_info == NULL)
+ assemble_integer (const0_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
+ else
+ output_constant ((tree)(handler->type_info),
POINTER_SIZE / BITS_PER_UNIT);
-#endif
-
+ }
putc ('\n', file); /* blank line */
}
}
/* Output the exception table if we have and need one. */
-#ifdef NEW_EH_MODEL
-
static short language_code = 0;
static short version_code = 0;
@@ -1876,7 +1873,6 @@ void set_exception_version_code (code)
version_code = code;
}
-#endif
void
output_exception_table ()
@@ -1893,17 +1889,20 @@ output_exception_table ()
assemble_align (GET_MODE_ALIGNMENT (ptr_mode));
assemble_label ("__EXCEPTION_TABLE__");
-#ifdef NEW_EH_MODEL
- assemble_integer (GEN_INT (language_code), 2 , 1);
- assemble_integer (GEN_INT (version_code), 2 , 1);
-
- /* Add enough padding to make sure table aligns on a pointer boundry. */
- i = GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT - 4;
- for ( ; i < 0; i = i + GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT)
- ;
- if (i != 0)
- assemble_integer (const0_rtx, i , 1);
-#endif
+ if (flag_new_exceptions)
+ {
+ assemble_integer (GEN_INT (NEW_EH_RUNTIME),
+ POINTER_SIZE / BITS_PER_UNIT, 1);
+ assemble_integer (GEN_INT (language_code), 2 , 1);
+ assemble_integer (GEN_INT (version_code), 2 , 1);
+
+ /* Add enough padding to make sure table aligns on a pointer boundry. */
+ i = GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT - 4;
+ for ( ; i < 0; i = i + GET_MODE_ALIGNMENT (ptr_mode) / BITS_PER_UNIT)
+ ;
+ if (i != 0)
+ assemble_integer (const0_rtx, i , 1);
+ }
for (i = 0; i < eh_table_size; ++i)
output_exception_table_entry (asm_out_file, eh_table[i]);
@@ -1913,11 +1912,12 @@ output_exception_table ()
/* Ending marker for table. */
assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
-#ifndef NEW_EH_MODEL
+
/* for binary compatability, the old __throw checked the second
position for a -1, so we should output at least 2 -1's */
- assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
-#endif
+ if (! flag_new_exceptions)
+ assemble_integer (constm1_rtx, POINTER_SIZE / BITS_PER_UNIT, 1);
+
putc ('\n', asm_out_file); /* blank line */
}
@@ -2424,11 +2424,30 @@ get_reg_for_handler ()
and then return to the stub. */
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 ()
{
rtx stub_start = gen_label_rtx ();
rtx after_stub = gen_label_rtx ();
rtx handler, offset;
+ rtx jump_to, temp;
emit_jump (after_stub);
emit_label (stub_start);
@@ -2436,28 +2455,19 @@ expand_builtin_eh_stub ()
eh_regs (&handler, &offset, 0);
adjust_stack (offset);
-#ifdef NEW_EH_MODEL
/* 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,
leaving the pointer to _eh_conext in the same hardware register. */
- {
- rtx jump_to, temp;
- temp = gen_rtx_MEM (Pmode, handler);
- MEM_IN_STRUCT_P (temp) = 1;
- RTX_UNCHANGING_P (temp) = 1;
- emit_insn (gen_rtx_SET (Pmode, offset, temp));
- emit_insn (gen_rtx_USE (Pmode, handler));
+ temp = gen_rtx_MEM (Pmode, handler);
+ MEM_IN_STRUCT_P (temp) = 1;
+ RTX_UNCHANGING_P (temp) = 1;
+ emit_insn (gen_rtx_SET (Pmode, offset, temp));
+ 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);
return gen_rtx_LABEL_REF (Pmode, stub_start);
}
diff --git a/gcc/except.h b/gcc/except.h
index d2523cb..9198e41 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -149,13 +149,9 @@ extern int doing_eh PROTO ((int));
/* Toplevel initialization for EH. */
-#ifdef NEW_EH_MODEL
-
void set_exception_lang_code PROTO((short));
void set_exception_version_code PROTO((short));
-#endif
-
/* A list of handlers asocciated with an exception region. HANDLER_LABEL
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
@@ -381,6 +377,7 @@ extern void expand_fixup_region_end PROTO((tree));
void expand_builtin_unwind_init PROTO((void));
rtx expand_builtin_dwarf_fp_regnum PROTO((void));
rtx expand_builtin_eh_stub PROTO((void));
+rtx expand_builtin_eh_stub_old PROTO((void));
#ifdef TREE_CODE
rtx expand_builtin_frob_return_addr PROTO((tree));
rtx expand_builtin_extract_return_addr PROTO((tree));
diff --git a/gcc/expr.c b/gcc/expr.c
index 058d121..fe276bd 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8954,6 +8954,8 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_SET_RETURN_ADDR_REG:
expand_builtin_set_return_addr_reg (TREE_VALUE (arglist));
return const0_rtx;
+ case BUILT_IN_EH_STUB_OLD:
+ return expand_builtin_eh_stub_old ();
case BUILT_IN_EH_STUB:
return expand_builtin_eh_stub ();
case BUILT_IN_SET_EH_REGS:
diff --git a/gcc/final.c b/gcc/final.c
index d30e5b2..4679fa3 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -2057,9 +2057,8 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
&& ! exceptions_via_longjmp)
{
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_BLOCK_NUMBER (insn));
-#ifndef NEW_EH_MODEL
- add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
-#endif
+ if (! flag_new_exceptions)
+ add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
#ifdef ASM_OUTPUT_EH_REGION_BEG
ASM_OUTPUT_EH_REGION_BEG (file, NOTE_BLOCK_NUMBER (insn));
#endif
@@ -2070,9 +2069,8 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
&& ! exceptions_via_longjmp)
{
ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_BLOCK_NUMBER (insn));
-#ifdef NEW_EH_MODEL
- add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
-#endif
+ if (flag_new_exceptions)
+ add_eh_table_entry (NOTE_BLOCK_NUMBER (insn));
#ifdef ASM_OUTPUT_EH_REGION_END
ASM_OUTPUT_EH_REGION_END (file, NOTE_BLOCK_NUMBER (insn));
#endif
diff --git a/gcc/flags.h b/gcc/flags.h
index dccfc54..2b67005 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -377,6 +377,11 @@ extern int flag_pic;
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
by default. */
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index c860412..1999931 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -3367,11 +3367,41 @@ EH_TABLE_LOOKUP
an inner block. */
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)
{
if (table)
{
-#ifdef NEW_EH_MODEL
/* The new model assumed the table is sorted inner-most out so the
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)
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;
@@ -3568,6 +3575,7 @@ __throw ()
frame_state *sub_udata = &ustruct2;
frame_state my_ustruct, *my_udata = &my_ustruct;
long args_size;
+ int new_exception_model;
/* This is required for C++ semantics. We must call terminate if we
try and rethrow an exception, when there is no exception currently
@@ -3611,7 +3619,16 @@ label:
if (! udata)
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 (handler)
@@ -3630,9 +3647,7 @@ label:
if (! handler)
__terminate ();
-#ifdef NEW_EH_MODEL
eh->handler_label = handler;
-#endif
if (pc == saved_pc)
/* We found a handler in the throw context, no need to unwind. */
@@ -3691,7 +3706,10 @@ label:
/* udata now refers to the frame called by the handler frame. */
/* 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. */
if (my_udata->saved[my_udata->retaddr_column] == REG_SAVED_OFFSET)
@@ -3702,19 +3720,23 @@ label:
/* Set up the registers we use to communicate with the stub.
We check STACK_GROWS_DOWNWARD so the stub can use adjust_stack. */
-#ifdef NEW_EH_MODEL
- __builtin_set_eh_regs ((void *)eh,
+ if (new_exception_model)
+ __builtin_set_eh_regs ((void *)eh,
+#ifdef STACK_GROWS_DOWNWARD
+ udata->cfa - my_udata->cfa
#else
- __builtin_set_eh_regs (handler,
+ my_udata->cfa - udata->cfa
#endif
+ + args_size);
+ else
+ __builtin_set_eh_regs (handler,
#ifdef STACK_GROWS_DOWNWARD
udata->cfa - my_udata->cfa
#else
my_udata->cfa - udata->cfa
#endif
- + args_size
- );
+ + args_size);
/* Epilogue: restore the handler frame's register values and return
to the stub. */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 60cbc6a..ed0e1a4 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -600,6 +600,11 @@ int flag_pic;
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
by default. */
@@ -759,6 +764,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
{"pic", &flag_pic, 1},
{"PIC", &flag_pic, 2},
{"exceptions", &flag_exceptions, 1},
+ {"new-exceptions", &flag_new_exceptions, 1},
{"sjlj-exceptions", &exceptions_via_longjmp, 1},
{"asynchronous-exceptions", &asynchronous_exceptions, 1},
{"profile-arcs", &profile_arc_flag, 1},
diff --git a/gcc/tree.h b/gcc/tree.h
index b864020..c7779dd 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -116,6 +116,7 @@ enum built_in_function
BUILT_IN_FROB_RETURN_ADDR,
BUILT_IN_EXTRACT_RETURN_ADDR,
BUILT_IN_SET_RETURN_ADDR_REG,
+ BUILT_IN_EH_STUB_OLD,
BUILT_IN_EH_STUB,
BUILT_IN_SET_EH_REGS,