[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