]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Use lookup table to get register sizes in dwarf2 eh
authorBernd Schmidt <bernds@cygnus.co.uk>
Thu, 30 Sep 1999 13:40:41 +0000 (13:40 +0000)
committerBernd Schmidt <crux@gcc.gnu.org>
Thu, 30 Sep 1999 13:40:41 +0000 (13:40 +0000)
From-SVN: r29730

gcc/ChangeLog
gcc/builtins.c
gcc/c-decl.c
gcc/dwarf2out.c
gcc/except.h
gcc/libgcc2.c
gcc/tree.h

index 2e621bbf7e3a51328264b5bae7d9fc4fc0aa58af..b95214dfacf6af284cdcc66e517761cdb30d72f4 100644 (file)
@@ -1,3 +1,24 @@
+Thu Sep 30 14:39:17 1999  Bernd Schmidt  <bernds@cygnus.co.uk>
+
+       * tree.h (enum built_in_function): Rename BUILT_IN_DWARF_REG_SIZE
+       to BUILT_IN_INIT_DWARF_REG_SIZES.
+       * builtins.c (expand_builtins, case BUILT_IN_INIT_DWARF_REG_SIZES):
+       Renamed from BUILT_IN_DWARF_REG_SIZE; call
+       expand_builtin_init_dwarf_reg_sizes.
+       * c-decl.c (init_decl_processing): Replace __builtin_dwarf_reg_size
+       with __builtin_init_dwarf_reg_size_table.
+       * dwarf2out.c (struct reg_size_range): Delete.
+       (expand_builtin_init_dwarf_reg_sizes): New function.
+       (expand_builtin_dwarf_reg_size): Delete.
+       * except.h (expand_builtin_init_dwarf_reg_sizes): Declare.
+       (expand_builtin_dwarf_reg_size): Don't declare.
+       * libgcc2.c (dwarf_reg_size_table_initialized): New.
+       (dwarf_reg_size_table): New.
+       (init_reg_size_table): New function.
+       (copy_reg): Use dwarf_reg_size_table.
+       (eh_context_initialize): Make sure dwarf_reg_size_table is initialized
+       before use.
+
 Thu Sep 30 05:40:34 1999  Richard Earnshaw <rearnsha@arm.com>
 
        * c-lang.c (finish_file case ndef ASM_OUTPUT_{CON,DE}STRUCTOR): 
index 36a6493d64526e3a9111ed2745ac1f4c2fcca0b7..1fb7b7413664a130573ee3cc0a779fd88b90203f 100644 (file)
@@ -2484,8 +2484,9 @@ expand_builtin (exp, target, subtarget, mode, ignore)
 #ifdef DWARF2_UNWIND_INFO
     case BUILT_IN_DWARF_FP_REGNUM:
       return expand_builtin_dwarf_fp_regnum ();
-    case BUILT_IN_DWARF_REG_SIZE:
-      return expand_builtin_dwarf_reg_size (TREE_VALUE (arglist), target);
+    case BUILT_IN_INIT_DWARF_REG_SIZES:
+      expand_builtin_init_dwarf_reg_sizes (TREE_VALUE (arglist));
+      return const0_rtx;
 #endif
     case BUILT_IN_FROB_RETURN_ADDR:
       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
index ca8f26b88c082de92b5ddc5e6a66d4828b43d32e..75ad2bac0b79ae04f11d3371edd41d30740b9fe4 100644 (file)
@@ -3068,8 +3068,8 @@ init_decl_processing ()
   builtin_function ("__builtin_dwarf_fp_regnum",
                    build_function_type (unsigned_type_node, endlink),
                    BUILT_IN_DWARF_FP_REGNUM, BUILT_IN_NORMAL, NULL_PTR);
-  builtin_function ("__builtin_dwarf_reg_size", int_ftype_int,
-                   BUILT_IN_DWARF_REG_SIZE, BUILT_IN_NORMAL, NULL_PTR);                    
+  builtin_function ("__builtin_init_dwarf_reg_size_table", void_ftype_ptr,
+                   BUILT_IN_INIT_DWARF_REG_SIZES, BUILT_IN_NORMAL, NULL_PTR);
   builtin_function ("__builtin_frob_return_addr", ptr_ftype_ptr,
                    BUILT_IN_FROB_RETURN_ADDR, BUILT_IN_NORMAL, NULL_PTR);
   builtin_function ("__builtin_extract_return_addr", ptr_ftype_ptr,
index 74f9d6dc611b97aee73c4689ebb65aeb27fedaf1..6732e5811decfe66333cd6562c58895722291282 100644 (file)
@@ -560,110 +560,26 @@ reg_number (rtl)
   return regno;
 }
 
