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:
parent
ebcc6a7ec0
commit
10f4f63540
@ -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
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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"))]
|
||||
|
Loading…
Reference in New Issue
Block a user