svn ci -m "introduce bank[0,1] registers and fix rte delay slot scheduling"

2007-06-21  Christian Bruel  <christian.bruel@st.com>

	* config/sh/sh-protos.h (sh_loads_bankedreg_p): Declare.
	* config/sh/sh.c (sh_loads_bankedreg_p): New function.
	(push_regs): Changed saving order or banked registers.
	(sh_expand_epilogue): Likewise.
	* config/sh/sh.h (BANKED_REGISTER_P): New macro.
	(FIRST_BANKED_REG): Likewise.
	(LAST_BANKED_REG): Likewise.
	* config/sh/sh.md (banked) New attribute.
	(in_delay_slot): Check banked attribute.

2007-06-21  Christian Bruel  <christian.bruel@st.com>

	* gcc.dg/attr-isr.c: Test delay slot content.

From-SVN: r125914
This commit is contained in:
Christian Bruel 2007-06-21 10:58:53 +02:00 committed by Christian Bruel
parent 86488aa376
commit 5c7cafa8dc
7 changed files with 78 additions and 6 deletions

View File

@ -1,3 +1,15 @@
2007-06-21 Christian Bruel <christian.bruel@st.com>
* config/sh/sh-protos.h (sh_loads_bankedreg_p): Declare.
* config/sh/sh.c (sh_loads_bankedreg_p): New function.
(push_regs): Changed saving order or banked registers.
(sh_expand_epilogue): Likewise.
* config/sh/sh.h (BANKED_REGISTER_P): New macro.
(FIRST_BANKED_REG): Likewise.
(LAST_BANKED_REG): Likewise.
* config/sh/sh.md (banked) New attribute.
(in_delay_slot): Check banked attribute.
2007-06-20 Sebastian Pop <sebpop@gmail.com> 2007-06-20 Sebastian Pop <sebpop@gmail.com>
PR tree-optimization/32075 PR tree-optimization/32075

View File

