aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-05-19 16:38:15 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1994-05-19 16:38:15 -0400
commit9847c2f6771c42f3448fe99ef5bbc1b3499133b0 (patch)
treecfa2a666fb4abf98b5718507c2bb077a95f67c64
parent2986ae008b26f29b421ee34debbc3113658d0453 (diff)
downloadgcc-9847c2f6771c42f3448fe99ef5bbc1b3499133b0.zip
gcc-9847c2f6771c42f3448fe99ef5bbc1b3499133b0.tar.gz
gcc-9847c2f6771c42f3448fe99ef5bbc1b3499133b0.tar.bz2
(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
-rw-r--r--gcc/emit-rtl.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 55ee134..32e7fb5 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -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
target floating formats are the same, handling two-word floating
constants are easy. Note that REAL_VALUE_TO_TARGET_{SINGLE,DOUBLE}
- are defined as returning 32 bit and 64-bit values, respectively,
- and not values of BITS_PER_WORD and 2 * BITS_PER_WORD bits. */
+ are defined as returning one or two 32 bit values, respectively,
+ and not values of BITS_PER_WORD bits. */
#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_BITSIZE (mode) == 64
&& GET_CODE (op) == CONST_DOUBLE)
{
- HOST_WIDE_INT k[2];
+ long k[2];
REAL_VALUE_TYPE rv;
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
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.
??? This is a potential portability problem and should
be fixed at some point. */
- if (HOST_BITS_PER_WIDE_INT == 32)
- return GEN_INT (k[i]);
- else if (HOST_BITS_PER_WIDE_INT == 64 && i == 0)
- return GEN_INT ((k[! WORDS_BIG_ENDIAN] << (HOST_BITS_PER_WIDE_INT / 2))
- | k[WORDS_BIG_ENDIAN]);
+ if (BITS_PER_WORD == 32)
+ return GEN_INT ((HOST_WIDE_INT) k[i]);
+#if HOST_BITS_PER_WIDE_INT > 32
+ 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]);
+#endif
else
abort ();
}
@@ -1128,17 +1133,16 @@ operand_subword (op, i, validate_address, mode)
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. */
#ifdef REAL_ARITHMETIC
- if ((HOST_BITS_PER_WIDE_INT == BITS_PER_WORD)
- && GET_MODE_CLASS (mode) == MODE_FLOAT
+ if (GET_MODE_CLASS (mode) == MODE_FLOAT
&& GET_MODE_BITSIZE (mode) == 32
&& GET_CODE (op) == CONST_DOUBLE)
{
- HOST_WIDE_INT l;
+ long l;
REAL_VALUE_TYPE rv;
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
REAL_VALUE_TO_TARGET_SINGLE (rv, l);
- return GEN_INT (l);
+ return GEN_INT ((HOST_WIDE_INT) l);
}
#else
if (((HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT