aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/sh
diff options
context:
space:
mode:
authorJ"orn Rennecke <joern.rennecke@superh.com>2004-01-14 18:02:42 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2004-01-14 18:02:42 +0000
commitf96540656c6cb530d90e14b2334c9ad3d153e76d (patch)
tree2cc2782f68d7471085c984bdb8c413e60df2f2f8 /gcc/config/sh
parentabbe8578d63babc4d94ecd35a70c281386dfd0ce (diff)
downloadgcc-f96540656c6cb530d90e14b2334c9ad3d153e76d.zip
gcc-f96540656c6cb530d90e14b2334c9ad3d153e76d.tar.gz
gcc-f96540656c6cb530d90e14b2334c9ad3d153e76d.tar.bz2
re PR target/9365 ([SH] segfault in gen_far_branch (config/sh/sh.c))
PR target/9365 * sh.c (gen_block_redirect): Add special handling of RETURN. (gen_far_branch) Don't call gen_stuff_delay_slot if there is no far branch target (i.e. it's a return). From-SVN: r75872
Diffstat (limited to 'gcc/config/sh')
-rw-r--r--gcc/config/sh/sh.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 8159c5a..43657e4 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -3368,6 +3368,14 @@ gen_block_redirect (rtx jump, int addr, int need_block)
else if (recog_memoized (prev) == CODE_FOR_block_branch_redirect)
need_block = 0;
}
+ if (GET_CODE (PATTERN (jump)) == RETURN)
+ {
+ if (! need_block)
+ return prev;
+ /* Reorg even does nasty things with return insns that cause branches
+ to go out of range - see find_end_label and callers. */
+ return emit_insn_before (gen_block_branch_redirect (GEN_INT (0)) , jump);
+ }
/* We can't use JUMP_LABEL here because it might be undefined
when not optimizing. */
dest = XEXP (SET_SRC (PATTERN (jump)), 0);
@@ -3535,11 +3543,16 @@ gen_far_branch (struct far_branch *bp)
JUMP_LABEL (jump) = bp->far_label;
if (! invert_jump (insn, label, 1))
abort ();
- (emit_insn_after
- (gen_stuff_delay_slot
- (GEN_INT (INSN_UID (XEXP (SET_SRC (PATTERN (jump)), 0))),
- GEN_INT (recog_memoized (insn) == CODE_FOR_branch_false)),
- insn));
+ /* If we are branching around a jump (rather than a return), prevent
+ reorg from using an insn from the jump target as the delay slot insn -
+ when reorg did this, it pessimized code (we rather hide the delay slot)
+ and it could cause branches to go out of range. */
+ if (bp->far_label)
+ (emit_insn_after
+ (gen_stuff_delay_slot
+ (GEN_INT (INSN_UID (XEXP (SET_SRC (PATTERN (jump)), 0))),
+ GEN_INT (recog_memoized (insn) == CODE_FOR_branch_false)),
+ insn));
/* Prevent reorg from undoing our splits. */
gen_block_redirect (jump, bp->address += 2, 2);
}