This is the mail archive of the
mailing list for the GCC project.
Re: interaction between shorten_branches and delay slot scheduling
- From: Richard Sandiford <richard at codesourcery dot com>
- To: Daniel Towner <daniel dot towner at picochip dot com>
- Cc: gcc at gcc dot gnu dot org
- Date: Wed, 08 Mar 2006 11:00:06 +0000
- Subject: Re: interaction between shorten_branches and delay slot scheduling
- References: <440DD227.email@example.com>
Daniel Towner <firstname.lastname@example.org> writes:
> Am I doing something fundamentally wrong with the way I am defining the
> length attribute, or the delay slot attribute?
No, I think this just The Way Things Are. I had a similar problem
with the h8sx delayed branch, and ended up reversing the delay slot
and branch if the branch turned out to be too long. Maybe a similar
thing will work for your port?
The full code is in config/h8300, but I've snipped the most relevant
parts below. And no, it's not pretty. ;) I don't think it's too bad
conceptually though. There was never any guarantee that the delay slot
insn would be emitted at the very end; if the target has a limited range
of conditional branch (as MIPS does) then we generate a branch around an
unconditional jump, and the delay slot goes in the branch-around instead.
(define_attr "length" ""
(cond [(eq_attr "type" "branch")
;; In a forward delayed branch, (pc) represents the end of the
;; delay sequence, not the end of the branch itself.
(if_then_else (and (ge (minus (match_dup 0) (pc))
(le (plus (minus (match_dup 0) (pc))
(symbol_ref "DELAY_SLOT_LENGTH (insn)"))
;; Only allow jumps to have a delay slot if we think they might
;; be short enough. This is just an optimization: we don't know
;; for certain whether they will be or not.
(define_delay (and (eq_attr "delay_slot" "jump")
(eq (symbol_ref "get_attr_length (insn)") (const_int 2)))
[(eq_attr "can_delay" "yes")
(label_ref (match_operand 0 "" "")))]
if (final_sequence != 0)
if (get_attr_length (insn) == 2)
return \"bra/s %l0\";
/* The branch isn't short enough to use bra/s. Output the
branch and delay slot in their normal order.
If this is a backward branch, it will now be branching two
bytes further than previously thought. The length-based
test for bra vs. jump is very conservative though, so the
branch will still be within range. */
vec = XVEC (final_sequence, 0);
final_sequence = 0;
final_scan_insn (RTVEC_ELT (vec, 1), asm_out_file, optimize, 1, & seen);
final_scan_insn (RTVEC_ELT (vec, 0), asm_out_file, optimize, 1, & seen);
INSN_DELETED_P (RTVEC_ELT (vec, 1)) = 1;
[(set_attr "type" "branch")
(set (attr "delay_slot")
(if_then_else (ne (symbol_ref "TARGET_H8300SX") (const_int 0))
(set_attr "cc" "none")])