/* real.c - software floating point emulation.
- Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002,
+ 2003, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
Contributed by Stephen L. Moshier (moshier@world.std.com).
Re-written by Richard Henderson <rth@redhat.com>
*r = u;
return true;
}
+
+/* Return true if arithmetic on values in IMODE that were promoted
+ from values in TMODE is equivalent to direct arithmetic on values
+ in TMODE. */
+
+bool
+real_can_shorten_arithmetic (enum machine_mode imode, enum machine_mode tmode)
+{
+ const struct real_format *tfmt, *ifmt;
+ tfmt = REAL_MODE_FORMAT (tmode);
+ ifmt = REAL_MODE_FORMAT (imode);
+ /* These conditions are conservative rather than trying to catch the
+ exact boundary conditions; the main case to allow is IEEE float
+ and double. */
+ return (ifmt->b == tfmt->b
+ && ifmt->p > 2 * tfmt->p
+ && ifmt->emin < 2 * tfmt->emin - tfmt->p - 2
+ && ifmt->emin < tfmt->emin - tfmt->emax - tfmt->p - 2
+ && ifmt->emax > 2 * tfmt->emax + 2
+ && ifmt->emax > tfmt->emax - tfmt->emin + tfmt->p + 2
+ && ifmt->round_towards_zero == tfmt->round_towards_zero
+ && (ifmt->has_sign_dependent_rounding
+ == tfmt->has_sign_dependent_rounding)
+ && ifmt->has_nans >= tfmt->has_nans
+ && ifmt->has_inf >= tfmt->has_inf
+ && ifmt->has_signed_zero >= tfmt->has_signed_zero
+ && !MODE_COMPOSITE_P (tmode)
+ && !MODE_COMPOSITE_P (imode));
+}
\f
/* Render R as an integer. */
required to be the value of the long double rounded to the
nearest double. Rounding means we need a slightly smaller
value for LDBL_MAX. */
- clear_significand_bit (r, SIGNIFICAND_BITS - fmt->pnan);
+ clear_significand_bit (r, SIGNIFICAND_BITS - fmt->pnan - 1);
}
}
10,
7,
7,
- -95,
- 96,
+ -94,
+ 97,
31,
31,
false,
10,
16,
16,
- -383,
- 384,
+ -382,
+ 385,
63,
63,
false,
10,
34,
34,
- -6143,
- 6144,
+ -6142,
+ 6145,
127,
127,
false,