+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):
#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));
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,
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 */
#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));
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 ()
/* 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) ();
#ifdef DWARF2_UNWIND_INFO
-
/* Return the table version of an exception descriptor */
short
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. */
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,