]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c-decl.c (init_decl_processing): Add __builtin_dwarf_reg_size.
authorJason Merrill <jason@yorick.cygnus.com>
Sat, 27 Sep 1997 18:16:15 +0000 (18:16 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 27 Sep 1997 18:16:15 +0000 (14:16 -0400)
* c-decl.c (init_decl_processing): Add __builtin_dwarf_reg_size.
* tree.h (built_in_function): Likewise.
* expr.c (expand_builtin): Likewise.
* except.h: Likewise.
* dwarf2out.c (expand_builtin_dwarf_reg_size): New fn.
* libgcc2.c (copy_reg): New fn.
(__throw): Use it.

From-SVN: r15750

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

index 13948ef94c79fa28c618483944bd9111733fb523..bcf67e3d422f25d9d1aca5d3e5b9dd898554c710 100644 (file)
@@ -1,3 +1,13 @@
+Sat Sep 27 11:02:38 1997  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * c-decl.c (init_decl_processing): Add __builtin_dwarf_reg_size.
+       * tree.h (built_in_function): Likewise.
+       * expr.c (expand_builtin): Likewise.
+       * except.h: Likewise.
+       * dwarf2out.c (expand_builtin_dwarf_reg_size): New fn.
+       * libgcc2.c (copy_reg): New fn.
+       (__throw): Use it.
+
 Fri Sep 26 08:54:59 1997  Paul Eggert  <eggert@twinsun.com>
 
        * c-typeck.c (build_binary_op): Warn about comparing signed vs
index 09143e41fce7111c79436530999cf04ce5553f81..5774f755b032c5ed56b625d19d2876bc8413183e 100644 (file)
@@ -3200,6 +3200,8 @@ init_decl_processing ()
   builtin_function ("__builtin_dwarf_fp_regnum",
                    build_function_type (unsigned_type_node, endlink),
                    BUILT_IN_DWARF_FP_REGNUM, NULL_PTR);
+  builtin_function ("__builtin_dwarf_reg_size", int_ftype_int,
+                   BUILT_IN_DWARF_REG_SIZE, NULL_PTR);             
   builtin_function ("__builtin_frob_return_addr", ptr_ftype_ptr,
                    BUILT_IN_FROB_RETURN_ADDR, NULL_PTR);
   builtin_function ("__builtin_extract_return_addr", ptr_ftype_ptr,
index 56ce82b8e01da3b21c97acd1388285fd86513854..6ad1c1b0ae9c6057038a6634c787bd3e6054464f 100644 (file)
@@ -502,6 +502,83 @@ 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.  */
+
+rtx
+expand_builtin_dwarf_reg_size (reg_tree, target)
+     tree reg_tree;
+     rtx target;
+{
+  int i, n_ranges, size;
+  struct reg_size_range ranges[5];
+  tree t, t2;
+
+  ranges[0].beg = 0;
+  ranges[0].size = GET_MODE_SIZE (reg_raw_mode[0]);
+  n_ranges = 1;
+
+  for (i = 1; i < FIRST_PSEUDO_REGISTER; ++i)
+    {
+      size = GET_MODE_SIZE (reg_raw_mode[i]);
+      if (size != ranges[n_ranges-1].size)
+       {
+         ranges[n_ranges-1].end = i-1;
+         ranges[n_ranges].beg = i;
+         ranges[n_ranges].size = GET_MODE_SIZE (reg_raw_mode[i]);
+         ++n_ranges;
+         assert (n_ranges < 5);
+       }
+    }
+  ranges[n_ranges-1].end = i-1;
+
+  /* The usual case: fp regs surrounded by general regs.  */
+  if (n_ranges == 3 && ranges[0].size == ranges[2].size)
+    {
+      assert ((DWARF_FRAME_REGNUM (ranges[1].end)
+              - DWARF_FRAME_REGNUM (ranges[1].beg))
+             == ranges[1].end - ranges[1].beg);
+      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
+    {
+      --n_ranges;
+      t = build_int_2 (ranges[n_ranges].size, 0);
+      size = DWARF_FRAME_REGNUM (ranges[n_ranges].beg);
+      for (; n_ranges--; )
+       {
+         assert ((DWARF_FRAME_REGNUM (ranges[n_ranges].end)
+                  - DWARF_FRAME_REGNUM (ranges[n_ranges].beg))
+                 == ranges[n_ranges].end - ranges[n_ranges].beg);
+         assert (DWARF_FRAME_REGNUM (ranges[n_ranges].beg) < size);
+         size = DWARF_FRAME_REGNUM (ranges[n_ranges].beg);
+         t2 = fold (build (LE_EXPR, integer_type_node, reg_tree,
+                           build_int_2 (DWARF_FRAME_REGNUM
+                                        (ranges[n_ranges].end), 0)));
+         t = fold (build (COND_EXPR, integer_type_node, t2,
+                          build_int_2 (ranges[n_ranges].size, 0), t));
+       }
+    }
+  return expand_expr (t, target, Pmode, 0);
+}
+
 /* Convert a DWARF call frame info. operation to its string name */
 
 static char *
index 71c49c25a77178c8c5d4e3b0b732aebaf45cdf25..fc2c37b3dbb11b915450aff7cb1e7dc361f06565 100644 (file)
@@ -292,4 +292,5 @@ rtx expand_builtin_frob_return_addr PROTO((tree));
 rtx expand_builtin_extract_return_addr PROTO((tree));
 void expand_builtin_set_return_addr_reg PROTO((tree));
 void expand_builtin_set_eh_regs                PROTO((tree, tree));
+rtx expand_builtin_dwarf_reg_size      PROTO((tree, rtx));
 #endif
index 4ed0b39d7101c3ef962404cdee43dc9acc47ddfd..1b5d5091c0281ad8412bcbe73b08ddf07a1c16b5 100644 (file)
@@ -9159,6 +9159,8 @@ 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);
 #endif
     case BUILT_IN_FROB_RETURN_ADDR:
       return expand_builtin_frob_return_addr (TREE_VALUE (arglist));
index 2b9c6bc886449c355609905a2e750497b5c6012a..6a49a1b2acb5e7a048c6ecaf19489f00b0881d9a 100644 (file)
@@ -3556,6 +3556,22 @@ put_reg (unsigned reg, void *val, frame_state *udata)
     abort ();
 }
 
+/* Copy the saved value for register REG from frame UDATA to frame
+   TARGET_UDATA.  Unlike the previous two functions, this can handle
+   registers that are not one word large.  */
+
+static void
+copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata)
+{
+  if (udata->saved[reg] == REG_SAVED_OFFSET
+      && target_udata->saved[reg] == REG_SAVED_OFFSET)
+    memcpy (target_udata->cfa + target_udata->reg_or_offset[reg],
+           udata->cfa + udata->reg_or_offset[reg],
+           __builtin_dwarf_reg_size (reg));
+  else
+    abort ();
+}
+
 /* Retrieve the return address for frame UDATA, where SUB_UDATA is a
    frame called by UDATA or 0.  */
 
