Commit d9d5c9de by Bernd Schmidt Committed by Bernd Schmidt

Use lookup table to get register sizes in dwarf2 eh

From-SVN: r29730
parent a89e95f9
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):
......
......@@ -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));
......
......@@ -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,
......
......@@ -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 */
......
......@@ -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));
......
......@@ -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. */
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment