Loading...
--- Libc/Libc-1725.40.4/stdlib/strtofp.c
+++ Libc/Libc-1583.40.7/stdlib/strtofp.c
@@ -285,50 +285,23 @@
#include <assert.h>
#include <ctype.h>
#include <errno.h>
+#include <fenv.h>
#include <float.h>
-#include <stdbool.h>
+#if !defined(ENABLE_LOCALE_SUPPORT) || ENABLE_LOCALE_SUPPORT
+#include <langinfo.h>
+#include <locale.h>
+#endif
+#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <strings.h>
-
-// Check whether access to the floating-point environment is supported
-#if !defined(ENABLE_FENV_ACCESS)
-#if __has_include(<fenv.h>)
- #include <fenv.h>
-
- #define ENABLE_FENV_ACCESS 1
-#else
- #define ENABLE_FENV_ACCESS 0
-#endif
-#endif
-
-// Check whether precision/range of floating-point values is defined
-#if __has_include(<math.h>)
- #include <math.h>
-#else
-#if !defined(FLT_EVAL_METHOD)
- // Note that Clang's builtin float.h header does define this macro
- #define FLT_EVAL_METHOD -1
-#endif
-#endif
-
-// Check whether locales are supported
-#if !defined(ENABLE_LOCALE_SUPPORT)
-#if __has_include(<langinfo.h>) && __has_include(<locale.h>)
- #include <langinfo.h>
- #include <locale.h>
-#if defined(__APPLE__)
- #include <xlocale.h>
- #include <xlocale_private.h>
-#endif
-
- #define ENABLE_LOCALE_SUPPORT 1
-#else
- #define ENABLE_LOCALE_SUPPORT 0
-#endif
-#endif
+#if defined(__APPLE__) && (!defined(ENABLE_LOCALE_SUPPORT) || ENABLE_LOCALE_SUPPORT)
+#include <xlocale.h>
+#include <xlocale_private.h>
+#endif
+
+// #pragma STDC FENV_ACCESS ON
// ================================================================
// Detect the floating-point formats supported on this platform
@@ -362,17 +335,17 @@
// Is "long double" on this system the same as Float80?
// (Example: macOS, Linux, and FreeBSD when running on x86 or x86_64 processors.)
#if (FLT_RADIX == 2) && (LDBL_MANT_DIG == 64) && (LDBL_MIN_EXP == -16381) && (LDBL_MAX_EXP == 16384)
- #define LONG_DOUBLE_IS_FLOAT80 1
+ #define LONG_DOUBLE_IS_FLOAT80 1
#else
- #define LONG_DOUBLE_IS_FLOAT80 0
+ #define LONG_DOUBLE_IS_FLOAT80 0
#endif
// Does "long double" on this system use IEEE 754 binary128 format?
// (Example: Android on LP64 hardware.)
#if (FLT_RADIX == 2) && (LDBL_MANT_DIG == 113) && (LDBL_MIN_EXP == -16381) && (LDBL_MAX_EXP == 16384)
- #define LONG_DOUBLE_IS_BINARY128 1
+ #define LONG_DOUBLE_IS_BINARY128 1
#else
- #define LONG_DOUBLE_IS_BINARY128 0
+ #define LONG_DOUBLE_IS_BINARY128 0
#endif
// ================================================================
@@ -397,6 +370,11 @@
// calling the standard functions: We defer such calls until
// we see a character that is not a digit or other known character,
// and we handle the "C" locale specially.)
+
+// Enable locale support by default
+#ifndef ENABLE_LOCALE_SUPPORT
+ #define ENABLE_LOCALE_SUPPORT 1
+#endif
// Define macros used for locale information below:
//
@@ -436,36 +414,6 @@
#error Need definition for strtofp_locale_decimal_point and strtofp_current_locale for this platform
#endif
-// ================================================================
-// Floating-point rounding mode
-
-#if ENABLE_FENV_ACCESS
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wignored-pragmas"
- #pragma STDC FENV_ACCESS ON
- #pragma GCC diagnostic pop
-
- #define FENV_ROUNDING_MODE() fegetround()
-#else
- // By default, we use FE_TONEAREST, which rounds to the nearest representable value
- #define FENV_ROUNDING_MODE() 0
-#endif
-
-// In certain scenarios, we require FE_TOWARDZERO, which rounds towards zero,
-// but need to provide a sentinel value if it is not defined
-#ifndef FE_TOWARDZERO
- #define FE_TOWARDZERO 0xFE00
-#endif
-
-#if defined(FE_DOWNWARD) && FE_TOWARDZERO == FE_DOWNWARD
- #error "Definition of FE_TOWARDZERO conflicts with FE_DOWNWARD"
-#endif
-#if defined(FE_TONEAREST) && FE_TOWARDZERO == FE_TONEAREST
- #error "Definition of FE_TOWARDZERO conflicts with FE_TONEAREST"
-#endif
-#if defined(FE_UPWARD) && FE_TOWARDZERO == FE_UPWARD
- #error "Definition of FE_TOWARDZERO conflicts with FE_UPWARD"
-#endif
// ================================================================
//
@@ -511,7 +459,7 @@
#define ENABLE_FLOAT80_OPTIMIZATIONS 1
#endif
#else
- #define ENABLE_FLOAT80_OPTIMIZATIONS 0
+ #undef ENABLE_FLOAT80_OPTIMIZATIONS
#endif
// Enable binary128 interval optimization by default.
@@ -520,7 +468,7 @@
#define ENABLE_BINARY128_OPTIMIZATIONS 1
#endif
#else
- #define ENABLE_BINARY128_OPTIMIZATIONS 0
+ #undef ENABLE_BINARY128_OPTIMIZATIONS
#endif
// At least one format must be enabled
@@ -998,7 +946,7 @@
static const int mp_word_bits = sizeof(mp_word_t) * 8;
// __builtin_clz() takes an `unsigned` which may be different from mp_word_t
// This adjusts the result accordingly.
-#define CLZ_WORD(word) ((unsigned)__builtin_clz((word)) + (mp_word_bits - sizeof(unsigned) * 8))
+#define CLZ_WORD(word) (__builtin_clz((word)) + (mp_word_bits - sizeof(unsigned) * 8))
// A multi-precision integer is represented as two pointers:
// lsw - points to least-significant word (lowest address in memory)
@@ -1083,10 +1031,8 @@
static mp_t shiftRightMPWithRounding(mp_t work,
int shift,
int trailingNonZero,
- bool negative,
+ int negative,
int roundingMode) {
- (void)negative;
-
if (shift == 0) {
return work;
}
@@ -1104,17 +1050,12 @@
// words and possibly increment.
result.lsw += wordsShift;
switch (roundingMode) {
-#ifdef FE_TOWARDZERO
case FE_TOWARDZERO:
return result;
-#endif
-#ifdef FE_DOWNWARD
case FE_DOWNWARD:
// Upwards & downwards rounding are symmetric
negative = !negative;
// FALL THROUGH
-#endif
-#ifdef FE_UPWARD
case FE_UPWARD:
for (mp_word_t *p = work.lsw; p < result.lsw; p++) {
trailingNonZero |= *p;
@@ -1124,15 +1065,12 @@
} else {
break; // Increment and return
}
-#endif
-#ifdef FE_TONEAREST
case FE_TONEAREST:
-#endif
default: {
// shift is non-zero, so result.lsw[-1] is valid
// and is the most-significant-word of the fraction:
mp_word_t fractionMsw = result.lsw[-1];
- mp_word_t oneHalf = 1U << (mp_word_bits - 1);
+ mp_word_t oneHalf = 1 << (mp_word_bits - 1);
if (fractionMsw < oneHalf) {
return result;
} else if (fractionMsw > oneHalf) {
@@ -1154,35 +1092,28 @@
}
result.lsw += wordsShift;
- mp_word_t fraction = result.lsw[0] & ((1U << bitsShift) - 1);
-
- {
- mp_word_t *p = result.lsw;
- mp_dword_t t = *p++ >> bitsShift;
- for (; p < result.msw; p++) {
- t |= (mp_dword_t)*p << (mp_word_bits - bitsShift);
- p[-1] = (mp_word_t)t;
- t >>= mp_word_bits;
- }
- if (t == 0) {
- result.msw -= 1;
- } else {
- p[-1] = (mp_word_t)t;
- }
+ mp_word_t fraction = result.lsw[0] & ((1 << bitsShift) - 1);
+
+ mp_word_t *p = result.lsw;
+ mp_dword_t t = *p++ >> bitsShift;
+ for (; p < result.msw; p++) {
+ t |= (mp_dword_t)*p << (mp_word_bits - bitsShift);
+ p[-1] = (mp_word_t)t;
+ t >>= mp_word_bits;
+ }
+ if (t == 0) {
+ result.msw -= 1;
+ } else {
+ p[-1] = (mp_word_t)t;
}
switch (roundingMode) {
-#ifdef FE_TOWARDZERO
case FE_TOWARDZERO:
return result;
-#endif
-#ifdef FE_DOWNWARD
case FE_DOWNWARD:
// Upwards & downwards rounding are symmetric
negative = !negative;
// FALL THROUGH
-#endif
-#ifdef FE_UPWARD
case FE_UPWARD:
trailingNonZero |= fraction;
for (mp_word_t *p = work.lsw; p < result.lsw; p++) {
@@ -1193,12 +1124,9 @@
} else {
break; // Increment and return
}
-#endif
-#ifdef FE_TONEAREST
case FE_TONEAREST:
-#endif
default: {
- mp_word_t half = (mp_word_t)(1U << (bitsShift - 1));
+ mp_word_t half = 1 << (bitsShift - 1);
if (fraction < half) {
return result;
} else if (fraction > half) {
@@ -1258,7 +1186,7 @@
t >>= mp_word_bits;
}
while (t > 0) {
- *p++ = (mp_word_t)t;
+ *p++ = t;
t >>= mp_word_bits;
}
dest->msw = p;
@@ -1513,7 +1441,7 @@
// Decimal exponent, corrected for decimal point location
int base10Exponent;
// True if number is negative
- bool negative;
+ int negative;
};
// ================================================================
@@ -1524,7 +1452,6 @@
// ================================================================
// ================================================================
-// Store a suitably-signed infinity to the destination
static void infinity(struct parseInfo *info) {
// 16/32/64-bit formats we can hardcode the full value
// and memcpy() it. This is endian-safe (assuming that
@@ -1557,7 +1484,7 @@
// 80- and 128-bit formats we build up incrementally.
// TODO: Support big-endian.
- memset(info->dest, 0, (size_t)info->bytes);
+ memset(info->dest, 0, info->bytes);
switch(info->bytes) {
#if ENABLE_FLOAT80_SUPPORT
case 10: // float80
@@ -1574,78 +1501,10 @@
}
}
-// Store the max normal value to the destination, suitably signed.
-static void max_value(struct parseInfo *info) {
- switch (info->bytes) {
-#if ENABLE_BINARY16_SUPPORT
- case 2: { // binary16
- uint16_t raw = info->negative ? 0xfbff : 0x7bff;
- memcpy(info->dest, &raw, sizeof(raw));
- return;
- }
-#endif
-#if ENABLE_BINARY32_SUPPORT
- case 4: { // binary32
- uint32_t raw = info->negative ? 0xff7fffffUL : 0x7f7fffffUL;
- memcpy(info->dest, &raw, sizeof(raw));
- return;
- }
-#endif
-#if ENABLE_BINARY64_SUPPORT
- case 8: { // binary64
- uint64_t raw = info->negative ? 0xffefffffffffffffULL : 0x7fefffffffffffffULL;
- memcpy(info->dest, &raw, sizeof(raw));
- return;
- }
-#endif
- default:
- break;
- }
-
- // 80- and 128-bit formats we build up incrementally.
- // TODO: Support big-endian.
- memset(info->dest, 0xff, info->bytes);
- switch(info->bytes) {
-#if ENABLE_FLOAT80_SUPPORT
- case 10: // float80
- info->dest[7] = 0xff;
- info->dest[8] = 0xfe;
- info->dest[9] = info->negative ? 0xff : 0x7f;
-#endif
-#if ENABLE_BINARY128_SUPPORT
- case 16: // binary128
- info->dest[14] = 0xfe;
- info->dest[15] = info->negative ? 0xff : 0x7f;
- break;
-#endif
- }
-}
-
-// This gets invoked for inputs whose magnitude is greater
-// than the max normal value + 1 ulp.
-// Gdtoa returns signed INF for such values regardless of the
-// rounding mode. Glibc rounds them correctly.
static void overflow(struct parseInfo *info) {
// Overflow is always an ERANGE error
errno = ERANGE;
- int roundingMode = FENV_ROUNDING_MODE();
- int negative = info->negative;
-
- if (0
-#ifdef FE_TOWARDZERO
- || roundingMode == FE_TOWARDZERO
-#endif
-#ifdef FE_DOWNWARD
- || (roundingMode == FE_DOWNWARD && !negative)
-#endif
-#ifdef FE_UPWARD
- || (roundingMode == FE_UPWARD && negative)
-#endif
- ) {
- max_value(info);
- } else {
- infinity(info);
- }
+ infinity(info);
}
// This gets invoked for inputs that are nonzero, but closer to zero
@@ -1668,15 +1527,9 @@
// very small non-zero (such as "1e-999999").
errno = ERANGE;
uint8_t bottomBit = 0;
- int roundingMode = FENV_ROUNDING_MODE();
- if (0
-#ifdef FE_DOWNWARD
- || (roundingMode == FE_DOWNWARD && info->negative)
-#endif
-#ifdef FE_UPWARD
- || (roundingMode == FE_UPWARD && !info->negative)
-#endif
- ) {
+ int roundingMode = fegetround();
+ if ((roundingMode == FE_DOWNWARD && info->negative)
+ || (roundingMode == FE_UPWARD && !info->negative)) {
bottomBit = 1;
}
@@ -1708,7 +1561,7 @@
#if ENABLE_FLOAT80_SUPPORT || ENABLE_BINARY128_SUPPORT
case 10: case 16: {
// TODO: Make this endian-safe
- memset(info->dest, 0, (size_t)info->bytes); // Initialize to +0
+ memset(info->dest, 0, info->bytes); // Initialize to +0
info->dest[0] = bottomBit;
info->dest[info->bytes - 1] = info->negative ? 0x80 : 0;
break;
@@ -1768,10 +1621,10 @@
int batchSize = remainingDigitCount > 9 ? 9 : remainingDigitCount;
uint64_t batch = 0;
for (int i = 0; i < batchSize; i++, p++) {
- unsigned t = (unsigned)(*p - '0');
+ unsigned t = *p - '0';
while (t > 9) {
p += 1; // Skip non-digits (decimal point)
- t = (unsigned)(*p - '0');
+ t = *p - '0';
}
batch = batch * 10 + t;
}
@@ -1829,7 +1682,7 @@
int roundingMode,
mp_word_t *stackWorkArea,
int stackWorkAreaWords,
- bool heapAllocOK)
+ int heapAllocOK)
{
mp_t mpSignificand;
int binaryExponent;
@@ -1861,13 +1714,13 @@
int totalWordsNeeded = significandWordsNeeded + exponentWordsNeeded;
mp_t workMP;
if (totalWordsNeeded <= stackWorkAreaWords) {
- memset(stackWorkArea, 0, (size_t)stackWorkAreaWords * sizeof(mp_word_t));
+ memset(stackWorkArea, 0, stackWorkAreaWords * sizeof(mp_word_t));
workMP.lsw = workMP.msw = stackWorkArea;
} else {
assert(heapAllocOK);
- heapAlloc = (mp_word_t *)calloc((size_t)totalWordsNeeded, sizeof(mp_word_t));
+ heapAlloc = (mp_word_t *)calloc(totalWordsNeeded, sizeof(mp_word_t));
if (heapAlloc == NULL) {
- memset(info->dest, 0, (size_t)info->bytes);
+ memset(info->dest, 0, info->bytes);
return;
}
workMP.lsw = workMP.msw = heapAlloc;
@@ -1923,9 +1776,9 @@
work = stackWorkArea;
} else {
assert(heapAllocOK);
- heapAlloc = (mp_word_t *)calloc((size_t)totalWordsNeeded, sizeof(mp_word_t));
+ heapAlloc = (mp_word_t *)calloc(totalWordsNeeded, sizeof(mp_word_t));
if (heapAlloc == NULL) {
- memset(info->dest, 0, (size_t)info->bytes);
+ memset(info->dest, 0, info->bytes);
return;
}
work = heapAlloc;
@@ -2008,18 +1861,18 @@
}
// Zero-extend to sigBits and copy to dest
- size_t mpWords = (size_t)(mpSignificand.msw - mpSignificand.lsw);
- size_t expectedWords = (size_t)((info->sigBits + mp_word_bits - 1) / mp_word_bits);
+ size_t mpWords = mpSignificand.msw - mpSignificand.lsw;
+ size_t expectedWords = (info->sigBits + mp_word_bits - 1) / mp_word_bits;
if (mpWords < expectedWords) {
memset(mpSignificand.lsw + mpWords, 0, (expectedWords - mpWords) * sizeof(mp_word_t));
}
// TODO: Endianness. This only works for little-endian systems.
- memcpy(info->dest, mpSignificand.lsw, ((unsigned)info->sigBits + 7) / 8);
+ memcpy(info->dest, mpSignificand.lsw, (info->sigBits + 7) / 8);
// Free the heap work area (if any)
free(heapAlloc);
// Set the exponent & sign bits
- uint16_t exponentBits = (uint16_t)(binaryExponent - info->minBinaryExp);
+ uint16_t exponentBits = binaryExponent - info->minBinaryExp;
if (info->bytes <= 8) {
// float80 and binary128 have 16 bit exponent+sign, so no shift needed
exponentBits <<= 16 - (info->bytes * 8 - info->sigBits + 1);
@@ -2058,7 +1911,8 @@
// been verified to be '0x'.
static void
hexFloat(const unsigned char *start, struct parseInfo *info) {
- const unsigned char *p = start + 2; // Skip leading '0x'
+ const unsigned char *p = start;
+ p += 2; // Skip leading '0x'
// Two 64-bit ints that we use as a joint 128-bit accumulator
uint64_t significand_lsw = 0, significand_msw = 0;
@@ -2151,15 +2005,15 @@
} else {
// Skip zeros in "0x1p+0000000000000000000000000001"
int exp = 0;
- unsigned t = (unsigned)(*p - '0');
+ unsigned t = *p - '0';
while (t < 10) {
if (exp > 99999999) {
exp = 99999999;
} else {
- exp = exp * 10 + (int)t;
+ exp = exp * 10 + t;
}
p += 1;
- t = (unsigned)(*p - '0');
+ t = *p - '0';
}
if (negativeExponent) {
exp = -exp;
@@ -2226,12 +2080,9 @@
significand_msw = 0;
}
- switch (FENV_ROUNDING_MODE()) {
-#ifdef FE_TOWARDZERO
+ switch (fegetround()) {
case FE_TOWARDZERO:
break;
-#endif
-#ifdef FE_DOWNWARD
case FE_DOWNWARD:
if (info->negative && (fraction != 0)) {
significand_lsw += 1;
@@ -2240,8 +2091,6 @@
}
}
break;
-#endif
-#ifdef FE_UPWARD
case FE_UPWARD:
if (!info->negative && (fraction != 0)) {
significand_lsw += 1;
@@ -2250,10 +2099,7 @@
}
}
break;
-#endif
-#ifdef FE_TONEAREST
case FE_TONEAREST:
-#endif
default: {
const uint64_t oneHalf = (uint64_t)1 << 63;
if (fraction > oneHalf
@@ -2280,14 +2126,13 @@
significand_msw >>= 1;
}
base2Exponent += 1;
- } else if (base2Exponent == info->minBinaryExp // Subnormal
- && fraction != 0) { // Not exact
- errno = ERANGE;
- }
- }
- }
-
- if (info->end) *info->end = (char *)(uintptr_t)p;
+ } else if (base2Exponent == info->minBinaryExp) {
+ errno = ERANGE; // Subnormal did not overflow to normal, so set ERANGE
+ }
+ }
+ }
+
+ if (info->end) *info->end = (char *)p;
if (base2Exponent > info->maxBinaryExp) {
overflow(info);
} else if (base2Exponent < info->minBinaryExp - info->sigBits + 1) {
@@ -2296,33 +2141,33 @@
switch (info->bytes) {
#if ENABLE_BINARY16_SUPPORT
case 2: {
- uint16_t exponentBits = (uint16_t)(base2Exponent - info->minBinaryExp);
- uint16_t raw = (uint16_t)
- ((info->negative ? 0x8000U : 0U)
- | (uint16_t)(exponentBits << 10)
- | (significand_lsw & 0x3ffU));
+ uint16_t exponentBits = base2Exponent - info->minBinaryExp;
+ uint16_t raw =
+ (info->negative ? 0x8000U : 0)
+ | (exponentBits << 10)
+ | (significand_lsw & 0x3ffU);
memcpy(info->dest, &raw, sizeof(raw));
break;
}
#endif
#if ENABLE_BINARY32_SUPPORT
case 4: {
- uint32_t exponentBits = (uint32_t)(base2Exponent - info->minBinaryExp);
- uint32_t raw = (uint32_t)
- ((info->negative ? 0x80000000UL : 0UL)
- | (exponentBits << 23U)
- | (uint32_t)(significand_lsw & 0x7fffffULL));
+ uint32_t exponentBits = base2Exponent - info->minBinaryExp;
+ uint32_t raw =
+ (info->negative ? 0x80000000UL : 0)
+ | (exponentBits << 23)
+ | (significand_lsw & 0x7fffffULL);
memcpy(info->dest, &raw, sizeof(raw));
break;
}
#endif
#if ENABLE_BINARY64_SUPPORT
case 8: {
- uint64_t exponentBits = (uint64_t)(base2Exponent - info->minBinaryExp);
- uint64_t raw = (uint64_t)
- ((info->negative ? 0x8000000000000000ULL : 0UL)
- | (exponentBits << 52U)
- | (significand_lsw & 0xfffffffffffffULL));
+ uint64_t exponentBits = base2Exponent - info->minBinaryExp;
+ uint64_t raw =
+ (info->negative ? 0x8000000000000000ULL : 0)
+ | (exponentBits << 52)
+ | (significand_lsw & 0xfffffffffffffULL);
memcpy(info->dest, &raw, sizeof(raw));
break;
}
@@ -2330,7 +2175,7 @@
#if ENABLE_FLOAT80_SUPPORT
case 10: {
// TODO: Support big-endian
- uint16_t exponentBits = (uint16_t)(base2Exponent - info->minBinaryExp);
+ uint16_t exponentBits = base2Exponent - info->minBinaryExp;
memcpy(info->dest, &significand_lsw, sizeof(significand_lsw));
info->dest[8] = exponentBits & 0xff;
info->dest[9] = (exponentBits >> 8) | (info->negative ? 0x80 : 0);
@@ -2340,7 +2185,7 @@
#if ENABLE_BINARY128_SUPPORT
case 16: {
// TODO: Support big-endian
- uint16_t exponentBits = (uint16_t)(base2Exponent - info->minBinaryExp);
+ uint16_t exponentBits = base2Exponent - info->minBinaryExp;
memcpy(info->dest, &significand_lsw, sizeof(significand_lsw));
memcpy(info->dest + 8, &significand_msw, sizeof(significand_msw));
info->dest[14] = exponentBits & 0xff;
@@ -2367,19 +2212,20 @@
static void parseNan(const unsigned char *start, struct parseInfo *info) {
const unsigned char *p = start + 3; // Skip "nan"
- unsigned char _Alignas(sizeof(mp_word_t)) stackWorkArea[20];
+
+ unsigned char stackWorkArea[20];
memset(stackWorkArea, 0, sizeof(stackWorkArea));
const unsigned char *endNan = p;
if (*p == '(') {
p += 1;
- unsigned base = 10;
+ int base = 10;
if (*p == '0') {
- p += 1;
- if (*p == 'x') {
+ if (p[1] == 'x') {
base = 16;
- p += 1;
+ p += 2;
} else {
base = 8;
+ p += 1;
}
}
mp_t stackMP = { (mp_word_t *)stackWorkArea,
@@ -2406,7 +2252,7 @@
}
}
// TODO: Endianness. This only works for little-endian.
- memcpy(info->dest, stackWorkArea, (size_t)info->bytes);
+ memcpy(info->dest, stackWorkArea, info->bytes);
switch (info->bytes) {
#if ENABLE_BINARY16_SUPPORT
case 2: {
@@ -2445,7 +2291,7 @@
}
#endif
}
- if (info->end) *info->end = (char *)(uintptr_t)p;
+ if (info->end) *info->end = (char *)p;
}
// This is used as the initial parse for all formats.
@@ -2474,6 +2320,7 @@
fastParse64(struct parseInfo *info) {
const unsigned char *p = (const unsigned char *)info->start;
+ const unsigned char *firstUnparsedDigit;
uint64_t digits = 0;
int digitCount = 0;
int base10Exponent = 0;
@@ -2520,7 +2367,7 @@
p += 3;
}
// Matched 'inf' or 'infinity' case-insensitive
- if (info->end) *info->end = (char *)(uintptr_t)p;
+ if (info->end) *info->end = (char *)p;
infinity(info);
return 0;
}
@@ -2571,20 +2418,18 @@
}
// Collect digits before the decimal point
- const unsigned char *firstUnparsedDigit = p;
- {
- uint8_t t = (uint8_t)(*p - '0');
- if (t < 10) {
- digits = t;
+ firstUnparsedDigit = p;
+ uint8_t t = *p - '0';
+ if (t < 10) {
+ digits = t;
+ p += 1;
+ t = *p - '0';
+ while(t < 10) {
+ digits = 10 * digits + t;
p += 1;
- t = (uint8_t)(*p - '0');
- while(t < 10) {
- digits = 10 * digits + t;
- p += 1;
- t = (uint8_t)(*p - '0');
- }
- digitCount = (int)(p - firstUnparsedDigit);
- }
+ t = *p - '0';
+ }
+ digitCount = (int)(p - firstUnparsedDigit);
}
// Try to match an optional decimal point
@@ -2633,29 +2478,29 @@
}
// "0.000000001234" has 4 digits
firstUnparsedDigit = p;
- unsigned t = (unsigned)(*p - '0');
+ unsigned t = *p - '0';
if (t < 10) {
p += 1;
digits = t;
- t = (unsigned)(*p - '0');
+ t = *p - '0';
while (t < 10) {
digits = 10 * digits + t;
p += 1;
- t = (unsigned)(*p - '0');
+ t = *p - '0';
}
}
digitCount = (int)(p - firstUnparsedDigit);
} else {
// Perf: For canada.txt benchmark, this loop is ~30% of total runtime
- unsigned t = (unsigned)(*p - '0');
+ unsigned t = *p - '0';
if (t < 10) {
p += 1;
digits = 10 * digits + t;
- t = (unsigned)(*p - '0');
+ t = *p - '0';
while (t < 10) {
p += 1;
digits = 10 * digits + t;
- t = (unsigned)(*p - '0');
+ t = *p - '0';
}
}
digitCount += p - firstDigitAfterDecimalPoint;
@@ -2676,15 +2521,15 @@
} else if (*p == '+') {
p += 1;
}
- uint8_t t = (uint8_t)(*p - '0');
+ uint8_t t = *p - '0';
if (t < 10) {
- unsigned exp = t;
+ int exp = t;
p += 1;
- t = (uint8_t)(*p - '0');
+ t = *p - '0';
while (t < 10) {
p += 1;
exp = 10 * exp + t;
- t = (uint8_t)(*p - '0');
+ t = *p - '0';
}
if (p - exponentPhraseStart > 9) {
// The exponent text was unusually long... re-parse
@@ -2702,13 +2547,13 @@
exp = 99999999;
}
}
- base10Exponent += (int)exp * negativeExponent;
+ base10Exponent += exp * negativeExponent;
} else {
p = exponentPhraseStart;
}
}
- if (info->end) *info->end = (char *)(uintptr_t)p;
+ if (info->end) *info->end = (char *)p;
// No non-zero digits, must be an explicit zero:
// "0", ".000", "0.0", "0e0", "0.0e999", etc.
@@ -2735,7 +2580,7 @@
const unsigned char *q = firstUnparsedDigit;
while (i < 19) {
// Note: Skip non-digit chars (e.g., decimal point)
- unsigned t = (unsigned)(*q - '0');
+ unsigned t = *q - '0';
if (t < 10) {
digits = digits * 10 + t;
i += 1;
@@ -2757,7 +2602,7 @@
return 1; // Regular decimal case...
fail:
- if (info->end) *info->end = (char *)(uintptr_t)info->start;
+ if (info->end) *info->end = (char *)info->start;
memset(info->dest, 0, info->bytes);
return 0;
}
@@ -2779,19 +2624,18 @@
static const int minDecimalExp = -7;
static const int maxDecimalExp = 5;
static const int maxDecimalMidpointDigits = 22;
- struct parseInfo info = {
- .bytes = bytes,
- .sigBits = sigBits,
- .minBinaryExp = minBinaryExp,
- .maxBinaryExp = maxBinaryExp,
- .minDecimalExp = minDecimalExp,
- .maxDecimalExp = maxDecimalExp,
- .maxDecimalMidpointDigits = maxDecimalMidpointDigits,
- .dest = dest,
- .start = start,
- .end = end,
- .loc = loc,
- };
+ struct parseInfo info;
+ info.bytes = bytes;
+ info.sigBits = sigBits;
+ info.minBinaryExp = minBinaryExp;
+ info.maxBinaryExp = maxBinaryExp;
+ info.minDecimalExp = minDecimalExp;
+ info.maxDecimalExp = maxDecimalExp;
+ info.maxDecimalMidpointDigits = maxDecimalMidpointDigits;
+ info.dest = dest;
+ info.start = start;
+ info.end = end;
+ info.loc = loc;
// ================================================================
// Parse the input (mostly)
@@ -2807,9 +2651,9 @@
// ================================================================
// Slow Path (varint calculation)
// ================================================================
- char _Alignas(sizeof(mp_word_t)) stackWorkArea[32];
+ char stackWorkArea[32];
static const size_t stackWorkAreaWords = sizeof(stackWorkArea) / sizeof(mp_word_t);
- generalSlowpath(&info, FENV_ROUNDING_MODE(), (mp_word_t *)stackWorkArea, stackWorkAreaWords, false);
+ generalSlowpath(&info, fegetround(), (mp_word_t *)stackWorkArea, stackWorkAreaWords, 0);
}
#endif
@@ -2829,19 +2673,18 @@
static const int minDecimalExp = -46;
static const int maxDecimalExp = 40;
static const int maxDecimalMidpointDigits = 113;
- struct parseInfo info = {
- .bytes = bytes,
- .sigBits = sigBits,
- .minBinaryExp = minBinaryExp,
- .maxBinaryExp = maxBinaryExp,
- .minDecimalExp = minDecimalExp,
- .maxDecimalExp = maxDecimalExp,
- .maxDecimalMidpointDigits = maxDecimalMidpointDigits,
- .dest = dest,
- .start = start,
- .end = end,
- .loc = loc,
- };
+ struct parseInfo info;
+ info.bytes = bytes;
+ info.sigBits = sigBits;
+ info.minBinaryExp = minBinaryExp;
+ info.maxBinaryExp = maxBinaryExp;
+ info.minDecimalExp = minDecimalExp;
+ info.maxDecimalExp = maxDecimalExp;
+ info.maxDecimalMidpointDigits = maxDecimalMidpointDigits;
+ info.dest = dest;
+ info.start = start;
+ info.end = end;
+ info.loc = loc;
// ================================================================
// Parse the input (mostly)
@@ -2870,7 +2713,7 @@
}
#endif
- int roundingMode = FENV_ROUNDING_MODE();
+ int roundingMode = fegetround();
#if 1
// ================================================================
@@ -2880,12 +2723,12 @@
// upper/lower bounds for the correct answer. If those bounds
// agree, then we can return the result.
int16_t exp10;
- unsigned upperBoundOffset;
+ int upperBoundOffset;
if (info.digitCount <= 19) {
- exp10 = (int16_t)info.base10Exponent;
+ exp10 = info.base10Exponent;
upperBoundOffset = 4;
} else {
- exp10 = (int16_t)(info.base10Exponent + info.digitCount - 19);
+ exp10 = info.base10Exponent + info.digitCount - 19;
upperBoundOffset = 36;
}
@@ -2926,13 +2769,10 @@
uint64_t u = l + upperBoundOffset;
uint32_t lowerSignificand, upperSignificand;
switch (roundingMode) {
-#ifdef FE_TOWARDZERO
case FE_TOWARDZERO:
lowerSignificand = (l) >> 40;
upperSignificand = (u) >> 40;
break;
-#endif
-#ifdef FE_DOWNWARD
case FE_DOWNWARD:
if (info.negative) {
lowerSignificand = (l + 0x0ffffffffff) >> 40;
@@ -2942,8 +2782,6 @@
upperSignificand = (l + 4) >> 40;
}
break;
-#endif
-#ifdef FE_UPWARD
case FE_UPWARD:
if (!info.negative) {
lowerSignificand = (l + 0x0ffffffffff) >> 40;
@@ -2953,11 +2791,8 @@
upperSignificand = (u) >> 40;
}
break;
-#endif
-#ifdef FE_TONEAREST
+ default:
case FE_TONEAREST:
-#endif
- default:
// Instead of worrying about exact ties-round-even, round lower
// down (adding 0x7ff...ff) and upper up (adding 0x800...00) so
// that exact ties fall through to be handled elsewhere.
@@ -2977,12 +2812,12 @@
}
// TODO: ... Subnormal? ...
} else if (upperSignificand == lowerSignificand) {
- uint32_t exponentBits = (uint32_t)(binaryExponent - minBinaryExp) << (sigBits - 1);
+ uint32_t exponentBits = ((uint32_t)binaryExponent - minBinaryExp) << (sigBits - 1);
uint32_t significandMask = (((uint32_t)1 << (sigBits - 1)) - 1);
uint32_t significandBits = lowerSignificand & significandMask;
uint32_t signbit = info.negative ? 0x80000000UL : 0ULL;
uint32_t raw = signbit | exponentBits | significandBits;
- memcpy(info.dest, &raw, sizeof(raw));
+ memcpy(dest, &raw, sizeof(raw));
return;
}
#endif
@@ -2990,9 +2825,9 @@
// ================================================================
// Slow Path (varint calculation)
// ================================================================
- char _Alignas(sizeof(mp_word_t)) stackWorkArea[128];
+ char stackWorkArea[128];
static const size_t stackWorkAreaWords = sizeof(stackWorkArea) / sizeof(mp_word_t);
- generalSlowpath(&info, FENV_ROUNDING_MODE(), (mp_word_t *)stackWorkArea, stackWorkAreaWords, false);
+ generalSlowpath(&info, fegetround(), (mp_word_t *)stackWorkArea, stackWorkAreaWords, 0);
}
#endif
@@ -3013,19 +2848,18 @@
static const int minDecimalExp = -325;
static const int maxDecimalExp = 310;
static const int maxDecimalMidpointDigits = 768;
- struct parseInfo info = {
- .bytes = bytes,
- .sigBits = sigBits,
- .minBinaryExp = minBinaryExp,
- .maxBinaryExp = maxBinaryExp,
- .minDecimalExp = minDecimalExp,
- .maxDecimalExp = maxDecimalExp,
- .maxDecimalMidpointDigits = maxDecimalMidpointDigits,
- .dest = dest,
- .start = start,
- .end = end,
- .loc = loc,
- };
+ struct parseInfo info;
+ info.bytes = bytes;
+ info.sigBits = sigBits;
+ info.minBinaryExp = minBinaryExp;
+ info.maxBinaryExp = maxBinaryExp;
+ info.minDecimalExp = minDecimalExp;
+ info.maxDecimalExp = maxDecimalExp;
+ info.maxDecimalMidpointDigits = maxDecimalMidpointDigits;
+ info.dest = dest;
+ info.start = start;
+ info.end = end;
+ info.loc = loc;
// ================================================================
// Parse the input (mostly)
@@ -3086,8 +2920,8 @@
if (info.digitCount <= 19) {
// We can give exact inputs to fma if we have <= 19 digits
// and base10Exponent is in [1..18].
- uint64_t lowMask = 0x7ff;
- uint64_t highMask = ~lowMask;
+ int64_t lowMask = 0x7ff;
+ int64_t highMask = ~lowMask;
// digits has <= 64 bits (19 digits)
double highDigits = (double)(info.digits & highMask); // <= 53 bits
double lowDigits = (double)(info.digits & lowMask); // 11 bits
@@ -3095,7 +2929,7 @@
if (info.negative) p10 = -p10;
double u = lowDigits * p10; // Exact (11 bits + 42 bits)
// Inputs to fma are all exact, so result is correctly rounded
- double result = __builtin_fma(highDigits, p10, u);
+ double result = fma(highDigits, p10, u);
memcpy(info.dest, &result, sizeof(result));
return;
}
@@ -3103,7 +2937,7 @@
}
#endif
- int roundingMode = FENV_ROUNDING_MODE();
+ int roundingMode = fegetround();
#if 1
// ================================================================
@@ -3111,9 +2945,9 @@
// ================================================================
int16_t exp10;
// Total possible inaccuracy in our calculations below
- unsigned intervalWidth;
+ int intervalWidth;
if (info.digitCount <= 19) {
- exp10 = (int16_t)info.base10Exponent;
+ exp10 = info.base10Exponent;
// We have all the digits, so our upper/lower bounds
// on the significand are the same, which makes the final
// bounds fairly tight.
@@ -3126,7 +2960,7 @@
// have upper/lower bounds for 10^p.
// info.digits already has the first 19 digits, we just need to
// adjust the effective exponent.
- exp10 = (int16_t)(info.base10Exponent + info.digitCount - 19);
+ exp10 = info.base10Exponent + info.digitCount - 19;
// The non-trivial significand bounds lead to a wider final interval.
// This still gives us success ~96% of the time.
intervalWidth = 80;
@@ -3185,36 +3019,25 @@
// bits. For example, to precisely round away from zero, we
// would ideally want to add 0x7ff.ffffffffffffffff. Rounding that
// value down/up to the nearest integer gives us 0x7ff, 0x800.
- unsigned lowerRoundOffset, upperRoundOffset;
- {
- bool negative = info.negative;
- switch (roundingMode) {
-#ifdef FE_UPWARD
- case FE_UPWARD:
- negative = !negative;
- // FALL THROUGH
-#endif
-#ifdef FE_DOWNWARD
- case FE_DOWNWARD:
- if (negative) {
- lowerRoundOffset = 0x7ff; upperRoundOffset = 0x800 + intervalWidth;
- break;
- }
- // FALL THROUGH
-#endif
-#ifdef FE_TOWARDZERO
- case FE_TOWARDZERO:
- lowerRoundOffset = 0; upperRoundOffset = intervalWidth;
+ int lowerRoundOffset, upperRoundOffset;
+ int negative = info.negative;
+ switch (roundingMode) {
+ case FE_UPWARD:
+ negative = !negative;
+ // FALL THROUGH
+ case FE_DOWNWARD:
+ if (negative) {
+ lowerRoundOffset = 0x7ff; upperRoundOffset = 0x800 + intervalWidth;
break;
-#endif
-#ifdef FE_TONEAREST
- case FE_TONEAREST:
-#endif
- default:
- (void)negative;
- lowerRoundOffset = 0x3ff; upperRoundOffset = 0x400 + intervalWidth;
- break;
- }
+ }
+ // FALL THROUGH
+ case FE_TOWARDZERO:
+ lowerRoundOffset = 0; upperRoundOffset = intervalWidth;
+ break;
+ default:
+ case FE_TONEAREST:
+ lowerRoundOffset = 0x3ff; upperRoundOffset = 0x400 + intervalWidth;
+ break;
}
uint64_t lowerSignificand = (l + lowerRoundOffset) >> 11;
uint64_t upperSignificand = (l + upperRoundOffset) >> 11;
@@ -3239,29 +3062,20 @@
if (shift < 64) {
assert(0 < shift && shift < 64);
uint64_t lro, uro;
- bool negative = info.negative;
+ int negative = info.negative;
switch (roundingMode) {
-#ifdef FE_UPWARD
case FE_UPWARD:
negative = !negative;
// FALL THROUGH
-#endif
-#ifdef FE_DOWNWARD
case FE_DOWNWARD:
if (negative) {
lro = (1ULL << (shift)) - 1; uro = lro + intervalWidth; break;
}
// FALL THROUGH
-#endif
-#ifdef FE_TOWARDZERO
case FE_TOWARDZERO:
lro = 0; uro = intervalWidth; break;
-#endif
-#ifdef FE_TONEAREST
+ default:
case FE_TONEAREST:
-#endif
- default:
- (void)negative;
lro = (1ULL << (shift - 1)) - 1; uro = (1ULL << (shift - 1)) + intervalWidth; break;
}
lowerSignificand = (l + lro) >> shift;
@@ -3276,18 +3090,18 @@
if (raw != 0x0010000000000000ULL) {
errno = ERANGE;
}
- memcpy(info.dest, &raw, sizeof(raw));
+ memcpy(dest, &raw, sizeof(raw));
return;
}
}
} else if (upperSignificand == lowerSignificand) {
// Normal
- uint64_t exponentBits = (uint64_t)(adjustedBinaryExponent - minBinaryExp) << (sigBits - 1);
+ uint64_t exponentBits = ((uint64_t)adjustedBinaryExponent - minBinaryExp) << (sigBits - 1);
uint64_t significandMask = (((uint64_t)1 << (sigBits - 1)) - 1);
uint64_t significandBits = lowerSignificand & significandMask;
uint64_t signbit = info.negative ? 0x8000000000000000ULL : 0ULL;
uint64_t raw = signbit | exponentBits | significandBits;
- memcpy(info.dest, &raw, sizeof(raw));
+ memcpy(dest, &raw, sizeof(raw));
return;
}
// TODO: If we fall through, should we try refining the
@@ -3300,9 +3114,9 @@
// ================================================================
// Random testing suggests this step only runs about 3% of the
// time, so we focus here on optimizing for code size rather than perf.
- char _Alignas(sizeof(mp_word_t)) stackWorkArea[656];
+ char stackWorkArea[656];
static const size_t stackWorkAreaWords = sizeof(stackWorkArea) / sizeof(mp_word_t);
- generalSlowpath(&info, roundingMode, (mp_word_t *)stackWorkArea, stackWorkAreaWords, false);
+ generalSlowpath(&info, roundingMode, (mp_word_t *)stackWorkArea, stackWorkAreaWords, 0);
}
#endif
@@ -3341,7 +3155,7 @@
#define extractHigh64(x) ((x).high)
#define isZero(x) ((x).low == 0 && (x).high == 0)
#define isEqual(lhs, rhs) ((lhs).low == (rhs).low && ((lhs).high == (rhs).high))
-static my_uint128_t shiftLeft(my_uint128_t lhs, int rhs) {
+my_uint128_t shiftLeft(my_uint128_t lhs, int rhs) {
if (rhs > 64) {
lhs.high = lhs.low << (rhs - 64);
lhs.low = 0;
@@ -3354,7 +3168,7 @@
}
return lhs;
}
-static my_uint128_t shiftRight(my_uint128_t lhs, int rhs) {
+my_uint128_t shiftRight(my_uint128_t lhs, int rhs) {
if (rhs > 64) {
lhs.low = lhs.high >> (rhs - 64);
lhs.high = 0;
@@ -3367,18 +3181,18 @@
}
return lhs;
}
-static my_uint128_t create128FromHighLow64(uint64_t high, uint64_t low) {
+my_uint128_t create128FromHighLow64(uint64_t high, uint64_t low) {
my_uint128_t result = {low, high};
return result;
}
-static my_uint128_t add128x64(my_uint128_t lhs, uint64_t rhs) {
+my_uint128_t add128x64(my_uint128_t lhs, uint64_t rhs) {
if (lhs.low > UINT64_MAX - rhs) {
lhs.high += 1;
}
lhs.low += rhs;
return lhs;
}
-static my_uint128_t add128x128(my_uint128_t lhs, my_uint128_t rhs) {
+my_uint128_t add128x128(my_uint128_t lhs, my_uint128_t rhs) {
if (lhs.low > UINT64_MAX - rhs.low) {
lhs.high += 1;
}
@@ -3386,7 +3200,7 @@
lhs.high += rhs.high;
return lhs;
}
-static my_uint128_t fullMultiply64x64(uint64_t lhs, uint64_t rhs) {
+my_uint128_t fullMultiply64x64(uint64_t lhs, uint64_t rhs) {
uint64_t a = (lhs >> 32) * (rhs >> 32);
uint64_t b = (lhs >> 32) * (rhs & UINT32_MAX);
uint64_t c = (lhs & UINT32_MAX) * (rhs >> 32);
@@ -3395,11 +3209,11 @@
return create128FromHighLow64(a + (b >> 32) + (c >> 32),
(b << 32) + (d & UINT32_MAX));
}
-static my_uint128_t multiply128xInt(my_uint128_t lhs, int rhs) {
- uint64_t a = (lhs.low & UINT32_MAX) * (uint64_t)rhs;
- uint64_t b = (lhs.low >> 32) * (uint64_t)rhs;
+my_uint128_t multiply128xInt(my_uint128_t lhs, int rhs) {
+ uint64_t a = (lhs.low & UINT32_MAX) * rhs;
+ uint64_t b = (lhs.low >> 32) * rhs;
b += (a >> 32);
- lhs.high = (lhs.high * (uint64_t)rhs) + (b >> 32);
+ lhs.high = (lhs.high * rhs) + (b >> 32);
lhs.low = (a & UINT32_MAX) + (b << 32);
return lhs;
}
@@ -3460,12 +3274,12 @@
static int highPrecisionIntervalPath(struct parseInfo *info, int roundingMode) {
int16_t exp10;
- unsigned upperBoundOffset;
+ int upperBoundOffset;
if (info->digitCount <= 38) {
- exp10 = (int16_t)info->base10Exponent;
+ exp10 = info->base10Exponent;
upperBoundOffset = 16; // FIXME
} else {
- exp10 = (int16_t)(info->base10Exponent + info->digitCount - 38);
+ exp10 = info->base10Exponent + info->digitCount - 38;
upperBoundOffset = 272; // FIXME
}
@@ -3483,7 +3297,7 @@
p++;
}
digits = multiply128xInt(digits, 10);
- digits = add128x64(digits, (uint64_t)(*p - '0'));
+ digits = add128x64(digits, *p - '0');
p += 1;
}
if (extractHigh64(digits) != 0) {
@@ -3516,14 +3330,11 @@
// Upper/lower bounds for the 64-bit significand
my_uint128_t u = add128x64(l, upperBoundOffset);
- bool negative = info->negative;
+ int negative = info->negative;
switch (roundingMode) {
-#ifdef FE_DOWNWARD
case FE_DOWNWARD:
negative = !negative;
// FALL THROUGH
-#endif
-#ifdef FE_UPWARD
case FE_UPWARD:
if (!negative) {
my_uint128_t offset = create128FromHighLow64(UINT64_MAX, UINT64_MAX);
@@ -3534,16 +3345,10 @@
break;
}
// FALL THROUGH
-#endif
-#ifdef FE_TOWARDZERO
case FE_TOWARDZERO:
break;
-#endif
-#ifdef FE_TONEAREST
- case FE_TONEAREST:
-#endif
- default: {
- (void)negative;
+ default:
+ case FE_TONEAREST: {
my_uint128_t offset = create128FromHighLow64(UINT64_MAX, UINT64_MAX);
offset = shiftRight(offset, info->sigBits + 1);
l = add128x128(l, offset);
@@ -3571,7 +3376,7 @@
switch (info->bytes) {
case 10: {
uint16_t signbit = info->negative ? 0x8000U : 0U;
- uint16_t exponentBits = signbit | (uint16_t)(binaryExponent - info->minBinaryExp);
+ uint16_t exponentBits = signbit | ((uint16_t)binaryExponent - info->minBinaryExp);
uint64_t significandBits = extractLow64(lowerSignificand);
memcpy(info->dest, &significandBits, sizeof(significandBits));
memcpy(info->dest + 8, &exponentBits, sizeof(exponentBits));
@@ -3579,7 +3384,7 @@
}
case 16: {
uint16_t signbit = info->negative ? 0x8000U : 0U;
- uint16_t exponentBits = signbit | (uint16_t)(binaryExponent - info->minBinaryExp);
+ uint16_t exponentBits = signbit | ((uint16_t)binaryExponent - info->minBinaryExp);
memcpy(info->dest, &lowerSignificand, sizeof(lowerSignificand));
memcpy(info->dest + 14, &exponentBits, sizeof(exponentBits));
return 1;
@@ -3607,19 +3412,18 @@
static const int minDecimalExp = -5000;
static const int maxDecimalExp = 5000;
static const int maxDecimalMidpointDigits = 11515;
- struct parseInfo info = {
- .bytes = bytes,
- .sigBits = sigBits,
- .minBinaryExp = minBinaryExp,
- .maxBinaryExp = maxBinaryExp,
- .minDecimalExp = minDecimalExp,
- .maxDecimalExp = maxDecimalExp,
- .maxDecimalMidpointDigits = maxDecimalMidpointDigits,
- .dest = dest,
- .start = start,
- .end = end,
- .loc = loc,
- };
+ struct parseInfo info;
+ info.bytes = bytes;
+ info.sigBits = sigBits;
+ info.minBinaryExp = minBinaryExp;
+ info.maxBinaryExp = maxBinaryExp;
+ info.minDecimalExp = minDecimalExp;
+ info.maxDecimalExp = maxDecimalExp;
+ info.maxDecimalMidpointDigits = maxDecimalMidpointDigits;
+ info.dest = dest;
+ info.start = start;
+ info.end = end;
+ info.loc = loc;
// ================================================================
// Parse the input (mostly)
@@ -3653,7 +3457,7 @@
}
#endif
- int roundingMode = FENV_ROUNDING_MODE();
+ int roundingMode = fegetround();
#if ENABLE_FLOAT80_OPTIMIZATIONS
if (highPrecisionIntervalPath(&info, roundingMode)) {
@@ -3664,9 +3468,9 @@
// ================================================================
// Slow Path (varint calculation)
// ================================================================
- char _Alignas(sizeof(mp_word_t)) stackWorkArea[1536];
+ char stackWorkArea[1536];
static const size_t stackWorkAreaWords = sizeof(stackWorkArea) / sizeof(mp_word_t);
- generalSlowpath(&info, roundingMode, (mp_word_t *)stackWorkArea, stackWorkAreaWords, true);
+ generalSlowpath(&info, roundingMode, (mp_word_t *)stackWorkArea, stackWorkAreaWords, 1);
}
#endif
@@ -3687,19 +3491,18 @@
static const int minDecimalExp = -5000;
static const int maxDecimalExp = 5000;
static const int maxDecimalMidpointDigits = 11564;
- struct parseInfo info = {
- .bytes = bytes,
- .sigBits = sigBits,
- .minBinaryExp = minBinaryExp,
- .maxBinaryExp = maxBinaryExp,
- .minDecimalExp = minDecimalExp,
- .maxDecimalExp = maxDecimalExp,
- .maxDecimalMidpointDigits = maxDecimalMidpointDigits,
- .dest = dest,
- .start = start,
- .end = end,
- .loc = loc,
- };
+ struct parseInfo info;
+ info.bytes = bytes;
+ info.sigBits = sigBits;
+ info.minBinaryExp = minBinaryExp;
+ info.maxBinaryExp = maxBinaryExp;
+ info.minDecimalExp = minDecimalExp;
+ info.maxDecimalExp = maxDecimalExp;
+ info.maxDecimalMidpointDigits = maxDecimalMidpointDigits;
+ info.dest = dest;
+ info.start = start;
+ info.end = end;
+ info.loc = loc;
// ================================================================
// Parse the input (mostly)
@@ -3735,7 +3538,7 @@
}
#endif
- int roundingMode = FENV_ROUNDING_MODE();
+ int roundingMode = fegetround();
#if ENABLE_BINARY128_OPTIMIZATIONS
if (highPrecisionIntervalPath(&info, roundingMode)) {
@@ -3746,9 +3549,9 @@
// ================================================================
// Slow Path (varint calculation)
// ================================================================
- char _Alignas(sizeof(mp_word_t)) stackWorkArea[1536];
+ char stackWorkArea[1536];
static const size_t stackWorkAreaWords = sizeof(stackWorkArea) / sizeof(mp_word_t);
- generalSlowpath(&info, roundingMode, (mp_word_t *)stackWorkArea, stackWorkAreaWords, true);
+ generalSlowpath(&info, roundingMode, (mp_word_t *)stackWorkArea, stackWorkAreaWords, 1);
}
#endif
@@ -3772,7 +3575,7 @@
void strtoencf16(unsigned char * restrict encptr,
const char * restrict nptr,
char ** restrict endptr) {
- _ffpp_strtoencf16_l(encptr, nptr, endptr, strtofp_current_locale());
+ _ffpp_strtoencf16_l(encptr, nptr, endptr, strtofp_current_locale());
}
#endif
@@ -3826,7 +3629,7 @@
#if ENABLE_BINARY64_SUPPORT && LONG_DOUBLE_IS_BINARY64
// TS 18661-3 `strtoencf64x` API
// If `long double` is binary64, we assume Float64x is binary64
-void strtoencf64x(unsigned char * restrict encptr,
+void strtoencf64x(unsigned char *restrict encptr,
const char * restrict nptr,
char ** restrict endptr) {
_ffpp_strtoencf64_l(encptr, nptr, endptr, strtofp_current_locale());
@@ -3880,7 +3683,7 @@
#if ENABLE_FLOAT80_SUPPORT && ENABLE_LOCALE_SUPPORT
// Non-standard but helpful for testing.
-void strtoencf80_l(unsigned char * restrict encptr,
+void strtoencf80_l(unsigned char *restrict encptr,
const char * restrict nptr,
char ** restrict endptr,
strtofp_locale_t loc) {
@@ -3891,7 +3694,7 @@
#if ENABLE_FLOAT80_SUPPORT && LONG_DOUBLE_IS_FLOAT80
// TS 18661-3 `strtoencf64x` API
// If `long double` is float80, assume `Float64x` is float80
-void strtoencf64x(unsigned char * restrict encptr,
+void strtoencf64x(unsigned char *restrict encptr,
const char * restrict nptr,
char ** restrict endptr) {
_ffpp_strtoencf80_l(encptr, nptr, endptr, strtofp_current_locale());