summaryrefslogtreecommitdiff
path: root/gcc/cse.c
diff options
context:
space:
mode:
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>1994-06-14 21:53:33 +0000
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>1994-06-14 21:53:33 +0000
commit8cb81425743091dd88e9683359809f0beae9b86f (patch)
tree0884fc31c84b6ba32f7cd320eefc449333747ac1 /gcc/cse.c
parent3206482e6bbd09e70a029f09162f513ac3ba97c4 (diff)
downloadgcc-8cb81425743091dd88e9683359809f0beae9b86f.tar.gz
(simplify_unary_operation): Correctly and consistently handle
CONST_INT cases for FLOAT and UNSIGNED_FLOAT. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@7470 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cse.c')
-rw-r--r--gcc/cse.c69
1 files changed, 33 insertions, 36 deletions
diff --git a/gcc/cse.c b/gcc/cse.c
index 6eb8758a2b9..eb541ae7b1d 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