Disable simd-related warnings

This commit is contained in:
Maya Warrier 2023-04-01 04:09:00 -04:00
parent 20f3870361
commit f59f73c4da
3 changed files with 31 additions and 18 deletions

View File

@ -9,8 +9,6 @@
#include "float_common.h" #include "float_common.h"
#define FASTFLOAT_SSE2 1
#if FASTFLOAT_SSE2 #if FASTFLOAT_SSE2
#include <emmintrin.h> #include <emmintrin.h>
#endif #endif
@ -44,25 +42,26 @@ uint64_t fast_read_u64(const char* chars)
return val; return val;
} }
// https://quick-bench.com/q/fk6Y07KDGu8XZ9iUtQD8QJTc3Hg
fastfloat_really_inline fastfloat_really_inline
uint64_t fast_read_u64(const char16_t* chars) uint64_t fast_read_u64(const char16_t* chars)
{ {
#if FASTFLOAT_SSE2 #if FASTFLOAT_SSE2
const unsigned char* const p = reinterpret_cast<const unsigned char *>(chars); FASTFLOAT_SIMD_DISABLE_WARNINGS
static const char16_t masks[] = {0xff, 0xff, 0xff, 0xff}; static const char16_t masks[] = {0xff, 0xff, 0xff, 0xff};
const __m128i m_masks = _mm_loadu_si128(reinterpret_cast<const __m128i*>(masks)); const __m128i m_masks = _mm_loadu_si128(reinterpret_cast<const __m128i*>(masks));
// mask hi bytes
// mask hi bytes and pack
const char* const p = reinterpret_cast<const char*>(chars);
__m128i i1 = _mm_and_si128(_mm_loadu_si64(p), m_masks); __m128i i1 = _mm_and_si128(_mm_loadu_si64(p), m_masks);
__m128i i2 = _mm_and_si128(_mm_loadu_si64(p + 8), m_masks); __m128i i2 = _mm_and_si128(_mm_loadu_si64(p + 8), m_masks);
// pack into chars
__m128i packed = _mm_packus_epi16(i1, i2); __m128i packed = _mm_packus_epi16(i1, i2);
// extract // extract
uint64_t val; uint64_t val;
_mm_storeu_si64(&val, _mm_shuffle_epi32(packed, 0x8)); _mm_storeu_si64(&val, _mm_shuffle_epi32(packed, 0x8));
return val; return val;
FASTFLOAT_SIMD_RESTORE_WARNINGS
#else #else
alignas(8) unsigned char bytes[8]; alignas(8) unsigned char bytes[8];
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
@ -143,7 +142,7 @@ bool is_made_of_eight_digits_fast(const CharT *chars) noexcept {
typedef span<const char> byte_span; typedef span<const char> byte_span;
template <typename CharT = char> template <typename CharT>
struct parsed_number_string { struct parsed_number_string {
int64_t exponent{0}; int64_t exponent{0};
uint64_t mantissa{0}; uint64_t mantissa{0};
@ -161,10 +160,9 @@ struct parsed_number_string {
// parse an ASCII string. // parse an ASCII string.
template <typename CharT> template <typename CharT>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 fastfloat_really_inline FASTFLOAT_CONSTEXPR20
parsed_number_string<CharT> parse_number_string(const CharT *p, const CharT *pend, parse_options options) noexcept { parsed_number_string<CharT> parse_number_string(const CharT *p, const CharT *pend, parse_options options, const bool parse_ints = false) noexcept {
const chars_format fmt = options.format; const chars_format fmt = options.format;
const parse_rules rules = options.rules; const parse_rules rules = options.rules;
const bool parse_ints = options.parse_ints;
const CharT decimal_point = static_cast<CharT>(options.decimal_point); const CharT decimal_point = static_cast<CharT>(options.decimal_point);
parsed_number_string<CharT> answer; parsed_number_string<CharT> answer;
@ -279,9 +277,9 @@ parsed_number_string<CharT> parse_number_string(const CharT *p, const CharT *pen
start++; start++;
} }
constexpr uint64_t minimal_twenty_digit_integer{10000000000000000000ULL}; constexpr uint64_t minimal_twenty_digit_integer{10000000000000000000ULL};
// maya: A 64-bit number may have up to 20 digits, not 19! // maya: A 64-bit number may have up to 20 digits!
// If we're parsing ints, preserve accuracy up to 20 digits instead // If we're parsing ints, preserve accuracy up to 20 digits
// of converting them to the closest floating point value. // instead of rounding them to a floating point value.
answer.too_many_digits = rules == parse_rules::json_rules && parse_ints && answer.is_64bit_int ? answer.too_many_digits = rules == parse_rules::json_rules && parse_ints && answer.is_64bit_int ?
(digit_count > 20 || i < minimal_twenty_digit_integer) : digit_count > 19; (digit_count > 20 || i < minimal_twenty_digit_integer) : digit_count > 19;

View File

@ -27,16 +27,13 @@ struct from_chars_result {
struct parse_options { struct parse_options {
constexpr explicit parse_options( constexpr explicit parse_options(
chars_format fmt = chars_format::general, chars_format fmt = chars_format::general,
parse_rules rules = parse_rules::std_rules, parse_rules rules = parse_rules::std_rules, char dot = '.')
bool parse_ints = false, char dot = '.') : format(fmt), rules(rules), decimal_point(dot) {}
: format(fmt), rules(rules), parse_ints(parse_ints), decimal_point(dot) {}
/** Which number formats are accepted */ /** Which number formats are accepted */
chars_format format; chars_format format;
/** Which parsing rules to use */ /** Which parsing rules to use */
parse_rules rules; parse_rules rules;
/* Whether to parse integers too, only applicable with json_rules */
bool parse_ints;
/** The character used as decimal point */ /** The character used as decimal point */
char decimal_point; char decimal_point;
}; };

View File

@ -78,6 +78,24 @@
#endif #endif
#endif #endif
#if defined(__GNUC__)
#define FASTFLOAT_SIMD_DISABLE_WARNINGS \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wcast-align=strict\"")
#else
#define FASTFLOAT_SIMD_DISABLE_WARNINGS
#endif
#if defined(__GNUC__)
#define FASTFLOAT_SIMD_RESTORE_WARNINGS \
_Pragma("GCC diagnostic pop")
#else
#define FASTFLOAT_SIMD_RESTORE_WARNINGS
#endif
#ifdef FASTFLOAT_VISUAL_STUDIO #ifdef FASTFLOAT_VISUAL_STUDIO
#define fastfloat_really_inline __forceinline #define fastfloat_really_inline __forceinline
#else #else