Commit 7cae975e by Richard Henderson Committed by Richard Henderson

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
parent b56a20f6
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> Thu Apr 29 15:58:52 1999 Robert Lipe <robertlipe@usa.net>
......
...@@ -1273,24 +1273,35 @@ operand_subword (op, i, validate_address, mode) ...@@ -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 /* We handle 32-bit and >= 64-bit words here. Note that the order in
which the words are written depends on the word endianness. which the words are written depends on the word endianness.
??? This is a potential portability problem and should ??? 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) 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) 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 #endif
else if (BITS_PER_WORD == 16) else if (BITS_PER_WORD == 16)
{ {
long value; val = k[i >> 1];
value = k[i >> 1]; if ((i & 1) == !WORDS_BIG_ENDIAN)
if ((i & 0x1) == !WORDS_BIG_ENDIAN) val >>= 16;
value >>= 16; val &= 0xffff;
value &= 0xffff; return GEN_INT (val);
return GEN_INT ((HOST_WIDE_INT) value);
} }
else else
abort (); abort ();
...@@ -1307,7 +1318,13 @@ operand_subword (op, i, validate_address, mode) ...@@ -1307,7 +1318,13 @@ operand_subword (op, i, validate_address, mode)
REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k); REAL_VALUE_TO_TARGET_LONG_DOUBLE (rv, k);
if (BITS_PER_WORD == 32) 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 */ #else /* no REAL_ARITHMETIC */
if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
...@@ -1345,25 +1362,18 @@ operand_subword (op, i, validate_address, mode) ...@@ -1345,25 +1362,18 @@ operand_subword (op, i, validate_address, mode)
REAL_VALUE_FROM_CONST_DOUBLE (rv, op); REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
REAL_VALUE_TO_TARGET_SINGLE (rv, l); REAL_VALUE_TO_TARGET_SINGLE (rv, l);
/* If 32 bits is an entire word for the target, but not for the host, /* Sign extend from known 32-bit value to HOST_WIDE_INT. */
then sign-extend on the host so that the number will look the same val = l;
way on the host that it would on the target. See for instance val = ((val & 0xffffffff) ^ 0x80000000) - 0x80000000;
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
if (BITS_PER_WORD == 16) if (BITS_PER_WORD == 16)
{ {
if ((i & 0x1) == !WORDS_BIG_ENDIAN) if ((i & 1) == !WORDS_BIG_ENDIAN)
l >>= 16; val >>= 16;
l &= 0xffff; val &= 0xffff;
} }
return GEN_INT ((HOST_WIDE_INT) l);
return GEN_INT (val);
} }
#else #else
if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment