OSDN Git Service

* sh.h (OVERRIDE_OPTIONS): Set default values for align_loops
authoramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 3 Mar 2003 19:50:38 +0000 (19:50 +0000)
committeramylaar <amylaar@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 3 Mar 2003 19:50:38 +0000 (19:50 +0000)
and align_jumps if not set.
Force align_jumps to be at least 2.
When relaxing, force align_functions to be at least the maximum of
align_loops, align_jumps and 4.
* sh.c (find_barrier, barrier_align): Honour align_jumps_log.
(sh_loop_align): Honour align_loops_log.

* sh.md (length attribute): Use prev_nonnote_insn instead of PREV_INSN
to check for indirect_jump_scratch.
(indirect_jump_scratch): Add second set.
* sh.c (output_far_jump): Use prev_nonnote_insn instead of PREV_INSN
when looking for indirect_jump_scratch.
Extract scratch register taking new structure of indirect_jump_scratch
into account.
(gen_block_redirect): Set INSN_SCOPE for indirect_jump_scratch.

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

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.h
gcc/config/sh/sh.md

index 988250c..436ee28 100644 (file)
@@ -1,3 +1,22 @@
+Mon Mar  3 19:47:26 2003  J"orn Rennecke <joern.rennecke@superh.com>
+
+       * sh.h (OVERRIDE_OPTIONS): Set default values for align_loops
+       and align_jumps if not set.
+       Force align_jumps to be at least 2.
+       When relaxing, force align_functions to be at least the maximum of
+       align_loops, align_jumps and 4.
+       * sh.c (find_barrier, barrier_align): Honour align_jumps_log.
+       (sh_loop_align): Honour align_loops_log.
+
+       * sh.md (length attribute): Use prev_nonnote_insn instead of PREV_INSN
+       to check for indirect_jump_scratch.
+       (indirect_jump_scratch): Add second set.
+       * sh.c (output_far_jump): Use prev_nonnote_insn instead of PREV_INSN
+       when looking for indirect_jump_scratch.
+       Extract scratch register taking new structure of indirect_jump_scratch
+       into account.
+       (gen_block_redirect): Set INSN_SCOPE for indirect_jump_scratch.
+
 Mon Mar  3 19:07:21 CET 2003  Jan Hubicka  <jh@suse.cz>
 
        * calls.c (rtx_for_function_call): Take the address as an argument
index 3c7549b..e3f9a26 100644 (file)
@@ -1048,6 +1048,7 @@ output_far_jump (insn, op)
   const char *jump;
   int far;
   int offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
+  rtx prev;
 
   this.lab = gen_label_rtx ();
 
@@ -1072,10 +1073,10 @@ output_far_jump (insn, op)
        jump = "mov.l   %O0,%1; jmp     @%1";
     }
   /* If we have a scratch register available, use it.  */
-  if (GET_CODE (PREV_INSN (insn)) == INSN
-      && INSN_CODE (PREV_INSN (insn)) == CODE_FOR_indirect_jump_scratch)
+  if (GET_CODE ((prev = prev_nonnote_insn (insn))) == INSN
+      && INSN_CODE (prev) == CODE_FOR_indirect_jump_scratch)
     {
-      this.reg = SET_DEST (PATTERN (PREV_INSN (insn)));
+      this.reg = SET_DEST (XVECEXP (PATTERN (prev), 0, 0));
       if (REGNO (this.reg) == R0_REG && flag_pic && ! TARGET_SH2)
        jump = "mov.l   r1,@-r15; mova  %O0,r0; mov.l   @r0,r1; add     r1,r0; mov.l    @r15+,r1; jmp   @%1";
       output_asm_insn (jump, &this.lab);
@@ -3016,7 +3017,7 @@ find_barrier (num_mova, mova, from)
        {
          if (num_mova)
            num_mova--;
-         if (barrier_align (next_real_insn (from)) == CACHE_LOG)
+         if (barrier_align (next_real_insn (from)) == align_jumps_log)
            {
              /* We have just passed the barrier in front of the
                 ADDR_DIFF_VEC, which is stored in found_barrier.  Since
@@ -3454,6 +3455,13 @@ gen_block_redirect (jump, addr, need_block)
       rtx insn = emit_insn_before (gen_indirect_jump_scratch
                                   (reg, GEN_INT (INSN_UID (JUMP_LABEL (jump))))
                                   , jump);
+      /* ??? We would like this to have the scope of the jump, but that
+        scope will change when a delay slot insn of an inner scope is added.
+        Hence, after delay slot scheduling, we'll have to expect
+        NOTE_INSN_BLOCK_END notes between the indirect_jump_scratch and
+        the jump.  */
+        
+      INSN_SCOPE (insn) = INSN_SCOPE (jump);
       INSN_CODE (insn) = CODE_FOR_indirect_jump_scratch;
       return insn;
     }
@@ -3596,14 +3604,14 @@ barrier_align (barrier_or_label)
       return ((TARGET_SMALLCODE
               || ((unsigned) XVECLEN (pat, 1) * GET_MODE_SIZE (GET_MODE (pat))
                   <= (unsigned)1 << (CACHE_LOG - 2)))
-             ? 1 << TARGET_SHMEDIA : CACHE_LOG);
+             ? 1 << TARGET_SHMEDIA : align_jumps_log);
     }
 
   if (TARGET_SMALLCODE)
     return 0;
 
   if (! TARGET_SH2 || ! optimize)
