aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@cygnus.co.uk>1999-09-30 13:40:41 +0000
committerBernd Schmidt <crux@gcc.gnu.org>1999-09-30 13:40:41 +0000
commitd9d5c9de1c377b1104d371bc935a31e53e83cf8d (patch)
tree15d8cd0891da1777322bd125841935d8803c44f4
parenta89e95f9fb5a2c04a9efe3036fd90f1fb0b474c0 (diff)
downloadgcc-d9d5c9de1c377b1104d371bc935a31e53e83cf8d.zip
gcc-d9d5c9de1c377b1104d371bc935a31e53e83cf8d.tar.gz
gcc-d9d5c9de1c377b1104d371bc935a31e53e83cf8d.tar.bz2
Use lookup table to get register sizes in dwarf2 eh
From-SVN: r29730
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/builtins.c5
-rw-r--r--gcc/c-decl.c4
-rw-r--r--gcc/dwarf2out.c112
-rw-r--r--gcc/except.h2
-rw-r--r--gcc/libgcc2.c27
-rw-r--r--gcc/tree.h2
7 files changed, 67 insertions, 106 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2e621bb..b95214d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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):
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 36a6493..1fb7b74 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -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));
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index ca8f26b..75ad2ba 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -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,
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 74f9d6d..6732e58 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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 */
diff --git a/gcc/except.h b/gcc/except.h
index 73bbe4d..07d4359 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -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));
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index aa8839b..777112c 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -3120,6 +3120,18 @@ __get_eh_info ()
return &eh->info;
}
+#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. */
diff --git a/gcc/tree.h b/gcc/tree.h
index f2b6c72..cacdb28 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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,