aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/Makefile.in15
-rw-r--r--gcc/expr.c22
-rw-r--r--gcc/expr.h2
-rw-r--r--gcc/final.c22
-rw-r--r--gcc/flow.c4
-rw-r--r--gcc/rtl.c3
-rw-r--r--gcc/rtl.h3
-rw-r--r--gcc/toplev.c37
8 files changed, 73 insertions, 35 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 907c6f8..76616a8 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -528,8 +528,8 @@ BC_ALL = bc-arity.h bc-opcode.h bc-opname.h
# Language-independent object files.
OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \
- function.o stmt.o expr.o calls.o expmed.o explow.o optabs.o varasm.o \
- rtl.o print-rtl.o rtlanal.o emit-rtl.o real.o \
+ function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o \
+ varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o real.o \
dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o \
integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o \
regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o \
@@ -1209,9 +1209,12 @@ function.o : function.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h \
insn-flags.h insn-codes.h expr.h regs.h hard-reg-set.h insn-config.h \
recog.h output.h bytecode.h bc-emit.h
stmt.o : stmt.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h \
- insn-flags.h insn-config.h insn-codes.h hard-reg-set.h expr.h loop.h \
- recog.h bytecode.h bc-typecd.h bc-typecd.def bc-opcode.h bc-optab.h \
- bc-emit.h
+ insn-flags.h insn-config.h insn-codes.h hard-reg-set.h expr.h except.h \
+ loop.h recog.h bytecode.h bc-typecd.h bc-typecd.def bc-opcode.h \
+ bc-optab.h bc-emit.h
+except.o : except.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h \
+ insn-flags.h insn-codes.h expr.h regs.h hard-reg-set.h insn-config.h \
+ recog.h output.h except.h
expr.o : expr.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h function.h regs.h \
insn-flags.h insn-codes.h expr.h insn-config.h recog.h output.h \
typeclass.h bytecode.h bc-opcode.h bc-typecd.h bc-typecd.def bc-optab.h \
@@ -1279,7 +1282,7 @@ reorg.o : reorg.c $(CONFIG_H) $(RTL_H) conditions.h hard-reg-set.h \
sched.o : sched.c $(CONFIG_H) $(RTL_H) basic-block.h regs.h hard-reg-set.h \
flags.h insn-config.h insn-attr.h
final.o : final.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h regs.h \
- recog.h conditions.h insn-config.h insn-attr.h real.h output.h \
+ recog.h conditions.h insn-config.h insn-attr.h except.h real.h output.h \
hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h defaults.h
recog.o : recog.c $(CONFIG_H) $(RTL_H) \
regs.h recog.h hard-reg-set.h flags.h insn-config.h insn-attr.h \
diff --git a/gcc/expr.c b/gcc/expr.c
index 09fc824..5dc9bcd 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -27,6 +27,7 @@ Boston, MA 02111-1307, USA. */
#include "flags.h"
#include "regs.h"
#include "hard-reg-set.h"
+#include "except.h"
#include "function.h"
#include "insn-flags.h"
#include "insn-codes.h"
@@ -210,7 +211,6 @@ static void do_jump_for_compare PROTO((rtx, rtx, rtx));
static rtx compare PROTO((tree, enum rtx_code, enum rtx_code));
static rtx do_store_flag PROTO((tree, rtx, enum machine_mode, int));
static tree defer_cleanups_to PROTO((tree));
-extern void (*interim_eh_hook) PROTO((tree));
extern tree truthvalue_conversion PROTO((tree));
/* Record for each mode whether we can move a register directly to or
@@ -5689,7 +5689,7 @@ expand_expr (exp, target, tmode, modifier)
= tree_cons (NULL_TREE, TREE_OPERAND (exp, 2), cleanups_this_call);
/* That's it for this cleanup. */
TREE_OPERAND (exp, 2) = 0;
- (*interim_eh_hook) (NULL_TREE);
+ expand_eh_region_start ();
}
return RTL_EXPR_RTL (exp);
@@ -6723,10 +6723,10 @@ expand_expr (exp, target, tmode, modifier)
pop_obstacks ();
- /* Now add in the conditionalized cleanups. */
+ /* Now add in the conditionalized cleanups. */
cleanups_this_call
= tree_cons (NULL_TREE, new_cleanups, cleanups_this_call);
- (*interim_eh_hook) (NULL_TREE);
+ expand_eh_region_start ();
}
return temp;
}
@@ -6815,7 +6815,7 @@ expand_expr (exp, target, tmode, modifier)
cleanups_this_call = tree_cons (NULL_TREE,
cleanups,
cleanups_this_call);
- (*interim_eh_hook) (NULL_TREE);
+ expand_eh_region_start ();
}
return target;
@@ -9731,7 +9731,7 @@ defer_cleanups_to (old_cleanups)
while (cleanups_this_call != old_cleanups)
{
- (*interim_eh_hook) (TREE_VALUE (cleanups_this_call));
+ expand_eh_region_end (TREE_VALUE (cleanups_this_call));
last = cleanups_this_call;
cleanups_this_call = TREE_CHAIN (cleanups_this_call);
}
@@ -9774,7 +9774,7 @@ expand_cleanups_to (old_cleanups)
{
while (cleanups_this_call != old_cleanups)
{
- (*interim_eh_hook) (TREE_VALUE (cleanups_this_call));
+ expand_eh_region_end (TREE_VALUE (cleanups_this_call));
expand_expr (TREE_VALUE (cleanups_this_call), const0_rtx, VOIDmode, 0);
cleanups_this_call = TREE_CHAIN (cleanups_this_call);
}
@@ -9973,10 +9973,10 @@ do_jump (exp, if_false_label, if_true_label)
pop_obstacks ();
- /* Now add in the conditionalized cleanups. */
+ /* Now add in the conditionalized cleanups. */
cleanups_this_call
= tree_cons (NULL_TREE, new_cleanups, cleanups_this_call);
- (*interim_eh_hook) (NULL_TREE);
+ expand_eh_region_start ();
}
else
{
@@ -10037,10 +10037,10 @@ do_jump (exp, if_false_label, if_true_label)
pop_obstacks ();
- /* Now add in the conditionalized cleanups. */
+ /* Now add in the conditionalized cleanups. */
cleanups_this_call
= tree_cons (NULL_TREE, new_cleanups, cleanups_this_call);
- (*interim_eh_hook) (NULL_TREE);
+ expand_eh_region_start ();
}
else
{
diff --git a/gcc/expr.h b/gcc/expr.h
index f6a9247..c5200e8 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -358,6 +358,8 @@ extern rtx bcmp_libfunc;
extern rtx memset_libfunc;
extern rtx bzero_libfunc;
+extern rtx throw_libfunc;
+
extern rtx eqhf2_libfunc;
extern rtx nehf2_libfunc;
extern rtx gthf2_libfunc;
diff --git a/gcc/final.c b/gcc/final.c
index 2932f89..d3e329e 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -67,6 +67,7 @@ Boston, MA 02111-1307, USA. */
#include "hard-reg-set.h"
#include "defaults.h"
#include "output.h"
+#include "except.h"
/* Get N_SLINE and N_SOL from stab.h if we can expect the file to exist. */
#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
@@ -1196,6 +1197,8 @@ final (first, file, optimize, prescan)
last_ignored_compare = 0;
new_block = 1;
+ check_exception_handler_labels ();
+
/* Make a map indicating which line numbers appear in this function.
When producing SDB debugging info, delete troublesome line number
notes from inlined functions in other files as well as duplicate
@@ -1298,6 +1301,25 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)
break;
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG)
+ {
+ ASM_OUTPUT_INTERNAL_LABEL (file, "LEHB", NOTE_BLOCK_NUMBER (insn));
+ 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
+ break;
+ }
+
+ if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)
+ {
+ ASM_OUTPUT_INTERNAL_LABEL (file, "LEHE", NOTE_BLOCK_NUMBER (insn));
+#ifdef ASM_OUTPUT_EH_REGION_END
+ ASM_OUTPUT_EH_REGION_END (file, NOTE_BLOCK_NUMBER (insn));
+#endif
+ break;
+ }
+
if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
{
#ifdef FUNCTION_END_PROLOGUE
diff --git a/gcc/flow.c b/gcc/flow.c
index e521150..d38e56d 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -117,6 +117,7 @@ Boston, MA 02111-1307, USA. */
#include "hard-reg-set.h"
#include "flags.h"
#include "output.h"
+#include "except.h"
#include "obstack.h"
#define obstack_chunk_alloc xmalloc
@@ -510,6 +511,9 @@ find_basic_blocks (f, nonlocal_label_list)
if (! LABEL_REF_NONLOCAL_P (x))
block_live[BLOCK_NUM (XEXP (x, 0))] = 1;
+ for (x = exception_handler_labels; x; x = XEXP (x, 1))
+ block_live[BLOCK_NUM (XEXP (x, 0))] = 1;
+
/* Record which basic blocks control can drop in to. */
for (i = 0; i < n_basic_blocks; i++)
diff --git a/gcc/rtl.c b/gcc/rtl.c
index 8c65d48..7a366b4 100644
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -172,7 +172,8 @@ char *note_insn_name[] = { 0 , "NOTE_INSN_DELETED",
"NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
"NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
"NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
- "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG"};
+ "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
+ "NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END"};
char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
"REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 892b709..6c13ac7 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -384,6 +384,9 @@ extern char *reg_note_name[];
i.e. the point just after all of the parms have been moved into
their homes, etc. */
#define NOTE_INSN_FUNCTION_BEG -13
+/* These note where exception handling regions begin and end. */
+#define NOTE_INSN_EH_REGION_BEG -14
+#define NOTE_INSN_EH_REGION_END -15
#if 0 /* These are not used, and I don't know what they were for. --rms. */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index a442c20..a21e2d6 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -62,6 +62,7 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "bytecode.h"
#include "bc-emit.h"
+#include "except.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h"
@@ -271,12 +272,6 @@ struct rtx_def *(*lang_expand_expr) ();
void (*incomplete_decl_finalize_hook) () = 0;
-/* Pointer to function for interim exception handling implementation.
- This interface will change, and it is only here until a better interface
- replaces it. */
-
-void (*interim_eh_hook) PROTO((tree));
-
/* Highest label number used at the end of reload. */
int max_label_num_after_reload;
@@ -492,8 +487,13 @@ int flag_short_temps;
int flag_pic;
+/* Nonzero means generate extra code for exception handling and enable
+ exception handling. */
+
+int flag_exceptions = 1;
+
/* Nonzero means don't place uninitialized global data in common storage
- by default. */
+ by default. */
int flag_no_common;
@@ -593,6 +593,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
{"schedule-insns2", &flag_schedule_insns_after_reload, 1},
{"pic", &flag_pic, 1},
{"PIC", &flag_pic, 2},
+ {"exceptions", &flag_exceptions, 1},
{"fast-math", &flag_fast_math, 1},
{"common", &flag_no_common, 0},
{"inhibit-size-directive", &flag_inhibit_size_directive, 1},
@@ -997,15 +998,6 @@ decl_name (decl, kind)
{
return IDENTIFIER_POINTER (DECL_NAME (decl));
}
-
-/* This is the default interim_eh_hook function. */
-
-void
-interim_eh (finalization)
- tree finalization;
-{
- /* Don't do anything by default. */
-}
static int need_error_newline;
@@ -2416,6 +2408,12 @@ compile_file (name)
}
}
+ /* Now that all possible functions have been output, we can dump
+ the exception table. */
+
+ if (exception_table_p ())
+ output_exception_table ();
+
for (i = 0; i < len; i++)
{
decl = vec[i];
@@ -2894,6 +2892,9 @@ rest_of_compilation (decl)
FINALIZE_PIC;
#endif
+ /* Add an unwinder for exception handling, if needed. */
+ emit_unwinder ();
+
insns = get_insns ();
/* Copy any shared structure that should not be shared. */
@@ -2909,6 +2910,9 @@ rest_of_compilation (decl)
for all references to such slots. */
/* fixup_stack_slots (); */
+ /* Find all the EH handlers. */
+ find_exception_handler_labels ();
+
/* Always do one jump optimization pass to ensure that JUMP_LABEL fields
are initialized and to compute whether control can drop off the end
of the function. */
@@ -3430,7 +3434,6 @@ main (argc, argv, envp)
decl_printable_name = decl_name;
lang_expand_expr = (struct rtx_def *(*)()) do_abort;
- interim_eh_hook = interim_eh;
/* Initialize whether `char' is signed. */
flag_signed_char = DEFAULT_SIGNED_CHAR;