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:
parent
f8045c4158
commit
91a19652f8
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
;; ------------------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user