*/
/* If the region is empty then it's technically true that all of the bits
- * are zero. It's important to be able to do answer the case where
+ * are zero. It's important to be able to answer the case where
* %$\id{from} = \id{to} = 0$% without accessing memory.
*/
assert(to >= from); if (to == from) return (ALLCLEAR);
/* Set the biased exponent. */
z0 |= (exp + maxexp) << esh;
- /* Clear the unit bit if we're suppose to use a hidden-bit convention. */
+ /* Clear the unit bit if we're suppose to use a hidden-bit
+ * convention.
+ */
if (fmt->f&FLTIF_HIDDEN) {
mb = fmt->prec - 1; mw = (mb + 31)/32; mb = mb%32;
z[nw - mw] &= ~B32(mb);
* requisite compile-time configuration machinery is worth the effort.)
*/
-# define SETINF(TY, rc, z) \
- do { (z) = TY##_MAX; (rc) = FLTERR_OFLOW | FLTERR_INEXACT; } while (0)
+# define SETINF(TY, rc, z) do { \
+ (z) = TY##_MAX; \
+ (rc) = FLTERR_OFLOW | FLTERR_INEXACT; \
+ } while (0)
#endif
#ifdef DIGIT_BITS
#endif
#ifdef FROB_NANS
+ /* The native floating point format uses the opposite quiet-vs-signalling
+ * NaN convention from the recommended `quiet bit' convention, so the bit
+ * needs hacking on input.
+ */
+
# define FROBNAN_ENCDECLS struct floatbits _y
# define FROBNAN_ENC do { \
if (_x->f&FLTF_NANMASK) { \
} \
} while (0)
#else
+ /* The native floating point format either uses the conventional
+ * `quiet-bit' convention, or isn't IEEE at all. Either way, there's
+ * nothing to do here.
+ */
+
# define FROBNAN_ENCDECLS
# define FROBNAN_ENC do ; while (0)
#endif
* zero.
*
* * If the implementation's floating-point radix is not a
- * power of two, and @x@ is a nonzero finite value, then
+ * power of two, and @x@ is a nonzero finite value, then the
* @FLTERR_INEXACT@ error bit is set (unconditionally), and
* the value is rounded by the implementation using its
* prevailing rounding policy. If the radix is a power of
#endif
#ifdef FROB_NANS
+ /* The native floating point format uses the opposite quiet-vs-signalling
+ * NaN convention from the recommended `quiet bit' convention, so the bit
+ * needs hacking on output.
+ */
+
# define FROBNAN_DEC do { \
if (_z->f&FLTF_NANMASK) _z->f ^= FLTF_NANMASK; \
} while (0)
#else
+ /* The native floating point format either uses the conventional
+ * `quiet-bit' convention, or isn't IEEE at all. Either way, there's
+ * nothing to do here.
+ */
+
# define FROBNAN_DEC do ; while (0)
#endif
*
* Returns: Error flags (@FLTERR_...@).
*
- * Use: Decode the native C floatingpoint value @x@ and store the
+ * Use: Decode the native C floating-point value @x@ and store the
* result in @z_out@.
*
* The @TY@ may be @flt@ to encode a @float@, @dbl@ to encode a
* error bit is set and the decoded payload is left empty.
*
* * If the implementation's floating-point radix is not a
- * power of two, and @x@ is a nonzero finite value, then
+ * power of two, and @x@ is a nonzero finite value, then the
* @FLTERR_INEXACT@ error bit is set (unconditionally), and
* the rounded value (according to the rounding mode @r@) is
* stored in as many fraction words as necessary to identify
/* Predicates considered for rounding. */
#define FRPF_LOW 0x0001u /* lost bits not exactly zero or half */
-#define FRPF_HALF 0x0002u /* lost a half or more */
+#define FRPF_HALF 0x0002u /* lost a half or more */
#define FRPF_ODD 0x0004u /* final place is currently odd */
#define FRPF_NEG 0x0008u /* number is negative */
/*----- Native formats ----------------------------------------------------*/
-/* Hacking for platforms which ill-advisedly have the opposite sense for the
- * quiet NaN bit.
- *
- * Obviously we toggle the quiet bit, but there's a problem: if the quiet bit
- * is the only one set, then if we toggle it, the fraction will become zero
- * and we'll be left with an infinity. Follow MIPS and set all of the bits.
- *
- * This is all internal machinery and shouldn't be relied on by applications.
- */
-#if defined(__hppa__) || (defined(__mips__) && !defined(__mips_nan2008))
-# define FLTFMT__MUST_FROB_NANS
-
-# define FLTFMT__FROB_NAN_F32(x_inout, rc) do { \
- uint32 *_x_inout_ = (x_inout), _x0_ = _x_inout_[0]; \
- \
- if ((_x0_&0x7f800000) != 0x7f800000 || !(_x0_&0x007fffff)) \
- ; \
- else if (_x0_&0x003fffff) \
- _x_inout_[0] = _x0_ ^ 0x00400000; \
- else { \
- _x_inout_[0] = (_x0_&0x80000000) | 0x7fffffff; \
- (rc) |= FLTERR_INEXACT; \
- } \
- } while (0)
-
-# define FLTFMT__FROB_NAN_F64(x_inout, rc) do { \
- uint32 *_x_inout_ = (x_inout), \
- _x0_ = _x_inout_[0], _x1_ = _x_inout_[1]; \
- \
- if ((_x0_&0x7ff00000) != 0x7ff00000 || (!(_x0_&0x000fffff) && !_x1_)) \
- ; \
- else if ((_x0_&0x0007ffff) || _x1_) \
- _x_inout_[0] = _x0_ ^ 0x00080000; \
- else { \
- _x_inout_[0] = (_x0_&0x80000000) | 0x7fffffff; \
- _x_inout_[1] = 0xffffffff; \
- (rc) |= FLTERR_INEXACT; \
- } \
- } while (0)
-
-# define FLTFMT__FROB_NAN_F128(x_inout, rc) do { \
- uint32 *_x_inout_ = (x_inout), \
- _x0_ = _x_inout_[0], _x1_ = _x_inout_[1], \
- _x2_ = _x_inout_[2], _x3_ = _x_inout_[3]; \
- \
- if ((_x0_&0x7fff0000) != 0x7fff0000 || \
- (!(_x0_&0x000fffff) && !_x1_ && !_x2_ && !_x3_)) \
- ; \
- else if ((_x0_&0x00007fff) || _x1_ || _x2_ || _x3_) \
- _x_inout_[0] = _x0_ ^ 0x00008000; \
- else { \
- _x_inout_[0] = (_x0_&0x80000000) | 0x7fffffff; \
- _x_inout_[1] = _x_inout_[2] = _x_inout_[3] = 0xffffffff; \
- (rc) |= FLTERR_INEXACT; \
- } \
- } while (0)
-
-# define FLTFMT__FROB_NAN_IDBLEXT80(x_inout, rc) do { \
- uint32 *_x_inout_ = (x_inout), \
- _x0_ = _x_inout_[0], _x1_ = _x_inout_[1], _x2_ = _x_inout_[2]; \
- \
- if ((_x0_&0x00007fff) != 0x00007fff || (!(_x1_&0x7fffffff) && !_x2_)) \
- ; \
- else if ((_x1_&0x3fffffff) || _x1_ || _x2_) \
- _x_inout_[1] = _x1_ ^ 0x40000000; \
- else { \
- _x_inout_[1] = (_x1_&0x80000000) | 0x3fffffff; /* preserve unit */ \
- _x_inout_[2] = 0xffffffff; \
- } \
- } while (0)
-
-#else
-# define FLTFMT__FROB_NAN_F32(x_inout, rc) do ; while (0)
-# define FLTFMT__FROB_NAN_F64(x_inout, rc) do ; while (0)
-# define FLTFMT__FROB_NAN_F128(x_inout, rc) do ; while (0)
-# define FLTFMT__FROB_NAN_IDBLEXT80(x_inout, rc) do ; while (0)
-#endif
-
/* --- @fltfmt_encTY@ --- *
*
* Arguments: @ty *z_out@ = storage for the result
* zero.
*
* * If the implementation's floating-point radix is not a
- * power of two, and @x@ is a nonzero finite value, then
+ * power of two, and @x@ is a nonzero finite value, then the
* @FLTERR_INEXACT@ error bit is set (unconditionally), and
* the value is rounded by the implementation using its
* prevailing rounding policy. If the radix is a power of
*
* Returns: Error flags (@FLTERR_...@).
*
- * Use: Decode the native C floatingpoint value @x@ and store the
+ * Use: Decode the native C floating-point value @x@ and store the
* result in @z_out@.
*
* The @TY@ may be @flt@ to encode a @float@, @dbl@ to encode a
* error bit is set and the decoded payload is left empty.
*
* * If the implementation's floating-point radix is not a
- * power of two, and @x@ is a nonzero finite value, then
+ * power of two, and @x@ is a nonzero finite value, then the
* @FLTERR_INEXACT@ error bit is set (unconditionally), and
* the rounded value (according to the rounding mode @r@) is
* stored in as many fraction words as necessary to identify
* Use: Encode a native C floating-point value in an external format.
*
* The @CTY@ is an abbreviation for a C type: @flt@ for @float@,
- * or @dbl@ for @double@; @fty@ is an abbreviation for the
+ * or @dbl@ for @double@; @FTY@ is an abbreviation for the
* external format, @f32@ for IEEE Binary32, or @f64@ for IEEE
* Binary64; and @E@ is @l@ for little-endian or @b@ for
* big-endian byte order. Not all combinations are currently
* Use: Decodes a floating point value in an external format into a
* native value.
*
- * The naming conventions are the same as for @fltfmt_dbltof64b@
+ * The naming conventions are the same as for @fltfmt_CTYtoFTYE@
* above.
*
* On platforms where the external format is used natively,