diff options
author | Paolo Bonzini <bonzini@gnu.org> | 2005-04-05 14:50:35 +0000 |
---|---|---|
committer | Paolo Bonzini <bonzini@gcc.gnu.org> | 2005-04-05 14:50:35 +0000 |
commit | bf667275670a58261be7e15e9e9807cb60750e85 (patch) | |
tree | 9063690ca6fe6c4afac8a638d99c0df2385390f6 /gcc/rtlhooks.c | |
parent | c81739f769ffb7f7d7bc417bc21444e298c2392e (diff) | |
download | gcc-bf667275670a58261be7e15e9e9807cb60750e85.zip gcc-bf667275670a58261be7e15e9e9807cb60750e85.tar.gz gcc-bf667275670a58261be7e15e9e9807cb60750e85.tar.bz2 |
combine.c (RTL_HOOKS_GEN_LOWPART_NO_EMIT): Use gen_lowpart_for_combine.
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.
From-SVN: r97633
Diffstat (limited to 'gcc/rtlhooks.c')
-rw-r--r-- | gcc/rtlhooks.c | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/gcc/rtlhooks.c b/gcc/rtlhooks.c index dbe9593..9d5dafd 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; +} + |