http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54762
Bug #: 54762 Summary: [SH] Utilize zero-displacement branches for conditional far branches Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: olege...@gcc.gnu.org Target: sh*-*-* When the displacement of a conditional branch is too small the branch is 'widened', which results in code like this (a random snippet from CSiBE): mov.l r8,@-r15 sts.l pr,@-r15 mov.l @(32,r4),r8 tst r8,r8 bt .L293 mov.l @r8,r1 cmp/eq r4,r1 bt .L295 <<< .L293: bra .L297 <<< mov #-2,r6 <<< .L295: mov.l @(4,r8),r2 < lots of code > .L297: In such cases zero-displacement branches could be utilized to branch around the far branch. For example: mov.l r8,@-r15 sts.l pr,@-r15 mov.l @(32,r4),r8 tst r8,r8 bf 0f bra .L297 0: mov #-2,r6 mov.l @r8,r1 cmp/eq r4,r1 bt 0f bra .L297 0: mov #-2,r6 mov.l @(4,r8),r2 < lots of code > .L297: Maybe this could be achieved by adding variations to the existing "branch_true" and "branch_false" patterns like: (define_insn "branch_true_far" [(set (pc) (if_then_else (ne (match_operand 1 "t_reg_operand" "") (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "TARGET_SH1" { return "bf 0f" "\n" " bra %l0" "\n" "0: %#"; } [(set_attr "type" "cbranch") (set_attr "needs_delay_slot" "yes") (set_attr "length" "4")]) ;; not sure whether length should be 4 or 6 ;; in this case...