Commit 10f4f635 by J"orn Rennecke Committed by Joern Rennecke

sh.h (OVERRIDE_OPTIONS): Set default values for align_loops and align_jumps if not set.

	* 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.

From-SVN: r63728
parent ebcc6a7e
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> 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 * calls.c (rtx_for_function_call): Take the address as an argument
......
...@@ -1048,6 +1048,7 @@ output_far_jump (insn, op) ...@@ -1048,6 +1048,7 @@ output_far_jump (insn, op)
const char *jump; const char *jump;
int far; int far;
int offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn)); int offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
rtx prev;
this.lab = gen_label_rtx (); this.lab = gen_label_rtx ();
...@@ -1072,10 +1073,10 @@ output_far_jump (insn, op) ...@@ -1072,10 +1073,10 @@ output_far_jump (insn, op)
jump = "mov.l %O0,%1; jmp @%1"; jump = "mov.l %O0,%1; jmp @%1";
} }
/* If we have a scratch register available, use it. */ /* If we have a scratch register available, use it. */
if (GET_CODE (PREV_INSN (insn)) == INSN if (GET_CODE ((prev = prev_nonnote_insn (insn))) == INSN
&& INSN_CODE (PREV_INSN (insn)) == CODE_FOR_indirect_jump_scratch) && 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) 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"; 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); output_asm_insn (jump, &this.lab);
...@@ -3016,7 +3017,7 @@ find_barrier (num_mova, mova, from) ...@@ -3016,7 +3017,7 @@ find_barrier (num_mova, mova, from)
{ {
if (num_mova) if (num_mova)
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 /* We have just passed the barrier in front of the
ADDR_DIFF_VEC, which is stored in found_barrier. Since ADDR_DIFF_VEC, which is stored in found_barrier. Since
...@@ -3454,6 +3455,13 @@ gen_block_redirect (jump, addr, need_block) ...@@ -3454,6 +3455,13 @@ gen_block_redirect (jump, addr, need_block)
rtx insn = emit_insn_before (gen_indirect_jump_scratch rtx insn = emit_insn_before (gen_indirect_jump_scratch
(reg, GEN_INT (INSN_UID (JUMP_LABEL (jump)))) (reg, GEN_INT (INSN_UID (JUMP_LABEL (jump))))
, 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; INSN_CODE (insn) = CODE_FOR_indirect_jump_scratch;
return insn; return insn;
} }
...@@ -3596,14 +3604,14 @@ barrier_align (barrier_or_label) ...@@ -3596,14 +3604,14 @@ barrier_align (barrier_or_label)
return ((TARGET_SMALLCODE return ((TARGET_SMALLCODE
|| ((unsigned) XVECLEN (pat, 1) * GET_MODE_SIZE (GET_MODE (pat)) || ((unsigned) XVECLEN (pat, 1) * GET_MODE_SIZE (GET_MODE (pat))
<= (unsigned)1 << (CACHE_LOG - 2))) <= (unsigned)1 << (CACHE_LOG - 2)))
? 1 << TARGET_SHMEDIA : CACHE_LOG); ? 1 << TARGET_SHMEDIA : align_jumps_log);
} }
if (TARGET_SMALLCODE) if (TARGET_SMALLCODE)
return 0; return 0;
if (! TARGET_SH2 || ! optimize) if (! TARGET_SH2 || ! optimize)
return CACHE_LOG; return align_jumps_log;
/* When fixing up pcloads, a constant table might be inserted just before /* 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 the basic block that ends with the barrier. Thus, we can't trust the
...@@ -3679,7 +3687,7 @@ barrier_align (barrier_or_label) ...@@ -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 /* 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) ...@@ -3704,10 +3712,7 @@ sh_loop_align (label)
|| recog_memoized (next) == CODE_FOR_consttable_2) || recog_memoized (next) == CODE_FOR_consttable_2)
return 0; return 0;
if (TARGET_SH5) return align_loops_log;
return 3;
return 2;
} }
/* Exported to toplev.c. /* Exported to toplev.c.
...@@ -4418,9 +4423,6 @@ split_branches (first) ...@@ -4418,9 +4423,6 @@ split_branches (first)
If relaxing, output the label and pseudo-ops used to link together If relaxing, output the label and pseudo-ops used to link together
calls and the instruction which set the registers. */ 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 /* ??? 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 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 variable length. This is because the second pass of shorten_branches
......
...@@ -489,6 +489,13 @@ do { \ ...@@ -489,6 +489,13 @@ do { \
flag_schedule_insns = 0; \ 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. \ /* Allocation boundary (in *bytes*) for the code of a function. \
SH1: 32 bit alignment is faster, because instructions are always \ SH1: 32 bit alignment is faster, because instructions are always \
fetched as a pair from a longword boundary. \ fetched as a pair from a longword boundary. \
...@@ -496,6 +503,20 @@ do { \ ...@@ -496,6 +503,20 @@ do { \
if (align_functions == 0) \ if (align_functions == 0) \
align_functions \ align_functions \
= TARGET_SMALLCODE ? FUNCTION_BOUNDARY/8 : (1 << CACHE_LOG); \ = 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) } while (0)
/* Target machine storage layout. */ /* Target machine storage layout. */
......
...@@ -391,9 +391,9 @@ ...@@ -391,9 +391,9 @@
(eq_attr "type" "jump") (eq_attr "type" "jump")
(cond [(eq_attr "med_branch_p" "yes") (cond [(eq_attr "med_branch_p" "yes")
(const_int 2) (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")) (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"))) (symbol_ref "code_for_indirect_jump_scratch")))
(if_then_else (eq_attr "braf_branch_p" "yes") (if_then_else (eq_attr "braf_branch_p" "yes")
(const_int 6) (const_int 6)
...@@ -5035,9 +5035,14 @@ ...@@ -5035,9 +5035,14 @@
;; This one has the additional purpose to record a possible scratch register ;; This one has the additional purpose to record a possible scratch register
;; for the following branch. ;; 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" (define_insn "indirect_jump_scratch"
[(set (match_operand:SI 0 "register_operand" "=r") [(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" "TARGET_SH1"
"" ""
[(set_attr "length" "0")]) [(set_attr "length" "0")])
...@@ -5475,6 +5480,19 @@ ...@@ -5475,6 +5480,19 @@
[(set_attr "type" "jump") [(set_attr "type" "jump")
(set_attr "needs_delay_slot" "yes")]) (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" (define_insn "jump_media"
[(set (pc) [(set (pc)
(match_operand:DI 0 "target_operand" "b"))] (match_operand:DI 0 "target_operand" "b"))]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment