chiark / gitweb /
@@@ fltfmt fettling mdw/tvec
authorMark Wooding <mdw@distorted.org.uk>
Sun, 27 Apr 2025 03:06:06 +0000 (04:06 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 27 Apr 2025 03:19:42 +0000 (04:19 +0100)
utils/fltfmt-convert.c
utils/fltfmt.c
utils/fltfmt.h

index cc24dba5f777b81f7201a4820ef09ef03121bc60..0b6971fc76a3df322a521d187e30c7549b9c2135 100644 (file)
@@ -199,7 +199,7 @@ CONVERSIONS(DEF_CONV)
  * 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,
index cb39eca4cbaa145f87ecc360fd7b3eb735f763b1..177004e89c1532f6396f9010c48d2ac48a065833 100644 (file)
@@ -301,7 +301,7 @@ static unsigned ms_set_bit(const uint32 *x, unsigned from, unsigned to)
    */
 
   /* 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);
@@ -757,7 +757,9 @@ unsigned fltfmt_encieee(const struct fltfmt_ieeefmt *fmt,
        /* 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);
@@ -1203,8 +1205,10 @@ unsigned fltfmt_decidblext80(struct floatbits *z_out, uint16 se, kludge64 m)
     * 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
@@ -1231,6 +1235,11 @@ unsigned fltfmt_decidblext80(struct floatbits *z_out, uint16 se, kludge64 m)
 #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) {                                         \
@@ -1239,6 +1248,11 @@ unsigned fltfmt_decidblext80(struct floatbits *z_out, uint16 se, kludge64 m)
      }                                                                 \
    } 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
@@ -1412,7 +1426,7 @@ unsigned fltfmt_decidblext80(struct floatbits *z_out, uint16 se, kludge64 m)
  *                 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
@@ -1508,10 +1522,20 @@ unsigned fltfmt_encldbl(long double *z_out,
 #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
 
@@ -1638,7 +1662,7 @@ unsigned fltfmt_encldbl(long double *z_out,
  *
  * 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
@@ -1655,7 +1679,7 @@ unsigned fltfmt_encldbl(long double *z_out,
  *                 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
index efa678c40f9c397a9812e42d81d6eec7fff695d9..cfdbbe783d5d8891d6116e450f55c2c1847cefb8 100644 (file)
@@ -55,7 +55,7 @@
 
 /* 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 */
 
@@ -483,84 +483,6 @@ extern unsigned fltfmt_decidblext80(struct floatbits */*z_out*/,
 
 /*----- 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
@@ -594,7 +516,7 @@ extern unsigned fltfmt_decidblext80(struct floatbits */*z_out*/,
  *                 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
@@ -625,7 +547,7 @@ extern unsigned fltfmt_encldbl(long double */*z_out*/,
  *
  * 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
@@ -642,7 +564,7 @@ extern unsigned fltfmt_encldbl(long double */*z_out*/,
  *                 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
@@ -674,7 +596,7 @@ extern unsigned fltfmt_decldbl(struct floatbits */*z_out*/,
  * 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
@@ -700,7 +622,7 @@ extern unsigned fltfmt_dbltof64b(octet */*p*/, double /*x*/, unsigned /*r*/);
  * 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,