@ -168,6 +168,7 @@ extern rtx replace_n_hard_rtx (rtx, rtx *, int , int);
extern int shmedia_cleanup_truncate (rtx *, void *); extern int shmedia_cleanup_truncate (rtx *, void *);
extern int sh_contains_memref_p (rtx); extern int sh_contains_memref_p (rtx);
extern int sh_loads_bankedreg_p (rtx);
extern rtx shmedia_prepare_call_address (rtx fnaddr, int is_sibcall); extern rtx shmedia_prepare_call_address (rtx fnaddr, int is_sibcall);
struct secondary_reload_info; struct secondary_reload_info;
extern enum reg_class sh_secondary_reload (bool, rtx, enum reg_class, extern enum reg_class sh_secondary_reload (bool, rtx, enum reg_class,

View File

@ -5723,13 +5723,13 @@ pop (int rn)
static void static void
push_regs (HARD_REG_SET *mask, int interrupt_handler) push_regs (HARD_REG_SET *mask, int interrupt_handler)
{ {
int i; int i = interrupt_handler ? LAST_BANKED_REG + 1 : 0;
int skip_fpscr = 0; int skip_fpscr = 0;
/* Push PR last; this gives better latencies after the prologue, and /* Push PR last; this gives better latencies after the prologue, and
candidates for the return delay slot when there are no general candidates for the return delay slot when there are no general
registers pushed. */ registers pushed. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) for (; i < FIRST_PSEUDO_REGISTER; i++)
{ {
/* If this is an interrupt handler, and the SZ bit varies, /* If this is an interrupt handler, and the SZ bit varies,
and we have to push any floating point register, we need and we have to push any floating point register, we need
@ -5749,6 +5749,13 @@ push_regs (HARD_REG_SET *mask, int interrupt_handler)
&& TEST_HARD_REG_BIT (*mask, i)) && TEST_HARD_REG_BIT (*mask, i))
push (i); push (i);
} }
/* 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);
if (TEST_HARD_REG_BIT (*mask, PR_REG)) if (TEST_HARD_REG_BIT (*mask, PR_REG))
push (PR_REG); push (PR_REG);
} }
@ -6675,6 +6682,8 @@ sh_expand_epilogue (bool sibcall_p)
} }
else /* ! TARGET_SH5 */ else /* ! TARGET_SH5 */
{ {
int last_reg;
save_size = 0; save_size = 0;
if (TEST_HARD_REG_BIT (live_regs_mask, PR_REG)) if (TEST_HARD_REG_BIT (live_regs_mask, PR_REG))
{ {
@ -6682,7 +6691,21 @@ sh_expand_epilogue (bool sibcall_p)
emit_insn (gen_blockage ()); emit_insn (gen_blockage ());
pop (PR_REG); pop (PR_REG);
} }
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
/* Banked registers are poped first to avoid being scheduled in the
delay slot. RTE switches banks before the ds instruction. */
if (current_function_interrupt)
{
for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
if (TEST_HARD_REG_BIT (live_regs_mask, i))
pop (LAST_BANKED_REG - i);
last_reg = FIRST_PSEUDO_REGISTER - LAST_BANKED_REG - 1;
}
else
last_reg = FIRST_PSEUDO_REGISTER;
for (i = 0; i < last_reg; i++)
{ {
int j = (FIRST_PSEUDO_REGISTER - 1) - i; int j = (FIRST_PSEUDO_REGISTER - 1) - i;
@ -6692,9 +6715,9 @@ sh_expand_epilogue (bool sibcall_p)
fpscr_deferred = 1; fpscr_deferred = 1;
else if (j != PR_REG && TEST_HARD_REG_BIT (live_regs_mask, j)) else if (j != PR_REG && TEST_HARD_REG_BIT (live_regs_mask, j))
pop (j); pop (j);
if (j == FIRST_FP_REG && fpscr_deferred) if (j == FIRST_FP_REG && fpscr_deferred)
pop (FPSCR_REG); pop (FPSCR_REG);
} }
} }
if (target_flags != save_flags && ! current_function_interrupt) if (target_flags != save_flags && ! current_function_interrupt)
@ -10839,6 +10862,20 @@ sh_contains_memref_p (rtx insn)
return for_each_rtx (&PATTERN (insn), &sh_contains_memref_p_1, NULL); return for_each_rtx (&PATTERN (insn), &sh_contains_memref_p_1, NULL);
} }
/* Return nonzero iff INSN loads a banked register. */
int
sh_loads_bankedreg_p (rtx insn)
{
if (GET_CODE (PATTERN (insn)) == SET)
{
rtx op = SET_DEST (PATTERN(insn));
if (REG_P (op) && BANKED_REGISTER_P (REGNO (op)))
return 1;
}
return 0;
}
/* FNADDR is the MEM expression from a call expander. Return an address /* FNADDR is the MEM expression from a call expander. Return an address
to use in an SHmedia insn pattern. */ to use in an SHmedia insn pattern. */
rtx rtx

View File

@ -1033,6 +1033,16 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
#define FIRST_TARGET_REG TR0_REG #define FIRST_TARGET_REG TR0_REG
#define LAST_TARGET_REG (FIRST_TARGET_REG + (TARGET_SHMEDIA ? 7 : -1)) #define LAST_TARGET_REG (FIRST_TARGET_REG + (TARGET_SHMEDIA ? 7 : -1))
/* Registers that can be accessed through bank0 or bank1 depending on sr.md. */
#define FIRST_BANKED_REG R0_REG
#define LAST_BANKED_REG R7_REG
#define BANKED_REGISTER_P(REGNO) \
IN_RANGE ((REGNO), \
(unsigned HOST_WIDE_INT) FIRST_BANKED_REG, \
(unsigned HOST_WIDE_INT) LAST_BANKED_REG)
#define GENERAL_REGISTER_P(REGNO) \ #define GENERAL_REGISTER_P(REGNO) \
IN_RANGE ((REGNO), \ IN_RANGE ((REGNO), \
(unsigned HOST_WIDE_INT) FIRST_GENERAL_REG, \ (unsigned HOST_WIDE_INT) FIRST_GENERAL_REG, \

View File

@ -463,6 +463,12 @@
(define_attr "needs_delay_slot" "yes,no" (const_string "no")) (define_attr "needs_delay_slot" "yes,no" (const_string "no"))
(define_attr "banked" "yes,no"
(cond [(eq (symbol_ref "sh_loads_bankedreg_p (insn)")
(const_int 1))
(const_string "yes")]
(const_string "no")))
;; ??? This should be (nil) instead of (const_int 0) ;; ??? This should be (nil) instead of (const_int 0)
(define_attr "hit_stack" "yes,no" (define_attr "hit_stack" "yes,no"
(cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)") (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
@ -541,8 +547,9 @@
(eq_attr "type" "!pload,prset")) (eq_attr "type" "!pload,prset"))
(and (eq_attr "interrupt_function" "yes") (and (eq_attr "interrupt_function" "yes")
(ior (ior
(ne (symbol_ref "TARGET_SH3") (const_int 0)) (eq (symbol_ref "TARGET_SH3") (const_int 0))
(eq_attr "hit_stack" "no"))))) (nil) (nil)]) (eq_attr "hit_stack" "no")
(eq_attr "banked" "no"))))) (nil) (nil)])
;; Since a call implicitly uses the PR register, we can't allow ;; Since a call implicitly uses the PR register, we can't allow
;; a PR register store in a jsr delay slot. ;; a PR register store in a jsr delay slot.

View File

@ -1,3 +1,7 @@
2007-06-21 Christian Bruel <christian.bruel@st.com>
* gcc.dg/attr-isr.c: Test delay slot content.
2007-06-20 Jerry DeLisle <jvdelisle@gcc.gnu.org> 2007-06-20 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/32361 PR fortran/32361

View File

@ -16,3 +16,4 @@ void
/* { dg-final { scan-assembler-times "\[^f\]r\[0-9\]\[ \t\]*," 8 } } */ /* { dg-final { scan-assembler-times "\[^f\]r\[0-9\]\[ \t\]*," 8 } } */
/* { dg-final { scan-assembler-not "\[^f\]r1\[0-3\]" } } */ /* { dg-final { scan-assembler-not "\[^f\]r1\[0-3\]" } } */
/* { dg-final { scan-assembler-times "macl" 2} } */ /* { dg-final { scan-assembler-times "macl" 2} } */
/* { dg-final { scan-assembler-not "rte.*\n.*r15\[+\],r\[0-7\]\n" } } */