c-decl.c (init_decl_processing): Add __builtin_dwarf_reg_size.
* 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
This commit is contained in:
parent
faf199a621
commit
2f3ca9e7f4
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue