sh.c (push_regs): Emit movml for interrupt handler when possible.

* config/sh/sh.c (push_regs): Emit movml for interrupt handler
	when possible.
	(sh_expand_epilogue): Likewise.
	* config/sh/sh.md (movml_push_banked): New insn.
	(movml_pop_banked): Likewise.
	* gcc.dg/attr-isr.c: Skip test for -m2a.  Don't	run on sh2a*-*-*.


Co-Authored-By: Kaz Kojima <kkojima@gcc.gnu.org>

From-SVN: r163602
This commit is contained in:
Naveen H.S 2010-08-27 23:29:41 +00:00 committed by Kaz Kojima
parent f8045c4158
commit 91a19652f8
5 changed files with 124 additions and 7 deletions

View File

@ -1,3 +1,12 @@
2010-08-27 Naveen H.S <naveen.S@kpitcummins.com>
Kaz Kojima <kkojima@gcc.gnu.org>
* config/sh/sh.c (push_regs): Emit movml for interrupt handler
when possible.
(sh_expand_epilogue): Likewise.
* config/sh/sh.md (movml_push_banked): New insn.
(movml_pop_banked): Likewise.
2010-08-28 Bernd Schmidt <bernds@codesourcery.com>
* genautomata.c (gen_regexp_repeat, gen_regexp_allof,

View File

@ -6407,9 +6407,50 @@ push_regs (HARD_REG_SET *mask, int interrupt_handler)
/* Push banked registers last to improve delay slot opportunities. */
if (interrupt_handler)
for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
if (TEST_HARD_REG_BIT (*mask, i))
push (i);
{
bool use_movml = false;
if (TARGET_SH2A)
{
unsigned int count = 0;
for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
if (TEST_HARD_REG_BIT (*mask, i))
count++;
else
break;
/* Use movml when all banked registers are pushed. */
if (count == LAST_BANKED_REG - FIRST_BANKED_REG + 1)
use_movml = true;
}
if (use_movml)
{
rtx x, mem, reg, set;
rtx sp_reg = gen_rtx_REG (SImode, STACK_POINTER_REGNUM);
/* We must avoid scheduling multiple store insn with another
insns. */
emit_insn (gen_blockage ());
x = gen_movml_push_banked (sp_reg);
x = frame_insn (x);
for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
{
mem = gen_rtx_MEM (SImode, plus_constant (sp_reg, i * 4));
reg = gen_rtx_REG (SImode, i);
add_reg_note (x, REG_CFA_OFFSET, gen_rtx_SET (SImode, mem, reg));
}
set = gen_rtx_SET (SImode, sp_reg, plus_constant (sp_reg, - 32));
add_reg_note (x, REG_CFA_ADJUST_CFA, set);
emit_insn (gen_blockage ());
}
else
for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
if (TEST_HARD_REG_BIT (*mask, i))
push (i);
}
/* Don't push PR register for an ISR with RESBANK attribute assigned. */
if (TEST_HARD_REG_BIT (*mask, PR_REG) && !sh_cfun_resbank_handler_p ())
@ -7347,9 +7388,37 @@ sh_expand_epilogue (bool sibcall_p)
delay slot. RTE switches banks before the ds instruction. */
if (current_function_interrupt)
{
for (i = LAST_BANKED_REG; i >= FIRST_BANKED_REG; i--)
if (TEST_HARD_REG_BIT (live_regs_mask, i))
pop (i);
bool use_movml = false;
if (TARGET_SH2A)
{
unsigned int count = 0;
for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
if (TEST_HARD_REG_BIT (live_regs_mask, i))
count++;
else
break;
/* Use movml when all banked register are poped. */
if (count == LAST_BANKED_REG - FIRST_BANKED_REG + 1)
use_movml = true;
}
if (use_movml)
{
rtx sp_reg = gen_rtx_REG (SImode, STACK_POINTER_REGNUM);
/* We must avoid scheduling multiple load insn with another
insns. */
emit_insn (gen_blockage ());
emit_insn (gen_movml_pop_banked (sp_reg));
emit_insn (gen_blockage ());
}
else
for (i = LAST_BANKED_REG; i >= FIRST_BANKED_REG; i--)
if (TEST_HARD_REG_BIT (live_regs_mask, i))
pop (i);
last_reg = FIRST_PSEUDO_REGISTER - LAST_BANKED_REG - 1;
}

View File

@ -9216,6 +9216,39 @@ mov.l\\t1f,r0\\n\\
""
[(set_attr "length" "0")])
;; Define movml instructions for SH2A target. Currently they are
;; used to push and pop all banked registers only.
(define_insn "movml_push_banked"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus (match_dup 0) (const_int -32)))
(set (mem:SI (plus:SI (match_dup 0) (const_int 28))) (reg:SI R7_REG))
(set (mem:SI (plus:SI (match_dup 0) (const_int 24))) (reg:SI R6_REG))
(set (mem:SI (plus:SI (match_dup 0) (const_int 20))) (reg:SI R5_REG))
(set (mem:SI (plus:SI (match_dup 0) (const_int 16))) (reg:SI R4_REG))
(set (mem:SI (plus:SI (match_dup 0) (const_int 12))) (reg:SI R3_REG))
(set (mem:SI (plus:SI (match_dup 0) (const_int 8))) (reg:SI R2_REG))
(set (mem:SI (plus:SI (match_dup 0) (const_int 4))) (reg:SI R1_REG))
(set (mem:SI (plus:SI (match_dup 0) (const_int 0))) (reg:SI R0_REG))]
"TARGET_SH2A && REGNO (operands[0]) == 15"
"movml.l\tr7,@-r15"
[(set_attr "in_delay_slot" "no")])
(define_insn "movml_pop_banked"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus (match_dup 0) (const_int 32)))
(set (reg:SI R0_REG) (mem:SI (plus:SI (match_dup 0) (const_int -32))))
(set (reg:SI R1_REG) (mem:SI (plus:SI (match_dup 0) (const_int -28))))
(set (reg:SI R2_REG) (mem:SI (plus:SI (match_dup 0) (const_int -24))))
(set (reg:SI R3_REG) (mem:SI (plus:SI (match_dup 0) (const_int -20))))
(set (reg:SI R4_REG) (mem:SI (plus:SI (match_dup 0) (const_int -16))))
(set (reg:SI R5_REG) (mem:SI (plus:SI (match_dup 0) (const_int -12))))
(set (reg:SI R6_REG) (mem:SI (plus:SI (match_dup 0) (const_int -8))))
(set (reg:SI R7_REG) (mem:SI (plus:SI (match_dup 0) (const_int -4))))]
"TARGET_SH2A && REGNO (operands[0]) == 15"
"movml.l\t@r15+,r7"
[(set_attr "in_delay_slot" "no")])
;; ------------------------------------------------------------------------
;; Scc instructions
;; ------------------------------------------------------------------------

View File

@ -1,3 +1,8 @@
2010-08-27 Naveen H.S <naveen.S@kpitcummins.com>
Kaz Kojima <kkojima@gcc.gnu.org>
* gcc.dg/attr-isr.c: Skip test for -m2a. Don't run on sh2a*-*-*.
2010-08-23 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/ppc-fpconv-1.c: New test for integer to

View File

@ -1,4 +1,5 @@
/* { dg-do compile { target { { sh-*-* sh[1234ble]*-*-* } && nonpic } } } */
/* { dg-do compile { target { { { sh-*-* sh[1234ble]*-*-* } && { ! sh2a*-*-* } } && nonpic } } } */
/* { dg-skip-if "" { "sh*-*-*" } { "-m2a*" } { "" } } */
/* { dg-options "-O" } */
extern void foo ();