Code size and check #define combos
diff --git a/README.md b/README.md
index fdf8960..bb71b6c 100644
--- a/README.md
+++ b/README.md
@@ -114,30 +114,29 @@
## Floating Point Support
By default, all floating-point features are supported. This includes
-encoding and decoding of half-precision and CBOR preferred float-point
-encoding.
+encoding and decoding of half-precision, CBOR preferred serialization
+for float-point and floating-point epoch dates.
-If full floating-point is not needed the following #defines can be used
-to reduce object code size.
+If full floating-point is not needed the following #defines can be
+used to reduce object code size.
QCBOR_DISABLE_FLOAT_HW_USE -- Avoid all use of floating-point HW.
-QCBOR_DISABLE_PREFERRED_FLOAT -- Eliminates support
-for half-precision and CBOR preferred encoding.
+QCBOR_DISABLE_PREFERRED_FLOAT -- Eliminates support for half-precision
+and CBOR preferred encoding.
-Even are #defined, QCBOR can still encode and decode basic floating
-point.
+Even if these are #defined, QCBOR can still encode and decode basic
+floating point.
-See discussion in qcbor_encode.h for details
+Defining QCBOR_DISABLE_PREFERRED_FLOAT will reduce object code size by
+about 900 bytes, though 550 of these bytes can be avoided without the
+define by just not calling any of the functions that encode
+floating-point numbers.
+Defining QCBOR_DISABLE_FLOAT_HW_USE will save a small amount of object
+code. Its main use is on CPUs that have no floating-point hardware.
-TODO: update this... The files ieee754.c and ieee754.h are support for half-precision
-floating-point. The encoding side of the floating-point functionality
-is about 500 bytes. If it is never called because no floating-point
-numbers are ever encoded, all 500 bytes will be dead stripped and not
-impact code size. The decoding side is about 150 bytes of object
-code. It is never dead stripped because it directly referenced by the
-core decoder, however it doesn't add very much to the size.
+See discussion in qcbor_encode.h for details.
## Code Size
@@ -145,26 +144,31 @@
| | smallest | largest |
|---------------|----------|---------|
- | encode only | 1000 | 1800 |
- | decode only | 2600 | 4250 |
- | combined | 3600 | 6050 |
+ | encode only | 1000 | 2100 |
+ | decode only | 2800 | 4400 |
+ | combined | 3800 | 6300 |
The following are some ways to make the code smaller.
-The gcc compiler output is usually smaller than llvm because stack guards are off by default.
-You can all turn of stack gaurds with llvm. It is safe to turn off stack guards with
-this code because Usefulbuf provides similar defenses and this code was carefully
-written to be defensive.
+The gcc compiler output is usually smaller than llvm because stack
+guards are off by default (be sure you actually have gcc and not llvm
+installed to be invoked by the gcc command). You can also turn of
+stack gaurds with llvm. It is safe to turn off stack guards with this
+code because Usefulbuf provides similar defenses and this code was
+carefully written to be defensive.
-Use fewer of the encode functions, particularly avoid floating-point and bstr wrapping. This
-combined with dead-stripping works very well to automatically omit functions
-that are not needed on the encode side.
+Use fewer of the encode functions, particularly avoid floating-point
+and bstr wrapping. This combined with dead-stripping works very well
+to automatically omit functions that are not needed on the encode
+side.
-Disable features with defines like QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA
-and QCBOR_DISABLE_PREFERRED_FLOAT.
-This is the primary means of reducing code on the decode side. More of these defines are
-planned than are currently implemented, but they are a little complex to implement because
-all the configurations must be tested.
+Disable features with defines like
+QCBOR_CONFIG_DISABLE_EXP_AND_MANTISSA (saves about 400 bytes) and
+QCBOR_DISABLE_PREFERRED_FLOAT (saves about 900 bytes). This is the
+primary means of reducing code on the decode side. More of these
+defines are planned than are currently implemented, but they are a
+little complex to implement because all the configurations must be
+tested.
## Other Software Using QCBOR
diff --git a/inc/qcbor/qcbor_encode.h b/inc/qcbor/qcbor_encode.h
index be29d1c..49bdaff 100644
--- a/inc/qcbor/qcbor_encode.h
+++ b/inc/qcbor/qcbor_encode.h
@@ -283,11 +283,13 @@
will eliminate all support for preferred serialization and
half-precision. An error will be returned when attempting to decode
half-precision. A float will always be encoded and decoded as 32-bits
- and a double will always be encoded and decoded as 64 bits.
+ and a double will always be encoded and decoded as 64 bits. This
+ will reduce object code by about 900 bytes.
Note that even if QCBOR_DISABLE_PREFERRED_FLOAT is not defined all
the float-point encoding object code can be avoided by never calling
- any functions that encode double or float.
+ any functions that encode double or float. Just not calling
+ floating-point functions will reduce object code by about 500 bytes.
On CPUs that have no floating-point hardware,
QCBOR_DISABLE_FLOAT_HW_USE should be defined in most cases. If it is
diff --git a/src/ieee754.c b/src/ieee754.c
index 1538033..3f94ee2 100644
--- a/src/ieee754.c
+++ b/src/ieee754.c
@@ -162,13 +162,6 @@
return u64;
}
-static inline float CopyUint32ToFloat(uint32_t u32)
-{
- float f;
- memcpy(&f, &u32, sizeof(uint32_t));
- return f;
-}
-
static inline double CopyUint64ToDouble(uint64_t u64)
{
double d;
@@ -325,68 +318,10 @@
}
-
-// Public function; see ieee754.h
-float IEEE754_HalfToFloat(uint16_t uHalfPrecision)
-{
- // Pull out the three parts of the half-precision float
- // Do all the work in 32 bits because that is what the end result is
- // may give smaller code size and will keep static analyzers happier.
- const uint32_t uHalfSignificand = uHalfPrecision & HALF_SIGNIFICAND_MASK;
- const int32_t nHalfUnBiasedExponent = (int32_t)((uHalfPrecision & HALF_EXPONENT_MASK) >> HALF_EXPONENT_SHIFT) - HALF_EXPONENT_BIAS;
- const uint32_t uHalfSign = (uHalfPrecision & HALF_SIGN_MASK) >> HALF_SIGN_SHIFT;
-
-
- // Make the three parts of the single-precision number
- uint32_t uSingleSignificand, uSingleSign, uSingleBiasedExponent;
- if(nHalfUnBiasedExponent == HALF_EXPONENT_ZERO) {
- // 0 or subnormal
- if(uHalfSignificand) {
- // Subnormal case
- uSingleBiasedExponent = -HALF_EXPONENT_BIAS + SINGLE_EXPONENT_BIAS +1;
- // A half-precision subnormal can always be converted to a normal single-precision float because the ranges line up
- uSingleSignificand = uHalfSignificand;
- // Shift bits from right of the decimal to left, reducing the exponent by 1 each time
- do {
- uSingleSignificand <<= 1;
- uSingleBiasedExponent--;
- } while ((uSingleSignificand & 0x400) == 0);
- uSingleSignificand &= HALF_SIGNIFICAND_MASK;
- uSingleSignificand <<= (SINGLE_NUM_SIGNIFICAND_BITS - HALF_NUM_SIGNIFICAND_BITS);
- } else {
- // Just zero
- uSingleBiasedExponent = SINGLE_EXPONENT_ZERO + SINGLE_EXPONENT_BIAS;
- uSingleSignificand = 0;
- }
- } else if(nHalfUnBiasedExponent == HALF_EXPONENT_INF_OR_NAN) {
- // NaN or Inifinity
- uSingleBiasedExponent = SINGLE_EXPONENT_INF_OR_NAN + SINGLE_EXPONENT_BIAS;
- if(uHalfSignificand) {
- // NaN
- // First preserve the NaN payload from half to single
- uSingleSignificand = uHalfSignificand & ~HALF_QUIET_NAN_BIT;
- if(uHalfSignificand & HALF_QUIET_NAN_BIT) {
- // Next, set qNaN if needed since half qNaN bit is not copied above
- uSingleSignificand |= SINGLE_QUIET_NAN_BIT;
- }
- } else {
- // Infinity
- uSingleSignificand = 0;
- }
- } else {
- // Normal number
- uSingleBiasedExponent = (uint32_t)(nHalfUnBiasedExponent + SINGLE_EXPONENT_BIAS);
- uSingleSignificand = uHalfSignificand << (SINGLE_NUM_SIGNIFICAND_BITS - HALF_NUM_SIGNIFICAND_BITS);
- }
- uSingleSign = uHalfSign;
-
- // Shift the three parts of the single-precision into place
- const uint32_t uSinglePrecision = uSingleSignificand |
- (uSingleBiasedExponent << SINGLE_EXPONENT_SHIFT) |
- (uSingleSign << SINGLE_SIGN_SHIFT);
-
- return CopyUint32ToFloat(uSinglePrecision);
-}
+/*
+ EEE754_HalfToFloat() was created but is not needed. It can be retrieved from
+ github history if needed.
+ */
// Public function; see ieee754.h
@@ -595,4 +530,8 @@
return result;
}
+#else
+
+int x;
+
#endif /* QCBOR_DISABLE_PREFERRED_FLOAT */
diff --git a/src/ieee754.h b/src/ieee754.h
index 54d4e57..d614825 100644
--- a/src/ieee754.h
+++ b/src/ieee754.h
@@ -77,13 +77,6 @@
/*
- Convert half-precision float to single-precision float. This is a
- loss-less conversion.
- */
-float IEEE754_HalfToFloat(uint16_t uHalfPrecision);
-
-
-/*
Convert double-precision float to half-precision float. Precision
and NaN payload bits will be lost. Too-large values will round up to
infinity and too small to zero.