-struct reg_size_range
-{
-  int beg;
-  int end;
-  int size;
-};
-
-/* Given a register number in REG_TREE, return an rtx for its size in bytes.
-   We do this in kind of a roundabout way, by building up a list of
-   register size ranges and seeing where our register falls in one of those
-   ranges.  We need to do it this way because REG_TREE is not a constant,
-   and the target macros were not designed to make this task easy.  */
+/* Generate code to initialize the register size table.  */
 
-rtx
-expand_builtin_dwarf_reg_size (reg_tree, target)
-     tree reg_tree;
-     rtx target;
+void
+expand_builtin_init_dwarf_reg_sizes (address)
+     tree address;
 {
-  enum machine_mode mode;
-  int size;
-  struct reg_size_range ranges[5];
-  tree t, t2;
-
-  int i = 0;
-  int n_ranges = 0;
-  int last_size = -1;
+  int i;
+  enum machine_mode mode = TYPE_MODE (char_type_node);
+  rtx addr = expand_expr (address, NULL_RTX, VOIDmode, 0);
+  rtx mem = gen_rtx_MEM (mode, addr);
 
-  for (; i < FIRST_PSEUDO_REGISTER; ++i)
+  for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
     {
-      /* The return address is out of order on the MIPS, and we don't use
-        copy_reg for it anyway, so we don't care here how large it is.  */
-      if (DWARF_FRAME_REGNUM (i) == DWARF_FRAME_RETURN_COLUMN)
-       continue;
-
-      mode = reg_raw_mode[i];
-
-      /* CCmode is arbitrarily given a size of 4 bytes.  It is more useful
-        to use the same size as word_mode, since that reduces the number
-        of ranges we need.  It should not matter, since the result should
-        never be used for a condition code register anyways.  */
-      if (GET_MODE_CLASS (mode) == MODE_CC)
-       mode = word_mode;
-
-      size = GET_MODE_SIZE (mode);
-
-      /* If this register is not valid in the specified mode and
-        we have a previous size, use that for the size of this
-        register to avoid making junk tiny ranges.  */
-      if (! HARD_REGNO_MODE_OK (i, mode) && last_size != -1)
-       size = last_size;
-
-      if (size != last_size)
-       {
-         ranges[n_ranges].beg = i;
-         ranges[n_ranges].size = last_size = size;
-         ++n_ranges;
-         if (n_ranges >= 5)
-           abort ();
-       }
-      ranges[n_ranges-1].end = i;
-    }
+      int offset = i * GET_MODE_SIZE (mode);
+      int size = GET_MODE_SIZE (reg_raw_mode[i]);
 
-  /* The usual case: fp regs surrounded by general regs.  */
-  if (n_ranges == 3 && ranges[0].size == ranges[2].size)
-    {
-      if ((DWARF_FRAME_REGNUM (ranges[1].end)
-          - DWARF_FRAME_REGNUM (ranges[1].beg))
-         != ranges[1].end - ranges[1].beg)
-       abort ();
-      t  = fold (build (GE_EXPR, integer_type_node, reg_tree,
-                       build_int_2 (DWARF_FRAME_REGNUM (ranges[1].beg), 0)));
-      t2 = fold (build (LE_EXPR, integer_type_node, reg_tree,
-                       build_int_2 (DWARF_FRAME_REGNUM (ranges[1].end), 0)));
-      t = fold (build (TRUTH_ANDIF_EXPR, integer_type_node, t, t2));
-      t = fold (build (COND_EXPR, integer_type_node, t,
-                      build_int_2 (ranges[1].size, 0),
-                      build_int_2 (ranges[0].size, 0)));
-    }
-  else
-    {
-      /* Initialize last_end to be larger than any possible
-        DWARF_FRAME_REGNUM.  */
-      int last_end = 0x7fffffff;
-      --n_ranges;
-      t = build_int_2 (ranges[n_ranges].size, 0);
-      do
-       {
-         int beg = DWARF_FRAME_REGNUM (ranges[n_ranges].beg);
-         int end = DWARF_FRAME_REGNUM (ranges[n_ranges].end);
-         if (beg < 0)
-           continue;
-         if (end >= last_end)
-           abort ();
-         last_end = end;
-         if (end - beg != ranges[n_ranges].end - ranges[n_ranges].beg)
-           abort ();
-         t2 = fold (build (LE_EXPR, integer_type_node, reg_tree,
-                           build_int_2 (end, 0)));
-         t = fold (build (COND_EXPR, integer_type_node, t2,
-                          build_int_2 (ranges[n_ranges].size, 0), t));
-       }
-      while (--n_ranges >= 0);
+      emit_move_insn (change_address (mem, mode,
+                                     plus_constant (addr, offset)),
+                     GEN_INT (size));
     }
-  return expand_expr (t, target, Pmode, 0);
 }
 
 /* Convert a DWARF call frame info. operation to its string name */
