From 2a6493a579df35f164cd186d7d35e2f5e2e2f87f Mon Sep 17 00:00:00 2001 From: amylaar Date: Mon, 3 Mar 2003 19:50:38 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@63728 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 19 +++++++++++++++++++ gcc/config/sh/sh.c | 30 ++++++++++++++++-------------- gcc/config/sh/sh.h | 21 +++++++++++++++++++++ gcc/config/sh/sh.md | 24 +++++++++++++++++++++--- 4 files changed, 77 insertions(+), 17 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 988250c800c..436ee289aa4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +Mon Mar 3 19:47:26 2003 J"orn Rennecke + + * 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 * calls.c (rtx_for_function_call): Take the address as an argument diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 3c7549b29b5..e3f9a26398b 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -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 diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index 82325b89d81..5e1712a18dc 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -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) /* Target machine storage layout. */ diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index f26d2b37e50..65dd6967e86 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -391,9 +391,9 @@ (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) @@ -5035,9 +5035,14 @@ ;; 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")]) @@ -5475,6 +5480,19 @@ [(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"))] -- 2.11.0