OSDN Git Service

svn ci -m "introduce bank[0,1] registers and fix rte delay slot scheduling"
authorchrbr <chrbr@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 Jun 2007 08:58:53 +0000 (08:58 +0000)
committerchrbr <chrbr@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 Jun 2007 08:58:53 +0000 (08:58 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@125914 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/sh/sh-protos.h
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sh/sh.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/attr-isr.c

index aaf940e..212090b 100644 (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>
 
        PR tree-optimization/32075
index e142b1c..b3c9387 100644 (file)
@@ -168,6 +168,7 @@ extern rtx replace_n_hard_rtx (rtx, rtx *, int , int);
 extern int shmedia_cleanup_truncate (rtx *, void *);
 
 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);
 struct secondary_reload_info;
 extern enum reg_class sh_secondary_reload (bool, rtx, enum reg_class,
index 60520f7..0541256 100644 (file)
@@ -5723,13 +5723,13 @@ pop (int rn)
 static void
 push_regs (HARD_REG_SET *mask, int interrupt_handler)
 {
-  int i;
+  int i = interrupt_handler ? LAST_BANKED_REG + 1 : 0;
   int skip_fpscr = 0;
 
   /* Push PR last; this gives better latencies after the prologue, and
      candidates for the return delay slot when there are no general
      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,
         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))
        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))
     push (PR_REG);
 }
@@ -6675,6 +6682,8 @@ sh_expand_epilogue (bool sibcall_p)
     }
   else /* ! TARGET_SH5 */
     {
+      int last_reg;
+
       save_size = 0;
       if (TEST_HARD_REG_BIT (live_regs_mask, PR_REG))
        {
@@ -6682,7 +6691,21 @@ sh_expand_epilogue (bool sibcall_p)
            emit_insn (gen_blockage ());
          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;
 
@@ -6692,9 +6715,9 @@ sh_expand_epilogue (bool sibcall_p)
            fpscr_deferred = 1;
          else if (j != PR_REG && TEST_HARD_REG_BIT (live_regs_mask, j))
            pop (j);
+
          if (j == FIRST_FP_REG && fpscr_deferred)
            pop (FPSCR_REG);
-
        }
     }
   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 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
    to use in an SHmedia insn pattern.  */
 rtx
index 91a5611..4fe0de8 100644 (file)
@@ -1033,6 +1033,16 @@ extern char sh_additional_register_names[ADDREGNAMES_SIZE] \
 #define FIRST_TARGET_REG TR0_REG
 #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) \
   IN_RANGE ((REGNO), \
            (unsigned HOST_WIDE_INT) FIRST_GENERAL_REG, \
index e85470e..be6294f 100644 (file)
 
 (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)
 (define_attr "hit_stack" "yes,no"
        (cond [(eq (symbol_ref "find_regno_note (insn, REG_INC, SP_REG)")
                  (eq_attr "type" "!pload,prset"))
             (and (eq_attr "interrupt_function" "yes")
                  (ior
-                  (ne (symbol_ref "TARGET_SH3") (const_int 0))
-                  (eq_attr "hit_stack" "no"))))) (nil) (nil)])
+                  (eq (symbol_ref "TARGET_SH3") (const_int 0))
+                  (eq_attr "hit_stack" "no")
+                  (eq_attr "banked" "no"))))) (nil) (nil)])
 
 ;; Since a call implicitly uses the PR register, we can't allow
 ;; a PR register store in a jsr delay slot.
index caf24ed..f38fda0 100644 (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>
 
        PR fortran/32361
index 113ac21..8292fe9 100644 (file)
@@ -16,3 +16,4 @@ void
 /* { dg-final { scan-assembler-times "\[^f\]r\[0-9\]\[ \t\]*," 8 } } */
 /* { dg-final { scan-assembler-not "\[^f\]r1\[0-3\]" } } */
 /* { dg-final { scan-assembler-times "macl" 2} } */
+/* { dg-final { scan-assembler-not "rte.*\n.*r15\[+\],r\[0-7\]\n" } } */