Move the floating point code to cborinternal_p.h

... and put it behind #ifndef CBOR_NO_FLOATING_POINT.

The functions were not really compiler support, but are internal
functionality of TinyCBOR. This commit also puts both the <math.H> and
<float.h> headers behind an #if, so constrained systems without floating
point support won't enable it.

Signed-off-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Thiago Macieira
2018-08-13 21:03:31 -07:00
parent 88943666c4
commit bfc40dcf90
5 changed files with 107 additions and 70 deletions
+19 -2
View File
@@ -15,6 +15,7 @@ matrix:
- QMAKESPEC=linux-g++
- EVAL="CC=gcc-7 && CXX=g++-7"
- CFLAGS="-Os"
- LDFLAGS="-Wl,--no-undefined -lm"
- QMAKEFLAGS="-config release"
- os: linux
addons:
@@ -29,9 +30,23 @@ matrix:
- EVAL="CC=clang-5.0 && CXX=clang++"
- PATH=$PATH:/usr/local/clang/bin
- CFLAGS="-Oz"
- LDFLAGS="-Wl,--no-undefined -lm"
- QMAKEFLAGS="-config release"
- MAKEFLAGS=-s
- TESTARGS=-silent
- os: linux
env:
- QMAKESPEC=linux-gcc-freestanding
- EVAL="CXX=false"
- CFLAGS="-ffreestanding -Os"
- LDFLAGS="-Wl,--no-undefined -lm"
- os: linux
env:
- QMAKESPEC=linux-gcc-no-math
- EVAL="CXX=false && touch src/math.h src/float.h"
- CFLAGS="-ffreestanding -DCBOR_NO_FLOATING_POINT -Os"
- LDFLAGS="-Wl,--no-undefined"
- LDLIBS=""
- os: osx
env:
- QMAKESPEC=macx-clang
@@ -57,10 +72,12 @@ script:
- make -s clean
- make -k
CFLAGS="$CFLAGS -O0 -g"
- make
LDFLAGS="$LDFLAGS" ${LDLIBS+LDLIBS="$LDLIBS"}
- grep -q freestanding-pass .config || make
QMAKEFLAGS="$QMAKEFLAGS QMAKE_CXX=$CXX"
tests/Makefile
- (cd tests && make check -k
- grep -q freestanding-pass .config ||
(cd tests && make check -k
TESTRUNNER=`which valgrind 2>/dev/null`)
- make -s clean
- ./scripts/update-docs.sh
+69
View File
@@ -27,6 +27,75 @@
#include "compilersupport_p.h"
#ifndef CBOR_NO_FLOATING_POINT
# include <float.h>
# include <math.h>
#else
# ifndef CBOR_NO_HALF_FLOAT_TYPE
# define CBOR_NO_HALF_FLOAT_TYPE 1
# endif
#endif
#ifndef CBOR_NO_HALF_FLOAT_TYPE
# ifdef __F16C__
# include <immintrin.h>
static inline unsigned short encode_half(double val)
{
return _cvtss_sh((float)val, 3);
}
static inline double decode_half(unsigned short half)
{
return _cvtsh_ss(half);
}
# else
/* software implementation of float-to-fp16 conversions */
static inline unsigned short encode_half(double val)
{
uint64_t v;
int sign, exp, mant;
memcpy(&v, &val, sizeof(v));
sign = v >> 63 << 15;
exp = (v >> 52) & 0x7ff;
mant = v << 12 >> 12 >> (53-11); /* keep only the 11 most significant bits of the mantissa */
exp -= 1023;
if (exp == 1024) {
/* infinity or NaN */
exp = 16;
mant >>= 1;
} else if (exp >= 16) {
/* overflow, as largest number */
exp = 15;
mant = 1023;
} else if (exp >= -14) {
/* regular normal */
} else if (exp >= -24) {
/* subnormal */
mant |= 1024;
mant >>= -(exp + 14);
exp = -15;
} else {
/* underflow, make zero */
return 0;
}
/* safe cast here as bit operations above guarantee not to overflow */
return (unsigned short)(sign | ((exp + 15) << 10) | mant);
}
/* this function was copied & adapted from RFC 7049 Appendix D */
static inline double decode_half(unsigned short half)
{
int exp = (half >> 10) & 0x1f;
int mant = half & 0x3ff;
double val;
if (exp == 0) val = ldexp(mant, -24);
else if (exp != 31) val = ldexp(mant + 1024, exp - 25);
else val = mant == 0 ? INFINITY : NAN;
return half & 0x8000 ? -val : val;
}
# endif
#endif /* CBOR_NO_HALF_FLOAT_TYPE */
#ifndef CBOR_INTERNAL_API
# define CBOR_INTERNAL_API
#endif
+3 -6
View File
@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2017 Intel Corporation
** Copyright (C) 2018 Intel Corporation
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
@@ -36,11 +36,6 @@
#include <inttypes.h>
#include <string.h>
#ifndef CBOR_NO_FLOATING_POINT
# include <float.h>
# include <math.h>
#endif
/**
* \defgroup CborPretty Converting CBOR to text
* \brief Group of functions used to convert CBOR to text form.
@@ -149,6 +144,7 @@
* \value CborPrettyDefaultFlags Default conversion flags.
*/
#ifndef CBOR_NO_FLOATING_POINT
static inline bool convertToUint64(double v, uint64_t *absolute)
{
double supremum;
@@ -179,6 +175,7 @@ static inline bool convertToUint64(double v, uint64_t *absolute)
*absolute = v;
return *absolute == v;
}
#endif
static void printRecursionLimit(CborStreamFunction stream, void *out)
{
+16 -3
View File
@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 Intel Corporation
** Copyright (C) 2018 Intel Corporation
**
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
@@ -32,11 +32,10 @@
#include "cbor.h"
#include "cborjson.h"
#include "cborinternal_p.h"
#include "compilersupport_p.h"
#include <float.h>
#include <inttypes.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -595,6 +594,7 @@ static CborError value_to_json(FILE *out, CborValue *it, int flags, CborType typ
break;
}
#ifndef CBOR_NO_FLOATING_POINT
case CborDoubleType: {
double val;
if (false) {
@@ -606,9 +606,15 @@ static CborError value_to_json(FILE *out, CborValue *it, int flags, CborType typ
} else if (false) {
uint16_t f16;
case CborHalfFloatType:
# ifndef CBOR_NO_HALF_FLOAT_TYPE
status->flags = TypeWasNotNative;
cbor_value_get_half_float(it, &f16);
val = decode_half(f16);
# else
(void)f16;
err = CborErrorUnsupportedType;
break;
# endif
} else {
cbor_value_get_double(it, &val);
}
@@ -634,6 +640,13 @@ static CborError value_to_json(FILE *out, CborValue *it, int flags, CborType typ
}
break;
}
#else
case CborDoubleType:
case CborFloatType:
case CborHalfFloatType:
err = CborErrorUnsupportedType;
break;
#endif /* !CBOR_NO_FLOATING_POINT */
case CborInvalidType:
return CborErrorUnknownType;
-59
View File
@@ -36,8 +36,6 @@
#ifndef assert
# include <assert.h>
#endif
#include <float.h>
#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
@@ -46,10 +44,6 @@
# include <stdbool.h>
#endif
#ifdef __F16C__
# include <immintrin.h>
#endif
#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L || __cpp_static_assert >= 200410
# define cbor_static_assert(x) static_assert(x, #x)
#elif !defined(__cplusplus) && defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) && (__STDC_VERSION__ > 199901L)
@@ -207,58 +201,5 @@ static inline bool add_check_overflow(size_t v1, size_t v2, size_t *r)
#endif
}
static inline unsigned short encode_half(double val)
{
#ifdef __F16C__
return _cvtss_sh((float)val, 3);
#else
uint64_t v;
int sign, exp, mant;
memcpy(&v, &val, sizeof(v));
sign = v >> 63 << 15;
exp = (v >> 52) & 0x7ff;
mant = v << 12 >> 12 >> (53-11); /* keep only the 11 most significant bits of the mantissa */
exp -= 1023;
if (exp == 1024) {
/* infinity or NaN */
exp = 16;
mant >>= 1;
} else if (exp >= 16) {
/* overflow, as largest number */
exp = 15;
mant = 1023;
} else if (exp >= -14) {
/* regular normal */
} else if (exp >= -24) {
/* subnormal */
mant |= 1024;
mant >>= -(exp + 14);
exp = -15;
} else {
/* underflow, make zero */
return 0;
}
/* safe cast here as bit operations above guarantee not to overflow */
return (unsigned short)(sign | ((exp + 15) << 10) | mant);
#endif
}
/* this function was copied & adapted from RFC 7049 Appendix D */
static inline double decode_half(unsigned short half)
{
#ifdef __F16C__
return _cvtsh_ss(half);
#else
int exp = (half >> 10) & 0x1f;
int mant = half & 0x3ff;
double val;
if (exp == 0) val = ldexp(mant, -24);
else if (exp != 31) val = ldexp(mant + 1024, exp - 25);
else val = mant == 0 ? INFINITY : NAN;
return half & 0x8000 ? -val : val;
#endif
}
#endif /* COMPILERSUPPORT_H */