index 73bbe4dc8d7303a6e0aeaf71ff58e00d97acd6b9..07d4359a239f74df4ad0316535cb6104b8c92e08 100644 (file)
@@ -473,7 +473,7 @@ rtx expand_builtin_dwarf_fp_regnum  PROTO((void));
 #ifdef TREE_CODE
 rtx expand_builtin_frob_return_addr    PROTO((tree));
 rtx expand_builtin_extract_return_addr PROTO((tree));
-rtx expand_builtin_dwarf_reg_size      PROTO((tree, rtx));
+void expand_builtin_init_dwarf_reg_sizes       PROTO((tree));
 void expand_builtin_eh_return          PROTO((tree, tree, tree));
 #endif
 void expand_eh_return                  PROTO((void));
index aa8839be00da2711bdeaa0b180aff8fc0055878d..777112ce4e4a11ac9c1c23fd9621b1d241450c71 100644 (file)
@@ -3120,6 +3120,18 @@ __get_eh_info ()
   return &eh->info;
 }
 \f
+#ifdef DWARF2_UNWIND_INFO
+static int dwarf_reg_size_table_initialized = 0;
+static char dwarf_reg_size_table[FIRST_PSEUDO_REGISTER];
+
+static void
+init_reg_size_table ()
+{
+  __builtin_init_dwarf_reg_size_table (dwarf_reg_size_table);
+  dwarf_reg_size_table_initialized = 1;
+}
+#endif
+
 #if __GTHREADS
 static void
 eh_threads_initialize ()
@@ -3152,12 +3164,24 @@ eh_context_initialize ()
       /* Use static version of EH context. */
       get_eh_context = &eh_context_static;
     }
+#ifdef DWARF2_UNWIND_INFO
+  {
+    static __gthread_once_t once_regsizes = __GTHREAD_ONCE_INIT;
+    if (__gthread_once (&once_regsizes, init_reg_size_table) != 0
+       || ! dwarf_reg_size_table_initialized)
+      init_reg_size_table ();
+  }
+#endif
 
 #else /* no __GTHREADS */
 
   /* Use static version of EH context. */
   get_eh_context = &eh_context_static;
 
+#ifdef DWARF2_UNWIND_INFO
+  init_reg_size_table ();
+#endif
+
 #endif /* no __GTHREADS */
 
   return (*get_eh_context) ();
@@ -3395,7 +3419,6 @@ EH_TABLE_LOOKUP
 
 #ifdef DWARF2_UNWIND_INFO
 
-
 /* Return the table version of an exception descriptor */
 
 short 
@@ -3620,7 +3643,7 @@ copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
   word_type *preg = get_reg_addr (reg, udata, NULL);
   word_type *ptreg = get_reg_addr (reg, target_udata, NULL);
 
-  memcpy (ptreg, preg, __builtin_dwarf_reg_size (reg));
+  memcpy (ptreg, preg, dwarf_reg_size_table [reg]);
 }
 
 /* Retrieve the return address for frame UDATA.  */
index f2b6c729a10c96853e543944b538b9bac34615f6..cacdb28f20318d633ebb3402e5aaa007cfbe15c7 100644 (file)
@@ -120,7 +120,7 @@ enum built_in_function
   BUILT_IN_UNWIND_INIT,
   BUILT_IN_DWARF_CFA,
   BUILT_IN_DWARF_FP_REGNUM,
-  BUILT_IN_DWARF_REG_SIZE,
+  BUILT_IN_INIT_DWARF_REG_SIZES,
   BUILT_IN_FROB_RETURN_ADDR,
   BUILT_IN_EXTRACT_RETURN_ADDR,
   BUILT_IN_EH_RETURN,