aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-06-14 17:53:33 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1994-06-14 17:53:33 -0400
commit62c0ea12e975a682cb5446eb4ca6f3b76b7be031 (patch)
tree0884fc31c84b6ba32f7cd320eefc449333747ac1 /gcc
parentac7157f6c94451a44f4c7dc127a9bea28cb534ca (diff)
downloadgcc-62c0ea12e975a682cb5446eb4ca6f3b76b7be031.zip
gcc-62c0ea12e975a682cb5446eb4ca6f3b76b7be031.tar.gz
gcc-62c0ea12e975a682cb5446eb4ca6f3b76b7be031.tar.bz2
(simplify_unary_operation): Correctly and consistently handle
CONST_INT cases for FLOAT and UNSIGNED_FLOAT. From-SVN: r7470
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cse.c69
1 files changed, 33 insertions, 36 deletions
diff --git a/gcc/cse.c b/gcc/cse.c
index 6eb8758..eb541ae 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -2886,70 +2886,67 @@ simplify_unary_operation (code, mode, op, op_mode)
check the wrong mode (input vs. output) for a conversion operation,
such as FIX. At some point, this should be simplified. */
-#if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
- if (code == FLOAT && GET_CODE (op) == CONST_INT)
- {
- REAL_VALUE_TYPE d;
+#if !defined(REAL_IS_NOT_DOUBLE) || defined(REAL_ARITHMETIC)
-#ifdef REAL_ARITHMETIC
- REAL_VALUE_FROM_INT (d, INTVAL (op), INTVAL (op) < 0 ? ~0 : 0);
-#else
- d = (double) INTVAL (op);
-#endif
- return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
- }
- else if (code == UNSIGNED_FLOAT && GET_CODE (op) == CONST_INT)
+ if (code == FLOAT && GET_MODE (op) == VOIDmode
+ && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
{
+ HOST_WIDE_INT hv, lv;
REAL_VALUE_TYPE d;
-#ifdef REAL_ARITHMETIC
- REAL_VALUE_FROM_INT (d, INTVAL (op), 0);
-#else
- d = (double) (unsigned int) INTVAL (op);
-#endif
- return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
- }
-
- else if (code == FLOAT && GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
- {
- REAL_VALUE_TYPE d;
+ if (GET_CODE (op) == CONST_INT)
+ lv = INTVAL (op), hv = INTVAL (op) < 0 ? -1 : 0;
+ else
+ lv = CONST_DOUBLE_HIGH (op), hv = CONST_DOUBLE_LOW (op);
#ifdef REAL_ARITHMETIC
- REAL_VALUE_FROM_INT (d, CONST_DOUBLE_LOW (op), CONST_DOUBLE_HIGH (op));
+ REAL_VALUE_FROM_INT (d, lv, hv);
#else
- if (CONST_DOUBLE_HIGH (op) < 0)
+ if (hv < 0)
{
- d = (double) (~ CONST_DOUBLE_HIGH (op));
+ d = (double) (~ hv);
d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
* (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
- d += (double) (unsigned HOST_WIDE_INT) (~ CONST_DOUBLE_LOW (op));
+ d += (double) (unsigned HOST_WIDE_INT) (~ lv);
d = (- d - 1.0);
}
else
{
- d = (double) CONST_DOUBLE_HIGH (op);
+ d = (double) hv;
d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
* (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
- d += (double) (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
+ d += (double) (unsigned HOST_WIDE_INT) lv;
}
#endif /* REAL_ARITHMETIC */
+
return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
}
- else if (code == UNSIGNED_FLOAT && GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == VOIDmode)
+ else if (code == UNSIGNED_FLOAT && GET_MODE (op) == VOIDmode
+ && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
{
+ HOST_WIDE_INT hv, lv;
REAL_VALUE_TYPE d;
+ if (GET_CODE (op) == CONST_INT)
+ lv = INTVAL (op), hv = INTVAL (op) < 0 ? -1 : 0;
+ else
+ lv = CONST_DOUBLE_HIGH (op), hv = CONST_DOUBLE_LOW (op);
+
+ if (GET_MODE_BITSIZE (op_mode) >= HOST_BITS_PER_WIDE_INT * 2)
+ ;
+ else
+ hv = 0, lv &= GET_MODE_MASK (op_mode);
+
#ifdef REAL_ARITHMETIC
- REAL_VALUE_FROM_UNSIGNED_INT (d, CONST_DOUBLE_LOW (op),
- CONST_DOUBLE_HIGH (op));
+ REAL_VALUE_FROM_UNSIGNED_INT (d, lv, hv);
#else
- d = (double) CONST_DOUBLE_HIGH (op);
+
+ d = (double) hv;
d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
* (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
- d += (double) (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
+ d += (double) (unsigned HOST_WIDE_INT) lv;
#endif /* REAL_ARITHMETIC */
+
return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
}
#endif