Commit 9847c2f6 by Richard Kenner

(operand_subword): Fix arg of REAL_VALUE_TO_TARGET_SINGLE and ..._DOUBLE.

(operand_subword): Fix arg of REAL_VALUE_TO_TARGET_SINGLE and
.._DOUBLE.  Permit float subword extraction when host's word width iswider than target's.

From-SVN: r7338
parent 2986ae00
...@@ -1075,30 +1075,35 @@ operand_subword (op, i, validate_address, mode) ...@@ -1075,30 +1075,35 @@ operand_subword (op, i, validate_address, mode)
/* The only remaining cases are when OP is a constant. If the host and /* The only remaining cases are when OP is a constant. If the host and
target floating formats are the same, handling two-word floating target floating formats are the same, handling two-word floating
constants are easy. Note that REAL_VALUE_TO_TARGET_{SINGLE,DOUBLE} constants are easy. Note that REAL_VALUE_TO_TARGET_{SINGLE,DOUBLE}
are defined as returning 32 bit and 64-bit values, respectively, are defined as returning one or two 32 bit values, respectively,
and not values of BITS_PER_WORD and 2 * BITS_PER_WORD bits. */ and not values of BITS_PER_WORD bits. */
#ifdef REAL_ARITHMETIC #ifdef REAL_ARITHMETIC
if ((HOST_BITS_PER_WIDE_INT == BITS_PER_WORD) /* The output is some bits, the width of the target machine's word.
A wider-word host can surely hold them in a CONST_INT. A narrower-word
host can't. */
if (HOST_BITS_PER_WIDE_INT >= BITS_PER_WORD
&& GET_MODE_CLASS (mode) == MODE_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT
&& GET_MODE_BITSIZE (mode) == 64 && GET_MODE_BITSIZE (mode) == 64
&& GET_CODE (op) == CONST_DOUBLE) && GET_CODE (op) == CONST_DOUBLE)
{ {
HOST_WIDE_INT k[2]; long k[2];
REAL_VALUE_TYPE rv; REAL_VALUE_TYPE rv;
REAL_VALUE_FROM_CONST_DOUBLE (rv, op); REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
REAL_VALUE_TO_TARGET_DOUBLE (rv, k); REAL_VALUE_TO_TARGET_DOUBLE (rv, k);
/* We handle 32-bit and 64-bit host 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. */
if (HOST_BITS_PER_WIDE_INT == 32) if (BITS_PER_WORD == 32)
return GEN_INT (k[i]); return GEN_INT ((HOST_WIDE_INT) k[i]);
else if (HOST_BITS_PER_WIDE_INT == 64 && i == 0) #if HOST_BITS_PER_WIDE_INT > 32
return GEN_INT ((k[! WORDS_BIG_ENDIAN] << (HOST_BITS_PER_WIDE_INT / 2)) else if (BITS_PER_WORD >= 64 && i == 0)
| k[WORDS_BIG_ENDIAN]); return GEN_INT ((((HOST_WIDE_INT) k[! WORDS_BIG_ENDIAN]) << 32)
| (HOST_WIDE_INT) k[WORDS_BIG_ENDIAN]);
#endif
else else
abort (); abort ();
} }
...@@ -1128,17 +1133,16 @@ operand_subword (op, i, validate_address, mode) ...@@ -1128,17 +1133,16 @@ operand_subword (op, i, validate_address, mode)
values often do not have the same high-order bits. We have already values often do not have the same high-order bits. We have already
verified that we want the only defined word of the single-word value. */ verified that we want the only defined word of the single-word value. */
#ifdef REAL_ARITHMETIC #ifdef REAL_ARITHMETIC
if ((HOST_BITS_PER_WIDE_INT == BITS_PER_WORD) if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& GET_MODE_CLASS (mode) == MODE_FLOAT
&& GET_MODE_BITSIZE (mode) == 32 && GET_MODE_BITSIZE (mode) == 32
&& GET_CODE (op) == CONST_DOUBLE) && GET_CODE (op) == CONST_DOUBLE)
{ {
HOST_WIDE_INT l; long l;
REAL_VALUE_TYPE rv; REAL_VALUE_TYPE rv;
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);
return GEN_INT (l); return GEN_INT ((HOST_WIDE_INT) l);
} }
#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