diff options
author | J"orn Rennecke <joern.rennecke@superh.com> | 2004-01-14 18:02:42 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 2004-01-14 18:02:42 +0000 |
commit | f96540656c6cb530d90e14b2334c9ad3d153e76d (patch) | |
tree | 2cc2782f68d7471085c984bdb8c413e60df2f2f8 /gcc/config/sh | |
parent | abbe8578d63babc4d94ecd35a70c281386dfd0ce (diff) | |
download | gcc-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.c | 23 |
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); } |