-    return CACHE_LOG;
+    return align_jumps_log;
 
   /* When fixing up pcloads, a constant table might be inserted just before
      the basic block that ends with the barrier.  Thus, we can't trust the
@@ -3679,7 +3687,7 @@ barrier_align (barrier_or_label)
        }
     }
   
-  return CACHE_LOG;
+  return align_jumps_log;
 }
 
 /* If we are inside a phony loop, almost any kind of label can turn up as the
@@ -3704,10 +3712,7 @@ sh_loop_align (label)
       || recog_memoized (next) == CODE_FOR_consttable_2)
     return 0;
 
-  if (TARGET_SH5)
-    return 3;
-
-  return 2;
+  return align_loops_log;
 }
 
 /* Exported to toplev.c.
@@ -4418,9 +4423,6 @@ split_branches (first)
    If relaxing, output the label and pseudo-ops used to link together
    calls and the instruction which set the registers.  */
 
-/* ??? This is unnecessary, and probably should be deleted.  This makes
-   the insn_addresses declaration above unnecessary.  */
-
 /* ??? The addresses printed by this routine for insns are nonsense for
    insns which are inside of a sequence where none of the inner insns have
    variable length.  This is because the second pass of shorten_branches
index 82325b8..5e1712a 100644 (file)
@@ -489,6 +489,13 @@ do {                                                                       \
       flag_schedule_insns = 0;                                         \
     }                                                                  \
                                                                        \
+  if (align_loops == 0)                                                        \
+    align_loops =  1 << (TARGET_SH5 ? 3 : 2);                          \
+  if (align_jumps == 0)                                                        \
+    align_jumps = 1 << CACHE_LOG;                                      \
+  else if (align_jumps <= 1)                                           \
+    align_jumps = 2;                                                   \
+                                                                       \
   /* Allocation boundary (in *bytes*) for the code of a function.      \
      SH1: 32 bit alignment is faster, because instructions are always  \
      fetched as a pair from a longword boundary.                       \
@@ -496,6 +503,20 @@ do {                                                                       \
   if (align_functions == 0)                                            \
     align_functions                                                    \
       = TARGET_SMALLCODE ? FUNCTION_BOUNDARY/8 : (1 << CACHE_LOG);     \
+  /* The linker relaxation code breaks when a function contains                \
+     alignments that are larger than that at the start of a            \
+     compilation unit.  */                                             \
+  if (TARGET_RELAX)                                                    \
+    {                                                                  \
+      int min_align                                                    \
+       = align_loops > align_jumps ? align_loops : align_jumps;        \
+                                                                       \
+      /* Also take possible .long constants / mova tables int account. */\
+      if (min_align < 4)                                               \
+       min_align = 4;                                                  \
+      if (align_functions < min_align)                                 \
+       align_functions = min_align;                                    \
+    }                                                                  \
 } while (0)
 \f
 /* Target machine storage layout.  */
index f26d2b3..65dd696 100644 (file)
         (eq_attr "type" "jump")
         (cond [(eq_attr "med_branch_p" "yes")
                (const_int 2)
-               (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
+               (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
                         (symbol_ref "INSN"))
-                    (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
+                    (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
                         (symbol_ref "code_for_indirect_jump_scratch")))
                (if_then_else (eq_attr "braf_branch_p" "yes")
                              (const_int 6)
 
 ;; This one has the additional purpose to record a possible scratch register
 ;; for the following branch.
+;; ??? Unfortunately, just setting the scratch register is not good enough,
+;; because the insn then might be deemed dead and deleted.  And we can't
+;; make the use in the jump insn explicit because that would disable
+;; delay slot scheduling from the target.
 (define_insn "indirect_jump_scratch"
   [(set (match_operand:SI 0 "register_operand" "=r")
-       (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
+       (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR)) 
+   (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
   "TARGET_SH1"
   ""
   [(set_attr "length" "0")])
   [(set_attr "type" "jump")
    (set_attr "needs_delay_slot" "yes")])
 
+;; ??? It would be much saner to explicitly use the scratch register
+;; in the jump insn, and have indirect_jump_scratch only set it,
+;; but fill_simple_delay_slots would refuse to do delay slot filling
+;; from the target then, as it uses simplejump_p.
+;;(define_insn "jump_compact_far"
+;;  [(set (pc)
+;;     (label_ref (match_operand 0 "" "")))
+;;   (use (match_operand 1 "register_operand" "r")]
+;;  "TARGET_SH1"
+;;  "* return output_far_jump(insn, operands[0], operands[1]);"
+;;  [(set_attr "type" "jump")
+;;   (set_attr "needs_delay_slot" "yes")])
+
 (define_insn "jump_media"
   [(set (pc)
        (match_operand:DI 0 "target_operand" "b"))]