Commit bf3f9581 by Bernd Schmidt Committed by Bernd Schmidt

bfin.c (expand_prologue_reg_save, [...]): Code to save and restore I/M/B/L regs…

bfin.c (expand_prologue_reg_save, [...]): Code to save and restore I/M/B/L regs and ASTAT moved here...

	* config/bfin/bfin.c (expand_prologue_reg_save,
	expand_epilogue_reg_restore): Code to save and restore I/M/B/L regs and
	ASTAT moved here...
	(expand_interrupt_handler_prologue, expand_interrupt_handler_epilogue):
	... from here.  New argument ALL; callers changed.
	(n_regs_saved_by_prologue): Count ASTAT for plain saveall functions.
	(bfin_expand_prologue, bfin_expand_epilogue): Deal with functions that
	have the "saveall" attribute.

From-SVN: r128762
parent 1bde0042
2007-09-25 Bernd Schmidt <bernd.schmidt@analog.com>
* config/bfin/bfin.c (expand_prologue_reg_save,
expand_epilogue_reg_restore): Code to save and restore I/M/B/L regs and
ASTAT moved here...
(expand_interrupt_handler_prologue, expand_interrupt_handler_epilogue):
... from here. New argument ALL; callers changed.
(n_regs_saved_by_prologue): Count ASTAT for plain saveall functions.
(bfin_expand_prologue, bfin_expand_epilogue): Deal with functions that
have the "saveall" attribute.
2007-09-25 Hans-Peter Nilsson <hp@bitrange.com>
* config/mmix/mmix.h (FUNCTION_INCOMING_ARG_REGNO_P): Don't define
......@@ -416,6 +416,8 @@ stack_frame_needed_p (void)
static void
expand_prologue_reg_save (rtx spreg, int saveall, bool is_inthandler)
{
rtx predec1 = gen_rtx_PRE_DEC (SImode, spreg);
rtx predec = gen_rtx_MEM (SImode, predec1);
int ndregs = saveall ? 8 : n_dregs_to_save (is_inthandler);
int npregs = saveall ? 6 : n_pregs_to_save (is_inthandler);
int dregno = REG_R7 + 1 - ndregs;
......@@ -424,7 +426,13 @@ expand_prologue_reg_save (rtx spreg, int saveall, bool is_inthandler)
int i;
rtx pat, insn, val;
if (total == 0)
if (saveall || is_inthandler)
{
insn = emit_move_insn (predec, gen_rtx_REG (SImode, REG_ASTAT));
RTX_FRAME_RELATED_P (insn) = 1;
}
if (total == 0 && !saveall)
return;
val = GEN_INT (-total * 4);
......@@ -458,6 +466,20 @@ expand_prologue_reg_save (rtx spreg, int saveall, bool is_inthandler)
}
insn = emit_insn (pat);
RTX_FRAME_RELATED_P (insn) = 1;
for (i = REG_P7 + 1; i < REG_CC; i++)
if (saveall
|| (is_inthandler
&& (df_regs_ever_live_p (i)
|| (!leaf_function_p () && call_used_regs[i]))))
{
if (i == REG_A0 || i == REG_A1)
insn = emit_move_insn (gen_rtx_MEM (PDImode, predec1),
gen_rtx_REG (PDImode, i));
else
insn = emit_move_insn (predec, gen_rtx_REG (SImode, i));
RTX_FRAME_RELATED_P (insn) = 1;
}
}
/* Emit code to restore registers in the epilogue. SAVEALL is nonzero if we
......@@ -468,12 +490,35 @@ expand_prologue_reg_save (rtx spreg, int saveall, bool is_inthandler)
static void
expand_epilogue_reg_restore (rtx spreg, bool saveall, bool is_inthandler)
{
rtx postinc1 = gen_rtx_POST_INC (SImode, spreg);
rtx postinc = gen_rtx_MEM (SImode, postinc1);
int ndregs = saveall ? 8 : n_dregs_to_save (is_inthandler);
int npregs = saveall ? 6 : n_pregs_to_save (is_inthandler);
int total = ndregs + npregs;
int i, regno;
rtx pat, insn;
/* A slightly crude technique to stop flow from trying to delete "dead"
insns. */
MEM_VOLATILE_P (postinc) = 1;
for (i = REG_CC - 1; i > REG_P7; i--)
if (saveall
|| (is_inthandler
&& (df_regs_ever_live_p (i)
|| (!leaf_function_p () && call_used_regs[i]))))
{
if (i == REG_A0 || i == REG_A1)
{
rtx mem = gen_rtx_MEM (PDImode, postinc1);
MEM_VOLATILE_P (mem) = 1;
emit_move_insn (gen_rtx_REG (PDImode, i), mem);
}
else
emit_move_insn (gen_rtx_REG (SImode, i), postinc);
}
if (total == 0)
return;
......@@ -507,6 +552,9 @@ expand_epilogue_reg_restore (rtx spreg, bool saveall, bool is_inthandler)
insn = emit_insn (pat);
RTX_FRAME_RELATED_P (insn) = 1;
if (saveall || is_inthandler)
emit_move_insn (gen_rtx_REG (SImode, REG_ASTAT), postinc);
}
/* Perform any needed actions needed for a function that is receiving a
......@@ -591,6 +639,7 @@ n_regs_saved_by_prologue (void)
int ndregs = all ? 8 : n_dregs_to_save (is_inthandler);
int npregs = all ? 6 : n_pregs_to_save (is_inthandler);
int n = ndregs + npregs;
int i;
if (all || stack_frame_needed_p ())
/* We use a LINK instruction in this case. */
......@@ -603,23 +652,24 @@ n_regs_saved_by_prologue (void)
n++;
}
if (fkind != SUBROUTINE || all)
/* Increment once for ASTAT. */
n++;
if (fkind != SUBROUTINE)
{
int i;
/* Increment once for ASTAT. */
n++;
/* RETE/X/N. */
if (lookup_attribute ("nesting", attrs))
n++;
for (i = REG_P7 + 1; i < REG_CC; i++)
if (all
|| df_regs_ever_live_p (i)
|| (!leaf_function_p () && call_used_regs[i]))
n += i == REG_A0 || i == REG_A1 ? 2 : 1;
}
for (i = REG_P7 + 1; i < REG_CC; i++)
if (all
|| (fkind != SUBROUTINE
&& (df_regs_ever_live_p (i)
|| (!leaf_function_p () && call_used_regs[i]))))
n += i == REG_A0 || i == REG_A1 ? 2 : 1;
return n;
}
......@@ -882,15 +932,13 @@ do_unlink (rtx spreg, HOST_WIDE_INT frame_size, bool all, int epilogue_p)
SPREG contains (reg:SI REG_SP). */
static void
expand_interrupt_handler_prologue (rtx spreg, e_funkind fkind)
expand_interrupt_handler_prologue (rtx spreg, e_funkind fkind, bool all)
{
int i;
HOST_WIDE_INT frame_size = get_frame_size ();
rtx predec1 = gen_rtx_PRE_DEC (SImode, spreg);
rtx predec = gen_rtx_MEM (SImode, predec1);
rtx insn;
tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
bool all = lookup_attribute ("saveall", attrs) != NULL_TREE;
tree kspisusp = lookup_attribute ("kspisusp", attrs);
if (kspisusp)
......@@ -907,28 +955,12 @@ expand_interrupt_handler_prologue (rtx spreg, e_funkind fkind)
RTX_FRAME_RELATED_P (insn) = 1;
}
insn = emit_move_insn (predec, gen_rtx_REG (SImode, REG_ASTAT));
RTX_FRAME_RELATED_P (insn) = 1;
/* If we're calling other functions, they won't save their call-clobbered
registers, so we must save everything here. */
if (!current_function_is_leaf)
all = true;
expand_prologue_reg_save (spreg, all, true);
for (i = REG_P7 + 1; i < REG_CC; i++)
if (all
|| df_regs_ever_live_p (i)
|| (!leaf_function_p () && call_used_regs[i]))
{
if (i == REG_A0 || i == REG_A1)
insn = emit_move_insn (gen_rtx_MEM (PDImode, predec1),
gen_rtx_REG (PDImode, i));
else
insn = emit_move_insn (predec, gen_rtx_REG (SImode, i));
RTX_FRAME_RELATED_P (insn) = 1;
}
if (lookup_attribute ("nesting", attrs))
{
rtx srcreg = gen_rtx_REG (Pmode, (fkind == EXCPT_HANDLER ? REG_RETX
......@@ -961,13 +993,11 @@ expand_interrupt_handler_prologue (rtx spreg, e_funkind fkind)
SPREG contains (reg:SI REG_SP). */
static void
expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind)
expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind, bool all)
{
int i;
tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
rtx postinc1 = gen_rtx_POST_INC (SImode, spreg);
rtx postinc = gen_rtx_MEM (SImode, postinc1);
tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
bool all = lookup_attribute ("saveall", attrs) != NULL_TREE;
/* A slightly crude technique to stop flow from trying to delete "dead"
insns. */
......@@ -988,25 +1018,8 @@ expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind)
if (!current_function_is_leaf)
all = true;
for (i = REG_CC - 1; i > REG_P7; i--)
if (all
|| df_regs_ever_live_p (i)
|| (!leaf_function_p () && call_used_regs[i]))
{
if (i == REG_A0 || i == REG_A1)
{
rtx mem = gen_rtx_MEM (PDImode, postinc1);
MEM_VOLATILE_P (mem) = 1;
emit_move_insn (gen_rtx_REG (PDImode, i), mem);
}
else
emit_move_insn (gen_rtx_REG (SImode, i), postinc);
}
expand_epilogue_reg_restore (spreg, all, true);
emit_move_insn (gen_rtx_REG (SImode, REG_ASTAT), postinc);
/* Deallocate any space we left on the stack in case we needed to save the
argument registers. */
if (fkind == EXCPT_HANDLER)
......@@ -1051,10 +1064,12 @@ bfin_expand_prologue (void)
rtx spreg = gen_rtx_REG (Pmode, REG_SP);
e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
rtx pic_reg_loaded = NULL_RTX;
tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
bool all = lookup_attribute ("saveall", attrs) != NULL_TREE;
if (fkind != SUBROUTINE)
{
expand_interrupt_handler_prologue (spreg, fkind);
expand_interrupt_handler_prologue (spreg, fkind, all);
return;
}
......@@ -1104,7 +1119,7 @@ bfin_expand_prologue (void)
emit_insn (gen_compare_lt (bfin_cc_rtx, spreg, lim));
emit_insn (gen_trapifcc ());
}
expand_prologue_reg_save (spreg, 0, false);
expand_prologue_reg_save (spreg, all, false);
do_link (spreg, frame_size, false);
......@@ -1126,16 +1141,18 @@ bfin_expand_epilogue (int need_return, int eh_return, bool sibcall_p)
rtx spreg = gen_rtx_REG (Pmode, REG_SP);
e_funkind fkind = funkind (TREE_TYPE (current_function_decl));
int e = sibcall_p ? -1 : 1;
tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
bool all = lookup_attribute ("saveall", attrs) != NULL_TREE;
if (fkind != SUBROUTINE)
{
expand_interrupt_handler_epilogue (spreg, fkind);
expand_interrupt_handler_epilogue (spreg, fkind, all);
return;
}
do_unlink (spreg, get_frame_size (), false, e);
expand_epilogue_reg_restore (spreg, false, false);
expand_epilogue_reg_restore (spreg, all, false);
/* Omit the return insn if this is for a sibcall. */
if (! need_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