Commit ae1e2d4c by Andreas Schwab Committed by Andreas Schwab

re PR target/29166 (broken unwind information for many life variables resulting…

re PR target/29166 (broken unwind information for many life variables resulting in register corruption)

	PR target/29166
	* config/ia64/ia64.c (ia64_compute_frame_size): Account space for
	save of BR0 in extra_spill_size instead of spill_size.
	(ia64_expand_prologue): Save BR0 outside of the gr/br/fr spill
	area.
	(ia64_expand_epilogue): Restore BR0 from its new location.

testsuite/:
	* g++.dg/eh/pr29166.C: New test.

From-SVN: r120319
parent 9bed0a34
2007-01-01 Andreas Schwab <schwab@suse.de>
PR target/29166
* config/ia64/ia64.c (ia64_compute_frame_size): Account space for
save of BR0 in extra_spill_size instead of spill_size.
(ia64_expand_prologue): Save BR0 outside of the gr/br/fr spill
area.
(ia64_expand_epilogue): Restore BR0 from its new location.
2007-01-01 Andrew Pinski <pinskia@gmail.com>
* gimplify.c (gimplify_init_constructor <case VECTOR_TYPE>):
......
......@@ -2453,7 +2453,7 @@ ia64_compute_frame_size (HOST_WIDE_INT size)
current_frame_info.reg_save_b0 = find_gr_spill (1);
if (current_frame_info.reg_save_b0 == 0)
{
spill_size += 8;
extra_spill_size += 8;
n_spilled += 1;
}
......@@ -2482,7 +2482,7 @@ ia64_compute_frame_size (HOST_WIDE_INT size)
if (regs_ever_live[BR_REG (0)] && ! call_used_regs[BR_REG (0)])
{
SET_HARD_REG_BIT (mask, BR_REG (0));
spill_size += 8;
extra_spill_size += 8;
n_spilled += 1;
}
......@@ -3172,6 +3172,31 @@ ia64_expand_prologue (void)
}
}
/* Save the return pointer. */
if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
{
reg = gen_rtx_REG (DImode, BR_REG (0));
if (current_frame_info.reg_save_b0 != 0)
{
alt_reg = gen_rtx_REG (DImode, current_frame_info.reg_save_b0);
insn = emit_move_insn (alt_reg, reg);
RTX_FRAME_RELATED_P (insn) = 1;
/* Even if we're not going to generate an epilogue, we still
need to save the register so that EH works. */
if (! epilogue_p)
emit_insn (gen_prologue_use (alt_reg));
}
else
{
alt_regno = next_scratch_gr_reg ();
alt_reg = gen_rtx_REG (DImode, alt_regno);
emit_move_insn (alt_reg, reg);
do_spill (gen_movdi_x, alt_reg, cfa_off, reg);
cfa_off -= 8;
}
}
if (current_frame_info.reg_save_gp)
{
insn = emit_move_insn (gen_rtx_REG (DImode,
......@@ -3198,32 +3223,6 @@ ia64_expand_prologue (void)
cfa_off -= 8;
}
/* Handle BR0 specially -- it may be getting stored permanently in
some GR register. */
if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
{
reg = gen_rtx_REG (DImode, BR_REG (0));
if (current_frame_info.reg_save_b0 != 0)
{
alt_reg = gen_rtx_REG (DImode, current_frame_info.reg_save_b0);
insn = emit_move_insn (alt_reg, reg);
RTX_FRAME_RELATED_P (insn) = 1;
/* Even if we're not going to generate an epilogue, we still
need to save the register so that EH works. */
if (! epilogue_p)
emit_insn (gen_prologue_use (alt_reg));
}
else
{
alt_regno = next_scratch_gr_reg ();
alt_reg = gen_rtx_REG (DImode, alt_regno);
emit_move_insn (alt_reg, reg);
do_spill (gen_movdi_x, alt_reg, cfa_off, reg);
cfa_off -= 8;
}
}
/* Spill the rest of the BR registers. */
for (regno = BR_REG (1); regno <= BR_REG (7); ++regno)
if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
......@@ -3357,6 +3356,22 @@ ia64_expand_epilogue (int sibcall_p)
emit_move_insn (reg, alt_reg);
}
/* Restore the return pointer. */
if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
{
if (current_frame_info.reg_save_b0 != 0)
alt_reg = gen_rtx_REG (DImode, current_frame_info.reg_save_b0);
else
{
alt_regno = next_scratch_gr_reg ();
alt_reg = gen_rtx_REG (DImode, alt_regno);
do_restore (gen_movdi_x, alt_reg, cfa_off);
cfa_off -= 8;
}
reg = gen_rtx_REG (DImode, BR_REG (0));
emit_move_insn (reg, alt_reg);
}
/* We should now be at the base of the gr/br/fr spill area. */
gcc_assert (cfa_off == (current_frame_info.spill_cfa_off
+ current_frame_info.spill_size));
......@@ -3375,23 +3390,7 @@ ia64_expand_epilogue (int sibcall_p)
cfa_off -= 8;
}
/* Restore the branch registers. Handle B0 specially, as it may
have gotten stored in some GR register. */
if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
{
if (current_frame_info.reg_save_b0 != 0)
alt_reg = gen_rtx_REG (DImode, current_frame_info.reg_save_b0);
else
{
alt_regno = next_scratch_gr_reg ();
alt_reg = gen_rtx_REG (DImode, alt_regno);
do_restore (gen_movdi_x, alt_reg, cfa_off);
cfa_off -= 8;
}
reg = gen_rtx_REG (DImode, BR_REG (0));
emit_move_insn (reg, alt_reg);
}
/* Restore the branch registers. */
for (regno = BR_REG (1); regno <= BR_REG (7); ++regno)
if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
{
......
2007-01-01 Andreas Schwab <schwab@suse.de>
PR target/29166
* g++.dg/eh/pr29166.C: New test.
2007-01-01 Joseph Myers <joseph@codesourcery.com>
* lib/target-supports.exp (check_effective_target_powerpc_spe):
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