From 037a52285fe7424ffa9f92aca8684ea3fab4c5a6 Mon Sep 17 00:00:00 2001 From: mrs Date: Tue, 23 Jul 1996 19:58:32 +0000 Subject: [PATCH] install EH code git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@12548 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/Makefile.in | 15 +++++++++------ gcc/expr.c | 22 +++++++++++----------- gcc/expr.h | 2 ++ gcc/final.c | 22 ++++++++++++++++++++++ gcc/flow.c | 4 ++++ gcc/rtl.c | 3 ++- gcc/rtl.h | 3 +++ gcc/toplev.c | 37 ++++++++++++++++++++----------------- 8 files changed, 73 insertions(+), 35 deletions(-) diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 907c6f87db3..76616a8e3cf 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 09fc824c092..5dc9bcd828e 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 f6a9247b30b..c5200e8eba8 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 2932f8996d4..d3e329efdb2 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 e521150371b..d38e56df64e 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 8c65d483b10..7a366b4e46f 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 892b709186a..6c13ac748b5 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 a442c2020aa..a21e2d66de7 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; -- 2.11.0