[multiple changes]
authorAndrew MacLeod <amacleod@cygnus.com>
Mon, 8 Jun 1998 12:43:28 +0000 (12:43 +0000)
committerAndrew Macleod <amacleod@gcc.gnu.org>
Mon, 8 Jun 1998 12:43:28 +0000 (12:43 +0000)
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

14 files changed:
gcc/ChangeLog
gcc/c-decl.c
gcc/cp/ChangeLog
gcc/cp/except.c
gcc/cp/exception.cc
gcc/eh-common.h
gcc/except.c
gcc/except.h
gcc/expr.c
gcc/final.c
gcc/flags.h
gcc/libgcc2.c
gcc/toplev.c
gcc/tree.h

index 07b0a2b..b879382 100644 (file)
@@ -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.
index 6a0e0ea..bc8f617 100644 (file)
@@ -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
index 912b332..f426641 100644 (file)
@@ -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
index 89dee7e..44e250c 100644 (file)
@@ -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.  */
index 461dba4..b081fa7 100644 (file)
@@ -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;
 }
 
index 708946b..51ecf31 100644 (file)
@@ -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
 #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 */
 
 
index 5881e22..b3cb9cd 100644 (file)
@@ -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 */
 }
 \f
@@ -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);
 }
index d2523cb..9198e41 100644 (file)
@@ -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));
index 058d121..fe276bd 100644 (file)
@@ -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:
index d30e5b2..4679fa3 100644 (file)
@@ -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
index dccfc54..2b67005 100644 (file)
@@ -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.  */
 
index c860412..1999931 100644 (file)
@@ -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.  */
index 60cbc6a..ed0e1a4 100644 (file)
@@ -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},
index b864020..c7779dd 100644 (file)
@@ -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,