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
This commit is contained in:
J"orn Rennecke 2003-03-03 19:50:38 +00:00 committed by Joern Rennecke
parent ebcc6a7ec0
commit 10f4f63540
4 changed files with 77 additions and 17 deletions

View 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

View 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

View 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)
/* Target machine storage layout. */

View File

@ -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"))]