[Git][NTPsec/ntpsec][master] 4 commits: l_fp: don't multiply to negate...

Gary E. Miller gitlab at mg.gitlab.com
Wed Apr 5 23:32:59 UTC 2017


Gary E. Miller pushed to branch master at NTPsec / ntpsec


Commits:
8b1f971c by Gary E. Miller at 2017-04-05T16:32:34-07:00
l_fp: don't multiply to negate...

All tests pass.

- - - - -
975b1525 by Gary E. Miller at 2017-04-05T16:32:34-07:00
tests/ieee754io: tweak some tests.  Avoid shift wrapping.

- - - - -
986e321a by Gary E. Miller at 2017-04-05T16:32:34-07:00
ieee754io: simplification using uint64_t.

All tests pass.

- - - - -
86e474b2 by Gary E. Miller at 2017-04-05T16:32:34-07:00
waf: Solaris and OpenBSD are not POSIX, using custom types.

Need to fix upstream bug in Bison, and test for Solaris
and OpenBSD weirdness before -Wsign-conversion can be used.

- - - - -


4 changed files:

- include/ntp_fp.h
- libparse/ieee754io.c
- tests/libparse/ieee754io.c
- wafhelpers/configure.py


Changes:

=====================================
include/ntp_fp.h
=====================================
--- a/include/ntp_fp.h
+++ b/include/ntp_fp.h
@@ -142,7 +142,7 @@ static inline l_fp ntohl_fp(l_fp_w lfpw) {
  * native operations is to be independent of whether the l_fp
  * type is signed or unsigned.
  */
-#define	L_NEG(v)	(v) = (l_fp)(-1 * (int64_t)(v))
+#define	L_NEG(v)	(v) = (l_fp)(-(int64_t)(v))
 #define	L_ISNEG(v)	M_ISNEG(lfpuint(v))
 #define	L_ISGT(a, b)	((int64_t)(a) > (int64_t)(b))
 #define	L_ISGTU(a, b)	((a) > (b))


=====================================
libparse/ieee754io.c
=====================================
--- a/libparse/ieee754io.c
+++ b/libparse/ieee754io.c
@@ -13,7 +13,7 @@
 #include "ntp_fp.h"
 #include "ieee754io.h"
 
-static unsigned long get_byte (unsigned char *, offsets_t, int *);
+static uint64_t get_byte (unsigned char *, offsets_t, int *);
 
 #ifdef DEBUG_PARSELIB
 
@@ -51,18 +51,24 @@ fmt_blong(
 static char *
 fmt_flt(
 	bool sign,
-	unsigned long mh,
-	unsigned long ml,
-	unsigned long ch
+	uint64_t ml,
+	unsigned long ch,
+        int length
 	)
 {
 	char *buf;
 
 	LIB_GETBUF(buf);
-	snprintf(buf, LIB_BUFLENGTH, "%c %s %s %s", sign ? '-' : '+',
-		 fmt_blong(ch, 11),
-		 fmt_blong(mh, 20),
-		 fmt_blong(ml, 32));
+        if ( 8 == length ) {
+	    snprintf(buf, LIB_BUFLENGTH, "%c %s %s %s", sign ? '-' : '+',
+		     fmt_blong(ch, 11),
+		     fmt_blong(ml >> 32, 20),
+		     fmt_blong(ml & 0x0FFFFFFFFULL, 32));
+        } else {
+	    snprintf(buf, LIB_BUFLENGTH, "%c %s %s", sign ? '-' : '+',
+		     fmt_blong(ch, 8),
+		     fmt_blong(ml, 23));
+        }
 
 	return buf;
 }
@@ -89,22 +95,18 @@ fmt_hex(
 
 #endif
 
-static unsigned long
+static uint64_t
 get_byte(
 	 unsigned char *bufp,
 	 offsets_t offset,
 	 int *fieldindex
 	 )
 {
-  unsigned char val;
+    unsigned char val;
 
-  val     = *(bufp + offset[*fieldindex]);
-#ifdef DEBUG_PARSELIB
-  if (debug > 4)
-    printf("fetchieee754: getbyte(0x%08x, %d) = 0x%02x\n", (unsigned int)(bufp)+offset[*fieldindex], *fieldindex, val);
-#endif
-  (*fieldindex)++;
-  return val;
+    val = *(bufp + offset[*fieldindex]);
+    (*fieldindex)++;
+    return val;
 }
 
 /*
@@ -121,20 +123,17 @@ fetch_ieee754(
 {
   unsigned char *bufp = *buffpp;
   bool sign;
-  unsigned int bias;
+  unsigned int bias;               /* bias 127 or 1023 */
   unsigned int maxexp;
-  int mbits;
-  unsigned long mantissa_low;
-  unsigned long mantissa_high;
-  unsigned long characteristic;    /* biased exponent */
-  long exponent;                   /* unbiased exponent */
+  int mbits;                       /* length of mantissa, 23 or 52 */
+  uint64_t mantissa;               /* mantissa, 23 or 52 bits used, +1 */
+  unsigned long characteristic;    /* biased exponent, 0 to 255 or 2047 */
+  int exponent;                    /* unbiased exponent */
   unsigned int maxexp_lfp;         /* maximum exponent that fits in an l_fp */
-  int frac_offset;	           /* where the fraction starts */
-#ifdef DEBUG_PARSELIB
-  int length;
-#endif
   unsigned char val;
   int fieldindex = 0;              /* index into bufp */
+  int fudge;                       /* shift difference of l_fp and IEEE */
+  int shift;                       /* amount to shift IEEE to get l_fp */
   
 
   *lfpp = 0;           /* return zero for all errors: NAN, +INF, -INF, etc. */
@@ -151,9 +150,7 @@ fetch_ieee754(
   switch (size)
     {
     case IEEE_DOUBLE:
-#ifdef DEBUG_PARSELIB
-      length = 8;
-#endif
+      fudge = -20;
       maxexp_lfp = 31;
       mbits  = 52;
       bias   = 1023;
@@ -162,20 +159,18 @@ fetch_ieee754(
       /* grab lower characteristic bits */
       characteristic  |= (val & 0xF0U) >> 4;
 
-      mantissa_high  = (val & 0x0FU) << 16;
-      mantissa_high |= get_byte(bufp, offsets, &fieldindex) << 8;
-      mantissa_high |= get_byte(bufp, offsets, &fieldindex);
+      mantissa  = (val & 0x0FULL) << 48;
+      mantissa |= get_byte(bufp, offsets, &fieldindex) << 40;
+      mantissa |= get_byte(bufp, offsets, &fieldindex) << 32;
 
-      mantissa_low   = get_byte(bufp, offsets, &fieldindex) << 24;
-      mantissa_low  |= get_byte(bufp, offsets, &fieldindex) << 16;
-      mantissa_low  |= get_byte(bufp, offsets, &fieldindex) << 8;
-      mantissa_low  |= get_byte(bufp, offsets, &fieldindex);
+      mantissa |= get_byte(bufp, offsets, &fieldindex) << 24;
+      mantissa |= get_byte(bufp, offsets, &fieldindex) << 16;
+      mantissa |= get_byte(bufp, offsets, &fieldindex) << 8;
+      mantissa |= get_byte(bufp, offsets, &fieldindex);
       break;
 
     case IEEE_SINGLE:
-#ifdef DEBUG_PARSELIB
-      length = 4;
-#endif
+      fudge = 9;
       maxexp_lfp = 127;
       mbits  = 23;
       bias   = 127;
@@ -184,43 +179,27 @@ fetch_ieee754(
       /* grab last characteristic bit from 2nd byte */
       characteristic |= (val & 0x80) ? 1U : 0 ;
 
-      mantissa_high  = 0;
-
-      mantissa_low   = (val & 0x7FU) << 16;
-      mantissa_low  |= get_byte(bufp, offsets, &fieldindex) << 8;
-      mantissa_low  |= get_byte(bufp, offsets, &fieldindex);
+      mantissa   = (val & 0x7FU) << 16;
+      mantissa  |= get_byte(bufp, offsets, &fieldindex) << 8;
+      mantissa  |= get_byte(bufp, offsets, &fieldindex);
       break;
 
     default:
       return IEEE_BADCALL;
     }
 
-#ifdef DEBUG_PARSELIB
-  if (debug > 4) {
-    double d;
-    float f;
-
-    if (size == IEEE_SINGLE)
-      {
-	int i;
-
-	for (i = 0; i < length; i++)
-	  {
-	    *((unsigned char *)(&f)+i) = *(*buffpp + offsets[i]);
-	  }
-	d = f;
-    } else {
-	int i;
+  exponent = (int)characteristic - (int)bias;
 
-	for (i = 0; i < length; i++)
-	  {
-	    *((unsigned char *)(&d)+i) = *(*buffpp + offsets[i]);
-	  }
+#ifdef DEBUG_PARSELIB
+  if ( 1 || debug > 4) {
+    int length = 8;
+    if ( IEEE_SINGLE == size ) {
+	length = 4;
     }
-    
-    printf("fetchieee754: FP: %s -> %s -> %e(=%s)\n", fmt_hex(*buffpp, length),
-	   fmt_flt(sign, mantissa_high, mantissa_low, characteristic),
-	   d, fmt_hex((unsigned char *)&d, length));
+
+    printf("\nfetchieee754: FP: %s -> %s\n", fmt_hex(*buffpp, length),
+	   fmt_flt(sign, mantissa, characteristic, length));
+    printf("fetchieee754: Exp: %d, mbits %d\n", exponent, mbits);
   }
 #endif
 
@@ -233,7 +212,7 @@ fetch_ieee754(
       /*
        * NaN or Infinity
        */
-      if (mantissa_low || mantissa_high) {
+      if (mantissa) {
 	  /*
 	   * NaN
 	   */
@@ -251,9 +230,8 @@ fetch_ieee754(
   /*
    * check for overflows
    */
-  exponent = (long int)characteristic - bias;
 
-  if (exponent > maxexp_lfp) {
+  if (exponent > (int)maxexp_lfp) {
       /*
        * sorry an l_fp only so long
        * overflow only in respect to NTP-FP representation
@@ -261,56 +239,28 @@ fetch_ieee754(
       return sign ? IEEE_NEGOVERFLOW : IEEE_POSOVERFLOW;
   }
 
-  frac_offset = mbits - exponent;
-
-  if (characteristic == 0) {
-      /*
-       * de-normalized or tiny number - fits only as 0
-       */
-      return IEEE_OK;
-  }
-
-  /*
-   * adjust for implied 1
-   */
-  if (mbits > 31)
-    mantissa_high |= 1U << (mbits - 32);
-  else
-    mantissa_low  |= 1U << mbits;
-
-  /*
-   * take mantissa apart - if only all machine would support
-   * 64 bit operations 8-(
-   */
-  if (frac_offset > mbits) {
-      frac_offset -= mbits + 1; /* will now contain right shift count - 1*/
-      if (mbits > 31) {
-	  uint32_t frac;
-	  frac   = mantissa_high << (63 - mbits);
-	  frac  |= mantissa_low  >> (mbits - 33);
-	  frac >>= frac_offset;
-	  *lfpp = lfpfrac(frac);
-      } else {
-	  *lfpp = lfpfrac( mantissa_low >> frac_offset);
-      }
-  } else if (frac_offset > 32) {
-	/*
-	 * must split in high word
-	 */
-	*lfpp = lfptouint(mantissa_high >> (frac_offset - 32));
-	*lfpp |= lfpfrac(((mantissa_high &
-                       ((1U << (frac_offset - 32)) - 1)) << (64 - frac_offset)) |
-                        (mantissa_low  >> (frac_offset - 32)));
-  } else {
+    if (characteristic == 0) {
 	/*
-	 * must split in low word
+	 * de-normalized or tiny number - fits only as 0
 	 */
-	*lfpp = lfptouint((mantissa_high << (32 - frac_offset)) |
-                          (((mantissa_low >> frac_offset) &
-                           ((1U << (32 - frac_offset)) - 1))));
-	/* coverity[large_shift] */
-	*lfpp |= lfpfrac((mantissa_low &
-                        ((1U << frac_offset) - 1)) << (32 - frac_offset));
+	return IEEE_OK;
+    }
+
+    /*
+     * add in implied 1
+     */
+    mantissa  |= 1ULL << mbits;
+
+    shift = exponent + fudge;
+    if ( 0 == shift ) {
+	/* no shift */
+	*lfpp = mantissa;
+    } else if ( 0 > shift ) {
+	/* right shift */
+	*lfpp = mantissa >> -shift;
+    } else {
+	/* left shift */
+	*lfpp = mantissa << shift;
     }
 
     /*


=====================================
tests/libparse/ieee754io.c
=====================================
--- a/tests/libparse/ieee754io.c
+++ b/tests/libparse/ieee754io.c
@@ -103,10 +103,9 @@ TEST(ieee754io, test_nan32) {
 
 TEST(ieee754io, test_max32) {
         int ret;
-        /* not enough precision in a float to get max l_fp */
-        unsigned char buf[4] = { 127, 127, 255, 255};
-        /* not enough precision in a float to get negative max l_fp */
-        unsigned char buf_n[4] = { 255, 127, 255, 255};
+        /* not enough precision in a float to get precision of l_fp */
+        unsigned char buf[4] = { 0x4e, 0xff, 255, 255};
+        unsigned char buf_n[4] = { 0xce, 0xff, 255, 255};
         unsigned char *bp = &buf[0];
         l_fp fp;
 
@@ -114,14 +113,14 @@ TEST(ieee754io, test_max32) {
         ret = fetch_ieee754( &bp, IEEE_SINGLE, &fp, native_off);
 
         TEST_ASSERT( IEEE_OK == ret);
-        TEST_ASSERT_EQUAL_UINT64( (unsigned long)0xFFFFFF00UL, fp );
+        TEST_ASSERT_EQUAL_INT64( 0x7FFFFF8000000000UL, fp );
 
         /* negative max that fits */
         bp = &buf_n[0];
         ret = fetch_ieee754( &bp, IEEE_SINGLE, &fp, native_off);
 
         TEST_ASSERT( IEEE_OK == ret);
-        TEST_ASSERT_EQUAL_UINT64( (unsigned long)0xFFFFFFFF00000100UL, fp );
+        TEST_ASSERT_EQUAL_UINT64( 0x8000008000000000UL, fp );
 }
 
 TEST(ieee754io, test_order32) {
@@ -150,7 +149,7 @@ TEST(ieee754io, test_order32) {
 TEST(ieee754io, test_small32) {
         int ret;
         /* small number, one LSB of l_fp */
-        unsigned char buf[4] = { 0x33, 255, 255, 255};
+        unsigned char buf[4] = { 0x2F, 255, 255, 255};
         unsigned char *bp = &buf[0];
         l_fp fp;
 
@@ -299,7 +298,7 @@ TEST(ieee754io, test_order64) {
 TEST(ieee754io, test_small64) {
         int ret;
         /* small number, one LSB of l_fp  */
-        unsigned char buf[8] = { 0x33, 255, 255, 255, 255, 255, 255, 255};
+        unsigned char buf[8] = { 0x3d, 255, 255, 255, 255, 255, 255, 255};
         unsigned char *bp = &buf[0];
         l_fp fp;
 


=====================================
wafhelpers/configure.py
=====================================
--- a/wafhelpers/configure.py
+++ b/wafhelpers/configure.py
@@ -279,7 +279,7 @@ def cmd_configure(ctx, config):
         # "-Wfloat-equal",   # Not Ready For Prime Time
         # "-Wmissing-prototypes",  # Not Ready For Prime Time
         # "-Wmissing-declarations", # Not Ready For Primt Time
-        "-Wsign-conversion",
+        # "-Wsign-conversion",      # fails on Solaris and OpenBSD 6
         "-Wshadow",
         "-Wstrict-prototypes",
         "-Wundef",



View it on GitLab: https://gitlab.com/NTPsec/ntpsec/compare/7de3fc541cf80b0288b1ac5c8ca4de578fd162fd...86e474b20b5bc8b7dcfcafdfa382dc7ee52b0562
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20170405/a0af562f/attachment.html>


More information about the vc mailing list