@@ -3729,8 +3745,7 @@ label:
                    && udata->reg_or_offset[udata->retaddr_column] == i)
                  continue;
 #endif
-               val = get_reg (i, udata, sub_udata);
-               put_reg (i, val, my_udata);
+               copy_reg (i, udata, my_udata);
              }
 
          pc = get_return_addr (udata, sub_udata) - 1;
@@ -3744,10 +3759,7 @@ label:
        {
          i = udata->reg_or_offset[udata->retaddr_column];
          if (in_reg_window (i, udata))
-           {
-             val = get_reg (i, udata, sub_udata);
-             put_reg (i, val, my_udata);
-           }
+           copy_reg (i, udata, sub_udata);
        }
 #endif
     }
index d594bd92ccda16cab18bc01e24fe529c92077c98..4f43f6ffe6a446986145bd50ca8bff392ae6042e 100644 (file)
@@ -105,6 +105,7 @@ enum built_in_function
   BUILT_IN_FP, BUILT_IN_SP,
   BUILT_IN_UNWIND_INIT,
   BUILT_IN_DWARF_FP_REGNUM,
+  BUILT_IN_DWARF_REG_SIZE,
   BUILT_IN_FROB_RETURN_ADDR,
   BUILT_IN_EXTRACT_RETURN_ADDR,
   BUILT_IN_SET_RETURN_ADDR_REG,