OSDN Git Service

install EH code
authormrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Jul 1996 19:58:32 +0000 (19:58 +0000)
committermrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Jul 1996 19:58:32 +0000 (19:58 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@12548 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/Makefile.in
gcc/expr.c
gcc/expr.h
gcc/final.c
gcc/flow.c
gcc/rtl.c
gcc/rtl.h
gcc/toplev.c

index 907c6f8..76616a8 100644 (file)
@@ -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 \
index 09fc824..5dc9bcd 100644 (file)
@@ -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
          {
index f6a9247..c5200e8 100644 (file)
@@ -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;
index 2932f89..d3e329e 100644 (file)
@@ -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
index e521150..d38e56d 100644 (file)
@@ -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++)
index 8c65d48..7a366b4 100644 (file)
--- 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",
index 892b709..6c13ac7 100644 (file)
--- 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.  */
index a442c20..a21e2d6 100644 (file)
@@ -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.  */
-}
 \f
 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;