diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2004-07-04 22:48:29 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2004-07-04 22:48:29 +0000 |
commit | 2107286fcd3b0aa210f88b6f533da7921e9f92c9 (patch) | |
tree | 7d81e49523f4b5c21f90e543fe411dacc03d084c /gnu | |
parent | f221546ae378002ecbe2e7aea2d61437023335c5 (diff) |
Disable optimize_reg_copy_3() on m68k platforms.
This is a workaround for lines 1055-1057 of tcp_input.c being miscompiled,
though the problem looks like missing use/clobber qualifiers in the
extendplussidi insn, rather than a specific optimize_reg_copy_3() issue.
A proper fix may be devised in the future, in the meantime this allows
m68k platforms to be back in track.
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/egcs/gcc/config/m68k/openbsd.h | 3 | ||||
-rw-r--r-- | gnu/egcs/gcc/regmove.c | 36 |
2 files changed, 31 insertions, 8 deletions
diff --git a/gnu/egcs/gcc/config/m68k/openbsd.h b/gnu/egcs/gcc/config/m68k/openbsd.h index 107cc5446f8..67d877c8d39 100644 --- a/gnu/egcs/gcc/config/m68k/openbsd.h +++ b/gnu/egcs/gcc/config/m68k/openbsd.h @@ -59,6 +59,9 @@ Boston, MA 02111-1307, USA. */ /* Every structure or union's size must be a multiple of 2 bytes. */ #define STRUCTURE_SIZE_BOUNDARY 16 +/* optimize_reg_copy_3() is known to misbehave with some constructs */ +#define BROKEN_OPTIMIZE_REG_COPY_3_P + /* Specific options for DBX Output. */ /* This is BSD, so it wants DBX format. */ diff --git a/gnu/egcs/gcc/regmove.c b/gnu/egcs/gcc/regmove.c index 81a3520a4fe..b580f8665bd 100644 --- a/gnu/egcs/gcc/regmove.c +++ b/gnu/egcs/gcc/regmove.c @@ -62,7 +62,7 @@ static int find_matches PROTO((rtx, struct match *)); static int fixup_match_1 PROTO((rtx, rtx, rtx, rtx, rtx, int, int, int, FILE *)) ; static int reg_is_remote_constant_p PROTO((rtx, rtx, rtx)); -static int stable_but_for_p PROTO((rtx, rtx, rtx)); +static int stable_and_no_regs_but_for_p PROTO((rtx, rtx, rtx)); static int regclass_compatible_p PROTO((int, int)); static int loop_depth; @@ -1127,12 +1127,14 @@ regmove_optimize (f, nregs, regmove_dump_file) if (! set) continue; +#ifndef BROKEN_OPTIMIZE_REG_COPY_3_P if (flag_expensive_optimizations && ! pass && (GET_CODE (SET_SRC (set)) == SIGN_EXTEND || GET_CODE (SET_SRC (set)) == ZERO_EXTEND) && GET_CODE (XEXP (SET_SRC (set), 0)) == REG && GET_CODE (SET_DEST(set)) == REG) optimize_reg_copy_3 (insn, SET_DEST (set), SET_SRC (set)); +#endif if (flag_expensive_optimizations && ! pass && GET_CODE (SET_SRC (set)) == REG @@ -1663,6 +1665,12 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number, rtx src_note = find_reg_note (insn, REG_DEAD, src), dst_note; int length, s_length, true_loop_depth; + /* If SRC is marked as unchanging, we may not change it. + ??? Maybe we could get better code by removing the unchanging bit + instead, and changing it back if we don't succeed? */ + if (RTX_UNCHANGING_P (src)) + return 0; + if (! src_note) { /* Look for (set (regX) (op regA constX)) @@ -1679,7 +1687,7 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number, && XEXP (SET_SRC (set), 0) == src && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT) insn_const = INTVAL (XEXP (SET_SRC (set), 1)); - else if (! stable_but_for_p (SET_SRC (set), src, dst)) + else if (! stable_and_no_regs_but_for_p (SET_SRC (set), src, dst)) return 0; else /* We might find a src_note while scanning. */ @@ -2089,10 +2097,16 @@ fixup_match_1 (insn, set, src, src_subreg, dst, backward, operand_number, } -/* return nonzero if X is stable but for mentioning SRC or mentioning / - changing DST . If in doubt, presume it is unstable. */ +/* return nonzero if X is stable and mentions no regsiters but for + mentioning SRC or mentioning / changing DST . If in doubt, presume + it is unstable. + The rationale is that we want to check if we can move an insn easily + while just paying attention to SRC and DST. A register is considered + stable if it has the RTX_UNCHANGING_P bit set, but that would still + leave the burden to update REG_DEAD / REG_UNUSED notes, so we don't + want any registers but SRC and DST. */ static int -stable_but_for_p (x, src, dst) +stable_and_no_regs_but_for_p (x, src, dst) rtx x, src, dst; { RTX_CODE code = GET_CODE (x); @@ -2103,13 +2117,19 @@ stable_but_for_p (x, src, dst) int i; char *fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) - if (fmt[i] == 'e' && ! stable_but_for_p (XEXP (x, i), src, dst)) + if (fmt[i] == 'e' + && ! stable_and_no_regs_but_for_p (XEXP (x, i), src, dst)) return 0; return 1; } case 'o': - if (x == src || x == dst) - return 1; + if (code == REG) + return x == src || x == dst; + /* If this is a MEM, look inside - there might be a register hidden in + the address of an unchanging MEM. */ + if (code == MEM + && ! stable_and_no_regs_but_for_p (XEXP (x, 0), src, dst)) + return 0; /* fall through */ default: return ! rtx_unstable_p (x); |