Archived
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:
+19
-2
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user