aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/bfin
diff options
context:
space:
mode:
authorBernd Schmidt <bernd.schmidt@analog.com>2008-10-29 15:12:28 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2008-10-29 15:12:28 +0000
commita848cf52b5e71ebeb05a23888ff3660c4f5012b8 (patch)
tree5ff9fd3890a2e19a7516577f05a62978f06b18e5 /gcc/config/bfin
parent7e51fe23ab9e0781f59a96c3101dd36fd28bb657 (diff)
downloadgcc-a848cf52b5e71ebeb05a23888ff3660c4f5012b8.zip
gcc-a848cf52b5e71ebeb05a23888ff3660c4f5012b8.tar.gz
gcc-a848cf52b5e71ebeb05a23888ff3660c4f5012b8.tar.bz2
bfin.c (struct machine_function): New member has_loopreg_clobber.
* config/bfin/bfin.c (struct machine_function): New member has_loopreg_clobber. (bfin_expand_movmem): Set it when generating memcpy insns. (n_regs_saved_by_prologue, expand_prologue_reg_save, expand_epilogue_reg_restore): If we have hardware loops, memcpy insns (indicated by has_loopreg_clobber) or function calls, we need to save the loop registers. From-SVN: r141425
Diffstat (limited to 'gcc/config/bfin')
-rw-r--r--gcc/config/bfin/bfin.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 3421dd0..5a289df 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -60,7 +60,11 @@
This is added to the cfun structure. */
struct machine_function GTY(())
{
+ /* Set if we are notified by the doloop pass that a hardware loop
+ was created. */
int has_hardware_loops;
+ /* Set if we create a memcpy pattern that uses loop registers. */
+ int has_loopreg_clobber;
};
/* Test and compare insns in bfin.md store the information needed to
@@ -544,7 +548,16 @@ expand_prologue_reg_save (rtx spreg, int saveall, bool is_inthandler)
if (saveall || is_inthandler)
{
rtx insn = emit_move_insn (predec, gen_rtx_REG (SImode, REG_ASTAT));
+
RTX_FRAME_RELATED_P (insn) = 1;
+ if (! current_function_is_leaf
+ || cfun->machine->has_hardware_loops
+ || cfun->machine->has_loopreg_clobber)
+ for (dregno = REG_LT0; dregno <= REG_LB1; dregno++)
+ {
+ insn = emit_move_insn (predec, gen_rtx_REG (SImode, dregno));
+ RTX_FRAME_RELATED_P (insn) = 1;
+ }
}
if (total_consec != 0)
@@ -714,7 +727,15 @@ expand_epilogue_reg_restore (rtx spreg, bool saveall, bool is_inthandler)
RTX_FRAME_RELATED_P (insn) = 1;
}
if (saveall || is_inthandler)
- emit_move_insn (gen_rtx_REG (SImode, REG_ASTAT), postinc);
+ {
+ if (! current_function_is_leaf
+ || cfun->machine->has_hardware_loops
+ || cfun->machine->has_loopreg_clobber)
+ for (regno = REG_LB1; regno >= REG_LT0; regno--)
+ emit_move_insn (gen_rtx_REG (SImode, regno), postinc);
+
+ emit_move_insn (gen_rtx_REG (SImode, REG_ASTAT), postinc);
+ }
}
/* Perform any needed actions needed for a function that is receiving a
@@ -813,8 +834,16 @@ n_regs_saved_by_prologue (void)
}
if (fkind != SUBROUTINE || all)
- /* Increment once for ASTAT. */
- n++;
+ {
+ /* Increment once for ASTAT. */
+ n++;
+ if (! current_function_is_leaf
+ || cfun->machine->has_hardware_loops
+ || cfun->machine->has_loopreg_clobber)
+ {
+ n += 6;
+ }
+ }
if (fkind != SUBROUTINE)
{
@@ -3398,6 +3427,7 @@ bfin_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp)
countreg = copy_to_mode_reg (Pmode, GEN_INT (new_count));
emit_insn (gen_rep_movsi (destreg, srcreg, countreg, destreg, srcreg));
+ cfun->machine->has_loopreg_clobber = true;
}
if (count & 2)
{
@@ -3418,6 +3448,7 @@ bfin_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp)
countreg = copy_to_mode_reg (Pmode, GEN_INT (new_count));
emit_insn (gen_rep_movhi (destreg, srcreg, countreg, destreg, srcreg));
+ cfun->machine->has_loopreg_clobber = true;
}
}
if (count & 1)