From 423a9cd9f2809b5aad20b7e73ca95a3fcdcd3612 Mon Sep 17 00:00:00 2001 From: Miod Vallat Date: Tue, 13 Jul 2004 17:22:57 +0000 Subject: A better fix for the m68k optimize_reg_copy_3() problem. The problem really only arises when optimize_reg_copy_3() attempts to merge a load which fits in a register and a load which does not fit - in the m68k case, merging an int32_t foo and (int64_t)foo two lines later. In this case, and only if the backend provides its own expansion of the extendsidi2 insn (usually for performance and code size reasons) as embedded assembly statements but not rtl operations, then gcc at this point will ``fail to realize'' that when sign-extending (or zero-extending) the value of rN into rN and r(N+1), the value of rN is not preserved on big-endian architectures, and the optimization will produce bad code. Of all the OpenBSD-supported platforms, arm and m68k are the only affected; but further optimizations in gcc3 (on arm) apparently neuter this bug, which I have been unable to reproduce in an arm build with gcc3. This commit works around the problem by preventing expansions larger than the width of a general register, on m68k only. Other platforms are not affected. --- gnu/egcs/gcc/regmove.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'gnu/egcs') diff --git a/gnu/egcs/gcc/regmove.c b/gnu/egcs/gcc/regmove.c index b580f8665bd..6f5e1c0894a 100644 --- a/gnu/egcs/gcc/regmove.c +++ b/gnu/egcs/gcc/regmove.c @@ -708,6 +708,14 @@ optimize_reg_copy_3 (insn, dest, src) GET_MODE_BITSIZE (GET_MODE (src_reg)))) return; +#ifdef BROKEN_OPTIMIZE_REG_COPY_3_P + /* If we are on a big-endian target, do not expand to more than one + register. */ + if (BYTES_BIG_ENDIAN && + GET_MODE_BITSIZE (GET_MODE (src)) > BITS_PER_WORD) + return; +#endif + old_mode = GET_MODE (src_reg); PUT_MODE (src_reg, GET_MODE (src)); XEXP (src, 0) = SET_SRC (set); @@ -1127,14 +1135,12 @@ 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 -- cgit v1.2.3