Commit 1f9e4ca1 by Jie Zhang Committed by Bernd Schmidt

bfin-protos.h (bfin_expand_epilogue): Add a third argument of type bool.

	* config/bfin/bfin-protos.h (bfin_expand_epilogue): Add a third
	argument of type bool.
	* config/bfin/bfin.c (add_to_reg): Add epilogue_p as a fourth
	argument. Safely select temporary P register according to it.
	(do_link): Change call site of add_to_reg accordingly.
	(do_unlink): Add epilogue_p as a fourth argument and pass it
	to add_to_reg.
	(expand_interrupt_handler_epilogue): Change call of do_unlink
	accordingly.
	(bfin_expand_prologue): Add a third argument sibcall_p.
	* config/bfin/bfin.md (epilogue): Change call of
	bfin_expand_epilogue accordingly.
	(sibcall_epilogue): Likewise.
	(eh_return_internal): Likewise.

From-SVN: r124542
parent a9b43781
2007-05-08 Jie Zhang <jie.zhang@analog.com>
* config/bfin/bfin-protos.h (bfin_expand_epilogue): Add a third
argument of type bool.
* config/bfin/bfin.c (add_to_reg): Add epilogue_p as a fourth
argument. Safely select temporary P register according to it.
(do_link): Change call site of add_to_reg accordingly.
(do_unlink): Add epilogue_p as a fourth argument and pass it
to add_to_reg.
(expand_interrupt_handler_epilogue): Change call of do_unlink
accordingly.
(bfin_expand_prologue): Add a third argument sibcall_p.
* config/bfin/bfin.md (epilogue): Change call of
bfin_expand_epilogue accordingly.
(sibcall_epilogue): Likewise.
(eh_return_internal): Likewise.
2007-05-08 Uros Bizjak <ubizjak@gmail.com> 2007-05-08 Uros Bizjak <ubizjak@gmail.com>
PR target/31854 PR target/31854
......
...@@ -89,7 +89,7 @@ extern bool bfin_legitimate_address_p (Mmode, rtx, int); ...@@ -89,7 +89,7 @@ extern bool bfin_legitimate_address_p (Mmode, rtx, int);
extern rtx bfin_va_arg (tree, tree); extern rtx bfin_va_arg (tree, tree);
extern void bfin_expand_prologue (void); extern void bfin_expand_prologue (void);
extern void bfin_expand_epilogue (int, int); extern void bfin_expand_epilogue (int, int, bool);
extern int push_multiple_operation (rtx, Mmode); extern int push_multiple_operation (rtx, Mmode);
extern int pop_multiple_operation (rtx, Mmode); extern int pop_multiple_operation (rtx, Mmode);
extern void output_push_multiple (rtx, rtx *); extern void output_push_multiple (rtx, rtx *);
......
...@@ -569,12 +569,14 @@ frame_related_constant_load (rtx reg, HOST_WIDE_INT constant, bool related) ...@@ -569,12 +569,14 @@ frame_related_constant_load (rtx reg, HOST_WIDE_INT constant, bool related)
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
} }
/* Generate efficient code to add a value to a P register. We can use /* Generate efficient code to add a value to a P register.
P1 as a scratch register. Set RTX_FRAME_RELATED_P on the generated Set RTX_FRAME_RELATED_P on the generated insns if FRAME is nonzero.
insns if FRAME is nonzero. */ EPILOGUE_P is zero if this function is called for prologue,
otherwise it's nonzero. And it's less than zero if this is for
sibcall epilogue. */
static void static void
add_to_reg (rtx reg, HOST_WIDE_INT value, int frame) add_to_reg (rtx reg, HOST_WIDE_INT value, int frame, int epilogue_p)
{ {
if (value == 0) if (value == 0)
return; return;
...@@ -584,9 +586,41 @@ add_to_reg (rtx reg, HOST_WIDE_INT value, int frame) ...@@ -584,9 +586,41 @@ add_to_reg (rtx reg, HOST_WIDE_INT value, int frame)
in one instruction. */ in one instruction. */
if (value > 120 || value < -120) if (value > 120 || value < -120)
{ {
rtx tmpreg = gen_rtx_REG (SImode, REG_P1); rtx tmpreg;
rtx tmpreg2;
rtx insn; rtx insn;
tmpreg2 = NULL_RTX;
/* For prologue or normal epilogue, P1 can be safely used
as the temporary register. For sibcall epilogue, we try to find
a call used P register, which will be restored in epilogue.
If we cannot find such a P register, we have to use one I register
to help us. */
if (epilogue_p >= 0)
tmpreg = gen_rtx_REG (SImode, REG_P1);
else
{
int i;
for (i = REG_P0; i <= REG_P5; i++)
if ((regs_ever_live[i] && ! call_used_regs[i])
|| (!TARGET_FDPIC
&& i == PIC_OFFSET_TABLE_REGNUM
&& (current_function_uses_pic_offset_table
|| (TARGET_ID_SHARED_LIBRARY
&& ! current_function_is_leaf))))
break;
if (i <= REG_P5)
tmpreg = gen_rtx_REG (SImode, i);
else
{
tmpreg = gen_rtx_REG (SImode, REG_P1);
tmpreg2 = gen_rtx_REG (SImode, REG_I0);
emit_move_insn (tmpreg2, tmpreg);
}
}
if (frame) if (frame)
frame_related_constant_load (tmpreg, value, TRUE); frame_related_constant_load (tmpreg, value, TRUE);
else else
...@@ -595,6 +629,9 @@ add_to_reg (rtx reg, HOST_WIDE_INT value, int frame) ...@@ -595,6 +629,9 @@ add_to_reg (rtx reg, HOST_WIDE_INT value, int frame)
insn = emit_insn (gen_addsi3 (reg, reg, tmpreg)); insn = emit_insn (gen_addsi3 (reg, reg, tmpreg));
if (frame) if (frame)
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
if (tmpreg2 != NULL_RTX)
emit_move_insn (tmpreg, tmpreg2);
} }
else else
do do
...@@ -702,14 +739,17 @@ do_link (rtx spreg, HOST_WIDE_INT frame_size, bool all) ...@@ -702,14 +739,17 @@ do_link (rtx spreg, HOST_WIDE_INT frame_size, bool all)
rtx insn = emit_insn (pat); rtx insn = emit_insn (pat);
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
} }
add_to_reg (spreg, -frame_size, 1); add_to_reg (spreg, -frame_size, 1, 0);
} }
} }
/* Like do_link, but used for epilogues to deallocate the stack frame. */ /* Like do_link, but used for epilogues to deallocate the stack frame.
EPILOGUE_P is zero if this function is called for prologue,
otherwise it's nonzero. And it's less than zero if this is for
sibcall epilogue. */
static void static void
do_unlink (rtx spreg, HOST_WIDE_INT frame_size, bool all) do_unlink (rtx spreg, HOST_WIDE_INT frame_size, bool all, int epilogue_p)
{ {
frame_size += arg_area_size (); frame_size += arg_area_size ();
...@@ -719,7 +759,7 @@ do_unlink (rtx spreg, HOST_WIDE_INT frame_size, bool all) ...@@ -719,7 +759,7 @@ do_unlink (rtx spreg, HOST_WIDE_INT frame_size, bool all)
{ {
rtx postinc = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, spreg)); rtx postinc = gen_rtx_MEM (Pmode, gen_rtx_POST_INC (Pmode, spreg));
add_to_reg (spreg, frame_size, 0); add_to_reg (spreg, frame_size, 0, epilogue_p);
if (must_save_fp_p ()) if (must_save_fp_p ())
{ {
rtx fpreg = gen_rtx_REG (Pmode, REG_FP); rtx fpreg = gen_rtx_REG (Pmode, REG_FP);
...@@ -842,7 +882,7 @@ expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind) ...@@ -842,7 +882,7 @@ expand_interrupt_handler_epilogue (rtx spreg, e_funkind fkind)
insns. */ insns. */
MEM_VOLATILE_P (postinc) = 1; MEM_VOLATILE_P (postinc) = 1;
do_unlink (spreg, get_frame_size (), all); do_unlink (spreg, get_frame_size (), all, 1);
if (lookup_attribute ("nesting", attrs)) if (lookup_attribute ("nesting", attrs))
{ {
...@@ -968,7 +1008,7 @@ bfin_expand_prologue (void) ...@@ -968,7 +1008,7 @@ bfin_expand_prologue (void)
{ {
if (lim != p2reg) if (lim != p2reg)
emit_move_insn (p2reg, lim); emit_move_insn (p2reg, lim);
add_to_reg (p2reg, offset, 0); add_to_reg (p2reg, offset, 0, 0);
lim = p2reg; lim = p2reg;
} }
emit_insn (gen_compare_lt (bfin_cc_rtx, spreg, lim)); emit_insn (gen_compare_lt (bfin_cc_rtx, spreg, lim));
...@@ -987,13 +1027,15 @@ bfin_expand_prologue (void) ...@@ -987,13 +1027,15 @@ bfin_expand_prologue (void)
/* Generate RTL for the epilogue of the current function. NEED_RETURN is zero /* Generate RTL for the epilogue of the current function. NEED_RETURN is zero
if this is for a sibcall. EH_RETURN is nonzero if we're expanding an if this is for a sibcall. EH_RETURN is nonzero if we're expanding an
eh_return pattern. */ eh_return pattern. SIBCALL_P is true if this is a sibcall epilogue,
false otherwise. */
void void
bfin_expand_epilogue (int need_return, int eh_return) 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;
if (fkind != SUBROUTINE) if (fkind != SUBROUTINE)
{ {
...@@ -1001,7 +1043,7 @@ bfin_expand_epilogue (int need_return, int eh_return) ...@@ -1001,7 +1043,7 @@ bfin_expand_epilogue (int need_return, int eh_return)
return; return;
} }
do_unlink (spreg, get_frame_size (), false); do_unlink (spreg, get_frame_size (), false, e);
expand_epilogue_reg_restore (spreg, false, false); expand_epilogue_reg_restore (spreg, false, false);
......
...@@ -2668,12 +2668,12 @@ ...@@ -2668,12 +2668,12 @@
(define_expand "epilogue" (define_expand "epilogue"
[(const_int 1)] [(const_int 1)]
"" ""
"bfin_expand_epilogue (1, 0); DONE;") "bfin_expand_epilogue (1, 0, 0); DONE;")
(define_expand "sibcall_epilogue" (define_expand "sibcall_epilogue"
[(const_int 1)] [(const_int 1)]
"" ""
"bfin_expand_epilogue (0, 0); DONE;") "bfin_expand_epilogue (0, 0, 1); DONE;")
(define_expand "eh_return" (define_expand "eh_return"
[(unspec_volatile [(match_operand:SI 0 "register_operand" "")] [(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
...@@ -2693,7 +2693,7 @@ ...@@ -2693,7 +2693,7 @@
"#" "#"
"reload_completed" "reload_completed"
[(const_int 1)] [(const_int 1)]
"bfin_expand_epilogue (1, 1); DONE;") "bfin_expand_epilogue (1, 1, 0); DONE;")
(define_insn "link" (define_insn "link"
[(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS)) [(set (mem:SI (plus:SI (reg:SI REG_SP) (const_int -4))) (reg:SI REG_RETS))
......
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