Merge pull request #991 from knapply/master

Permit 32-bit GCC compilation
This commit is contained in:
Daniel Lemire 2020-06-26 09:50:18 -04:00 committed by GitHub
commit 74178fd1c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 76 additions and 39 deletions

View File

@ -83,13 +83,13 @@ really_inline T tape_ref::next_tape_value() const noexcept {
really_inline uint32_t internal::tape_ref::get_string_length() const noexcept { really_inline uint32_t internal::tape_ref::get_string_length() const noexcept {
uint64_t string_buf_index = size_t(tape_value()); uint64_t string_buf_index = size_t(tape_value());
uint32_t len; uint32_t len;
memcpy(&len, &doc->string_buf[string_buf_index], sizeof(len)); memcpy(&len, &doc->string_buf[size_t(string_buf_index)], sizeof(len));
return len; return len;
} }
really_inline const char * internal::tape_ref::get_c_str() const noexcept { really_inline const char * internal::tape_ref::get_c_str() const noexcept {
uint64_t string_buf_index = size_t(tape_value()); uint64_t string_buf_index = size_t(tape_value());
return reinterpret_cast<const char *>(&doc->string_buf[string_buf_index + sizeof(uint32_t)]); return reinterpret_cast<const char *>(&doc->string_buf[size_t(string_buf_index) + sizeof(uint32_t)]);
} }
inline std::string_view internal::tape_ref::get_string_view() const noexcept { inline std::string_view internal::tape_ref::get_string_view() const noexcept {

View File

@ -37,13 +37,14 @@
#if defined(__x86_64__) || defined(_M_AMD64) #if defined(__x86_64__) || defined(_M_AMD64)
#define SIMDJSON_IS_X86_64 1 #define SIMDJSON_IS_X86_64 1
#endif #elif defined(__aarch64__) || defined(_M_ARM64)
#if defined(__aarch64__) || defined(_M_ARM64)
#define SIMDJSON_IS_ARM64 1 #define SIMDJSON_IS_ARM64 1
#else
#define SIMDJSON_IS_32BITS 1
#endif #endif
#if (!defined(SIMDJSON_IS_X86_64)) && (!defined(SIMDJSON_IS_ARM64)) #ifdef SIMDJSON_IS_32BITS
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO #if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(__GNUC__)
#pragma message("The simdjson library is designed\ #pragma message("The simdjson library is designed\
for 64-bit processors and it seems that you are not \ for 64-bit processors and it seems that you are not \
compiling for a known 64-bit platform. All fast kernels \ compiling for a known 64-bit platform. All fast kernels \
@ -54,7 +55,7 @@ use a 64-bit target such as x64 or 64-bit ARM.")
for 64-bit processors. It seems that you are not \ for 64-bit processors. It seems that you are not \
compiling for a known 64-bit platform." compiling for a known 64-bit platform."
#endif #endif
#endif // (!defined(SIMDJSON_IS_X86_64)) && (!defined(SIMDJSON_IS_ARM64)) #endif // SIMDJSON_IS_32BITS
// this is almost standard? // this is almost standard?
#undef STRINGIFY_IMPLEMENTATION_ #undef STRINGIFY_IMPLEMENTATION_

View File

@ -1,4 +1,4 @@
/* auto-generated on Tue 23 Jun 2020 20:51:12 EDT. Do not edit! */ /* auto-generated on Fri Jun 26 01:04:15 UTC 2020. Do not edit! */
#include <iostream> #include <iostream>
#include "simdjson.h" #include "simdjson.h"
@ -43,3 +43,4 @@ int main(int argc, char *argv[]) {
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -1,4 +1,4 @@
/* auto-generated on Tue 23 Jun 2020 20:51:12 EDT. Do not edit! */ /* auto-generated on Fri Jun 26 01:04:15 UTC 2020. Do not edit! */
/* begin file src/simdjson.cpp */ /* begin file src/simdjson.cpp */
#include "simdjson.h" #include "simdjson.h"
@ -934,9 +934,8 @@ struct value128 {
uint64_t high; uint64_t high;
}; };
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) && \ #ifdef SIMDJSON_IS_32BITS // _umul128 for x86, arm
!defined(_M_X64) && !defined(_M_ARM64)// _umul128 for x86, arm // this is a slow emulation routine for 32-bit
// this is a slow emulation routine for 32-bit Windows
// //
static inline uint64_t __emulu(uint32_t x, uint32_t y) { static inline uint64_t __emulu(uint32_t x, uint32_t y) {
return x * (uint64_t)y; return x * (uint64_t)y;
@ -955,7 +954,7 @@ static inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
really_inline value128 full_multiplication(uint64_t value1, uint64_t value2) { really_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
value128 answer; value128 answer;
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO #if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#ifdef _M_ARM64 #ifdef _M_ARM64
// ARM64 has native support for 64-bit multiplications, no need to emultate // ARM64 has native support for 64-bit multiplications, no need to emultate
answer.high = __umulh(value1, value2); answer.high = __umulh(value1, value2);
@ -963,7 +962,7 @@ really_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
#else #else
answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
#endif // _M_ARM64 #endif // _M_ARM64
#else // SIMDJSON_REGULAR_VISUAL_STUDIO #else // defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
__uint128_t r = ((__uint128_t)value1) * value2; __uint128_t r = ((__uint128_t)value1) * value2;
answer.low = uint64_t(r); answer.low = uint64_t(r);
answer.high = uint64_t(r >> 64); answer.high = uint64_t(r >> 64);
@ -7826,7 +7825,7 @@ really_inline bool add_overflow(uint64_t value1, uint64_t value2,
#endif #endif
} }
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO #if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#pragma intrinsic(_umul128) #pragma intrinsic(_umul128)
#endif #endif
really_inline bool mul_overflow(uint64_t value1, uint64_t value2, really_inline bool mul_overflow(uint64_t value1, uint64_t value2,
@ -11114,7 +11113,7 @@ really_inline bool add_overflow(uint64_t value1, uint64_t value2,
#endif #endif
} }
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO #if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#pragma intrinsic(_umul128) #pragma intrinsic(_umul128)
#endif #endif
really_inline bool mul_overflow(uint64_t value1, uint64_t value2, really_inline bool mul_overflow(uint64_t value1, uint64_t value2,

View File

@ -1,4 +1,4 @@
/* auto-generated on Tue 23 Jun 2020 20:51:12 EDT. Do not edit! */ /* auto-generated on Fri Jun 26 01:04:15 UTC 2020. Do not edit! */
/* begin file include/simdjson.h */ /* begin file include/simdjson.h */
#ifndef SIMDJSON_H #ifndef SIMDJSON_H
#define SIMDJSON_H #define SIMDJSON_H
@ -91,13 +91,14 @@
#if defined(__x86_64__) || defined(_M_AMD64) #if defined(__x86_64__) || defined(_M_AMD64)
#define SIMDJSON_IS_X86_64 1 #define SIMDJSON_IS_X86_64 1
#endif #elif defined(__aarch64__) || defined(_M_ARM64)
#if defined(__aarch64__) || defined(_M_ARM64)
#define SIMDJSON_IS_ARM64 1 #define SIMDJSON_IS_ARM64 1
#else
#define SIMDJSON_IS_32BITS 1
#endif #endif
#if (!defined(SIMDJSON_IS_X86_64)) && (!defined(SIMDJSON_IS_ARM64)) #ifdef SIMDJSON_IS_32BITS
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO #if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(__GNUC__)
#pragma message("The simdjson library is designed\ #pragma message("The simdjson library is designed\
for 64-bit processors and it seems that you are not \ for 64-bit processors and it seems that you are not \
compiling for a known 64-bit platform. All fast kernels \ compiling for a known 64-bit platform. All fast kernels \
@ -108,7 +109,7 @@ use a 64-bit target such as x64 or 64-bit ARM.")
for 64-bit processors. It seems that you are not \ for 64-bit processors. It seems that you are not \
compiling for a known 64-bit platform." compiling for a known 64-bit platform."
#endif #endif
#endif // (!defined(SIMDJSON_IS_X86_64)) && (!defined(SIMDJSON_IS_ARM64)) #endif // SIMDJSON_IS_32BITS
// this is almost standard? // this is almost standard?
#undef STRINGIFY_IMPLEMENTATION_ #undef STRINGIFY_IMPLEMENTATION_
@ -2632,7 +2633,6 @@ inline error_code dom_parser_implementation::allocate(size_t capacity, size_t ma
#endif // SIMDJSON_INTERNAL_DOM_PARSER_IMPLEMENTATION_H #endif // SIMDJSON_INTERNAL_DOM_PARSER_IMPLEMENTATION_H
/* end file include/simdjson/internal/dom_parser_implementation.h */ /* end file include/simdjson/internal/dom_parser_implementation.h */
#include <optional>
#include <string> #include <string>
#include <atomic> #include <atomic>
#include <vector> #include <vector>
@ -4008,21 +4008,42 @@ public:
*/ */
inline simdjson_result<object> get_object() const noexcept; inline simdjson_result<object> get_object() const noexcept;
/** /**
* Cast this element to a string. * Cast this element to a null-terminated C string.
*
* The string is guaranteed to be valid UTF-8.
* *
* Equivalent to get<const char *>(). * The get_c_str() function is equivalent to get<const char *>().
*
* The length of the string is given by get_string_length(). Because JSON strings
* may contain null characters, it may be incorrect to use strlen to determine the
* string length.
* *
* @returns An pointer to a null-terminated string. This string is stored in the parser and will * It is possible to get a single string_view instance which represents both the string
* content and its length: see get_string().
*
* @returns A pointer to a null-terminated UTF-8 string. This string is stored in the parser and will
* be invalidated the next time it parses a document or when it is destroyed. * be invalidated the next time it parses a document or when it is destroyed.
* Returns INCORRECT_TYPE if the JSON element is not a string. * Returns INCORRECT_TYPE if the JSON element is not a string.
*/ */
inline simdjson_result<const char *> get_c_str() const noexcept; inline simdjson_result<const char *> get_c_str() const noexcept;
/** /**
* Cast this element to a string. * Gives the length in bytes of the string.
*
* It is possible to get a single string_view instance which represents both the string
* content and its length: see get_string().
*
* @returns A string length in bytes.
* Returns INCORRECT_TYPE if the JSON element is not a string.
*/
inline simdjson_result<size_t> get_string_length() const noexcept;
/**
* Cast this element to a string.
*
* The string is guaranteed to be valid UTF-8.
* *
* Equivalent to get<std::string_view>(). * Equivalent to get<std::string_view>().
* *
* @returns A string. The string is stored in the parser and will be invalidated the next time it * @returns An UTF-8 string. The string is stored in the parser and will be invalidated the next time it
* parses a document or when it is destroyed. * parses a document or when it is destroyed.
* Returns INCORRECT_TYPE if the JSON element is not a string. * Returns INCORRECT_TYPE if the JSON element is not a string.
*/ */
@ -4199,7 +4220,9 @@ public:
inline operator bool() const noexcept(false); inline operator bool() const noexcept(false);
/** /**
* Read this element as a null-terminated string. * Read this element as a null-terminated UTF-8 string.
*
* Be mindful that JSON allows strings to contain null characters.
* *
* Does *not* convert other types to a string; requires that the JSON type of the element was * Does *not* convert other types to a string; requires that the JSON type of the element was
* an actual string. * an actual string.
@ -4210,7 +4233,7 @@ public:
inline explicit operator const char*() const noexcept(false); inline explicit operator const char*() const noexcept(false);
/** /**
* Read this element as a null-terminated string. * Read this element as a null-terminated UTF-8 string.
* *
* Does *not* convert other types to a string; requires that the JSON type of the element was * Does *not* convert other types to a string; requires that the JSON type of the element was
* an actual string. * an actual string.
@ -4410,6 +4433,7 @@ public:
really_inline simdjson_result<dom::array> get_array() const noexcept; really_inline simdjson_result<dom::array> get_array() const noexcept;
really_inline simdjson_result<dom::object> get_object() const noexcept; really_inline simdjson_result<dom::object> get_object() const noexcept;
really_inline simdjson_result<const char *> get_c_str() const noexcept; really_inline simdjson_result<const char *> get_c_str() const noexcept;
really_inline simdjson_result<size_t> get_string_length() const noexcept;
really_inline simdjson_result<std::string_view> get_string() const noexcept; really_inline simdjson_result<std::string_view> get_string() const noexcept;
really_inline simdjson_result<int64_t> get_int64() const noexcept; really_inline simdjson_result<int64_t> get_int64() const noexcept;
really_inline simdjson_result<uint64_t> get_uint64() const noexcept; really_inline simdjson_result<uint64_t> get_uint64() const noexcept;
@ -5820,6 +5844,10 @@ really_inline simdjson_result<const char *> simdjson_result<dom::element>::get_c
if (error()) { return error(); } if (error()) { return error(); }
return first.get_c_str(); return first.get_c_str();
} }
really_inline simdjson_result<size_t> simdjson_result<dom::element>::get_string_length() const noexcept {
if (error()) { return error(); }
return first.get_string_length();
}
really_inline simdjson_result<std::string_view> simdjson_result<dom::element>::get_string() const noexcept { really_inline simdjson_result<std::string_view> simdjson_result<dom::element>::get_string() const noexcept {
if (error()) { return error(); } if (error()) { return error(); }
return first.get_string(); return first.get_string();
@ -5960,6 +5988,15 @@ inline simdjson_result<const char *> element::get_c_str() const noexcept {
return INCORRECT_TYPE; return INCORRECT_TYPE;
} }
} }
inline simdjson_result<size_t> element::get_string_length() const noexcept {
switch (tape.tape_ref_type()) {
case internal::tape_type::STRING: {
return tape.get_string_length();
}
default:
return INCORRECT_TYPE;
}
}
inline simdjson_result<std::string_view> element::get_string() const noexcept { inline simdjson_result<std::string_view> element::get_string() const noexcept {
switch (tape.tape_ref_type()) { switch (tape.tape_ref_type()) {
case internal::tape_type::STRING: case internal::tape_type::STRING:
@ -7612,13 +7649,13 @@ really_inline T tape_ref::next_tape_value() const noexcept {
really_inline uint32_t internal::tape_ref::get_string_length() const noexcept { really_inline uint32_t internal::tape_ref::get_string_length() const noexcept {
uint64_t string_buf_index = size_t(tape_value()); uint64_t string_buf_index = size_t(tape_value());
uint32_t len; uint32_t len;
memcpy(&len, &doc->string_buf[string_buf_index], sizeof(len)); memcpy(&len, &doc->string_buf[size_t(string_buf_index)], sizeof(len));
return len; return len;
} }
really_inline const char * internal::tape_ref::get_c_str() const noexcept { really_inline const char * internal::tape_ref::get_c_str() const noexcept {
uint64_t string_buf_index = size_t(tape_value()); uint64_t string_buf_index = size_t(tape_value());
return reinterpret_cast<const char *>(&doc->string_buf[string_buf_index + sizeof(uint32_t)]); return reinterpret_cast<const char *>(&doc->string_buf[size_t(string_buf_index) + sizeof(uint32_t)]);
} }
inline std::string_view internal::tape_ref::get_string_view() const noexcept { inline std::string_view internal::tape_ref::get_string_view() const noexcept {

View File

@ -58,7 +58,7 @@ really_inline bool add_overflow(uint64_t value1, uint64_t value2,
#endif #endif
} }
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO #if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#pragma intrinsic(_umul128) #pragma intrinsic(_umul128)
#endif #endif
really_inline bool mul_overflow(uint64_t value1, uint64_t value2, really_inline bool mul_overflow(uint64_t value1, uint64_t value2,

View File

@ -317,9 +317,8 @@ struct value128 {
uint64_t high; uint64_t high;
}; };
#if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) && \ #ifdef SIMDJSON_IS_32BITS // _umul128 for x86, arm
!defined(_M_X64) && !defined(_M_ARM64)// _umul128 for x86, arm // this is a slow emulation routine for 32-bit
// this is a slow emulation routine for 32-bit Windows
// //
static inline uint64_t __emulu(uint32_t x, uint32_t y) { static inline uint64_t __emulu(uint32_t x, uint32_t y) {
return x * (uint64_t)y; return x * (uint64_t)y;
@ -338,7 +337,7 @@ static inline uint64_t _umul128(uint64_t ab, uint64_t cd, uint64_t *hi) {
really_inline value128 full_multiplication(uint64_t value1, uint64_t value2) { really_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
value128 answer; value128 answer;
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO #if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#ifdef _M_ARM64 #ifdef _M_ARM64
// ARM64 has native support for 64-bit multiplications, no need to emultate // ARM64 has native support for 64-bit multiplications, no need to emultate
answer.high = __umulh(value1, value2); answer.high = __umulh(value1, value2);
@ -346,7 +345,7 @@ really_inline value128 full_multiplication(uint64_t value1, uint64_t value2) {
#else #else
answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64 answer.low = _umul128(value1, value2, &answer.high); // _umul128 not available on ARM64
#endif // _M_ARM64 #endif // _M_ARM64
#else // SIMDJSON_REGULAR_VISUAL_STUDIO #else // defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
__uint128_t r = ((__uint128_t)value1) * value2; __uint128_t r = ((__uint128_t)value1) * value2;
answer.low = uint64_t(r); answer.low = uint64_t(r);
answer.high = uint64_t(r >> 64); answer.high = uint64_t(r >> 64);

View File

@ -66,7 +66,7 @@ really_inline bool add_overflow(uint64_t value1, uint64_t value2,
#endif #endif
} }
#ifdef SIMDJSON_REGULAR_VISUAL_STUDIO #if defined(SIMDJSON_REGULAR_VISUAL_STUDIO) || defined(SIMDJSON_IS_32BITS)
#pragma intrinsic(_umul128) #pragma intrinsic(_umul128)
#endif #endif
really_inline bool mul_overflow(uint64_t value1, uint64_t value2, really_inline bool mul_overflow(uint64_t value1, uint64_t value2,