diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/combine.c | 4 | ||||
-rw-r--r-- | gcc/cse.c | 41 | ||||
-rw-r--r-- | gcc/rtlhooks.c | 52 |
4 files changed, 61 insertions, 45 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4610b4cc1bb..14ab0a31c91 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2004-04-05 Paolo Bonzini <bonzini@gnu.org> + + * combine.c (RTL_HOOKS_GEN_LOWPART_NO_EMIT): Use + gen_lowpart_for_combine. + * cse.c (gen_lowpart_if_possible): Move... + * rtlhooks.c (gen_lowpart_if_possible): ... here. Also try + gen_lowpart_SUBREG. + (gen_lowpart_no_emit_general): Use it. + 2005-04-05 Eric Botcazou <ebotcazou@libertysurf.fr> * config/sparc/sparc.c (TARGET_ASM_FILE_END): Undefine before diff --git a/gcc/combine.c b/gcc/combine.c index 297b58e914e..313a3d90d23 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -422,6 +422,10 @@ static bool unmentioned_reg_p (rtx, rtx); #undef RTL_HOOKS_GEN_LOWPART #define RTL_HOOKS_GEN_LOWPART gen_lowpart_for_combine +/* Our implementation of gen_lowpart never emits a new pseudo. */ +#undef RTL_HOOKS_GEN_LOWPART_NO_EMIT +#define RTL_HOOKS_GEN_LOWPART_NO_EMIT gen_lowpart_for_combine + #undef RTL_HOOKS_REG_NONZERO_REG_BITS #define RTL_HOOKS_REG_NONZERO_REG_BITS reg_nonzero_bits_for_combine diff --git a/gcc/cse.c b/gcc/cse.c index 4d6f76d9328..5431da77160 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -4361,47 +4361,6 @@ equiv_constant (rtx x) return 0; } -/* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a fixed-point - number, return an rtx (MEM, SUBREG, or CONST_INT) that refers to the - least-significant part of X. - MODE specifies how big a part of X to return. - - If the requested operation cannot be done, 0 is returned. - - This is similar to gen_lowpart_general in emit-rtl.c. */ - -rtx -gen_lowpart_if_possible (enum machine_mode mode, rtx x) -{ - rtx result = gen_lowpart_common (mode, x); - - if (result) - return result; - else if (MEM_P (x)) - { - /* This is the only other case we handle. */ - int offset = 0; - rtx new; - - if (WORDS_BIG_ENDIAN) - offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD) - - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)); - if (BYTES_BIG_ENDIAN) - /* Adjust the address so that the address-after-the-data is - unchanged. */ - offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)) - - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))); - - new = adjust_address_nv (x, mode, offset); - if (! memory_address_p (mode, XEXP (new, 0))) - return 0; - - return new; - } - else - return 0; -} - /* Given INSN, a jump insn, PATH_TAKEN indicates if we are following the "taken" branch. It will be zero if not. diff --git a/gcc/rtlhooks.c b/gcc/rtlhooks.c index dbe959308c0..9d5dafdff44 100644 --- a/gcc/rtlhooks.c +++ b/gcc/rtlhooks.c @@ -25,6 +25,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "rtl.h" #include "rtlhooks-def.h" #include "expr.h" +#include "recog.h" /* For speed, we will copy the RTX hooks struct member-by-member @@ -84,12 +85,11 @@ gen_lowpart_general (enum machine_mode mode, rtx x) rtx gen_lowpart_no_emit_general (enum machine_mode mode, rtx x) { - rtx result = gen_lowpart_common (mode, x); + rtx result = gen_lowpart_if_possible (mode, x); if (result) return result; - if (mode != GET_MODE (x) && GET_MODE (x) != VOIDmode) - return gen_lowpart_SUBREG (mode, x); - return x; + else + return x; } rtx @@ -113,3 +113,47 @@ reg_nonzero_bits_general (rtx x ATTRIBUTE_UNUSED, { return NULL; } + +/* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a fixed-point + number, return an rtx (MEM, SUBREG, or CONST_INT) that refers to the + least-significant part of X. + MODE specifies how big a part of X to return. + + If the requested operation cannot be done, 0 is returned. + + This is similar to gen_lowpart_general. */ + +rtx +gen_lowpart_if_possible (enum machine_mode mode, rtx x) +{ + rtx result = gen_lowpart_common (mode, x); + + if (result) + return result; + else if (MEM_P (x)) + { + /* This is the only other case we handle. */ + int offset = 0; + rtx new; + + if (WORDS_BIG_ENDIAN) + offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD) + - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD)); + if (BYTES_BIG_ENDIAN) + /* Adjust the address so that the address-after-the-data is + unchanged. */ + offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)) + - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x)))); + + new = adjust_address_nv (x, mode, offset); + if (! memory_address_p (mode, XEXP (new, 0))) + return 0; + + return new; + } + else if (mode != GET_MODE (x) && GET_MODE (x) != VOIDmode) + return gen_lowpart_SUBREG (mode, x); + else + return 0; +} + |