diff options
author | Zdenek Dvorak <dvorakz@suse.cz> | 2006-02-23 21:55:21 +0100 |
---|---|---|
committer | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2006-02-23 20:55:21 +0000 |
commit | 65acccdd22e3fc50f4272bc274e10e96dbbcd527 (patch) | |
tree | 4644db9aaf9652a8ad6c838fd26cc5277918467b | |
parent | cbb5e20166ec05d529f819e12e0727ca6ff1749a (diff) | |
download | gcc-65acccdd22e3fc50f4272bc274e10e96dbbcd527.zip gcc-65acccdd22e3fc50f4272bc274e10e96dbbcd527.tar.gz gcc-65acccdd22e3fc50f4272bc274e10e96dbbcd527.tar.bz2 |
emit-rtl.c (immed_double_const): Cleanup.
* emit-rtl.c (immed_double_const): Cleanup.
From-SVN: r111396
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 64 |
2 files changed, 18 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c3e3cd9..9b05db88 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2006-02-23 Zdenek Dvorak <dvorakz@suse.cz> + + * emit-rtl.c (immed_double_const): Cleanup. + 2006-02-23 Daniel Berlin <dberlin@dberlin.org> Fix PR tree-optimization/26376 diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index f1613ad..7dfdd3a 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -444,64 +444,28 @@ immed_double_const (HOST_WIDE_INT i0, HOST_WIDE_INT i1, enum machine_mode mode) rtx value; unsigned int i; + /* There are the following cases (note that there are no modes with + HOST_BITS_PER_WIDE_INT < GET_MODE_BITSIZE (mode) < 2 * HOST_BITS_PER_WIDE_INT): + + 1) If GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT, then we use + gen_int_mode. + 2) GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT, but the value of + the integer fits into HOST_WIDE_INT anyway (i.e., i1 consists only + from copies of the sign bit, and sign of i0 and i1 are the same), then + we return a CONST_INT for i0. + 3) Otherwise, we create a CONST_DOUBLE for i0 and i1. */ if (mode != VOIDmode) { - int width; - gcc_assert (GET_MODE_CLASS (mode) == MODE_INT || GET_MODE_CLASS (mode) == MODE_PARTIAL_INT /* We can get a 0 for an error mark. */ || GET_MODE_CLASS (mode) == MODE_VECTOR_INT || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT); - /* We clear out all bits that don't belong in MODE, unless they and - our sign bit are all one. So we get either a reasonable negative - value or a reasonable unsigned value for this mode. */ - width = GET_MODE_BITSIZE (mode); - if (width < HOST_BITS_PER_WIDE_INT - && ((i0 & ((HOST_WIDE_INT) (-1) << (width - 1))) - != ((HOST_WIDE_INT) (-1) << (width - 1)))) - i0 &= ((HOST_WIDE_INT) 1 << width) - 1, i1 = 0; - else if (width == HOST_BITS_PER_WIDE_INT - && ! (i1 == ~0 && i0 < 0)) - i1 = 0; - else - /* We should be able to represent this value as a constant. */ - gcc_assert (width <= 2 * HOST_BITS_PER_WIDE_INT); - - /* If this would be an entire word for the target, but is not for - the host, then sign-extend on the host so that the number will - look the same way on the host that it would on the target. - - For example, when building a 64 bit alpha hosted 32 bit sparc - targeted compiler, then we want the 32 bit unsigned value -1 to be - represented as a 64 bit value -1, and not as 0x00000000ffffffff. - The latter confuses the sparc backend. */ - - if (width < HOST_BITS_PER_WIDE_INT - && (i0 & ((HOST_WIDE_INT) 1 << (width - 1)))) - i0 |= ((HOST_WIDE_INT) (-1) << width); - - /* If MODE fits within HOST_BITS_PER_WIDE_INT, always use a - CONST_INT. - - ??? Strictly speaking, this is wrong if we create a CONST_INT for - a large unsigned constant with the size of MODE being - HOST_BITS_PER_WIDE_INT and later try to interpret that constant - in a wider mode. In that case we will mis-interpret it as a - negative number. - - Unfortunately, the only alternative is to make a CONST_DOUBLE for - any constant in any mode if it is an unsigned constant larger - than the maximum signed integer in an int on the host. However, - doing this will break everyone that always expects to see a - CONST_INT for SImode and smaller. - - We have always been making CONST_INTs in this case, so nothing - new is being broken. */ - - if (width <= HOST_BITS_PER_WIDE_INT) - i1 = (i0 < 0) ? ~(HOST_WIDE_INT) 0 : 0; + if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT) + return gen_int_mode (i0, mode); + + gcc_assert (GET_MODE_BITSIZE (mode) == 2 * HOST_BITS_PER_WIDE_INT); } /* If this integer fits in one word, return a CONST_INT. */ |