diff options
author | Richard Henderson <rth@cygnus.com> | 1999-04-29 10:24:37 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 1999-04-29 10:24:37 -0700 |
commit | 7cae975e66fef11bcb7d165cd399efae6e0b807b (patch) | |
tree | 249cc9b85abd467b0262af2410f2a2ec1a9a2c12 | |
parent | b56a20f600d16002e02c5e3b622b3a736c011cbf (diff) | |
download | gcc-7cae975e66fef11bcb7d165cd399efae6e0b807b.zip gcc-7cae975e66fef11bcb7d165cd399efae6e0b807b.tar.gz gcc-7cae975e66fef11bcb7d165cd399efae6e0b807b.tar.bz2 |
emit-rtl.c (operand_subword): Religiously mask and sign-extend from 32-bits to HOST_WIDE_INT.
* emit-rtl.c (operand_subword): Religiously mask and sign-extend
from 32-bits to HOST_WIDE_INT.
From-SVN: r26699
-rw-r--r-- | gcc/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 66 |
2 files changed, 42 insertions, 28 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8262582..5f6fdc6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +Thu Apr 29 17:23:59 1999 Richard Henderson <rth@cygnus.com> + + * emit-rtl.c (operand_subword): Religiously mask and sign-extend + from 32-bits to HOST_WIDE_INT. Thu Apr 29 15:58:52 1999 Robert Lipe <robertlipe@usa.net> diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 88edee3..b1e2d3d 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1273,24 +1273,35 @@ operand_subword (op, i, validate_address, mode) /* We handle 32-bit and >= 64-bit words here. Note that the order in which the words are written depends on the word endianness. - ??? This is a potential portability problem and should - be fixed at some point. */ + be fixed at some point. + + We must excercise caution with the sign bit. By definition there + are 32 significant bits in K; there may be more in a HOST_WIDE_INT. + Consider a host with a 32-bit long and a 64-bit HOST_WIDE_INT. + So we explicitly mask and sign-extend as necessary. */ if (BITS_PER_WORD == 32) - return GEN_INT ((HOST_WIDE_INT) k[i]); -#if HOST_BITS_PER_WIDE_INT > 32 + { + val = k[i]; + val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000; + return GEN_INT (val); + } +#if HOST_BITS_PER_WIDE_INT >= 64 else if (BITS_PER_WORD >= 64 && i == 0) - return GEN_INT ((((HOST_WIDE_INT) k[! WORDS_BIG_ENDIAN]) << 32) - | (HOST_WIDE_INT) k[WORDS_BIG_ENDIAN]); + { + val = k[! WORDS_BIG_ENDIAN]; + val = (((val & 0xffffffff) ^ 0x80000000) - 0x80000000) << 32; + val |= (HOST_WIDE_INT) k[WORDS_BIG_ENDIAN] & 0xffffffff; + return GEN_INT (val); + } #endif else if (BITS_PER_WORD == 16) { - long value; - value = k[i >> 1]; - if ((i & 0x1) == !WORDS_BIG_ENDIAN) - value >>= 16; - value &= 0xffff; - return GEN_INT ((HOST_WIDE_INT) value); + val = k[i >> 1]; + if ((i & 1) == !WORDS_BIG_ENDIAN) + val >>= 16; + val &= 0xffff; + return GEN_INT (val); } else abort (); @@ -1307,7 +1318,13 @@ operand_subword (op, i, validate_address, mode) REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k); if (BITS_PER_WORD == 32) - return GEN_INT ((HOST_WIDE_INT) k[i]); + { + val = k[i]; + val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000; + return GEN_INT (val); + } + else + abort (); } #else /* no REAL_ARITHMETIC */ if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT @@ -1345,25 +1362,18 @@ operand_subword (op, i, validate_address, mode) REAL_VALUE_FROM_CONST_DOUBLE (rv, op); REAL_VALUE_TO_TARGET_SINGLE (rv, l); - /* If 32 bits is an entire word for the target, but 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. See for instance - simplify_unary_operation. The #if is needed to avoid compiler - warnings. */ - -#if HOST_BITS_PER_LONG > 32 - if (BITS_PER_WORD < HOST_BITS_PER_LONG && BITS_PER_WORD == 32 - && (l & ((long) 1 << 31))) - l |= ((long) (-1) << 32); -#endif + /* Sign extend from known 32-bit value to HOST_WIDE_INT. */ + val = l; + val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000; if (BITS_PER_WORD == 16) { - if ((i & 0x1) == !WORDS_BIG_ENDIAN) - l >>= 16; - l &= 0xffff; + if ((i & 1) == !WORDS_BIG_ENDIAN) + val >>= 16; + val &= 0xffff; } - return GEN_INT ((HOST_WIDE_INT) l); + + return GEN_INT (val); } #else if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT |