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