diff --git a/.cmake.conf b/.cmake.conf index 293fdc9e681..78517d03cb0 100644 --- a/.cmake.conf +++ b/.cmake.conf @@ -1,4 +1,4 @@ -set(QT_REPO_MODULE_VERSION "6.2.11") +set(QT_REPO_MODULE_VERSION "6.2.12") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "") # Minimum requirement for building Qt diff --git a/.qmake.conf b/.qmake.conf index f5796cae5c5..9996ed34a55 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -6,4 +6,4 @@ DEFINES += QT_NO_JAVA_STYLE_ITERATORS QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) -MODULE_VERSION = 6.2.11 +MODULE_VERSION = 6.2.12 diff --git a/cmake/QtPostProcessHelpers.cmake b/cmake/QtPostProcessHelpers.cmake index 36969fbe213..7a1b914135a 100644 --- a/cmake/QtPostProcessHelpers.cmake +++ b/cmake/QtPostProcessHelpers.cmake @@ -448,8 +448,8 @@ if (__qt_qml_plugins_config_file_list AND NOT QT_SKIP_AUTO_QML_PLUGIN_INCLUSION) endif()") endif() - get_target_property(qt_plugins "${QT_MODULE}" QT_PLUGINS) - if(qt_plugins OR QT_MODULE_PLUGIN_INCLUDES) + get_target_property(module_plugin_types "${QT_MODULE}" MODULE_PLUGIN_TYPES) + if(module_plugin_types OR QT_MODULE_PLUGIN_INCLUDES) list(APPEND modules_with_plugins "${QT_MODULE}") configure_file( "${QT_CMAKE_DIR}/QtPlugins.cmake.in" diff --git a/cmake/QtPublicWalkLibsHelpers.cmake b/cmake/QtPublicWalkLibsHelpers.cmake index 85f09b7679e..1b4bd566851 100644 --- a/cmake/QtPublicWalkLibsHelpers.cmake +++ b/cmake/QtPublicWalkLibsHelpers.cmake @@ -186,7 +186,7 @@ function(__qt_internal_walk_libs # namespace. Which one is preferred doesn't really matter. This code exists to # avoid ending up with both, Qt::Foo and Foo in our dependencies. set(namespaceless_lib_target "${CMAKE_MATCH_1}") - if(TARGET namespaceless_lib_target) + if(TARGET "${namespaceless_lib_target}") set(lib_target ${namespaceless_lib_target}) endif() endif() diff --git a/examples/opengl/contextinfo/widget.cpp b/examples/opengl/contextinfo/widget.cpp index df1e6a6f7b9..64b2254b85d 100644 --- a/examples/opengl/contextinfo/widget.cpp +++ b/examples/opengl/contextinfo/widget.cpp @@ -126,7 +126,9 @@ struct Renderable { static struct Renderable renderables[] = { { "default", QSurfaceFormat::DefaultRenderableType }, +#ifndef Q_OS_ANDROID { "OpenGL", QSurfaceFormat::OpenGL }, +#endif { "OpenGL ES", QSurfaceFormat::OpenGLES } }; diff --git a/src/3rdparty/libjpeg/CMakeLists.txt b/src/3rdparty/libjpeg/CMakeLists.txt index e2ac21ca79e..88d0afd9a82 100644 --- a/src/3rdparty/libjpeg/CMakeLists.txt +++ b/src/3rdparty/libjpeg/CMakeLists.txt @@ -61,7 +61,8 @@ set(JPEG_SOURCES src/jerror.c src/jfdctflt.c src/jmemmgr.c - src/jmemnobs.c) + src/jmemnobs.c + src/jpeg_nbits.c) qt_internal_add_3rdparty_library(BundledLibjpeg16bits STATIC diff --git a/src/3rdparty/libjpeg/COPYRIGHT.txt b/src/3rdparty/libjpeg/COPYRIGHT.txt index 5b6ff32c691..ce9d95bfebc 100644 --- a/src/3rdparty/libjpeg/COPYRIGHT.txt +++ b/src/3rdparty/libjpeg/COPYRIGHT.txt @@ -1,4 +1,4 @@ -Copyright (C) 2009-2023 D. R. Commander +Copyright (C) 2009-2024 D. R. Commander Copyright (C) 2015, 2020 Google, Inc. Copyright (C) 2019-2020 Arm Limited Copyright (C) 2015-2016, 2018 Matthieu Darbois diff --git a/src/3rdparty/libjpeg/import_from_libjpeg_tarball.sh b/src/3rdparty/libjpeg/import_from_libjpeg_tarball.sh index de3f3091ea7..fe8b41275fb 100755 --- a/src/3rdparty/libjpeg/import_from_libjpeg_tarball.sh +++ b/src/3rdparty/libjpeg/import_from_libjpeg_tarball.sh @@ -160,7 +160,7 @@ FILES=" jmemnobs.c jmemsys.h jmorecfg.h - jpeg_nbits_table.h + jpeg_nbits.h jquant1.c jquant2.c jsamplecomp.h diff --git a/src/3rdparty/libjpeg/qt_attribution.json b/src/3rdparty/libjpeg/qt_attribution.json index c925f7c9ba9..8d5776a6a45 100644 --- a/src/3rdparty/libjpeg/qt_attribution.json +++ b/src/3rdparty/libjpeg/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "The Independent JPEG Group's JPEG software", "Homepage": "http://libjpeg-turbo.virtualgl.org/", - "Version": "3.0.1", - "DownloadLocation": "https://sourceforge.net/projects/libjpeg-turbo/files/3.0.1/libjpeg-turbo-3.0.1.tar.gz", + "Version": "3.0.2", + "DownloadLocation": "https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/3.0.2/libjpeg-turbo-3.0.2.tar.gz", "License": "Independent JPEG Group License and BSD 3-Clause \"New\" or \"Revised\" License and zlib License", "LicenseId": "IJG AND BSD-3-Clause AND Zlib", "LicenseFiles": [ "LICENSE", "ijg-license.txt", "zlib-license.txt"], diff --git a/src/3rdparty/libjpeg/src/ChangeLog.md b/src/3rdparty/libjpeg/src/ChangeLog.md index a4667851333..a929b62a8cd 100644 --- a/src/3rdparty/libjpeg/src/ChangeLog.md +++ b/src/3rdparty/libjpeg/src/ChangeLog.md @@ -1,3 +1,38 @@ +3.0.2 +===== + +### Significant changes relative to 3.0.1: + +1. Fixed a signed integer overflow in the `tj3CompressFromYUV8()`, +`tj3DecodeYUV8()`, `tj3DecompressToYUV8()`, and `tj3EncodeYUV8()` functions, +detected by the Clang and GCC undefined behavior sanitizers, that could be +triggered by setting the `align` parameter to an unreasonably large value. +This issue did not pose a security threat, but removing the warning made it +easier to detect actual security issues, should they arise in the future. + +2. Introduced a new parameter (`TJPARAM_MAXMEMORY` in the TurboJPEG C API and +`TJ.PARAM_MAXMEMORY` in the TurboJPEG Java API) and a corresponding TJBench +option (`-maxmemory`) for specifying the maximum amount of memory (in +megabytes) that will be allocated for intermediate buffers, which are used with +progressive JPEG compression and decompression, optimized baseline entropy +coding, lossless JPEG compression, and lossless transformation. The new +parameter and option serve the same purpose as the `max_memory_to_use` field in +the `jpeg_memory_mgr` struct in the libjpeg API, the `JPEGMEM` environment +variable, and the cjpeg/djpeg/jpegtran `-maxmemory` option. + +3. Introduced a new parameter (`TJPARAM_MAXPIXELS` in the TurboJPEG C API and +`TJ.PARAM_MAXPIXELS` in the TurboJPEG Java API) and a corresponding TJBench +option (`-maxpixels`) for specifying the maximum number of pixels that the +decompression, lossless transformation, and packed-pixel image loading +functions/methods will process. + +4. Fixed an error ("Unsupported color conversion request") that occurred when +attempting to decompress a 3-component lossless JPEG image without an Adobe +APP14 marker. The decompressor now assumes that a 3-component lossless JPEG +image without an Adobe APP14 marker uses the RGB colorspace if its component +IDs are 1, 2, and 3. + + 3.0.1 ===== @@ -2146,7 +2181,7 @@ and unit tests now work on those architectures. 0.0.93 ====== -### Significant changes since 0.0.91: +### Significant changes relative to 0.0.91: 1. 2982659: Fixed x86-64 build on FreeBSD systems diff --git a/src/3rdparty/libjpeg/src/jchuff.c b/src/3rdparty/libjpeg/src/jchuff.c index 3fede05f804..488c9b5c3a7 100644 --- a/src/3rdparty/libjpeg/src/jchuff.c +++ b/src/3rdparty/libjpeg/src/jchuff.c @@ -6,7 +6,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2009-2011, 2014-2016, 2018-2023, D. R. Commander. + * Copyright (C) 2009-2011, 2014-2016, 2018-2024, D. R. Commander. * Copyright (C) 2015, Matthieu Darbois. * Copyright (C) 2018, Matthias Räncker. * Copyright (C) 2020, Arm Limited. @@ -35,41 +35,7 @@ #include "jchuff.h" /* Declarations shared with jc*huff.c */ #endif #include - -/* - * NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be - * used for bit counting rather than the lookup table. This will reduce the - * memory footprint by 64k, which is important for some mobile applications - * that create many isolated instances of libjpeg-turbo (web browsers, for - * instance.) This may improve performance on some mobile platforms as well. - * This feature is enabled by default only on Arm processors, because some x86 - * chips have a slow implementation of bsr, and the use of clz/bsr cannot be - * shown to have a significant performance impact even on the x86 chips that - * have a fast implementation of it. When building for Armv6, you can - * explicitly disable the use of clz/bsr by adding -mthumb to the compiler - * flags (this defines __thumb__). - */ - -/* NOTE: Both GCC and Clang define __GNUC__ */ -#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \ - defined(_M_ARM) || defined(_M_ARM64) -#if !defined(__thumb__) || defined(__thumb2__) -#define USE_CLZ_INTRINSIC -#endif -#endif - -#ifdef USE_CLZ_INTRINSIC -#if defined(_MSC_VER) && !defined(__clang__) -#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x)) -#else -#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x)) -#endif -#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0) -#else -#include "jpeg_nbits_table.h" -#define JPEG_NBITS(x) (jpeg_nbits_table[x]) -#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x) -#endif +#include "jpeg_nbits.h" /* Expanded entropy encoder object for Huffman encoding. diff --git a/src/3rdparty/libjpeg/src/jconfig.h b/src/3rdparty/libjpeg/src/jconfig.h index a91be588e7b..1e03e166e77 100644 --- a/src/3rdparty/libjpeg/src/jconfig.h +++ b/src/3rdparty/libjpeg/src/jconfig.h @@ -2,9 +2,9 @@ #define JPEG_LIB_VERSION 80 -#define LIBJPEG_TURBO_VERSION 3.0.0 +#define LIBJPEG_TURBO_VERSION 3.0.2 -#define LIBJPEG_TURBO_VERSION_NUMBER 3000000 +#define LIBJPEG_TURBO_VERSION_NUMBER 3000002 #define C_ARITH_CODING_SUPPORTED 1 @@ -17,3 +17,4 @@ #endif #define NO_PUTENV + diff --git a/src/3rdparty/libjpeg/src/jconfigint.h b/src/3rdparty/libjpeg/src/jconfigint.h index a58061e52bb..afcb25d247c 100644 --- a/src/3rdparty/libjpeg/src/jconfigint.h +++ b/src/3rdparty/libjpeg/src/jconfigint.h @@ -4,11 +4,13 @@ #define BUILD "" +#define HIDDEN + #define INLINE inline #define PACKAGE_NAME "libjpeg-turbo" -#define VERSION "3.0.0" +#define VERSION "3.0.2" #if SIZE_MAX == 0xffffffff #define SIZEOF_SIZE_T 4 @@ -46,3 +48,4 @@ /* #undef WITH_SIMD */ #endif + diff --git a/src/3rdparty/libjpeg/src/jconfigint.h.in b/src/3rdparty/libjpeg/src/jconfigint.h.in index e7e66e74c02..5c14e32a1d1 100644 --- a/src/3rdparty/libjpeg/src/jconfigint.h.in +++ b/src/3rdparty/libjpeg/src/jconfigint.h.in @@ -1,6 +1,9 @@ /* libjpeg-turbo build number */ #define BUILD "@BUILD@" +/* How to hide global symbols. */ +#define HIDDEN @HIDDEN@ + /* Compiler's inline keyword */ #undef inline diff --git a/src/3rdparty/libjpeg/src/jcphuff.c b/src/3rdparty/libjpeg/src/jcphuff.c index 56e63bd62d3..484e2d857f0 100644 --- a/src/3rdparty/libjpeg/src/jcphuff.c +++ b/src/3rdparty/libjpeg/src/jcphuff.c @@ -6,7 +6,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2011, 2015, 2018, 2021-2022, D. R. Commander. + * Copyright (C) 2011, 2015, 2018, 2021-2022, 2024, D. R. Commander. * Copyright (C) 2016, 2018, 2022, Matthieu Darbois. * Copyright (C) 2020, Arm Limited. * Copyright (C) 2021, Alex Richardson. @@ -44,40 +44,7 @@ #ifdef C_PROGRESSIVE_SUPPORTED -/* - * NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be - * used for bit counting rather than the lookup table. This will reduce the - * memory footprint by 64k, which is important for some mobile applications - * that create many isolated instances of libjpeg-turbo (web browsers, for - * instance.) This may improve performance on some mobile platforms as well. - * This feature is enabled by default only on Arm processors, because some x86 - * chips have a slow implementation of bsr, and the use of clz/bsr cannot be - * shown to have a significant performance impact even on the x86 chips that - * have a fast implementation of it. When building for Armv6, you can - * explicitly disable the use of clz/bsr by adding -mthumb to the compiler - * flags (this defines __thumb__). - */ - -/* NOTE: Both GCC and Clang define __GNUC__ */ -#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \ - defined(_M_ARM) || defined(_M_ARM64) -#if !defined(__thumb__) || defined(__thumb2__) -#define USE_CLZ_INTRINSIC -#endif -#endif - -#ifdef USE_CLZ_INTRINSIC -#if defined(_MSC_VER) && !defined(__clang__) -#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x)) -#else -#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x)) -#endif -#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0) -#else -#include "jpeg_nbits_table.h" -#define JPEG_NBITS(x) (jpeg_nbits_table[x]) -#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x) -#endif +#include "jpeg_nbits.h" /* Expanded entropy encoder object for progressive Huffman encoding. */ diff --git a/src/3rdparty/libjpeg/src/jdapimin.c b/src/3rdparty/libjpeg/src/jdapimin.c index 51ca552dad8..30d92841a8c 100644 --- a/src/3rdparty/libjpeg/src/jdapimin.c +++ b/src/3rdparty/libjpeg/src/jdapimin.c @@ -6,7 +6,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2016, 2022, D. R. Commander. + * Copyright (C) 2016, 2022, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -160,9 +160,12 @@ default_decompress_parms(j_decompress_ptr cinfo) int cid1 = cinfo->comp_info[1].component_id; int cid2 = cinfo->comp_info[2].component_id; - if (cid0 == 1 && cid1 == 2 && cid2 == 3) - cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ - else if (cid0 == 82 && cid1 == 71 && cid2 == 66) + if (cid0 == 1 && cid1 == 2 && cid2 == 3) { + if (cinfo->master->lossless) + cinfo->jpeg_color_space = JCS_RGB; /* assume RGB w/out marker */ + else + cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ + } else if (cid0 == 82 && cid1 == 71 && cid2 == 66) cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ else { TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); diff --git a/src/3rdparty/libjpeg/src/jerror.h b/src/3rdparty/libjpeg/src/jerror.h index 39362fdd477..71ba03e2a3e 100644 --- a/src/3rdparty/libjpeg/src/jerror.h +++ b/src/3rdparty/libjpeg/src/jerror.h @@ -7,7 +7,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2014, 2017, 2021-2022, D. R. Commander. + * Copyright (C) 2014, 2017, 2021-2023, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -111,7 +111,7 @@ JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") #if JPEG_LIB_VERSION >= 70 JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined") #endif -JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_BACKING_STORE, "Memory limit exceeded") JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") diff --git a/src/3rdparty/libjpeg/src/jmemsys.h b/src/3rdparty/libjpeg/src/jmemsys.h index 9229550afde..ac09ef4c36d 100644 --- a/src/3rdparty/libjpeg/src/jmemsys.h +++ b/src/3rdparty/libjpeg/src/jmemsys.h @@ -99,24 +99,6 @@ EXTERN(size_t) jpeg_mem_available(j_common_ptr cinfo, size_t min_bytes_needed, #define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ -#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ - -typedef unsigned short XMSH; /* type of extended-memory handles */ -typedef unsigned short EMSH; /* type of expanded-memory handles */ - -typedef union { - short file_handle; /* DOS file handle if it's a temp file */ - XMSH xms_handle; /* handle if it's a chunk of XMS */ - EMSH ems_handle; /* handle if it's a chunk of EMS */ -} handle_union; - -#endif /* USE_MSDOS_MEMMGR */ - -#ifdef USE_MAC_MEMMGR /* Mac-specific junk */ -#include -#endif /* USE_MAC_MEMMGR */ - - typedef struct backing_store_struct *backing_store_ptr; typedef struct backing_store_struct { @@ -130,22 +112,9 @@ typedef struct backing_store_struct { void (*close_backing_store) (j_common_ptr cinfo, backing_store_ptr info); /* Private fields for system-dependent backing-store management */ -#ifdef USE_MSDOS_MEMMGR - /* For the MS-DOS manager (jmemdos.c), we need: */ - handle_union handle; /* reference to backing-store storage object */ - char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ -#else -#ifdef USE_MAC_MEMMGR - /* For the Mac manager (jmemmac.c), we need: */ - short temp_file; /* file reference number to temp file */ - FSSpec tempSpec; /* the FSSpec for the temp file */ - char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ -#else /* For a typical implementation with temp files, we need: */ FILE *temp_file; /* stdio reference to temp file */ char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ -#endif -#endif } backing_store_info; diff --git a/src/3rdparty/libjpeg/src/jpeg_nbits_table.h b/src/3rdparty/libjpeg/src/jpeg_nbits.c similarity index 99% rename from src/3rdparty/libjpeg/src/jpeg_nbits_table.h rename to src/3rdparty/libjpeg/src/jpeg_nbits.c index fcf73878c31..c8ee6b056cb 100644 --- a/src/3rdparty/libjpeg/src/jpeg_nbits_table.h +++ b/src/3rdparty/libjpeg/src/jpeg_nbits.c @@ -1,4 +1,32 @@ -static const unsigned char jpeg_nbits_table[65536] = { +/* + * Copyright (C) 2024, D. R. Commander. + * + * For conditions of distribution and use, see the accompanying README.ijg + * file. + */ + +#include "jpeg_nbits.h" +#include "jconfigint.h" + + +#ifndef USE_CLZ_INTRINSIC + +#define INCLUDE_JPEG_NBITS_TABLE + +/* When building for x86[-64] with the SIMD extensions enabled, the C Huffman + * encoders can reuse jpeg_nbits_table from the SSE2 baseline Huffman encoder. + */ +#if (defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || \ + defined(_M_X64)) && defined(WITH_SIMD) +#undef INCLUDE_JPEG_NBITS_TABLE +#endif + +#endif + + +#ifdef INCLUDE_JPEG_NBITS_TABLE + +const unsigned char HIDDEN jpeg_nbits_table[65536] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, @@ -4096,3 +4124,11 @@ static const unsigned char jpeg_nbits_table[65536] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; + +#else + +/* Suppress compiler warnings about empty translation unit. */ + +typedef int dummy_jpeg_nbits_table; + +#endif diff --git a/src/3rdparty/libjpeg/src/jpeg_nbits.h b/src/3rdparty/libjpeg/src/jpeg_nbits.h new file mode 100644 index 00000000000..6481a1228d1 --- /dev/null +++ b/src/3rdparty/libjpeg/src/jpeg_nbits.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014, 2021, 2024, D. R. Commander. + * Copyright (C) 2014, Olle Liljenzin. + * Copyright (C) 2020, Arm Limited. + * + * For conditions of distribution and use, see the accompanying README.ijg + * file. + */ + +/* + * NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be + * used for bit counting rather than the lookup table. This will reduce the + * memory footprint by 64k, which is important for some mobile applications + * that create many isolated instances of libjpeg-turbo (web browsers, for + * instance.) This may improve performance on some mobile platforms as well. + * This feature is enabled by default only on Arm processors, because some x86 + * chips have a slow implementation of bsr, and the use of clz/bsr cannot be + * shown to have a significant performance impact even on the x86 chips that + * have a fast implementation of it. When building for Armv6, you can + * explicitly disable the use of clz/bsr by adding -mthumb to the compiler + * flags (this defines __thumb__). + */ + +/* NOTE: Both GCC and Clang define __GNUC__ */ +#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \ + defined(_M_ARM) || defined(_M_ARM64) +#if !defined(__thumb__) || defined(__thumb2__) +#define USE_CLZ_INTRINSIC +#endif +#endif + +#ifdef USE_CLZ_INTRINSIC +#if defined(_MSC_VER) && !defined(__clang__) +#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x)) +#else +#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x)) +#endif +#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0) +#else +extern const unsigned char jpeg_nbits_table[65536]; +#define JPEG_NBITS(x) (jpeg_nbits_table[x]) +#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x) +#endif diff --git a/src/3rdparty/libjpeg/src/jversion.h b/src/3rdparty/libjpeg/src/jversion.h index f9ad5c29c99..5c127dc635a 100644 --- a/src/3rdparty/libjpeg/src/jversion.h +++ b/src/3rdparty/libjpeg/src/jversion.h @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2012-2023, D. R. Commander. + * Copyright (C) 2010, 2012-2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -37,7 +37,7 @@ */ #define JCOPYRIGHT \ - "Copyright (C) 2009-2023 D. R. Commander\n" \ + "Copyright (C) 2009-2024 D. R. Commander\n" \ "Copyright (C) 2015, 2020 Google, Inc.\n" \ "Copyright (C) 2019-2020 Arm Limited\n" \ "Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \ @@ -52,4 +52,4 @@ "Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding" #define JCOPYRIGHT_SHORT \ - "Copyright (C) 1991-2023 The libjpeg-turbo Project and many others" + "Copyright (C) 1991-2024 The libjpeg-turbo Project and many others" diff --git a/src/3rdparty/libpng/ANNOUNCE b/src/3rdparty/libpng/ANNOUNCE index 404cbb0de9a..bc147adb78b 100644 --- a/src/3rdparty/libpng/ANNOUNCE +++ b/src/3rdparty/libpng/ANNOUNCE @@ -1,5 +1,5 @@ -libpng 1.6.40 - June 21, 2023 -============================= +libpng 1.6.43 - February 23, 2024 +================================= This is a public release of libpng, intended for use in production code. @@ -9,13 +9,13 @@ Files available for download Source files with LF line endings (for Unix/Linux): - * libpng-1.6.40.tar.xz (LZMA-compressed, recommended) - * libpng-1.6.40.tar.gz + * libpng-1.6.43.tar.xz (LZMA-compressed, recommended) + * libpng-1.6.43.tar.gz (deflate-compressed) Source files with CRLF line endings (for Windows): - * lpng1640.7z (LZMA-compressed, recommended) - * lpng1640.zip + * lpng1643.7z (LZMA-compressed, recommended) + * lpng1643.zip (deflate-compressed) Other information: @@ -25,15 +25,36 @@ Other information: * TRADEMARK.md -Changes from version 1.6.39 to version 1.6.40 +Changes from version 1.6.42 to version 1.6.43 --------------------------------------------- - * Fixed the eXIf chunk multiplicity checks. - * Fixed a memory leak in pCAL processing. - * Corrected the validity report about tRNS inside png_get_valid(). - * Fixed various build issues on *BSD, Mac and Windows. - * Updated the configurations and the scripts for continuous integration. - * Cleaned up the code, the build scripts, and the documentation. + * Fixed the row width check in png_check_IHDR(). + This corrected a bug that was specific to the 16-bit platforms, + and removed a spurious compiler warning from the 64-bit builds. + (Reported by Jacek Caban; fixed by John Bowler) + * Added eXIf chunk support to the push-mode reader in pngpread.c. + (Contributed by Chris Blume) + * Added contrib/pngexif for the benefit of the users who would like + to inspect the content of eXIf chunks. + * Added contrib/conftest/basic.dfa, a basic build-time configuration. + (Contributed by John Bowler) + * Fixed a preprocessor condition in pngread.c that broke build-time + configurations like contrib/conftest/pngcp.dfa. + (Contributed by John Bowler) + * Added CMake build support for LoongArch LSX. + (Contributed by GuXiWei) + * Fixed a CMake build error that occurred under a peculiar state of the + dependency tree. This was a regression introduced in libpng-1.6.41. + (Contributed by Dan Rosser) + * Marked the installed libpng headers as system headers in CMake. + (Contributed by Benjamin Buch) + * Updated the build support for RISCOS. + (Contributed by Cameron Cawley) + * Updated the makefiles to allow cross-platform builds to initialize + conventional make variables like AR and ARFLAGS. + * Added various improvements to the CI scripts in areas like version + consistency verification and text linting. + * Added version consistency verification to pngtest.c also. Send comments/corrections/commendations to png-mng-implement at lists.sf.net. diff --git a/src/3rdparty/libpng/CHANGES b/src/3rdparty/libpng/CHANGES index 2d8c585c0e7..441b57ecf1a 100644 --- a/src/3rdparty/libpng/CHANGES +++ b/src/3rdparty/libpng/CHANGES @@ -6129,6 +6129,73 @@ Version 1.6.40 [June 21, 2023] Updated the configurations and the scripts for continuous integration. Cleaned up the code, the build scripts, and the documentation. +Version 1.6.41 [January 24, 2024] + Added SIMD-optimized code for the LoongArch LSX hardware. + (Contributed by GuXiWei, JinBo and ZhangLixia) + Fixed the run-time discovery of MIPS MSA hardware. + (Contributed by Sui Jingfeng) + Fixed an off-by-one error in the function png_do_check_palette_indexes(), + which failed to recognize errors that might have existed in the first + column of a broken palette-encoded image. This was a benign regression + accidentally introduced in libpng-1.6.33. No pixel was harmed. + (Contributed by Adam Richter; reviewed by John Bowler) + Fixed, improved and modernized the contrib/pngminus programs, i.e., + png2pnm.c and pnm2png.c + Removed old and peculiar portability hacks that were meant to silence + warnings issued by gcc version 7.1 alone. + (Contributed by John Bowler) + Fixed and modernized the CMake file, and raised the minimum required + CMake version from 3.1 to 3.6. + (Contributed by Clinton Ingram, Timothy Lyanguzov, Tyler Kropp, et al.) + Allowed the configure script to disable the building of auxiliary tools + and tests, thus catching up with the CMake file. + (Contributed by Carlo Bramini) + Fixed a build issue on Mac. + (Contributed by Zixu Wang) + Moved the Autoconf macro files to scripts/autoconf. + Moved the CMake files (except for the main CMakeLists.txt) to + scripts/cmake and moved the list of their contributing authors to + scripts/cmake/AUTHORS.md + Updated the CI configurations and scripts. + Relicensed the CI scripts to the MIT License. + Improved the test coverage. + (Contributed by John Bowler) + +Version 1.6.42 [January 29, 2024] + Fixed the implementation of the macro function png_check_sig(). + This was an API regression, introduced in libpng-1.6.41. + (Reported by Matthieu Darbois) + Fixed and updated the libpng manual. + +Version 1.6.43 [February 23, 2024] + Fixed the row width check in png_check_IHDR(). + This corrected a bug that was specific to the 16-bit platforms, + and removed a spurious compiler warning from the 64-bit builds. + (Reported by Jacek Caban; fixed by John Bowler) + Added eXIf chunk support to the push-mode reader in pngpread.c. + (Contributed by Chris Blume) + Added contrib/pngexif for the benefit of the users who would like + to inspect the content of eXIf chunks. + Added contrib/conftest/basic.dfa, a basic build-time configuration. + (Contributed by John Bowler) + Fixed a preprocessor condition in pngread.c that broke build-time + configurations like contrib/conftest/pngcp.dfa. + (Contributed by John Bowler) + Added CMake build support for LoongArch LSX. + (Contributed by GuXiWei) + Fixed a CMake build error that occurred under a peculiar state of the + dependency tree. This was a regression introduced in libpng-1.6.41. + (Contributed by Dan Rosser) + Marked the installed libpng headers as system headers in CMake. + (Contributed by Benjamin Buch) + Updated the build support for RISCOS. + (Contributed by Cameron Cawley) + Updated the makefiles to allow cross-platform builds to initialize + conventional make variables like AR and ARFLAGS. + Added various improvements to the CI scripts in areas like version + consistency verification and text linting. + Added version consistency verification to pngtest.c also. + Send comments/corrections/commendations to png-mng-implement at lists.sf.net. Subscription is required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-implement diff --git a/src/3rdparty/libpng/LICENSE b/src/3rdparty/libpng/LICENSE index 086d1c2fda6..25f298f0fcf 100644 --- a/src/3rdparty/libpng/LICENSE +++ b/src/3rdparty/libpng/LICENSE @@ -4,8 +4,8 @@ COPYRIGHT NOTICE, DISCLAIMER, and LICENSE PNG Reference Library License version 2 --------------------------------------- - * Copyright (c) 1995-2023 The PNG Reference Library Authors. - * Copyright (c) 2018-2023 Cosmin Truta. + * Copyright (c) 1995-2024 The PNG Reference Library Authors. + * Copyright (c) 2018-2024 Cosmin Truta. * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. * Copyright (c) 1996-1997 Andreas Dilger. * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. diff --git a/src/3rdparty/libpng/README b/src/3rdparty/libpng/README index dedd2c1639e..a6ca3ae9f94 100644 --- a/src/3rdparty/libpng/README +++ b/src/3rdparty/libpng/README @@ -1,4 +1,4 @@ -README for libpng version 1.6.40 +README for libpng version 1.6.43 ================================ See the note about version numbers near the top of `png.h`. @@ -142,10 +142,11 @@ Files included in this distribution pngwrite.c => High-level write functions pngwtran.c => Write data transformations pngwutil.c => Write utility functions - arm/ => Optimized code for the ARM platform - intel/ => Optimized code for the INTEL-SSE2 platform - mips/ => Optimized code for the MIPS platform - powerpc/ => Optimized code for the PowerPC platform + arm/ => Optimized code for ARM Neon + intel/ => Optimized code for INTEL SSE2 + loongarch/ => Optimized code for LoongArch LSX + mips/ => Optimized code for MIPS MSA and MIPS MMI + powerpc/ => Optimized code for PowerPC VSX ci/ => Scripts for continuous integration contrib/ => External contributions arm-neon/ => Optimized code for the ARM-NEON platform @@ -158,6 +159,7 @@ Files included in this distribution libtests/ => Test programs oss-fuzz/ => Files used by the OSS-Fuzz project for fuzz-testing libpng + pngexif/ => Program to inspect the EXIF information in PNG files pngminim/ => Minimal decoder, encoder, and progressive decoder programs demonstrating the use of pngusr.dfa pngminus/ => Simple pnm2png and png2pnm programs diff --git a/src/3rdparty/libpng/libpng-manual.txt b/src/3rdparty/libpng/libpng-manual.txt index 67b50788266..79880575994 100644 --- a/src/3rdparty/libpng/libpng-manual.txt +++ b/src/3rdparty/libpng/libpng-manual.txt @@ -1,6 +1,6 @@ libpng-manual.txt - A description on how to use and modify libpng - Copyright (c) 2018-2023 Cosmin Truta + Copyright (c) 2018-2024 Cosmin Truta Copyright (c) 1998-2018 Glenn Randers-Pehrson This document is released under the libpng license. @@ -9,9 +9,9 @@ libpng-manual.txt - A description on how to use and modify libpng Based on: - libpng version 1.6.36, December 2018, through 1.6.40 - June 2023 + libpng version 1.6.36, December 2018, through 1.6.43 - February 2024 Updated and distributed by Cosmin Truta - Copyright (c) 2018-2023 Cosmin Truta + Copyright (c) 2018-2024 Cosmin Truta libpng versions 0.97, January 1998, through 1.6.35 - July 2018 Updated and distributed by Glenn Randers-Pehrson @@ -357,7 +357,7 @@ Customizing libpng. return ERROR; } - is_png = !png_sig_cmp(header, 0, number); + is_png = (png_sig_cmp(header, 0, number) == 0); if (!is_png) { return NOT_PNG; @@ -385,8 +385,7 @@ create the structure, so your application should check for that. if (!info_ptr) { - png_destroy_read_struct(&png_ptr, - (png_infopp)NULL, (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, NULL, NULL); return ERROR; } @@ -419,14 +418,13 @@ free any memory. if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr, - &end_info); + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); return ERROR; } -Pass (png_infopp)NULL instead of &end_info if you didn't create -an end_info structure. +Pass NULL instead of &end_info if you didn't create an end_info +structure. If you would rather avoid the complexity of setjmp/longjmp issues, you can compile libpng with PNG_NO_SETJMP, in which case @@ -496,7 +494,7 @@ You can set up a callback function to handle any unknown chunks in the input stream. You must supply the function read_chunk_callback(png_structp png_ptr, - png_unknown_chunkp chunk); + png_unknown_chunkp chunk) { /* The unknown chunk structure contains your chunk data, along with similar data for any other @@ -547,9 +545,9 @@ a progress meter or the like. It's demonstrated in pngtest.c. You must supply a function void read_row_callback(png_structp png_ptr, - png_uint_32 row, int pass); + png_uint_32 row, int pass) { - /* put your code here */ + /* put your code here */ } (You can give it another name that you like instead of "read_row_callback") @@ -1180,22 +1178,22 @@ where row_pointers is an array of pointers to the pixel data for each row: If you know your image size and pixel size ahead of time, you can allocate row_pointers prior to calling png_read_png() with - if (height > PNG_UINT_32_MAX/(sizeof (png_byte))) - png_error (png_ptr, + if (height > PNG_UINT_32_MAX / (sizeof (png_bytep))) + png_error(png_ptr, "Image is too tall to process in memory"); - if (width > PNG_UINT_32_MAX/pixel_size) - png_error (png_ptr, + if (width > PNG_UINT_32_MAX / pixel_size) + png_error(png_ptr, "Image is too wide to process in memory"); row_pointers = png_malloc(png_ptr, height*(sizeof (png_bytep))); - for (int i=0; i PNG_SIZE_MAX/(width*pixel_size)) { - png_error(png_ptr,"image_data buffer would be too large"); - } + if (height > PNG_SIZE_MAX/(width*pixel_size)) + png_error(png_ptr, "image_data buffer would be too large"); - png_bytep buffer=png_malloc(png_ptr,height*width*pixel_size); + png_bytep buffer = png_malloc(png_ptr, + height*width*pixel_size); - for (int i=0; i= 10504 png_set_scale_16(png_ptr); #else png_set_strip_16(png_ptr); #endif + } (The more accurate "png_set_scale_16()" API became available in libpng version 1.5.4). @@ -1901,7 +1900,7 @@ Note that png_set_filler() does not change the color type. If you want to do that, you can add a true alpha channel with if (color_type == PNG_COLOR_TYPE_RGB || - color_type == PNG_COLOR_TYPE_GRAY) + color_type == PNG_COLOR_TYPE_GRAY) png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER); where "filler" contains the alpha value to assign to each pixel. @@ -1926,7 +1925,7 @@ with alpha. if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_RGB_ALPHA) png_set_rgb_to_gray(png_ptr, error_action, - double red_weight, double green_weight); + (double)red_weight, (double)green_weight); error_action = 1: silently do the conversion @@ -1949,8 +1948,8 @@ In the corresponding fixed point API the red_weight and green_weight values are simply scaled by 100,000: png_set_rgb_to_gray(png_ptr, error_action, - png_fixed_point red_weight, - png_fixed_point green_weight); + (png_fixed_point)red_weight, + (png_fixed_point)green_weight); If you have set error_action = 1 or 2, you can later check whether the image really was gray, after processing @@ -2186,9 +2185,8 @@ do your own check for number_of_rows*width*pixel_size if you are using a multiple-row buffer: /* Guard against integer overflow */ - if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) { - png_error(png_ptr,"image_data buffer would be too large"); - } + if (number_of_rows > PNG_SIZE_MAX/(width*pixel_size)) + png_error(png_ptr, "image_data buffer would be too large"); Remember: Before you call png_read_update_info(), the png_get_*() functions return the values corresponding to the original PNG image. @@ -2408,12 +2406,11 @@ separate. if (!end_info) { - png_destroy_read_struct(&png_ptr, &info_ptr, - (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return ERROR; } - png_read_end(png_ptr, end_info); + png_read_end(png_ptr, end_info); If you are not interested, you should still call png_read_end() but you can pass NULL, avoiding the need to create an end_info structure. @@ -2421,7 +2418,7 @@ If you do this, libpng will not process any chunks after IDAT other than skipping over them and perhaps (depending on whether you have called png_set_crc_action) checking their CRCs while looking for the IEND chunk. - png_read_end(png_ptr, (png_infop)NULL); + png_read_end(png_ptr, NULL); If you don't call png_read_end(), then your file pointer will be left pointing to the first chunk after the last IDAT, which is probably @@ -2430,13 +2427,11 @@ the PNG datastream. When you are done, you can free all memory allocated by libpng like this: - png_destroy_read_struct(&png_ptr, &info_ptr, - &end_info); + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); or, if you didn't create an end_info structure, - png_destroy_read_struct(&png_ptr, &info_ptr, - (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); It is also possible to individually free the info_ptr members that point to libpng-allocated storage with the following function: @@ -2556,15 +2551,13 @@ png_infop info_ptr; if (!info_ptr) { - png_destroy_read_struct(&png_ptr, - (png_infopp)NULL, (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, NULL, NULL); return ERROR; } if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr, - (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return ERROR; } @@ -2597,8 +2590,7 @@ png_infop info_ptr; { if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_read_struct(&png_ptr, &info_ptr, - (png_infopp)NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return ERROR; } @@ -2763,8 +2755,7 @@ both "png_ptr"; you can call them anything you like, such as png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { - png_destroy_write_struct(&png_ptr, - (png_infopp)NULL); + png_destroy_write_struct(&png_ptr, NULL); return ERROR; } @@ -2790,7 +2781,7 @@ section below for more information on the libpng error handling. if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_write_struct(&png_ptr, &info_ptr); + png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return ERROR; } @@ -2844,9 +2835,9 @@ a progress meter or the like. It's demonstrated in pngtest.c. You must supply a function void write_row_callback(png_structp png_ptr, png_uint_32 row, - int pass); + int pass) { - /* put your code here */ + /* put your code here */ } (You can give it another name that you like instead of "write_row_callback") @@ -3116,8 +3107,8 @@ width, height, bit_depth, and color_type must be the same in each call. png_set_eXIf_1(png_ptr, info_ptr, num_exif, exif); - exif - Exif profile (array of - png_byte) (PNG_INFO_eXIf) + exif - Exif profile (array of png_byte) + (PNG_INFO_eXIf) png_set_hIST(png_ptr, info_ptr, hist); @@ -3127,12 +3118,12 @@ width, height, bit_depth, and color_type must be the same in each call. png_set_tIME(png_ptr, info_ptr, mod_time); mod_time - time image was last modified - (PNG_VALID_tIME) + (PNG_INFO_tIME) png_set_bKGD(png_ptr, info_ptr, background); background - background color (of type - png_color_16p) (PNG_VALID_bKGD) + png_color_16p) (PNG_INFO_bKGD) png_set_text(png_ptr, info_ptr, text_ptr, num_text); @@ -4218,7 +4209,7 @@ png_create_read_struct_2() or png_create_write_struct_2() to register your own functions as described above. These functions also provide a void pointer that can be retrieved via - mem_ptr=png_get_mem_ptr(png_ptr); + mem_ptr = png_get_mem_ptr(png_ptr); Your replacement memory functions must have prototypes as follows: @@ -4515,7 +4506,7 @@ When PNG_DEBUG is defined but is zero, the macros aren't defined, but you can still use PNG_DEBUG to control your own debugging: #ifdef PNG_DEBUG - fprintf(stderr, ... + fprintf(stderr, ...); #endif When PNG_DEBUG = 1, the macros are defined, but only png_debug statements @@ -4692,7 +4683,7 @@ deprecated since libpng-1.0.16 and libpng-1.2.6. The function png_check_sig(sig, num) was replaced with - !png_sig_cmp(sig, 0, num) + png_sig_cmp(sig, 0, num) == 0 It has been deprecated since libpng-0.90. The function @@ -4756,8 +4747,8 @@ png_get_mmx_bitdepth_threshold(), png_get_mmx_rowbytes_threshold(), png_set_asm_flags(), and png_mmx_supported() We removed the obsolete png_check_sig(), png_memcpy_check(), and -png_memset_check() functions. Instead use !png_sig_cmp(), memcpy(), -and memset(), respectively. +png_memset_check() functions. Instead use png_sig_cmp() == 0, +memcpy(), and memset(), respectively. The function png_set_gray_1_2_4_to_8() was removed. It has been deprecated since libpng-1.0.18 and 1.2.9, when it was replaced with @@ -5239,7 +5230,7 @@ changed, and is unaffected by conditional compilation macros. It is the best choice for use in configure scripts for detecting the presence of any libpng version since 0.88. In an autoconf "configure.in" you could use - AC_CHECK_LIB(png, png_get_io_ptr, ... + AC_CHECK_LIB(png, png_get_io_ptr, ...) XV. Source code repository @@ -5248,12 +5239,12 @@ control. The git repository was built from old libpng-x.y.z.tar.gz files going back to version 0.70. You can access the git repository (read only) at - https://github.com/glennrp/libpng or + https://github.com/pnggroup/libpng or https://git.code.sf.net/p/libpng/code.git or you can browse it with a web browser at - https://github.com/glennrp/libpng or + https://github.com/pnggroup/libpng or https://sourceforge.net/p/libpng/code/ci/libpng16/tree/ Patches can be sent to png-mng-implement at lists.sourceforge.net or @@ -5263,7 +5254,7 @@ uploaded to the libpng bug tracker at or as a "pull request" to - https://github.com/glennrp/libpng/pulls + https://github.com/pnggroup/libpng/pulls We also accept patches built from the tar or zip distributions, and simple verbal descriptions of bug fixes, reported either to the diff --git a/src/3rdparty/libpng/png.c b/src/3rdparty/libpng/png.c index d6471b06ccd..9ed31570092 100644 --- a/src/3rdparty/libpng/png.c +++ b/src/3rdparty/libpng/png.c @@ -1,7 +1,7 @@ /* png.c - location for general purpose libpng functions * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -14,27 +14,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_40 Your_png_h_is_not_version_1_6_40; - -#ifdef __GNUC__ -/* The version tests may need to be added to, but the problem warning has - * consistently been fixed in GCC versions which obtain wide-spread release. - * The problem is that many versions of GCC rearrange comparison expressions in - * the optimizer in such a way that the results of the comparison will change - * if signed integer overflow occurs. Such comparisons are not permitted in - * ANSI C90, however GCC isn't clever enough to work out that that do not occur - * below in png_ascii_from_fp and png_muldiv, so it produces a warning with - * -Wextra. Unfortunately this is highly dependent on the optimizer and the - * machine architecture so the warning comes and goes unpredictably and is - * impossible to "fix", even were that a good idea. - */ -#if __GNUC__ == 7 && __GNUC_MINOR__ == 1 -#define GCC_STRICT_OVERFLOW 1 -#endif /* GNU 7.1.x */ -#endif /* GNU */ -#ifndef GCC_STRICT_OVERFLOW -#define GCC_STRICT_OVERFLOW 0 -#endif +typedef png_libpng_version_1_6_43 Your_png_h_is_not_version_1_6_43; /* Tells libpng that we have already handled the first "num_bytes" bytes * of the PNG file signature. If the PNG data is embedded into another @@ -73,21 +53,21 @@ png_set_sig_bytes(png_structrp png_ptr, int num_bytes) int PNGAPI png_sig_cmp(png_const_bytep sig, size_t start, size_t num_to_check) { - png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + static const png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10}; if (num_to_check > 8) num_to_check = 8; else if (num_to_check < 1) - return (-1); + return -1; if (start > 7) - return (-1); + return -1; if (start + num_to_check > 8) num_to_check = 8 - start; - return ((int)(memcmp(&sig[start], &png_signature[start], num_to_check))); + return memcmp(&sig[start], &png_signature[start], num_to_check); } #endif /* READ */ @@ -447,7 +427,6 @@ png_info_init_3,(png_infopp ptr_ptr, size_t png_info_struct_size), memset(info_ptr, 0, (sizeof *info_ptr)); } -/* The following API is not called internally */ void PNGAPI png_data_freer(png_const_structrp png_ptr, png_inforp info_ptr, int freer, png_uint_32 mask) @@ -686,9 +665,9 @@ png_voidp PNGAPI png_get_io_ptr(png_const_structrp png_ptr) { if (png_ptr == NULL) - return (NULL); + return NULL; - return (png_ptr->io_ptr); + return png_ptr->io_ptr; } #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) @@ -752,7 +731,7 @@ png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) { size_t pos = 0; - char number_buf[5]; /* enough for a four-digit year */ + char number_buf[5] = {0, 0, 0, 0, 0}; /* enough for a four-digit year */ # define APPEND_STRING(string) pos = png_safecat(out, 29, pos, (string)) # define APPEND_NUMBER(format, value)\ @@ -815,8 +794,8 @@ png_get_copyright(png_const_structrp png_ptr) return PNG_STRING_COPYRIGHT #else return PNG_STRING_NEWLINE \ - "libpng version 1.6.40" PNG_STRING_NEWLINE \ - "Copyright (c) 2018-2023 Cosmin Truta" PNG_STRING_NEWLINE \ + "libpng version 1.6.43" PNG_STRING_NEWLINE \ + "Copyright (c) 2018-2024 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ @@ -977,7 +956,7 @@ png_reset_zstream(png_structrp png_ptr) return Z_STREAM_ERROR; /* WARNING: this resets the window bits to the maximum! */ - return (inflateReset(&png_ptr->zstream)); + return inflateReset(&png_ptr->zstream); } #endif /* READ */ @@ -986,7 +965,7 @@ png_uint_32 PNGAPI png_access_version_number(void) { /* Version of *.c files used when building libpng */ - return((png_uint_32)PNG_LIBPNG_VER); + return (png_uint_32)PNG_LIBPNG_VER; } #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) @@ -1842,14 +1821,14 @@ png_icc_profile_error(png_const_structrp png_ptr, png_colorspacerp colorspace, } # ifdef PNG_WARNINGS_SUPPORTED else - { - char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */ + { + char number[PNG_NUMBER_BUFFER_SIZE]; /* +24 = 114 */ - pos = png_safecat(message, (sizeof message), pos, - png_format_number(number, number+(sizeof number), - PNG_NUMBER_FORMAT_x, value)); - pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */ - } + pos = png_safecat(message, (sizeof message), pos, + png_format_number(number, number+(sizeof number), + PNG_NUMBER_FORMAT_x, value)); + pos = png_safecat(message, (sizeof message), pos, "h: "); /* +2 = 116 */ + } # endif /* The 'reason' is an arbitrary message, allow +79 maximum 195 */ pos = png_safecat(message, (sizeof message), pos, reason); @@ -2532,17 +2511,6 @@ png_colorspace_set_rgb_coefficients(png_structrp png_ptr) #endif /* COLORSPACE */ -#ifdef __GNUC__ -/* This exists solely to work round a warning from GNU C. */ -static int /* PRIVATE */ -png_gt(size_t a, size_t b) -{ - return a > b; -} -#else -# define png_gt(a,b) ((a) > (b)) -#endif - void /* PRIVATE */ png_check_IHDR(png_const_structrp png_ptr, png_uint_32 width, png_uint_32 height, int bit_depth, @@ -2564,8 +2532,16 @@ png_check_IHDR(png_const_structrp png_ptr, error = 1; } - if (png_gt(((width + 7) & (~7U)), - ((PNG_SIZE_MAX + /* The bit mask on the first line below must be at least as big as a + * png_uint_32. "~7U" is not adequate on 16-bit systems because it will + * be an unsigned 16-bit value. Casting to (png_alloc_size_t) makes the + * type of the result at least as bit (in bits) as the RHS of the > operator + * which also avoids a common warning on 64-bit systems that the comparison + * of (png_uint_32) against the constant value on the RHS will always be + * false. + */ + if (((width + 7) & ~(png_alloc_size_t)7) > + (((PNG_SIZE_MAX - 48 /* big_row_buf hack */ - 1) /* filter byte */ / 8) /* 8-byte RGBA pixels */ @@ -2891,14 +2867,6 @@ png_pow10(int power) /* Function to format a floating point value in ASCII with a given * precision. */ -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic push -/* The problem arises below with exp_b10, which can never overflow because it - * comes, originally, from frexp and is therefore limited to a range which is - * typically +/-710 (log2(DBL_MAX)/log2(DBL_MIN)). - */ -#pragma GCC diagnostic warning "-Wstrict-overflow=2" -#endif /* GCC_STRICT_OVERFLOW */ void /* PRIVATE */ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size, double fp, unsigned int precision) @@ -3220,10 +3188,6 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, size_t size, /* Here on buffer too small. */ png_error(png_ptr, "ASCII conversion buffer too small"); } -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic pop -#endif /* GCC_STRICT_OVERFLOW */ - # endif /* FLOATING_POINT */ # ifdef PNG_FIXED_POINT_SUPPORTED @@ -3251,7 +3215,7 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii, if (num <= 0x80000000) /* else overflowed */ { unsigned int ndigits = 0, first = 16 /* flag value */; - char digits[10]; + char digits[10] = {0}; while (num) { @@ -3336,15 +3300,6 @@ png_fixed(png_const_structrp png_ptr, double fp, png_const_charp text) * the nearest .00001). Overflow and divide by zero are signalled in * the result, a boolean - true on success, false on overflow. */ -#if GCC_STRICT_OVERFLOW /* from above */ -/* It is not obvious which comparison below gets optimized in such a way that - * signed overflow would change the result; looking through the code does not - * reveal any tests which have the form GCC complains about, so presumably the - * optimizer is moving an add or subtract into the 'if' somewhere. - */ -#pragma GCC diagnostic push -#pragma GCC diagnostic warning "-Wstrict-overflow=2" -#endif /* GCC_STRICT_OVERFLOW */ int png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, png_int_32 divisor) @@ -3459,9 +3414,6 @@ png_muldiv(png_fixed_point_p res, png_fixed_point a, png_int_32 times, return 0; } -#if GCC_STRICT_OVERFLOW -#pragma GCC diagnostic pop -#endif /* GCC_STRICT_OVERFLOW */ #endif /* READ_GAMMA || INCH_CONVERSIONS */ #if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_INCH_CONVERSIONS_SUPPORTED) diff --git a/src/3rdparty/libpng/png.h b/src/3rdparty/libpng/png.h index cfc4841099d..83d39031260 100644 --- a/src/3rdparty/libpng/png.h +++ b/src/3rdparty/libpng/png.h @@ -1,9 +1,9 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.40 + * libpng version 1.6.43 * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -15,7 +15,7 @@ * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger * libpng versions 0.97, January 1998, through 1.6.35, July 2018: * Glenn Randers-Pehrson - * libpng versions 1.6.36, December 2018, through 1.6.40, June 2023: + * libpng versions 1.6.36, December 2018, through 1.6.43, February 2024: * Cosmin Truta * See also "Contributing Authors", below. */ @@ -27,8 +27,8 @@ * PNG Reference Library License version 2 * --------------------------------------- * - * * Copyright (c) 1995-2023 The PNG Reference Library Authors. - * * Copyright (c) 2018-2023 Cosmin Truta. + * * Copyright (c) 1995-2024 The PNG Reference Library Authors. + * * Copyright (c) 2018-2024 Cosmin Truta. * * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. * * Copyright (c) 1996-1997 Andreas Dilger. * * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -239,7 +239,7 @@ * ... * 1.5.30 15 10530 15.so.15.30[.0] * ... - * 1.6.40 16 10640 16.so.16.40[.0] + * 1.6.43 16 10643 16.so.16.43[.0] * * Henceforth the source version will match the shared-library major and * minor numbers; the shared-library major version number will be used for @@ -255,9 +255,6 @@ * to the info_ptr or png_ptr members through png.h, and the compiled * application is loaded with a different version of the library. * - * DLLNUM will change each time there are forward or backward changes - * in binary compatibility (e.g., when a new feature is added). - * * See libpng.txt or libpng.3 for more information. The PNG specification * is available as a W3C Recommendation and as an ISO/IEC Standard; see * @@ -278,19 +275,21 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.40" -#define PNG_HEADER_VERSION_STRING " libpng version 1.6.40 - June 21, 2023\n" +#define PNG_LIBPNG_VER_STRING "1.6.43" +#define PNG_HEADER_VERSION_STRING " libpng version " PNG_LIBPNG_VER_STRING "\n" -#define PNG_LIBPNG_VER_SONUM 16 -#define PNG_LIBPNG_VER_DLLNUM 16 +/* The versions of shared library builds should stay in sync, going forward */ +#define PNG_LIBPNG_VER_SHAREDLIB 16 +#define PNG_LIBPNG_VER_SONUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ +#define PNG_LIBPNG_VER_DLLNUM PNG_LIBPNG_VER_SHAREDLIB /* [Deprecated] */ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 40 +#define PNG_LIBPNG_VER_RELEASE 43 /* This should be zero for a public release, or non-zero for a - * development version. [Deprecated] + * development version. */ #define PNG_LIBPNG_VER_BUILD 0 @@ -318,7 +317,7 @@ * From version 1.0.1 it is: * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10640 /* 1.6.40 */ +#define PNG_LIBPNG_VER 10643 /* 1.6.43 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -428,7 +427,7 @@ extern "C" { /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_40; +typedef char* png_libpng_version_1_6_43; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * @@ -849,7 +848,7 @@ PNG_FUNCTION(void, (PNGCAPI *png_longjmp_ptr), PNGARG((jmp_buf, int)), typedef); #define PNG_TRANSFORM_GRAY_TO_RGB 0x2000 /* read only */ /* Added to libpng-1.5.4 */ #define PNG_TRANSFORM_EXPAND_16 0x4000 /* read only */ -#if INT_MAX >= 0x8000 /* else this might break */ +#if ~0U > 0xffffU /* or else this might break on a 16-bit machine */ #define PNG_TRANSFORM_SCALE_16 0x8000 /* read only */ #endif @@ -908,15 +907,15 @@ PNG_EXPORT(2, void, png_set_sig_bytes, (png_structrp png_ptr, int num_bytes)); /* Check sig[start] through sig[start + num_to_check - 1] to see if it's a * PNG file. Returns zero if the supplied bytes match the 8-byte PNG * signature, and non-zero otherwise. Having num_to_check == 0 or - * start > 7 will always fail (ie return non-zero). + * start > 7 will always fail (i.e. return non-zero). */ PNG_EXPORT(3, int, png_sig_cmp, (png_const_bytep sig, size_t start, size_t num_to_check)); /* Simple signature checking function. This is the same as calling - * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n). + * png_check_sig(sig, n) := (png_sig_cmp(sig, 0, n) == 0). */ -#define png_check_sig(sig, n) !png_sig_cmp((sig), 0, (n)) +#define png_check_sig(sig, n) (png_sig_cmp((sig), 0, (n)) == 0) /* DEPRECATED */ /* Allocate and initialize png_ptr struct for reading, and any other memory. */ PNG_EXPORTA(4, png_structp, png_create_read_struct, @@ -1730,12 +1729,9 @@ PNG_EXPORT(97, void, png_free, (png_const_structrp png_ptr, png_voidp ptr)); PNG_EXPORT(98, void, png_free_data, (png_const_structrp png_ptr, png_inforp info_ptr, png_uint_32 free_me, int num)); -/* Reassign responsibility for freeing existing data, whether allocated +/* Reassign the responsibility for freeing existing data, whether allocated * by libpng or by the application; this works on the png_info structure passed - * in, it does not change the state for other png_info structures. - * - * It is unlikely that this function works correctly as of 1.6.0 and using it - * may result either in memory leaks or double free of allocated data. + * in, without changing the state for other png_info structures. */ PNG_EXPORT(99, void, png_data_freer, (png_const_structrp png_ptr, png_inforp info_ptr, int freer, png_uint_32 mask)); @@ -3207,11 +3203,18 @@ PNG_EXPORT(245, int, png_image_write_to_memory, (png_imagep image, void *memory, #ifdef PNG_MIPS_MSA_API_SUPPORTED # define PNG_MIPS_MSA 6 /* HARDWARE: MIPS Msa SIMD instructions supported */ #endif -#define PNG_IGNORE_ADLER32 8 -#ifdef PNG_POWERPC_VSX_API_SUPPORTED -# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions supported */ +#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED +# define PNG_IGNORE_ADLER32 8 /* SOFTWARE: disable Adler32 check on IDAT */ #endif -#define PNG_OPTION_NEXT 12 /* Next option - numbers must be even */ +#ifdef PNG_POWERPC_VSX_API_SUPPORTED +# define PNG_POWERPC_VSX 10 /* HARDWARE: PowerPC VSX SIMD instructions + * supported */ +#endif +#ifdef PNG_MIPS_MMI_API_SUPPORTED +# define PNG_MIPS_MMI 12 /* HARDWARE: MIPS MMI SIMD instructions supported */ +#endif + +#define PNG_OPTION_NEXT 14 /* Next option - numbers must be even */ /* Return values: NOTE: there are four values and 'off' is *not* zero */ #define PNG_OPTION_UNSET 0 /* Unset - defaults to off */ diff --git a/src/3rdparty/libpng/pngconf.h b/src/3rdparty/libpng/pngconf.h index 6671e3c3356..000d7b1a8a6 100644 --- a/src/3rdparty/libpng/pngconf.h +++ b/src/3rdparty/libpng/pngconf.h @@ -1,9 +1,9 @@ /* pngconf.h - machine-configurable file for libpng * - * libpng version 1.6.40 + * libpng version 1.6.43 * - * Copyright (c) 2018-2022 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. diff --git a/src/3rdparty/libpng/pngerror.c b/src/3rdparty/libpng/pngerror.c index ec3a709b9d2..29ebda79437 100644 --- a/src/3rdparty/libpng/pngerror.c +++ b/src/3rdparty/libpng/pngerror.c @@ -1,7 +1,7 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -255,7 +255,7 @@ void png_warning_parameter_unsigned(png_warning_parameters p, int number, int format, png_alloc_size_t value) { - char buffer[PNG_NUMBER_BUFFER_SIZE]; + char buffer[PNG_NUMBER_BUFFER_SIZE] = {0}; png_warning_parameter(p, number, PNG_FORMAT_NUMBER(buffer, format, value)); } @@ -265,7 +265,7 @@ png_warning_parameter_signed(png_warning_parameters p, int number, int format, { png_alloc_size_t u; png_charp str; - char buffer[PNG_NUMBER_BUFFER_SIZE]; + char buffer[PNG_NUMBER_BUFFER_SIZE] = {0}; /* Avoid overflow by doing the negate in a png_alloc_size_t: */ u = (png_alloc_size_t)value; @@ -858,7 +858,7 @@ png_get_error_ptr(png_const_structrp png_ptr) if (png_ptr == NULL) return NULL; - return ((png_voidp)png_ptr->error_ptr); + return (png_voidp)png_ptr->error_ptr; } @@ -933,31 +933,25 @@ png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) #endif int /* PRIVATE */ -png_safe_execute(png_imagep image_in, int (*function)(png_voidp), png_voidp arg) +png_safe_execute(png_imagep image, int (*function)(png_voidp), png_voidp arg) { - volatile png_imagep image = image_in; - volatile int result; - volatile png_voidp saved_error_buf; + png_voidp saved_error_buf = image->opaque->error_buf; jmp_buf safe_jmpbuf; + int result; - /* Safely execute function(arg) with png_error returning to this function. */ - saved_error_buf = image->opaque->error_buf; - result = setjmp(safe_jmpbuf) == 0; - - if (result != 0) + /* Safely execute function(arg), with png_error returning back here. */ + if (setjmp(safe_jmpbuf) == 0) { - image->opaque->error_buf = safe_jmpbuf; result = function(arg); + image->opaque->error_buf = saved_error_buf; + return result; } + /* On png_error, return via longjmp, pop the jmpbuf, and free the image. */ image->opaque->error_buf = saved_error_buf; - - /* And do the cleanup prior to any failure return. */ - if (result == 0) - png_image_free(image); - - return result; + png_image_free(image); + return 0; } #endif /* SIMPLIFIED READ || SIMPLIFIED_WRITE */ #endif /* READ || WRITE */ diff --git a/src/3rdparty/libpng/pngget.c b/src/3rdparty/libpng/pngget.c index 1490a032e1a..1084b268ff9 100644 --- a/src/3rdparty/libpng/pngget.c +++ b/src/3rdparty/libpng/pngget.c @@ -1,7 +1,7 @@ /* pngget.c - retrieval of values from info struct * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -28,22 +28,22 @@ png_get_valid(png_const_structrp png_ptr, png_const_inforp info_ptr, * valid tRNS chunk in this case. */ if (flag == PNG_INFO_tRNS && png_ptr->num_trans == 0) - return(0); + return 0; #endif - return(info_ptr->valid & flag); + return info_ptr->valid & flag; } - return(0); + return 0; } size_t PNGAPI png_get_rowbytes(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->rowbytes); + return info_ptr->rowbytes; - return(0); + return 0; } #ifdef PNG_INFO_IMAGE_SUPPORTED @@ -51,9 +51,9 @@ png_bytepp PNGAPI png_get_rows(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->row_pointers); + return info_ptr->row_pointers; - return(0); + return 0; } #endif @@ -65,7 +65,7 @@ png_get_image_width(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->width; - return (0); + return 0; } png_uint_32 PNGAPI @@ -74,7 +74,7 @@ png_get_image_height(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->height; - return (0); + return 0; } png_byte PNGAPI @@ -83,7 +83,7 @@ png_get_bit_depth(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->bit_depth; - return (0); + return 0; } png_byte PNGAPI @@ -92,7 +92,7 @@ png_get_color_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->color_type; - return (0); + return 0; } png_byte PNGAPI @@ -101,7 +101,7 @@ png_get_filter_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->filter_type; - return (0); + return 0; } png_byte PNGAPI @@ -110,7 +110,7 @@ png_get_interlace_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->interlace_type; - return (0); + return 0; } png_byte PNGAPI @@ -119,7 +119,7 @@ png_get_compression_type(png_const_structrp png_ptr, png_const_inforp info_ptr) if (png_ptr != NULL && info_ptr != NULL) return info_ptr->compression_type; - return (0); + return 0; } png_uint_32 PNGAPI @@ -127,21 +127,20 @@ png_get_x_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_x_pixels_per_meter"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) - { - png_debug1(1, "in %s retrieval function", - "png_get_x_pixels_per_meter"); - - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->x_pixels_per_unit); - } + { + if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) + return info_ptr->x_pixels_per_unit; + } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_uint_32 PNGAPI @@ -149,42 +148,41 @@ png_get_y_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_y_pixels_per_meter"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", - "png_get_y_pixels_per_meter"); - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER) - return (info_ptr->y_pixels_per_unit); + return info_ptr->y_pixels_per_unit; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_uint_32 PNGAPI png_get_pixels_per_meter(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_pHYs_SUPPORTED + png_debug(1, "in png_get_pixels_per_meter"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_pixels_per_meter"); - if (info_ptr->phys_unit_type == PNG_RESOLUTION_METER && info_ptr->x_pixels_per_unit == info_ptr->y_pixels_per_unit) - return (info_ptr->x_pixels_per_unit); + return info_ptr->x_pixels_per_unit; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } #ifdef PNG_FLOATING_POINT_SUPPORTED @@ -193,21 +191,21 @@ png_get_pixel_aspect_ratio(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_READ_pHYs_SUPPORTED + png_debug(1, "in png_get_pixel_aspect_ratio"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio"); - if (info_ptr->x_pixels_per_unit != 0) - return ((float)((float)info_ptr->y_pixels_per_unit - /(float)info_ptr->x_pixels_per_unit)); + return (float)info_ptr->y_pixels_per_unit + / (float)info_ptr->x_pixels_per_unit; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return ((float)0.0); + return (float)0.0; } #endif @@ -217,6 +215,8 @@ png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_READ_pHYs_SUPPORTED + png_debug(1, "in png_get_pixel_aspect_ratio_fixed"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0 && info_ptr->x_pixels_per_unit > 0 && info_ptr->y_pixels_per_unit > 0 && @@ -225,8 +225,6 @@ png_get_pixel_aspect_ratio_fixed(png_const_structrp png_ptr, { png_fixed_point res; - png_debug1(1, "in %s retrieval function", "png_get_aspect_ratio_fixed"); - /* The following casts work because a PNG 4 byte integer only has a valid * range of 0..2^31-1; otherwise the cast might overflow. */ @@ -247,80 +245,80 @@ png_int_32 PNGAPI png_get_x_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_x_offset_microns"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_microns"); - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->x_offset); + return info_ptr->x_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_int_32 PNGAPI png_get_y_offset_microns(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_y_offset_microns"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_microns"); - if (info_ptr->offset_unit_type == PNG_OFFSET_MICROMETER) - return (info_ptr->y_offset); + return info_ptr->y_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_int_32 PNGAPI png_get_x_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_x_offset_pixels"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_x_offset_pixels"); - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->x_offset); + return info_ptr->x_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } png_int_32 PNGAPI png_get_y_offset_pixels(png_const_structrp png_ptr, png_const_inforp info_ptr) { #ifdef PNG_oFFs_SUPPORTED + png_debug(1, "in png_get_y_offset_pixels"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs) != 0) { - png_debug1(1, "in %s retrieval function", "png_get_y_offset_pixels"); - if (info_ptr->offset_unit_type == PNG_OFFSET_PIXEL) - return (info_ptr->y_offset); + return info_ptr->y_offset; } #else PNG_UNUSED(png_ptr) PNG_UNUSED(info_ptr) #endif - return (0); + return 0; } #ifdef PNG_INCH_CONVERSIONS_SUPPORTED @@ -434,11 +432,11 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, { png_uint_32 retval = 0; + png_debug1(1, "in %s retrieval function", "pHYs"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs) != 0) { - png_debug1(1, "in %s retrieval function", "pHYs"); - if (res_x != NULL) { *res_x = info_ptr->x_pixels_per_unit; @@ -464,7 +462,7 @@ png_get_pHYs_dpi(png_const_structrp png_ptr, png_const_inforp info_ptr, } } - return (retval); + return retval; } #endif /* pHYs */ #endif /* INCH_CONVERSIONS */ @@ -478,9 +476,9 @@ png_byte PNGAPI png_get_channels(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->channels); + return info_ptr->channels; - return (0); + return 0; } #ifdef PNG_READ_SUPPORTED @@ -488,9 +486,9 @@ png_const_bytep PNGAPI png_get_signature(png_const_structrp png_ptr, png_const_inforp info_ptr) { if (png_ptr != NULL && info_ptr != NULL) - return(info_ptr->signature); + return info_ptr->signature; - return (NULL); + return NULL; } #endif @@ -499,17 +497,17 @@ png_uint_32 PNGAPI png_get_bKGD(png_const_structrp png_ptr, png_inforp info_ptr, png_color_16p *background) { + png_debug1(1, "in %s retrieval function", "bKGD"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD) != 0 && background != NULL) { - png_debug1(1, "in %s retrieval function", "bKGD"); - *background = &(info_ptr->background); - return (PNG_INFO_bKGD); + return PNG_INFO_bKGD; } - return (0); + return 0; } #endif @@ -524,6 +522,8 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, double *white_x, double *white_y, double *red_x, double *red_y, double *green_x, double *green_y, double *blue_x, double *blue_y) { + png_debug1(1, "in %s retrieval function", "cHRM"); + /* Quiet API change: this code used to only return the end points if a cHRM * chunk was present, but the end points can also come from iCCP or sRGB * chunks, so in 1.6.0 the png_get_ APIs return the end points regardless and @@ -533,8 +533,6 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, if (png_ptr != NULL && info_ptr != NULL && (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) { - png_debug1(1, "in %s retrieval function", "cHRM"); - if (white_x != NULL) *white_x = png_float(png_ptr, info_ptr->colorspace.end_points_xy.whitex, "cHRM white X"); @@ -559,10 +557,10 @@ png_get_cHRM(png_const_structrp png_ptr, png_const_inforp info_ptr, if (blue_y != NULL) *blue_y = png_float(png_ptr, info_ptr->colorspace.end_points_xy.bluey, "cHRM blue Y"); - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } png_uint_32 PNGAPI @@ -571,11 +569,11 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, double *green_Y, double *green_Z, double *blue_X, double *blue_Y, double *blue_Z) { + png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) { - png_debug1(1, "in %s retrieval function", "cHRM_XYZ(float)"); - if (red_X != NULL) *red_X = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.red_X, "cHRM red X"); @@ -603,10 +601,10 @@ png_get_cHRM_XYZ(png_const_structrp png_ptr, png_const_inforp info_ptr, if (blue_Z != NULL) *blue_Z = png_float(png_ptr, info_ptr->colorspace.end_points_XYZ.blue_Z, "cHRM blue Z"); - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } # endif @@ -619,11 +617,11 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, png_fixed_point *int_blue_X, png_fixed_point *int_blue_Y, png_fixed_point *int_blue_Z) { + png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->colorspace.flags & PNG_COLORSPACE_HAVE_ENDPOINTS) != 0) { - png_debug1(1, "in %s retrieval function", "cHRM_XYZ"); - if (int_red_X != NULL) *int_red_X = info_ptr->colorspace.end_points_XYZ.red_X; if (int_red_Y != NULL) @@ -642,10 +640,10 @@ png_get_cHRM_XYZ_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, *int_blue_Y = info_ptr->colorspace.end_points_XYZ.blue_Y; if (int_blue_Z != NULL) *int_blue_Z = info_ptr->colorspace.end_points_XYZ.blue_Z; - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } png_uint_32 PNGAPI @@ -675,10 +673,10 @@ png_get_cHRM_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, *blue_x = info_ptr->colorspace.end_points_xy.bluex; if (blue_y != NULL) *blue_y = info_ptr->colorspace.end_points_xy.bluey; - return (PNG_INFO_cHRM); + return PNG_INFO_cHRM; } - return (0); + return 0; } # endif #endif @@ -696,10 +694,10 @@ png_get_gAMA_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, file_gamma != NULL) { *file_gamma = info_ptr->colorspace.gamma; - return (PNG_INFO_gAMA); + return PNG_INFO_gAMA; } - return (0); + return 0; } # endif @@ -716,10 +714,10 @@ png_get_gAMA(png_const_structrp png_ptr, png_const_inforp info_ptr, { *file_gamma = png_float(png_ptr, info_ptr->colorspace.gamma, "png_get_gAMA"); - return (PNG_INFO_gAMA); + return PNG_INFO_gAMA; } - return (0); + return 0; } # endif #endif @@ -735,10 +733,10 @@ png_get_sRGB(png_const_structrp png_ptr, png_const_inforp info_ptr, (info_ptr->valid & PNG_INFO_sRGB) != 0 && file_srgb_intent != NULL) { *file_srgb_intent = info_ptr->colorspace.rendering_intent; - return (PNG_INFO_sRGB); + return PNG_INFO_sRGB; } - return (0); + return 0; } #endif @@ -762,10 +760,10 @@ png_get_iCCP(png_const_structrp png_ptr, png_inforp info_ptr, */ if (compression_type != NULL) *compression_type = PNG_COMPRESSION_TYPE_BASE; - return (PNG_INFO_iCCP); + return PNG_INFO_iCCP; } - return (0); + return 0; } #endif @@ -775,13 +773,15 @@ int PNGAPI png_get_sPLT(png_const_structrp png_ptr, png_inforp info_ptr, png_sPLT_tpp spalettes) { + png_debug1(1, "in %s retrieval function", "sPLT"); + if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL) { *spalettes = info_ptr->splt_palettes; return info_ptr->splt_palettes_num; } - return (0); + return 0; } #endif @@ -807,10 +807,10 @@ png_get_eXIf_1(png_const_structrp png_ptr, png_const_inforp info_ptr, { *num_exif = info_ptr->num_exif; *exif = info_ptr->exif; - return (PNG_INFO_eXIf); + return PNG_INFO_eXIf; } - return (0); + return 0; } #endif @@ -825,10 +825,10 @@ png_get_hIST(png_const_structrp png_ptr, png_inforp info_ptr, (info_ptr->valid & PNG_INFO_hIST) != 0 && hist != NULL) { *hist = info_ptr->hist; - return (PNG_INFO_hIST); + return PNG_INFO_hIST; } - return (0); + return 0; } #endif @@ -841,7 +841,7 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, png_debug1(1, "in %s retrieval function", "IHDR"); if (png_ptr == NULL || info_ptr == NULL) - return (0); + return 0; if (width != NULL) *width = info_ptr->width; @@ -873,7 +873,7 @@ png_get_IHDR(png_const_structrp png_ptr, png_const_inforp info_ptr, info_ptr->bit_depth, info_ptr->color_type, info_ptr->interlace_type, info_ptr->compression_type, info_ptr->filter_type); - return (1); + return 1; } #ifdef PNG_oFFs_SUPPORTED @@ -890,10 +890,10 @@ png_get_oFFs(png_const_structrp png_ptr, png_const_inforp info_ptr, *offset_x = info_ptr->x_offset; *offset_y = info_ptr->y_offset; *unit_type = (int)info_ptr->offset_unit_type; - return (PNG_INFO_oFFs); + return PNG_INFO_oFFs; } - return (0); + return 0; } #endif @@ -917,10 +917,10 @@ png_get_pCAL(png_const_structrp png_ptr, png_inforp info_ptr, *nparams = (int)info_ptr->pcal_nparams; *units = info_ptr->pcal_units; *params = info_ptr->pcal_params; - return (PNG_INFO_pCAL); + return PNG_INFO_pCAL; } - return (0); + return 0; } #endif @@ -932,6 +932,8 @@ png_uint_32 PNGAPI png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, png_fixed_point *width, png_fixed_point *height) { + png_debug1(1, "in %s retrieval function", "sCAL"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) { @@ -943,10 +945,10 @@ png_get_sCAL_fixed(png_const_structrp png_ptr, png_const_inforp info_ptr, *width = png_fixed(png_ptr, atof(info_ptr->scal_s_width), "sCAL width"); *height = png_fixed(png_ptr, atof(info_ptr->scal_s_height), "sCAL height"); - return (PNG_INFO_sCAL); + return PNG_INFO_sCAL; } - return(0); + return 0; } # endif /* FLOATING_ARITHMETIC */ # endif /* FIXED_POINT */ @@ -955,32 +957,36 @@ png_uint_32 PNGAPI png_get_sCAL(png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, double *width, double *height) { + png_debug1(1, "in %s retrieval function", "sCAL(float)"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) { *unit = info_ptr->scal_unit; *width = atof(info_ptr->scal_s_width); *height = atof(info_ptr->scal_s_height); - return (PNG_INFO_sCAL); + return PNG_INFO_sCAL; } - return(0); + return 0; } # endif /* FLOATING POINT */ png_uint_32 PNGAPI png_get_sCAL_s(png_const_structrp png_ptr, png_const_inforp info_ptr, int *unit, png_charpp width, png_charpp height) { + png_debug1(1, "in %s retrieval function", "sCAL(str)"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL) != 0) { *unit = info_ptr->scal_unit; *width = info_ptr->scal_s_width; *height = info_ptr->scal_s_height; - return (PNG_INFO_sCAL); + return PNG_INFO_sCAL; } - return(0); + return 0; } #endif /* sCAL */ @@ -1015,7 +1021,7 @@ png_get_pHYs(png_const_structrp png_ptr, png_const_inforp info_ptr, } } - return (retval); + return retval; } #endif /* pHYs */ @@ -1031,10 +1037,10 @@ png_get_PLTE(png_const_structrp png_ptr, png_inforp info_ptr, *palette = info_ptr->palette; *num_palette = info_ptr->num_palette; png_debug1(3, "num_palette = %d", *num_palette); - return (PNG_INFO_PLTE); + return PNG_INFO_PLTE; } - return (0); + return 0; } #ifdef PNG_sBIT_SUPPORTED @@ -1048,10 +1054,10 @@ png_get_sBIT(png_const_structrp png_ptr, png_inforp info_ptr, (info_ptr->valid & PNG_INFO_sBIT) != 0 && sig_bit != NULL) { *sig_bit = &(info_ptr->sig_bit); - return (PNG_INFO_sBIT); + return PNG_INFO_sBIT; } - return (0); + return 0; } #endif @@ -1062,7 +1068,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, { if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0) { - png_debug1(1, "in 0x%lx retrieval function", + png_debug1(1, "in text retrieval function, chunk typeid = 0x%lx", (unsigned long)png_ptr->chunk_name); if (text_ptr != NULL) @@ -1077,7 +1083,7 @@ png_get_text(png_const_structrp png_ptr, png_inforp info_ptr, if (num_text != NULL) *num_text = 0; - return(0); + return 0; } #endif @@ -1092,10 +1098,10 @@ png_get_tIME(png_const_structrp png_ptr, png_inforp info_ptr, (info_ptr->valid & PNG_INFO_tIME) != 0 && mod_time != NULL) { *mod_time = &(info_ptr->mod_time); - return (PNG_INFO_tIME); + return PNG_INFO_tIME; } - return (0); + return 0; } #endif @@ -1105,11 +1111,12 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, png_bytep *trans_alpha, int *num_trans, png_color_16p *trans_color) { png_uint_32 retval = 0; + + png_debug1(1, "in %s retrieval function", "tRNS"); + if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS) != 0) { - png_debug1(1, "in %s retrieval function", "tRNS"); - if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (trans_alpha != NULL) @@ -1141,7 +1148,7 @@ png_get_tRNS(png_const_structrp png_ptr, png_inforp info_ptr, } } - return (retval); + return retval; } #endif @@ -1156,7 +1163,7 @@ png_get_unknown_chunks(png_const_structrp png_ptr, png_inforp info_ptr, return info_ptr->unknown_chunks_num; } - return (0); + return 0; } #endif @@ -1252,7 +1259,7 @@ png_get_palette_max(png_const_structp png_ptr, png_const_infop info_ptr) if (png_ptr != NULL && info_ptr != NULL) return png_ptr->num_palette_max; - return (-1); + return -1; } # endif #endif diff --git a/src/3rdparty/libpng/pnglibconf.h b/src/3rdparty/libpng/pnglibconf.h index c7033ae176f..83f09fbe773 100644 --- a/src/3rdparty/libpng/pnglibconf.h +++ b/src/3rdparty/libpng/pnglibconf.h @@ -1,8 +1,8 @@ /* pnglibconf.h - library build configuration */ -/* libpng version 1.6.40 */ +/* libpng version 1.6.43 */ -/* Copyright (c) 2018-2023 Cosmin Truta */ +/* Copyright (c) 2018-2024 Cosmin Truta */ /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */ /* This code is released under the libpng license. */ @@ -27,6 +27,7 @@ #define PNG_COLORSPACE_SUPPORTED #define PNG_CONSOLE_IO_SUPPORTED #define PNG_CONVERT_tIME_SUPPORTED +/*#undef PNG_DISABLE_ADLER32_CHECK_SUPPORTED*/ #define PNG_EASY_ACCESS_SUPPORTED /*#undef PNG_ERROR_NUMBERS_SUPPORTED*/ #define PNG_ERROR_TEXT_SUPPORTED @@ -41,6 +42,10 @@ #define PNG_INCH_CONVERSIONS_SUPPORTED #define PNG_INFO_IMAGE_SUPPORTED #define PNG_IO_STATE_SUPPORTED +/*#undef PNG_MIPS_MMI_API_SUPPORTED*/ +/*#undef PNG_MIPS_MMI_CHECK_SUPPORTED*/ +/*#undef PNG_MIPS_MSA_API_SUPPORTED*/ +/*#undef PNG_MIPS_MSA_CHECK_SUPPORTED*/ #define PNG_MNG_FEATURES_SUPPORTED #define PNG_POINTER_INDEXING_SUPPORTED /*#undef PNG_POWERPC_VSX_API_SUPPORTED*/ diff --git a/src/3rdparty/libpng/pngpread.c b/src/3rdparty/libpng/pngpread.c index e283627b77c..ffab19c08c0 100644 --- a/src/3rdparty/libpng/pngpread.c +++ b/src/3rdparty/libpng/pngpread.c @@ -1,7 +1,7 @@ /* pngpread.c - read a png file in push mode * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -145,10 +145,10 @@ png_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) num_to_check); png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); - if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) + if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) { if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0) png_error(png_ptr, "Not a PNG file"); else @@ -294,6 +294,14 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); } +#endif +#ifdef PNG_READ_eXIf_SUPPORTED + else if (png_ptr->chunk_name == png_eXIf) + { + PNG_PUSH_SAVE_BUFFER_IF_FULL + png_handle_eXIf(png_ptr, info_ptr, png_ptr->push_length); + } + #endif #ifdef PNG_READ_sRGB_SUPPORTED else if (chunk_name == png_sRGB) @@ -1089,7 +1097,7 @@ png_voidp PNGAPI png_get_progressive_ptr(png_const_structrp png_ptr) { if (png_ptr == NULL) - return (NULL); + return NULL; return png_ptr->io_ptr; } diff --git a/src/3rdparty/libpng/pngpriv.h b/src/3rdparty/libpng/pngpriv.h index 7c19373f0b8..9bfdb713421 100644 --- a/src/3rdparty/libpng/pngpriv.h +++ b/src/3rdparty/libpng/pngpriv.h @@ -1,7 +1,7 @@ /* pngpriv.h - private declarations for use inside libpng * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -36,7 +36,7 @@ * still required (as of 2011-05-02.) */ #ifndef _POSIX_SOURCE -# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ +# define _POSIX_SOURCE 1 /* Just the POSIX 1003.1 and C89 APIs */ #endif #ifndef PNG_VERSION_INFO_ONLY @@ -190,13 +190,27 @@ #endif /* PNG_ARM_NEON_OPT > 0 */ #ifndef PNG_MIPS_MSA_OPT -# if defined(__mips_msa) && (__mips_isa_rev >= 5) && defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# if defined(__mips_msa) && (__mips_isa_rev >= 5) && \ + defined(PNG_ALIGNED_MEMORY_SUPPORTED) # define PNG_MIPS_MSA_OPT 2 # else # define PNG_MIPS_MSA_OPT 0 # endif #endif +#ifndef PNG_MIPS_MMI_OPT +# ifdef PNG_MIPS_MMI +# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) && \ + defined(PNG_ALIGNED_MEMORY_SUPPORTED) +# define PNG_MIPS_MMI_OPT 1 +# else +# define PNG_MIPS_MMI_OPT 0 +# endif +# else +# define PNG_MIPS_MMI_OPT 0 +# endif +#endif + #ifndef PNG_POWERPC_VSX_OPT # if defined(__PPC64__) && defined(__ALTIVEC__) && defined(__VSX__) # define PNG_POWERPC_VSX_OPT 2 @@ -205,13 +219,21 @@ # endif #endif +#ifndef PNG_LOONGARCH_LSX_OPT +# if defined(__loongarch_sx) +# define PNG_LOONGARCH_LSX_OPT 1 +# else +# define PNG_LOONGARCH_LSX_OPT 0 +# endif +#endif + #ifndef PNG_INTEL_SSE_OPT # ifdef PNG_INTEL_SSE /* Only check for SSE if the build configuration has been modified to * enable SSE optimizations. This means that these optimizations will * be off by default. See contrib/intel for more details. */ -# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \ +# if defined(__SSE4_1__) || defined(__AVX__) || defined(__SSSE3__) || \ defined(__SSE2__) || defined(_M_X64) || defined(_M_AMD64) || \ (defined(_M_IX86_FP) && _M_IX86_FP >= 2) # define PNG_INTEL_SSE_OPT 1 @@ -248,7 +270,6 @@ #endif #if PNG_MIPS_MSA_OPT > 0 -# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_msa # ifndef PNG_MIPS_MSA_IMPLEMENTATION # if defined(__mips_msa) # if defined(__clang__) @@ -264,11 +285,28 @@ # ifndef PNG_MIPS_MSA_IMPLEMENTATION # define PNG_MIPS_MSA_IMPLEMENTATION 1 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips # endif #else # define PNG_MIPS_MSA_IMPLEMENTATION 0 #endif /* PNG_MIPS_MSA_OPT > 0 */ +#if PNG_MIPS_MMI_OPT > 0 +# ifndef PNG_MIPS_MMI_IMPLEMENTATION +# if defined(__mips_loongson_mmi) && (_MIPS_SIM == _ABI64) +# define PNG_MIPS_MMI_IMPLEMENTATION 2 +# else /* !defined __mips_loongson_mmi || _MIPS_SIM != _ABI64 */ +# define PNG_MIPS_MMI_IMPLEMENTATION 0 +# endif /* __mips_loongson_mmi && _MIPS_SIM == _ABI64 */ +# endif /* !PNG_MIPS_MMI_IMPLEMENTATION */ + +# if PNG_MIPS_MMI_IMPLEMENTATION > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_mips +# endif +#else +# define PNG_MIPS_MMI_IMPLEMENTATION 0 +#endif /* PNG_MIPS_MMI_OPT > 0 */ + #if PNG_POWERPC_VSX_OPT > 0 # define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_vsx # define PNG_POWERPC_VSX_IMPLEMENTATION 1 @@ -276,6 +314,12 @@ # define PNG_POWERPC_VSX_IMPLEMENTATION 0 #endif +#if PNG_LOONGARCH_LSX_OPT > 0 +# define PNG_FILTER_OPTIMIZATIONS png_init_filter_functions_lsx +# define PNG_LOONGARCH_LSX_IMPLEMENTATION 1 +#else +# define PNG_LOONGARCH_LSX_IMPLEMENTATION 0 +#endif /* Is this a build of a DLL where compilation of the object modules requires * different preprocessor settings to those required for a simple library? If @@ -514,18 +558,8 @@ */ # include -# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ - defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) - /* We need to check that hasn't already been included earlier - * as it seems it doesn't agree with , yet we should really use - * if possible. - */ -# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__) -# include -# endif -# else -# include -# endif +# include + # if defined(_AMIGA) && defined(__SASC) && defined(_M68881) /* Amiga SAS/C: We must include builtin FPU functions when compiling using * MATH=68881 @@ -1306,7 +1340,7 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); #endif -#if PNG_MIPS_MSA_OPT > 0 +#if PNG_MIPS_MSA_IMPLEMENTATION == 1 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_msa,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_msa,(png_row_infop @@ -1323,6 +1357,23 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_msa,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); #endif +#if PNG_MIPS_MMI_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_mmi,(png_row_infop row_info, + png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_mmi,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif + #if PNG_POWERPC_VSX_OPT > 0 PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_vsx,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); @@ -1355,6 +1406,23 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_sse2,(png_row_infop row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); #endif +#if PNG_LOONGARCH_LSX_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_up_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub3_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_sub4_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg3_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_avg4_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth3_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_lsx,(png_row_infop + row_info, png_bytep row, png_const_bytep prev_row),PNG_EMPTY); +#endif + /* Choose the best filter to use and filter the row data */ PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr, png_row_infop row_info),PNG_EMPTY); @@ -2094,17 +2162,27 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_neon, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); #endif -#if PNG_MIPS_MSA_OPT > 0 -PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_msa, +#if PNG_MIPS_MSA_IMPLEMENTATION == 1 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); #endif +# if PNG_MIPS_MMI_IMPLEMENTATION > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_mips, + (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +# endif + # if PNG_INTEL_SSE_IMPLEMENTATION > 0 PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2, (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); # endif #endif +#if PNG_LOONGARCH_LSX_OPT > 0 +PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_lsx, + (png_structp png_ptr, unsigned int bpp), PNG_EMPTY); +#endif + PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, png_const_charp key, png_bytep new_key), PNG_EMPTY); diff --git a/src/3rdparty/libpng/pngread.c b/src/3rdparty/libpng/pngread.c index 96996ced5ba..07a39df6e2e 100644 --- a/src/3rdparty/libpng/pngread.c +++ b/src/3rdparty/libpng/pngread.c @@ -1,7 +1,7 @@ /* pngread.c - read a PNG file * - * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -568,7 +568,11 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row) #endif #ifdef PNG_READ_TRANSFORMS_SUPPORTED - if (png_ptr->transformations) + if (png_ptr->transformations +# ifdef PNG_CHECK_FOR_INVALID_INDEX_SUPPORTED + || png_ptr->num_palette_max >= 0 +# endif + ) png_do_read_transformations(png_ptr, &row_info); #endif @@ -785,7 +789,7 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr) #ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED /* Report invalid palette index; added at libng-1.5.10 */ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - png_ptr->num_palette_max > png_ptr->num_palette) + png_ptr->num_palette_max >= png_ptr->num_palette) png_benign_error(png_ptr, "Read palette index exceeding num_palette"); #endif @@ -1049,6 +1053,8 @@ void PNGAPI png_read_png(png_structrp png_ptr, png_inforp info_ptr, int transforms, voidp params) { + png_debug(1, "in png_read_png"); + if (png_ptr == NULL || info_ptr == NULL) return; diff --git a/src/3rdparty/libpng/pngrtran.c b/src/3rdparty/libpng/pngrtran.c index 238f5afe7e8..1526123e025 100644 --- a/src/3rdparty/libpng/pngrtran.c +++ b/src/3rdparty/libpng/pngrtran.c @@ -1,7 +1,7 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -290,21 +290,20 @@ png_set_alpha_mode_fixed(png_structrp png_ptr, int mode, int compose = 0; png_fixed_point file_gamma; - png_debug(1, "in png_set_alpha_mode"); + png_debug(1, "in png_set_alpha_mode_fixed"); if (png_rtran_ok(png_ptr, 0) == 0) return; output_gamma = translate_gamma_flags(png_ptr, output_gamma, 1/*screen*/); - /* Validate the value to ensure it is in a reasonable range. The value + /* Validate the value to ensure it is in a reasonable range. The value * is expected to be 1 or greater, but this range test allows for some - * viewing correction values. The intent is to weed out users of this API - * who use the inverse of the gamma value accidentally! Since some of these - * values are reasonable this may have to be changed: + * viewing correction values. The intent is to weed out the API users + * who might use the inverse of the gamma value accidentally! * - * 1.6.x: changed from 0.07..3 to 0.01..100 (to accommodate the optimal 16-bit - * gamma of 36, and its reciprocal.) + * In libpng 1.6.0, we changed from 0.07..3 to 0.01..100, to accommodate + * the optimal 16-bit gamma of 36 and its reciprocal. */ if (output_gamma < 1000 || output_gamma > 10000000) png_error(png_ptr, "output gamma out of expected range"); @@ -441,7 +440,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, int i; png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); for (i = 0; i < num_palette; i++) png_ptr->quantize_index[i] = (png_byte)i; } @@ -458,7 +457,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, /* Initialize an array to sort colors */ png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); /* Initialize the quantize_sort array */ for (i = 0; i < num_palette; i++) @@ -592,11 +591,9 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, /* Initialize palette index arrays */ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * - (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr, - (png_alloc_size_t)((png_uint_32)num_palette * - (sizeof (png_byte)))); + (png_alloc_size_t)num_palette); /* Initialize the sort array */ for (i = 0; i < num_palette; i++) @@ -761,12 +758,11 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette, size_t num_entries = ((size_t)1 << total_bits); png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr, - (png_alloc_size_t)(num_entries * (sizeof (png_byte)))); + (png_alloc_size_t)(num_entries)); - distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries * - (sizeof (png_byte)))); + distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)num_entries); - memset(distance, 0xff, num_entries * (sizeof (png_byte))); + memset(distance, 0xff, num_entries); for (i = 0; i < num_palette; i++) { @@ -970,7 +966,7 @@ void PNGFAPI png_set_rgb_to_gray_fixed(png_structrp png_ptr, int error_action, png_fixed_point red, png_fixed_point green) { - png_debug(1, "in png_set_rgb_to_gray"); + png_debug(1, "in png_set_rgb_to_gray_fixed"); /* Need the IHDR here because of the check on color_type below. */ /* TODO: fix this */ diff --git a/src/3rdparty/libpng/pngrutil.c b/src/3rdparty/libpng/pngrutil.c index 068ab193a33..d31dc21dae8 100644 --- a/src/3rdparty/libpng/pngrutil.c +++ b/src/3rdparty/libpng/pngrutil.c @@ -1,7 +1,7 @@ /* pngrutil.c - utilities to read a PNG file * - * Copyright (c) 2018-2022 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -26,7 +26,7 @@ png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf) if (uval > PNG_UINT_31_MAX) png_error(png_ptr, "PNG unsigned integer out of range"); - return (uval); + return uval; } #if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_READ_cHRM_SUPPORTED) @@ -140,7 +140,7 @@ png_read_sig(png_structrp png_ptr, png_inforp info_ptr) if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check) != 0) { if (num_checked < 4 && - png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) + png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4) != 0) png_error(png_ptr, "Not a PNG file"); else png_error(png_ptr, "PNG file corrupted by ASCII conversion"); @@ -171,7 +171,7 @@ png_read_chunk_header(png_structrp png_ptr) /* Put the chunk name into png_ptr->chunk_name. */ png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(buf+4); - png_debug2(0, "Reading %lx chunk, length = %lu", + png_debug2(0, "Reading chunk typeid = 0x%lx, length = %lu", (unsigned long)png_ptr->chunk_name, (unsigned long)length); /* Reset the crc and run it over the chunk name. */ @@ -238,10 +238,10 @@ png_crc_finish(png_structrp png_ptr, png_uint_32 skip) else png_chunk_error(png_ptr, "CRC error"); - return (1); + return 1; } - return (0); + return 0; } /* Compare the CRC stored in the PNG file with that calculated by libpng from @@ -277,11 +277,11 @@ png_crc_error(png_structrp png_ptr) if (need_crc != 0) { crc = png_get_uint_32(crc_bytes); - return ((int)(crc != png_ptr->crc)); + return crc != png_ptr->crc; } else - return (0); + return 0; } #if defined(PNG_READ_iCCP_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) ||\ @@ -421,8 +421,7 @@ png_inflate_claim(png_structrp png_ptr, png_uint_32 owner) png_ptr->flags |= PNG_FLAG_ZSTREAM_INITIALIZED; } -#if ZLIB_VERNUM >= 0x1290 && \ - defined(PNG_SET_OPTION_SUPPORTED) && defined(PNG_IGNORE_ADLER32) +#ifdef PNG_DISABLE_ADLER32_CHECK_SUPPORTED if (((png_ptr->options >> PNG_IGNORE_ADLER32) & 3) == PNG_OPTION_ON) /* Turn off validation of the ADLER32 checksum in IDAT chunks */ ret = inflateValidate(&png_ptr->zstream, 0); diff --git a/src/3rdparty/libpng/pngset.c b/src/3rdparty/libpng/pngset.c index 3fc31feb0cb..eb1c8c7a35a 100644 --- a/src/3rdparty/libpng/pngset.c +++ b/src/3rdparty/libpng/pngset.c @@ -1,7 +1,7 @@ /* pngset.c - storage of image information into info struct * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -763,11 +763,11 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, { int i; - png_debug1(1, "in %lx storage function", png_ptr == NULL ? 0xabadca11U : - (unsigned long)png_ptr->chunk_name); + png_debug1(1, "in text storage function, chunk typeid = 0x%lx", + png_ptr == NULL ? 0xabadca11UL : (unsigned long)png_ptr->chunk_name); if (png_ptr == NULL || info_ptr == NULL || num_text <= 0 || text_ptr == NULL) - return(0); + return 0; /* Make sure we have enough space in the "text" array in info_struct * to hold all of the incoming text_ptr objects. This compare can't overflow @@ -947,7 +947,7 @@ png_set_text_2(png_const_structrp png_ptr, png_inforp info_ptr, png_debug1(3, "transferred text chunk %d", info_ptr->num_text); } - return(0); + return 0; } #endif @@ -1063,6 +1063,8 @@ png_set_sPLT(png_const_structrp png_ptr, { png_sPLT_tp np; + png_debug1(1, "in %s storage function", "sPLT"); + if (png_ptr == NULL || info_ptr == NULL || nentries <= 0 || entries == NULL) return; @@ -1537,7 +1539,7 @@ void PNGAPI png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, png_bytepp row_pointers) { - png_debug1(1, "in %s storage function", "rows"); + png_debug(1, "in png_set_rows"); if (png_ptr == NULL || info_ptr == NULL) return; @@ -1556,6 +1558,8 @@ png_set_rows(png_const_structrp png_ptr, png_inforp info_ptr, void PNGAPI png_set_compression_buffer_size(png_structrp png_ptr, size_t size) { + png_debug(1, "in png_set_compression_buffer_size"); + if (png_ptr == NULL) return; @@ -1627,6 +1631,8 @@ void PNGAPI png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max, png_uint_32 user_height_max) { + png_debug(1, "in png_set_user_limits"); + /* Images with dimensions larger than these limits will be * rejected by png_set_IHDR(). To accept any PNG datastream * regardless of dimensions, set both limits to 0x7fffffff. @@ -1642,6 +1648,8 @@ png_set_user_limits(png_structrp png_ptr, png_uint_32 user_width_max, void PNGAPI png_set_chunk_cache_max(png_structrp png_ptr, png_uint_32 user_chunk_cache_max) { + png_debug(1, "in png_set_chunk_cache_max"); + if (png_ptr != NULL) png_ptr->user_chunk_cache_max = user_chunk_cache_max; } @@ -1651,6 +1659,8 @@ void PNGAPI png_set_chunk_malloc_max(png_structrp png_ptr, png_alloc_size_t user_chunk_malloc_max) { + png_debug(1, "in png_set_chunk_malloc_max"); + if (png_ptr != NULL) png_ptr->user_chunk_malloc_max = user_chunk_malloc_max; } diff --git a/src/3rdparty/libpng/pngtrans.c b/src/3rdparty/libpng/pngtrans.c index 1100f46ebec..62cb21edf1f 100644 --- a/src/3rdparty/libpng/pngtrans.c +++ b/src/3rdparty/libpng/pngtrans.c @@ -1,7 +1,7 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * Copyright (c) 2018 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -103,10 +103,10 @@ png_set_interlace_handling(png_structrp png_ptr) if (png_ptr != 0 && png_ptr->interlaced != 0) { png_ptr->transformations |= PNG_INTERLACE; - return (7); + return 7; } - return (1); + return 1; } #endif @@ -498,6 +498,8 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start) png_bytep dp = row; /* destination pointer */ png_bytep ep = row + row_info->rowbytes; /* One beyond end of row */ + png_debug(1, "in png_do_strip_channel"); + /* At the start sp will point to the first byte to copy and dp to where * it is copied to. ep always points just beyond the end of the row, so * the loop simply copies (channels-1) channels until sp reaches ep. @@ -698,6 +700,8 @@ png_do_bgr(png_row_infop row_info, png_bytep row) void /* PRIVATE */ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) { + png_debug(1, "in png_do_check_palette_indexes"); + if (png_ptr->num_palette < (1 << row_info->bit_depth) && png_ptr->num_palette > 0) /* num_palette can be 0 in MNG files */ { @@ -708,7 +712,7 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info) * forms produced on either GCC or MSVC. */ int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width); - png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1; + png_bytep rp = png_ptr->row_buf + row_info->rowbytes; switch (row_info->bit_depth) { @@ -833,7 +837,7 @@ png_voidp PNGAPI png_get_user_transform_ptr(png_const_structrp png_ptr) { if (png_ptr == NULL) - return (NULL); + return NULL; return png_ptr->user_transform_ptr; } diff --git a/src/3rdparty/libpng/pngwrite.c b/src/3rdparty/libpng/pngwrite.c index 32f4bfbe7df..77e412f43d5 100644 --- a/src/3rdparty/libpng/pngwrite.c +++ b/src/3rdparty/libpng/pngwrite.c @@ -1,7 +1,7 @@ /* pngwrite.c - general routines to write a PNG file * - * Copyright (c) 2018-2023 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -369,7 +369,8 @@ png_write_end(png_structrp png_ptr, png_inforp info_ptr) png_error(png_ptr, "No IDATs written into file"); #ifdef PNG_WRITE_CHECK_FOR_INVALID_INDEX_SUPPORTED - if (png_ptr->num_palette_max > png_ptr->num_palette) + if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && + png_ptr->num_palette_max >= png_ptr->num_palette) png_benign_error(png_ptr, "Wrote palette index exceeding num_palette"); #endif @@ -714,12 +715,12 @@ png_write_row(png_structrp png_ptr, png_const_bytep row) /* 1.5.6: moved from png_struct to be a local structure: */ png_row_info row_info; - if (png_ptr == NULL) - return; - png_debug2(1, "in png_write_row (row %u, pass %d)", png_ptr->row_number, png_ptr->pass); + if (png_ptr == NULL) + return; + /* Initialize transformations and other stuff if first time */ if (png_ptr->row_number == 0 && png_ptr->pass == 0) { @@ -1210,6 +1211,8 @@ png_set_compression_strategy(png_structrp png_ptr, int strategy) void PNGAPI png_set_compression_window_bits(png_structrp png_ptr, int window_bits) { + png_debug(1, "in png_set_compression_window_bits"); + if (png_ptr == NULL) return; @@ -1293,6 +1296,8 @@ png_set_text_compression_strategy(png_structrp png_ptr, int strategy) void PNGAPI png_set_text_compression_window_bits(png_structrp png_ptr, int window_bits) { + png_debug(1, "in png_set_text_compression_window_bits"); + if (png_ptr == NULL) return; @@ -1330,6 +1335,8 @@ png_set_text_compression_method(png_structrp png_ptr, int method) void PNGAPI png_set_write_status_fn(png_structrp png_ptr, png_write_status_ptr write_row_fn) { + png_debug(1, "in png_set_write_status_fn"); + if (png_ptr == NULL) return; @@ -1357,6 +1364,8 @@ void PNGAPI png_write_png(png_structrp png_ptr, png_inforp info_ptr, int transforms, voidp params) { + png_debug(1, "in png_write_png"); + if (png_ptr == NULL || info_ptr == NULL) return; diff --git a/src/3rdparty/libpng/pngwutil.c b/src/3rdparty/libpng/pngwutil.c index 01f0607c709..14cc4ce367f 100644 --- a/src/3rdparty/libpng/pngwutil.c +++ b/src/3rdparty/libpng/pngwutil.c @@ -1,7 +1,7 @@ /* pngwutil.c - utilities to write a PNG file * - * Copyright (c) 2018-2022 Cosmin Truta + * Copyright (c) 2018-2024 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson * Copyright (c) 1996-1997 Andreas Dilger * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. @@ -2311,7 +2311,7 @@ png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp, break; } - return (sum); + return sum; } static void /* PRIVATE */ @@ -2361,7 +2361,7 @@ png_setup_up_row(png_structrp png_ptr, size_t row_bytes, size_t lmins) break; } - return (sum); + return sum; } static void /* PRIVATE */ png_setup_up_row_only(png_structrp png_ptr, size_t row_bytes) @@ -2417,7 +2417,7 @@ png_setup_avg_row(png_structrp png_ptr, png_uint_32 bpp, break; } - return (sum); + return sum; } static void /* PRIVATE */ png_setup_avg_row_only(png_structrp png_ptr, png_uint_32 bpp, @@ -2500,7 +2500,7 @@ png_setup_paeth_row(png_structrp png_ptr, png_uint_32 bpp, break; } - return (sum); + return sum; } static void /* PRIVATE */ png_setup_paeth_row_only(png_structrp png_ptr, png_uint_32 bpp, diff --git a/src/3rdparty/libpng/qt_attribution.json b/src/3rdparty/libpng/qt_attribution.json index cf5aae3824d..7ba436e3bd1 100644 --- a/src/3rdparty/libpng/qt_attribution.json +++ b/src/3rdparty/libpng/qt_attribution.json @@ -6,13 +6,13 @@ "Description": "libpng is the official PNG reference library.", "Homepage": "http://www.libpng.org/pub/png/libpng.html", - "Version": "1.6.40", - "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.40.tar.xz", + "Version": "1.6.43", + "DownloadLocation": "https://download.sourceforge.net/libpng/libpng-1.6.43.tar.xz", "License": "libpng License and PNG Reference Library version 2", "LicenseId": "Libpng AND libpng-2.0", "LicenseFile": "LICENSE", - "Copyright": "Copyright (c) 1995-2023 The PNG Reference Library Authors -Copyright (c) 2000-2023 Cosmin Truta + "Copyright": "Copyright (c) 1995-2024 The PNG Reference Library Authors +Copyright (c) 2000-2024 Cosmin Truta Copyright (c) 1998-2018 Glenn Randers-Pehrson Copyright (c) 1996-1997 Andreas Dilger Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. diff --git a/src/3rdparty/md4c/0001-md4c-Fix-MSVC-compiler-level-3-warnings.patch b/src/3rdparty/md4c/0001-md4c-Fix-MSVC-compiler-level-3-warnings.patch deleted file mode 100644 index 5f2cf8401b6..00000000000 --- a/src/3rdparty/md4c/0001-md4c-Fix-MSVC-compiler-level-3-warnings.patch +++ /dev/null @@ -1,40 +0,0 @@ -diff --git a/src/3rdparty/md4c/md4c.c b/src/3rdparty/md4c/md4c.c -index 6aeef112e5..9d0d1b7d7b 100644 ---- a/src/3rdparty/md4c/md4c.c -+++ b/src/3rdparty/md4c/md4c.c -@@ -916,7 +916,7 @@ md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines, - } - - if(off >= end) { -- *p_size = ptr - buffer; -+ *p_size = (MD_SIZE)(ptr - buffer); - return; - } - -@@ -2229,7 +2229,7 @@ md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, int n_lines, - - if(beg_line != end_line) { - MD_CHECK(md_merge_lines_alloc(ctx, beg, end, beg_line, -- n_lines - (beg_line - lines), _T(' '), &label, &label_size)); -+ (int)(n_lines - (beg_line - lines)), _T(' '), &label, &label_size)); - } else { - label = (CHAR*) STR(beg); - label_size = end - beg; -@@ -4265,7 +4265,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) - MD_CHECK(md_enter_leave_span_a(ctx, (mark->ch != ']'), - (opener->ch == '!' ? MD_SPAN_IMG : MD_SPAN_A), - STR(dest_mark->beg), dest_mark->end - dest_mark->beg, FALSE, -- md_mark_get_ptr(ctx, title_mark - ctx->marks), title_mark->prev)); -+ md_mark_get_ptr(ctx, (int)(title_mark - ctx->marks)), title_mark->prev)); - - /* link/image closer may span multiple lines. */ - if(mark->ch == ']') { -@@ -4908,7 +4908,7 @@ md_push_block_bytes(MD_CTX* ctx, int n_bytes) - - /* Fix the ->current_block after the reallocation. */ - if(ctx->current_block != NULL) { -- OFF off_current_block = (char*) ctx->current_block - (char*) ctx->block_bytes; -+ OFF off_current_block = (OFF)((char*) ctx->current_block - (char*) ctx->block_bytes); - ctx->current_block = (MD_BLOCK*) ((char*) new_block_bytes + off_current_block); - } - diff --git a/src/3rdparty/md4c/LICENSE.md b/src/3rdparty/md4c/LICENSE.md index 2088ba453e3..c80b3a95ced 100644 --- a/src/3rdparty/md4c/LICENSE.md +++ b/src/3rdparty/md4c/LICENSE.md @@ -1,7 +1,7 @@ # The MIT License (MIT) -Copyright © 2016-2020 Martin Mitáš +Copyright © 2016-2024 Martin Mitáš Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), diff --git a/src/3rdparty/md4c/md4c.c b/src/3rdparty/md4c/md4c.c index 9d0d1b7d7b0..812bde53585 100644 --- a/src/3rdparty/md4c/md4c.c +++ b/src/3rdparty/md4c/md4c.c @@ -2,7 +2,7 @@ * MD4C: Markdown parser for C * (http://github.com/mity/md4c) * - * Copyright (c) 2016-2020 Martin Mitas + * Copyright (c) 2016-2024 Martin Mitáš * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -67,6 +67,9 @@ #define STRINGIZE_(x) #x #define STRINGIZE(x) STRINGIZE_(x) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + #ifndef TRUE #define TRUE 1 #define FALSE 0 @@ -115,6 +118,22 @@ #define MD_UNUSED(x) ((void)x) +/****************************** + *** Some internal limits *** + ******************************/ + +/* We limit code span marks to lower than 32 backticks. This solves the + * pathologic case of too many openers, each of different length: Their + * resolving would be then O(n^2). */ +#define CODESPAN_MARK_MAXLEN 32 + +/* We limit column count of tables to prevent quadratic explosion of output + * from pathological input of a table thousands of columns and thousands + * of rows where rows are requested with as little as single character + * per-line, relying on us to "helpfully" fill all the missing "". */ +#define TABLE_MAXCOLCOUNT 128 + + /************************ *** Internal Types *** ************************/ @@ -130,14 +149,13 @@ typedef struct MD_CONTAINER_tag MD_CONTAINER; typedef struct MD_REF_DEF_tag MD_REF_DEF; -/* During analyzes of inline marks, we need to manage some "mark chains", - * of (yet unresolved) openers. This structure holds start/end of the chain. - * The chain internals are then realized through MD_MARK::prev and ::next. +/* During analyzes of inline marks, we need to manage stacks of unresolved + * openers of the given type. + * The stack connects the marks via MD_MARK::next; */ -typedef struct MD_MARKCHAIN_tag MD_MARKCHAIN; -struct MD_MARKCHAIN_tag { - int head; /* Index of first mark in the chain, or -1 if empty. */ - int tail; /* Index of last mark in the chain, or -1 if empty. */ +typedef struct MD_MARKSTACK_tag MD_MARKSTACK; +struct MD_MARKSTACK_tag { + int top; /* -1 if empty. */ }; /* Context propagated through all the parsing. */ @@ -178,24 +196,33 @@ struct MD_CTX_tag { #endif /* For resolving of inline spans. */ - MD_MARKCHAIN mark_chains[13]; -#define PTR_CHAIN (ctx->mark_chains[0]) -#define TABLECELLBOUNDARIES (ctx->mark_chains[1]) -#define ASTERISK_OPENERS_extraword_mod3_0 (ctx->mark_chains[2]) -#define ASTERISK_OPENERS_extraword_mod3_1 (ctx->mark_chains[3]) -#define ASTERISK_OPENERS_extraword_mod3_2 (ctx->mark_chains[4]) -#define ASTERISK_OPENERS_intraword_mod3_0 (ctx->mark_chains[5]) -#define ASTERISK_OPENERS_intraword_mod3_1 (ctx->mark_chains[6]) -#define ASTERISK_OPENERS_intraword_mod3_2 (ctx->mark_chains[7]) -#define UNDERSCORE_OPENERS (ctx->mark_chains[8]) -#define TILDE_OPENERS_1 (ctx->mark_chains[9]) -#define TILDE_OPENERS_2 (ctx->mark_chains[10]) -#define BRACKET_OPENERS (ctx->mark_chains[11]) -#define DOLLAR_OPENERS (ctx->mark_chains[12]) -#define OPENERS_CHAIN_FIRST 2 -#define OPENERS_CHAIN_LAST 12 + MD_MARKSTACK opener_stacks[16]; +#define ASTERISK_OPENERS_oo_mod3_0 (ctx->opener_stacks[0]) /* Opener-only */ +#define ASTERISK_OPENERS_oo_mod3_1 (ctx->opener_stacks[1]) +#define ASTERISK_OPENERS_oo_mod3_2 (ctx->opener_stacks[2]) +#define ASTERISK_OPENERS_oc_mod3_0 (ctx->opener_stacks[3]) /* Both opener and closer candidate */ +#define ASTERISK_OPENERS_oc_mod3_1 (ctx->opener_stacks[4]) +#define ASTERISK_OPENERS_oc_mod3_2 (ctx->opener_stacks[5]) +#define UNDERSCORE_OPENERS_oo_mod3_0 (ctx->opener_stacks[6]) /* Opener-only */ +#define UNDERSCORE_OPENERS_oo_mod3_1 (ctx->opener_stacks[7]) +#define UNDERSCORE_OPENERS_oo_mod3_2 (ctx->opener_stacks[8]) +#define UNDERSCORE_OPENERS_oc_mod3_0 (ctx->opener_stacks[9]) /* Both opener and closer candidate */ +#define UNDERSCORE_OPENERS_oc_mod3_1 (ctx->opener_stacks[10]) +#define UNDERSCORE_OPENERS_oc_mod3_2 (ctx->opener_stacks[11]) +#define TILDE_OPENERS_1 (ctx->opener_stacks[12]) +#define TILDE_OPENERS_2 (ctx->opener_stacks[13]) +#define BRACKET_OPENERS (ctx->opener_stacks[14]) +#define DOLLAR_OPENERS (ctx->opener_stacks[15]) + /* Stack of dummies which need to call free() for pointers stored in them. + * These are constructed during inline parsing and freed after all the block + * is processed (i.e. all callbacks referring those strings are called). */ + MD_MARKSTACK ptr_stack; + + /* For resolving table rows. */ int n_table_cell_boundaries; + int table_cell_boundaries_head; + int table_cell_boundaries_tail; /* For resolving links. */ int unresolved_link_head; @@ -251,8 +278,9 @@ typedef enum MD_LINETYPE_tag MD_LINETYPE; typedef struct MD_LINE_ANALYSIS_tag MD_LINE_ANALYSIS; struct MD_LINE_ANALYSIS_tag { - MD_LINETYPE type : 16; - unsigned data : 16; + MD_LINETYPE type; + unsigned data; + int enforce_new_block; OFF beg; OFF end; unsigned indent; /* Indentation level. */ @@ -465,6 +493,40 @@ md_text_with_null_replacement(MD_CTX* ctx, MD_TEXTTYPE type, const CHAR* str, SZ } while(0) +/* If the offset falls into a gap between line, we return the following + * line. */ +static const MD_LINE* +md_lookup_line(OFF off, const MD_LINE* lines, MD_SIZE n_lines, MD_SIZE* p_line_index) +{ + MD_SIZE lo, hi; + MD_SIZE pivot; + const MD_LINE* line; + + lo = 0; + hi = n_lines - 1; + while(lo <= hi) { + pivot = (lo + hi) / 2; + line = &lines[pivot]; + + if(off < line->beg) { + if(hi == 0 || lines[hi-1].end < off) { + if(p_line_index != NULL) + *p_line_index = pivot; + return line; + } + hi = pivot - 1; + } else if(off > line->end) { + lo = pivot + 1; + } else { + if(p_line_index != NULL) + *p_line_index = pivot; + return line; + } + } + + return NULL; +} + /************************* *** Unicode Support *** @@ -537,39 +599,67 @@ struct MD_UNICODE_FOLD_INFO_tag { { #define R(cp_min, cp_max) ((cp_min) | 0x40000000), ((cp_max) | 0x80000000) #define S(cp) (cp) - /* Unicode "Pc", "Pd", "Pe", "Pf", "Pi", "Po", "Ps" categories. + /* Unicode general "P" and "S" categories. * (generated by scripts/build_punct_map.py) */ static const unsigned PUNCT_MAP[] = { - R(0x0021,0x0023), R(0x0025,0x002a), R(0x002c,0x002f), R(0x003a,0x003b), R(0x003f,0x0040), - R(0x005b,0x005d), S(0x005f), S(0x007b), S(0x007d), S(0x00a1), S(0x00a7), S(0x00ab), R(0x00b6,0x00b7), - S(0x00bb), S(0x00bf), S(0x037e), S(0x0387), R(0x055a,0x055f), R(0x0589,0x058a), S(0x05be), S(0x05c0), - S(0x05c3), S(0x05c6), R(0x05f3,0x05f4), R(0x0609,0x060a), R(0x060c,0x060d), S(0x061b), R(0x061e,0x061f), - R(0x066a,0x066d), S(0x06d4), R(0x0700,0x070d), R(0x07f7,0x07f9), R(0x0830,0x083e), S(0x085e), - R(0x0964,0x0965), S(0x0970), S(0x09fd), S(0x0a76), S(0x0af0), S(0x0c77), S(0x0c84), S(0x0df4), S(0x0e4f), - R(0x0e5a,0x0e5b), R(0x0f04,0x0f12), S(0x0f14), R(0x0f3a,0x0f3d), S(0x0f85), R(0x0fd0,0x0fd4), - R(0x0fd9,0x0fda), R(0x104a,0x104f), S(0x10fb), R(0x1360,0x1368), S(0x1400), S(0x166e), R(0x169b,0x169c), - R(0x16eb,0x16ed), R(0x1735,0x1736), R(0x17d4,0x17d6), R(0x17d8,0x17da), R(0x1800,0x180a), - R(0x1944,0x1945), R(0x1a1e,0x1a1f), R(0x1aa0,0x1aa6), R(0x1aa8,0x1aad), R(0x1b5a,0x1b60), - R(0x1bfc,0x1bff), R(0x1c3b,0x1c3f), R(0x1c7e,0x1c7f), R(0x1cc0,0x1cc7), S(0x1cd3), R(0x2010,0x2027), - R(0x2030,0x2043), R(0x2045,0x2051), R(0x2053,0x205e), R(0x207d,0x207e), R(0x208d,0x208e), - R(0x2308,0x230b), R(0x2329,0x232a), R(0x2768,0x2775), R(0x27c5,0x27c6), R(0x27e6,0x27ef), - R(0x2983,0x2998), R(0x29d8,0x29db), R(0x29fc,0x29fd), R(0x2cf9,0x2cfc), R(0x2cfe,0x2cff), S(0x2d70), - R(0x2e00,0x2e2e), R(0x2e30,0x2e4f), S(0x2e52), R(0x3001,0x3003), R(0x3008,0x3011), R(0x3014,0x301f), - S(0x3030), S(0x303d), S(0x30a0), S(0x30fb), R(0xa4fe,0xa4ff), R(0xa60d,0xa60f), S(0xa673), S(0xa67e), - R(0xa6f2,0xa6f7), R(0xa874,0xa877), R(0xa8ce,0xa8cf), R(0xa8f8,0xa8fa), S(0xa8fc), R(0xa92e,0xa92f), - S(0xa95f), R(0xa9c1,0xa9cd), R(0xa9de,0xa9df), R(0xaa5c,0xaa5f), R(0xaade,0xaadf), R(0xaaf0,0xaaf1), - S(0xabeb), R(0xfd3e,0xfd3f), R(0xfe10,0xfe19), R(0xfe30,0xfe52), R(0xfe54,0xfe61), S(0xfe63), S(0xfe68), - R(0xfe6a,0xfe6b), R(0xff01,0xff03), R(0xff05,0xff0a), R(0xff0c,0xff0f), R(0xff1a,0xff1b), - R(0xff1f,0xff20), R(0xff3b,0xff3d), S(0xff3f), S(0xff5b), S(0xff5d), R(0xff5f,0xff65), R(0x10100,0x10102), - S(0x1039f), S(0x103d0), S(0x1056f), S(0x10857), S(0x1091f), S(0x1093f), R(0x10a50,0x10a58), S(0x10a7f), - R(0x10af0,0x10af6), R(0x10b39,0x10b3f), R(0x10b99,0x10b9c), S(0x10ead), R(0x10f55,0x10f59), - R(0x11047,0x1104d), R(0x110bb,0x110bc), R(0x110be,0x110c1), R(0x11140,0x11143), R(0x11174,0x11175), - R(0x111c5,0x111c8), S(0x111cd), S(0x111db), R(0x111dd,0x111df), R(0x11238,0x1123d), S(0x112a9), - R(0x1144b,0x1144f), R(0x1145a,0x1145b), S(0x1145d), S(0x114c6), R(0x115c1,0x115d7), R(0x11641,0x11643), - R(0x11660,0x1166c), R(0x1173c,0x1173e), S(0x1183b), R(0x11944,0x11946), S(0x119e2), R(0x11a3f,0x11a46), - R(0x11a9a,0x11a9c), R(0x11a9e,0x11aa2), R(0x11c41,0x11c45), R(0x11c70,0x11c71), R(0x11ef7,0x11ef8), - S(0x11fff), R(0x12470,0x12474), R(0x16a6e,0x16a6f), S(0x16af5), R(0x16b37,0x16b3b), S(0x16b44), - R(0x16e97,0x16e9a), S(0x16fe2), S(0x1bc9f), R(0x1da87,0x1da8b), R(0x1e95e,0x1e95f) + R(0x0021,0x002f), R(0x003a,0x0040), R(0x005b,0x0060), R(0x007b,0x007e), R(0x00a1,0x00a9), + R(0x00ab,0x00ac), R(0x00ae,0x00b1), S(0x00b4), R(0x00b6,0x00b8), S(0x00bb), S(0x00bf), S(0x00d7), + S(0x00f7), R(0x02c2,0x02c5), R(0x02d2,0x02df), R(0x02e5,0x02eb), S(0x02ed), R(0x02ef,0x02ff), S(0x0375), + S(0x037e), R(0x0384,0x0385), S(0x0387), S(0x03f6), S(0x0482), R(0x055a,0x055f), R(0x0589,0x058a), + R(0x058d,0x058f), S(0x05be), S(0x05c0), S(0x05c3), S(0x05c6), R(0x05f3,0x05f4), R(0x0606,0x060f), + S(0x061b), R(0x061d,0x061f), R(0x066a,0x066d), S(0x06d4), S(0x06de), S(0x06e9), R(0x06fd,0x06fe), + R(0x0700,0x070d), R(0x07f6,0x07f9), R(0x07fe,0x07ff), R(0x0830,0x083e), S(0x085e), S(0x0888), + R(0x0964,0x0965), S(0x0970), R(0x09f2,0x09f3), R(0x09fa,0x09fb), S(0x09fd), S(0x0a76), R(0x0af0,0x0af1), + S(0x0b70), R(0x0bf3,0x0bfa), S(0x0c77), S(0x0c7f), S(0x0c84), S(0x0d4f), S(0x0d79), S(0x0df4), S(0x0e3f), + S(0x0e4f), R(0x0e5a,0x0e5b), R(0x0f01,0x0f17), R(0x0f1a,0x0f1f), S(0x0f34), S(0x0f36), S(0x0f38), + R(0x0f3a,0x0f3d), S(0x0f85), R(0x0fbe,0x0fc5), R(0x0fc7,0x0fcc), R(0x0fce,0x0fda), R(0x104a,0x104f), + R(0x109e,0x109f), S(0x10fb), R(0x1360,0x1368), R(0x1390,0x1399), S(0x1400), R(0x166d,0x166e), + R(0x169b,0x169c), R(0x16eb,0x16ed), R(0x1735,0x1736), R(0x17d4,0x17d6), R(0x17d8,0x17db), + R(0x1800,0x180a), S(0x1940), R(0x1944,0x1945), R(0x19de,0x19ff), R(0x1a1e,0x1a1f), R(0x1aa0,0x1aa6), + R(0x1aa8,0x1aad), R(0x1b5a,0x1b6a), R(0x1b74,0x1b7e), R(0x1bfc,0x1bff), R(0x1c3b,0x1c3f), + R(0x1c7e,0x1c7f), R(0x1cc0,0x1cc7), S(0x1cd3), S(0x1fbd), R(0x1fbf,0x1fc1), R(0x1fcd,0x1fcf), + R(0x1fdd,0x1fdf), R(0x1fed,0x1fef), R(0x1ffd,0x1ffe), R(0x2010,0x2027), R(0x2030,0x205e), + R(0x207a,0x207e), R(0x208a,0x208e), R(0x20a0,0x20c0), R(0x2100,0x2101), R(0x2103,0x2106), + R(0x2108,0x2109), S(0x2114), R(0x2116,0x2118), R(0x211e,0x2123), S(0x2125), S(0x2127), S(0x2129), + S(0x212e), R(0x213a,0x213b), R(0x2140,0x2144), R(0x214a,0x214d), S(0x214f), R(0x218a,0x218b), + R(0x2190,0x2426), R(0x2440,0x244a), R(0x249c,0x24e9), R(0x2500,0x2775), R(0x2794,0x2b73), + R(0x2b76,0x2b95), R(0x2b97,0x2bff), R(0x2ce5,0x2cea), R(0x2cf9,0x2cfc), R(0x2cfe,0x2cff), S(0x2d70), + R(0x2e00,0x2e2e), R(0x2e30,0x2e5d), R(0x2e80,0x2e99), R(0x2e9b,0x2ef3), R(0x2f00,0x2fd5), + R(0x2ff0,0x2fff), R(0x3001,0x3004), R(0x3008,0x3020), S(0x3030), R(0x3036,0x3037), R(0x303d,0x303f), + R(0x309b,0x309c), S(0x30a0), S(0x30fb), R(0x3190,0x3191), R(0x3196,0x319f), R(0x31c0,0x31e3), S(0x31ef), + R(0x3200,0x321e), R(0x322a,0x3247), S(0x3250), R(0x3260,0x327f), R(0x328a,0x32b0), R(0x32c0,0x33ff), + R(0x4dc0,0x4dff), R(0xa490,0xa4c6), R(0xa4fe,0xa4ff), R(0xa60d,0xa60f), S(0xa673), S(0xa67e), + R(0xa6f2,0xa6f7), R(0xa700,0xa716), R(0xa720,0xa721), R(0xa789,0xa78a), R(0xa828,0xa82b), + R(0xa836,0xa839), R(0xa874,0xa877), R(0xa8ce,0xa8cf), R(0xa8f8,0xa8fa), S(0xa8fc), R(0xa92e,0xa92f), + S(0xa95f), R(0xa9c1,0xa9cd), R(0xa9de,0xa9df), R(0xaa5c,0xaa5f), R(0xaa77,0xaa79), R(0xaade,0xaadf), + R(0xaaf0,0xaaf1), S(0xab5b), R(0xab6a,0xab6b), S(0xabeb), S(0xfb29), R(0xfbb2,0xfbc2), R(0xfd3e,0xfd4f), + S(0xfdcf), R(0xfdfc,0xfdff), R(0xfe10,0xfe19), R(0xfe30,0xfe52), R(0xfe54,0xfe66), R(0xfe68,0xfe6b), + R(0xff01,0xff0f), R(0xff1a,0xff20), R(0xff3b,0xff40), R(0xff5b,0xff65), R(0xffe0,0xffe6), + R(0xffe8,0xffee), R(0xfffc,0xfffd), R(0x10100,0x10102), R(0x10137,0x1013f), R(0x10179,0x10189), + R(0x1018c,0x1018e), R(0x10190,0x1019c), S(0x101a0), R(0x101d0,0x101fc), S(0x1039f), S(0x103d0), + S(0x1056f), S(0x10857), R(0x10877,0x10878), S(0x1091f), S(0x1093f), R(0x10a50,0x10a58), S(0x10a7f), + S(0x10ac8), R(0x10af0,0x10af6), R(0x10b39,0x10b3f), R(0x10b99,0x10b9c), S(0x10ead), R(0x10f55,0x10f59), + R(0x10f86,0x10f89), R(0x11047,0x1104d), R(0x110bb,0x110bc), R(0x110be,0x110c1), R(0x11140,0x11143), + R(0x11174,0x11175), R(0x111c5,0x111c8), S(0x111cd), S(0x111db), R(0x111dd,0x111df), R(0x11238,0x1123d), + S(0x112a9), R(0x1144b,0x1144f), R(0x1145a,0x1145b), S(0x1145d), S(0x114c6), R(0x115c1,0x115d7), + R(0x11641,0x11643), R(0x11660,0x1166c), S(0x116b9), R(0x1173c,0x1173f), S(0x1183b), R(0x11944,0x11946), + S(0x119e2), R(0x11a3f,0x11a46), R(0x11a9a,0x11a9c), R(0x11a9e,0x11aa2), R(0x11b00,0x11b09), + R(0x11c41,0x11c45), R(0x11c70,0x11c71), R(0x11ef7,0x11ef8), R(0x11f43,0x11f4f), R(0x11fd5,0x11ff1), + S(0x11fff), R(0x12470,0x12474), R(0x12ff1,0x12ff2), R(0x16a6e,0x16a6f), S(0x16af5), R(0x16b37,0x16b3f), + R(0x16b44,0x16b45), R(0x16e97,0x16e9a), S(0x16fe2), S(0x1bc9c), S(0x1bc9f), R(0x1cf50,0x1cfc3), + R(0x1d000,0x1d0f5), R(0x1d100,0x1d126), R(0x1d129,0x1d164), R(0x1d16a,0x1d16c), R(0x1d183,0x1d184), + R(0x1d18c,0x1d1a9), R(0x1d1ae,0x1d1ea), R(0x1d200,0x1d241), S(0x1d245), R(0x1d300,0x1d356), S(0x1d6c1), + S(0x1d6db), S(0x1d6fb), S(0x1d715), S(0x1d735), S(0x1d74f), S(0x1d76f), S(0x1d789), S(0x1d7a9), + S(0x1d7c3), R(0x1d800,0x1d9ff), R(0x1da37,0x1da3a), R(0x1da6d,0x1da74), R(0x1da76,0x1da83), + R(0x1da85,0x1da8b), S(0x1e14f), S(0x1e2ff), R(0x1e95e,0x1e95f), S(0x1ecac), S(0x1ecb0), S(0x1ed2e), + R(0x1eef0,0x1eef1), R(0x1f000,0x1f02b), R(0x1f030,0x1f093), R(0x1f0a0,0x1f0ae), R(0x1f0b1,0x1f0bf), + R(0x1f0c1,0x1f0cf), R(0x1f0d1,0x1f0f5), R(0x1f10d,0x1f1ad), R(0x1f1e6,0x1f202), R(0x1f210,0x1f23b), + R(0x1f240,0x1f248), R(0x1f250,0x1f251), R(0x1f260,0x1f265), R(0x1f300,0x1f6d7), R(0x1f6dc,0x1f6ec), + R(0x1f6f0,0x1f6fc), R(0x1f700,0x1f776), R(0x1f77b,0x1f7d9), R(0x1f7e0,0x1f7eb), S(0x1f7f0), + R(0x1f800,0x1f80b), R(0x1f810,0x1f847), R(0x1f850,0x1f859), R(0x1f860,0x1f887), R(0x1f890,0x1f8ad), + R(0x1f8b0,0x1f8b1), R(0x1f900,0x1fa53), R(0x1fa60,0x1fa6d), R(0x1fa70,0x1fa7c), R(0x1fa80,0x1fa88), + R(0x1fa90,0x1fabd), R(0x1fabf,0x1fac5), R(0x1face,0x1fadb), R(0x1fae0,0x1fae8), R(0x1faf0,0x1faf8), + R(0x1fb00,0x1fb92), R(0x1fb94,0x1fbca) }; #undef R #undef S @@ -610,13 +700,14 @@ struct MD_UNICODE_FOLD_INFO_tag { R(0x1f68,0x1f6f), S(0x1fb8), S(0x1fb9), S(0x1fba), S(0x1fbb), S(0x1fbe), R(0x1fc8,0x1fcb), S(0x1fd8), S(0x1fd9), S(0x1fda), S(0x1fdb), S(0x1fe8), S(0x1fe9), S(0x1fea), S(0x1feb), S(0x1fec), S(0x1ff8), S(0x1ff9), S(0x1ffa), S(0x1ffb), S(0x2126), S(0x212a), S(0x212b), S(0x2132), R(0x2160,0x216f), S(0x2183), - R(0x24b6,0x24cf), R(0x2c00,0x2c2e), S(0x2c60), S(0x2c62), S(0x2c63), S(0x2c64), R(0x2c67,0x2c6b), + R(0x24b6,0x24cf), R(0x2c00,0x2c2f), S(0x2c60), S(0x2c62), S(0x2c63), S(0x2c64), R(0x2c67,0x2c6b), S(0x2c6d), S(0x2c6e), S(0x2c6f), S(0x2c70), S(0x2c72), S(0x2c75), S(0x2c7e), S(0x2c7f), R(0x2c80,0x2ce2), S(0x2ceb), S(0x2ced), S(0x2cf2), R(0xa640,0xa66c), R(0xa680,0xa69a), R(0xa722,0xa72e), R(0xa732,0xa76e), S(0xa779), S(0xa77b), S(0xa77d), R(0xa77e,0xa786), S(0xa78b), S(0xa78d), S(0xa790), S(0xa792), R(0xa796,0xa7a8), S(0xa7aa), S(0xa7ab), S(0xa7ac), S(0xa7ad), S(0xa7ae), S(0xa7b0), S(0xa7b1), S(0xa7b2), - S(0xa7b3), R(0xa7b4,0xa7be), S(0xa7c2), S(0xa7c4), S(0xa7c5), S(0xa7c6), S(0xa7c7), S(0xa7c9), S(0xa7f5), - R(0xab70,0xabbf), R(0xff21,0xff3a), R(0x10400,0x10427), R(0x104b0,0x104d3), R(0x10c80,0x10cb2), + S(0xa7b3), R(0xa7b4,0xa7c2), S(0xa7c4), S(0xa7c5), S(0xa7c6), S(0xa7c7), S(0xa7c9), S(0xa7d0), S(0xa7d6), + S(0xa7d8), S(0xa7f5), R(0xab70,0xabbf), R(0xff21,0xff3a), R(0x10400,0x10427), R(0x104b0,0x104d3), + R(0x10570,0x1057a), R(0x1057c,0x1058a), R(0x1058c,0x10592), S(0x10594), S(0x10595), R(0x10c80,0x10cb2), R(0x118a0,0x118bf), R(0x16e40,0x16e5f), R(0x1e900,0x1e921) }; static const unsigned FOLD_MAP_1_DATA[] = { @@ -635,13 +726,13 @@ struct MD_UNICODE_FOLD_INFO_tag { 0x1f10, 0x1f15, 0x1f20, 0x1f27, 0x1f30, 0x1f37, 0x1f40, 0x1f45, 0x1f51, 0x1f53, 0x1f55, 0x1f57, 0x1f60, 0x1f67, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x03b9, 0x1f72, 0x1f75, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x03c9, 0x006b, 0x00e5, 0x214e, 0x2170, - 0x217f, 0x2184, 0x24d0, 0x24e9, 0x2c30, 0x2c5e, 0x2c61, 0x026b, 0x1d7d, 0x027d, 0x2c68, 0x2c6c, 0x0251, + 0x217f, 0x2184, 0x24d0, 0x24e9, 0x2c30, 0x2c5f, 0x2c61, 0x026b, 0x1d7d, 0x027d, 0x2c68, 0x2c6c, 0x0251, 0x0271, 0x0250, 0x0252, 0x2c73, 0x2c76, 0x023f, 0x0240, 0x2c81, 0x2ce3, 0x2cec, 0x2cee, 0x2cf3, 0xa641, 0xa66d, 0xa681, 0xa69b, 0xa723, 0xa72f, 0xa733, 0xa76f, 0xa77a, 0xa77c, 0x1d79, 0xa77f, 0xa787, 0xa78c, 0x0265, 0xa791, 0xa793, 0xa797, 0xa7a9, 0x0266, 0x025c, 0x0261, 0x026c, 0x026a, 0x029e, 0x0287, 0x029d, - 0xab53, 0xa7b5, 0xa7bf, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8, 0xa7ca, 0xa7f6, 0x13a0, 0x13ef, 0xff41, - 0xff5a, 0x10428, 0x1044f, 0x104d8, 0x104fb, 0x10cc0, 0x10cf2, 0x118c0, 0x118df, 0x16e60, 0x16e7f, 0x1e922, - 0x1e943 + 0xab53, 0xa7b5, 0xa7c3, 0xa794, 0x0282, 0x1d8e, 0xa7c8, 0xa7ca, 0xa7d1, 0xa7d7, 0xa7d9, 0xa7f6, 0x13a0, + 0x13ef, 0xff41, 0xff5a, 0x10428, 0x1044f, 0x104d8, 0x104fb, 0x10597, 0x105a1, 0x105a3, 0x105b1, 0x105b3, + 0x105b9, 0x105bb, 0x105bc, 0x10cc0, 0x10cf2, 0x118c0, 0x118df, 0x16e60, 0x16e7f, 0x1e922, 0x1e943 }; static const unsigned FOLD_MAP_2[] = { S(0x00df), S(0x0130), S(0x0149), S(0x01f0), S(0x0587), S(0x1e96), S(0x1e97), S(0x1e98), S(0x1e99), @@ -894,7 +985,7 @@ struct MD_UNICODE_FOLD_INFO_tag { * what the caller should allocate.) */ static void -md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines, +md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines, CHAR line_break_replacement_char, CHAR* buffer, SZ* p_size) { CHAR* ptr = buffer; @@ -931,7 +1022,7 @@ md_merge_lines(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines, /* Wrapper of md_merge_lines() which allocates new buffer for the output string. */ static int -md_merge_lines_alloc(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, int n_lines, +md_merge_lines_alloc(MD_CTX* ctx, OFF beg, OFF end, const MD_LINE* lines, MD_SIZE n_lines, CHAR line_break_replacement_char, CHAR** p_str, SZ* p_size) { CHAR* buffer; @@ -978,12 +1069,12 @@ md_skip_unicode_whitespace(const CHAR* label, OFF off, SZ size) * by n_lines == 0. */ static int -md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { int attr_state; OFF off = beg; OFF line_end = (n_lines > 0) ? lines[0].end : ctx->size; - int i = 0; + MD_SIZE line_index = 0; MD_ASSERT(CH(beg) == _T('<')); @@ -1073,12 +1164,12 @@ md_is_html_tag(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_ if(n_lines == 0) return FALSE; - i++; - if(i >= n_lines) + line_index++; + if(line_index >= n_lines) return FALSE; - off = lines[i].beg; - line_end = lines[i].end; + off = lines[line_index].beg; + line_end = lines[line_index].end; if(attr_state == 0 || attr_state == 41) attr_state = 1; @@ -1097,12 +1188,12 @@ done: static int md_scan_for_html_closer(MD_CTX* ctx, const MD_CHAR* str, MD_SIZE len, - const MD_LINE* lines, int n_lines, + const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end, OFF* p_scan_horizon) { OFF off = beg; - int i = 0; + MD_SIZE line_index = 0; if(off < *p_scan_horizon && *p_scan_horizon >= max_end - len) { /* We have already scanned the range up to the max_end so we know @@ -1111,7 +1202,7 @@ md_scan_for_html_closer(MD_CTX* ctx, const MD_CHAR* str, MD_SIZE len, } while(TRUE) { - while(off + len <= lines[i].end && off + len <= max_end) { + while(off + len <= lines[line_index].end && off + len <= max_end) { if(md_ascii_eq(STR(off), str, len)) { /* Success. */ *p_end = off + len; @@ -1120,19 +1211,19 @@ md_scan_for_html_closer(MD_CTX* ctx, const MD_CHAR* str, MD_SIZE len, off++; } - i++; - if(off >= max_end || i >= n_lines) { + line_index++; + if(off >= max_end || line_index >= n_lines) { /* Failure. */ *p_scan_horizon = off; return FALSE; } - off = lines[i].beg; + off = lines[line_index].beg; } } static int -md_is_html_comment(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_comment(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { OFF off = beg; @@ -1142,30 +1233,17 @@ md_is_html_comment(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF return FALSE; if(CH(off+1) != _T('!') || CH(off+2) != _T('-') || CH(off+3) != _T('-')) return FALSE; - off += 4; - /* ">" and "->" must not follow the opening. */ - if(off < lines[0].end && CH(off) == _T('>')) - return FALSE; - if(off+1 < lines[0].end && CH(off) == _T('-') && CH(off+1) == _T('>')) - return FALSE; + /* Skip only "" or "" */ + off += 2; - /* HTML comment must not contain "--", so we scan just for "--" instead - * of "-->" and verify manually that '>' follows. */ - if(md_scan_for_html_closer(ctx, _T("--"), 2, - lines, n_lines, off, max_end, p_end, &ctx->html_comment_horizon)) - { - if(*p_end < max_end && CH(*p_end) == _T('>')) { - *p_end = *p_end + 1; - return TRUE; - } - } - - return FALSE; + /* Scan for ordinary comment closer "-->". */ + return md_scan_for_html_closer(ctx, _T("-->"), 3, + lines, n_lines, off, max_end, p_end, &ctx->html_comment_horizon); } static int -md_is_html_processing_instruction(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_processing_instruction(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { OFF off = beg; @@ -1180,7 +1258,7 @@ md_is_html_processing_instruction(MD_CTX* ctx, const MD_LINE* lines, int n_lines } static int -md_is_html_declaration(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_declaration(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { OFF off = beg; @@ -1196,15 +1274,13 @@ md_is_html_declaration(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, off++; while(off < lines[0].end && ISALPHA(off)) off++; - if(off < lines[0].end && !ISWHITESPACE(off)) - return FALSE; return md_scan_for_html_closer(ctx, _T(">"), 1, lines, n_lines, off, max_end, p_end, &ctx->html_decl_horizon); } static int -md_is_html_cdata(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_cdata(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { static const CHAR open_str[] = _T(""), 3, lines, n_lines, off, max_end, p_end, &ctx->html_cdata_horizon); } static int -md_is_html_any(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, OFF max_end, OFF* p_end) +md_is_html_any(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF max_end, OFF* p_end) { MD_ASSERT(CH(beg) == _T('<')); return (md_is_html_tag(ctx, lines, n_lines, beg, max_end, p_end) || @@ -1853,14 +1926,14 @@ struct MD_LINK_ATTR_tag { static int -md_is_link_label(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, - OFF* p_end, int* p_beg_line_index, int* p_end_line_index, +md_is_link_label(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, + OFF* p_end, MD_SIZE* p_beg_line_index, MD_SIZE* p_end_line_index, OFF* p_contents_beg, OFF* p_contents_end) { OFF off = beg; OFF contents_beg = 0; OFF contents_end = 0; - int line_index = 0; + MD_SIZE line_index = 0; int len = 0; if(CH(off) != _T('[')) @@ -2010,13 +2083,13 @@ md_is_link_destination(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, } static int -md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, - OFF* p_end, int* p_beg_line_index, int* p_end_line_index, +md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, + OFF* p_end, MD_SIZE* p_beg_line_index, MD_SIZE* p_end_line_index, OFF* p_contents_beg, OFF* p_contents_end) { OFF off = beg; CHAR closer_char; - int line_index = 0; + MD_SIZE line_index = 0; /* White space with up to one line break. */ while(off < lines[line_index].end && ISWHITESPACE(off)) @@ -2078,21 +2151,21 @@ md_is_link_title(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, * Returns -1 in case of an error (out of memory). */ static int -md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, int n_lines) +md_is_link_reference_definition(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) { OFF label_contents_beg; OFF label_contents_end; - int label_contents_line_index = -1; + MD_SIZE label_contents_line_index; int label_is_multiline = FALSE; OFF dest_contents_beg; OFF dest_contents_end; OFF title_contents_beg; OFF title_contents_end; - int title_contents_line_index; + MD_SIZE title_contents_line_index; int title_is_multiline = FALSE; OFF off; - int line_index = 0; - int tmp_line_index; + MD_SIZE line_index = 0; + MD_SIZE tmp_line_index; MD_REF_DEF* def = NULL; int ret = 0; @@ -2200,12 +2273,12 @@ abort: } static int -md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, int n_lines, +md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF end, MD_LINK_ATTR* attr) { const MD_REF_DEF* def; const MD_LINE* beg_line; - const MD_LINE* end_line; + int is_multiline; CHAR* label; SZ label_size; int ret; @@ -2217,17 +2290,10 @@ md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, int n_lines, end--; /* Find lines corresponding to the beg and end positions. */ - MD_ASSERT(lines[0].beg <= beg); - beg_line = lines; - while(beg >= beg_line->end) - beg_line++; + beg_line = md_lookup_line(beg, lines, n_lines, NULL); + is_multiline = (end > beg_line->end); - MD_ASSERT(end <= lines[n_lines-1].end); - end_line = beg_line; - while(end >= end_line->end) - end_line++; - - if(beg_line != end_line) { + if(is_multiline) { MD_CHECK(md_merge_lines_alloc(ctx, beg, end, beg_line, (int)(n_lines - (beg_line - lines)), _T(' '), &label, &label_size)); } else { @@ -2244,7 +2310,7 @@ md_is_link_reference(MD_CTX* ctx, const MD_LINE* lines, int n_lines, attr->title_needs_free = FALSE; } - if(beg_line != end_line) + if(is_multiline) free(label); ret = (def != NULL); @@ -2254,14 +2320,14 @@ abort: } static int -md_is_inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, int n_lines, +md_is_inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, OFF* p_end, MD_LINK_ATTR* attr) { - int line_index = 0; - int tmp_line_index; + MD_SIZE line_index = 0; + MD_SIZE tmp_line_index; OFF title_contents_beg; OFF title_contents_end; - int title_contents_line_index; + MD_SIZE title_contents_line_index; int title_is_multiline; OFF off = beg; int ret = FALSE; @@ -2275,7 +2341,7 @@ md_is_inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, int n_lines, /* Optional white space with up to one line break. */ while(off < lines[line_index].end && ISWHITESPACE(off)) off++; - if(off >= lines[line_index].end && ISNEWLINE(off)) { + if(off >= lines[line_index].end && (off >= ctx->size || ISNEWLINE(off))) { line_index++; if(line_index >= n_lines) return FALSE; @@ -2318,7 +2384,7 @@ md_is_inline_link_spec(MD_CTX* ctx, const MD_LINE* lines, int n_lines, /* Optional whitespace followed with final ')'. */ while(off < lines[line_index].end && ISWHITESPACE(off)) off++; - if(off >= lines[line_index].end && ISNEWLINE(off)) { + if(off >= lines[line_index].end) { line_index++; if(line_index >= n_lines) return FALSE; @@ -2438,11 +2504,11 @@ struct MD_MARK_tag { OFF beg; OFF end; - /* For unresolved openers, 'prev' and 'next' form the chain of open openers - * of given type 'ch'. + /* For unresolved openers, 'next' may be used to form a stack of + * unresolved open openers. * - * During resolving, we disconnect from the chain and point to the - * corresponding counterpart so opener points to its closer and vice versa. + * When resolved with MD_MARK_OPENER/CLOSER flag, next/prev is index of the + * respective closer/opener. */ int prev; int next; @@ -2458,46 +2524,60 @@ struct MD_MARK_tag { #define MD_MARK_RESOLVED 0x10 /* Resolved in any definite way. */ /* Mark flags specific for various mark types (so they can share bits). */ -#define MD_MARK_EMPH_INTRAWORD 0x20 /* Helper for the "rule of 3". */ +#define MD_MARK_EMPH_OC 0x20 /* Opener/closer mixed candidate. Helper for the "rule of 3". */ #define MD_MARK_EMPH_MOD3_0 0x40 #define MD_MARK_EMPH_MOD3_1 0x80 #define MD_MARK_EMPH_MOD3_2 (0x40 | 0x80) #define MD_MARK_EMPH_MOD3_MASK (0x40 | 0x80) #define MD_MARK_AUTOLINK 0x20 /* Distinguisher for '<', '>'. */ +#define MD_MARK_AUTOLINK_MISSING_MAILTO 0x40 #define MD_MARK_VALIDPERMISSIVEAUTOLINK 0x20 /* For permissive autolinks. */ +#define MD_MARK_HASNESTEDBRACKETS 0x20 /* For '[' to rule out invalid link labels early */ -static MD_MARKCHAIN* -md_asterisk_chain(MD_CTX* ctx, unsigned flags) +static MD_MARKSTACK* +md_emph_stack(MD_CTX* ctx, MD_CHAR ch, unsigned flags) { - switch(flags & (MD_MARK_EMPH_INTRAWORD | MD_MARK_EMPH_MOD3_MASK)) { - case MD_MARK_EMPH_INTRAWORD | MD_MARK_EMPH_MOD3_0: return &ASTERISK_OPENERS_intraword_mod3_0; - case MD_MARK_EMPH_INTRAWORD | MD_MARK_EMPH_MOD3_1: return &ASTERISK_OPENERS_intraword_mod3_1; - case MD_MARK_EMPH_INTRAWORD | MD_MARK_EMPH_MOD3_2: return &ASTERISK_OPENERS_intraword_mod3_2; - case MD_MARK_EMPH_MOD3_0: return &ASTERISK_OPENERS_extraword_mod3_0; - case MD_MARK_EMPH_MOD3_1: return &ASTERISK_OPENERS_extraword_mod3_1; - case MD_MARK_EMPH_MOD3_2: return &ASTERISK_OPENERS_extraword_mod3_2; - default: MD_UNREACHABLE(); + MD_MARKSTACK* stack; + + switch(ch) { + case '*': stack = &ASTERISK_OPENERS_oo_mod3_0; break; + case '_': stack = &UNDERSCORE_OPENERS_oo_mod3_0; break; + default: MD_UNREACHABLE(); } - return NULL; + + if(flags & MD_MARK_EMPH_OC) + stack += 3; + + switch(flags & MD_MARK_EMPH_MOD3_MASK) { + case MD_MARK_EMPH_MOD3_0: stack += 0; break; + case MD_MARK_EMPH_MOD3_1: stack += 1; break; + case MD_MARK_EMPH_MOD3_2: stack += 2; break; + default: MD_UNREACHABLE(); + } + + return stack; } -static MD_MARKCHAIN* -md_mark_chain(MD_CTX* ctx, int mark_index) +static MD_MARKSTACK* +md_opener_stack(MD_CTX* ctx, int mark_index) { MD_MARK* mark = &ctx->marks[mark_index]; switch(mark->ch) { - case _T('*'): return md_asterisk_chain(ctx, mark->flags); - case _T('_'): return &UNDERSCORE_OPENERS; + case _T('*'): + case _T('_'): return md_emph_stack(ctx, mark->ch, mark->flags); + case _T('~'): return (mark->end - mark->beg == 1) ? &TILDE_OPENERS_1 : &TILDE_OPENERS_2; + + case _T('!'): case _T('['): return &BRACKET_OPENERS; - case _T('|'): return &TABLECELLBOUNDARIES; - default: return NULL; + + default: MD_UNREACHABLE(); } } static MD_MARK* -md_push_mark(MD_CTX* ctx) +md_add_mark(MD_CTX* ctx) { if(ctx->n_marks >= ctx->alloc_marks) { MD_MARK* new_marks; @@ -2517,18 +2597,18 @@ md_push_mark(MD_CTX* ctx) return &ctx->marks[ctx->n_marks++]; } -#define PUSH_MARK_() \ +#define ADD_MARK_() \ do { \ - mark = md_push_mark(ctx); \ + mark = md_add_mark(ctx); \ if(mark == NULL) { \ ret = -1; \ goto abort; \ } \ } while(0) -#define PUSH_MARK(ch_, beg_, end_, flags_) \ +#define ADD_MARK(ch_, beg_, end_, flags_) \ do { \ - PUSH_MARK_(); \ + ADD_MARK_(); \ mark->beg = (beg_); \ mark->end = (end_); \ mark->prev = -1; \ @@ -2538,17 +2618,20 @@ md_push_mark(MD_CTX* ctx) } while(0) -static void -md_mark_chain_append(MD_CTX* ctx, MD_MARKCHAIN* chain, int mark_index) +static inline void +md_mark_stack_push(MD_CTX* ctx, MD_MARKSTACK* stack, int mark_index) { - if(chain->tail >= 0) - ctx->marks[chain->tail].next = mark_index; - else - chain->head = mark_index; + ctx->marks[mark_index].next = stack->top; + stack->top = mark_index; +} - ctx->marks[mark_index].prev = chain->tail; - ctx->marks[mark_index].next = -1; - chain->tail = mark_index; +static inline int +md_mark_stack_pop(MD_CTX* ctx, MD_MARKSTACK* stack) +{ + int top = stack->top; + if(top >= 0) + stack->top = ctx->marks[top].next; + return top; } /* Sometimes, we need to store a pointer into the mark. It is quite rare @@ -2575,112 +2658,52 @@ md_mark_get_ptr(MD_CTX* ctx, int mark_index) return ptr; } -static void -md_resolve_range(MD_CTX* ctx, MD_MARKCHAIN* chain, int opener_index, int closer_index) +static inline void +md_resolve_range(MD_CTX* ctx, int opener_index, int closer_index) { MD_MARK* opener = &ctx->marks[opener_index]; MD_MARK* closer = &ctx->marks[closer_index]; - /* Remove opener from the list of openers. */ - if(chain != NULL) { - if(opener->prev >= 0) - ctx->marks[opener->prev].next = opener->next; - else - chain->head = opener->next; - - if(opener->next >= 0) - ctx->marks[opener->next].prev = opener->prev; - else - chain->tail = opener->prev; - } - /* Interconnect opener and closer and mark both as resolved. */ opener->next = closer_index; - opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; closer->prev = opener_index; + + opener->flags |= MD_MARK_OPENER | MD_MARK_RESOLVED; closer->flags |= MD_MARK_CLOSER | MD_MARK_RESOLVED; } -#define MD_ROLLBACK_ALL 0 -#define MD_ROLLBACK_CROSSING 1 +#define MD_ROLLBACK_CROSSING 0 +#define MD_ROLLBACK_ALL 1 /* In the range ctx->marks[opener_index] ... [closer_index], undo some or all * resolvings accordingly to these rules: * - * (1) All openers BEFORE the range corresponding to any closer inside the - * range are un-resolved and they are re-added to their respective chains - * of unresolved openers. This ensures we can reuse the opener for closers - * AFTER the range. + * (1) All stacks of openers are cut so that any pending potential openers + * are discarded from future consideration. * * (2) If 'how' is MD_ROLLBACK_ALL, then ALL resolved marks inside the range - * are discarded. + * are thrown away and turned into dummy marks ('D'). * - * (3) If 'how' is MD_ROLLBACK_CROSSING, only closers with openers handled - * in (1) are discarded. I.e. pairs of openers and closers which are both - * inside the range are retained as well as any unpaired marks. + * WARNING: Do not call for arbitrary range of opener and closer. + * This must form (potentially) valid range not crossing nesting boundaries + * of already resolved ranges. */ static void md_rollback(MD_CTX* ctx, int opener_index, int closer_index, int how) { int i; - int mark_index; - /* Cut all unresolved openers at the mark index. */ - for(i = OPENERS_CHAIN_FIRST; i < OPENERS_CHAIN_LAST+1; i++) { - MD_MARKCHAIN* chain = &ctx->mark_chains[i]; - - while(chain->tail >= opener_index) - chain->tail = ctx->marks[chain->tail].prev; - - if(chain->tail >= 0) - ctx->marks[chain->tail].next = -1; - else - chain->head = -1; + for(i = 0; i < (int) SIZEOF_ARRAY(ctx->opener_stacks); i++) { + MD_MARKSTACK* stack = &ctx->opener_stacks[i]; + while(stack->top >= opener_index) + md_mark_stack_pop(ctx, stack); } - /* Go backwards so that unresolved openers are re-added into their - * respective chains, in the right order. */ - mark_index = closer_index - 1; - while(mark_index > opener_index) { - MD_MARK* mark = &ctx->marks[mark_index]; - int mark_flags = mark->flags; - int discard_flag = (how == MD_ROLLBACK_ALL); - - if(mark->flags & MD_MARK_CLOSER) { - int mark_opener_index = mark->prev; - - /* Undo opener BEFORE the range. */ - if(mark_opener_index < opener_index) { - MD_MARK* mark_opener = &ctx->marks[mark_opener_index]; - MD_MARKCHAIN* chain; - - mark_opener->flags &= ~(MD_MARK_OPENER | MD_MARK_CLOSER | MD_MARK_RESOLVED); - chain = md_mark_chain(ctx, opener_index); - if(chain != NULL) { - md_mark_chain_append(ctx, chain, mark_opener_index); - discard_flag = 1; - } - } - } - - /* And reset our flags. */ - if(discard_flag) - mark->flags &= ~(MD_MARK_OPENER | MD_MARK_CLOSER | MD_MARK_RESOLVED); - - /* Jump as far as we can over unresolved or non-interesting marks. */ - switch(how) { - case MD_ROLLBACK_CROSSING: - if((mark_flags & MD_MARK_CLOSER) && mark->prev > opener_index) { - /* If we are closer with opener INSIDE the range, there may - * not be any other crosser inside the subrange. */ - mark_index = mark->prev; - break; - } - MD_FALLTHROUGH(); - default: - mark_index--; - break; + if(how == MD_ROLLBACK_ALL) { + for(i = opener_index + 1; i < closer_index; i++) { + ctx->marks[i].ch = 'D'; + ctx->marks[i].flags = 0; } } } @@ -2731,15 +2754,9 @@ md_build_mark_char_map(MD_CTX* ctx) } } -/* We limit code span marks to lower than 32 backticks. This solves the - * pathologic case of too many openers, each of different length: Their - * resolving would be then O(n^2). */ -#define CODESPAN_MARK_MAXLEN 32 - static int -md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, - OFF* p_opener_beg, OFF* p_opener_end, - OFF* p_closer_beg, OFF* p_closer_end, +md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, OFF beg, + MD_MARK* opener, MD_MARK* closer, OFF last_potential_closers[CODESPAN_MARK_MAXLEN], int* p_reached_paragraph_end) { @@ -2754,7 +2771,7 @@ md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, int has_space_before_closer = FALSE; int has_eol_before_closer = FALSE; int has_only_space = TRUE; - int line_index = 0; + MD_SIZE line_index = 0; line_end = lines[0].end; opener_end = opener_beg; @@ -2764,7 +2781,7 @@ md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, has_eol_after_opener = (opener_end == line_end); /* The caller needs to know end of the opening mark even if we fail. */ - *p_opener_end = opener_end; + opener->end = opener_end; mark_len = opener_end - opener_beg; if(mark_len > CODESPAN_MARK_MAXLEN) @@ -2840,18 +2857,22 @@ md_is_code_span(MD_CTX* ctx, const MD_LINE* lines, int n_lines, OFF beg, if(has_space_before_closer) closer_beg--; else { + /* Go back to the end of prev line */ closer_beg = lines[line_index-1].end; - /* We need to eat the preceding "\r\n" but not any line trailing - * spaces. */ + /* But restore any trailing whitespace */ while(closer_beg < ctx->size && ISBLANK(closer_beg)) closer_beg++; } } - *p_opener_beg = opener_beg; - *p_opener_end = opener_end; - *p_closer_beg = closer_beg; - *p_closer_end = closer_end; + opener->ch = _T('`'); + opener->beg = opener_beg; + opener->end = opener_end; + opener->flags = MD_MARK_POTENTIAL_OPENER; + closer->ch = _T('`'); + closer->beg = closer_beg; + closer->end = closer_end; + closer->flags = MD_MARK_POTENTIAL_CLOSER; return TRUE; } @@ -2961,18 +2982,17 @@ md_is_autolink(MD_CTX* ctx, OFF beg, OFF max_end, OFF* p_end, int* p_missing_mai } static int -md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) +md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int table_mode) { - int i; + MD_SIZE line_index; int ret = 0; MD_MARK* mark; OFF codespan_last_potential_closers[CODESPAN_MARK_MAXLEN] = { 0 }; int codespan_scanned_till_paragraph_end = FALSE; - for(i = 0; i < n_lines; i++) { - const MD_LINE* line = &lines[i]; + for(line_index = 0; line_index < n_lines; line_index++) { + const MD_LINE* line = &lines[line_index]; OFF off = line->beg; - OFF line_end = line->end; while(TRUE) { CHAR ch; @@ -2987,13 +3007,13 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) #endif /* Optimization: Use some loop unrolling. */ - while(off + 3 < line_end && !IS_MARK_CHAR(off+0) && !IS_MARK_CHAR(off+1) - && !IS_MARK_CHAR(off+2) && !IS_MARK_CHAR(off+3)) + while(off + 3 < line->end && !IS_MARK_CHAR(off+0) && !IS_MARK_CHAR(off+1) + && !IS_MARK_CHAR(off+2) && !IS_MARK_CHAR(off+3)) off += 4; - while(off < line_end && !IS_MARK_CHAR(off+0)) + while(off < line->end && !IS_MARK_CHAR(off+0)) off++; - if(off >= line_end) + if(off >= line->end) break; ch = CH(off); @@ -3003,8 +3023,8 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) * line to form a hard break. */ if(ch == _T('\\') && off+1 < ctx->size && (ISPUNCT(off+1) || ISNEWLINE(off+1))) { /* Hard-break cannot be on the last line of the block. */ - if(!ISNEWLINE(off+1) || i+1 < n_lines) - PUSH_MARK(ch, off, off+2, MD_MARK_RESOLVED); + if(!ISNEWLINE(off+1) || line_index+1 < n_lines) + ADD_MARK(ch, off, off+2, MD_MARK_RESOLVED); off += 2; continue; } @@ -3015,7 +3035,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) int left_level; /* What precedes: 0 = whitespace; 1 = punctuation; 2 = other char. */ int right_level; /* What follows: 0 = whitespace; 1 = punctuation; 2 = other char. */ - while(tmp < line_end && CH(tmp) == ch) + while(tmp < line->end && CH(tmp) == ch) tmp++; if(off == line->beg || ISUNICODEWHITESPACEBEFORE(off)) @@ -3025,7 +3045,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) else left_level = 2; - if(tmp == line_end || ISUNICODEWHITESPACE(tmp)) + if(tmp == line->end || ISUNICODEWHITESPACE(tmp)) right_level = 0; else if(ISUNICODEPUNCT(tmp)) right_level = 1; @@ -3045,8 +3065,8 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) flags |= MD_MARK_POTENTIAL_CLOSER; if(right_level > 0 && right_level >= left_level) flags |= MD_MARK_POTENTIAL_OPENER; - if(left_level == 2 && right_level == 2) - flags |= MD_MARK_EMPH_INTRAWORD; + if(flags == (MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER)) + flags |= MD_MARK_EMPH_OC; /* For "the rule of three" we need to remember the original * size of the mark (modulo three), before we potentially @@ -3058,7 +3078,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) case 2: flags |= MD_MARK_EMPH_MOD3_2; break; } - PUSH_MARK(ch, off, tmp, flags); + ADD_MARK(ch, off, tmp, flags); /* During resolving, multiple asterisks may have to be * split into independent span start/ends. Consider e.g. @@ -3066,7 +3086,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) * marks to have enough space for that. */ off++; while(off < tmp) { - PUSH_MARK('D', off, off, 0); + ADD_MARK('D', off, off, 0); off++; } continue; @@ -3078,38 +3098,32 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* A potential code span start/end. */ if(ch == _T('`')) { - OFF opener_beg, opener_end; - OFF closer_beg, closer_end; + MD_MARK opener; + MD_MARK closer; int is_code_span; - is_code_span = md_is_code_span(ctx, lines + i, n_lines - i, off, - &opener_beg, &opener_end, &closer_beg, &closer_end, - codespan_last_potential_closers, - &codespan_scanned_till_paragraph_end); + is_code_span = md_is_code_span(ctx, line, n_lines - line_index, off, + &opener, &closer, codespan_last_potential_closers, + &codespan_scanned_till_paragraph_end); if(is_code_span) { - PUSH_MARK(_T('`'), opener_beg, opener_end, MD_MARK_OPENER | MD_MARK_RESOLVED); - PUSH_MARK(_T('`'), closer_beg, closer_end, MD_MARK_CLOSER | MD_MARK_RESOLVED); - ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; - ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; - - off = closer_end; + ADD_MARK(opener.ch, opener.beg, opener.end, opener.flags); + ADD_MARK(closer.ch, closer.beg, closer.end, closer.flags); + md_resolve_range(ctx, ctx->n_marks-2, ctx->n_marks-1); + off = closer.end; /* Advance the current line accordingly. */ - while(off > line_end) { - i++; - line++; - line_end = line->end; - } + if(off > line->end) + line = md_lookup_line(off, lines, n_lines, &line_index); continue; } - off = opener_end; + off = opener.end; continue; } /* A potential entity start. */ if(ch == _T('&')) { - PUSH_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); off++; continue; } @@ -3118,7 +3132,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) if(ch == _T(';')) { /* We surely cannot be entity unless the previous mark is '&'. */ if(ctx->n_marks > 0 && ctx->marks[ctx->n_marks-1].ch == _T('&')) - PUSH_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); off++; continue; @@ -3137,21 +3151,18 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* Given the nature of the raw HTML, we have to recognize * it here. Doing so later in md_analyze_lt_gt() could * open can of worms of quadratic complexity. */ - is_html = md_is_html_any(ctx, lines + i, n_lines - i, off, + is_html = md_is_html_any(ctx, line, n_lines - line_index, off, lines[n_lines-1].end, &html_end); if(is_html) { - PUSH_MARK(_T('<'), off, off, MD_MARK_OPENER | MD_MARK_RESOLVED); - PUSH_MARK(_T('>'), html_end, html_end, MD_MARK_CLOSER | MD_MARK_RESOLVED); + ADD_MARK(_T('<'), off, off, MD_MARK_OPENER | MD_MARK_RESOLVED); + ADD_MARK(_T('>'), html_end, html_end, MD_MARK_CLOSER | MD_MARK_RESOLVED); ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; off = html_end; /* Advance the current line accordingly. */ - while(off > line_end) { - i++; - line++; - line_end = line->end; - } + if(off > line->end) + line = md_lookup_line(off, lines, n_lines, &line_index); continue; } } @@ -3159,10 +3170,12 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) is_autolink = md_is_autolink(ctx, off, lines[n_lines-1].end, &autolink_end, &missing_mailto); if(is_autolink) { - PUSH_MARK((missing_mailto ? _T('@') : _T('<')), off, off+1, - MD_MARK_OPENER | MD_MARK_RESOLVED | MD_MARK_AUTOLINK); - PUSH_MARK(_T('>'), autolink_end-1, autolink_end, - MD_MARK_CLOSER | MD_MARK_RESOLVED | MD_MARK_AUTOLINK); + unsigned flags = MD_MARK_RESOLVED | MD_MARK_AUTOLINK; + if(missing_mailto) + flags |= MD_MARK_AUTOLINK_MISSING_MAILTO; + + ADD_MARK(_T('<'), off, off+1, MD_MARK_OPENER | flags); + ADD_MARK(_T('>'), autolink_end-1, autolink_end, MD_MARK_CLOSER | flags); ctx->marks[ctx->n_marks-2].next = ctx->n_marks-1; ctx->marks[ctx->n_marks-1].prev = ctx->n_marks-2; off = autolink_end; @@ -3174,18 +3187,18 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) } /* A potential link or its part. */ - if(ch == _T('[') || (ch == _T('!') && off+1 < line_end && CH(off+1) == _T('['))) { + if(ch == _T('[') || (ch == _T('!') && off+1 < line->end && CH(off+1) == _T('['))) { OFF tmp = (ch == _T('[') ? off+1 : off+2); - PUSH_MARK(ch, off, tmp, MD_MARK_POTENTIAL_OPENER); + ADD_MARK(ch, off, tmp, MD_MARK_POTENTIAL_OPENER); off = tmp; /* Two dummies to make enough place for data we need if it is * a link. */ - PUSH_MARK('D', off, off, 0); - PUSH_MARK('D', off, off, 0); + ADD_MARK('D', off, off, 0); + ADD_MARK('D', off, off, 0); continue; } if(ch == _T(']')) { - PUSH_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_CLOSER); off++; continue; } @@ -3195,9 +3208,9 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) if(line->beg + 1 <= off && ISALNUM(off-1) && off + 3 < line->end && ISALNUM(off+1)) { - PUSH_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); + ADD_MARK(ch, off, off+1, MD_MARK_POTENTIAL_OPENER); /* Push a dummy as a reserve for a closer. */ - PUSH_MARK('D', off, off, 0); + ADD_MARK('D', line->beg, line->end, 0); } off++; @@ -3226,12 +3239,11 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) const SZ suffix_size = scheme_map[scheme_index].suffix_size; if(line->beg + scheme_size <= off && md_ascii_eq(STR(off-scheme_size), scheme, scheme_size) && - (line->beg + scheme_size == off || ISWHITESPACE(off-scheme_size-1) || ISANYOF(off-scheme_size-1, _T("*_~(["))) && off + 1 + suffix_size < line->end && md_ascii_eq(STR(off+1), suffix, suffix_size)) { - PUSH_MARK(ch, off-scheme_size, off+1+suffix_size, MD_MARK_POTENTIAL_OPENER); + ADD_MARK(ch, off-scheme_size, off+1+suffix_size, MD_MARK_POTENTIAL_OPENER); /* Push a dummy as a reserve for a closer. */ - PUSH_MARK('D', off, off, 0); + ADD_MARK('D', line->beg, line->end, 0); off += 1 + suffix_size; break; } @@ -3244,12 +3256,11 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* A potential permissive WWW autolink. */ if(ch == _T('.')) { if(line->beg + 3 <= off && md_ascii_eq(STR(off-3), _T("www"), 3) && - (line->beg + 3 == off || ISWHITESPACE(off-4) || ISANYOF(off-4, _T("*_~(["))) && - off + 1 < line_end) + (off-3 == line->beg || ISUNICODEWHITESPACEBEFORE(off-3) || ISUNICODEPUNCTBEFORE(off-3))) { - PUSH_MARK(ch, off-3, off+1, MD_MARK_POTENTIAL_OPENER); + ADD_MARK(ch, off-3, off+1, MD_MARK_POTENTIAL_OPENER); /* Push a dummy as a reserve for a closer. */ - PUSH_MARK('D', off, off, 0); + ADD_MARK('D', line->beg, line->end, 0); off++; continue; } @@ -3260,7 +3271,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* A potential table cell boundary or wiki link label delimiter. */ if((table_mode || ctx->parser.flags & MD_FLAG_WIKILINKS) && ch == _T('|')) { - PUSH_MARK(ch, off, off+1, 0); + ADD_MARK(ch, off, off+1, 0); off++; continue; } @@ -3269,18 +3280,18 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) if(ch == _T('~')) { OFF tmp = off+1; - while(tmp < line_end && CH(tmp) == _T('~')) + while(tmp < line->end && CH(tmp) == _T('~')) tmp++; if(tmp - off < 3) { unsigned flags = 0; - if(tmp < line_end && !ISUNICODEWHITESPACE(tmp)) + if(tmp < line->end && !ISUNICODEWHITESPACE(tmp)) flags |= MD_MARK_POTENTIAL_OPENER; if(off > line->beg && !ISUNICODEWHITESPACEBEFORE(off)) flags |= MD_MARK_POTENTIAL_CLOSER; if(flags != 0) - PUSH_MARK(ch, off, tmp, flags); + ADD_MARK(ch, off, tmp, flags); } off = tmp; @@ -3293,11 +3304,20 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) * where two dollar signs signify a display equation. */ OFF tmp = off+1; - while(tmp < line_end && CH(tmp) == _T('$')) + while(tmp < line->end && CH(tmp) == _T('$')) tmp++; - if (tmp - off <= 2) - PUSH_MARK(ch, off, tmp, MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER); + if(tmp - off <= 2) { + unsigned flags = MD_MARK_POTENTIAL_OPENER | MD_MARK_POTENTIAL_CLOSER; + + if(off > line->beg && !ISUNICODEWHITESPACEBEFORE(off) && !ISUNICODEPUNCTBEFORE(off)) + flags &= ~MD_MARK_POTENTIAL_OPENER; + if(tmp < line->end && !ISUNICODEWHITESPACE(tmp) && !ISUNICODEPUNCT(tmp)) + flags &= ~MD_MARK_POTENTIAL_CLOSER; + if(flags != 0) + ADD_MARK(ch, off, tmp, flags); + } + off = tmp; continue; } @@ -3306,11 +3326,11 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) if(ISWHITESPACE_(ch)) { OFF tmp = off+1; - while(tmp < line_end && ISWHITESPACE(tmp)) + while(tmp < line->end && ISWHITESPACE(tmp)) tmp++; if(tmp - off > 1 || ch != _T(' ')) - PUSH_MARK(ch, off, tmp, MD_MARK_RESOLVED); + ADD_MARK(ch, off, tmp, MD_MARK_RESOLVED); off = tmp; continue; @@ -3318,7 +3338,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* NULL character. */ if(ch == _T('\0')) { - PUSH_MARK(ch, off, off+1, MD_MARK_RESOLVED); + ADD_MARK(ch, off, off+1, MD_MARK_RESOLVED); off++; continue; } @@ -3329,7 +3349,7 @@ md_collect_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) /* Add a dummy mark at the end of the mark vector to simplify * process_inlines(). */ - PUSH_MARK(127, ctx->size, ctx->size, MD_MARK_RESOLVED); + ADD_MARK(127, ctx->size, ctx->size, MD_MARK_RESOLVED); abort: return ret; @@ -3343,36 +3363,33 @@ md_analyze_bracket(MD_CTX* ctx, int mark_index) * or enclosing pair of brackets (if the inner is the link, the outer * one cannot be.) * - * Therefore we here only construct a list of resolved '[' ']' pairs - * ordered by position of the closer. This allows ur to analyze what is - * or is not link in the right order, from inside to outside in case - * of nested brackets. + * Therefore we here only construct a list of '[' ']' pairs ordered by + * position of the closer. This allows us to analyze what is or is not + * link in the right order, from inside to outside in case of nested + * brackets. * - * The resolving itself is deferred into md_resolve_links(). + * The resolving itself is deferred to md_resolve_links(). */ MD_MARK* mark = &ctx->marks[mark_index]; if(mark->flags & MD_MARK_POTENTIAL_OPENER) { - md_mark_chain_append(ctx, &BRACKET_OPENERS, mark_index); + if(BRACKET_OPENERS.top >= 0) + ctx->marks[BRACKET_OPENERS.top].flags |= MD_MARK_HASNESTEDBRACKETS; + + md_mark_stack_push(ctx, &BRACKET_OPENERS, mark_index); return; } - if(BRACKET_OPENERS.tail >= 0) { - /* Pop the opener from the chain. */ - int opener_index = BRACKET_OPENERS.tail; + if(BRACKET_OPENERS.top >= 0) { + int opener_index = md_mark_stack_pop(ctx, &BRACKET_OPENERS); MD_MARK* opener = &ctx->marks[opener_index]; - if(opener->prev >= 0) - ctx->marks[opener->prev].next = -1; - else - BRACKET_OPENERS.head = -1; - BRACKET_OPENERS.tail = opener->prev; /* Interconnect the opener and closer. */ opener->next = mark_index; mark->prev = opener_index; - /* Add the pair into chain of potential links for md_resolve_links(). + /* Add the pair into a list of potential links for md_resolve_links(). * Note we misuse opener->prev for this as opener->next points to its * closer. */ if(ctx->unresolved_link_tail >= 0) @@ -3385,11 +3402,11 @@ md_analyze_bracket(MD_CTX* ctx, int mark_index) } /* Forward declaration. */ -static void md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines, +static void md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int mark_beg, int mark_end); static int -md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) +md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) { int opener_index = ctx->unresolved_link_head; OFF last_link_beg = 0; @@ -3460,10 +3477,15 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) delim = m; break; } - if(m->ch != 'D' && m->beg - opener->end > 100) - break; + if(m->ch != 'D') { + if(m->beg - opener->end > 100) + break; + if(m->ch != 'D' && (m->flags & MD_MARK_OPENER)) + delim_index = m->next; + } delim_index++; } + dest_beg = opener->end; dest_end = (delim != NULL) ? delim->beg : closer->beg; if(dest_end - dest_beg == 0 || dest_end - dest_beg > 100) @@ -3483,9 +3505,13 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) if(is_link) { if(delim != NULL) { if(delim->end < closer->beg) { + md_rollback(ctx, opener_index, delim_index, MD_ROLLBACK_ALL); + md_rollback(ctx, delim_index, closer_index, MD_ROLLBACK_CROSSING); + delim->flags |= MD_MARK_RESOLVED; opener->end = delim->beg; } else { /* The pipe is just before the closer: [[foo|]] */ + md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL); closer->beg = delim->beg; delim = NULL; } @@ -3502,13 +3528,8 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) last_link_beg = opener->beg; last_link_end = closer->end; - if(delim != NULL) { - delim->flags |= MD_MARK_RESOLVED; - md_rollback(ctx, opener_index, delim_index, MD_ROLLBACK_ALL); - md_analyze_link_contents(ctx, lines, n_lines, opener_index+1, closer_index); - } else { - md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL); - } + if(delim != NULL) + md_analyze_link_contents(ctx, lines, n_lines, delim_index+1, closer_index); opener_index = next_opener->prev; continue; @@ -3518,10 +3539,12 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) if(next_opener != NULL && next_opener->beg == closer->end) { if(next_closer->beg > closer->end + 1) { /* Might be full reference link. */ - is_link = md_is_link_reference(ctx, lines, n_lines, next_opener->beg, next_closer->end, &attr); + if(!(next_opener->flags & MD_MARK_HASNESTEDBRACKETS)) + is_link = md_is_link_reference(ctx, lines, n_lines, next_opener->beg, next_closer->end, &attr); } else { /* Might be shortcut reference link. */ - is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); + if(!(opener->flags & MD_MARK_HASNESTEDBRACKETS)) + is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); } if(is_link < 0) @@ -3578,7 +3601,8 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) if(!is_link) { /* Might be collapsed reference link. */ - is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); + if(!(opener->flags & MD_MARK_HASNESTEDBRACKETS)) + is_link = md_is_link_reference(ctx, lines, n_lines, opener->beg, closer->end, &attr); if(is_link < 0) return -1; } @@ -3599,7 +3623,7 @@ md_resolve_links(MD_CTX* ctx, const MD_LINE* lines, int n_lines) md_mark_store_ptr(ctx, opener_index+2, attr.title); /* The title might or might not have been allocated for us. */ if(attr.title_needs_free) - md_mark_chain_append(ctx, &PTR_CHAIN, opener_index+2); + md_mark_stack_push(ctx, &ctx->ptr_stack, opener_index+2); ctx->marks[opener_index+2].prev = attr.title_size; if(opener->ch == '[') { @@ -3672,7 +3696,7 @@ md_analyze_entity(MD_CTX* ctx, int mark_index) if(md_is_entity(ctx, opener->beg, closer->end, &off)) { MD_ASSERT(off == closer->end); - md_resolve_range(ctx, NULL, mark_index, mark_index+1); + md_resolve_range(ctx, mark_index, mark_index+1); opener->end = closer->end; } } @@ -3682,8 +3706,13 @@ md_analyze_table_cell_boundary(MD_CTX* ctx, int mark_index) { MD_MARK* mark = &ctx->marks[mark_index]; mark->flags |= MD_MARK_RESOLVED; + mark->next = -1; - md_mark_chain_append(ctx, &TABLECELLBOUNDARIES, mark_index); + if(ctx->table_cell_boundaries_head < 0) + ctx->table_cell_boundaries_head = mark_index; + else + ctx->marks[ctx->table_cell_boundaries_tail].next = mark_index; + ctx->table_cell_boundaries_tail = mark_index; ctx->n_table_cell_boundaries++; } @@ -3712,262 +3741,312 @@ static void md_analyze_emph(MD_CTX* ctx, int mark_index) { MD_MARK* mark = &ctx->marks[mark_index]; - MD_MARKCHAIN* chain = md_mark_chain(ctx, mark_index); /* If we can be a closer, try to resolve with the preceding opener. */ if(mark->flags & MD_MARK_POTENTIAL_CLOSER) { MD_MARK* opener = NULL; int opener_index = 0; + MD_MARKSTACK* opener_stacks[6]; + int i, n_opener_stacks; + unsigned flags = mark->flags; - if(mark->ch == _T('*')) { - MD_MARKCHAIN* opener_chains[6]; - int i, n_opener_chains; - unsigned flags = mark->flags; + n_opener_stacks = 0; - /* Apply the "rule of three". */ - n_opener_chains = 0; - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_intraword_mod3_0; - if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_intraword_mod3_1; - if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_intraword_mod3_2; - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_extraword_mod3_0; - if(!(flags & MD_MARK_EMPH_INTRAWORD) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_extraword_mod3_1; - if(!(flags & MD_MARK_EMPH_INTRAWORD) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) - opener_chains[n_opener_chains++] = &ASTERISK_OPENERS_extraword_mod3_2; + /* Apply the rule of 3 */ + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_0 | MD_MARK_EMPH_OC); + if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_1 | MD_MARK_EMPH_OC); + if((flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_2 | MD_MARK_EMPH_OC); + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_0); + if(!(flags & MD_MARK_EMPH_OC) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_2) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_1); + if(!(flags & MD_MARK_EMPH_OC) || (flags & MD_MARK_EMPH_MOD3_MASK) != MD_MARK_EMPH_MOD3_1) + opener_stacks[n_opener_stacks++] = md_emph_stack(ctx, mark->ch, MD_MARK_EMPH_MOD3_2); - /* Opener is the most recent mark from the allowed chains. */ - for(i = 0; i < n_opener_chains; i++) { - if(opener_chains[i]->tail >= 0) { - int tmp_index = opener_chains[i]->tail; - MD_MARK* tmp_mark = &ctx->marks[tmp_index]; - if(opener == NULL || tmp_mark->end > opener->end) { - opener_index = tmp_index; - opener = tmp_mark; - } + /* Opener is the most recent mark from the allowed stacks. */ + for(i = 0; i < n_opener_stacks; i++) { + if(opener_stacks[i]->top >= 0) { + int m_index = opener_stacks[i]->top; + MD_MARK* m = &ctx->marks[m_index]; + + if(opener == NULL || m->end > opener->end) { + opener_index = m_index; + opener = m; } } - } else { - /* Simple emph. mark */ - if(chain->tail >= 0) { - opener_index = chain->tail; - opener = &ctx->marks[opener_index]; - } } /* Resolve, if we have found matching opener. */ if(opener != NULL) { SZ opener_size = opener->end - opener->beg; SZ closer_size = mark->end - mark->beg; - MD_MARKCHAIN* opener_chain = md_mark_chain(ctx, opener_index); + MD_MARKSTACK* stack = md_opener_stack(ctx, opener_index); if(opener_size > closer_size) { opener_index = md_split_emph_mark(ctx, opener_index, closer_size); - md_mark_chain_append(ctx, opener_chain, opener_index); + md_mark_stack_push(ctx, stack, opener_index); } else if(opener_size < closer_size) { md_split_emph_mark(ctx, mark_index, closer_size - opener_size); } + /* Above we were only peeking. */ + md_mark_stack_pop(ctx, stack); + md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING); - md_resolve_range(ctx, opener_chain, opener_index, mark_index); + md_resolve_range(ctx, opener_index, mark_index); return; } } /* If we could not resolve as closer, we may be yet be an opener. */ if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_chain_append(ctx, chain, mark_index); + md_mark_stack_push(ctx, md_emph_stack(ctx, mark->ch, mark->flags), mark_index); } static void md_analyze_tilde(MD_CTX* ctx, int mark_index) { MD_MARK* mark = &ctx->marks[mark_index]; - MD_MARKCHAIN* chain = md_mark_chain(ctx, mark_index); + MD_MARKSTACK* stack = md_opener_stack(ctx, mark_index); /* We attempt to be Github Flavored Markdown compatible here. GFM accepts * only tildes sequences of length 1 and 2, and the length of the opener * and closer has to match. */ - if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && chain->head >= 0) { - int opener_index = chain->head; + if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && stack->top >= 0) { + int opener_index = stack->top; + md_mark_stack_pop(ctx, stack); md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_CROSSING); - md_resolve_range(ctx, chain, opener_index, mark_index); + md_resolve_range(ctx, opener_index, mark_index); return; } if(mark->flags & MD_MARK_POTENTIAL_OPENER) - md_mark_chain_append(ctx, chain, mark_index); + md_mark_stack_push(ctx, stack, mark_index); } static void md_analyze_dollar(MD_CTX* ctx, int mark_index) { - /* This should mimic the way inline equations work in LaTeX, so there - * can only ever be one item in the chain (i.e. the dollars can't be - * nested). This is basically the same as the md_analyze_tilde function, - * except that we require matching openers and closers to be of the same - * length. - * - * E.g.: $abc$$def$$ => abc (display equation) def (end equation) */ - if(DOLLAR_OPENERS.head >= 0) { + MD_MARK* mark = &ctx->marks[mark_index]; + + if((mark->flags & MD_MARK_POTENTIAL_CLOSER) && DOLLAR_OPENERS.top >= 0) { /* If the potential closer has a non-matching number of $, discard */ - MD_MARK* open = &ctx->marks[DOLLAR_OPENERS.head]; - MD_MARK* close = &ctx->marks[mark_index]; + MD_MARK* opener = &ctx->marks[DOLLAR_OPENERS.top]; + int opener_index = DOLLAR_OPENERS.top; + MD_MARK* closer = mark; + int closer_index = mark_index; - int opener_index = DOLLAR_OPENERS.head; - md_rollback(ctx, opener_index, mark_index, MD_ROLLBACK_ALL); - if (open->end - open->beg == close->end - close->beg) { + if(opener->end - opener->beg == closer->end - closer->beg) { /* We are the matching closer */ - md_resolve_range(ctx, &DOLLAR_OPENERS, opener_index, mark_index); - } else { - /* We don't match the opener, so discard old opener and insert as opener */ - md_mark_chain_append(ctx, &DOLLAR_OPENERS, mark_index); + md_mark_stack_pop(ctx, &DOLLAR_OPENERS); + md_rollback(ctx, opener_index, closer_index, MD_ROLLBACK_ALL); + md_resolve_range(ctx, opener_index, closer_index); + + /* Discard all pending openers: Latex math span do not allow + * nesting. */ + DOLLAR_OPENERS.top = -1; + return; } - } else { - /* No unmatched openers, so we are opener */ - md_mark_chain_append(ctx, &DOLLAR_OPENERS, mark_index); } + + if(mark->flags & MD_MARK_POTENTIAL_OPENER) + md_mark_stack_push(ctx, &DOLLAR_OPENERS, mark_index); +} + +static MD_MARK* +md_scan_left_for_resolved_mark(MD_CTX* ctx, MD_MARK* mark_from, OFF off, MD_MARK** p_cursor) +{ + MD_MARK* mark; + + for(mark = mark_from; mark >= ctx->marks; mark--) { + if(mark->ch == 'D' || mark->beg > off) + continue; + if(mark->beg <= off && off < mark->end && (mark->flags & MD_MARK_RESOLVED)) { + if(p_cursor != NULL) + *p_cursor = mark; + return mark; + } + if(mark->end <= off) + break; + } + + if(p_cursor != NULL) + *p_cursor = mark; + return NULL; +} + +static MD_MARK* +md_scan_right_for_resolved_mark(MD_CTX* ctx, MD_MARK* mark_from, OFF off, MD_MARK** p_cursor) +{ + MD_MARK* mark; + + for(mark = mark_from; mark < ctx->marks + ctx->n_marks; mark++) { + if(mark->ch == 'D' || mark->end <= off) + continue; + if(mark->beg <= off && off < mark->end && (mark->flags & MD_MARK_RESOLVED)) { + if(p_cursor != NULL) + *p_cursor = mark; + return mark; + } + if(mark->beg > off) + break; + } + + if(p_cursor != NULL) + *p_cursor = mark; + return NULL; } static void -md_analyze_permissive_url_autolink(MD_CTX* ctx, int mark_index) +md_analyze_permissive_autolink(MD_CTX* ctx, int mark_index) { + static const struct { + const MD_CHAR start_char; + const MD_CHAR delim_char; + const MD_CHAR* allowed_nonalnum_chars; + int min_components; + const MD_CHAR optional_end_char; + } URL_MAP[] = { + { _T('\0'), _T('.'), _T(".-_"), 2, _T('\0') }, /* host, mandatory */ + { _T('/'), _T('/'), _T("/.-_"), 0, _T('/') }, /* path */ + { _T('?'), _T('&'), _T("&.-+_=()"), 1, _T('\0') }, /* query */ + { _T('#'), _T('\0'), _T(".-+_") , 1, _T('\0') } /* fragment */ + }; + MD_MARK* opener = &ctx->marks[mark_index]; - int closer_index = mark_index + 1; - MD_MARK* closer = &ctx->marks[closer_index]; - MD_MARK* next_resolved_mark; - OFF off = opener->end; - int n_dots = FALSE; - int has_underscore_in_last_seg = FALSE; - int has_underscore_in_next_to_last_seg = FALSE; - int n_opened_parenthesis = 0; - int n_excess_parenthesis = 0; - - /* Check for domain. */ - while(off < ctx->size) { - if(ISALNUM(off) || CH(off) == _T('-')) { - off++; - } else if(CH(off) == _T('.')) { - /* We must see at least one period. */ - n_dots++; - has_underscore_in_next_to_last_seg = has_underscore_in_last_seg; - has_underscore_in_last_seg = FALSE; - off++; - } else if(CH(off) == _T('_')) { - /* No underscore may be present in the last two domain segments. */ - has_underscore_in_last_seg = TRUE; - off++; - } else { - break; - } - } - if(off > opener->end && CH(off-1) == _T('.')) { - off--; - n_dots--; - } - if(off <= opener->end || n_dots == 0 || has_underscore_in_next_to_last_seg || has_underscore_in_last_seg) - return; - - /* Check for path. */ - next_resolved_mark = closer + 1; - while(next_resolved_mark->ch == 'D' || !(next_resolved_mark->flags & MD_MARK_RESOLVED)) - next_resolved_mark++; - while(off < next_resolved_mark->beg && CH(off) != _T('<') && !ISWHITESPACE(off) && !ISNEWLINE(off)) { - /* Parenthesis must be balanced. */ - if(CH(off) == _T('(')) { - n_opened_parenthesis++; - } else if(CH(off) == _T(')')) { - if(n_opened_parenthesis > 0) - n_opened_parenthesis--; - else - n_excess_parenthesis++; - } - - off++; - } - - /* Trim a trailing punctuation from the end. */ - while(TRUE) { - if(ISANYOF(off-1, _T("?!.,:*_~"))) { - off--; - } else if(CH(off-1) == ')' && n_excess_parenthesis > 0) { - /* Unmatched ')' can be in an interior of the path but not at the - * of it, so the auto-link may be safely nested in a parenthesis - * pair. */ - off--; - n_excess_parenthesis--; - } else { - break; - } - } - - /* Ok. Lets call it an auto-link. Adapt opener and create closer to zero - * length so all the contents becomes the link text. */ - MD_ASSERT(closer->ch == 'D'); - opener->end = opener->beg; - closer->ch = opener->ch; - closer->beg = off; - closer->end = off; - md_resolve_range(ctx, NULL, mark_index, closer_index); -} - -/* The permissive autolinks do not have to be enclosed in '<' '>' but we - * instead impose stricter rules what is understood as an e-mail address - * here. Actually any non-alphanumeric characters with exception of '.' - * are prohibited both in username and after '@'. */ -static void -md_analyze_permissive_email_autolink(MD_CTX* ctx, int mark_index) -{ - MD_MARK* opener = &ctx->marks[mark_index]; - int closer_index; - MD_MARK* closer; + MD_MARK* closer = &ctx->marks[mark_index + 1]; /* The dummy. */ + OFF line_beg = closer->beg; /* md_collect_mark() set this for us */ + OFF line_end = closer->end; /* ditto */ OFF beg = opener->beg; OFF end = opener->end; - int dot_count = 0; + MD_MARK* left_cursor = opener; + int left_boundary_ok = FALSE; + MD_MARK* right_cursor = opener; + int right_boundary_ok = FALSE; + unsigned i; - MD_ASSERT(CH(beg) == _T('@')); - - /* Scan for name before '@'. */ - while(beg > 0 && (ISALNUM(beg-1) || ISANYOF(beg-1, _T(".-_+")))) - beg--; - - /* Scan for domain after '@'. */ - while(end < ctx->size && (ISALNUM(end) || ISANYOF(end, _T(".-_")))) { - if(CH(end) == _T('.')) - dot_count++; - end++; - } - if(CH(end-1) == _T('.')) { /* Final '.' not part of it. */ - dot_count--; - end--; - } - else if(ISANYOF2(end-1, _T('-'), _T('_'))) /* These are forbidden at the end. */ - return; - if(CH(end-1) == _T('@') || dot_count == 0) - return; - - /* Ok. Lets call it auto-link. Adapt opener and create closer to zero - * length so all the contents becomes the link text. */ - closer_index = mark_index + 1; - closer = &ctx->marks[closer_index]; MD_ASSERT(closer->ch == 'D'); + if(opener->ch == '@') { + MD_ASSERT(CH(opener->beg) == _T('@')); + + /* Scan backwards for the user name (before '@'). */ + while(beg > line_beg) { + if(ISALNUM(beg-1)) + beg--; + else if(beg >= line_beg+2 && ISALNUM(beg-2) && + ISANYOF(beg-1, _T(".-_+")) && + md_scan_left_for_resolved_mark(ctx, left_cursor, beg-1, &left_cursor) == NULL && + ISALNUM(beg)) + beg--; + else + break; + } + if(beg == opener->beg) /* empty user name */ + return; + } + + /* Verify there's line boundary, whitespace, allowed punctuation or + * resolved emphasis mark just before the suspected autolink. */ + if(beg == line_beg || ISUNICODEWHITESPACEBEFORE(beg) || ISANYOF(beg-1, _T("({["))) { + left_boundary_ok = TRUE; + } else if(ISANYOF(beg-1, _T("*_~"))) { + MD_MARK* left_mark; + + left_mark = md_scan_left_for_resolved_mark(ctx, left_cursor, beg-1, &left_cursor); + if(left_mark != NULL && (left_mark->flags & MD_MARK_OPENER)) + left_boundary_ok = TRUE; + } + if(!left_boundary_ok) + return; + + for(i = 0; i < SIZEOF_ARRAY(URL_MAP); i++) { + int n_components = 0; + int n_open_brackets = 0; + + if(URL_MAP[i].start_char != _T('\0')) { + if(end >= line_end || CH(end) != URL_MAP[i].start_char) + continue; + if(URL_MAP[i].min_components > 0 && (end+1 >= line_end || !ISALNUM(end+1))) + continue; + end++; + } + + while(end < line_end) { + if(ISALNUM(end)) { + if(n_components == 0) + n_components++; + end++; + } else if(end < line_end && + ISANYOF(end, URL_MAP[i].allowed_nonalnum_chars) && + md_scan_right_for_resolved_mark(ctx, right_cursor, end, &right_cursor) == NULL && + ((end > line_beg && (ISALNUM(end-1) || CH(end-1) == _T(')'))) || CH(end) == _T('(')) && + ((end+1 < line_end && (ISALNUM(end+1) || CH(end+1) == _T('('))) || CH(end) == _T(')'))) + { + if(CH(end) == URL_MAP[i].delim_char) + n_components++; + + /* brackets have to be balanced. */ + if(CH(end) == _T('(')) { + n_open_brackets++; + } else if(CH(end) == _T(')')) { + if(n_open_brackets <= 0) + break; + n_open_brackets--; + } + + end++; + } else { + break; + } + } + + if(end < line_end && URL_MAP[i].optional_end_char != _T('\0') && + CH(end) == URL_MAP[i].optional_end_char) + end++; + + if(n_components < URL_MAP[i].min_components || n_open_brackets != 0) + return; + + if(opener->ch == '@') /* E-mail autolinks wants only the host. */ + break; + } + + /* Verify there's line boundary, whitespace, allowed punctuation or + * resolved emphasis mark just after the suspected autolink. */ + if(end == line_end || ISUNICODEWHITESPACE(end) || ISANYOF(end, _T(")}].!?,;"))) { + right_boundary_ok = TRUE; + } else { + MD_MARK* right_mark; + + right_mark = md_scan_right_for_resolved_mark(ctx, right_cursor, end, &right_cursor); + if(right_mark != NULL && (right_mark->flags & MD_MARK_CLOSER)) + right_boundary_ok = TRUE; + } + if(!right_boundary_ok) + return; + + /* Success, we are an autolink. */ opener->beg = beg; opener->end = beg; - closer->ch = opener->ch; closer->beg = end; closer->end = end; - md_resolve_range(ctx, NULL, mark_index, closer_index); + closer->ch = opener->ch; + md_resolve_range(ctx, mark_index, mark_index + 1); } +#define MD_ANALYZE_NOSKIP_EMPH 0x01 + static inline void -md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, - int mark_beg, int mark_end, const CHAR* mark_chars) +md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, + int mark_beg, int mark_end, const CHAR* mark_chars, unsigned flags) { int i = mark_beg; + OFF last_end = lines[0].beg; + MD_UNUSED(lines); MD_UNUSED(n_lines); @@ -3976,7 +4055,9 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, /* Skip resolved spans. */ if(mark->flags & MD_MARK_RESOLVED) { - if(mark->flags & MD_MARK_OPENER) { + if((mark->flags & MD_MARK_OPENER) && + !((flags & MD_ANALYZE_NOSKIP_EMPH) && ISANYOF_(mark->ch, "*_~"))) + { MD_ASSERT(i < mark->next); i = mark->next + 1; } else { @@ -3991,6 +4072,12 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, continue; } + /* The resolving in previous step could have expanded a mark. */ + if(mark->beg < last_end) { + i++; + continue; + } + /* Analyze the mark. */ switch(mark->ch) { case '[': /* Pass through. */ @@ -4003,8 +4090,15 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, case '~': md_analyze_tilde(ctx, i); break; case '$': md_analyze_dollar(ctx, i); break; case '.': /* Pass through. */ - case ':': md_analyze_permissive_url_autolink(ctx, i); break; - case '@': md_analyze_permissive_email_autolink(ctx, i); break; + case ':': /* Pass through. */ + case '@': md_analyze_permissive_autolink(ctx, i); break; + } + + if(mark->flags & MD_MARK_RESOLVED) { + if(mark->flags & MD_MARK_OPENER) + last_end = ctx->marks[mark->next].end; + else + last_end = mark->end; } i++; @@ -4013,7 +4107,7 @@ md_analyze_marks(MD_CTX* ctx, const MD_LINE* lines, int n_lines, /* Analyze marks (build ctx->marks). */ static int -md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mode) +md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int table_mode) { int ret; @@ -4023,31 +4117,22 @@ md_analyze_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines, int table_mod /* Collect all marks. */ MD_CHECK(md_collect_marks(ctx, lines, n_lines, table_mode)); - /* We analyze marks in few groups to handle their precedence. */ - /* (1) Entities; code spans; autolinks; raw HTML. */ - md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("&")); - - /* (2) Links. */ - md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("[]!")); + /* (1) Links. */ + md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("[]!"), 0); MD_CHECK(md_resolve_links(ctx, lines, n_lines)); - BRACKET_OPENERS.head = -1; - BRACKET_OPENERS.tail = -1; + BRACKET_OPENERS.top = -1; ctx->unresolved_link_head = -1; ctx->unresolved_link_tail = -1; if(table_mode) { - /* (3) Analyze table cell boundaries. - * Note we reset TABLECELLBOUNDARIES chain prior to the call md_analyze_marks(), - * not after, because caller may need it. */ + /* (2) Analyze table cell boundaries. */ MD_ASSERT(n_lines == 1); - TABLECELLBOUNDARIES.head = -1; - TABLECELLBOUNDARIES.tail = -1; ctx->n_table_cell_boundaries = 0; - md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("|")); + md_analyze_marks(ctx, lines, n_lines, 0, ctx->n_marks, _T("|"), 0); return ret; } - /* (4) Emphasis and strong emphasis; permissive autolinks. */ + /* (3) Emphasis and strong emphasis; permissive autolinks. */ md_analyze_link_contents(ctx, lines, n_lines, 0, ctx->n_marks); abort: @@ -4055,22 +4140,28 @@ abort: } static void -md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines, +md_analyze_link_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines, int mark_beg, int mark_end) { int i; - md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("*_~$@:.")); + md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("&"), 0); + md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("*_~$"), 0); - for(i = OPENERS_CHAIN_FIRST; i <= OPENERS_CHAIN_LAST; i++) { - ctx->mark_chains[i].head = -1; - ctx->mark_chains[i].tail = -1; + if((ctx->parser.flags & MD_FLAG_PERMISSIVEAUTOLINKS) != 0) { + /* These have to be processed last, as they may be greedy and expand + * from their original mark. Also their implementation must be careful + * not to cross any (previously) resolved marks when doing so. */ + md_analyze_marks(ctx, lines, n_lines, mark_beg, mark_end, _T("@:."), MD_ANALYZE_NOSKIP_EMPH); } + + for(i = 0; i < (int) SIZEOF_ARRAY(ctx->opener_stacks); i++) + ctx->opener_stacks[i].top = -1; } static int md_enter_leave_span_a(MD_CTX* ctx, int enter, MD_SPANTYPE type, - const CHAR* dest, SZ dest_size, int prohibit_escapes_in_dest, + const CHAR* dest, SZ dest_size, int is_autolink, const CHAR* title, SZ title_size) { MD_ATTRIBUTE_BUILD href_build = { 0 }; @@ -4082,10 +4173,10 @@ md_enter_leave_span_a(MD_CTX* ctx, int enter, MD_SPANTYPE type, * MD_SPAN_IMG_DETAIL are binary-compatible. */ memset(&det, 0, sizeof(MD_SPAN_A_DETAIL)); MD_CHECK(md_build_attribute(ctx, dest, dest_size, - (prohibit_escapes_in_dest ? MD_BUILD_ATTR_NO_ESCAPES : 0), + (is_autolink ? MD_BUILD_ATTR_NO_ESCAPES : 0), &det.href, &href_build)); MD_CHECK(md_build_attribute(ctx, title, title_size, 0, &det.title, &title_build)); - + det.is_autolink = is_autolink; if(enter) MD_ENTER_SPAN(type, &det); else @@ -4120,7 +4211,7 @@ abort: /* Render the output, accordingly to the analyzed ctx->marks. */ static int -md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) +md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) { MD_TEXTTYPE text_type; const MD_LINE* line = lines; @@ -4128,6 +4219,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) MD_MARK* mark; OFF off = lines[0].beg; OFF end = lines[n_lines-1].end; + OFF tmp; int enforce_hardbreak = 0; int ret = 0; @@ -4143,7 +4235,7 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) while(1) { /* Process the text up to the next mark or end-of-line. */ - OFF tmp = (line->end < mark->beg ? line->end : mark->beg); + tmp = (line->end < mark->beg ? line->end : mark->beg); if(tmp > off) { MD_TEXT(text_type, STR(off), tmp - off); off = tmp; @@ -4265,7 +4357,8 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) MD_CHECK(md_enter_leave_span_a(ctx, (mark->ch != ']'), (opener->ch == '!' ? MD_SPAN_IMG : MD_SPAN_A), STR(dest_mark->beg), dest_mark->end - dest_mark->beg, FALSE, - md_mark_get_ptr(ctx, (int)(title_mark - ctx->marks)), title_mark->prev)); + md_mark_get_ptr(ctx, (int)(title_mark - ctx->marks)), + title_mark->prev)); /* link/image closer may span multiple lines. */ if(mark->ch == ']') { @@ -4307,11 +4400,13 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) if(mark->flags & MD_MARK_OPENER) closer->flags |= MD_MARK_VALIDPERMISSIVEAUTOLINK; - if(opener->ch == '@' || opener->ch == '.') { + if(opener->ch == '@' || opener->ch == '.' || + (opener->ch == '<' && (opener->flags & MD_MARK_AUTOLINK_MISSING_MAILTO))) + { dest_size += 7; MD_TEMP_BUFFER(dest_size * sizeof(CHAR)); memcpy(ctx->buffer, - (opener->ch == '@' ? _T("mailto:") : _T("http://")), + (opener->ch == '.' ? _T("http://") : _T("mailto:")), 7 * sizeof(CHAR)); memcpy(ctx->buffer + 7, dest, (dest_size-7) * sizeof(CHAR)); dest = ctx->buffer; @@ -4351,8 +4446,6 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) break; if(text_type == MD_TEXT_CODE || text_type == MD_TEXT_LATEXMATH) { - OFF tmp; - MD_ASSERT(prev_mark != NULL); MD_ASSERT(ISANYOF2_(prev_mark->ch, '`', '$') && (prev_mark->flags & MD_MARK_OPENER)); MD_ASSERT(ISANYOF2_(mark->ch, '`', '$') && (mark->flags & MD_MARK_CLOSER)); @@ -4366,13 +4459,12 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) MD_TEXT(text_type, STR(tmp), off-tmp); /* and new lines are transformed into single spaces. */ - if(prev_mark->end < off && off < mark->beg) + if(off == line->end) MD_TEXT(text_type, _T(" "), 1); } else if(text_type == MD_TEXT_HTML) { /* Inside raw HTML, we output the new line verbatim, including * any trailing spaces. */ - OFF tmp = off; - + tmp = off; while(tmp < end && ISBLANK(tmp)) tmp++; if(tmp > off) @@ -4383,7 +4475,9 @@ md_process_inlines(MD_CTX* ctx, const MD_LINE* lines, int n_lines) MD_TEXTTYPE break_type = MD_TEXT_SOFTBR; if(text_type == MD_TEXT_NORMAL) { - if(enforce_hardbreak) + if(ctx->parser.flags & MD_FLAG_HARD_SOFT_BREAKS) + break_type = MD_TEXT_BR; + else if(enforce_hardbreak) break_type = MD_TEXT_BR; else if((CH(line->end) == _T(' ') && CH(line->end+1) == _T(' '))) break_type = MD_TEXT_BR; @@ -4435,7 +4529,7 @@ md_analyze_table_alignment(MD_CTX* ctx, OFF beg, OFF end, MD_ALIGN* align, int n } /* Forward declaration. */ -static int md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines); +static int md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines); static int md_process_table_cell(MD_CTX* ctx, MD_BLOCKTYPE cell_type, MD_ALIGN align, OFF beg, OFF end) @@ -4488,7 +4582,7 @@ md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end, } j = 0; pipe_offs[j++] = beg; - for(i = TABLECELLBOUNDARIES.head; i >= 0; i = ctx->marks[i].next) { + for(i = ctx->table_cell_boundaries_head; i >= 0; i = ctx->marks[i].next) { MD_MARK* mark = &ctx->marks[i]; pipe_offs[j++] = mark->end; } @@ -4510,20 +4604,17 @@ md_process_table_row(MD_CTX* ctx, MD_BLOCKTYPE cell_type, OFF beg, OFF end, abort: free(pipe_offs); - /* Free any temporary memory blocks stored within some dummy marks. */ - for(i = PTR_CHAIN.head; i >= 0; i = ctx->marks[i].next) - free(md_mark_get_ptr(ctx, i)); - PTR_CHAIN.head = -1; - PTR_CHAIN.tail = -1; + ctx->table_cell_boundaries_head = -1; + ctx->table_cell_boundaries_tail = -1; return ret; } static int -md_process_table_block_contents(MD_CTX* ctx, int col_count, const MD_LINE* lines, int n_lines) +md_process_table_block_contents(MD_CTX* ctx, int col_count, const MD_LINE* lines, MD_SIZE n_lines) { MD_ALIGN* align; - int i; + MD_SIZE line_index; int ret = 0; /* At least two lines have to be present: The column headers and the line @@ -4546,9 +4637,9 @@ md_process_table_block_contents(MD_CTX* ctx, int col_count, const MD_LINE* lines if(n_lines > 2) { MD_ENTER_BLOCK(MD_BLOCK_TBODY, NULL); - for(i = 2; i < n_lines; i++) { + for(line_index = 2; line_index < n_lines; line_index++) { MD_CHECK(md_process_table_row(ctx, MD_BLOCK_TD, - lines[i].beg, lines[i].end, align, col_count)); + lines[line_index].beg, lines[line_index].end, align, col_count)); } MD_LEAVE_BLOCK(MD_BLOCK_TBODY, NULL); } @@ -4584,7 +4675,7 @@ struct MD_BLOCK_tag { * MD_BLOCK_LI: Task mark offset in the input doc. * MD_BLOCK_OL: Start item number. */ - unsigned n_lines; + MD_SIZE n_lines; }; struct MD_CONTAINER_tag { @@ -4600,7 +4691,7 @@ struct MD_CONTAINER_tag { static int -md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines) +md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, MD_SIZE n_lines) { int i; int ret; @@ -4610,25 +4701,24 @@ md_process_normal_block_contents(MD_CTX* ctx, const MD_LINE* lines, int n_lines) abort: /* Free any temporary memory blocks stored within some dummy marks. */ - for(i = PTR_CHAIN.head; i >= 0; i = ctx->marks[i].next) + for(i = ctx->ptr_stack.top; i >= 0; i = ctx->marks[i].next) free(md_mark_get_ptr(ctx, i)); - PTR_CHAIN.head = -1; - PTR_CHAIN.tail = -1; + ctx->ptr_stack.top = -1; return ret; } static int -md_process_verbatim_block_contents(MD_CTX* ctx, MD_TEXTTYPE text_type, const MD_VERBATIMLINE* lines, int n_lines) +md_process_verbatim_block_contents(MD_CTX* ctx, MD_TEXTTYPE text_type, const MD_VERBATIMLINE* lines, MD_SIZE n_lines) { static const CHAR indent_chunk_str[] = _T(" "); static const SZ indent_chunk_size = SIZEOF_ARRAY(indent_chunk_str) - 1; - int i; + MD_SIZE line_index; int ret = 0; - for(i = 0; i < n_lines; i++) { - const MD_VERBATIMLINE* line = &lines[i]; + for(line_index = 0; line_index < n_lines; line_index++) { + const MD_VERBATIMLINE* line = &lines[line_index]; int indent = line->indent; MD_ASSERT(indent >= 0); @@ -4653,7 +4743,7 @@ abort: } static int -md_process_code_block_contents(MD_CTX* ctx, int is_fenced, const MD_VERBATIMLINE* lines, int n_lines) +md_process_code_block_contents(MD_CTX* ctx, int is_fenced, const MD_VERBATIMLINE* lines, MD_SIZE n_lines) { if(is_fenced) { /* Skip the first line in case of fenced code: It is the fence. @@ -4908,7 +4998,7 @@ md_push_block_bytes(MD_CTX* ctx, int n_bytes) /* Fix the ->current_block after the reallocation. */ if(ctx->current_block != NULL) { - OFF off_current_block = (OFF)((char*) ctx->current_block - (char*) ctx->block_bytes); + OFF off_current_block = (OFF) ((char*) ctx->current_block - (char*) ctx->block_bytes); ctx->current_block = (MD_BLOCK*) ((char*) new_block_bytes + off_current_block); } @@ -4980,8 +5070,8 @@ static int md_consume_link_reference_definitions(MD_CTX* ctx) { MD_LINE* lines = (MD_LINE*) (ctx->current_block + 1); - int n_lines = ctx->current_block->n_lines; - int n = 0; + MD_SIZE n_lines = ctx->current_block->n_lines; + MD_SIZE n = 0; /* Compute how many lines at the start of the block form one or more * reference definitions. */ @@ -5036,7 +5126,7 @@ md_end_current_block(MD_CTX* ctx) (ctx->current_block->type == MD_BLOCK_H && (ctx->current_block->flags & MD_BLOCK_SETEXT_HEADER))) { MD_LINE* lines = (MD_LINE*) (ctx->current_block + 1); - if(CH(lines[0].beg) == _T('[')) { + if(lines[0].beg < ctx->size && CH(lines[0].beg) == _T('[')) { MD_CHECK(md_consume_link_reference_definitions(ctx)); if(ctx->current_block == NULL) return ret; @@ -5044,7 +5134,7 @@ md_end_current_block(MD_CTX* ctx) } if(ctx->current_block->type == MD_BLOCK_H && (ctx->current_block->flags & MD_BLOCK_SETEXT_HEADER)) { - int n_lines = ctx->current_block->n_lines; + MD_SIZE n_lines = ctx->current_block->n_lines; if(n_lines > 1) { /* Get rid of the underline. */ @@ -5183,8 +5273,8 @@ md_is_setext_underline(MD_CTX* ctx, OFF beg, OFF* p_end, unsigned* p_level) while(off < ctx->size && CH(off) == CH(beg)) off++; - /* Optionally, space(s) can follow. */ - while(off < ctx->size && CH(off) == _T(' ')) + /* Optionally, space(s) or tabs can follow. */ + while(off < ctx->size && ISBLANK(off)) off++; /* But nothing more is allowed on the line. */ @@ -5211,21 +5301,23 @@ md_is_table_underline(MD_CTX* ctx, OFF beg, OFF* p_end, unsigned* p_col_count) } while(1) { - OFF cell_beg; int delimited = FALSE; /* Cell underline ("-----", ":----", "----:" or ":----:") */ - cell_beg = off; if(off < ctx->size && CH(off) == _T(':')) off++; + if(off >= ctx->size || CH(off) != _T('-')) + return FALSE; while(off < ctx->size && CH(off) == _T('-')) off++; if(off < ctx->size && CH(off) == _T(':')) off++; - if(off - cell_beg < 3) - return FALSE; col_count++; + if(col_count > TABLE_MAXCOLCOUNT) { + MD_LOG("Suppressing table (column_count >" STRINGIZE(TABLE_MAXCOLCOUNT) ")"); + return FALSE; + } /* Pipe delimiter (optional at the end of line). */ while(off < ctx->size && ISWHITESPACE(off)) @@ -5314,48 +5406,55 @@ out: return ret; } + +/* Helper data for md_is_html_block_start_condition() and + * md_is_html_block_end_condition() */ +typedef struct TAG_tag TAG; +struct TAG_tag { + const CHAR* name; + unsigned len : 8; +}; + +#ifdef X + #undef X +#endif +#define X(name) { _T(name), (sizeof(name)-1) / sizeof(CHAR) } +#define Xend { NULL, 0 } + +static const TAG t1[] = { X("pre"), X("script"), X("style"), X("textarea"), Xend }; + +static const TAG a6[] = { X("address"), X("article"), X("aside"), Xend }; +static const TAG b6[] = { X("base"), X("basefont"), X("blockquote"), X("body"), Xend }; +static const TAG c6[] = { X("caption"), X("center"), X("col"), X("colgroup"), Xend }; +static const TAG d6[] = { X("dd"), X("details"), X("dialog"), X("dir"), + X("div"), X("dl"), X("dt"), Xend }; +static const TAG f6[] = { X("fieldset"), X("figcaption"), X("figure"), X("footer"), + X("form"), X("frame"), X("frameset"), Xend }; +static const TAG h6[] = { X("h1"), X("h2"), X("h3"), X("h4"), X("h5"), X("h6"), + X("head"), X("header"), X("hr"), X("html"), Xend }; +static const TAG i6[] = { X("iframe"), Xend }; +static const TAG l6[] = { X("legend"), X("li"), X("link"), Xend }; +static const TAG m6[] = { X("main"), X("menu"), X("menuitem"), Xend }; +static const TAG n6[] = { X("nav"), X("noframes"), Xend }; +static const TAG o6[] = { X("ol"), X("optgroup"), X("option"), Xend }; +static const TAG p6[] = { X("p"), X("param"), Xend }; +static const TAG s6[] = { X("search"), X("section"), X("summary"), Xend }; +static const TAG t6[] = { X("table"), X("tbody"), X("td"), X("tfoot"), X("th"), + X("thead"), X("title"), X("tr"), X("track"), Xend }; +static const TAG u6[] = { X("ul"), Xend }; +static const TAG xx[] = { Xend }; + +#undef X +#undef Xend + /* Returns type of the raw HTML block, or FALSE if it is not HTML block. * (Refer to CommonMark specification for details about the types.) */ static int md_is_html_block_start_condition(MD_CTX* ctx, OFF beg) { - typedef struct TAG_tag TAG; - struct TAG_tag { - const CHAR* name; - unsigned len : 8; - }; - /* Type 6 is started by a long list of allowed tags. We use two-level * tree to speed-up the search. */ -#ifdef X - #undef X -#endif -#define X(name) { _T(name), (sizeof(name)-1) / sizeof(CHAR) } -#define Xend { NULL, 0 } - static const TAG t1[] = { X("script"), X("pre"), X("style"), Xend }; - - static const TAG a6[] = { X("address"), X("article"), X("aside"), Xend }; - static const TAG b6[] = { X("base"), X("basefont"), X("blockquote"), X("body"), Xend }; - static const TAG c6[] = { X("caption"), X("center"), X("col"), X("colgroup"), Xend }; - static const TAG d6[] = { X("dd"), X("details"), X("dialog"), X("dir"), - X("div"), X("dl"), X("dt"), Xend }; - static const TAG f6[] = { X("fieldset"), X("figcaption"), X("figure"), X("footer"), - X("form"), X("frame"), X("frameset"), Xend }; - static const TAG h6[] = { X("h1"), X("head"), X("header"), X("hr"), X("html"), Xend }; - static const TAG i6[] = { X("iframe"), Xend }; - static const TAG l6[] = { X("legend"), X("li"), X("link"), Xend }; - static const TAG m6[] = { X("main"), X("menu"), X("menuitem"), Xend }; - static const TAG n6[] = { X("nav"), X("noframes"), Xend }; - static const TAG o6[] = { X("ol"), X("optgroup"), X("option"), Xend }; - static const TAG p6[] = { X("p"), X("param"), Xend }; - static const TAG s6[] = { X("section"), X("source"), X("summary"), Xend }; - static const TAG t6[] = { X("table"), X("tbody"), X("td"), X("tfoot"), X("th"), - X("thead"), X("title"), X("tr"), X("track"), Xend }; - static const TAG u6[] = { X("ul"), Xend }; - static const TAG xx[] = { Xend }; -#undef X - static const TAG* map6[26] = { a6, b6, c6, d6, xx, f6, xx, h6, i6, xx, xx, l6, m6, n6, o6, p6, xx, xx, s6, t6, u6, xx, xx, xx, xx, xx @@ -5382,7 +5481,7 @@ md_is_html_block_start_condition(MD_CTX* ctx, OFF beg) /* Check for type 4 or 5: size && CH(off) == _T('!')) { /* Check for type 4: size && ISUPPER(off+1)) + if(off + 1 < ctx->size && ISASCII(off+1)) return 4; /* Check for type 5: size && !ISNEWLINE(off)) { - if(CH(off) == _T('<')) { - if(md_ascii_case_eq(STR(off), _T(""), 9)) { - *p_end = off + 9; - return TRUE; - } - - if(md_ascii_case_eq(STR(off), _T(""), 8)) { - *p_end = off + 8; - return TRUE; - } - - if(md_ascii_case_eq(STR(off), _T(""), 6)) { - *p_end = off + 6; - return TRUE; + while(off+1 < ctx->size && !ISNEWLINE(off)) { + if(CH(off) == _T('<') && CH(off+1) == _T('/')) { + for(i = 0; t1[i].name != NULL; i++) { + if(off + 2 + t1[i].len < ctx->size) { + if(md_ascii_case_eq(STR(off+2), t1[i].name, t1[i].len) && + CH(off+2+t1[i].len) == _T('>')) + { + *p_end = off+2+t1[i].len+1; + return TRUE; + } + } } } - off++; } *p_end = off; @@ -5505,8 +5600,12 @@ md_is_html_block_end_condition(MD_CTX* ctx, OFF beg, OFF* p_end) case 6: /* Pass through */ case 7: - *p_end = beg; - return (ISNEWLINE(beg) ? ctx->html_block_type : FALSE); + if(beg >= ctx->size || ISNEWLINE(beg)) { + /* Blank line ends types 6 and 7. */ + *p_end = beg; + return ctx->html_block_type; + } + return FALSE; default: MD_UNREACHABLE(); @@ -5684,6 +5783,7 @@ md_is_container_mark(MD_CTX* ctx, unsigned indent, OFF beg, OFF* p_end, MD_CONTA off++; } if(off > beg && + off < ctx->size && (CH(off) == _T('.') || CH(off) == _T(')')) && (off+1 >= ctx->size || ISBLANK(off+1) || ISNEWLINE(off+1))) { @@ -5717,7 +5817,7 @@ md_line_indentation(MD_CTX* ctx, unsigned total_indent, OFF beg, OFF* p_end) return indent - total_indent; } -static const MD_LINE_ANALYSIS md_dummy_blank_line = { MD_LINE_BLANK, 0, 0, 0, 0 }; +static const MD_LINE_ANALYSIS md_dummy_blank_line = { MD_LINE_BLANK, 0, 0, 0, 0, 0 }; /* Analyze type of the line and find some its properties. This serves as a * main input for determining type and boundaries of a block. */ @@ -5738,6 +5838,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, line->indent = md_line_indentation(ctx, total_indent, off, &off); total_indent += line->indent; line->beg = off; + line->enforce_new_block = FALSE; /* Given the indentation and block quote marks '>', determine how many of * the current containers are our parents. */ @@ -5879,20 +5980,26 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, * was a 2nd blank line at the beginning of the list item) and if * we would otherwise still belong to the list item, we enforce * the end of the list. */ - ctx->last_line_has_list_loosening_effect = FALSE; if(ctx->last_list_item_starts_with_two_blank_lines) { - if(n_parents > 0 && ctx->containers[n_parents-1].ch != _T('>') && + if(n_parents > 0 && n_parents == ctx->n_containers && + ctx->containers[n_parents-1].ch != _T('>') && n_brothers + n_children == 0 && ctx->current_block == NULL && ctx->n_block_bytes > (int) sizeof(MD_BLOCK)) { MD_BLOCK* top_block = (MD_BLOCK*) ((char*)ctx->block_bytes + ctx->n_block_bytes - sizeof(MD_BLOCK)); - if(top_block->type == MD_BLOCK_LI) + if(top_block->type == MD_BLOCK_LI) { n_parents--; + + line->indent = total_indent; + if(n_parents > 0) + line->indent -= MIN(line->indent, ctx->containers[n_parents-1].contents_indent); + } } ctx->last_list_item_starts_with_two_blank_lines = FALSE; } #endif + ctx->last_line_has_list_loosening_effect = FALSE; } /* Check whether we are Setext underline. */ @@ -5958,11 +6065,8 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, /* Check for indented code. * Note indented code block cannot interrupt a paragraph. */ - if(line->indent >= ctx->code_indent_offset && - (pivot_line->type == MD_LINE_BLANK || pivot_line->type == MD_LINE_INDENTEDCODE)) - { + if(line->indent >= ctx->code_indent_offset && (pivot_line->type != MD_LINE_TEXT)) { line->type = MD_LINE_INDENTEDCODE; - MD_ASSERT(line->indent >= ctx->code_indent_offset); line->indent -= ctx->code_indent_offset; line->data = 0; break; @@ -6031,10 +6135,13 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, } /* Check whether we are starting code fence. */ - if(off < ctx->size && ISANYOF2(off, _T('`'), _T('~'))) { + if(line->indent < ctx->code_indent_offset && + off < ctx->size && ISANYOF2(off, _T('`'), _T('~'))) + { if(md_is_opening_code_fence(ctx, off, &off)) { line->type = MD_LINE_FENCEDCODE; line->data = 1; + line->enforce_new_block = TRUE; break; } } @@ -6056,6 +6163,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, ctx->html_block_type = 0; } + line->enforce_new_block = TRUE; line->type = MD_LINE_HTML; break; } @@ -6100,7 +6208,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, task_container->is_task = TRUE; task_container->task_mark_off = tmp + 1; off = tmp + 3; - while(ISWHITESPACE(off)) + while(off < ctx->size && ISWHITESPACE(off)) off++; line->beg = off; } @@ -6154,7 +6262,7 @@ md_analyze_line(MD_CTX* ctx, OFF beg, OFF* p_end, } /* Trim trailing spaces. */ - if(line->type != MD_LINE_INDENTEDCODE && line->type != MD_LINE_FENCEDCODE) { + if(line->type != MD_LINE_INDENTEDCODE && line->type != MD_LINE_FENCEDCODE && line->type != MD_LINE_HTML) { while(line->end > line->beg && CH(line->end-1) == _T(' ')) line->end--; } @@ -6215,6 +6323,9 @@ md_process_line(MD_CTX* ctx, const MD_LINE_ANALYSIS** p_pivot_line, MD_LINE_ANAL return 0; } + if(line->enforce_new_block) + MD_CHECK(md_end_current_block(ctx)); + /* Some line types form block on their own. */ if(line->type == MD_LINE_HR || line->type == MD_LINE_ATXHEADER) { MD_CHECK(md_end_current_block(ctx)); @@ -6359,13 +6470,14 @@ md_parse(const MD_CHAR* text, MD_SIZE size, const MD_PARSER* parser, void* userd md_build_mark_char_map(&ctx); ctx.doc_ends_with_newline = (size > 0 && ISNEWLINE_(text[size-1])); - /* Reset all unresolved opener mark chains. */ - for(i = 0; i < (int) SIZEOF_ARRAY(ctx.mark_chains); i++) { - ctx.mark_chains[i].head = -1; - ctx.mark_chains[i].tail = -1; - } + /* Reset all mark stacks and lists. */ + for(i = 0; i < (int) SIZEOF_ARRAY(ctx.opener_stacks); i++) + ctx.opener_stacks[i].top = -1; + ctx.ptr_stack.top = -1; ctx.unresolved_link_head = -1; ctx.unresolved_link_tail = -1; + ctx.table_cell_boundaries_head = -1; + ctx.table_cell_boundaries_tail = -1; /* All the work. */ ret = md_process_doc(&ctx); diff --git a/src/3rdparty/md4c/md4c.h b/src/3rdparty/md4c/md4c.h index 95f78f9b9b9..8d6be1cb463 100644 --- a/src/3rdparty/md4c/md4c.h +++ b/src/3rdparty/md4c/md4c.h @@ -2,7 +2,7 @@ * MD4C: Markdown parser for C * (http://github.com/mity/md4c) * - * Copyright (c) 2016-2020 Martin Mitas + * Copyright (c) 2016-2024 Martin Mitáš * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -284,6 +284,7 @@ typedef struct MD_BLOCK_TD_DETAIL { typedef struct MD_SPAN_A_DETAIL { MD_ATTRIBUTE href; MD_ATTRIBUTE title; + int is_autolink; /* nonzero if this is an autolink */ } MD_SPAN_A_DETAIL; /* Detailed info for MD_SPAN_IMG. */ @@ -316,6 +317,7 @@ typedef struct MD_SPAN_WIKILINK { #define MD_FLAG_LATEXMATHSPANS 0x1000 /* Enable $ and $$ containing LaTeX equations. */ #define MD_FLAG_WIKILINKS 0x2000 /* Enable wiki links extension. */ #define MD_FLAG_UNDERLINE 0x4000 /* Enable underline extension (and disables '_' for normal emphasis). */ +#define MD_FLAG_HARD_SOFT_BREAKS 0x8000 /* Force all soft breaks to act as hard breaks. */ #define MD_FLAG_PERMISSIVEAUTOLINKS (MD_FLAG_PERMISSIVEEMAILAUTOLINKS | MD_FLAG_PERMISSIVEURLAUTOLINKS | MD_FLAG_PERMISSIVEWWWAUTOLINKS) #define MD_FLAG_NOHTML (MD_FLAG_NOHTMLBLOCKS | MD_FLAG_NOHTMLSPANS) diff --git a/src/3rdparty/md4c/qt_attribution.json b/src/3rdparty/md4c/qt_attribution.json index 29c0666f2d8..3a855eae8c4 100644 --- a/src/3rdparty/md4c/qt_attribution.json +++ b/src/3rdparty/md4c/qt_attribution.json @@ -9,7 +9,7 @@ "License": "MIT License", "LicenseId": "MIT", "LicenseFile": "LICENSE.md", - "Version": "0.4.8", - "DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.4.8", - "Copyright": "Copyright © 2016-2020 Martin Mitáš" + "Version": "0.5.2", + "DownloadLocation": "https://github.com/mity/md4c/releases/tag/release-0.5.2", + "Copyright": "Copyright © 2016-2024 Martin Mitáš" } diff --git a/src/3rdparty/pcre2/AUTHORS b/src/3rdparty/pcre2/AUTHORS index 11ef898b250..9669f7755ad 100644 --- a/src/3rdparty/pcre2/AUTHORS +++ b/src/3rdparty/pcre2/AUTHORS @@ -8,7 +8,7 @@ Email domain: gmail.com Retired from University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2022 University of Cambridge +Copyright (c) 1997-2024 University of Cambridge All rights reserved @@ -19,7 +19,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2010-2022 Zoltan Herczeg +Copyright(c) 2010-2024 Zoltan Herczeg All rights reserved. @@ -30,7 +30,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2009-2022 Zoltan Herczeg +Copyright(c) 2009-2024 Zoltan Herczeg All rights reserved. #### diff --git a/src/3rdparty/pcre2/CMakeLists.txt b/src/3rdparty/pcre2/CMakeLists.txt index f44d4bbd79c..bc0bc80f90b 100644 --- a/src/3rdparty/pcre2/CMakeLists.txt +++ b/src/3rdparty/pcre2/CMakeLists.txt @@ -12,6 +12,7 @@ qt_internal_add_3rdparty_library(BundledPcre2 src/pcre2.h src/pcre2_auto_possess.c src/pcre2_chartables.c + src/pcre2_chkdint.c src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c diff --git a/src/3rdparty/pcre2/LICENCE b/src/3rdparty/pcre2/LICENCE index 2f3cd5cac53..3c1ef032dec 100644 --- a/src/3rdparty/pcre2/LICENCE +++ b/src/3rdparty/pcre2/LICENCE @@ -26,7 +26,7 @@ Email domain: gmail.com Retired from University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2022 University of Cambridge +Copyright (c) 1997-2024 University of Cambridge All rights reserved. @@ -37,7 +37,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Email domain: freemail.hu -Copyright(c) 2010-2022 Zoltan Herczeg +Copyright(c) 2010-2024 Zoltan Herczeg All rights reserved. @@ -48,7 +48,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Email domain: freemail.hu -Copyright(c) 2009-2022 Zoltan Herczeg +Copyright(c) 2009-2024 Zoltan Herczeg All rights reserved. diff --git a/src/3rdparty/pcre2/import_from_pcre2_tarball.sh b/src/3rdparty/pcre2/import_from_pcre2_tarball.sh index 4a454b059be..007e0699a51 100755 --- a/src/3rdparty/pcre2/import_from_pcre2_tarball.sh +++ b/src/3rdparty/pcre2/import_from_pcre2_tarball.sh @@ -83,6 +83,7 @@ FILES=" LICENCE src/pcre2_auto_possess.c + src/pcre2_chkdint.c src/pcre2_compile.c src/pcre2_config.c src/pcre2_context.c @@ -115,9 +116,9 @@ FILES=" src/pcre2_ucptables.c src/pcre2_valid_utf.c src/pcre2_xclass.c + src/sljit/sljitConfigCPU.h src/sljit/sljitConfig.h src/sljit/sljitConfigInternal.h - src/sljit/sljitExecAllocator.c src/sljit/sljitLir.c src/sljit/sljitLir.h src/sljit/sljitNativeARM_32.c @@ -136,9 +137,15 @@ FILES=" src/sljit/sljitNativeX86_32.c src/sljit/sljitNativeX86_64.c src/sljit/sljitNativeX86_common.c - src/sljit/sljitProtExecAllocator.c - src/sljit/sljitUtils.c - src/sljit/sljitWXExecAllocator.c + src/sljit/allocator_src/sljitExecAllocatorPosix.c + src/sljit/allocator_src/sljitProtExecAllocatorPosix.c + src/sljit/allocator_src/sljitWXExecAllocatorPosix.c + src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c + src/sljit/allocator_src/sljitExecAllocatorWindows.c + src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c + src/sljit/allocator_src/sljitExecAllocatorApple.c + src/sljit/allocator_src/sljitWXExecAllocatorWindows.c + src/sljit/allocator_src/sljitExecAllocatorCore.c " for i in $FILES; do diff --git a/src/3rdparty/pcre2/qt_attribution.json b/src/3rdparty/pcre2/qt_attribution.json index 2d8c6586578..6dc8e9ceefc 100644 --- a/src/3rdparty/pcre2/qt_attribution.json +++ b/src/3rdparty/pcre2/qt_attribution.json @@ -7,13 +7,13 @@ "Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.", "Homepage": "http://www.pcre.org/", - "Version": "10.42", - "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.bz2", - "License": "BSD 3-clause \"New\" or \"Revised\" License", - "LicenseId": "BSD-3-Clause", + "Version": "10.43", + "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.43/pcre2-10.43.tar.bz2", + "License": "BSD 3-clause \"New\" or \"Revised\" License with PCRE2 binary-like Packages Exception", + "LicenseId": "LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception", "LicenseFile": "LICENCE", - "Copyright": "Copyright (c) 1997-2022 University of Cambridge -Copyright (c) 2010-2022 Zoltan Herczeg" + "Copyright": "Copyright (c) 1997-2024 University of Cambridge +Copyright (c) 2010-2024 Zoltan Herczeg" }, { "Id": "pcre2-sljit", @@ -24,11 +24,11 @@ Copyright (c) 2010-2022 Zoltan Herczeg" "Path": "src/sljit", "Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.", "Homepage": "http://www.pcre.org/", - "Version": "10.42", - "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.bz2", + "Version": "10.43", + "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.43/pcre2-10.43.tar.bz2", "License": "BSD 2-clause \"Simplified\" License", "LicenseId": "BSD-2-Clause", "LicenseFile": "LICENCE-SLJIT", - "Copyright": "Copyright (c) 2009-2022 Zoltan Herczeg" + "Copyright": "Copyright (c) 2009-2024 Zoltan Herczeg" } ] diff --git a/src/3rdparty/pcre2/src/config.h b/src/3rdparty/pcre2/src/config.h index eeade9d9ce2..72518dca5fc 100644 --- a/src/3rdparty/pcre2/src/config.h +++ b/src/3rdparty/pcre2/src/config.h @@ -14,13 +14,15 @@ #define MAX_NAME_SIZE 32 #define NEWLINE_DEFAULT 2 #define PARENS_NEST_LIMIT 250 +#define MAX_VARLOOKBEHIND 255 #define SUPPORT_UNICODE +#define PCRE2_EXPORT /* man 3 pcre2jit for a list of supported platforms; - as PCRE2 10.22, stable JIT support is available for: - - ARM 32-bit (v5, v7, and Thumb2) + as PCRE2 10.43, stable JIT support is available for: + - ARM 32-bit (v7 and Thumb2) - ARM 64-bit - Intel x86 32-bit and 64-bit - MIPS 32-bit and 64-bit @@ -32,7 +34,7 @@ #if !defined(PCRE2_DISABLE_JIT) && (\ /* ARM */ \ (defined(__GNUC__) \ - && (defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM) || defined(__aarch64__))) \ + && (defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__aarch64__))) \ /* x86 32/64 */ \ || defined(__i386) || defined(__i386__) || defined(_M_IX86) \ || defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64) \ diff --git a/src/3rdparty/pcre2/src/pcre2.h b/src/3rdparty/pcre2/src/pcre2.h index 1cbecd0e86e..d7a8ff5201e 100644 --- a/src/3rdparty/pcre2/src/pcre2.h +++ b/src/3rdparty/pcre2/src/pcre2.h @@ -5,7 +5,7 @@ /* This is the public header file for the PCRE library, second API, to be #included by applications that call PCRE2 functions. - Copyright (c) 2016-2021 University of Cambridge + Copyright (c) 2016-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE2_MAJOR 10 -#define PCRE2_MINOR 42 +#define PCRE2_MINOR 43 #define PCRE2_PRERELEASE -#define PCRE2_DATE 2022-12-11 +#define PCRE2_DATE 2024-02-16 /* When an application links to a PCRE DLL in Windows, the symbols that are imported have to be identified as such. When building PCRE2, the appropriate @@ -153,6 +153,12 @@ D is inspected during pcre2_dfa_match() execution #define PCRE2_EXTRA_ESCAPED_CR_IS_LF 0x00000010u /* C */ #define PCRE2_EXTRA_ALT_BSUX 0x00000020u /* C */ #define PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK 0x00000040u /* C */ +#define PCRE2_EXTRA_CASELESS_RESTRICT 0x00000080u /* C */ +#define PCRE2_EXTRA_ASCII_BSD 0x00000100u /* C */ +#define PCRE2_EXTRA_ASCII_BSS 0x00000200u /* C */ +#define PCRE2_EXTRA_ASCII_BSW 0x00000400u /* C */ +#define PCRE2_EXTRA_ASCII_POSIX 0x00000800u /* C */ +#define PCRE2_EXTRA_ASCII_DIGIT 0x00001000u /* C */ /* These are for pcre2_jit_compile(). */ @@ -180,11 +186,12 @@ pcre2_jit_match() ignores the latter since it bypasses all sanity checks). */ #define PCRE2_SUBSTITUTE_UNSET_EMPTY 0x00000400u /* pcre2_substitute() only */ #define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u /* pcre2_substitute() only */ #define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u /* pcre2_substitute() only */ -#define PCRE2_NO_JIT 0x00002000u /* Not for pcre2_dfa_match() */ +#define PCRE2_NO_JIT 0x00002000u /* not for pcre2_dfa_match() */ #define PCRE2_COPY_MATCHED_SUBJECT 0x00004000u #define PCRE2_SUBSTITUTE_LITERAL 0x00008000u /* pcre2_substitute() only */ #define PCRE2_SUBSTITUTE_MATCHED 0x00010000u /* pcre2_substitute() only */ #define PCRE2_SUBSTITUTE_REPLACEMENT_ONLY 0x00020000u /* pcre2_substitute() only */ +#define PCRE2_DISABLE_RECURSELOOP_CHECK 0x00040000u /* not for pcre2_dfa_match() or pcre2_jit_match() */ /* Options for pcre2_pattern_convert(). */ @@ -399,6 +406,7 @@ released, the numbers must not be changed. */ #define PCRE2_ERROR_CONVERT_SYNTAX (-64) #define PCRE2_ERROR_INTERNAL_DUPMATCH (-65) #define PCRE2_ERROR_DFA_UINVALID_UTF (-66) +#define PCRE2_ERROR_INVALIDOFFSET (-67) /* Request types for pcre2_pattern_info() */ @@ -575,7 +583,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION pcre2_config(uint32_t, void *); PCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \ pcre2_general_context_copy(pcre2_general_context *); \ PCRE2_EXP_DECL pcre2_general_context *PCRE2_CALL_CONVENTION \ - pcre2_general_context_create(void *(*)(PCRE2_SIZE, void *), \ + pcre2_general_context_create(void *(*)(size_t, void *), \ void (*)(void *, void *), void *); \ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ pcre2_general_context_free(pcre2_general_context *); @@ -595,6 +603,8 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_compile_extra_options(pcre2_compile_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_max_pattern_length(pcre2_compile_context *, PCRE2_SIZE); \ +PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ + pcre2_set_max_varlookbehind(pcre2_compile_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_newline(pcre2_compile_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ @@ -628,7 +638,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_recursion_limit(pcre2_match_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_recursion_memory_management(pcre2_match_context *, \ - void *(*)(PCRE2_SIZE, void *), void (*)(void *, void *), void *); + void *(*)(size_t, void *), void (*)(void *, void *), void *); #define PCRE2_CONVERT_CONTEXT_FUNCTIONS \ PCRE2_EXP_DECL pcre2_convert_context *PCRE2_CALL_CONVENTION \ @@ -687,6 +697,8 @@ PCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \ pcre2_get_mark(pcre2_match_data *); \ PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \ pcre2_get_match_data_size(pcre2_match_data *); \ +PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \ + pcre2_get_match_data_heapframes_size(pcre2_match_data *); \ PCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \ pcre2_get_ovector_count(pcre2_match_data *); \ PCRE2_EXP_DECL PCRE2_SIZE *PCRE2_CALL_CONVENTION \ @@ -722,7 +734,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_substring_number_from_name(const pcre2_code *, PCRE2_SPTR); \ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ - pcre2_substring_list_free(PCRE2_SPTR *); \ + pcre2_substring_list_free(PCRE2_UCHAR **); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_substring_list_get(pcre2_match_data *, PCRE2_UCHAR ***, PCRE2_SIZE **); @@ -771,7 +783,7 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ pcre2_jit_free_unused_memory(pcre2_general_context *); \ PCRE2_EXP_DECL pcre2_jit_stack *PCRE2_CALL_CONVENTION \ - pcre2_jit_stack_create(PCRE2_SIZE, PCRE2_SIZE, pcre2_general_context *); \ + pcre2_jit_stack_create(size_t, size_t, pcre2_general_context *); \ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ pcre2_jit_stack_assign(pcre2_match_context *, pcre2_jit_callback, void *); \ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \ @@ -851,6 +863,7 @@ pcre2_compile are called by application code. */ #define pcre2_general_context_free PCRE2_SUFFIX(pcre2_general_context_free_) #define pcre2_get_error_message PCRE2_SUFFIX(pcre2_get_error_message_) #define pcre2_get_mark PCRE2_SUFFIX(pcre2_get_mark_) +#define pcre2_get_match_data_heapframes_size PCRE2_SUFFIX(pcre2_get_match_data_heapframes_size_) #define pcre2_get_match_data_size PCRE2_SUFFIX(pcre2_get_match_data_size_) #define pcre2_get_ovector_pointer PCRE2_SUFFIX(pcre2_get_ovector_pointer_) #define pcre2_get_ovector_count PCRE2_SUFFIX(pcre2_get_ovector_count_) @@ -886,6 +899,7 @@ pcre2_compile are called by application code. */ #define pcre2_set_glob_separator PCRE2_SUFFIX(pcre2_set_glob_separator_) #define pcre2_set_heap_limit PCRE2_SUFFIX(pcre2_set_heap_limit_) #define pcre2_set_match_limit PCRE2_SUFFIX(pcre2_set_match_limit_) +#define pcre2_set_max_varlookbehind PCRE2_SUFFIX(pcre2_set_max_varlookbehind_) #define pcre2_set_max_pattern_length PCRE2_SUFFIX(pcre2_set_max_pattern_length_) #define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_) #define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_) diff --git a/src/3rdparty/pcre2/src/pcre2_auto_possess.c b/src/3rdparty/pcre2/src/pcre2_auto_possess.c index 419fd490018..210d13d37aa 100644 --- a/src/3rdparty/pcre2/src/pcre2_auto_possess.c +++ b/src/3rdparty/pcre2/src/pcre2_auto_possess.c @@ -560,6 +560,8 @@ matches to an empty string (also represented by a non-zero value). */ for(;;) { + PCRE2_SPTR bracode; + /* All operations move the code pointer forward. Therefore infinite recursions are not possible. */ @@ -617,7 +619,8 @@ for(;;) recursions. (This could be improved by keeping a list of group numbers that are called by recursion.) */ - switch(*(code - GET(code, 1))) + bracode = code - GET(code, 1); + switch(*bracode) { case OP_CBRA: case OP_SCBRA: @@ -636,16 +639,19 @@ for(;;) break; /* Atomic sub-patterns and assertions can always auto-possessify their - last iterator. However, if the group was entered as a result of checking - a previous iterator, this is not possible. */ + last iterator except for variable length lookbehinds. However, if the + group was entered as a result of checking a previous iterator, this is + not possible. */ case OP_ASSERT: case OP_ASSERT_NOT: - case OP_ASSERTBACK: - case OP_ASSERTBACK_NOT: case OP_ONCE: return !entered_a_group; + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + return (bracode[1+LINK_SIZE] == OP_VREVERSE)? FALSE : !entered_a_group; + /* Non-atomic assertions - don't possessify last iterator. This needs more thought. */ diff --git a/src/3rdparty/pcre2/src/pcre2_chartables.c b/src/3rdparty/pcre2/src/pcre2_chartables.c index 861914d1ac3..7362c3f2345 100644 --- a/src/3rdparty/pcre2/src/pcre2_chartables.c +++ b/src/3rdparty/pcre2/src/pcre2_chartables.c @@ -5,7 +5,8 @@ /* This file was automatically written by the pcre2_dftables auxiliary program. It contains character tables that are used when no external tables are passed to PCRE2 by the application that calls it. The tables -are used only for characters whose code values are less than 256. */ +are used only for characters whose code values are less than 256, and +only relevant if not in UCP mode. */ /* This set of tables was written in the C locale. */ @@ -18,13 +19,6 @@ PCRE2 is configured with --enable-rebuild-chartables. However, you can run pcre2_dftables manually with the -L option to build tables using the LC_ALL locale. */ -/* The following #include is present because without it gcc 4.x may remove -the array definition from the final binary if PCRE2 is built into a static -library and dead code stripping is activated. This leads to link errors. -Pulling in the header ensures that the array gets flagged as "someone -outside this compilation unit might reference this" and so it will always -be supplied to the linker. */ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -163,7 +157,7 @@ graph, print, punct, and cntrl. Other classes are built from combinations. */ 0x02 letter 0x04 lower case letter 0x08 decimal digit - 0x10 alphanumeric or '_' + 0x10 word (alphanumeric or '_') */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ diff --git a/src/3rdparty/pcre2/src/pcre2_chkdint.c b/src/3rdparty/pcre2/src/pcre2_chkdint.c new file mode 100644 index 00000000000..d04f6f8cf1a --- /dev/null +++ b/src/3rdparty/pcre2/src/pcre2_chkdint.c @@ -0,0 +1,96 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. + + Written by Philip Hazel + Copyright (c) 2023 University of Cambridge + +----------------------------------------------------------------------------- +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +----------------------------------------------------------------------------- +*/ + +/* This file contains functions to implement checked integer operation */ + +#ifndef PCRE2_PCRE2TEST +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" +#endif + +/************************************************* +* Checked Integer Multiplication * +*************************************************/ + +/* +Arguments: + r A pointer to PCRE2_SIZE to store the answer + a, b Two integers + +Returns: Bool indicating if the operation overflows + +It is modeled after C23's interface +The INT64_OR_DOUBLE type is a 64-bit integer type when available, +otherwise double. */ + +BOOL +PRIV(ckd_smul)(PCRE2_SIZE *r, int a, int b) +{ +#ifdef HAVE_BUILTIN_MUL_OVERFLOW +PCRE2_SIZE m; + +if (__builtin_mul_overflow(a, b, &m)) return TRUE; + +*r = m; +#else +INT64_OR_DOUBLE m; + +#ifdef PCRE2_DEBUG +if (a < 0 || b < 0) abort(); +#endif + +m = (INT64_OR_DOUBLE)a * (INT64_OR_DOUBLE)b; + +#if defined INT64_MAX || defined int64_t +if (sizeof(m) > sizeof(*r) && m > (INT64_OR_DOUBLE)PCRE2_SIZE_MAX) return TRUE; +*r = (PCRE2_SIZE)m; +#else +if (m > PCRE2_SIZE_MAX) return TRUE; +*r = m; +#endif + +#endif + +return FALSE; +} + +/* End of pcre_chkdint.c */ diff --git a/src/3rdparty/pcre2/src/pcre2_compile.c b/src/3rdparty/pcre2/src/pcre2_compile.c index edf7e82e6ee..8b364977c46 100644 --- a/src/3rdparty/pcre2/src/pcre2_compile.c +++ b/src/3rdparty/pcre2/src/pcre2_compile.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -118,17 +118,17 @@ them will be able to (i.e. assume a 64-bit world). */ #ifdef SUPPORT_UNICODE static unsigned int - add_list_to_class_internal(uint8_t *, PCRE2_UCHAR **, uint32_t, + add_list_to_class_internal(uint8_t *, PCRE2_UCHAR **, uint32_t, uint32_t, compile_block *, const uint32_t *, unsigned int); #endif static int - compile_regex(uint32_t, PCRE2_UCHAR **, uint32_t **, int *, uint32_t, - uint32_t *, uint32_t *, uint32_t *, uint32_t *, branch_chain *, - compile_block *, PCRE2_SIZE *); + compile_regex(uint32_t, uint32_t, PCRE2_UCHAR **, uint32_t **, int *, + uint32_t, uint32_t *, uint32_t *, uint32_t *, uint32_t *, branch_chain *, + open_capitem *, compile_block *, PCRE2_SIZE *); static int - get_branchlength(uint32_t **, int *, int *, parsed_recurse_check *, + get_branchlength(uint32_t **, int *, int *, int *, parsed_recurse_check *, compile_block *); static BOOL @@ -694,8 +694,8 @@ static uint32_t chartypeoffset[] = { now all in a single string, to reduce the number of relocations when a shared library is dynamically loaded. The list of lengths is terminated by a zero length entry. The first three must be alpha, lower, upper, as this is assumed -for handling case independence. The indices for graph, print, and punct are -needed, so identify them. */ +for handling case independence. The indices for several classes are needed, so +identify them. */ static const char posix_names[] = STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0 @@ -706,9 +706,11 @@ static const char posix_names[] = static const uint8_t posix_name_lengths[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; -#define PC_GRAPH 8 -#define PC_PRINT 9 -#define PC_PUNCT 10 +#define PC_DIGIT 7 +#define PC_GRAPH 8 +#define PC_PRINT 9 +#define PC_PUNCT 10 +#define PC_XDIGIT 13 /* Table of class bit maps for each POSIX class. Each class is formed from a base map, with an optional addition or removal of another map. Then, for some @@ -721,20 +723,20 @@ absolute value of the third field has these meanings: 0 => no tweaking, 1 => remove vertical space characters, 2 => remove underscore. */ static const int posix_class_maps[] = { - cbit_word, cbit_digit, -2, /* alpha */ - cbit_lower, -1, 0, /* lower */ - cbit_upper, -1, 0, /* upper */ - cbit_word, -1, 2, /* alnum - word without underscore */ - cbit_print, cbit_cntrl, 0, /* ascii */ - cbit_space, -1, 1, /* blank - a GNU extension */ - cbit_cntrl, -1, 0, /* cntrl */ - cbit_digit, -1, 0, /* digit */ - cbit_graph, -1, 0, /* graph */ - cbit_print, -1, 0, /* print */ - cbit_punct, -1, 0, /* punct */ - cbit_space, -1, 0, /* space */ - cbit_word, -1, 0, /* word - a Perl extension */ - cbit_xdigit,-1, 0 /* xdigit */ + cbit_word, cbit_digit, -2, /* alpha */ + cbit_lower, -1, 0, /* lower */ + cbit_upper, -1, 0, /* upper */ + cbit_word, -1, 2, /* alnum - word without underscore */ + cbit_print, cbit_cntrl, 0, /* ascii */ + cbit_space, -1, 1, /* blank - a GNU extension */ + cbit_cntrl, -1, 0, /* cntrl */ + cbit_digit, -1, 0, /* digit */ + cbit_graph, -1, 0, /* graph */ + cbit_print, -1, 0, /* print */ + cbit_punct, -1, 0, /* punct */ + cbit_space, -1, 0, /* space */ + cbit_word, -1, 0, /* word - a Perl extension */ + cbit_xdigit, -1, 0 /* xdigit */ }; #ifdef SUPPORT_UNICODE @@ -756,7 +758,7 @@ static int posix_substitutes[] = { PT_PXPUNCT, 0, /* punct */ PT_PXSPACE, 0, /* space */ /* Xps is POSIX space, but from 8.34 */ PT_WORD, 0, /* word */ /* Perl and POSIX space are the same */ - -1, 0 /* xdigit, treat as non-UCP */ + PT_PXXDIGIT, 0 /* xdigit */ /* Perl has additional hex digits */ }; #define POSIX_SUBSIZE (sizeof(posix_substitutes) / (2*sizeof(uint32_t))) #endif /* SUPPORT_UNICODE */ @@ -779,13 +781,15 @@ are allowed. */ PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_UCP|PCRE2_UNGREEDY) #define PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS \ - (PCRE2_EXTRA_MATCH_LINE|PCRE2_EXTRA_MATCH_WORD) + (PCRE2_EXTRA_MATCH_LINE|PCRE2_EXTRA_MATCH_WORD|PCRE2_EXTRA_CASELESS_RESTRICT) #define PUBLIC_COMPILE_EXTRA_OPTIONS \ (PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS| \ PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES|PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL| \ PCRE2_EXTRA_ESCAPED_CR_IS_LF|PCRE2_EXTRA_ALT_BSUX| \ - PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) + PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK|PCRE2_EXTRA_ASCII_BSD| \ + PCRE2_EXTRA_ASCII_BSS|PCRE2_EXTRA_ASCII_BSW|PCRE2_EXTRA_ASCII_POSIX| \ + PCRE2_EXTRA_ASCII_DIGIT) /* Compile time error code numbers. They are given names so that they can more easily be tracked. When a new number is added, the tables called eint1 and @@ -804,7 +808,7 @@ enum { ERR0 = COMPILE_ERROR_BASE, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90, - ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99 }; + ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99, ERR100 }; /* This is a table of start-of-pattern options such as (*UTF) and settings such as (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward @@ -817,7 +821,8 @@ enum { PSO_OPT, /* Value is an option bit */ PSO_BSR, /* Value is a \R type */ PSO_LIMH, /* Read integer value for heap limit */ PSO_LIMM, /* Read integer value for match limit */ - PSO_LIMD }; /* Read integer value for depth limit */ + PSO_LIMD /* Read integer value for depth limit */ + }; typedef struct pso { const uint8_t *name; @@ -828,7 +833,7 @@ typedef struct pso { /* NB: STRING_UTFn_RIGHTPAR contains the length as well */ -static pso pso_list[] = { +static const pso pso_list[] = { { (uint8_t *)STRING_UTFn_RIGHTPAR, PSO_OPT, PCRE2_UTF }, { (uint8_t *)STRING_UTF_RIGHTPAR, 4, PSO_OPT, PCRE2_UTF }, { (uint8_t *)STRING_UCP_RIGHTPAR, 4, PSO_OPT, PCRE2_UCP }, @@ -1059,24 +1064,24 @@ for (;;) case META_SKIP: fprintf(stderr, "META (*SKIP)"); break; case META_THEN: fprintf(stderr, "META (*THEN)"); break; - case META_OPTIONS: fprintf(stderr, "META_OPTIONS 0x%02x", *pptr++); break; + case META_OPTIONS: + fprintf(stderr, "META_OPTIONS 0x%08x 0x%08x", pptr[0], pptr[1]); + pptr += 2; + break; case META_LOOKBEHIND: - fprintf(stderr, "META (?<= %d offset=", meta_arg); - GETOFFSET(offset, pptr); - fprintf(stderr, "%zd", offset); + fprintf(stderr, "META (?<= %d %d", meta_arg, *pptr); + pptr += 2; break; case META_LOOKBEHIND_NA: - fprintf(stderr, "META (*naplb: %d offset=", meta_arg); - GETOFFSET(offset, pptr); - fprintf(stderr, "%zd", offset); + fprintf(stderr, "META (*naplb: %d %d", meta_arg, *pptr); + pptr += 2; break; case META_LOOKBEHINDNOT: - fprintf(stderr, "META (?= ptrend) return FALSE; - c = *p; - if (IS_DIGIT(c)) continue; - if (c == CHAR_RIGHT_CURLY_BRACKET) break; - if (c == CHAR_COMMA) - { - if (had_comma) return FALSE; - had_comma = TRUE; - } - else return FALSE; + had_minimum = TRUE; + while (++pp < ptrend && IS_DIGIT(*pp)) {} } -/* The only error from read_number() is for a number that is too big. */ +while (pp < ptrend && (*pp == CHAR_SPACE || *pp == CHAR_HT)) pp++; +if (pp >= ptrend) return FALSE; -p = *ptrptr; -if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &min, errorcodeptr)) - goto EXIT; - -if (*p == CHAR_RIGHT_CURLY_BRACKET) +if (*pp == CHAR_RIGHT_CURLY_BRACKET) { - p++; - max = min; + if (!had_minimum) return FALSE; } else { - if (*(++p) != CHAR_RIGHT_CURLY_BRACKET) + if (*pp++ != CHAR_COMMA) return FALSE; + while (pp < ptrend && (*pp == CHAR_SPACE || *pp == CHAR_HT)) pp++; + if (pp >= ptrend) return FALSE; + if (IS_DIGIT(*pp)) { - if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &max, - errorcodeptr)) - goto EXIT; + while (++pp < ptrend && IS_DIGIT(*pp)) {} + } + else if (!had_minimum) return FALSE; + while (pp < ptrend && (*pp == CHAR_SPACE || *pp == CHAR_HT)) pp++; + if (pp >= ptrend || *pp != CHAR_RIGHT_CURLY_BRACKET) return FALSE; + } + +/* Now process the quantifier for real. We know it must be {n} or (n,} or {,m} +or {n,m}. The only error that read_number() can return is for a number that is +too big. If *errorcodeptr is returned as zero it means no number was found. */ + +/* Deal with {,m} or n too big. If we successfully read m there is no need to +check m >= n because n defaults to zero. */ + +if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &min, errorcodeptr)) + { + if (*errorcodeptr != 0) goto EXIT; /* n too big */ + p++; /* Skip comma and subsequent spaces */ + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; + if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &max, errorcodeptr)) + { + if (*errorcodeptr != 0) goto EXIT; /* m too big */ + } + } + +/* Have read one number. Deal with {n} or {n,} or {n,m} */ + +else + { + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; + if (*p == CHAR_RIGHT_CURLY_BRACKET) + { + max = min; + } + else /* Handle {n,} or {n,m} */ + { + p++; /* Skip comma and subsequent spaces */ + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; + if (!read_number(&p, ptrend, -1, MAX_REPEAT_COUNT, ERR5, &max, errorcodeptr)) + { + if (*errorcodeptr != 0) goto EXIT; /* m too big */ + } + if (max < min) { *errorcodeptr = ERR4; goto EXIT; } } - p++; } +/* Valid quantifier exists */ + +while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; +p++; yield = TRUE; if (minp != NULL) *minp = (uint32_t)min; if (maxp != NULL) *maxp = (uint32_t)max; @@ -1491,6 +1536,7 @@ Arguments: chptr points to a returned data character errorcodeptr points to the errorcode variable (containing zero) options the current options bits + xoptions the current extra options bits isclass TRUE if inside a character class cb compile data block or NULL when called from pcre2_substitute() @@ -1502,10 +1548,12 @@ Returns: zero => a data character int PRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr, - int *errorcodeptr, uint32_t options, uint32_t extra_options, BOOL isclass, + int *errorcodeptr, uint32_t options, uint32_t xoptions, BOOL isclass, compile_block *cb) { BOOL utf = (options & PCRE2_UTF) != 0; +BOOL alt_bsux = + ((options & PCRE2_ALT_BSUX) | (xoptions & PCRE2_EXTRA_ALT_BSUX)) != 0; PCRE2_SPTR ptr = *ptrptr; uint32_t c, cc; int escape = 0; @@ -1539,7 +1587,7 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0) if (i > 0) { c = (uint32_t)i; - if (c == CHAR_CR && (extra_options & PCRE2_EXTRA_ESCAPED_CR_IS_LF) != 0) + if (c == CHAR_CR && (xoptions & PCRE2_EXTRA_ESCAPED_CR_IS_LF) != 0) c = CHAR_LF; } else /* Negative table entry */ @@ -1557,6 +1605,10 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0) { PCRE2_SPTR p = ptr + 1; + /* Perl ignores spaces and tabs after { */ + + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; + /* \N{U+ can be handled by the \x{ code. However, this construction is not valid in EBCDIC environments because it specifies a Unicode character, not a codepoint in the local code. For example \N{U+0041} @@ -1571,7 +1623,7 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0) #else if (utf) { - ptr = p + 1; + ptr = p + 2; escape = 0; /* Not a fancy escape after all */ goto COME_FROM_NU; } @@ -1602,8 +1654,6 @@ else int s; PCRE2_SPTR oldptr; BOOL overflow; - BOOL alt_bsux = - ((options & PCRE2_ALT_BSUX) | (extra_options & PCRE2_EXTRA_ALT_BSUX)) != 0; /* Filter calls from pcre2_substitute(). */ @@ -1632,7 +1682,9 @@ else is set. Otherwise, \u must be followed by exactly four hex digits or, if PCRE2_EXTRA_ALT_BSUX is set, by any number of hex digits in braces. Otherwise it is a lowercase u letter. This gives some compatibility with - ECMAScript (aka JavaScript). */ + ECMAScript (aka JavaScript). Unlike other braced items, white space is NOT + allowed. When \u{ is not followed by hex digits, a special return is given + because otherwise \u{ 12} (for example) would be treated as u{12}. */ case CHAR_u: if (!alt_bsux) *errorcodeptr = ERR37; else @@ -1641,11 +1693,11 @@ else if (ptr >= ptrend) break; if (*ptr == CHAR_LEFT_CURLY_BRACKET && - (extra_options & PCRE2_EXTRA_ALT_BSUX) != 0) + (xoptions & PCRE2_EXTRA_ALT_BSUX) != 0) { PCRE2_SPTR hptr = ptr + 1; - cc = 0; + cc = 0; while (hptr < ptrend && (xc = XDIGIT(*hptr)) != 0xff) { if ((cc & 0xf0000000) != 0) /* Test for 32-bit overflow */ @@ -1661,7 +1713,11 @@ else if (hptr == ptr + 1 || /* No hex digits */ hptr >= ptrend || /* Hit end of input */ *hptr != CHAR_RIGHT_CURLY_BRACKET) /* No } terminator */ - break; /* Hex escape not recognized */ + { + escape = ESC_ub; /* Special return */ + ptr++; /* Skip { */ + break; /* Hex escape not recognized */ + } c = cc; /* Accept the code point */ ptr = hptr + 1; @@ -1685,7 +1741,7 @@ else if (c > 0x10ffffU) *errorcodeptr = ERR77; else if (c >= 0xd800 && c <= 0xdfff && - (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) + (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) *errorcodeptr = ERR73; } else if (c > MAX_NON_UTF_CHAR) *errorcodeptr = ERR77; @@ -1741,12 +1797,16 @@ else if (*ptr == CHAR_LEFT_CURLY_BRACKET) { PCRE2_SPTR p = ptr + 1; + + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; if (!read_number(&p, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61, &s, errorcodeptr)) { if (*errorcodeptr == 0) escape = ESC_k; /* No number found */ break; } + while (p < ptrend && (*p == CHAR_SPACE || *p == CHAR_HT)) p++; + if (p >= ptrend || *p != CHAR_RIGHT_CURLY_BRACKET) { *errorcodeptr = ERR57; @@ -1842,56 +1902,64 @@ else break; /* \o is a relatively new Perl feature, supporting a more general way of - specifying character codes in octal. The only supported form is \o{ddd}. */ + specifying character codes in octal. The only supported form is \o{ddd}, + with optional spaces or tabs after { and before }. */ case CHAR_o: if (ptr >= ptrend || *ptr++ != CHAR_LEFT_CURLY_BRACKET) { ptr--; *errorcodeptr = ERR55; + break; } - else if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET) - *errorcodeptr = ERR78; - else + + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; + if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET) { - c = 0; - overflow = FALSE; - while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) - { - cc = *ptr++; - if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ + *errorcodeptr = ERR78; + break; + } + + c = 0; + overflow = FALSE; + while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) + { + cc = *ptr++; + if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ #if PCRE2_CODE_UNIT_WIDTH == 32 - if (c >= 0x20000000l) { overflow = TRUE; break; } + if (c >= 0x20000000l) { overflow = TRUE; break; } #endif - c = (c << 3) + (cc - CHAR_0); + c = (c << 3) + (cc - CHAR_0); #if PCRE2_CODE_UNIT_WIDTH == 8 - if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; } + if (c > (utf ? 0x10ffffU : 0xffU)) { overflow = TRUE; break; } #elif PCRE2_CODE_UNIT_WIDTH == 16 - if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; } + if (c > (utf ? 0x10ffffU : 0xffffU)) { overflow = TRUE; break; } #elif PCRE2_CODE_UNIT_WIDTH == 32 - if (utf && c > 0x10ffffU) { overflow = TRUE; break; } + if (utf && c > 0x10ffffU) { overflow = TRUE; break; } #endif - } - if (overflow) - { - while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++; - *errorcodeptr = ERR34; - } - else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET) - { - if (utf && c >= 0xd800 && c <= 0xdfff && - (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) - { - ptr--; - *errorcodeptr = ERR73; - } - } - else + } + + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; + + if (overflow) + { + while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++; + *errorcodeptr = ERR34; + } + else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET) + { + if (utf && c >= 0xd800 && c <= 0xdfff && + (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) { ptr--; - *errorcodeptr = ERR64; + *errorcodeptr = ERR73; } } + else + { + ptr--; + *errorcodeptr = ERR64; + } break; /* When PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX is set, \x must be followed @@ -1919,10 +1987,13 @@ else { if (ptr < ptrend && *ptr == CHAR_LEFT_CURLY_BRACKET) { + ptr++; + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; + #ifndef EBCDIC COME_FROM_NU: #endif - if (++ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET) + if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET) { *errorcodeptr = ERR78; break; @@ -1945,6 +2016,12 @@ else } } + /* Perl ignores spaces and tabs before } */ + + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; + + /* On overflow, skip remaining hex digits */ + if (overflow) { while (ptr < ptrend && XDIGIT(*ptr) != 0xff) ptr++; @@ -1953,17 +2030,17 @@ else else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET) { if (utf && c >= 0xd800 && c <= 0xdfff && - (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) + (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) { ptr--; *errorcodeptr = ERR73; } } - /* If the sequence of hex digits does not end with '}', give an error. - We used just to recognize this construct and fall through to the normal - \x handling, but nowadays Perl gives an error, which seems much more - sensible, so we do too. */ + /* If the sequence of hex digits (followed by optional space) does not + end with '}', give an error. We used just to recognize this construct + and fall through to the normal \x handling, but nowadays Perl gives an + error, which seems much more sensible, so we do too. */ else { @@ -2117,7 +2194,11 @@ if (c == CHAR_LEFT_CURLY_BRACKET) { if (ptr >= cb->end_pattern) goto ERROR_RETURN; c = *ptr++; +#if PCRE2_CODE_UNIT_WIDTH != 8 + while (c == '_' || c == '-' || (c <= 0xff && isspace(c))) +#else while (c == '_' || c == '-' || isspace(c)) +#endif { if (ptr >= cb->end_pattern) goto ERROR_RETURN; c = *ptr++; @@ -2355,12 +2436,13 @@ return -1; /* This function is called from parse_regex() below whenever it needs to read the name of a subpattern or a (*VERB) or an (*alpha_assertion). The initial -pointer must be to the character before the name. If that character is '*' we -are reading a verb or alpha assertion name. The pointer is updated to point -after the name, for a VERB or alpha assertion name, or after tha name's -terminator for a subpattern name. Returning both the offset and the name -pointer is redundant information, but some callers use one and some the other, -so it is simplest just to return both. +pointer must be to the preceding character. If that character is '*' we are +reading a verb or alpha assertion name. The pointer is updated to point after +the name, for a VERB or alpha assertion name, or after tha name's terminator +for a subpattern name. Returning both the offset and the name pointer is +redundant information, but some callers use one and some the other, so it is +simplest just to return both. When the name is in braces, spaces and tabs are +allowed (and ignored) at either end. Arguments: ptrptr points to the character pointer variable @@ -2383,9 +2465,13 @@ read_name(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, BOOL utf, uint32_t terminator, int *errorcodeptr, compile_block *cb) { PCRE2_SPTR ptr = *ptrptr; -BOOL is_group = (*ptr != CHAR_ASTERISK); +BOOL is_group = (*ptr++ != CHAR_ASTERISK); +BOOL is_braced = terminator == CHAR_RIGHT_CURLY_BRACKET; -if (++ptr >= ptrend) /* No characters in name */ +if (is_braced) + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; + +if (ptr >= ptrend) /* No characters in name */ { *errorcodeptr = is_group? ERR62: /* Subpattern name expected */ ERR60; /* Verb not recognized or malformed */ @@ -2464,6 +2550,8 @@ if (is_group) *errorcodeptr = ERR62; /* Subpattern name expected */ goto FAILED; } + if (is_braced) + while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++; if (ptr >= ptrend || *ptr != (PCRE2_UCHAR)terminator) { *errorcodeptr = ERR42; @@ -2532,6 +2620,85 @@ return parsed_pattern; +/************************************************* +* Handle \d, \D, \s, \S, \w, \W * +*************************************************/ + +/* This function is called from parse_regex() below, both for freestanding +escapes, and those within classes, to handle those escapes that may change when +Unicode property support is requested. Note that PCRE2_UCP will never be set +without Unicode support because that is checked when pcre2_compile() is called. + +Arguments: + escape the ESC_... value + parsed_pattern where to add the code + options options bits + xoptions extra options bits + +Returns: updated value of parsed_pattern +*/ +static uint32_t * +handle_escdsw(int escape, uint32_t *parsed_pattern, uint32_t options, + uint32_t xoptions) +{ +uint32_t ascii_option = 0; +uint32_t prop = ESC_p; + +switch(escape) + { + case ESC_D: + prop = ESC_P; + /* Fall through */ + case ESC_d: + ascii_option = PCRE2_EXTRA_ASCII_BSD; + break; + + case ESC_S: + prop = ESC_P; + /* Fall through */ + case ESC_s: + ascii_option = PCRE2_EXTRA_ASCII_BSS; + break; + + case ESC_W: + prop = ESC_P; + /* Fall through */ + case ESC_w: + ascii_option = PCRE2_EXTRA_ASCII_BSW; + break; + } + +if ((options & PCRE2_UCP) == 0 || (xoptions & ascii_option) != 0) + { + *parsed_pattern++ = META_ESCAPE + escape; + } +else + { + *parsed_pattern++ = META_ESCAPE + prop; + switch(escape) + { + case ESC_d: + case ESC_D: + *parsed_pattern++ = (PT_PC << 16) | ucp_Nd; + break; + + case ESC_s: + case ESC_S: + *parsed_pattern++ = PT_SPACE << 16; + break; + + case ESC_w: + case ESC_W: + *parsed_pattern++ = PT_WORD << 16; + break; + } + } + +return parsed_pattern; +} + + + /************************************************* * Parse regex and identify named groups * *************************************************/ @@ -2560,6 +2727,7 @@ typedef struct nest_save { uint16_t max_group; uint16_t flags; uint32_t options; + uint32_t xoptions; } nest_save; #define NSF_RESET 0x0001u @@ -2575,6 +2743,10 @@ the main compiling phase. */ PCRE2_EXTENDED|PCRE2_EXTENDED_MORE|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| \ PCRE2_UNGREEDY) +#define PARSE_TRACKED_EXTRA_OPTIONS (PCRE2_EXTRA_CASELESS_RESTRICT| \ + PCRE2_EXTRA_ASCII_BSD|PCRE2_EXTRA_ASCII_BSS|PCRE2_EXTRA_ASCII_BSW| \ + PCRE2_EXTRA_ASCII_DIGIT|PCRE2_EXTRA_ASCII_POSIX) + /* States used for analyzing ranges in character classes. The two OK values must be last. */ @@ -2609,9 +2781,11 @@ uint32_t *verbstartptr = NULL; uint32_t *previous_callout = NULL; uint32_t *parsed_pattern = cb->parsed_pattern; uint32_t *parsed_pattern_end = cb->parsed_pattern_end; +uint32_t *this_parsed_item = NULL; +uint32_t *prev_parsed_item = NULL; uint32_t meta_quantifier = 0; uint32_t add_after_mark = 0; -uint32_t extra_options = cb->cx->extra_options; +uint32_t xoptions = cb->cx->extra_options; uint16_t nest_depth = 0; int after_manual_callout = 0; int expect_cond_assert = 0; @@ -2635,12 +2809,12 @@ nest_save *top_nest, *end_nests; /* Insert leading items for word and line matching (features provided for the benefit of pcre2grep). */ -if ((extra_options & PCRE2_EXTRA_MATCH_LINE) != 0) +if ((xoptions & PCRE2_EXTRA_MATCH_LINE) != 0) { *parsed_pattern++ = META_CIRCUMFLEX; *parsed_pattern++ = META_NOCAPTURE; } -else if ((extra_options & PCRE2_EXTRA_MATCH_WORD) != 0) +else if ((xoptions & PCRE2_EXTRA_MATCH_WORD) != 0) { *parsed_pattern++ = META_ESCAPE + ESC_b; *parsed_pattern++ = META_NOCAPTURE; @@ -2691,6 +2865,7 @@ while (ptr < ptrend) int prev_expect_cond_assert; uint32_t min_repeat = 0, max_repeat = 0; uint32_t set, unset, *optset; + uint32_t xset, xunset, *xoptset; uint32_t terminator; uint32_t prev_meta_quantifier; BOOL prev_okquantifier; @@ -2709,6 +2884,17 @@ while (ptr < ptrend) goto FAILED; /* Parentheses too deeply nested */ } + /* If the last time round this loop something was added, parsed_pattern will + no longer be equal to this_parsed_item. Remember where the previous item + started and reset for the next item. Note that sometimes round the loop, + nothing gets added (e.g. for ignored white space). */ + + if (this_parsed_item != parsed_pattern) + { + prev_parsed_item = this_parsed_item; + this_parsed_item = parsed_pattern; + } + /* Get next input character, save its position for callout handling. */ thisptr = ptr; @@ -2817,7 +3003,7 @@ while (ptr < ptrend) if ((options & PCRE2_ALT_VERBNAMES) != 0) { escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - cb->cx->extra_options, FALSE, cb); + xoptions, FALSE, cb); if (errorcode != 0) goto FAILED; } else escape = 0; /* Treat all as literal */ @@ -2831,6 +3017,11 @@ while (ptr < ptrend) *parsed_pattern++ = c; break; + case ESC_ub: + *parsed_pattern++ = CHAR_u; + PARSED_LITERAL(CHAR_LEFT_CURLY_BRACKET, parsed_pattern); + break; + case ESC_Q: inescq = TRUE; break; @@ -2917,8 +3108,11 @@ while (ptr < ptrend) !read_repeat_counts(&tempptr, ptrend, NULL, NULL, &errorcode)))) { if (after_manual_callout-- <= 0) + { parsed_pattern = manage_callouts(thisptr, &previous_callout, auto_callout, parsed_pattern, cb); + this_parsed_item = parsed_pattern; /* New start for current item */ + } } /* If expect_cond_assert is 2, we have just passed (?( and are expecting an @@ -2995,7 +3189,6 @@ while (ptr < ptrend) continue; /* Next character in pattern */ } - /* Process the next item in the main part of a pattern. */ switch(c) @@ -3010,11 +3203,11 @@ while (ptr < ptrend) case CHAR_BACKSLASH: tempptr = ptr; escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - cb->cx->extra_options, FALSE, cb); + xoptions, FALSE, cb); if (errorcode != 0) { ESCAPE_FAILED: - if ((extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) + if ((xoptions & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) goto FAILED; ptr = tempptr; if (ptr >= ptrend) c = CHAR_BACKSLASH; else @@ -3088,6 +3281,16 @@ while (ptr < ptrend) *parsed_pattern++ = META_ESCAPE + escape; break; + /* This is a special return that happens only in EXTRA_ALT_BSUX mode, + when \u{ is not followed by hex digits and }. It requests two literal + characters, u and { and we need this, as otherwise \u{ 12} (for example) + would be treated as u{12} now that spaces are allowed in quantifiers. */ + + case ESC_ub: + *parsed_pattern++ = CHAR_u; + PARSED_LITERAL(CHAR_LEFT_CURLY_BRACKET, parsed_pattern); + break; + case ESC_X: #ifndef SUPPORT_UNICODE errorcode = ERR45; /* Supported only with Unicode support */ @@ -3107,9 +3310,7 @@ while (ptr < ptrend) *parsed_pattern++ = META_ESCAPE + escape; break; - /* Escapes that change in UCP mode. Note that PCRE2_UCP will never be set - without Unicode support because it is checked when pcre2_compile() is - called. */ + /* Escapes that may change in UCP mode. */ case ESC_d: case ESC_D: @@ -3118,33 +3319,8 @@ while (ptr < ptrend) case ESC_w: case ESC_W: okquantifier = TRUE; - if ((options & PCRE2_UCP) == 0) - { - *parsed_pattern++ = META_ESCAPE + escape; - } - else - { - *parsed_pattern++ = META_ESCAPE + - ((escape == ESC_d || escape == ESC_s || escape == ESC_w)? - ESC_p : ESC_P); - switch(escape) - { - case ESC_d: - case ESC_D: - *parsed_pattern++ = (PT_PC << 16) | ucp_Nd; - break; - - case ESC_s: - case ESC_S: - *parsed_pattern++ = PT_SPACE << 16; - break; - - case ESC_w: - case ESC_W: - *parsed_pattern++ = PT_WORD << 16; - break; - } - } + parsed_pattern = handle_escdsw(escape, parsed_pattern, options, + xoptions); break; /* Unicode property matching */ @@ -3206,7 +3382,8 @@ while (ptr < ptrend) if (errorcode != 0) goto ESCAPE_FAILED; } - /* Not a numerical recursion */ + /* Not a numerical recursion. Perl allows spaces and tabs after { and + before } but not for other delimiters. */ if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen, &errorcode, cb)) goto ESCAPE_FAILED; @@ -3273,7 +3450,8 @@ while (ptr < ptrend) /* ---- Quantifier post-processing ---- */ - /* Check that a quantifier is allowed after the previous item. */ + /* Check that a quantifier is allowed after the previous item. This + guarantees that there is a previous item. */ CHECK_QUANTIFIER: if (!prev_okquantifier) @@ -3288,7 +3466,7 @@ while (ptr < ptrend) wrapping it in non-capturing brackets, but we have to allow for a preceding (*MARK) for when (*ACCEPT) has an argument. */ - if (parsed_pattern[-1] == META_ACCEPT) + if (*prev_parsed_item == META_ACCEPT) { uint32_t *p; for (p = parsed_pattern - 1; p >= verbstartptr; p--) p[1] = p[0]; @@ -3507,18 +3685,24 @@ while (ptr < ptrend) class_range_state = RANGE_NO; - /* When PCRE2_UCP is set, some of the POSIX classes are converted to - use Unicode properties \p or \P or, in one case, \h or \H. The - substitutes table has two values per class, containing the type and - value of a \p or \P item. The special cases are specified with a - negative type: a non-zero value causes \h or \H to be used, and a zero - value falls through to behave like a non-UCP POSIX class. */ + /* When PCRE2_UCP is set, unless PCRE2_EXTRA_ASCII_POSIX is set, some + of the POSIX classes are converted to use Unicode properties \p or \P + or, in one case, \h or \H. The substitutes table has two values per + class, containing the type and value of a \p or \P item. The special + cases are specified with a negative type: a non-zero value causes \h or + \H to be used, and a zero value falls through to behave like a non-UCP + POSIX class. There are now also some extra options that force ASCII for + some classes. */ #ifdef SUPPORT_UNICODE - if ((options & PCRE2_UCP) != 0) + if ((options & PCRE2_UCP) != 0 && + (xoptions & PCRE2_EXTRA_ASCII_POSIX) == 0 && + !((xoptions & PCRE2_EXTRA_ASCII_DIGIT) != 0 && + (posix_class == PC_DIGIT || posix_class == PC_XDIGIT))) { int ptype = posix_substitutes[2*posix_class]; int pvalue = posix_substitutes[2*posix_class + 1]; + if (ptype >= 0) { *parsed_pattern++ = META_ESCAPE + (posix_negate? ESC_P : ESC_p); @@ -3587,11 +3771,11 @@ while (ptr < ptrend) { tempptr = ptr; escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - cb->cx->extra_options, TRUE, cb); + xoptions, TRUE, cb); if (errorcode != 0) { - if ((extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) + if ((xoptions & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) goto FAILED; ptr = tempptr; if (ptr >= ptrend) c = CHAR_BACKSLASH; else @@ -3605,7 +3789,7 @@ while (ptr < ptrend) { case 0: /* Escaped character code point is in c */ char_is_literal = FALSE; - goto CLASS_LITERAL; + goto CLASS_LITERAL; /* (a few lines above) */ case ESC_b: c = CHAR_BS; /* \b is backspace in a class */ @@ -3656,7 +3840,7 @@ while (ptr < ptrend) *parsed_pattern++ = META_ESCAPE + escape; break; - /* These escapes are converted to Unicode property tests when + /* These escapes may be converted to Unicode property tests when PCRE2_UCP is set. */ case ESC_d: @@ -3665,33 +3849,8 @@ while (ptr < ptrend) case ESC_S: case ESC_w: case ESC_W: - if ((options & PCRE2_UCP) == 0) - { - *parsed_pattern++ = META_ESCAPE + escape; - } - else - { - *parsed_pattern++ = META_ESCAPE + - ((escape == ESC_d || escape == ESC_s || escape == ESC_w)? - ESC_p : ESC_P); - switch(escape) - { - case ESC_d: - case ESC_D: - *parsed_pattern++ = (PT_PC << 16) | ucp_Nd; - break; - - case ESC_s: - case ESC_S: - *parsed_pattern++ = PT_SPACE << 16; - break; - - case ESC_w: - case ESC_W: - *parsed_pattern++ = PT_WORD << 16; - break; - } - } + parsed_pattern = handle_escdsw(escape, parsed_pattern, options, + xoptions); break; /* Explicit Unicode property matching */ @@ -3890,6 +4049,7 @@ while (ptr < ptrend) top_nest->nest_depth = nest_depth; top_nest->flags = NSF_ATOMICSR; top_nest->options = options & PARSE_TRACKED_OPTIONS; + top_nest->xoptions = xoptions & PARSE_TRACKED_EXTRA_OPTIONS; } break; #else /* SUPPORT_UNICODE */ @@ -4022,6 +4182,7 @@ while (ptr < ptrend) top_nest->nest_depth = nest_depth; top_nest->flags = 0; top_nest->options = options & PARSE_TRACKED_OPTIONS; + top_nest->xoptions = xoptions & PARSE_TRACKED_EXTRA_OPTIONS; /* Start of non-capturing group that resets the capture count for each branch. */ @@ -4036,24 +4197,28 @@ while (ptr < ptrend) ptr++; } - /* Scan for options imnsxJU to be set or unset. */ + /* Scan for options imnrsxJU to be set or unset. */ else { BOOL hyphenok = TRUE; uint32_t oldoptions = options; + uint32_t oldxoptions = xoptions; top_nest->reset_group = 0; top_nest->max_group = 0; set = unset = 0; optset = &set; + xset = xunset = 0; + xoptset = &xset; - /* ^ at the start unsets imnsx and disables the subsequent use of - */ + /* ^ at the start unsets irmnsx and disables the subsequent use of - */ if (ptr < ptrend && *ptr == CHAR_CIRCUMFLEX_ACCENT) { options &= ~(PCRE2_CASELESS|PCRE2_MULTILINE|PCRE2_NO_AUTO_CAPTURE| PCRE2_DOTALL|PCRE2_EXTENDED|PCRE2_EXTENDED_MORE); + xoptions &= ~(PCRE2_EXTRA_CASELESS_RESTRICT); hyphenok = FALSE; ptr++; } @@ -4071,9 +4236,51 @@ while (ptr < ptrend) goto FAILED; } optset = &unset; + xoptset = &xunset; hyphenok = FALSE; break; + /* There are some two-character sequences that start with 'a'. */ + + case CHAR_a: + if (ptr < ptrend) + { + if (*ptr == CHAR_D) + { + *xoptset |= PCRE2_EXTRA_ASCII_BSD; + ptr++; + break; + } + if (*ptr == CHAR_P) + { + *xoptset |= (PCRE2_EXTRA_ASCII_POSIX|PCRE2_EXTRA_ASCII_DIGIT); + ptr++; + break; + } + if (*ptr == CHAR_S) + { + *xoptset |= PCRE2_EXTRA_ASCII_BSS; + ptr++; + break; + } + if (*ptr == CHAR_T) + { + *xoptset |= PCRE2_EXTRA_ASCII_DIGIT; + ptr++; + break; + } + if (*ptr == CHAR_W) + { + *xoptset |= PCRE2_EXTRA_ASCII_BSW; + ptr++; + break; + } + } + *xoptset |= PCRE2_EXTRA_ASCII_BSD|PCRE2_EXTRA_ASCII_BSS| + PCRE2_EXTRA_ASCII_BSW| + PCRE2_EXTRA_ASCII_DIGIT|PCRE2_EXTRA_ASCII_POSIX; + break; + case CHAR_J: /* Record that it changed in the external options */ *optset |= PCRE2_DUPNAMES; cb->external_flags |= PCRE2_JCHANGED; @@ -4082,6 +4289,7 @@ while (ptr < ptrend) case CHAR_i: *optset |= PCRE2_CASELESS; break; case CHAR_m: *optset |= PCRE2_MULTILINE; break; case CHAR_n: *optset |= PCRE2_NO_AUTO_CAPTURE; break; + case CHAR_r: *xoptset|= PCRE2_EXTRA_CASELESS_RESTRICT; break; case CHAR_s: *optset |= PCRE2_DOTALL; break; case CHAR_U: *optset |= PCRE2_UNGREEDY; break; @@ -4112,6 +4320,7 @@ while (ptr < ptrend) unset |= PCRE2_EXTENDED_MORE; options = (options | set) & (~unset); + xoptions = (xoptions | xset) & (~xunset); /* If the options ended with ')' this is not the start of a nested group with option changes, so the options change at this level. @@ -4132,10 +4341,11 @@ while (ptr < ptrend) /* If nothing changed, no need to record. */ - if (options != oldoptions) + if (options != oldoptions || xoptions != oldxoptions) { *parsed_pattern++ = META_OPTIONS; *parsed_pattern++ = options; + *parsed_pattern++ = xoptions; } } /* End options processing */ break; /* End default case after (? */ @@ -4605,6 +4815,7 @@ while (ptr < ptrend) top_nest->nest_depth = nest_depth; top_nest->flags = NSF_CONDASSERT; top_nest->options = options & PARSE_TRACKED_OPTIONS; + top_nest->xoptions = xoptions & PARSE_TRACKED_EXTRA_OPTIONS; } break; @@ -4738,6 +4949,7 @@ while (ptr < ptrend) if (top_nest != NULL && top_nest->nest_depth == nest_depth) { options = (options & ~PARSE_TRACKED_OPTIONS) | top_nest->options; + xoptions = (xoptions & ~PARSE_TRACKED_EXTRA_OPTIONS) | top_nest->xoptions; if ((top_nest->flags & NSF_RESET) != 0 && top_nest->max_group > cb->bracount) cb->bracount = top_nest->max_group; @@ -4780,12 +4992,12 @@ parsed_pattern = manage_callouts(ptr, &previous_callout, auto_callout, /* Insert trailing items for word and line matching (features provided for the benefit of pcre2grep). */ -if ((extra_options & PCRE2_EXTRA_MATCH_LINE) != 0) +if ((xoptions & PCRE2_EXTRA_MATCH_LINE) != 0) { *parsed_pattern++ = META_KET; *parsed_pattern++ = META_DOLLAR; } -else if ((extra_options & PCRE2_EXTRA_MATCH_WORD) != 0) +else if ((xoptions & PCRE2_EXTRA_MATCH_WORD) != 0) { *parsed_pattern++ = META_KET; *parsed_pattern++ = META_ESCAPE + ESC_b; @@ -4862,6 +5074,8 @@ for (;;) case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: if (!skipassert) return code; /* Fall through */ @@ -4913,7 +5127,8 @@ for (;;) * Get othercase range * *************************************************/ -/* This function is passed the start and end of a class range in UCP mode. It +/* This function is passed the start and end of a class range in UCP mode. For +single characters the range may be just one character long. The function searches up the characters, looking for ranges of characters in the "other" case. Each call returns the next one, updating the start address. A character with multiple other cases is returned on its own with a special return value. @@ -4923,31 +5138,44 @@ Arguments: d end value ocptr where to put start of othercase range odptr where to put end of othercase range + restricted TRUE if caseless restriction applies Yield: -1 when no more 0 when a range is returned - >0 the CASESET offset for char with multiple other cases - in this case, ocptr contains the original + >0 the CASESET offset for char with multiple other cases; + for this return, *ocptr contains the original */ static int get_othercase_range(uint32_t *cptr, uint32_t d, uint32_t *ocptr, - uint32_t *odptr) + uint32_t *odptr, BOOL restricted) { uint32_t c, othercase, next; unsigned int co; /* Find the first character that has an other case. If it has multiple other -cases, return its case offset value. */ +cases, return its case offset value. When CASELESS_RESTRICT is set, ignore the +multi-case entries that begin with ASCII values. In 32-bit mode, a value +greater than the Unicode maximum ends the range. */ for (c = *cptr; c <= d; c++) { - if ((co = UCD_CASESET(c)) != 0) +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c > MAX_UTF_CODE_POINT) return -1; +#endif + if ((co = UCD_CASESET(c)) != 0 && + (!restricted || PRIV(ucd_caseless_sets)[co] > 127)) { *ocptr = c++; /* Character that has the set */ *cptr = c; /* Rest of input range */ return (int)co; } + + /* This is not a valid multiple-case character. Check that the single other + case is different to the original. We don't need to check "restricted" here + because the non-ASCII characters with multiple cases that include an ASCII + character don't have a different "othercase". */ + if ((othercase = UCD_OTHERCASE(c)) != c) break; } @@ -4988,7 +5216,8 @@ add_to_class(). Arguments: classbits the bit map for characters < 256 uchardptr points to the pointer for extra data - options the options word + options the options bits + xoptions the extra options bits cb compile data start start of range character end end of range character @@ -4999,7 +5228,8 @@ Returns: the number of < 256 characters added static unsigned int add_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr, - uint32_t options, compile_block *cb, uint32_t start, uint32_t end) + uint32_t options, uint32_t xoptions, compile_block *cb, uint32_t start, + uint32_t end) { uint32_t c; uint32_t classbits_end = (end <= 0xff ? end : 0xff); @@ -5007,8 +5237,8 @@ unsigned int n8 = 0; /* If caseless matching is required, scan the range and process alternate cases. In Unicode, there are 8-bit characters that have alternate cases that -are greater than 255 and vice-versa. Sometimes we can just extend the original -range. */ +are greater than 255 and vice-versa (though these may be ignored if caseless +restriction is in force). Sometimes we can just extend the original range. */ if ((options & PCRE2_CASELESS) != 0) { @@ -5021,20 +5251,23 @@ if ((options & PCRE2_CASELESS) != 0) options &= ~PCRE2_CASELESS; /* Remove for recursive calls */ c = start; - while ((rc = get_othercase_range(&c, end, &oc, &od)) >= 0) + while ((rc = get_othercase_range(&c, end, &oc, &od, + (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0)) >= 0) { /* Handle a single character that has more than one other case. */ - if (rc > 0) n8 += add_list_to_class_internal(classbits, uchardptr, options, cb, - PRIV(ucd_caseless_sets) + rc, oc); + if (rc > 0) n8 += add_list_to_class_internal(classbits, uchardptr, + options, xoptions, cb, PRIV(ucd_caseless_sets) + rc, oc); /* Do nothing if the other case range is within the original range. */ - else if (oc >= cb->class_range_start && od <= cb->class_range_end) continue; + else if (oc >= cb->class_range_start && od <= cb->class_range_end) + continue; - /* Extend the original range if there is overlap, noting that if oc < c, we - can't have od > end because a subrange is always shorter than the basic - range. Otherwise, use a recursive call to add the additional range. */ + /* Extend the original range if there is overlap, noting that if oc < c, + we can't have od > end because a subrange is always shorter than the + basic range. Otherwise, use a recursive call to add the additional range. + */ else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */ else if (od > end && oc <= end + 1) @@ -5042,10 +5275,13 @@ if ((options & PCRE2_CASELESS) != 0) end = od; /* Extend upwards */ if (end > classbits_end) classbits_end = (end <= 0xff ? end : 0xff); } - else n8 += add_to_class_internal(classbits, uchardptr, options, cb, oc, od); + else n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, + cb, oc, od); } } else +#else + (void)xoptions; /* Avoid compiler warning */ #endif /* SUPPORT_UNICODE */ /* Not UTF mode */ @@ -5141,7 +5377,8 @@ add_to_class_internal(), with which it is mutually recursive. Arguments: classbits the bit map for characters < 256 uchardptr points to the pointer for extra data - options the options word + options the options bits + xoptions the extra options bits cb contains pointers to tables etc. p points to row of 32-bit values, terminated by NOTACHAR except character to omit; this is used when adding lists of @@ -5154,7 +5391,8 @@ Returns: the number of < 256 characters added static unsigned int add_list_to_class_internal(uint8_t *classbits, PCRE2_UCHAR **uchardptr, - uint32_t options, compile_block *cb, const uint32_t *p, unsigned int except) + uint32_t options, uint32_t xoptions, compile_block *cb, const uint32_t *p, + unsigned int except) { unsigned int n8 = 0; while (p[0] < NOTACHAR) @@ -5163,7 +5401,8 @@ while (p[0] < NOTACHAR) if (p[0] != except) { while(p[n+1] == p[0] + n + 1) n++; - n8 += add_to_class_internal(classbits, uchardptr, options, cb, p[0], p[n]); + n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, cb, + p[0], p[n]); } p += n + 1; } @@ -5183,7 +5422,8 @@ to avoid duplication when handling case-independence. Arguments: classbits the bit map for characters < 256 uchardptr points to the pointer for extra data - options the options word + options the options bits + xoptions the extra options bits cb compile data start start of range character end end of range character @@ -5194,11 +5434,12 @@ Returns: the number of < 256 characters added static unsigned int add_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, - compile_block *cb, uint32_t start, uint32_t end) + uint32_t xoptions, compile_block *cb, uint32_t start, uint32_t end) { cb->class_range_start = start; cb->class_range_end = end; -return add_to_class_internal(classbits, uchardptr, options, cb, start, end); +return add_to_class_internal(classbits, uchardptr, options, xoptions, cb, + start, end); } @@ -5215,7 +5456,8 @@ case-independence. Arguments: classbits the bit map for characters < 256 uchardptr points to the pointer for extra data - options the options word + options the options bits + xoptions the extra options bits cb contains pointers to tables etc. p points to row of 32-bit values, terminated by NOTACHAR except character to omit; this is used when adding lists of @@ -5228,7 +5470,7 @@ Returns: the number of < 256 characters added static unsigned int add_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, uint32_t options, - compile_block *cb, const uint32_t *p, unsigned int except) + uint32_t xoptions, compile_block *cb, const uint32_t *p, unsigned int except) { unsigned int n8 = 0; while (p[0] < NOTACHAR) @@ -5239,7 +5481,8 @@ while (p[0] < NOTACHAR) while(p[n+1] == p[0] + n + 1) n++; cb->class_range_start = p[0]; cb->class_range_end = p[n]; - n8 += add_to_class_internal(classbits, uchardptr, options, cb, p[0], p[n]); + n8 += add_to_class_internal(classbits, uchardptr, options, xoptions, cb, + p[0], p[n]); } p += n + 1; } @@ -5258,7 +5501,8 @@ vertical whitespace to a class. The list must be in order. Arguments: classbits the bit map for characters < 256 uchardptr points to the pointer for extra data - options the options word + options the options bits + xoptions the extra options bits cb contains pointers to tables etc. p points to row of 32-bit values, terminated by NOTACHAR @@ -5268,16 +5512,16 @@ Returns: the number of < 256 characters added static unsigned int add_not_list_to_class(uint8_t *classbits, PCRE2_UCHAR **uchardptr, - uint32_t options, compile_block *cb, const uint32_t *p) + uint32_t options, uint32_t xoptions, compile_block *cb, const uint32_t *p) { BOOL utf = (options & PCRE2_UTF) != 0; unsigned int n8 = 0; if (p[0] > 0) - n8 += add_to_class(classbits, uchardptr, options, cb, 0, p[0] - 1); + n8 += add_to_class(classbits, uchardptr, options, xoptions, cb, 0, p[0] - 1); while (p[0] < NOTACHAR) { while (p[1] == p[0] + 1) p++; - n8 += add_to_class(classbits, uchardptr, options, cb, p[0] + 1, + n8 += add_to_class(classbits, uchardptr, options, xoptions, cb, p[0] + 1, (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1); p++; } @@ -5368,6 +5612,7 @@ real compile phase. The value of lengthptr distinguishes the two phases. Arguments: optionsptr pointer to the option bits + xoptionsptr pointer to the extra option bits codeptr points to the pointer to the current code point pptrptr points to the current parsed pattern pointer errorcodeptr points to error code variable @@ -5376,6 +5621,7 @@ Arguments: reqcuptr place to put the last required code unit reqcuflagsptr place to put the last required code unit flags bcptr points to current branch chain + open_caps points to current capitem cb contains pointers to tables etc. lengthptr NULL during the real compile phase points to length accumulator during pre-compile phase @@ -5386,9 +5632,10 @@ Returns: 0 There's been an error, *errorcodeptr is non-zero */ static int -compile_branch(uint32_t *optionsptr, PCRE2_UCHAR **codeptr, uint32_t **pptrptr, - int *errorcodeptr, uint32_t *firstcuptr, uint32_t *firstcuflagsptr, - uint32_t *reqcuptr, uint32_t *reqcuflagsptr, branch_chain *bcptr, +compile_branch(uint32_t *optionsptr, uint32_t *xoptionsptr, + PCRE2_UCHAR **codeptr, uint32_t **pptrptr, int *errorcodeptr, + uint32_t *firstcuptr, uint32_t *firstcuflagsptr, uint32_t *reqcuptr, + uint32_t *reqcuflagsptr, branch_chain *bcptr, open_capitem *open_caps, compile_block *cb, PCRE2_SIZE *lengthptr) { int bravalue = 0; @@ -5398,6 +5645,7 @@ uint32_t repeat_min = 0, repeat_max = 0; /* To please picky compilers */ uint32_t greedy_default, greedy_non_default; uint32_t repeat_type, op_type; uint32_t options = *optionsptr; /* May change dynamically */ +uint32_t xoptions = *xoptionsptr; /* May change dynamically */ uint32_t firstcu, reqcu; uint32_t zeroreqcu, zerofirstcu; uint32_t escape; @@ -5423,8 +5671,8 @@ const uint8_t *cbits = cb->cbits; uint8_t classbits[32]; /* We can fish out the UTF setting once and for all into a BOOL, but we must -not do this for other options (e.g. PCRE2_EXTENDED) because they may change -dynamically as we process the pattern. */ +not do this for other options (e.g. PCRE2_EXTENDED) that may change dynamically +as we process the pattern. */ #ifdef SUPPORT_UNICODE BOOL utf = (options & PCRE2_UTF) != 0; @@ -5633,8 +5881,8 @@ for (;; pptr++) If the class contains characters outside the 0-255 range, a different opcode is compiled. It may optionally have a bit map for characters < 256, - but those above are are explicitly listed afterwards. A flag code unit - tells whether the bitmap is present, and whether this is a negated class or + but those above are explicitly listed afterwards. A flag code unit tells + whether the bitmap is present, and whether this is a negated class or not. */ case META_CLASS_NOT: @@ -5675,11 +5923,14 @@ for (;; pptr++) /* For caseless UTF or UCP mode, check whether this character has more than one other case. If so, generate a special OP_NOTPROP item instead of - OP_NOTI. */ + OP_NOTI. When restricted by PCRE2_EXTRA_CASELESS_RESTRICT, ignore any + caseless set that starts with an ASCII character. */ #ifdef SUPPORT_UNICODE if ((utf||ucp) && (options & PCRE2_CASELESS) != 0 && - (d = UCD_CASESET(c)) != 0) + (d = UCD_CASESET(c)) != 0 && + ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) == 0 || + PRIV(ucd_caseless_sets)[d] > 127)) { *code++ = OP_NOTPROP; *code++ = PT_CLIST; @@ -5687,7 +5938,7 @@ for (;; pptr++) break; /* We are finished with this class */ } #endif - /* Char has only one other case, or UCP not available */ + /* Char has only one other (usable) case, or UCP not available */ *code++ = ((options & PCRE2_CASELESS) != 0)? OP_NOTI: OP_NOT; code += PUTCHAR(c, code); @@ -5697,7 +5948,9 @@ for (;; pptr++) /* Handle character classes that contain more than just one literal character. If there are exactly two characters in a positive class, see if they are case partners. This can be optimized to generate a caseless single - character match (which also sets first/required code units if relevant). */ + character match (which also sets first/required code units if relevant). + When casing restrictions apply, ignore a caseless set if both characters + are ASCII. */ if (meta == META_CLASS && pptr[1] < META_END && pptr[2] < META_END && pptr[3] == META_CLASS_END) @@ -5705,7 +5958,9 @@ for (;; pptr++) uint32_t c = pptr[1]; #ifdef SUPPORT_UNICODE - if (UCD_CASESET(c) == 0) + if (UCD_CASESET(c) == 0 || + ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) != 0 && + c < 128 && pptr[2] < 128)) #endif { uint32_t d; @@ -5797,41 +6052,45 @@ for (;; pptr++) XCL_PROP/XCL_NOTPROP directly, which is done here. */ #ifdef SUPPORT_UNICODE - if ((options & PCRE2_UCP) != 0) switch(posix_class) + if ((options & PCRE2_UCP) != 0 && + (xoptions & PCRE2_EXTRA_ASCII_POSIX) == 0) { - case PC_GRAPH: - case PC_PRINT: - case PC_PUNCT: - *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; - *class_uchardata++ = (PCRE2_UCHAR) - ((posix_class == PC_GRAPH)? PT_PXGRAPH : - (posix_class == PC_PRINT)? PT_PXPRINT : PT_PXPUNCT); - *class_uchardata++ = 0; - xclass_has_prop = TRUE; - goto CONTINUE_CLASS; + switch(posix_class) + { + case PC_GRAPH: + case PC_PRINT: + case PC_PUNCT: + *class_uchardata++ = local_negate? XCL_NOTPROP : XCL_PROP; + *class_uchardata++ = (PCRE2_UCHAR) + ((posix_class == PC_GRAPH)? PT_PXGRAPH : + (posix_class == PC_PRINT)? PT_PXPRINT : PT_PXPUNCT); + *class_uchardata++ = 0; + xclass_has_prop = TRUE; + goto CONTINUE_CLASS; - /* For the other POSIX classes (ascii, xdigit) we are going to - fall through to the non-UCP case and build a bit map for - characters with code points less than 256. However, if we are in - a negated POSIX class, characters with code points greater than - 255 must either all match or all not match, depending on whether - the whole class is not or is negated. For example, for - [[:^ascii:]... they must all match, whereas for [^[:^xdigit:]... - they must not. + /* For the other POSIX classes (ex: ascii) we are going to + fall through to the non-UCP case and build a bit map for + characters with code points less than 256. However, if we are in + a negated POSIX class, characters with code points greater than + 255 must either all match or all not match, depending on whether + the whole class is not or is negated. For example, for + [[:^ascii:]... they must all match, whereas for [^[:^ascii:]... + they must not. - In the special case where there are no xclass items, this is - automatically handled by the use of OP_CLASS or OP_NCLASS, but an - explicit range is needed for OP_XCLASS. Setting a flag here - causes the range to be generated later when it is known that - OP_XCLASS is required. In the 8-bit library this is relevant only in - utf mode, since no wide characters can exist otherwise. */ + In the special case where there are no xclass items, this is + automatically handled by the use of OP_CLASS or OP_NCLASS, but an + explicit range is needed for OP_XCLASS. Setting a flag here + causes the range to be generated later when it is known that + OP_XCLASS is required. In the 8-bit library this is relevant only in + utf mode, since no wide characters can exist otherwise. */ - default: + default: #if PCRE2_CODE_UNIT_WIDTH == 8 - if (utf) + if (utf) #endif - match_all_or_no_wide_chars |= local_negate; - break; + match_all_or_no_wide_chars |= local_negate; + break; + } } #endif /* SUPPORT_UNICODE */ @@ -5957,22 +6216,24 @@ for (;; pptr++) case ESC_h: (void)add_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, cb, PRIV(hspace_list), NOTACHAR); + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(hspace_list), + NOTACHAR); break; case ESC_H: (void)add_not_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, cb, PRIV(hspace_list)); + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(hspace_list)); break; case ESC_v: (void)add_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, cb, PRIV(vspace_list), NOTACHAR); + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(vspace_list), + NOTACHAR); break; case ESC_V: (void)add_not_list_to_class(classbits, &class_uchardata, - options & ~PCRE2_CASELESS, cb, PRIV(vspace_list)); + options & ~PCRE2_CASELESS, xoptions, cb, PRIV(vspace_list)); break; /* If Unicode is not supported, \P and \p are not allowed and are @@ -6046,32 +6307,32 @@ for (;; pptr++) if (C <= CHAR_i) { class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, C + uc, - ((D < CHAR_i)? D : CHAR_i) + uc); + add_to_class(classbits, &class_uchardata, options, xoptions, + cb, C + uc, ((D < CHAR_i)? D : CHAR_i) + uc); C = CHAR_j; } if (C <= D && C <= CHAR_r) { class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, C + uc, - ((D < CHAR_r)? D : CHAR_r) + uc); + add_to_class(classbits, &class_uchardata, options, xoptions, + cb, C + uc, ((D < CHAR_r)? D : CHAR_r) + uc); C = CHAR_s; } if (C <= D) { class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, C + uc, - D + uc); + add_to_class(classbits, &class_uchardata, options, xoptions, + cb, C + uc, D + uc); } } else #endif /* Not an EBCDIC special range */ - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, c, d); + class_has_8bitchar += add_to_class(classbits, &class_uchardata, + options, xoptions, cb, c, d); goto CONTINUE_CLASS; /* Go get the next char in the class */ } /* End of range handling */ @@ -6079,7 +6340,8 @@ for (;; pptr++) /* Handle a single character. */ class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cb, meta, meta); + add_to_class(classbits, &class_uchardata, options, xoptions, cb, + meta, meta); } /* Continue to the next item in the class. */ @@ -6124,11 +6386,11 @@ for (;; pptr++) characters > 255 are in or not in the class, so any that were explicitly given as well can be ignored. - In the UCP case, if certain negated POSIX classes ([:^ascii:] or - [^:xdigit:]) were present in a class, we either have to match or not match - all wide characters (depending on whether the whole class is or is not - negated). This requirement is indicated by match_all_or_no_wide_chars being - true. We do this by including an explicit range, which works in both cases. + In the UCP case, if certain negated POSIX classes (ex: [:^ascii:]) were + were present in a class, we either have to match or not match all wide + characters (depending on whether the whole class is or is not negated). + This requirement is indicated by match_all_or_no_wide_chars being true. + We do this by including an explicit range, which works in both cases. This applies only in UTF and 16-bit and 32-bit non-UTF modes, since there cannot be any wide characters in 8-bit non-UTF mode. @@ -6232,7 +6494,7 @@ for (;; pptr++) case META_ACCEPT: cb->had_accept = had_accept = TRUE; - for (oc = cb->open_caps; + for (oc = open_caps; oc != NULL && oc->assert_depth >= cb->assert_depth; oc = oc->next) { @@ -6317,6 +6579,7 @@ for (;; pptr++) case META_OPTIONS: *optionsptr = options = *(++pptr); + *xoptionsptr = xoptions = *(++pptr); greedy_default = ((options & PCRE2_UNGREEDY) != 0); greedy_non_default = greedy_default ^ 1; req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0; @@ -6562,7 +6825,8 @@ for (;; pptr++) if ((group_return = compile_regex( - options, /* The option state */ + options, /* The options state */ + xoptions, /* The extra options state */ &tempcode, /* Where to put code (updated) */ &pptr, /* Input pointer (updated) */ errorcodeptr, /* Where to put an error message */ @@ -6572,6 +6836,7 @@ for (;; pptr++) &subreqcu, /* For possible last char */ &subreqcuflags, bcptr, /* Current branch chain */ + open_caps, /* Pointer to capture stack */ cb, /* Compile data block */ (lengthptr == NULL)? NULL : /* Actual compile phase */ &length_prevgroup /* Pre-compile phase */ @@ -7112,15 +7377,12 @@ for (;; pptr++) /* In the pre-compile phase, we don't actually do the replication. We just adjust the length as if we had. Do some paranoid checks for - potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit - integer type when available, otherwise double. */ + potential integer overflow. */ if (lengthptr != NULL) { - PCRE2_SIZE delta = replicate*(1 + LINK_SIZE); - if ((INT64_OR_DOUBLE)replicate* - (INT64_OR_DOUBLE)(1 + LINK_SIZE) > - (INT64_OR_DOUBLE)INT_MAX || + PCRE2_SIZE delta; + if (PRIV(ckd_smul)(&delta, replicate, 1 + LINK_SIZE) || OFLOW_MAX - *lengthptr < delta) { *errorcodeptr = ERR20; @@ -7282,15 +7544,12 @@ for (;; pptr++) { /* In the pre-compile phase, we don't actually do the replication. We just adjust the length as if we had. Do some paranoid checks for - potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit - integer type when available, otherwise double. */ + potential integer overflow. */ if (lengthptr != NULL) { - PCRE2_SIZE delta = (repeat_min - 1)*length_prevgroup; - if ((INT64_OR_DOUBLE)(repeat_min - 1)* - (INT64_OR_DOUBLE)length_prevgroup > - (INT64_OR_DOUBLE)INT_MAX || + PCRE2_SIZE delta; + if (PRIV(ckd_smul)(&delta, repeat_min - 1, length_prevgroup) || OFLOW_MAX - *lengthptr < delta) { *errorcodeptr = ERR20; @@ -7334,21 +7593,19 @@ for (;; pptr++) just adjust the length as if we had. For each repetition we must add 1 to the length for BRAZERO and for all but the last repetition we must add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some - paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type - is a 64-bit integer type when available, otherwise double. */ + paranoid checks to avoid integer overflow. */ if (lengthptr != NULL && repeat_max > 0) { - PCRE2_SIZE delta = repeat_max*(length_prevgroup + 1 + 2 + 2*LINK_SIZE) - - 2 - 2*LINK_SIZE; /* Last one doesn't nest */ - if ((INT64_OR_DOUBLE)repeat_max * - (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE) - > (INT64_OR_DOUBLE)INT_MAX || - OFLOW_MAX - *lengthptr < delta) + PCRE2_SIZE delta; + if (PRIV(ckd_smul)(&delta, repeat_max, + length_prevgroup + 1 + 2 + 2*LINK_SIZE) || + OFLOW_MAX + (2 + 2*LINK_SIZE) - *lengthptr < delta) { *errorcodeptr = ERR20; return 0; } + delta -= (2 + 2*LINK_SIZE); /* Last one doesn't nest */ *lengthptr += delta; } @@ -7901,7 +8158,7 @@ for (;; pptr++) done. However, there's an option, in case anyone was relying on it. */ if (cb->assert_depth > 0 && meta_arg == ESC_K && - (cb->cx->extra_options & PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) == 0) + (xoptions & PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) == 0) { *errorcodeptr = ERR99; return 0; @@ -7909,23 +8166,41 @@ for (;; pptr++) /* For the rest (including \X when Unicode is supported - if not it's faulted at parse time), the OP value is the escape value when PCRE2_UCP is - not set; if it is set, these escapes do not show up here because they are - converted into Unicode property tests in parse_regex(). Note that \b and \B - do a one-character lookbehind, and \A also behaves as if it does. */ + not set; if it is set, most of them do not show up here because they are + converted into Unicode property tests in parse_regex(). - if (meta_arg == ESC_C) cb->external_flags |= PCRE2_HASBKC; /* Record */ - if ((meta_arg == ESC_b || meta_arg == ESC_B || meta_arg == ESC_A) && - cb->max_lookbehind == 0) - cb->max_lookbehind = 1; + In non-UTF mode, and for both 32-bit modes, we turn \C into OP_ALLANY + instead of OP_ANYBYTE so that it works in DFA mode and in lookbehinds. + There are special UCP codes for \B and \b which are used in UCP mode unless + "word" matching is being forced to ASCII. - /* In non-UTF mode, and for both 32-bit modes, we turn \C into OP_ALLANY - instead of OP_ANYBYTE so that it works in DFA mode and in lookbehinds. */ + Note that \b and \B do a one-character lookbehind, and \A also behaves as + if it does. */ + switch(meta_arg) + { + case ESC_C: + cb->external_flags |= PCRE2_HASBKC; /* Record */ #if PCRE2_CODE_UNIT_WIDTH == 32 - *code++ = (meta_arg == ESC_C)? OP_ALLANY : meta_arg; + meta_arg = OP_ALLANY; #else - *code++ = (!utf && meta_arg == ESC_C)? OP_ALLANY : meta_arg; + if (!utf) meta_arg = OP_ALLANY; #endif + break; + + case ESC_B: + case ESC_b: + if ((options & PCRE2_UCP) != 0 && (xoptions & PCRE2_EXTRA_ASCII_BSW) == 0) + meta_arg = (meta_arg == ESC_B)? OP_NOT_UCP_WORD_BOUNDARY : + OP_UCP_WORD_BOUNDARY; + /* Fall through */ + + case ESC_A: + if (cb->max_lookbehind == 0) cb->max_lookbehind = 1; + break; + } + + *code++ = meta_arg; break; /* End META_ESCAPE */ @@ -7953,13 +8228,16 @@ for (;; pptr++) /* For caseless UTF or UCP mode, check whether this character has more than one other case. If so, generate a special OP_PROP item instead of OP_CHARI. - */ + When casing restrictions apply, ignore caseless sets that start with an + ASCII character. */ #ifdef SUPPORT_UNICODE if ((utf||ucp) && (options & PCRE2_CASELESS) != 0) { uint32_t caseset = UCD_CASESET(meta); - if (caseset != 0) + if (caseset != 0 && + ((xoptions & PCRE2_EXTRA_CASELESS_RESTRICT) == 0 || + PRIV(ucd_caseless_sets)[caseset] > 127)) { *code++ = OP_PROP; *code++ = PT_CLIST; @@ -8075,6 +8353,7 @@ the two phases. Arguments: options option bits, including any changes for this subpattern + xoptions extra option bits, ditto codeptr -> the address of the current code pointer pptrptr -> the address of the current parsed pattern pointer errorcodeptr -> pointer to error code variable @@ -8094,10 +8373,11 @@ Returns: 0 There has been an error */ static int -compile_regex(uint32_t options, PCRE2_UCHAR **codeptr, uint32_t **pptrptr, - int *errorcodeptr, uint32_t skipunits, uint32_t *firstcuptr, - uint32_t *firstcuflagsptr, uint32_t *reqcuptr, uint32_t *reqcuflagsptr, - branch_chain *bcptr, compile_block *cb, PCRE2_SIZE *lengthptr) +compile_regex(uint32_t options, uint32_t xoptions, PCRE2_UCHAR **codeptr, + uint32_t **pptrptr, int *errorcodeptr, uint32_t skipunits, + uint32_t *firstcuptr, uint32_t *firstcuflagsptr, uint32_t *reqcuptr, + uint32_t *reqcuflagsptr, branch_chain *bcptr, open_capitem *open_caps, + compile_block *cb, PCRE2_SIZE *lengthptr) { PCRE2_UCHAR *code = *codeptr; PCRE2_UCHAR *last_branch = code; @@ -8109,6 +8389,7 @@ int okreturn = 1; uint32_t *pptr = *pptrptr; uint32_t firstcu, reqcu; uint32_t lookbehindlength; +uint32_t lookbehindminlength; uint32_t firstcuflags, reqcuflags; uint32_t branchfirstcu, branchreqcu; uint32_t branchfirstcuflags, branchreqcuflags; @@ -8151,9 +8432,10 @@ lookbehind = *code == OP_ASSERTBACK || if (lookbehind) { lookbehindlength = META_DATA(pptr[-1]); + lookbehindminlength = *pptr; pptr += SIZEOFFSET; } -else lookbehindlength = 0; +else lookbehindlength = lookbehindminlength = 0; /* If this is a capturing subpattern, add to the chain of open capturing items so that we can detect them if (*ACCEPT) is encountered. Note that only OP_CBRA @@ -8164,9 +8446,9 @@ if (*code == OP_CBRA) { capnumber = GET2(code, 1 + LINK_SIZE); capitem.number = capnumber; - capitem.next = cb->open_caps; + capitem.next = open_caps; capitem.assert_depth = cb->assert_depth; - cb->open_caps = &capitem; + open_caps = &capitem; } /* Offset is set zero to mark that this bracket is still open */ @@ -8180,22 +8462,39 @@ for (;;) { int branch_return; - /* Insert OP_REVERSE if this is as lookbehind assertion. */ + /* Insert OP_REVERSE or OP_VREVERSE if this is a lookbehind assertion. There + is only a single mimimum length for the whole assertion. When the mimimum + length is LOOKBEHIND_MAX it means that all branches are of fixed length, + though not necessarily the same length. In this case, the original OP_REVERSE + can be used. It can also be used if a branch in a variable length lookbehind + has the same maximum and minimum. Otherwise, use OP_VREVERSE, which has both + maximum and minimum values. */ if (lookbehind && lookbehindlength > 0) { - *code++ = OP_REVERSE; - PUTINC(code, 0, lookbehindlength); - length += 1 + LINK_SIZE; + if (lookbehindminlength == LOOKBEHIND_MAX || + lookbehindminlength == lookbehindlength) + { + *code++ = OP_REVERSE; + PUT2INC(code, 0, lookbehindlength); + length += 1 + IMM2_SIZE; + } + else + { + *code++ = OP_VREVERSE; + PUT2INC(code, 0, lookbehindminlength); + PUT2INC(code, 0, lookbehindlength); + length += 1 + 2*IMM2_SIZE; + } } /* Now compile the branch; in the pre-compile phase its length gets added into the length. */ if ((branch_return = - compile_branch(&options, &code, &pptr, errorcodeptr, &branchfirstcu, - &branchfirstcuflags, &branchreqcu, &branchreqcuflags, &bc, - cb, (lengthptr == NULL)? NULL : &length)) == 0) + compile_branch(&options, &xoptions, &code, &pptr, errorcodeptr, + &branchfirstcu, &branchfirstcuflags, &branchreqcu, &branchreqcuflags, + &bc, open_caps, cb, (lengthptr == NULL)? NULL : &length)) == 0) return 0; /* If a branch can match an empty string, so can the whole group. */ @@ -8293,10 +8592,6 @@ for (;;) PUT(code, 1, (int)(code - start_bracket)); code += 1 + LINK_SIZE; - /* If it was a capturing subpattern, remove the block from the chain. */ - - if (capnumber > 0) cb->open_caps = cb->open_caps->next; - /* Set values to pass back */ *codeptr = code; @@ -8339,8 +8634,8 @@ for (;;) code += 1 + LINK_SIZE; } - /* Set the lookbehind length (if not in a lookbehind the value will be zero) - and then advance past the vertical bar. */ + /* Set the maximum lookbehind length for the next branch (if not in a + lookbehind the value will be zero) and then advance past the vertical bar. */ lookbehindlength = META_DATA(*pptr); pptr++; @@ -9051,13 +9346,13 @@ return pptr; *************************************************/ /* This is called for nested groups within a branch of a lookbehind whose -length is being computed. If all the branches in the nested group have the same -length, that is OK. On entry, the pointer must be at the first element after -the group initializing code. On exit it points to OP_KET. Caching is used to -improve processing speed when the same capturing group occurs many times. +length is being computed. On entry, the pointer must be at the first element +after the group initializing code. On exit it points to OP_KET. Caching is used +to improve processing speed when the same capturing group occurs many times. Arguments: pptrptr pointer to pointer in the parsed pattern + minptr where to return the minimum length isinline FALSE if a reference or recursion; TRUE for inline group errcodeptr pointer to the errorcode lcptr pointer to the loop counter @@ -9065,15 +9360,17 @@ Arguments: recurses chain of recurse_check to catch mutual recursion cb pointer to the compile data -Returns: the group length or a negative number +Returns: the maximum group length or a negative number */ static int -get_grouplength(uint32_t **pptrptr, BOOL isinline, int *errcodeptr, int *lcptr, - int group, parsed_recurse_check *recurses, compile_block *cb) +get_grouplength(uint32_t **pptrptr, int *minptr, BOOL isinline, int *errcodeptr, + int *lcptr, int group, parsed_recurse_check *recurses, compile_block *cb) { -int branchlength; +uint32_t *gi = cb->groupinfo + 2 * group; +int branchlength, branchminlength; int grouplength = -1; +int groupminlength = INT_MAX; /* The cache can be used only if there is no possibility of there being two groups with the same number. We do not need to set the end pointer for a group @@ -9082,11 +9379,12 @@ an inline group. */ if (group > 0 && (cb->external_flags & PCRE2_DUPCAPUSED) == 0) { - uint32_t groupinfo = cb->groupinfo[group]; + uint32_t groupinfo = gi[0]; if ((groupinfo & GI_NOT_FIXED_LENGTH) != 0) return -1; if ((groupinfo & GI_SET_FIXED_LENGTH) != 0) { if (isinline) *pptrptr = parsed_skip(*pptrptr, PSKIP_KET); + *minptr = gi[1]; return groupinfo & GI_FIXED_LENGTH_MASK; } } @@ -9095,20 +9393,26 @@ if (group > 0 && (cb->external_flags & PCRE2_DUPCAPUSED) == 0) for(;;) { - branchlength = get_branchlength(pptrptr, errcodeptr, lcptr, recurses, cb); + branchlength = get_branchlength(pptrptr, &branchminlength, errcodeptr, lcptr, + recurses, cb); if (branchlength < 0) goto ISNOTFIXED; - if (grouplength == -1) grouplength = branchlength; - else if (grouplength != branchlength) goto ISNOTFIXED; + if (branchlength > grouplength) grouplength = branchlength; + if (branchminlength < groupminlength) groupminlength = branchminlength; if (**pptrptr == META_KET) break; *pptrptr += 1; /* Skip META_ALT */ } if (group > 0) - cb->groupinfo[group] |= (uint32_t)(GI_SET_FIXED_LENGTH | grouplength); + { + gi[0] |= (uint32_t)(GI_SET_FIXED_LENGTH | grouplength); + gi[1] = groupminlength; + } + +*minptr = groupminlength; return grouplength; ISNOTFIXED: -if (group > 0) cb->groupinfo[group] |= GI_NOT_FIXED_LENGTH; +if (group > 0) gi[0] |= GI_NOT_FIXED_LENGTH; return -1; } @@ -9118,27 +9422,30 @@ return -1; * Find length of a parsed branch * *************************************************/ -/* Return a fixed length for a branch in a lookbehind, giving an error if the -length is not fixed. On entry, *pptrptr points to the first element inside the -branch. On exit it is set to point to the ALT or KET. +/* Return fixed maximum and minimum lengths for a branch in a lookbehind, +giving an error if the length is not limited. On entry, *pptrptr points to the +first element inside the branch. On exit it is set to point to the ALT or KET. Arguments: pptrptr pointer to pointer in the parsed pattern + minptr where to return the minimum length errcodeptr pointer to error code lcptr pointer to loop counter recurses chain of recurse_check to catch mutual recursion cb pointer to compile block -Returns: the length, or a negative value on error +Returns: the maximum length, or a negative value on error */ static int -get_branchlength(uint32_t **pptrptr, int *errcodeptr, int *lcptr, +get_branchlength(uint32_t **pptrptr, int *minptr, int *errcodeptr, int *lcptr, parsed_recurse_check *recurses, compile_block *cb) { int branchlength = 0; -int grouplength; +int branchminlength = 0; +int grouplength, groupminlength; uint32_t lastitemlength = 0; +uint32_t lastitemminlength = 0; uint32_t *pptr = *pptrptr; PCRE2_SIZE offset; parsed_recurse_check this_recurse; @@ -9162,10 +9469,12 @@ for (;; pptr++) uint32_t escape; uint32_t group = 0; uint32_t itemlength = 0; + uint32_t itemminlength = 0; + uint32_t min, max; if (*pptr < META_END) { - itemlength = 1; + itemlength = itemminlength = 1; } else switch (META_CODE(*pptr)) @@ -9200,24 +9509,24 @@ for (;; pptr++) break; case META_OPTIONS: - pptr += 1; + pptr += 2; break; case META_BIGVALUE: - itemlength = 1; + itemlength = itemminlength = 1; pptr += 1; break; case META_CLASS: case META_CLASS_NOT: - itemlength = 1; + itemlength = itemminlength = 1; pptr = parsed_skip(pptr, PSKIP_CLASS); if (pptr == NULL) goto PARSED_SKIP_FAILED; break; case META_CLASS_EMPTY_NOT: case META_DOT: - itemlength = 1; + itemlength = itemminlength = 1; break; case META_CALLOUT_NUMBER: @@ -9228,14 +9537,19 @@ for (;; pptr++) pptr += 3 + SIZEOFFSET; break; - /* Only some escapes consume a character. Of those, \R and \X are never - allowed because they might match more than character. \C is allowed only in - 32-bit and non-UTF 8/16-bit modes. */ + /* Only some escapes consume a character. Of those, \R can match one or two + characters, but \X is never allowed because it matches an unknown number of + characters. \C is allowed only in 32-bit and non-UTF 8/16-bit modes. */ case META_ESCAPE: escape = META_DATA(*pptr); - if (escape == ESC_R || escape == ESC_X) return -1; - if (escape > ESC_b && escape < ESC_Z) + if (escape == ESC_X) return -1; + if (escape == ESC_R) + { + itemminlength = 1; + itemlength = 2; + } + else if (escape > ESC_b && escape < ESC_Z) { #if PCRE2_CODE_UNIT_WIDTH != 32 if ((cb->external_options & PCRE2_UTF) != 0 && escape == ESC_C) @@ -9244,7 +9558,7 @@ for (;; pptr++) return -1; } #endif - itemlength = 1; + itemlength = itemminlength = 1; if (escape == ESC_p || escape == ESC_P) pptr++; /* Skip prop data */ } break; @@ -9400,14 +9714,15 @@ for (;; pptr++) in the cache. */ gptr++; - grouplength = get_grouplength(&gptr, FALSE, errcodeptr, lcptr, group, - &this_recurse, cb); + grouplength = get_grouplength(&gptr, &groupminlength, FALSE, errcodeptr, + lcptr, group, &this_recurse, cb); if (grouplength < 0) { if (*errcodeptr == 0) goto ISNOTFIXED; return -1; /* Error already set */ } itemlength = grouplength; + itemminlength = groupminlength; break; /* A (DEFINE) group is never obeyed inline and so it does not contribute to @@ -9445,41 +9760,44 @@ for (;; pptr++) case META_SCRIPT_RUN: pptr++; CHECK_GROUP: - grouplength = get_grouplength(&pptr, TRUE, errcodeptr, lcptr, group, - recurses, cb); + grouplength = get_grouplength(&pptr, &groupminlength, TRUE, errcodeptr, + lcptr, group, recurses, cb); if (grouplength < 0) return -1; itemlength = grouplength; + itemminlength = groupminlength; break; + case META_QUERY: + case META_QUERY_PLUS: + case META_QUERY_QUERY: + min = 0; + max = 1; + goto REPETITION; + /* Exact repetition is OK; variable repetition is not. A repetition of zero must subtract the length that has already been added. */ case META_MINMAX: case META_MINMAX_PLUS: case META_MINMAX_QUERY: - if (pptr[1] == pptr[2]) + min = pptr[1]; + max = pptr[2]; + pptr += 2; + + REPETITION: + if (max != REPEAT_UNLIMITED) { - switch(pptr[1]) + if (lastitemlength != 0 && /* Should not occur, but just in case */ + max != 0 && + (INT_MAX - branchlength)/lastitemlength < max - 1) { - case 0: - branchlength -= lastitemlength; - break; - - case 1: - itemlength = 0; - break; - - default: /* Check for integer overflow */ - if (lastitemlength != 0 && /* Should not occur, but just in case */ - INT_MAX/lastitemlength < pptr[1] - 1) - { - *errcodeptr = ERR87; /* Integer overflow; lookbehind too big */ - return -1; - } - itemlength = (pptr[1] - 1) * lastitemlength; - break; + *errcodeptr = ERR87; /* Integer overflow; lookbehind too big */ + return -1; } - pptr += 2; + if (min == 0) branchminlength -= lastitemminlength; + else itemminlength = (min - 1) * lastitemminlength; + if (max == 0) branchlength -= lastitemlength; + else itemlength = (max - 1) * lastitemlength; break; } /* Fall through */ @@ -9493,7 +9811,9 @@ for (;; pptr++) } /* Add the item length to the branchlength, checking for integer overflow and - for the branch length exceeding the limit. */ + for the branch length exceeding the overall limit. Later, if there is at + least one variable-length branch in the group, there is a test for the + (smaller) variable-length branch length limit. */ if (INT_MAX - branchlength < (int)itemlength || (branchlength += itemlength) > LOOKBEHIND_MAX) @@ -9502,13 +9822,17 @@ for (;; pptr++) return -1; } + branchminlength += itemminlength; + /* Save this item length for use if the next item is a quantifier. */ lastitemlength = itemlength; + lastitemminlength = itemminlength; } EXIT: *pptrptr = pptr; +*minptr = branchminlength; return branchlength; PARSED_SKIP_FAILED: @@ -9523,9 +9847,9 @@ return -1; *************************************************/ /* This function is called for each lookbehind, to set the lengths in its -branches. An error occurs if any branch does not have a fixed length that is -less than the maximum (65535). On exit, the pointer must be left on the final -ket. +branches. An error occurs if any branch does not have a limited maximum length +that is less than the limit (65535). On exit, the pointer must be left on the +final ket. The function also maintains the max_lookbehind value. Any lookbehind branch that contains a nested lookbehind may actually look further back than the @@ -9548,16 +9872,27 @@ set_lookbehind_lengths(uint32_t **pptrptr, int *errcodeptr, int *lcptr, parsed_recurse_check *recurses, compile_block *cb) { PCRE2_SIZE offset; -int branchlength; uint32_t *bptr = *pptrptr; +uint32_t *gbptr = bptr; +int maxlength = 0; +int minlength = INT_MAX; +BOOL variable = FALSE; READPLUSOFFSET(offset, bptr); /* Offset for error messages */ *pptrptr += SIZEOFFSET; +/* Each branch can have a different maximum length, but we can keep only a +single minimum for the whole group, because there's nowhere to save individual +values in the META_ALT item. */ + do { + int branchlength, branchminlength; + *pptrptr += 1; - branchlength = get_branchlength(pptrptr, errcodeptr, lcptr, recurses, cb); + branchlength = get_branchlength(pptrptr, &branchminlength, errcodeptr, lcptr, + recurses, cb); + if (branchlength < 0) { /* The errorcode and offset may already be set from a nested lookbehind. */ @@ -9565,12 +9900,37 @@ do if (cb->erroroffset == PCRE2_UNSET) cb->erroroffset = offset; return FALSE; } + + if (branchlength != branchminlength) variable = TRUE; + if (branchminlength < minlength) minlength = branchminlength; + if (branchlength > maxlength) maxlength = branchlength; if (branchlength > cb->max_lookbehind) cb->max_lookbehind = branchlength; *bptr |= branchlength; /* branchlength never more than 65535 */ bptr = *pptrptr; } while (*bptr == META_ALT); +/* If any branch is of variable length, the whole lookbehind is of variable +length. If the maximum length of any branch exceeds the maximum for variable +lookbehinds, give an error. Otherwise, the minimum length is set in the word +that follows the original group META value. For a fixed-length lookbehind, this +is set to LOOKBEHIND_MAX, to indicate that each branch is of a fixed (but +possibly different) length. */ + +if (variable) + { + gbptr[1] = minlength; + if ((uint32_t)maxlength > cb->max_varlookbehind) + { + *errcodeptr = ERR100; + cb->erroroffset = offset; + return FALSE; + } + } +else gbptr[1] = LOOKBEHIND_MAX; + + +gbptr[1] = variable? minlength : LOOKBEHIND_MAX; return TRUE; } @@ -9703,7 +10063,6 @@ for (; *pptr != META_END; pptr++) break; case META_BIGVALUE: - case META_OPTIONS: case META_POSIX: case META_POSIX_NEG: pptr += 1; @@ -9712,6 +10071,7 @@ for (; *pptr != META_END; pptr++) case META_MINMAX: case META_MINMAX_QUERY: case META_MINMAX_PLUS: + case META_OPTIONS: pptr += 2; break; @@ -9820,12 +10180,15 @@ if (errorptr == NULL || erroroffset == NULL) return NULL; *errorptr = ERR0; *erroroffset = 0; -/* There must be a pattern! */ +/* There must be a pattern, but NULL is allowed with zero length. */ if (pattern == NULL) { - *errorptr = ERR16; - return NULL; + if (patlen == 0) pattern = (PCRE2_SPTR)""; else + { + *errorptr = ERR16; + return NULL; + } } /* A NULL compile context means "use a default context" */ @@ -9890,13 +10253,13 @@ cb.external_options = options; cb.groupinfo = stack_groupinfo; cb.had_recurse = FALSE; cb.lastcapture = 0; -cb.max_lookbehind = 0; +cb.max_lookbehind = 0; /* Max encountered */ +cb.max_varlookbehind = ccontext->max_varlookbehind; /* Limit */ cb.name_entry_size = 0; cb.name_table = NULL; cb.named_groups = named_groups; cb.named_group_list_size = NAMED_GROUP_LIST_SIZE; cb.names_found = 0; -cb.open_caps = NULL; cb.parens_depth = 0; cb.parsed_pattern = stack_parsed_pattern; cb.req_varyopt = 0; @@ -9949,7 +10312,7 @@ if ((options & PCRE2_LITERAL) == 0) for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++) { uint32_t c, pp; - pso *p = pso_list + i; + const pso *p = pso_list + i; if (patlen - skipatstart - 2 >= p->length && PRIV(strncmp_c8)(ptr + skipatstart + 2, (char *)(p->name), @@ -10158,39 +10521,36 @@ cb.parsed_pattern_end = cb.parsed_pattern + parsed_size_needed + 1; errorcode = parse_regex(ptr, cb.external_options, &has_lookbehind, &cb); if (errorcode != 0) goto HAD_CB_ERROR; -/* Workspace is needed to remember information about numbered groups: whether a -group can match an empty string and what its fixed length is. This is done to -avoid the possibility of recursive references causing very long compile times -when checking these features. Unnumbered groups do not have this exposure since -they cannot be referenced. We use an indexed vector for this purpose. If there -are sufficiently few groups, the default vector on the stack, as set up above, -can be used. Otherwise we have to get/free a special vector. The vector must be -initialized to zero. */ - -if (cb.bracount >= GROUPINFO_DEFAULT_SIZE) - { - cb.groupinfo = ccontext->memctl.malloc( - (cb.bracount + 1)*sizeof(uint32_t), ccontext->memctl.memory_data); - if (cb.groupinfo == NULL) - { - errorcode = ERR21; - cb.erroroffset = 0; - goto HAD_CB_ERROR; - } - } -memset(cb.groupinfo, 0, (cb.bracount + 1) * sizeof(uint32_t)); - -/* If there were any lookbehinds, scan the parsed pattern to figure out their -lengths. */ +/* If there are any lookbehinds, scan the parsed pattern to figure out their +lengths. Workspace is needed to remember whether numbered groups are or are not +of limited length, and if limited, what the minimum and maximum lengths are. +This caching saves re-computing the length of any group that is referenced more +than once, which is particularly relevant when recursion is involved. +Unnumbered groups do not have this exposure because they cannot be referenced. +If there are sufficiently few groups, the default index vector on the stack, as +set up above, can be used. Otherwise we have to get/free some heap memory. The +vector must be initialized to zero. */ if (has_lookbehind) { int loopcount = 0; + if (cb.bracount >= GROUPINFO_DEFAULT_SIZE/2) + { + cb.groupinfo = ccontext->memctl.malloc( + (2 * (cb.bracount + 1))*sizeof(uint32_t), ccontext->memctl.memory_data); + if (cb.groupinfo == NULL) + { + errorcode = ERR21; + cb.erroroffset = 0; + goto HAD_CB_ERROR; + } + } + memset(cb.groupinfo, 0, (2 * cb.bracount + 1) * sizeof(uint32_t)); errorcode = check_lookbehinds(cb.parsed_pattern, NULL, NULL, &cb, &loopcount); if (errorcode != 0) goto HAD_CB_ERROR; } -/* For debugging, there is a function that shows the parsed data vector. */ +/* For debugging, there is a function that shows the parsed pattern vector. */ #ifdef DEBUG_SHOW_PARSED fprintf(stderr, "+++ Pre-scan complete:\n"); @@ -10227,8 +10587,9 @@ pptr = cb.parsed_pattern; code = cworkspace; *code = OP_BRA; -(void)compile_regex(cb.external_options, &code, &pptr, &errorcode, 0, &firstcu, - &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, &length); +(void)compile_regex(cb.external_options, ccontext->extra_options, &code, &pptr, + &errorcode, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, NULL, + &cb, &length); if (errorcode != 0) goto HAD_CB_ERROR; /* Offset is in cb.erroroffset */ @@ -10306,7 +10667,6 @@ cb.start_code = codestart; cb.req_varyopt = 0; cb.had_accept = FALSE; cb.had_pruneorskip = FALSE; -cb.open_caps = NULL; /* If any named groups were found, create the name/number table from the list created in the pre-pass. */ @@ -10325,8 +10685,9 @@ of the function here. */ pptr = cb.parsed_pattern; code = (PCRE2_UCHAR *)codestart; *code = OP_BRA; -regexrc = compile_regex(re->overall_options, &code, &pptr, &errorcode, 0, - &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, &cb, NULL); +regexrc = compile_regex(re->overall_options, ccontext->extra_options, &code, + &pptr, &errorcode, 0, &firstcu, &firstcuflags, &reqcu, &reqcuflags, NULL, + NULL, &cb, NULL); if (regexrc < 0) re->flags |= PCRE2_MATCH_EMPTY; re->top_bracket = cb.bracount; re->top_backref = cb.top_backref; diff --git a/src/3rdparty/pcre2/src/pcre2_context.c b/src/3rdparty/pcre2/src/pcre2_context.c index 8e05ede50c2..0bc2ea0b047 100644 --- a/src/3rdparty/pcre2/src/pcre2_context.c +++ b/src/3rdparty/pcre2/src/pcre2_context.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -139,7 +139,9 @@ const pcre2_compile_context PRIV(default_compile_context) = { BSR_DEFAULT, /* Backslash R default */ NEWLINE_DEFAULT, /* Newline convention */ PARENS_NEST_LIMIT, /* As it says */ - 0 }; /* Extra options */ + 0, /* Extra options */ + MAX_VARLOOKBEHIND /* As it says */ + }; /* The create function copies the default into the new memory, but must override the default memory handling functions if a gcontext was provided. */ @@ -228,49 +230,48 @@ return ccontext; PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION pcre2_general_context_copy(pcre2_general_context *gcontext) { -pcre2_general_context *new = +pcre2_general_context *newcontext = gcontext->memctl.malloc(sizeof(pcre2_real_general_context), gcontext->memctl.memory_data); -if (new == NULL) return NULL; -memcpy(new, gcontext, sizeof(pcre2_real_general_context)); -return new; +if (newcontext == NULL) return NULL; +memcpy(newcontext, gcontext, sizeof(pcre2_real_general_context)); +return newcontext; } PCRE2_EXP_DEFN pcre2_compile_context * PCRE2_CALL_CONVENTION pcre2_compile_context_copy(pcre2_compile_context *ccontext) { -pcre2_compile_context *new = +pcre2_compile_context *newcontext = ccontext->memctl.malloc(sizeof(pcre2_real_compile_context), ccontext->memctl.memory_data); -if (new == NULL) return NULL; -memcpy(new, ccontext, sizeof(pcre2_real_compile_context)); -return new; +if (newcontext == NULL) return NULL; +memcpy(newcontext, ccontext, sizeof(pcre2_real_compile_context)); +return newcontext; } PCRE2_EXP_DEFN pcre2_match_context * PCRE2_CALL_CONVENTION pcre2_match_context_copy(pcre2_match_context *mcontext) { -pcre2_match_context *new = +pcre2_match_context *newcontext = mcontext->memctl.malloc(sizeof(pcre2_real_match_context), mcontext->memctl.memory_data); -if (new == NULL) return NULL; -memcpy(new, mcontext, sizeof(pcre2_real_match_context)); -return new; +if (newcontext == NULL) return NULL; +memcpy(newcontext, mcontext, sizeof(pcre2_real_match_context)); +return newcontext; } - PCRE2_EXP_DEFN pcre2_convert_context * PCRE2_CALL_CONVENTION pcre2_convert_context_copy(pcre2_convert_context *ccontext) { -pcre2_convert_context *new = +pcre2_convert_context *newcontext = ccontext->memctl.malloc(sizeof(pcre2_real_convert_context), ccontext->memctl.memory_data); -if (new == NULL) return NULL; -memcpy(new, ccontext, sizeof(pcre2_real_convert_context)); -return new; +if (newcontext == NULL) return NULL; +memcpy(newcontext, ccontext, sizeof(pcre2_real_convert_context)); +return newcontext; } @@ -370,6 +371,13 @@ switch(newline) } } +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_max_varlookbehind(pcre2_compile_context *ccontext, uint32_t limit) +{ +ccontext->max_varlookbehind = limit; +return 0; +} + PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext, uint32_t limit) { diff --git a/src/3rdparty/pcre2/src/pcre2_dfa_match.c b/src/3rdparty/pcre2/src/pcre2_dfa_match.c index b16e594cc06..caae65248ff 100644 --- a/src/3rdparty/pcre2/src/pcre2_dfa_match.c +++ b/src/3rdparty/pcre2/src/pcre2_dfa_match.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -168,7 +168,7 @@ static const uint8_t coptable[] = { 0, /* KetRmax */ 0, /* KetRmin */ 0, /* KetRpos */ - 0, /* Reverse */ + 0, 0, /* Reverse, Vreverse */ 0, /* Assert */ 0, /* Assert not */ 0, /* Assert behind */ @@ -187,7 +187,8 @@ static const uint8_t coptable[] = { 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ 0, 0, /* COMMIT, COMMIT_ARG */ 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */ - 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */ + 0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */ + 0, 0 /* \B and \b in UCP mode */ }; /* This table identifies those opcodes that inspect a character. It is used to @@ -245,7 +246,7 @@ static const uint8_t poptable[] = { 0, /* KetRmax */ 0, /* KetRmin */ 0, /* KetRpos */ - 0, /* Reverse */ + 0, 0, /* Reverse, Vreverse */ 0, /* Assert */ 0, /* Assert not */ 0, /* Assert behind */ @@ -264,7 +265,8 @@ static const uint8_t poptable[] = { 0, 0, 0, 0, /* SKIP, SKIP_ARG, THEN, THEN_ARG */ 0, 0, /* COMMIT, COMMIT_ARG */ 0, 0, 0, /* FAIL, ACCEPT, ASSERT_ACCEPT */ - 0, 0, 0 /* CLOSE, SKIPZERO, DEFINE */ + 0, 0, 0, /* CLOSE, SKIPZERO, DEFINE */ + 1, 1 /* \B and \b in UCP mode */ }; /* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W, @@ -426,7 +428,7 @@ overflow. */ else { - uint32_t newsize = (rws->size >= UINT32_MAX/2)? UINT32_MAX/2 : rws->size * 2; + uint32_t newsize = (rws->size >= UINT32_MAX/(sizeof(int)*2))? UINT32_MAX/sizeof(int) : rws->size * 2; uint32_t newsizeK = newsize/(1024/sizeof(int)); if (newsizeK + mb->heap_used > mb->heap_limit) @@ -589,7 +591,7 @@ if (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT) end_code = this_start_code; do { - size_t back = (size_t)GET(end_code, 2+LINK_SIZE); + size_t back = (size_t)GET2(end_code, 2+LINK_SIZE); if (back > max_back) max_back = back; end_code += GET(end_code, 1); } @@ -633,8 +635,8 @@ if (*this_start_code == OP_ASSERTBACK || *this_start_code == OP_ASSERTBACK_NOT) end_code = this_start_code; do { - uint32_t revlen = (end_code[1+LINK_SIZE] == OP_REVERSE)? 1 + LINK_SIZE : 0; - size_t back = (revlen == 0)? 0 : (size_t)GET(end_code, 2+LINK_SIZE); + uint32_t revlen = (end_code[1+LINK_SIZE] == OP_REVERSE)? 1 + IMM2_SIZE : 0; + size_t back = (revlen == 0)? 0 : (size_t)GET2(end_code, 2+LINK_SIZE); if (back <= gone_back) { int bstate = (int)(end_code - start_code + 1 + LINK_SIZE + revlen); @@ -1100,6 +1102,8 @@ for (;;) /*-----------------------------------------------------------------*/ case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: { int left_word, right_word; @@ -1112,13 +1116,13 @@ for (;;) #endif GETCHARTEST(d, temp); #ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) + if (codevalue == OP_UCP_WORD_BOUNDARY || + codevalue == OP_NOT_UCP_WORD_BOUNDARY) { - if (d == '_') left_word = TRUE; else - { - uint32_t cat = UCD_CATEGORY(d); - left_word = (cat == ucp_L || cat == ucp_N); - } + int chartype = UCD_CHARTYPE(d); + int category = PRIV(ucp_gentype)[chartype]; + left_word = (category == ucp_L || category == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc); } else #endif @@ -1137,13 +1141,13 @@ for (;;) mb->last_used_ptr = temp; } #ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) + if (codevalue == OP_UCP_WORD_BOUNDARY || + codevalue == OP_NOT_UCP_WORD_BOUNDARY) { - if (c == '_') right_word = TRUE; else - { - uint32_t cat = UCD_CATEGORY(c); - right_word = (cat == ucp_L || cat == ucp_N); - } + int chartype = UCD_CHARTYPE(c); + int category = PRIV(ucp_gentype)[chartype]; + right_word = (category == ucp_L || category == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc); } else #endif @@ -1151,7 +1155,9 @@ for (;;) } else right_word = FALSE; - if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY)) + if ((left_word == right_word) == + (codevalue == OP_NOT_WORD_BOUNDARY || + codevalue == OP_NOT_UCP_WORD_BOUNDARY)) { ADD_ACTIVE(state_offset + 1, 0); } } break; @@ -1168,6 +1174,7 @@ for (;;) if (clen > 0) { BOOL OK; + int chartype; const uint32_t *cp; const ucd_record * prop = GET_UCD(c); switch(code[1]) @@ -1177,8 +1184,9 @@ for (;;) break; case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; + chartype = prop->chartype; + OK = chartype == ucp_Lu || chartype == ucp_Ll || + chartype == ucp_Lt; break; case PT_GC: @@ -1201,8 +1209,9 @@ for (;;) /* These are specials for combination cases. */ case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N; break; /* Perl space used to exclude VT, but from Perl 5.18 it is included, @@ -1225,12 +1234,20 @@ for (;;) break; case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc; break; case PT_CLIST: +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c > MAX_UTF_CODE_POINT) + { + OK = FALSE; + break; + } +#endif cp = PRIV(ucd_caseless_sets) + code[2]; for (;;) { @@ -1440,6 +1457,7 @@ for (;;) if (clen > 0) { BOOL OK; + int chartype; const uint32_t *cp; const ucd_record * prop = GET_UCD(c); switch(code[2]) @@ -1449,8 +1467,8 @@ for (;;) break; case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; + chartype = prop->chartype; + OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; break; case PT_GC: @@ -1473,8 +1491,9 @@ for (;;) /* These are specials for combination cases. */ case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N; break; /* Perl space used to exclude VT, but from Perl 5.18 it is included, @@ -1497,12 +1516,20 @@ for (;;) break; case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc; break; case PT_CLIST: +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c > MAX_UTF_CODE_POINT) + { + OK = FALSE; + break; + } +#endif cp = PRIV(ucd_caseless_sets) + code[3]; for (;;) { @@ -1695,6 +1722,7 @@ for (;;) if (clen > 0) { BOOL OK; + int chartype; const uint32_t *cp; const ucd_record * prop = GET_UCD(c); switch(code[2]) @@ -1704,8 +1732,8 @@ for (;;) break; case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; + chartype = prop->chartype; + OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; break; case PT_GC: @@ -1728,8 +1756,9 @@ for (;;) /* These are specials for combination cases. */ case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N; break; /* Perl space used to exclude VT, but from Perl 5.18 it is included, @@ -1752,12 +1781,20 @@ for (;;) break; case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc; break; case PT_CLIST: +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c > MAX_UTF_CODE_POINT) + { + OK = FALSE; + break; + } +#endif cp = PRIV(ucd_caseless_sets) + code[3]; for (;;) { @@ -1975,6 +2012,7 @@ for (;;) if (clen > 0) { BOOL OK; + int chartype; const uint32_t *cp; const ucd_record * prop = GET_UCD(c); switch(code[1 + IMM2_SIZE + 1]) @@ -1984,8 +2022,8 @@ for (;;) break; case PT_LAMP: - OK = prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt; + chartype = prop->chartype; + OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt; break; case PT_GC: @@ -2009,8 +2047,9 @@ for (;;) /* These are specials for combination cases. */ case PT_ALNUM: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N; break; /* Perl space used to exclude VT, but from Perl 5.18 it is included, @@ -2033,12 +2072,20 @@ for (;;) break; case PT_WORD: - OK = PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - c == CHAR_UNDERSCORE; + chartype = prop->chartype; + OK = PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc; break; case PT_CLIST: +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c > MAX_UTF_CODE_POINT) + { + OK = FALSE; + break; + } +#endif cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2]; for (;;) { @@ -2894,7 +2941,6 @@ for (;;) int *local_workspace; PCRE2_SIZE *local_offsets; RWS_anchor *rws = (RWS_anchor *)RWS; - dfa_recursion_info *ri; PCRE2_SPTR callpat = start_code + GET(code, 1); uint32_t recno = (callpat == mb->start_code)? 0 : GET2(callpat, 1 + LINK_SIZE); @@ -2911,18 +2957,24 @@ for (;;) rws->free -= RWS_RSIZE + RWS_OVEC_RSIZE; /* Check for repeating a recursion without advancing the subject - pointer. This should catch convoluted mutual recursions. (Some simple - cases are caught at compile time.) */ + pointer or last used character. This should catch convoluted mutual + recursions. (Some simple cases are caught at compile time.) */ - for (ri = mb->recursive; ri != NULL; ri = ri->prevrec) - if (recno == ri->group_num && ptr == ri->subject_position) + for (dfa_recursion_info *ri = mb->recursive; + ri != NULL; + ri = ri->prevrec) + { + if (recno == ri->group_num && ptr == ri->subject_position && + mb->last_used_ptr == ri->last_used_ptr) return PCRE2_ERROR_RECURSELOOP; + } /* Remember this recursion and where we started it so as to catch infinite loops. */ new_recursive.group_num = recno; new_recursive.subject_position = ptr; + new_recursive.last_used_ptr = mb->last_used_ptr; new_recursive.prevrec = mb->recursive; mb->recursive = &new_recursive; @@ -3424,7 +3476,7 @@ anchored = (options & (PCRE2_ANCHORED|PCRE2_DFA_RESTART)) != 0 || where to start. */ startline = (re->flags & PCRE2_STARTLINE) != 0; -firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0; +firstline = !anchored && (re->overall_options & PCRE2_FIRSTLINE) != 0; bumpalong_limit = end_subject; /* Initialize and set up the fixed fields in the callout block, with a pointer @@ -3994,8 +4046,9 @@ for (;;) match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject); match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject); } + match_data->subject_length = length; match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject); - match_data->rightchar = (PCRE2_SIZE)( mb->last_used_ptr - subject); + match_data->rightchar = (PCRE2_SIZE)(mb->last_used_ptr - subject); match_data->startchar = (PCRE2_SIZE)(start_match - subject); match_data->rc = rc; diff --git a/src/3rdparty/pcre2/src/pcre2_error.c b/src/3rdparty/pcre2/src/pcre2_error.c index 09904c03e3b..1569f6315f5 100644 --- a/src/3rdparty/pcre2/src/pcre2_error.c +++ b/src/3rdparty/pcre2/src/pcre2_error.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2021 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -82,7 +82,7 @@ static const unsigned char compile_error_texts[] = "missing closing parenthesis\0" /* 15 */ "reference to non-existent subpattern\0" - "pattern passed as NULL\0" + "pattern passed as NULL with non-zero length\0" "unrecognised compile-time option bit(s)\0" "missing ) after (?# comment\0" "parentheses are too deeply nested\0" @@ -93,7 +93,7 @@ static const unsigned char compile_error_texts[] = "internal error: code overflow\0" "missing closing parenthesis for condition\0" /* 25 */ - "lookbehind assertion is not fixed length\0" + "length of lookbehind assertion is not limited\0" "a relative value of zero is not allowed\0" "conditional subpattern contains more than two branches\0" "assertion expected after (?( or (?(?C)\0" @@ -187,6 +187,8 @@ static const unsigned char compile_error_texts[] = "too many capturing groups (maximum 65535)\0" "atomic assertion expected after (?( or (?(?C)\0" "\\K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK)\0" + /* 100 */ + "branch too long in variable-length lookbehind assertion\0" ; /* Match-time and UTF error texts are in the same format. */ @@ -272,6 +274,7 @@ static const unsigned char match_error_texts[] = /* 65 */ "internal error - duplicate substitution match\0" "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\0" + "INTERNAL ERROR: invalid substring offset\0" ; diff --git a/src/3rdparty/pcre2/src/pcre2_find_bracket.c b/src/3rdparty/pcre2/src/pcre2_find_bracket.c index 70baa1394f5..1290c5e9de1 100644 --- a/src/3rdparty/pcre2/src/pcre2_find_bracket.c +++ b/src/3rdparty/pcre2/src/pcre2_find_bracket.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2018 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -41,9 +41,9 @@ POSSIBILITY OF SUCH DAMAGE. /* This module contains a single function that scans through a compiled pattern until it finds a capturing bracket with the given number, or, if the number is -negative, an instance of OP_REVERSE for a lookbehind. The function is called -from pcre2_compile.c and also from pcre2_study.c when finding the minimum -matching length. */ +negative, an instance of OP_REVERSE or OP_VREVERSE for a lookbehind. The +function is called from pcre2_compile.c and also from pcre2_study.c when +finding the minimum matching length. */ #ifdef HAVE_CONFIG_H @@ -85,7 +85,7 @@ for (;;) /* Handle lookbehind */ - else if (c == OP_REVERSE) + else if (c == OP_REVERSE || c == OP_VREVERSE) { if (number < 0) return (PCRE2_UCHAR *)code; code += PRIV(OP_lengths)[c]; diff --git a/src/3rdparty/pcre2/src/pcre2_internal.h b/src/3rdparty/pcre2/src/pcre2_internal.h index 92dd3138d4a..e5808182e67 100644 --- a/src/3rdparty/pcre2/src/pcre2_internal.h +++ b/src/3rdparty/pcre2/src/pcre2_internal.h @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -51,6 +51,24 @@ pcre2test.c with CODE_UNIT_WIDTH == 0. */ #error The use of both EBCDIC and SUPPORT_UNICODE is not supported. #endif +/* When compiling one of the libraries, the value of PCRE2_CODE_UNIT_WIDTH must +be 8, 16, or 32. AutoTools and CMake ensure that this is always the case, but +other other building methods may not, so here is a check. It is cut out when +building pcre2test, bcause that sets the value to zero. No other source should +be including this file. There is no explicit way of forcing a compile to be +abandoned, but trying to include a non-existent file seems cleanest. Otherwise +there will be many irrelevant consequential errors. */ + +#if (!defined PCRE2_BUILDING_PCRE2TEST && !defined PCRE2_DFTABLES) && \ + (!defined PCRE2_CODE_UNIT_WIDTH || \ + (PCRE2_CODE_UNIT_WIDTH != 8 && \ + PCRE2_CODE_UNIT_WIDTH != 16 && \ + PCRE2_CODE_UNIT_WIDTH != 32)) +#error PCRE2_CODE_UNIT_WIDTH must be defined as 8, 16, or 32. +#include +#endif + + /* Standard C headers */ #include @@ -119,20 +137,20 @@ only if it is not already set. */ #ifndef PCRE2_EXP_DECL # ifdef _WIN32 # ifndef PCRE2_STATIC -# define PCRE2_EXP_DECL extern __declspec(dllexport) -# define PCRE2_EXP_DEFN __declspec(dllexport) +# define PCRE2_EXP_DECL extern __declspec(dllexport) +# define PCRE2_EXP_DEFN __declspec(dllexport) # else -# define PCRE2_EXP_DECL extern +# define PCRE2_EXP_DECL extern PCRE2_EXPORT # define PCRE2_EXP_DEFN # endif # else # ifdef __cplusplus -# define PCRE2_EXP_DECL extern "C" +# define PCRE2_EXP_DECL extern "C" PCRE2_EXPORT # else -# define PCRE2_EXP_DECL extern +# define PCRE2_EXP_DECL extern PCRE2_EXPORT # endif # ifndef PCRE2_EXP_DEFN -# define PCRE2_EXP_DEFN PCRE2_EXP_DECL +# define PCRE2_EXP_DEFN PCRE2_EXP_DECL # endif # endif #endif @@ -156,8 +174,8 @@ pcre2_match() because of the way it backtracks. */ #define PCRE2_SPTR CUSTOM_SUBJECT_PTR #endif -/* When checking for integer overflow in pcre2_compile(), we need to handle -large integers. If a 64-bit integer type is available, we can use that. +/* When checking for integer overflow, we need to handle large integers. +If a 64-bit integer type is available, we can use that. Otherwise we have to cast to double, which of course requires floating point arithmetic. Handle this by defining a macro for the appropriate type. */ @@ -1281,7 +1299,7 @@ match. */ #define PT_ALNUM 6 /* Alphanumeric - the union of L and N */ #define PT_SPACE 7 /* Perl space - general category Z plus 9,10,12,13 */ #define PT_PXSPACE 8 /* POSIX space - Z plus 9,10,11,12,13 */ -#define PT_WORD 9 /* Word - L plus N plus underscore */ +#define PT_WORD 9 /* Word - L, N, Mn, or Pc */ #define PT_CLIST 10 /* Pseudo-property: match character list */ #define PT_UCNC 11 /* Universal Character nameable character */ #define PT_BIDICL 12 /* Specified bidi class */ @@ -1297,6 +1315,7 @@ table. */ #define PT_PXGRAPH 14 /* [:graph:] - characters that mark the paper */ #define PT_PXPRINT 15 /* [:print:] - [:graph:] plus non-control spaces */ #define PT_PXPUNCT 16 /* [:punct:] - punctuation characters */ +#define PT_PXXDIGIT 17 /* [:xdigit:] - hex digits */ /* This value is used when parsing \p and \P escapes to indicate that neither \p{script:...} nor \p{scx:...} has been encountered. */ @@ -1327,6 +1346,12 @@ mode rather than an escape sequence. It is also used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves like \N. +ESC_ub is a special return from check_escape() when, in BSUX mode, \u{ is not +followed by hex digits and }, in which case it should mean a literal "u" +followed by a literal "{". This hack is necessary for cases like \u{ 12} +because without it, this is interpreted as u{12} now that spaces are allowed in +quantifiers. + Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in check_escape(). There are tests in the code for an escape greater than ESC_b and less than ESC_Z to detect the types that may be repeated. These are the @@ -1336,7 +1361,7 @@ consume a character, that code will have to change. */ enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H, ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z, - ESC_E, ESC_Q, ESC_g, ESC_k }; + ESC_E, ESC_Q, ESC_g, ESC_k, ESC_ub }; /********************** Opcode definitions ******************/ @@ -1372,8 +1397,8 @@ enum { OP_SOD, /* 1 Start of data: \A */ OP_SOM, /* 2 Start of match (subject + offset): \G */ OP_SET_SOM, /* 3 Set start of match (\K) */ - OP_NOT_WORD_BOUNDARY, /* 4 \B */ - OP_WORD_BOUNDARY, /* 5 \b */ + OP_NOT_WORD_BOUNDARY, /* 4 \B -- see also OP_NOT_UCP_WORD_BOUNDARY */ + OP_WORD_BOUNDARY, /* 5 \b -- see also OP_UCP_WORD_BOUNDARY */ OP_NOT_DIGIT, /* 6 \D */ OP_DIGIT, /* 7 \d */ OP_NOT_WHITESPACE, /* 8 \S */ @@ -1547,78 +1572,85 @@ enum { /* The assertions must come before BRA, CBRA, ONCE, and COND. */ OP_REVERSE, /* 125 Move pointer back - used in lookbehind assertions */ - OP_ASSERT, /* 126 Positive lookahead */ - OP_ASSERT_NOT, /* 127 Negative lookahead */ - OP_ASSERTBACK, /* 128 Positive lookbehind */ - OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */ - OP_ASSERT_NA, /* 130 Positive non-atomic lookahead */ - OP_ASSERTBACK_NA, /* 131 Positive non-atomic lookbehind */ + OP_VREVERSE, /* 126 Move pointer back - variable */ + OP_ASSERT, /* 127 Positive lookahead */ + OP_ASSERT_NOT, /* 128 Negative lookahead */ + OP_ASSERTBACK, /* 129 Positive lookbehind */ + OP_ASSERTBACK_NOT, /* 130 Negative lookbehind */ + OP_ASSERT_NA, /* 131 Positive non-atomic lookahead */ + OP_ASSERTBACK_NA, /* 132 Positive non-atomic lookbehind */ /* ONCE, SCRIPT_RUN, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately after the assertions, with ONCE first, as there's a test for >= ONCE for a subpattern that isn't an assertion. The POS versions must immediately follow the non-POS versions in each case. */ - OP_ONCE, /* 132 Atomic group, contains captures */ - OP_SCRIPT_RUN, /* 133 Non-capture, but check characters' scripts */ - OP_BRA, /* 134 Start of non-capturing bracket */ - OP_BRAPOS, /* 135 Ditto, with unlimited, possessive repeat */ - OP_CBRA, /* 136 Start of capturing bracket */ - OP_CBRAPOS, /* 137 Ditto, with unlimited, possessive repeat */ - OP_COND, /* 138 Conditional group */ + OP_ONCE, /* 133 Atomic group, contains captures */ + OP_SCRIPT_RUN, /* 134 Non-capture, but check characters' scripts */ + OP_BRA, /* 135 Start of non-capturing bracket */ + OP_BRAPOS, /* 136 Ditto, with unlimited, possessive repeat */ + OP_CBRA, /* 137 Start of capturing bracket */ + OP_CBRAPOS, /* 138 Ditto, with unlimited, possessive repeat */ + OP_COND, /* 139 Conditional group */ /* These five must follow the previous five, in the same order. There's a check for >= SBRA to distinguish the two sets. */ - OP_SBRA, /* 139 Start of non-capturing bracket, check empty */ - OP_SBRAPOS, /* 149 Ditto, with unlimited, possessive repeat */ - OP_SCBRA, /* 141 Start of capturing bracket, check empty */ - OP_SCBRAPOS, /* 142 Ditto, with unlimited, possessive repeat */ - OP_SCOND, /* 143 Conditional group, check empty */ + OP_SBRA, /* 140 Start of non-capturing bracket, check empty */ + OP_SBRAPOS, /* 141 Ditto, with unlimited, possessive repeat */ + OP_SCBRA, /* 142 Start of capturing bracket, check empty */ + OP_SCBRAPOS, /* 143 Ditto, with unlimited, possessive repeat */ + OP_SCOND, /* 144 Conditional group, check empty */ /* The next two pairs must (respectively) be kept together. */ - OP_CREF, /* 144 Used to hold a capture number as condition */ - OP_DNCREF, /* 145 Used to point to duplicate names as a condition */ - OP_RREF, /* 146 Used to hold a recursion number as condition */ - OP_DNRREF, /* 147 Used to point to duplicate names as a condition */ - OP_FALSE, /* 148 Always false (used by DEFINE and VERSION) */ - OP_TRUE, /* 149 Always true (used by VERSION) */ + OP_CREF, /* 145 Used to hold a capture number as condition */ + OP_DNCREF, /* 146 Used to point to duplicate names as a condition */ + OP_RREF, /* 147 Used to hold a recursion number as condition */ + OP_DNRREF, /* 148 Used to point to duplicate names as a condition */ + OP_FALSE, /* 149 Always false (used by DEFINE and VERSION) */ + OP_TRUE, /* 150 Always true (used by VERSION) */ - OP_BRAZERO, /* 150 These two must remain together and in this */ - OP_BRAMINZERO, /* 151 order. */ - OP_BRAPOSZERO, /* 152 */ + OP_BRAZERO, /* 151 These two must remain together and in this */ + OP_BRAMINZERO, /* 152 order. */ + OP_BRAPOSZERO, /* 153 */ /* These are backtracking control verbs */ - OP_MARK, /* 153 always has an argument */ - OP_PRUNE, /* 154 */ - OP_PRUNE_ARG, /* 155 same, but with argument */ - OP_SKIP, /* 156 */ - OP_SKIP_ARG, /* 157 same, but with argument */ - OP_THEN, /* 158 */ - OP_THEN_ARG, /* 159 same, but with argument */ - OP_COMMIT, /* 160 */ - OP_COMMIT_ARG, /* 161 same, but with argument */ + OP_MARK, /* 154 always has an argument */ + OP_PRUNE, /* 155 */ + OP_PRUNE_ARG, /* 156 same, but with argument */ + OP_SKIP, /* 157 */ + OP_SKIP_ARG, /* 158 same, but with argument */ + OP_THEN, /* 159 */ + OP_THEN_ARG, /* 160 same, but with argument */ + OP_COMMIT, /* 161 */ + OP_COMMIT_ARG, /* 162 same, but with argument */ /* These are forced failure and success verbs. FAIL and ACCEPT do accept an argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL) without the need for a special opcode. */ - OP_FAIL, /* 162 */ - OP_ACCEPT, /* 163 */ - OP_ASSERT_ACCEPT, /* 164 Used inside assertions */ - OP_CLOSE, /* 165 Used before OP_ACCEPT to close open captures */ + OP_FAIL, /* 163 */ + OP_ACCEPT, /* 164 */ + OP_ASSERT_ACCEPT, /* 165 Used inside assertions */ + OP_CLOSE, /* 166 Used before OP_ACCEPT to close open captures */ /* This is used to skip a subpattern with a {0} quantifier */ - OP_SKIPZERO, /* 166 */ + OP_SKIPZERO, /* 167 */ /* This is used to identify a DEFINE group during compilation so that it can be checked for having only one branch. It is changed to OP_FALSE before compilation finishes. */ - OP_DEFINE, /* 167 */ + OP_DEFINE, /* 168 */ + + /* These opcodes replace their normal counterparts in UCP mode when + PCRE2_EXTRA_ASCII_BSW is not set. */ + + OP_NOT_UCP_WORD_BOUNDARY, /* 169 */ + OP_UCP_WORD_BOUNDARY, /* 170 */ /* This is not an opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors - there have been @@ -1664,7 +1696,7 @@ some cases doesn't actually use these names at all). */ "class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \ "Recurse", "Callout", "CalloutStr", \ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ - "Reverse", "Assert", "Assert not", \ + "Reverse", "VReverse", "Assert", "Assert not", \ "Assert back", "Assert back not", \ "Non-atomic assert", "Non-atomic assert back", \ "Once", \ @@ -1679,7 +1711,7 @@ some cases doesn't actually use these names at all). */ "*MARK", "*PRUNE", "*PRUNE", "*SKIP", "*SKIP", \ "*THEN", "*THEN", "*COMMIT", "*COMMIT", "*FAIL", \ "*ACCEPT", "*ASSERT_ACCEPT", \ - "Close", "Skip zero", "Define" + "Close", "Skip zero", "Define", "\\B (ucp)", "\\b (ucp)" /* This macro defines the length of fixed length operations in the compiled @@ -1746,7 +1778,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1+LINK_SIZE, /* KetRmax */ \ 1+LINK_SIZE, /* KetRmin */ \ 1+LINK_SIZE, /* KetRpos */ \ - 1+LINK_SIZE, /* Reverse */ \ + 1+IMM2_SIZE, /* Reverse */ \ + 1+2*IMM2_SIZE, /* VReverse */ \ 1+LINK_SIZE, /* Assert */ \ 1+LINK_SIZE, /* Assert not */ \ 1+LINK_SIZE, /* Assert behind */ \ @@ -1775,7 +1808,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1, 3, /* COMMIT, COMMIT_ARG */ \ 1, 1, 1, /* FAIL, ACCEPT, ASSERT_ACCEPT */ \ 1+IMM2_SIZE, 1, /* CLOSE, SKIPZERO */ \ - 1 /* DEFINE */ + 1, /* DEFINE */ \ + 1, 1 /* \B and \b in UCP mode */ /* A magic value for OP_RREF to indicate the "any recursion" condition. */ @@ -2042,6 +2076,9 @@ extern void * _pcre2_memmove(void *, const void *, size_t); #endif #endif /* PCRE2_CODE_UNIT_WIDTH */ + +extern BOOL PRIV(ckd_smul)(PCRE2_SIZE *, int, int); + #endif /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */ /* End of pcre2_internal.h */ diff --git a/src/3rdparty/pcre2/src/pcre2_intmodedep.h b/src/3rdparty/pcre2/src/pcre2_intmodedep.h index 390e737a6ef..5fcddce5fe1 100644 --- a/src/3rdparty/pcre2/src/pcre2_intmodedep.h +++ b/src/3rdparty/pcre2/src/pcre2_intmodedep.h @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -572,6 +572,7 @@ typedef struct pcre2_real_compile_context { uint16_t newline_convention; uint32_t parens_nest_limit; uint32_t extra_options; + uint32_t max_varlookbehind; } pcre2_real_compile_context; /* The real match context structure. */ @@ -605,12 +606,12 @@ defined specially because it is required in pcre2_serialize_decode() when copying the size from possibly unaligned memory into a variable of the same type. Use a macro rather than a typedef to avoid compiler warnings when this file is included multiple times by pcre2test. LOOKBEHIND_MAX specifies the -largest lookbehind that is supported. (OP_REVERSE in a pattern has a 16-bit -argument in 8-bit and 16-bit modes, so we need no more than a 16-bit field -here.) */ +largest lookbehind that is supported. (OP_REVERSE and OP_VREVERSE in a pattern +have 16-bit arguments in 8-bit and 16-bit modes, so we need no more than a +16-bit field here.) */ #undef CODE_BLOCKSIZE_TYPE -#define CODE_BLOCKSIZE_TYPE size_t +#define CODE_BLOCKSIZE_TYPE PCRE2_SIZE #undef LOOKBEHIND_MAX #define LOOKBEHIND_MAX UINT16_MAX @@ -658,6 +659,7 @@ typedef struct pcre2_real_match_data { PCRE2_SPTR mark; /* Pointer to last mark */ struct heapframe *heapframes; /* Backtracking frames heap memory */ PCRE2_SIZE heapframes_size; /* Malloc-ed size */ + PCRE2_SIZE subject_length; /* Subject length */ PCRE2_SIZE leftchar; /* Offset to leftmost code unit */ PCRE2_SIZE rightchar; /* Offset to rightmost code unit */ PCRE2_SIZE startchar; /* Offset to starting code unit */ @@ -675,8 +677,8 @@ typedef struct pcre2_real_match_data { #ifndef PCRE2_PCRE2TEST -/* Structures for checking for mutual recursion when scanning compiled or -parsed code. */ +/* Structures for checking for mutual function recursion when scanning compiled +or parsed code. */ typedef struct recurse_check { struct recurse_check *prev; @@ -688,7 +690,7 @@ typedef struct parsed_recurse_check { uint32_t *groupptr; } parsed_recurse_check; -/* Structure for building a cache when filling in recursion offsets. */ +/* Structure for building a cache when filling in pattern recursion offsets. */ typedef struct recurse_cache { PCRE2_SPTR group; @@ -734,7 +736,6 @@ typedef struct compile_block { uint16_t name_entry_size; /* Size of each entry */ uint16_t parens_depth; /* Depth of nested parentheses */ uint16_t assert_depth; /* Depth of nested assertions */ - open_capitem *open_caps; /* Chain of open capture items */ named_group *named_groups; /* Points to vector in pre-compile */ uint32_t named_group_list_size; /* Number of entries in the list */ uint32_t external_options; /* External (initial) options */ @@ -752,10 +753,11 @@ typedef struct compile_block { uint32_t class_range_end; /* Overall class range end */ PCRE2_UCHAR nl[4]; /* Newline string when fixed length */ uint32_t req_varyopt; /* "After variable item" flag for reqbyte */ - int max_lookbehind; /* Maximum lookbehind (characters) */ + uint32_t max_varlookbehind; /* Limit for variable lookbehinds */ + int max_lookbehind; /* Maximum lookbehind encountered (characters) */ BOOL had_accept; /* (*ACCEPT) encountered */ BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ - BOOL had_recurse; /* Had a recursion or subroutine call */ + BOOL had_recurse; /* Had a pattern recursion or subroutine call */ BOOL dupnames; /* Duplicate names exist */ } compile_block; @@ -773,6 +775,7 @@ call within the pattern when running pcre2_dfa_match(). */ typedef struct dfa_recursion_info { struct dfa_recursion_info *prevrec; PCRE2_SPTR subject_position; + PCRE2_SPTR last_used_ptr; uint32_t group_num; } dfa_recursion_info; @@ -793,7 +796,7 @@ typedef struct heapframe { PCRE2_SIZE length; /* Used for character, string, or code lengths */ PCRE2_SIZE back_frame; /* Amount to subtract on RRETURN */ PCRE2_SIZE temp_size; /* Used for short-term PCRE2_SIZE values */ - uint32_t rdepth; /* "Recursion" depth */ + uint32_t rdepth; /* Function "recursion" depth within pcre2_match() */ uint32_t group_frame_type; /* Type information for group frames */ uint32_t temp_32[4]; /* Used for short-term 32-bit or BOOL values */ uint8_t return_id; /* Where to go on in internal "return" */ @@ -826,14 +829,15 @@ typedef struct heapframe { allows for exactly the right size ovector for the number of capturing parentheses. (See also the comment for pcre2_real_match_data above.) */ - PCRE2_SPTR eptr; /* MUST BE FIRST */ - PCRE2_SPTR start_match; /* Can be adjusted by \K */ - PCRE2_SPTR mark; /* Most recent mark on the success path */ - uint32_t current_recurse; /* Current (deepest) recursion number */ - uint32_t capture_last; /* Most recent capture */ - PCRE2_SIZE last_group_offset; /* Saved offset to most recent group frame */ - PCRE2_SIZE offset_top; /* Offset after highest capture */ - PCRE2_SIZE ovector[131072]; /* Must be last in the structure */ + PCRE2_SPTR eptr; /* MUST BE FIRST */ + PCRE2_SPTR start_match; /* Can be adjusted by \K */ + PCRE2_SPTR mark; /* Most recent mark on the success path */ + PCRE2_SPTR recurse_last_used; /* Last character used at time of pattern recursion */ + uint32_t current_recurse; /* Group number of current (deepest) pattern recursion */ + uint32_t capture_last; /* Most recent capture */ + PCRE2_SIZE last_group_offset; /* Saved offset to most recent group frame */ + PCRE2_SIZE offset_top; /* Offset after highest capture */ + PCRE2_SIZE ovector[131072]; /* Must be last in the structure */ } heapframe; /* This typedef is a check that the size of the heapframe structure is a @@ -858,7 +862,7 @@ doing traditional NFA matching (pcre2_match() and friends). */ typedef struct match_block { pcre2_memctl memctl; /* For general use */ - PCRE2_SIZE heap_limit; /* As it says */ + uint32_t heap_limit; /* As it says */ uint32_t match_limit; /* As it says */ uint32_t match_limit_depth; /* As it says */ uint32_t match_call_count; /* Number of times a new frame is created */ @@ -875,10 +879,11 @@ typedef struct match_block { uint16_t name_count; /* Number of names in name table */ uint16_t name_entry_size; /* Size of entry in names table */ PCRE2_SPTR name_table; /* Table of group names */ - PCRE2_SPTR start_code; /* For use when recursing */ + PCRE2_SPTR start_code; /* For use in pattern recursion */ PCRE2_SPTR start_subject; /* Start of the subject string */ PCRE2_SPTR check_subject; /* Where UTF-checked from */ - PCRE2_SPTR end_subject; /* End of the subject string */ + PCRE2_SPTR end_subject; /* Usable end of the subject string */ + PCRE2_SPTR true_end_subject; /* Actual end of the subject string */ PCRE2_SPTR end_match_ptr; /* Subject position at end match */ PCRE2_SPTR start_used_ptr; /* Earliest consulted character */ PCRE2_SPTR last_used_ptr; /* Latest consulted character */ @@ -886,7 +891,7 @@ typedef struct match_block { PCRE2_SPTR nomatch_mark; /* Mark pointer to pass back on failure */ PCRE2_SPTR verb_ecode_ptr; /* For passing back info */ PCRE2_SPTR verb_skip_ptr; /* For passing back a (*SKIP) name */ - uint32_t verb_current_recurse; /* Current recurse when (*VERB) happens */ + uint32_t verb_current_recurse; /* Current recursion group when (*VERB) happens */ uint32_t moptions; /* Match options */ uint32_t poptions; /* Pattern options */ uint32_t skip_arg_count; /* For counting SKIP_ARGs */ @@ -911,7 +916,7 @@ typedef struct dfa_match_block { PCRE2_SPTR last_used_ptr; /* Latest consulted character */ const uint8_t *tables; /* Character tables */ PCRE2_SIZE start_offset; /* The start offset value */ - PCRE2_SIZE heap_limit; /* As it says */ + uint32_t heap_limit; /* As it says */ PCRE2_SIZE heap_used; /* As it says */ uint32_t match_limit; /* As it says */ uint32_t match_limit_depth; /* As it says */ @@ -926,7 +931,7 @@ typedef struct dfa_match_block { pcre2_callout_block *cb; /* Points to a callout block */ void *callout_data; /* To pass back to callouts */ int (*callout)(pcre2_callout_block *,void *); /* Callout function or NULL */ - dfa_recursion_info *recursive; /* Linked list of recursion data */ + dfa_recursion_info *recursive; /* Linked list of pattern recursion data */ } dfa_match_block; #endif /* PCRE2_PCRE2TEST */ diff --git a/src/3rdparty/pcre2/src/pcre2_jit_compile.c b/src/3rdparty/pcre2/src/pcre2_jit_compile.c index 0afd27c5eed..050063ec6d1 100644 --- a/src/3rdparty/pcre2/src/pcre2_jit_compile.c +++ b/src/3rdparty/pcre2/src/pcre2_jit_compile.c @@ -43,6 +43,12 @@ POSSIBILITY OF SUCH DAMAGE. #include "config.h" #endif +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#include +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ + #include "pcre2_internal.h" #ifdef SUPPORT_JIT @@ -236,12 +242,21 @@ code generator. It is allocated by compile_matchingpath, and contains the arguments for compile_backtrackingpath. Must be the first member of its descendants. */ typedef struct backtrack_common { - /* Concatenation stack. */ + /* Backtracking path of an opcode, which falls back + to our opcode, if it cannot resume matching. */ struct backtrack_common *prev; - jump_list *nextbacktracks; - /* Internal stack (for component operators). */ + /* Backtracks for opcodes without backtracking path. + These opcodes are between 'prev' and the current + opcode, and they never resume the match. */ + jump_list *simple_backtracks; + /* Internal backtracking list for block constructs + which contains other opcodes, such as brackets, + asserts, conditionals, etc. */ struct backtrack_common *top; - jump_list *topbacktracks; + /* Backtracks used internally by the opcode. For component + opcodes, this list is also used by those opcodes without + backtracking path which follows the 'top' backtrack. */ + jump_list *own_backtracks; /* Opcode pointer. */ PCRE2_SPTR cc; } backtrack_common; @@ -338,6 +353,12 @@ typedef struct recurse_backtrack { BOOL inlined_pattern; } recurse_backtrack; +typedef struct vreverse_backtrack { + backtrack_common common; + /* Return to the matching path. */ + struct sljit_label *matchingpath; +} vreverse_backtrack; + #define OP_THEN_TRAP OP_TABLE_LENGTH typedef struct then_trap_backtrack { @@ -404,7 +425,9 @@ typedef struct compiler_common { sljit_s32 match_end_ptr; /* Points to the marked string. */ sljit_s32 mark_ptr; - /* Recursive control verb management chain. */ + /* Head of the recursive control verb management chain. + Each item must have a previous offset and type + (see control_types) values. See do_search_mark. */ sljit_s32 control_head_ptr; /* Points to the last matched capture block index. */ sljit_s32 capture_last_ptr; @@ -474,12 +497,15 @@ typedef struct compiler_common { jump_list *stackalloc; jump_list *revertframes; jump_list *wordboundary; + jump_list *ucp_wordboundary; jump_list *anynewline; jump_list *hspace; jump_list *vspace; jump_list *casefulcmp; jump_list *caselesscmp; jump_list *reset_match; + /* Same as reset_match, but resets the STR_PTR as well. */ + jump_list *restart_match; BOOL unset_backref; BOOL alt_circumflex; #ifdef SUPPORT_UNICODE @@ -636,8 +662,8 @@ the start pointers when the end of the capturing group has not yet reached. */ sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) #define OP_FLAGS(op, dst, dstw, type) \ sljit_emit_op_flags(compiler, (op), (dst), (dstw), (type)) -#define CMOV(type, dst_reg, src, srcw) \ - sljit_emit_cmov(compiler, (type), (dst_reg), (src), (srcw)) +#define SELECT(type, dst_reg, src1, src1w, src2_reg) \ + sljit_emit_select(compiler, (type), (dst_reg), (src1), (src1w), (src2_reg)) #define GET_LOCAL_BASE(dst, dstw, offset) \ sljit_get_local_base(compiler, (dst), (dstw), (offset)) @@ -857,6 +883,21 @@ SLJIT_ASSERT(*cc >= OP_KET && *cc <= OP_KETRPOS); return count; } +static BOOL find_vreverse(PCRE2_SPTR cc) +{ + SLJIT_ASSERT(*cc == OP_ASSERTBACK || *cc == OP_ASSERTBACK_NOT || *cc == OP_ASSERTBACK_NA); + + do + { + if (cc[1 + LINK_SIZE] == OP_VREVERSE) + return TRUE; + cc += GET(cc, 1); + } + while (*cc == OP_ALT); + + return FALSE; +} + /* Functions whose might need modification for all new supported opcodes: next_opcode check_opcode_types @@ -927,6 +968,7 @@ switch(*cc) case OP_KETRMIN: case OP_KETRPOS: case OP_REVERSE: + case OP_VREVERSE: case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: @@ -963,6 +1005,8 @@ switch(*cc) case OP_ASSERT_ACCEPT: case OP_CLOSE: case OP_SKIPZERO: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: return cc + PRIV(OP_lengths)[*cc]; case OP_CHAR: @@ -1231,34 +1275,37 @@ while (cc < ccend) return TRUE; } -#define EARLY_FAIL_ENHANCE_MAX (1 + 3) +#define EARLY_FAIL_ENHANCE_MAX (3 + 3) /* -start: - 0 - skip / early fail allowed - 1 - only early fail with range allowed - >1 - (start - 1) early fail is processed + Start represent the number of allowed early fail enhancements -return: current number of iterators enhanced with fast fail + The 0-2 values has a special meaning: + 0 - skip is allowed for all iterators + 1 - fail is allowed for all iterators + 2 - fail is allowed for greedy iterators + 3 - only ranged early fail is allowed + >3 - (start - 3) number of remaining ranged early fails allowed + +return: the updated value of start */ -static int detect_early_fail(compiler_common *common, PCRE2_SPTR cc, int *private_data_start, - sljit_s32 depth, int start, BOOL fast_forward_allowed) +static int detect_early_fail(compiler_common *common, PCRE2_SPTR cc, + int *private_data_start, sljit_s32 depth, int start) { PCRE2_SPTR begin = cc; PCRE2_SPTR next_alt; PCRE2_SPTR end; PCRE2_SPTR accelerated_start; -BOOL prev_fast_forward_allowed; int result = 0; -int count; +int count, prev_count; SLJIT_ASSERT(*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA); SLJIT_ASSERT(*cc != OP_CBRA || common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] != 0); SLJIT_ASSERT(start < EARLY_FAIL_ENHANCE_MAX); next_alt = cc + GET(cc, 1); -if (*next_alt == OP_ALT) - fast_forward_allowed = FALSE; +if (*next_alt == OP_ALT && start < 1) + start = 1; do { @@ -1282,6 +1329,8 @@ do case OP_CIRCM: case OP_DOLL: case OP_DOLLM: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: /* Zero width assertions. */ cc++; continue; @@ -1299,21 +1348,22 @@ do case OP_HSPACE: case OP_NOT_VSPACE: case OP_VSPACE: - fast_forward_allowed = FALSE; + if (count < 1) + count = 1; cc++; continue; case OP_ANYNL: case OP_EXTUNI: - fast_forward_allowed = FALSE; - if (count == 0) - count = 1; + if (count < 3) + count = 3; cc++; continue; case OP_NOTPROP: case OP_PROP: - fast_forward_allowed = FALSE; + if (count < 1) + count = 1; cc += 1 + 2; continue; @@ -1321,17 +1371,22 @@ do case OP_CHARI: case OP_NOT: case OP_NOTI: - fast_forward_allowed = FALSE; + if (count < 1) + count = 1; cc += 2; #ifdef SUPPORT_UNICODE if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); #endif continue; - case OP_TYPESTAR: case OP_TYPEMINSTAR: - case OP_TYPEPLUS: case OP_TYPEMINPLUS: + if (count == 2) + count = 3; + /* Fall through */ + + case OP_TYPESTAR: + case OP_TYPEPLUS: case OP_TYPEPOSSTAR: case OP_TYPEPOSPLUS: /* The type or prop opcode is skipped in the next iteration. */ @@ -1343,14 +1398,18 @@ do break; } - if (count == 0) + if (count < 3) + count = 3; + continue; + + case OP_TYPEEXACT: + if (count < 1) count = 1; - fast_forward_allowed = FALSE; + cc += 1 + IMM2_SIZE; continue; case OP_TYPEUPTO: case OP_TYPEMINUPTO: - case OP_TYPEEXACT: case OP_TYPEPOSUPTO: cc += IMM2_SIZE; /* Fall through */ @@ -1359,37 +1418,40 @@ do case OP_TYPEMINQUERY: case OP_TYPEPOSQUERY: /* The type or prop opcode is skipped in the next iteration. */ - fast_forward_allowed = FALSE; - if (count == 0) - count = 1; + if (count < 3) + count = 3; cc += 1; continue; - case OP_STAR: case OP_MINSTAR: - case OP_PLUS: case OP_MINPLUS: + case OP_MINSTARI: + case OP_MINPLUSI: + case OP_NOTMINSTAR: + case OP_NOTMINPLUS: + case OP_NOTMINSTARI: + case OP_NOTMINPLUSI: + if (count == 2) + count = 3; + /* Fall through */ + + case OP_STAR: + case OP_PLUS: case OP_POSSTAR: case OP_POSPLUS: case OP_STARI: - case OP_MINSTARI: case OP_PLUSI: - case OP_MINPLUSI: case OP_POSSTARI: case OP_POSPLUSI: case OP_NOTSTAR: - case OP_NOTMINSTAR: case OP_NOTPLUS: - case OP_NOTMINPLUS: case OP_NOTPOSSTAR: case OP_NOTPOSPLUS: case OP_NOTSTARI: - case OP_NOTMINSTARI: case OP_NOTPLUSI: - case OP_NOTMINPLUSI: case OP_NOTPOSSTARI: case OP_NOTPOSPLUSI: accelerated_start = cc; @@ -1399,9 +1461,17 @@ do #endif break; + case OP_EXACT: + if (count < 1) + count = 1; + cc += 2 + IMM2_SIZE; +#ifdef SUPPORT_UNICODE + if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); +#endif + continue; + case OP_UPTO: case OP_MINUPTO: - case OP_EXACT: case OP_POSUPTO: case OP_UPTOI: case OP_MINUPTOI: @@ -1430,9 +1500,8 @@ do case OP_NOTQUERYI: case OP_NOTMINQUERYI: case OP_NOTPOSQUERYI: - fast_forward_allowed = FALSE; - if (count == 0) - count = 1; + if (count < 3) + count = 3; cc += 2; #ifdef SUPPORT_UNICODE if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); @@ -1452,10 +1521,14 @@ do switch (*cc) { - case OP_CRSTAR: case OP_CRMINSTAR: - case OP_CRPLUS: case OP_CRMINPLUS: + if (count == 2) + count = 3; + /* Fall through */ + + case OP_CRSTAR: + case OP_CRPLUS: case OP_CRPOSSTAR: case OP_CRPOSPLUS: cc++; @@ -1464,44 +1537,60 @@ do case OP_CRRANGE: case OP_CRMINRANGE: case OP_CRPOSRANGE: + if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE)) + { + /* Exact repeat. */ + cc += 1 + 2 * IMM2_SIZE; + if (count < 1) + count = 1; + continue; + } + cc += 2 * IMM2_SIZE; /* Fall through */ case OP_CRQUERY: case OP_CRMINQUERY: case OP_CRPOSQUERY: cc++; - if (count == 0) - count = 1; - /* Fall through */ + if (count < 3) + count = 3; + continue; + default: - accelerated_start = NULL; - fast_forward_allowed = FALSE; + /* No repeat. */ + if (count < 1) + count = 1; continue; } break; - case OP_ONCE: case OP_BRA: case OP_CBRA: - end = cc + GET(cc, 1); + prev_count = count; + if (count < 1) + count = 1; - prev_fast_forward_allowed = fast_forward_allowed; - fast_forward_allowed = FALSE; if (depth >= 4) break; - end = bracketend(cc) - (1 + LINK_SIZE); - if (*end != OP_KET || (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)) + if (count < 3 && cc[GET(cc, 1)] == OP_ALT) + count = 3; + + end = bracketend(cc); + if (end[-1 - LINK_SIZE] != OP_KET || (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)) break; - count = detect_early_fail(common, cc, private_data_start, depth + 1, count, prev_fast_forward_allowed); + prev_count = detect_early_fail(common, cc, private_data_start, depth + 1, prev_count); + + if (prev_count > count) + count = prev_count; if (PRIVATE_DATA(cc) != 0) common->private_data_ptrs[begin - common->start] = 1; if (count < EARLY_FAIL_ENHANCE_MAX) { - cc = end + (1 + LINK_SIZE); + cc = end; continue; } break; @@ -1514,55 +1603,52 @@ do continue; } - if (accelerated_start != NULL) + if (accelerated_start == NULL) + break; + + if (count == 0) { - if (count == 0) - { - count++; + common->fast_forward_bc_ptr = accelerated_start; + common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_skip; + *private_data_start += sizeof(sljit_sw); + count = 4; + } + else if (count < 3) + { + common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail; - if (fast_forward_allowed) - { - common->fast_forward_bc_ptr = accelerated_start; - common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_skip; - *private_data_start += sizeof(sljit_sw); - } - else - { - common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail; + if (common->early_fail_start_ptr == 0) + common->early_fail_start_ptr = *private_data_start; - if (common->early_fail_start_ptr == 0) - common->early_fail_start_ptr = *private_data_start; + *private_data_start += sizeof(sljit_sw); + common->early_fail_end_ptr = *private_data_start; - *private_data_start += sizeof(sljit_sw); - common->early_fail_end_ptr = *private_data_start; + if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) + return EARLY_FAIL_ENHANCE_MAX; - if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) - return EARLY_FAIL_ENHANCE_MAX; - } - } - else - { - common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail_range; + count = 4; + } + else + { + common->private_data_ptrs[(accelerated_start + 1) - common->start] = ((*private_data_start) << 3) | type_fail_range; - if (common->early_fail_start_ptr == 0) - common->early_fail_start_ptr = *private_data_start; + if (common->early_fail_start_ptr == 0) + common->early_fail_start_ptr = *private_data_start; - *private_data_start += 2 * sizeof(sljit_sw); - common->early_fail_end_ptr = *private_data_start; + *private_data_start += 2 * sizeof(sljit_sw); + common->early_fail_end_ptr = *private_data_start; - if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) - return EARLY_FAIL_ENHANCE_MAX; - } + if (*private_data_start > SLJIT_MAX_LOCAL_SIZE) + return EARLY_FAIL_ENHANCE_MAX; - /* Cannot be part of a repeat. */ - common->private_data_ptrs[begin - common->start] = 1; count++; - - if (count < EARLY_FAIL_ENHANCE_MAX) - continue; } - break; + /* Cannot be part of a repeat. */ + common->private_data_ptrs[begin - common->start] = 1; + + if (count >= EARLY_FAIL_ENHANCE_MAX) + break; } if (*cc != OP_ALT && *cc != OP_KET) @@ -1795,7 +1881,6 @@ while (cc < ccend) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ASSERT_NA: - case OP_ASSERTBACK_NA: case OP_ONCE: case OP_SCRIPT_RUN: case OP_BRAPOS: @@ -1807,6 +1892,19 @@ while (cc < ccend) bracketlen = 1 + LINK_SIZE; break; + case OP_ASSERTBACK_NA: + common->private_data_ptrs[cc - common->start] = private_data_ptr; + private_data_ptr += sizeof(sljit_sw); + + if (find_vreverse(cc)) + { + common->private_data_ptrs[cc + 1 - common->start] = 1; + private_data_ptr += sizeof(sljit_sw); + } + + bracketlen = 1 + LINK_SIZE; + break; + case OP_CBRAPOS: case OP_SCBRAPOS: common->private_data_ptrs[cc - common->start] = private_data_ptr; @@ -2106,6 +2204,9 @@ while (cc < ccend) case OP_CALLOUT: case OP_CALLOUT_STR: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); break; @@ -2261,7 +2362,7 @@ int i; for (i = 0; i < RECURSE_TMP_REG_COUNT; i++) { SLJIT_ASSERT(status->tmp_regs[i] >= 0); - SLJIT_ASSERT(sljit_get_register_index(status->saved_tmp_regs[i]) < 0 || status->tmp_regs[i] == status->saved_tmp_regs[i]); + SLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, status->saved_tmp_regs[i]) < 0 || status->tmp_regs[i] == status->saved_tmp_regs[i]); status->store_bases[i] = -1; } @@ -2281,7 +2382,7 @@ SLJIT_ASSERT(load_base > 0 && store_base > 0); if (status->store_bases[next_tmp_reg] == -1) { /* Preserve virtual registers. */ - if (sljit_get_register_index(status->saved_tmp_regs[next_tmp_reg]) < 0) + if (sljit_get_register_index(SLJIT_GP_REGISTER, status->saved_tmp_regs[next_tmp_reg]) < 0) OP1(SLJIT_MOV, status->saved_tmp_regs[next_tmp_reg], 0, tmp_reg, 0); } else @@ -2310,7 +2411,7 @@ for (i = 0; i < RECURSE_TMP_REG_COUNT; i++) OP1(SLJIT_MOV, SLJIT_MEM1(status->store_bases[next_tmp_reg]), status->store_offsets[next_tmp_reg], tmp_reg, 0); /* Restore virtual registers. */ - if (sljit_get_register_index(saved_tmp_reg) < 0) + if (sljit_get_register_index(SLJIT_GP_REGISTER, saved_tmp_reg) < 0) OP1(SLJIT_MOV, tmp_reg, 0, saved_tmp_reg, 0); } @@ -3047,8 +3148,16 @@ if (*cc == OP_COND || *cc == OP_SCOND) has_alternatives = FALSE; cc = next_opcode(common, cc); + if (has_alternatives) + { + if (*cc == OP_REVERSE) + cc += 1 + IMM2_SIZE; + else if (*cc == OP_VREVERSE) + cc += 1 + 2 * IMM2_SIZE; + current_offset = common->then_offsets + (cc - common->start); + } while (cc < end) { @@ -3057,7 +3166,18 @@ while (cc < end) else { if (*cc == OP_ALT && has_alternatives) - current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start); + { + cc += 1 + LINK_SIZE; + + if (*cc == OP_REVERSE) + cc += 1 + IMM2_SIZE; + else if (*cc == OP_VREVERSE) + cc += 1 + 2 * IMM2_SIZE; + + current_offset = common->then_offsets + (cc - common->start); + continue; + } + if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL) *current_offset = 1; cc = next_opcode(common, cc); @@ -3081,7 +3201,7 @@ return (value & (value - 1)) == 0; static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label) { -while (list) +while (list != NULL) { /* sljit_set_label is clever enough to do nothing if either the jump or the label is NULL. */ @@ -3239,7 +3359,7 @@ if (size == sizeof(sljit_sw)) return; } -if (sljit_get_register_index(TMP3) >= 0 && !sljit_has_cpu_feature(SLJIT_HAS_ZERO_REGISTER)) +if (sljit_get_register_index(SLJIT_GP_REGISTER, TMP3) >= 0 && !sljit_has_cpu_feature(SLJIT_HAS_ZERO_REGISTER)) { OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); src = TMP3; @@ -3818,9 +3938,9 @@ if (common->invalid_utf) { OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); } } #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ @@ -4058,9 +4178,9 @@ if (common->utf) OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400); if (options & READ_CHAR_UPDATE_STR_PTR) - CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0); + SELECT(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0, STR_PTR); if (max >= 0xd800) - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, 0x10000); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, 0x10000, TMP1); } else { @@ -4085,15 +4205,46 @@ if (common->invalid_utf) { OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); } } #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ #endif /* SUPPORT_UNICODE */ } +static void skip_valid_char(compiler_common *common) +{ +DEFINE_COMPILER; +#if (defined SUPPORT_UNICODE) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) +struct sljit_jump *jump; +#endif + +#if (defined SUPPORT_UNICODE) && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) + if (common->utf) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if PCRE2_CODE_UNIT_WIDTH == 8 + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +#elif PCRE2_CODE_UNIT_WIDTH == 16 + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xd800); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ + JUMPHERE(jump); + return; + } +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */ + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +} + #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 static BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass) @@ -4135,6 +4286,7 @@ if (negated) if (common->invalid_utf) { + OP1(SLJIT_MOV, TMP1, 0, TMP2, 0); add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL)); add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); @@ -4242,7 +4394,7 @@ if (common->utf && negated) { OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, SLJIT_IMM, 0x400); - CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0); + SELECT(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0, STR_PTR); } else { @@ -4399,7 +4551,7 @@ of the character (>= 0xc0). Return char value in TMP1. */ DEFINE_COMPILER; struct sljit_jump *jump; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); @@ -4445,7 +4597,7 @@ DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_jump *compare; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0x20); jump = JUMP(SLJIT_NOT_ZERO); @@ -4487,7 +4639,7 @@ struct sljit_label *three_byte_entry; struct sljit_label *exit_invalid_label; struct sljit_jump *exit_invalid[11]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc2); @@ -4522,7 +4674,7 @@ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0x20000); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0x20000, TMP1); exit_invalid[2] = NULL; } else @@ -4537,7 +4689,7 @@ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2d800); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0xd800); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0xd800, TMP1); exit_invalid[3] = NULL; } else @@ -4548,7 +4700,7 @@ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); exit_invalid[4] = NULL; } else @@ -4565,7 +4717,7 @@ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0, TMP1); exit_invalid[5] = NULL; } else @@ -4575,7 +4727,7 @@ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc10000); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000, TMP1); exit_invalid[6] = NULL; } else @@ -4612,7 +4764,7 @@ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); exit_invalid[10] = NULL; } else @@ -4643,7 +4795,7 @@ struct sljit_label *skip_start; struct sljit_label *three_byte_exit; struct sljit_jump *jump[5]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); if (common->nltype != NLTYPE_ANY) { @@ -4734,7 +4886,7 @@ struct sljit_label *exit_ok_label; struct sljit_label *exit_invalid_label; struct sljit_jump *exit_invalid[7]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0); @@ -4825,7 +4977,7 @@ static void do_utfpeakcharback(compiler_common *common) DEFINE_COMPILER; struct sljit_jump *jump[2]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); @@ -4868,7 +5020,7 @@ struct sljit_label *three_byte_entry; struct sljit_label *exit_invalid_label; struct sljit_jump *exit_invalid[8]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0); @@ -4905,7 +5057,7 @@ OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, -0xd800); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, -0xd800, TMP1); exit_invalid[2] = NULL; } else @@ -4915,7 +5067,7 @@ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x800); - CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + SELECT(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR, TMP1); exit_invalid[3] = NULL; } else @@ -4940,7 +5092,7 @@ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); if (has_cmov) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x100000); - CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000); + SELECT(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000, TMP1); exit_invalid[5] = NULL; } else @@ -5000,7 +5152,7 @@ undefined for invalid characters. */ DEFINE_COMPILER; struct sljit_jump *exit_invalid[3]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); /* TMP2 contains the high surrogate. */ exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00); @@ -5033,7 +5185,7 @@ char value in TMP1. */ DEFINE_COMPILER; struct sljit_jump *exit_invalid[2]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); /* TMP2 contains the high surrogate. */ exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); @@ -5062,7 +5214,7 @@ static void do_utfmoveback_invalid(compiler_common *common) DEFINE_COMPILER; struct sljit_jump *exit_invalid[3]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); exit_invalid[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x400); exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0); @@ -5091,7 +5243,7 @@ DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_jump *exit_invalid[3]; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); @@ -5140,7 +5292,7 @@ SLJIT_ASSERT(record->caseset == 0 && record->other_case == 0); SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 12); -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); #if PCRE2_CODE_UNIT_WIDTH == 32 if (!common->utf) @@ -5180,7 +5332,7 @@ SLJIT_ASSERT(record->caseset == 0 && record->other_case == 0); SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 12); -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); #if PCRE2_CODE_UNIT_WIDTH == 32 if (!common->utf) @@ -5379,7 +5531,7 @@ else if (common->utf) { OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, SLJIT_IMM, 0x400); - CMOV(SLJIT_LESS, STR_PTR, TMP2, 0); + SELECT(SLJIT_LESS, STR_PTR, TMP2, 0, STR_PTR); } else { @@ -5486,6 +5638,8 @@ while (TRUE) case OP_CIRCM: case OP_DOLL: case OP_DOLLM: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: /* Zero width assertions. */ cc++; continue; @@ -5869,6 +6023,7 @@ static BOOL check_fast_forward_char_pair_simd(compiler_common *common, fast_forw { sljit_s32 i, j, max_i = 0, max_j = 0; sljit_u32 max_pri = 0; + sljit_s32 max_offset = max_fast_forward_char_pair_offset(); PCRE2_UCHAR a1, a2, a_pri, b1, b2, b_pri; for (i = max - 1; i >= 1; i--) @@ -5879,7 +6034,7 @@ static BOOL check_fast_forward_char_pair_simd(compiler_common *common, fast_forw a2 = chars[i].chars[1]; a_pri = chars[i].last_count; - j = i - max_fast_forward_char_pair_offset(); + j = i - max_offset; if (j < 0) j = 0; @@ -5935,7 +6090,7 @@ if (has_match_end) OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offset + 1)); OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0); - CMOV(SLJIT_GREATER, STR_END, TMP1, 0); + SELECT(SLJIT_GREATER, STR_END, TMP1, 0, STR_END); } #ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD @@ -6138,7 +6293,7 @@ if (common->match_end_ptr != 0) OP2(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max)); add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS)); OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0); - CMOV(SLJIT_GREATER, STR_END, TMP1, 0); + SELECT(SLJIT_GREATER, STR_END, TMP1, 0, STR_END); } else { @@ -6368,7 +6523,7 @@ if (JIT_HAS_FAST_FORWARD_CHAR_SIMD && (common->nltype == NLTYPE_FIXED || common- if (common->mode != PCRE2_JIT_COMPLETE) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); - CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); } } } @@ -6430,7 +6585,7 @@ if (common->match_end_ptr != 0) OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1)); OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_END, 0, TMP1, 0); - CMOV(SLJIT_GREATER, STR_END, TMP1, 0); + SELECT(SLJIT_GREATER, STR_END, TMP1, 0, STR_END); } start = LABEL(); @@ -6567,13 +6722,14 @@ DEFINE_COMPILER; struct sljit_jump *jump; struct sljit_label *mainloop; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); GET_LOCAL_BASE(TMP1, 0, 0); /* Drop frames until we reach STACK_TOP. */ mainloop = LABEL(); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), -SSIZE_OF(sw)); -jump = CMP(SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0); +OP2U(SLJIT_SUB | SLJIT_SET_SIG_LESS_EQUAL | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0); +jump = JUMP(SLJIT_SIG_LESS_EQUAL); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); if (HAS_VIRTUAL_REGISTERS) @@ -6594,7 +6750,8 @@ else JUMPTO(SLJIT_JUMP, mainloop); JUMPHERE(jump); -jump = CMP(SLJIT_NOT_ZERO /* SIG_LESS */, TMP2, 0, SLJIT_IMM, 0); +sljit_set_current_flags(compiler, SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE | SLJIT_SET_SIG_LESS_EQUAL | SLJIT_SET_Z); +jump = JUMP(SLJIT_NOT_ZERO /* SIG_LESS */); /* End of reverting values. */ OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0); @@ -6615,7 +6772,17 @@ else JUMPTO(SLJIT_JUMP, mainloop); } -static void check_wordboundary(compiler_common *common) +#ifdef SUPPORT_UNICODE +#define UCPCAT(bit) (1 << (bit)) +#define UCPCAT2(bit1, bit2) (UCPCAT(bit1) | UCPCAT(bit2)) +#define UCPCAT3(bit1, bit2, bit3) (UCPCAT(bit1) | UCPCAT(bit2) | UCPCAT(bit3)) +#define UCPCAT_RANGE(start, end) (((1 << ((end) + 1)) - 1) - ((1 << (start)) - 1)) +#define UCPCAT_L UCPCAT_RANGE(ucp_Ll, ucp_Lu) +#define UCPCAT_N UCPCAT_RANGE(ucp_Nd, ucp_No) +#define UCPCAT_ALL ((1 << (ucp_Zs + 1)) - 1) +#endif + +static void check_wordboundary(compiler_common *common, BOOL ucp) { DEFINE_COMPILER; struct sljit_jump *skipread; @@ -6629,9 +6796,10 @@ jump_list *invalid_utf2 = NULL; struct sljit_jump *jump; #endif /* PCRE2_CODE_UNIT_WIDTH != 8 || SUPPORT_UNICODE */ +SLJIT_UNUSED_ARG(ucp); SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); -sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); /* Get type of the previous char, and put it to TMP3. */ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); @@ -6668,19 +6836,12 @@ else /* Testing char type. */ #ifdef SUPPORT_UNICODE -if (common->ucp) +if (ucp) { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); - jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - JUMPHERE(jump); - OP1(SLJIT_MOV, TMP3, 0, TMP2, 0); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP1, 0); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N); + OP_FLAGS(SLJIT_MOV, TMP3, 0, SLJIT_NOT_ZERO); } else #endif /* SUPPORT_UNICODE */ @@ -6714,18 +6875,12 @@ peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf2); valid_utf = LABEL(); -if (common->ucp) +if (ucp) { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); - jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - JUMPHERE(jump); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP1, 0); + OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); } else #endif /* SUPPORT_UNICODE */ @@ -7003,7 +7158,7 @@ while (i < len) else { OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, char_list[i]); - CMOV(SLJIT_ZERO, TMP2, TMP1, 0); + SELECT(SLJIT_ZERO, TMP2, TMP1, 0, TMP2); } i++; } @@ -7017,7 +7172,7 @@ if (j != 0) { j--; OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, char_list[i] & 0xff); - CMOV(SLJIT_ZERO, TMP2, TMP1, 0); + SELECT(SLJIT_ZERO, TMP2, TMP1, 0, TMP2); } } @@ -7042,7 +7197,7 @@ static void check_anynewline(compiler_common *common) /* Check whether TMP1 contains a newline character. TMP2 destroyed. */ DEFINE_COMPILER; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); @@ -7069,7 +7224,7 @@ static void check_hspace(compiler_common *common) /* Check whether TMP1 contains a newline character. TMP2 destroyed. */ DEFINE_COMPILER; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x09); OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); @@ -7108,7 +7263,7 @@ static void check_vspace(compiler_common *common) /* Check whether TMP1 contains a newline character. TMP2 destroyed. */ DEFINE_COMPILER; -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); @@ -7150,7 +7305,7 @@ else char2_reg = RETURN_ADDR; } -sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); if (char1_reg == STR_END) @@ -7237,7 +7392,7 @@ if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, else if (sljit_emit_mem_update(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS) opt_type = 2; -sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, char1_reg, 0); @@ -7464,16 +7619,6 @@ return cc; #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8 -#define SET_TYPE_OFFSET(value) \ - if ((value) != typeoffset) \ - { \ - if ((value) < typeoffset) \ - OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \ - else \ - OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \ - } \ - typeoffset = (value); - #define SET_CHAR_OFFSET(value) \ if ((value) != charoffset) \ { \ @@ -7498,7 +7643,6 @@ static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHA #define XCLASS_SCRIPT_EXTENSION_NOTPROP 0x080 #define XCLASS_SCRIPT_EXTENSION_RESTORE_RETURN_ADDR 0x100 #define XCLASS_SCRIPT_EXTENSION_RESTORE_LOCALS0 0x200 - #endif /* SUPPORT_UNICODE */ static void compile_xclass_matchingpath(compiler_common *common, PCRE2_SPTR cc, jump_list **backtracks) @@ -7516,9 +7660,10 @@ BOOL utf = common->utf; #ifdef SUPPORT_UNICODE sljit_u32 unicode_status = 0; +sljit_u32 category_list = 0; +sljit_u32 items; int typereg = TMP1; const sljit_u32 *other_cases; -sljit_uw typeoffset; #endif /* SUPPORT_UNICODE */ /* Scanning the necessary info. */ @@ -7535,6 +7680,7 @@ if (cc[-1] & XCL_MAP) while (*cc != XCL_END) { compares++; + if (*cc == XCL_SINGLE) { cc ++; @@ -7561,6 +7707,7 @@ while (*cc != XCL_END) { SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP); cc++; + if (*cc == PT_CLIST && cc[-1] == XCL_PROP) { other_cases = PRIV(ucd_caseless_sets) + cc[1]; @@ -7577,24 +7724,36 @@ while (*cc != XCL_END) min = 0; } + items = 0; + switch(*cc) { case PT_ANY: /* Any either accepts everything or ignored. */ if (cc[-1] == XCL_PROP) - { - compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); - if (list == backtracks) - add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - return; - } + items = UCPCAT_ALL; + else + compares--; break; case PT_LAMP: + items = UCPCAT3(ucp_Lu, ucp_Ll, ucp_Lt); + break; + case PT_GC: + items = UCPCAT_RANGE(PRIV(ucp_typerange)[(int)cc[1] * 2], PRIV(ucp_typerange)[(int)cc[1] * 2 + 1]); + break; + case PT_PC: + items = UCPCAT(cc[1]); + break; + + case PT_WORD: + items = UCPCAT2(ucp_Mn, ucp_Pc) | UCPCAT_L | UCPCAT_N; + break; + case PT_ALNUM: - unicode_status |= XCLASS_HAS_TYPE; + items = UCPCAT_L | UCPCAT_N; break; case PT_SCX: @@ -7613,7 +7772,6 @@ while (*cc != XCL_END) case PT_SPACE: case PT_PXSPACE: - case PT_WORD: case PT_PXGRAPH: case PT_PXPRINT: case PT_PXPUNCT: @@ -7622,6 +7780,7 @@ while (*cc != XCL_END) case PT_CLIST: case PT_UCNC: + case PT_PXXDIGIT: unicode_status |= XCLASS_SAVE_CHAR; break; @@ -7637,11 +7796,42 @@ while (*cc != XCL_END) SLJIT_UNREACHABLE(); break; } + + if (items > 0) + { + if (cc[-1] == XCL_NOTPROP) + items ^= UCPCAT_ALL; + category_list |= items; + unicode_status |= XCLASS_HAS_TYPE; + compares--; + } + cc += 2; } #endif /* SUPPORT_UNICODE */ } + +#ifdef SUPPORT_UNICODE +if (category_list == UCPCAT_ALL) + { + /* All characters are accepted, same as dotall. */ + compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); + if (list == backtracks) + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + return; + } + +if (compares == 0 && category_list == 0) + { + /* No characters are accepted, same as (*F) or dotall. */ + compile_char1_matchingpath(common, OP_ALLANY, cc, backtracks, FALSE); + if (list != backtracks) + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + return; + } +#else /* !SUPPORT_UNICODE */ SLJIT_ASSERT(compares > 0); +#endif /* SUPPORT_UNICODE */ /* We are not necessary in utf mode even in 8 bit mode. */ cc = ccbegin; @@ -7742,6 +7932,9 @@ if (unicode_status & XCLASS_NEEDS_UCD) ccbegin = cc; + if (category_list != 0) + compares++; + if (unicode_status & XCLASS_HAS_BIDICL) { OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, scriptx_bidiclass)); @@ -7946,7 +8139,16 @@ if (unicode_status & XCLASS_NEEDS_UCD) if (unicode_status & XCLASS_SAVE_CHAR) typereg = RETURN_ADDR; - OP1(SLJIT_MOV_U8, typereg, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); + OP2(SLJIT_SHL, typereg, 0, SLJIT_IMM, 1, TMP2, 0); + + if (category_list > 0) + { + compares--; + invertcmp = (compares == 0 && list != backtracks); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, category_list); + add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp)); + } } } #endif /* SUPPORT_UNICODE */ @@ -7954,9 +8156,6 @@ if (unicode_status & XCLASS_NEEDS_UCD) /* Generating code. */ charoffset = 0; numberofcmps = 0; -#ifdef SUPPORT_UNICODE -typeoffset = 0; -#endif /* SUPPORT_UNICODE */ while (*cc != XCL_END) { @@ -8024,36 +8223,17 @@ while (*cc != XCL_END) switch(*cc) { case PT_ANY: - if (!invertcmp) - jump = JUMP(SLJIT_JUMP); - break; - case PT_LAMP: - OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); - OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - case PT_GC: - c = PRIV(ucp_typerange)[(int)cc[1] * 2]; - SET_TYPE_OFFSET(c); - jump = CMP(SLJIT_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c); - break; - case PT_PC: - jump = CMP(SLJIT_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, (int)cc[1] - typeoffset); - break; - case PT_SC: case PT_SCX: case PT_BOOL: case PT_BIDICL: + case PT_WORD: + case PT_ALNUM: compares++; - /* Do nothing. */ + /* Already handled. */ break; case PT_SPACE: @@ -8068,24 +8248,8 @@ while (*cc != XCL_END) OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x9); OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); - SET_TYPE_OFFSET(ucp_Zl); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL); - jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); - break; - - case PT_WORD: - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL); - /* Fall through. */ - - case PT_ALNUM: - SET_TYPE_OFFSET(ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); - SET_TYPE_OFFSET(ucp_Nd); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Zl, ucp_Zs)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); break; @@ -8160,13 +8324,13 @@ while (*cc != XCL_END) break; case PT_PXGRAPH: - /* C and Z groups are the farthest two groups. */ - SET_TYPE_OFFSET(ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_GREATER, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT_RANGE(ucp_Zl, ucp_Zs)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); - jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); + jump = JUMP(SLJIT_ZERO); + c = charoffset; /* In case of ucp_Cf, we overwrite the result. */ SET_CHAR_OFFSET(0x2066); OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); @@ -8178,21 +8342,21 @@ while (*cc != XCL_END) OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066); OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + /* Restore charoffset. */ + SET_CHAR_OFFSET(c); + JUMPHERE(jump); jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); break; case PT_PXPRINT: - /* C and Z groups are the farthest two groups. */ - SET_TYPE_OFFSET(ucp_Ll); - OP2U(SLJIT_SUB | SLJIT_SET_GREATER, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Cc, ucp_Cs) | UCPCAT2(ucp_Zl, ucp_Zp)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); - OP2U(SLJIT_SUB | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll); - OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_NOT_EQUAL); - - jump = CMP(SLJIT_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT(ucp_Cf)); + jump = JUMP(SLJIT_ZERO); + c = charoffset; /* In case of ucp_Cf, we overwrite the result. */ SET_CHAR_OFFSET(0x2066); OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066); @@ -8201,22 +8365,54 @@ while (*cc != XCL_END) OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066); OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL); + /* Restore charoffset. */ + SET_CHAR_OFFSET(c); + JUMPHERE(jump); jump = CMP(SLJIT_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0); break; case PT_PXPUNCT: - SET_TYPE_OFFSET(ucp_Sc); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Sc, ucp_So)); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); SET_CHAR_OFFSET(0); OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x7f); OP_FLAGS(SLJIT_AND, TMP2, 0, SLJIT_LESS_EQUAL); - SET_TYPE_OFFSET(ucp_Pc); - OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc); - OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_LESS_EQUAL); + OP2U(SLJIT_AND | SLJIT_SET_Z, typereg, 0, SLJIT_IMM, UCPCAT_RANGE(ucp_Pc, ucp_Ps)); + OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_NOT_ZERO); + jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); + break; + + case PT_PXXDIGIT: + SET_CHAR_OFFSET(CHAR_A); + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, ~0x20); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP2, 0, SLJIT_IMM, CHAR_F - CHAR_A); + OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(CHAR_0); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_9 - CHAR_0); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff10); + jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff10); + + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff19 - 0xff10); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff21); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff26 - 0xff21); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff41); + OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff46 - 0xff41); + OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); + + SET_CHAR_OFFSET(0xff10); + + JUMPHERE(jump); + OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, 0); jump = JUMP(SLJIT_NOT_ZERO ^ invertcmp); break; @@ -8232,6 +8428,7 @@ while (*cc != XCL_END) add_jump(compiler, compares > 0 ? list : backtracks, jump); } +SLJIT_ASSERT(compares == 0); if (found != NULL) set_jumps(found, LABEL()); } @@ -8244,11 +8441,7 @@ if (found != NULL) static PCRE2_SPTR compile_simple_assertion_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks) { DEFINE_COMPILER; -int length; struct sljit_jump *jump[4]; -#ifdef SUPPORT_UNICODE -struct sljit_label *label; -#endif /* SUPPORT_UNICODE */ switch(type) { @@ -8276,16 +8469,18 @@ switch(type) case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: - add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + add_jump(compiler, (type == OP_NOT_WORD_BOUNDARY || type == OP_WORD_BOUNDARY) ? &common->wordboundary : &common->ucp_wordboundary, JUMP(SLJIT_FAST_CALL)); #ifdef SUPPORT_UNICODE if (common->invalid_utf) { - add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0)); return cc; } #endif /* SUPPORT_UNICODE */ sljit_set_current_flags(compiler, SLJIT_SET_Z); - add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + add_jump(compiler, backtracks, JUMP((type == OP_NOT_WORD_BOUNDARY || type == OP_NOT_UCP_WORD_BOUNDARY) ? SLJIT_NOT_ZERO : SLJIT_ZERO)); return cc; case OP_EODN: @@ -8481,36 +8676,6 @@ switch(type) } JUMPHERE(jump[0]); return cc; - - case OP_REVERSE: - length = GET(cc, 0); - if (length == 0) - return cc + LINK_SIZE; - if (HAS_VIRTUAL_REGISTERS) - { - OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - } - else - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); -#ifdef SUPPORT_UNICODE - if (common->utf) - { - OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, length); - label = LABEL(); - add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0)); - move_back(common, backtracks, FALSE); - OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); - JUMPTO(SLJIT_NOT_ZERO, label); - } - else -#endif - { - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0)); - } - check_start_used_ptr(common); - return cc + LINK_SIZE; } SLJIT_UNREACHABLE(); return cc; @@ -8667,7 +8832,7 @@ c = *cc++; #if PCRE2_CODE_UNIT_WIDTH == 32 if (c >= 0x110000) - return NULL; + return cc; #endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ lgb = UCD_GRAPHBREAK(c); @@ -8809,35 +8974,14 @@ switch(type) if (check_str_ptr) detect_partial_match(common, backtracks); #ifdef SUPPORT_UNICODE - if (common->utf) + if (common->utf && common->invalid_utf) { - if (common->invalid_utf) - { - read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR); - return cc; - } - -#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if PCRE2_CODE_UNIT_WIDTH == 8 - jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -#elif PCRE2_CODE_UNIT_WIDTH == 16 - jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); - OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xd800); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ - JUMPHERE(jump[0]); + read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR); return cc; -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ } #endif /* SUPPORT_UNICODE */ - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + + skip_valid_char(common); return cc; case OP_ANYBYTE: @@ -8928,7 +9072,7 @@ switch(type) #else sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, common->invalid_utf ? SLJIT_FUNC_ADDR(do_extuni_utf_invalid) : SLJIT_FUNC_ADDR(do_extuni_no_utf)); - if (!common->utf || common->invalid_utf) + if (common->invalid_utf) add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); #endif @@ -8990,7 +9134,7 @@ switch(type) if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) { OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, oc); - CMOV(SLJIT_EQUAL, TMP1, SLJIT_IMM, c); + SELECT(SLJIT_EQUAL, TMP1, SLJIT_IMM, c, TMP1); add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); } else @@ -9509,14 +9653,16 @@ if (!minimize) if (ref) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + if (ref) { - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); + if (!common->unset_backref) + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); } else { - compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); + compile_dnref_search(common, ccbegin, &backtrack->own_backtracks); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, TMP2, 0); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); @@ -9529,7 +9675,7 @@ if (!minimize) label = LABEL(); if (!ref) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1); - compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); + compile_ref_matchingpath(common, ccbegin, &backtrack->own_backtracks, FALSE, FALSE); if (min > 1 || max > 1) { @@ -9591,12 +9737,13 @@ else { if (ref) { - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); + if (!common->unset_backref) + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1))); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); } else { - compile_dnref_search(common, ccbegin, &backtrack->topbacktracks); + compile_dnref_search(common, ccbegin, &backtrack->own_backtracks); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0); zerolength = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); @@ -9605,11 +9752,11 @@ else BACKTRACK_AS(ref_iterator_backtrack)->matchingpath = LABEL(); if (max > 0) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); if (!ref) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); -compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); +compile_ref_matchingpath(common, ccbegin, &backtrack->own_backtracks, TRUE, TRUE); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); if (min > 1) @@ -9684,12 +9831,12 @@ if (entry->entry_label == NULL) else JUMPTO(SLJIT_FAST_CALL, entry->entry_label); /* Leave if the match is failed. */ -add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0)); +add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0)); BACKTRACK_AS(recurse_backtrack)->matchingpath = LABEL(); return cc + 1 + LINK_SIZE; } -static sljit_s32 SLJIT_FUNC do_callout_jit(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector) +static sljit_s32 SLJIT_FUNC SLJIT_FUNC_ATTRIBUTE do_callout_jit(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector) { PCRE2_SPTR begin; PCRE2_SIZE *ovector; @@ -9812,7 +9959,7 @@ free_stack(common, callout_arg_size); /* Check return value. */ OP2U(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); -add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER)); +add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_SIG_GREATER)); if (common->abort_label == NULL) add_jump(compiler, &common->abort, JUMP(SLJIT_NOT_EQUAL) /* SIG_LESS */); else @@ -9823,6 +9970,106 @@ return cc + callout_length; #undef CALLOUT_ARG_SIZE #undef CALLOUT_ARG_OFFSET +static PCRE2_SPTR compile_reverse_matchingpath(compiler_common *common, PCRE2_SPTR cc, backtrack_common *parent) +{ +DEFINE_COMPILER; +backtrack_common *backtrack = NULL; +jump_list **reverse_failed; +unsigned int lmin, lmax; +#ifdef SUPPORT_UNICODE +struct sljit_jump *jump; +struct sljit_label *label; +#endif + +SLJIT_ASSERT(parent->top == NULL); + +if (*cc == OP_REVERSE) + { + reverse_failed = &parent->own_backtracks; + lmin = GET2(cc, 1); + lmax = lmin; + cc += 1 + IMM2_SIZE; + + SLJIT_ASSERT(lmin > 0); + } +else + { + SLJIT_ASSERT(*cc == OP_VREVERSE); + PUSH_BACKTRACK(sizeof(vreverse_backtrack), cc, NULL); + + reverse_failed = &backtrack->own_backtracks; + lmin = GET2(cc, 1); + lmax = GET2(cc, 1 + IMM2_SIZE); + cc += 1 + 2 * IMM2_SIZE; + + SLJIT_ASSERT(lmin < lmax); + } + +if (HAS_VIRTUAL_REGISTERS) + { + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + } +else + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin)); + +#ifdef SUPPORT_UNICODE +if (common->utf) + { + if (lmin > 0) + { + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, lmin); + label = LABEL(); + add_jump(compiler, reverse_failed, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0)); + move_back(common, reverse_failed, FALSE); + OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + } + + if (lmin < lmax) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0); + + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, lmax - lmin); + label = LABEL(); + jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); + move_back(common, reverse_failed, FALSE); + OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); + JUMPTO(SLJIT_NOT_ZERO, label); + + JUMPHERE(jump); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0); + } + } +else +#endif + { + if (lmin > 0) + { + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(lmin)); + add_jump(compiler, reverse_failed, CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0)); + } + + if (lmin < lmax) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0); + + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(lmax - lmin)); + OP2U(SLJIT_SUB | SLJIT_SET_LESS, STR_PTR, 0, TMP2, 0); + SELECT(SLJIT_LESS, STR_PTR, TMP2, 0, STR_PTR); + + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0); + } + } + +check_start_used_ptr(common); + +if (lmin < lmax) + BACKTRACK_AS(vreverse_backtrack)->matchingpath = LABEL(); + +return cc; +} + static SLJIT_INLINE BOOL assert_needs_str_ptr_saving(PCRE2_SPTR cc) { while (TRUE) @@ -9841,6 +10088,8 @@ while (TRUE) case OP_DOLLM: case OP_CALLOUT: case OP_ALT: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: cc += PRIV(OP_lengths)[*cc]; break; @@ -9860,13 +10109,15 @@ int framesize; int extrasize; BOOL local_quit_available = FALSE; BOOL needs_control_head; +BOOL end_block_size = 0; +BOOL has_vreverse; int private_data_ptr; backtrack_common altbacktrack; PCRE2_SPTR ccbegin; PCRE2_UCHAR opcode; PCRE2_UCHAR bra = OP_BRA; jump_list *tmp = NULL; -jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; +jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.own_backtracks; jump_list **found; /* Saving previous accept variables. */ BOOL save_local_quit_available = common->local_quit_available; @@ -9889,6 +10140,7 @@ if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) bra = *cc; cc++; } + private_data_ptr = PRIVATE_DATA(cc); SLJIT_ASSERT(private_data_ptr != 0); framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head); @@ -9908,12 +10160,17 @@ if (bra == OP_BRAMINZERO) brajump = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); } +if ((opcode == OP_ASSERTBACK || opcode == OP_ASSERTBACK_NOT) && find_vreverse(ccbegin)) + end_block_size = 3; + if (framesize < 0) { extrasize = 1; if (bra == OP_BRA && !assert_needs_str_ptr_saving(ccbegin + 1 + LINK_SIZE)) extrasize = 0; + extrasize += end_block_size; + if (needs_control_head) extrasize++; @@ -9931,18 +10188,19 @@ if (framesize < 0) if (needs_control_head) { - SLJIT_ASSERT(extrasize == 2); + SLJIT_ASSERT(extrasize == end_block_size + 2); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1), TMP1, 0); } } else { - extrasize = needs_control_head ? 3 : 2; + extrasize = (needs_control_head ? 3 : 2) + end_block_size; + + OP1(SLJIT_MOV, TMP2, 0, STACK_TOP, 0); allocate_stack(common, framesize + extrasize); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - OP2(SLJIT_ADD, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP2, 0); if (needs_control_head) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr); @@ -9950,16 +10208,22 @@ else if (needs_control_head) { - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 2), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1), TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0); } else - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1), TMP1, 0); init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize); } +if (end_block_size > 0) + { + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_END, 0); + OP1(SLJIT_MOV, STR_END, 0, STR_PTR, 0); + } + memset(&altbacktrack, 0, sizeof(backtrack_common)); if (conditional || (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)) { @@ -9978,13 +10242,19 @@ while (1) common->accept_label = NULL; common->accept = NULL; altbacktrack.top = NULL; - altbacktrack.topbacktracks = NULL; + altbacktrack.own_backtracks = NULL; if (*ccbegin == OP_ALT && extrasize > 0) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); altbacktrack.cc = ccbegin; - compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); + ccbegin += 1 + LINK_SIZE; + + has_vreverse = (*ccbegin == OP_VREVERSE); + if (*ccbegin == OP_REVERSE || has_vreverse) + ccbegin = compile_reverse_matchingpath(common, ccbegin, &altbacktrack); + + compile_matchingpath(common, ccbegin, cc, &altbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { if (local_quit_available) @@ -10000,6 +10270,13 @@ while (1) common->accept = save_accept; return NULL; } + + if (has_vreverse) + { + SLJIT_ASSERT(altbacktrack.top != NULL); + add_jump(compiler, &altbacktrack.top->simple_backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + } + common->accept_label = LABEL(); if (common->accept != NULL) set_jumps(common->accept, common->accept_label); @@ -10012,6 +10289,9 @@ while (1) else if (extrasize > 0) free_stack(common, extrasize); + if (end_block_size > 0) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize + 1)); + if (needs_control_head) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1)); } @@ -10021,12 +10301,20 @@ while (1) { /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); + + if (end_block_size > 0) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(-extrasize + 2)); + if (needs_control_head) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-1)); } else { OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + + if (end_block_size > 0) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(-framesize - extrasize + 1)); + if (needs_control_head) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(-framesize - 2)); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); @@ -10040,7 +10328,7 @@ while (1) if (conditional) { if (extrasize > 0) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? STACK(-2) : STACK(-1)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-end_block_size - (needs_control_head ? 2 : 1))); } else if (bra == OP_BRAZERO) { @@ -10079,7 +10367,7 @@ while (1) common->accept = save_accept; return NULL; } - set_jumps(altbacktrack.topbacktracks, LABEL()); + set_jumps(altbacktrack.own_backtracks, LABEL()); if (*cc != OP_ALT) break; @@ -10112,8 +10400,11 @@ if (common->positive_assertion_quit != NULL) JUMPHERE(jump); } +if (end_block_size > 0) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + if (needs_control_head) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(end_block_size + 1)); if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) { @@ -10126,8 +10417,8 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) /* The topmost item should be 0. */ if (bra == OP_BRAZERO) { - if (extrasize == 2) - free_stack(common, 1); + if (extrasize >= 2) + free_stack(common, extrasize - 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } else if (extrasize > 0) @@ -10161,8 +10452,9 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) /* Keep the STR_PTR on the top of the stack. */ if (bra == OP_BRAZERO) { + /* This allocation is always successful. */ OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); - if (extrasize == 2) + if (extrasize >= 2) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); } else if (bra == OP_BRAMINZERO) @@ -10182,8 +10474,9 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) else { /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ - OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw)); - if (extrasize == 2) + OP2(SLJIT_SUB, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_IMM, (framesize + end_block_size + 2) * sizeof(sljit_sw)); + + if (extrasize == 2 + end_block_size) { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); if (bra == OP_BRAMINZERO) @@ -10191,7 +10484,7 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) } else { - SLJIT_ASSERT(extrasize == 3); + SLJIT_ASSERT(extrasize == 3 + end_block_size); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(-1)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); } @@ -10215,7 +10508,7 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize - 1) * sizeof(sljit_sw)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); } - set_jumps(backtrack->common.topbacktracks, LABEL()); + set_jumps(backtrack->common.own_backtracks, LABEL()); } } else @@ -10228,8 +10521,8 @@ else if (bra != OP_BRA) { - if (extrasize == 2) - free_stack(common, 1); + if (extrasize >= 2) + free_stack(common, extrasize - 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } else if (extrasize > 0) @@ -10260,9 +10553,9 @@ else if (bra != OP_BRA) { - SLJIT_ASSERT(found == &backtrack->common.topbacktracks); - set_jumps(backtrack->common.topbacktracks, LABEL()); - backtrack->common.topbacktracks = NULL; + SLJIT_ASSERT(found == &backtrack->common.own_backtracks); + set_jumps(backtrack->common.own_backtracks, LABEL()); + backtrack->common.own_backtracks = NULL; } } @@ -10371,7 +10664,7 @@ static PCRE2_SPTR SLJIT_FUNC do_script_run_utf(PCRE2_SPTR ptr, PCRE2_SPTR endptr #endif /* SUPPORT_UNICODE */ -static SLJIT_INLINE void match_script_run_common(compiler_common *common, int private_data_ptr, backtrack_common *parent) +static void match_script_run_common(compiler_common *common, int private_data_ptr, backtrack_common *parent) { DEFINE_COMPILER; @@ -10386,7 +10679,7 @@ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS2(W, W, W), SLJIT_IMM, SLJIT_FU #endif OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); -add_jump(compiler, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); +add_jump(compiler, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); } /* @@ -10460,6 +10753,7 @@ PCRE2_UCHAR ket; assert_backtrack *assert; BOOL has_alternatives; BOOL needs_control_head = FALSE; +BOOL has_vreverse = FALSE; struct sljit_jump *jump; struct sljit_jump *skip; struct sljit_label *rmax_label = NULL; @@ -10709,6 +11003,21 @@ else if (opcode == OP_CBRA || opcode == OP_SCBRA) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); } } +else if (opcode == OP_ASSERTBACK_NA && PRIVATE_DATA(ccbegin + 1)) + { + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + allocate_stack(common, 4); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), STR_END, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); + OP1(SLJIT_MOV, STR_END, 0, STR_PTR, 0); + + has_vreverse = (*matchingpath == OP_VREVERSE); + if (*matchingpath == OP_REVERSE || has_vreverse) + matchingpath = compile_reverse_matchingpath(common, matchingpath, backtrack); + } else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) { /* Saving the previous value. */ @@ -10716,6 +11025,9 @@ else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SC allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); + + if (*matchingpath == OP_REVERSE) + matchingpath = compile_reverse_matchingpath(common, matchingpath, backtrack); } else if (has_alternatives) { @@ -10835,14 +11147,28 @@ compile_matchingpath(common, matchingpath, cc, backtrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; -if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); +switch (opcode) + { + case OP_ASSERTBACK_NA: + if (has_vreverse) + { + SLJIT_ASSERT(backtrack->top != NULL && PRIVATE_DATA(ccbegin + 1)); + add_jump(compiler, &backtrack->top->simple_backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + } -if (opcode == OP_ONCE) - match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); - -if (opcode == OP_SCRIPT_RUN) - match_script_run_common(common, private_data_ptr, backtrack); + if (PRIVATE_DATA(ccbegin + 1)) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + break; + case OP_ASSERT_NA: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + break; + case OP_ONCE: + match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); + break; + case OP_SCRIPT_RUN: + match_script_run_common(common, private_data_ptr, backtrack); + break; + } stacksize = 0; if (repeat_type == OP_MINUPTO) @@ -11041,7 +11367,7 @@ switch(opcode) case OP_CBRAPOS: case OP_SCBRAPOS: offset = GET2(cc, 1 + LINK_SIZE); - /* This case cannot be optimized in the same was as + /* This case cannot be optimized in the same way as normal capturing brackets. */ SLJIT_ASSERT(common->optimized_cbracket[offset] == 0); cbraprivptr = OVECTOR_PRIV(offset); @@ -11158,7 +11484,7 @@ loop = LABEL(); while (*cc != OP_KETRPOS) { backtrack->top = NULL; - backtrack->topbacktracks = NULL; + backtrack->own_backtracks = NULL; cc += GET(cc, 1); compile_matchingpath(common, ccbegin, cc, backtrack); @@ -11239,7 +11565,7 @@ while (*cc != OP_KETRPOS) compile_backtrackingpath(common, backtrack->top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; - set_jumps(backtrack->topbacktracks, LABEL()); + set_jumps(backtrack->own_backtracks, LABEL()); if (framesize < 0) { @@ -11271,13 +11597,13 @@ while (*cc != OP_KETRPOS) /* We don't have to restore the control head in case of a failed match. */ -backtrack->topbacktracks = NULL; +backtrack->own_backtracks = NULL; if (!zero) { if (framesize < 0) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); else /* TMP2 is set to [private_data_ptr] above. */ - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), STACK(-stacksize), SLJIT_IMM, 0)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_NOT_EQUAL, SLJIT_MEM1(TMP2), STACK(-stacksize), SLJIT_IMM, 0)); } /* None of them matched. */ @@ -11473,7 +11799,7 @@ SLJIT_ASSERT(common->fast_forward_bc_ptr != NULL || early_fail_ptr == 0 || (early_fail_ptr >= common->early_fail_start_ptr && early_fail_ptr <= common->early_fail_end_ptr)); if (early_fail_type == type_fail) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr)); cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &exact, &end); @@ -11500,10 +11826,10 @@ if (exact > 1) && type != OP_ANYNL && type != OP_EXTUNI) { OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact)); - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0)); OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, FALSE); OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); JUMPTO(SLJIT_NOT_ZERO, label); } @@ -11511,13 +11837,13 @@ if (exact > 1) { OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, exact); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); JUMPTO(SLJIT_NOT_ZERO, label); } } else if (exact == 1) - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, TRUE); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, TRUE); if (early_fail_type == type_fail_range) { @@ -11526,7 +11852,7 @@ if (early_fail_type == type_fail_range) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, TMP2, 0); OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, TMP2, 0); - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0)); + add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_LESS_EQUAL, TMP2, 0, TMP1, 0)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr + SSIZE_OF(sw), STR_PTR, 0); @@ -11606,7 +11932,7 @@ switch(opcode) if (common->mode == PCRE2_JIT_COMPLETE) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); - CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); } else { @@ -11674,14 +12000,14 @@ switch(opcode) if (opcode == OP_UPTO) { OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO)); + add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_ZERO)); } - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE); + compile_char1_matchingpath(common, type, cc, &backtrack->own_backtracks, FALSE); if (early_fail_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), early_fail_ptr, STR_PTR, 0); JUMPHERE(jump); - detect_partial_match(common, &backtrack->topbacktracks); + detect_partial_match(common, &backtrack->own_backtracks); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); if (charpos_othercasebit != 0) OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit); @@ -11835,7 +12161,7 @@ switch(opcode) } #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 - if (common->utf) + if (type == OP_EXTUNI || common->utf) { OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); detect_partial_match(common, &no_match); @@ -11899,7 +12225,7 @@ switch(opcode) if (common->mode == PCRE2_JIT_COMPLETE) { OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); - CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); } else { @@ -11952,12 +12278,12 @@ PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL); if (*cc == OP_FAIL) { - add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); + add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_JUMP)); return cc + 1; } if (*cc == OP_ACCEPT && common->currententry == NULL && (common->re->overall_options & PCRE2_ENDANCHORED) != 0) - add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); + add_jump(compiler, &common->restart_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL || !common->might_be_empty) { @@ -11983,7 +12309,7 @@ else OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options)); OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY); -add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO)); +add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_NOT_ZERO)); OP2U(SLJIT_AND | SLJIT_SET_Z, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART); if (common->accept_label == NULL) add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO)); @@ -11995,7 +12321,7 @@ if (common->accept_label == NULL) add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0)); else CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label); -add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); +add_jump(compiler, &backtrack->own_backtracks, JUMP(SLJIT_JUMP)); return cc + 1; } @@ -12115,8 +12441,9 @@ while (cc < ccend) case OP_DOLLM: case OP_CIRC: case OP_CIRCM: - case OP_REVERSE: - cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + cc = compile_simple_assertion_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); break; case OP_NOT_DIGIT: @@ -12138,7 +12465,7 @@ while (cc < ccend) case OP_EXTUNI: case OP_NOT: case OP_NOTI: - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; case OP_SET_SOM: @@ -12153,9 +12480,9 @@ while (cc < ccend) case OP_CHAR: case OP_CHARI: if (common->mode == PCRE2_JIT_COMPLETE) - cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; case OP_STAR: @@ -12231,7 +12558,7 @@ while (cc < ccend) if (cc[1 + (32 / sizeof(PCRE2_UCHAR))] >= OP_CRSTAR && cc[1 + (32 / sizeof(PCRE2_UCHAR))] <= OP_CRPOSRANGE) cc = compile_iterator_matchingpath(common, cc, parent); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; #if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 @@ -12239,7 +12566,7 @@ while (cc < ccend) if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE) cc = compile_iterator_matchingpath(common, cc, parent); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE); + cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE); break; #endif @@ -12249,7 +12576,7 @@ while (cc < ccend) cc = compile_ref_iterator_matchingpath(common, cc, parent); else { - compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE, FALSE); cc += 1 + IMM2_SIZE; } break; @@ -12260,8 +12587,8 @@ while (cc < ccend) cc = compile_ref_iterator_matchingpath(common, cc, parent); else { - compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); - compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks); + compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->simple_backtracks : &parent->own_backtracks, TRUE, FALSE); cc += 1 + 2 * IMM2_SIZE; } break; @@ -12539,7 +12866,7 @@ switch(opcode) break; } -set_jumps(current->topbacktracks, LABEL()); +set_jumps(current->own_backtracks, LABEL()); } static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) @@ -12554,7 +12881,7 @@ type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE]; if ((type & 0x1) == 0) { /* Maximize case. */ - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath); @@ -12563,7 +12890,7 @@ if ((type & 0x1) == 0) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(ref_iterator_backtrack)->matchingpath); -set_jumps(current->topbacktracks, LABEL()); +set_jumps(current->own_backtracks, LABEL()); free_stack(common, ref ? 2 : 3); } @@ -12584,7 +12911,7 @@ if (!CURRENT_AS(recurse_backtrack)->inlined_pattern) else compile_backtrackingpath(common, current->top); -set_jumps(current->topbacktracks, LABEL()); +set_jumps(current->own_backtracks, LABEL()); } static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current) @@ -12603,13 +12930,13 @@ if (*cc == OP_BRAZERO) if (bra == OP_BRAZERO) { - SLJIT_ASSERT(current->topbacktracks == NULL); + SLJIT_ASSERT(current->own_backtracks == NULL); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); } if (CURRENT_AS(assert_backtrack)->framesize < 0) { - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); if (bra == OP_BRAZERO) { @@ -12641,10 +12968,10 @@ if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(assert_backtrack)->framesize - 1) * sizeof(sljit_sw)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(assert_backtrack)->private_data_ptr, TMP1, 0); - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); } else - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); if (bra == OP_BRAZERO) { @@ -12671,6 +12998,7 @@ PCRE2_UCHAR ket; assert_backtrack *assert; BOOL has_alternatives; BOOL needs_control_head = FALSE; +BOOL has_vreverse; struct sljit_jump *brazero = NULL; struct sljit_jump *next_alt = NULL; struct sljit_jump *once = NULL; @@ -12847,8 +13175,8 @@ else if (has_alternatives) } COMPILE_BACKTRACKINGPATH(current->top); -if (current->topbacktracks) - set_jumps(current->topbacktracks, LABEL()); +if (current->own_backtracks) + set_jumps(current->own_backtracks, LABEL()); if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) { @@ -12884,14 +13212,25 @@ if (has_alternatives) do { current->top = NULL; - current->topbacktracks = NULL; - current->nextbacktracks = NULL; + current->own_backtracks = NULL; + current->simple_backtracks = NULL; /* Conditional blocks always have an additional alternative, even if it is empty. */ if (*cc == OP_ALT) { ccprev = cc + 1 + LINK_SIZE; cc += GET(cc, 1); - if (opcode != OP_COND && opcode != OP_SCOND) + + has_vreverse = FALSE; + if (opcode == OP_ASSERTBACK || opcode == OP_ASSERTBACK_NA) + { + SLJIT_ASSERT(private_data_ptr != 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + + has_vreverse = (*ccprev == OP_VREVERSE); + if (*ccprev == OP_REVERSE || has_vreverse) + ccprev = compile_reverse_matchingpath(common, ccprev, current); + } + else if (opcode != OP_COND && opcode != OP_SCOND) { if (opcode != OP_ONCE) { @@ -12903,15 +13242,30 @@ if (has_alternatives) else OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0)); } + compile_matchingpath(common, ccprev, cc, current); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return; - if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + switch (opcode) + { + case OP_ASSERTBACK_NA: + if (has_vreverse) + { + SLJIT_ASSERT(current->top != NULL && PRIVATE_DATA(ccbegin + 1)); + add_jump(compiler, ¤t->top->simple_backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0)); + } - if (opcode == OP_SCRIPT_RUN) - match_script_run_common(common, private_data_ptr, current); + if (PRIVATE_DATA(ccbegin + 1)) + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + break; + case OP_ASSERT_NA: + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + break; + case OP_SCRIPT_RUN: + match_script_run_common(common, private_data_ptr, current); + break; + } } /* Instructions after the current alternative is successfully matched. */ @@ -12998,9 +13352,9 @@ if (has_alternatives) } COMPILE_BACKTRACKINGPATH(current->top); - if (current->topbacktracks) - set_jumps(current->topbacktracks, LABEL()); - SLJIT_ASSERT(!current->nextbacktracks); + if (current->own_backtracks) + set_jumps(current->own_backtracks, LABEL()); + SLJIT_ASSERT(!current->simple_backtracks); } while (*cc == OP_ALT); @@ -13042,6 +13396,15 @@ if (offset != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); } } +else if (opcode == OP_ASSERTBACK_NA && PRIVATE_DATA(ccbegin + 1)) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr + sizeof(sljit_sw), TMP2, 0); + free_stack(common, 4); + } else if (opcode == OP_ASSERT_NA || opcode == OP_ASSERTBACK_NA || opcode == OP_SCRIPT_RUN || opcode == OP_SBRA || opcode == OP_SCOND) { OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0)); @@ -13128,12 +13491,19 @@ static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *co DEFINE_COMPILER; int offset; struct sljit_jump *jump; +PCRE2_SPTR cc; +/* No retry on backtrack, just drop everything. */ if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) { - if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS) + cc = current->cc; + + if (*cc == OP_BRAPOSZERO) + cc++; + + if (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS) { - offset = (GET2(current->cc, 1 + LINK_SIZE)) << 1; + offset = (GET2(cc, 1 + LINK_SIZE)) << 1; OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP1, 0); @@ -13143,7 +13513,7 @@ if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) if (common->capture_last_ptr != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0); } - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); return; } @@ -13152,10 +13522,10 @@ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), CURRENT_AS(bracketpos_backtra add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (CURRENT_AS(bracketpos_backtrack)->framesize - 1) * sizeof(sljit_sw)); -if (current->topbacktracks) +if (current->own_backtracks) { jump = JUMP(SLJIT_JUMP); - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); /* Drop the stack frame. */ free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); JUMPHERE(jump); @@ -13168,8 +13538,8 @@ static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *co assert_backtrack backtrack; current->top = NULL; -current->topbacktracks = NULL; -current->nextbacktracks = NULL; +current->own_backtracks = NULL; +current->simple_backtracks = NULL; if (current->cc[1] > OP_ASSERTBACK_NOT) { /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */ @@ -13184,7 +13554,7 @@ else /* Manual call of compile_assert_matchingpath. */ compile_assert_matchingpath(common, current->cc, &backtrack, FALSE); } -SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); +SLJIT_ASSERT(!current->simple_backtracks && !current->own_backtracks); } static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current) @@ -13249,6 +13619,23 @@ else add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP)); } +static SLJIT_INLINE void compile_vreverse_backtrackingpath(compiler_common *common, struct backtrack_common *current) +{ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_label *label; + +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); +jump = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(3)); +skip_valid_char(common); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0); +JUMPTO(SLJIT_JUMP, CURRENT_AS(vreverse_backtrack)->matchingpath); + +label = LABEL(); +sljit_set_label(jump, label); +set_jumps(current->own_backtracks, label); +} + static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; @@ -13289,8 +13676,8 @@ then_trap_backtrack *save_then_trap = common->then_trap; while (current) { - if (current->nextbacktracks != NULL) - set_jumps(current->nextbacktracks, LABEL()); + if (current->simple_backtracks != NULL) + set_jumps(current->simple_backtracks, LABEL()); switch(*current->cc) { case OP_SET_SOM: @@ -13456,7 +13843,11 @@ while (current) case OP_FAIL: case OP_ACCEPT: case OP_ASSERT_ACCEPT: - set_jumps(current->topbacktracks, LABEL()); + set_jumps(current->own_backtracks, LABEL()); + break; + + case OP_VREVERSE: + compile_vreverse_backtrackingpath(common, current); break; case OP_THEN_TRAP: @@ -13502,7 +13893,7 @@ SLJIT_ASSERT(common->currententry->entry_label == NULL && common->recursive_head common->currententry->entry_label = LABEL(); set_jumps(common->currententry->entry_calls, common->currententry->entry_label); -sljit_emit_fast_enter(compiler, TMP2, 0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, TMP2, 0); count_match(common); local_size = (alt_max > 1) ? 2 : 1; @@ -13535,7 +13926,7 @@ cc += GET(cc, 1); while (1) { altbacktrack.top = NULL; - altbacktrack.topbacktracks = NULL; + altbacktrack.own_backtracks = NULL; if (altbacktrack.cc != ccbegin) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); @@ -13564,7 +13955,7 @@ while (1) common->currententry->backtrack_label = LABEL(); set_jumps(common->currententry->backtrack_calls, common->currententry->backtrack_label); - sljit_emit_fast_enter(compiler, TMP1, 0); + sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, TMP1, 0); if (recurse_flags & recurse_flag_accept_found) accept_exit = CMP(SLJIT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, -1); @@ -13612,7 +14003,7 @@ while (1) compile_backtrackingpath(common, altbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return; - set_jumps(altbacktrack.topbacktracks, LABEL()); + set_jumps(altbacktrack.own_backtracks, LABEL()); if (*cc != OP_ALT) break; @@ -13718,9 +14109,9 @@ jump_list *reqcu_not_found = NULL; SLJIT_ASSERT(tables); #if HAS_VIRTUAL_REGISTERS == 1 -SLJIT_ASSERT(sljit_get_register_index(TMP3) < 0 && sljit_get_register_index(ARGUMENTS) < 0 && sljit_get_register_index(RETURN_ADDR) < 0); +SLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, TMP3) < 0 && sljit_get_register_index(SLJIT_GP_REGISTER, ARGUMENTS) < 0 && sljit_get_register_index(SLJIT_GP_REGISTER, RETURN_ADDR) < 0); #elif HAS_VIRTUAL_REGISTERS == 0 -SLJIT_ASSERT(sljit_get_register_index(TMP3) >= 0 && sljit_get_register_index(ARGUMENTS) >= 0 && sljit_get_register_index(RETURN_ADDR) >= 0); +SLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, TMP3) >= 0 && sljit_get_register_index(SLJIT_GP_REGISTER, ARGUMENTS) >= 0 && sljit_get_register_index(SLJIT_GP_REGISTER, RETURN_ADDR) >= 0); #else #error "Invalid value for HAS_VIRTUAL_REGISTERS" #endif @@ -13892,13 +14283,13 @@ memset(common->private_data_ptrs, 0, total_length * sizeof(sljit_s32)); private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw); if ((re->overall_options & PCRE2_ANCHORED) == 0 && (re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0 && !common->has_skip_in_assert_back) - detect_early_fail(common, common->start, &private_data_size, 0, 0, TRUE); + detect_early_fail(common, common->start, &private_data_size, 0, 0); set_private_data_ptrs(common, &private_data_size, ccend); SLJIT_ASSERT(common->early_fail_start_ptr <= common->early_fail_end_ptr); -if (private_data_size > SLJIT_MAX_LOCAL_SIZE) +if (private_data_size > 65536) { SLJIT_FREE(common->private_data_ptrs, allocator_data); SLJIT_FREE(common->optimized_cbracket, allocator_data); @@ -13923,7 +14314,7 @@ common->compiler = compiler; /* Main pcre2_jit_exec entry. */ SLJIT_ASSERT((private_data_size & (sizeof(sljit_sw) - 1)) == 0); -sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, W), 5, 5, 0, 0, private_data_size); +sljit_emit_enter(compiler, 0, SLJIT_ARGS1(W, W), 5, 5, SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS, 0, private_data_size); /* Register init. */ reset_ovector(common, (re->top_bracket + 1) * 2); @@ -14187,7 +14578,7 @@ common->quit_label = quit_label; /* This is a (really) rare case. */ set_jumps(common->stackalloc, LABEL()); /* RETURN_ADDR is not a saved register. */ -sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, SLJIT_MEM1(SLJIT_SP), LOCALS0); SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); @@ -14225,7 +14616,12 @@ if (common->revertframes != NULL) if (common->wordboundary != NULL) { set_jumps(common->wordboundary, LABEL()); - check_wordboundary(common); + check_wordboundary(common, FALSE); + } +if (common->ucp_wordboundary != NULL) + { + set_jumps(common->ucp_wordboundary, LABEL()); + check_wordboundary(common, TRUE); } if (common->anynewline != NULL) { @@ -14252,10 +14648,17 @@ if (common->caselesscmp != NULL) set_jumps(common->caselesscmp, LABEL()); do_caselesscmp(common); } -if (common->reset_match != NULL) +if (common->reset_match != NULL || common->restart_match != NULL) { + if (common->restart_match != NULL) + { + set_jumps(common->restart_match, LABEL()); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr); + } + set_jumps(common->reset_match, LABEL()); do_reset_match(common, (re->top_bracket + 1) * 2); + /* The value of restart_match is in TMP1. */ CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label); OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0); JUMPTO(SLJIT_JUMP, reset_match_label); diff --git a/src/3rdparty/pcre2/src/pcre2_jit_match.c b/src/3rdparty/pcre2/src/pcre2_jit_match.c index 1ab3af073e6..ae5903e202b 100644 --- a/src/3rdparty/pcre2/src/pcre2_jit_match.c +++ b/src/3rdparty/pcre2/src/pcre2_jit_match.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2018 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -42,6 +42,12 @@ POSSIBILITY OF SUCH DAMAGE. #error This file must be included from pcre2_jit_compile.c. #endif +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#include +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ + #ifdef SUPPORT_JIT static SLJIT_NOINLINE int jit_machine_stack_exec(jit_arguments *arguments, jit_function executable_func) @@ -171,6 +177,7 @@ if (rc > (int)oveccount) rc = 0; match_data->code = re; match_data->subject = (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)? subject : NULL; +match_data->subject_length = length; match_data->rc = rc; match_data->startchar = arguments.startchar_ptr - subject; match_data->leftchar = 0; @@ -178,6 +185,13 @@ match_data->rightchar = 0; match_data->mark = arguments.mark_ptr; match_data->matchedby = PCRE2_MATCHEDBY_JIT; +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +if (rc > 0) + __msan_unpoison(match_data->ovector, 2 * rc * sizeof(match_data->ovector[0])); +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ + return match_data->rc; #endif /* SUPPORT_JIT */ diff --git a/src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h b/src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h index 165602edc0c..4a718b67b7e 100644 --- a/src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h +++ b/src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h @@ -82,7 +82,12 @@ POSSIBILITY OF SUCH DAMAGE. # endif # endif -static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 *str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars) +#if (defined(__GNUC__) && __SANITIZE_ADDRESS__) \ + || (defined(__clang__) \ + && ((__clang_major__ == 3 && __clang_minor__ >= 3) || (__clang_major__ > 3))) +__attribute__((no_sanitize_address)) +#endif +static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 **str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars) #undef FF_FUN { quad_word qw; @@ -171,7 +176,7 @@ else } # endif -str_ptr += IN_UCHARS(offs1); +*str_ptr += IN_UCHARS(offs1); #endif #if PCRE2_CODE_UNIT_WIDTH != 8 @@ -183,13 +188,13 @@ restart:; #endif #if defined(FFCPS) -if (str_ptr >= str_end) +if (*str_ptr >= str_end) return NULL; -sljit_u8 *p1 = str_ptr - diff; +sljit_u8 *p1 = *str_ptr - diff; #endif -sljit_s32 align_offset = ((uint64_t)str_ptr & 0xf); -str_ptr = (sljit_u8 *) ((uint64_t)str_ptr & ~0xf); -vect_t data = VLD1Q(str_ptr); +sljit_s32 align_offset = ((uint64_t)*str_ptr & 0xf); +*str_ptr = (sljit_u8 *) ((uint64_t)*str_ptr & ~0xf); +vect_t data = VLD1Q(*str_ptr); #if PCRE2_CODE_UNIT_WIDTH != 8 data = VANDQ(data, char_mask); #endif @@ -212,9 +217,9 @@ vect_t prev_data = data; # endif vect_t data2; -if (p1 < str_ptr) +if (p1 < *str_ptr) { - data2 = VLD1Q(str_ptr - diff); + data2 = VLD1Q(*str_ptr - diff); #if PCRE2_CODE_UNIT_WIDTH != 8 data2 = VANDQ(data2, char_mask); #endif @@ -242,12 +247,12 @@ if (align_offset < 8) qw.dw[0] >>= align_offset * 8; if (qw.dw[0]) { - str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8; + *str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8; goto match; } if (qw.dw[1]) { - str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; + *str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; goto match; } } @@ -256,15 +261,15 @@ else qw.dw[1] >>= (align_offset - 8) * 8; if (qw.dw[1]) { - str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8; + *str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8; goto match; } } -str_ptr += 16; +*str_ptr += 16; -while (str_ptr < str_end) +while (*str_ptr < str_end) { - vect_t orig_data = VLD1Q(str_ptr); + vect_t orig_data = VLD1Q(*str_ptr); #if PCRE2_CODE_UNIT_WIDTH != 8 orig_data = VANDQ(orig_data, char_mask); #endif @@ -287,7 +292,7 @@ while (str_ptr < str_end) # if defined (FFCPS_DIFF1) data2 = VEXTQ(prev_data, data, VECTOR_FACTOR - 1); # else - data2 = VLD1Q(str_ptr - diff); + data2 = VLD1Q(*str_ptr - diff); # if PCRE2_CODE_UNIT_WIDTH != 8 data2 = VANDQ(data2, char_mask); # endif @@ -312,11 +317,11 @@ while (str_ptr < str_end) VST1Q(qw.mem, eq); if (qw.dw[0]) - str_ptr += __builtin_ctzll(qw.dw[0]) / 8; + *str_ptr += __builtin_ctzll(qw.dw[0]) / 8; else if (qw.dw[1]) - str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; + *str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8; else { - str_ptr += 16; + *str_ptr += 16; #if defined (FFCPS_DIFF1) prev_data = orig_data; #endif @@ -324,24 +329,24 @@ while (str_ptr < str_end) } match:; - if (str_ptr >= str_end) + if (*str_ptr >= str_end) /* Failed match. */ return NULL; #if defined(FF_UTF) - if (utf_continue((PCRE2_SPTR)str_ptr - offs1)) + if (utf_continue((PCRE2_SPTR)*str_ptr - offs1)) { /* Not a match. */ - str_ptr += IN_UCHARS(1); + *str_ptr += IN_UCHARS(1); goto restart; } #endif /* Match. */ #if defined (FFCPS) - str_ptr -= IN_UCHARS(offs1); + *str_ptr -= IN_UCHARS(offs1); #endif - return str_ptr; + return *str_ptr; } /* Failed match. */ diff --git a/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h b/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h index 1a5ce4ed09f..783a85f50e2 100644 --- a/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h +++ b/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h @@ -42,7 +42,8 @@ POSSIBILITY OF SUCH DAMAGE. #if !(defined SUPPORT_VALGRIND) #if ((defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ - || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)) + || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + || (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64)) typedef enum { vector_compare_match1, @@ -50,7 +51,27 @@ typedef enum { vector_compare_match2, } vector_compare_type; -static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void) +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) +static SLJIT_INLINE sljit_s32 max_fast_forward_char_pair_offset(void) +{ +#if PCRE2_CODE_UNIT_WIDTH == 8 +/* The AVX2 code path is currently disabled. */ +/* return sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? 31 : 15; */ +return 15; +#elif PCRE2_CODE_UNIT_WIDTH == 16 +/* The AVX2 code path is currently disabled. */ +/* return sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? 15 : 7; */ +return 7; +#elif PCRE2_CODE_UNIT_WIDTH == 32 +/* The AVX2 code path is currently disabled. */ +/* return sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? 7 : 3; */ +return 3; +#else +#error "Unsupported unit width" +#endif +} +#else /* !SLJIT_CONFIG_X86 */ +static SLJIT_INLINE sljit_s32 max_fast_forward_char_pair_offset(void) { #if PCRE2_CODE_UNIT_WIDTH == 8 return 15; @@ -62,6 +83,7 @@ return 3; #error "Unsupported unit width" #endif } +#endif /* SLJIT_CONFIG_X86 */ #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 static struct sljit_jump *jump_if_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg) @@ -86,49 +108,35 @@ static sljit_s32 character_to_int32(PCRE2_UCHAR chr) { sljit_u32 value = chr; #if PCRE2_CODE_UNIT_WIDTH == 8 -#define SSE2_COMPARE_TYPE_INDEX 0 +#define SIMD_COMPARE_TYPE_INDEX 0 return (sljit_s32)((value << 24) | (value << 16) | (value << 8) | value); #elif PCRE2_CODE_UNIT_WIDTH == 16 -#define SSE2_COMPARE_TYPE_INDEX 1 +#define SIMD_COMPARE_TYPE_INDEX 1 return (sljit_s32)((value << 16) | value); #elif PCRE2_CODE_UNIT_WIDTH == 32 -#define SSE2_COMPARE_TYPE_INDEX 2 +#define SIMD_COMPARE_TYPE_INDEX 2 return (sljit_s32)(value); #else #error "Unsupported unit width" #endif } -static void load_from_mem_sse2(struct sljit_compiler *compiler, sljit_s32 dst_xmm_reg, sljit_s32 src_general_reg, sljit_s8 offset) -{ -sljit_u8 instruction[5]; - -SLJIT_ASSERT(dst_xmm_reg < 8); -SLJIT_ASSERT(src_general_reg < 8); - -/* MOVDQA xmm1, xmm2/m128 */ -instruction[0] = ((sljit_u8)offset & 0xf) == 0 ? 0x66 : 0xf3; -instruction[1] = 0x0f; -instruction[2] = 0x6f; - -if (offset == 0) - { - instruction[3] = (dst_xmm_reg << 3) | src_general_reg; - sljit_emit_op_custom(compiler, instruction, 4); - return; - } - -instruction[3] = 0x40 | (dst_xmm_reg << 3) | src_general_reg; -instruction[4] = (sljit_u8)offset; -sljit_emit_op_custom(compiler, instruction, 5); -} - static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, vector_compare_type compare_type, - int step, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind) + sljit_s32 reg_type, int step, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind) { sljit_u8 instruction[4]; -instruction[0] = 0x66; -instruction[1] = 0x0f; + +if (reg_type == SLJIT_SIMD_REG_128) + { + instruction[0] = 0x66; + instruction[1] = 0x0f; + } +else + { + /* Two byte VEX prefix. */ + instruction[0] = 0xc5; + instruction[1] = 0xfd; + } SLJIT_ASSERT(step >= 0 && step <= 3); @@ -139,8 +147,10 @@ if (compare_type != vector_compare_match2) if (compare_type == vector_compare_match1i) { /* POR xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ + if (reg_type == SLJIT_SIMD_REG_256) + instruction[1] ^= (dst_ind << 3); + + /* Prefix is filled. */ instruction[2] = 0xeb; instruction[3] = 0xc0 | (dst_ind << 3) | cmp2_ind; sljit_emit_op_custom(compiler, instruction, 4); @@ -152,20 +162,35 @@ if (compare_type != vector_compare_match2) return; /* PCMPEQB/W/D xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ - instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; + if (reg_type == SLJIT_SIMD_REG_256) + instruction[1] ^= (dst_ind << 3); + + /* Prefix is filled. */ + instruction[2] = 0x74 + SIMD_COMPARE_TYPE_INDEX; instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind; sljit_emit_op_custom(compiler, instruction, 4); return; } +if (reg_type == SLJIT_SIMD_REG_256) + { + if (step == 2) + return; + + if (step == 0) + { + step = 2; + instruction[1] ^= (dst_ind << 3); + } + } + switch (step) { case 0: + SLJIT_ASSERT(reg_type == SLJIT_SIMD_REG_128); + /* MOVDQA xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ + /* Prefix is filled. */ instruction[2] = 0x6f; instruction[3] = 0xc0 | (tmp_ind << 3) | dst_ind; sljit_emit_op_custom(compiler, instruction, 4); @@ -173,26 +198,29 @@ switch (step) case 1: /* PCMPEQB/W/D xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ - instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; + if (reg_type == SLJIT_SIMD_REG_256) + instruction[1] ^= (dst_ind << 3); + + /* Prefix is filled. */ + instruction[2] = 0x74 + SIMD_COMPARE_TYPE_INDEX; instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind; sljit_emit_op_custom(compiler, instruction, 4); return; case 2: /* PCMPEQB/W/D xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ - instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX; + /* Prefix is filled. */ + instruction[2] = 0x74 + SIMD_COMPARE_TYPE_INDEX; instruction[3] = 0xc0 | (tmp_ind << 3) | cmp2_ind; sljit_emit_op_custom(compiler, instruction, 4); return; case 3: /* POR xmm1, xmm2/m128 */ - /* instruction[0] = 0x66; */ - /* instruction[1] = 0x0f; */ + if (reg_type == SLJIT_SIMD_REG_256) + instruction[1] ^= (dst_ind << 3); + + /* Prefix is filled. */ instruction[2] = 0xeb; instruction[3] = 0xc0 | (dst_ind << 3) | tmp_ind; sljit_emit_op_custom(compiler, instruction, 4); @@ -200,12 +228,16 @@ switch (step) } } -#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2)) +#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD)) static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset) { DEFINE_COMPILER; sljit_u8 instruction[8]; +/* The AVX2 code path is currently disabled. */ +/* sljit_s32 reg_type = sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? SLJIT_SIMD_REG_256 : SLJIT_SIMD_REG_128; */ +sljit_s32 reg_type = SLJIT_SIMD_REG_128; +sljit_s32 value; struct sljit_label *start; #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 struct sljit_label *restart; @@ -213,12 +245,11 @@ struct sljit_label *restart; struct sljit_jump *quit; struct sljit_jump *partial_quit[2]; vector_compare_type compare_type = vector_compare_match1; -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); -sljit_s32 data_ind = 0; -sljit_s32 tmp_ind = 1; -sljit_s32 cmp1_ind = 2; -sljit_s32 cmp2_ind = 3; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 data_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); +sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); +sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); +sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); sljit_u32 bit = 0; int i; @@ -241,61 +272,34 @@ if (common->mode == PCRE2_JIT_COMPLETE) add_jump(compiler, &common->failed_match, partial_quit[0]); /* First part (unaligned start) */ - -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); - -SLJIT_ASSERT(tmp1_reg_ind < 8); - -/* MOVD xmm, r/m32 */ -instruction[0] = 0x66; -instruction[1] = 0x0f; -instruction[2] = 0x6e; -instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind; -sljit_emit_op_custom(compiler, instruction, 4); +value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); if (char1 != char2) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); - - /* MOVD xmm, r/m32 */ - instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); -/* PSHUFD xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x70; -instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind; -instruction[4] = 0; -sljit_emit_op_custom(compiler, instruction, 5); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR1, SLJIT_FR1, 0); if (char1 != char2) - { - /* PSHUFD xmm1, xmm2/m128, imm8 */ - instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 restart = LABEL(); #endif -OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); -load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); +value = (reg_type == SLJIT_SIMD_REG_256) ? 0x1f : 0xf; +OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~value); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value); + +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); + for (i = 0; i < 4; i++) - fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; -sljit_emit_op_custom(compiler, instruction, 4); + fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); @@ -306,27 +310,24 @@ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); /* Second part (aligned) */ start = LABEL(); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); +value = (reg_type == SLJIT_SIMD_REG_256) ? 32 : 16; +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); if (common->mode == PCRE2_JIT_COMPLETE) add_jump(compiler, &common->failed_match, partial_quit[1]); -load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); for (i = 0; i < 4; i++) - fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; -sljit_emit_op_custom(compiler, instruction, 4); + fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); JUMPHERE(quit); +SLJIT_ASSERT(tmp1_reg_ind < 8); /* BSF r32, r/m32 */ instruction[0] = 0x0f; instruction[1] = 0xbc; @@ -340,7 +341,7 @@ if (common->mode != PCRE2_JIT_COMPLETE) JUMPHERE(partial_quit[0]); JUMPHERE(partial_quit[1]); OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); - CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); } else add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); @@ -364,22 +365,25 @@ if (common->utf && offset > 0) #endif } -#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2)) +#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD)) static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2) { DEFINE_COMPILER; sljit_u8 instruction[8]; +/* The AVX2 code path is currently disabled. */ +/* sljit_s32 reg_type = sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? SLJIT_SIMD_REG_256 : SLJIT_SIMD_REG_128; */ +sljit_s32 reg_type = SLJIT_SIMD_REG_128; +sljit_s32 value; struct sljit_label *start; struct sljit_jump *quit; jump_list *not_found = NULL; vector_compare_type compare_type = vector_compare_match1; -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); -sljit_s32 data_ind = 0; -sljit_s32 tmp_ind = 1; -sljit_s32 cmp1_ind = 2; -sljit_s32 cmp2_ind = 3; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 data_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); +sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); +sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); +sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); sljit_u32 bit = 0; int i; @@ -401,57 +405,30 @@ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); /* First part (unaligned start) */ -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); - -SLJIT_ASSERT(tmp1_reg_ind < 8); - -/* MOVD xmm, r/m32 */ -instruction[0] = 0x66; -instruction[1] = 0x0f; -instruction[2] = 0x6e; -instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind; -sljit_emit_op_custom(compiler, instruction, 4); +value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR1, 0, SLJIT_IMM, character_to_int32(char1 | bit)); if (char1 != char2) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); - - /* MOVD xmm, r/m32 */ - instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2)); OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0); -/* PSHUFD xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x70; -instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind; -instruction[4] = 0; -sljit_emit_op_custom(compiler, instruction, 5); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR1, SLJIT_FR1, 0); if (char1 != char2) - { - /* PSHUFD xmm1, xmm2/m128, imm8 */ - instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); -OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); +value = (reg_type == SLJIT_SIMD_REG_256) ? 0x1f : 0xf; +OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~value); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value); + +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); -load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); for (i = 0; i < 4; i++) - fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; -sljit_emit_op_custom(compiler, instruction, 4); + fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); @@ -462,25 +439,23 @@ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); /* Second part (aligned) */ start = LABEL(); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); +value = (reg_type == SLJIT_SIMD_REG_256) ? 32 : 16; +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); -load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0); +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); + for (i = 0; i < 4; i++) - fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind; -sljit_emit_op_custom(compiler, instruction, 4); + fast_forward_char_pair_sse2_compare(compiler, compare_type, reg_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); JUMPHERE(quit); +SLJIT_ASSERT(tmp1_reg_ind < 8); /* BSF r32, r/m32 */ instruction[0] = 0x0f; instruction[1] = 0xbc; @@ -496,29 +471,31 @@ return not_found; #ifndef _WIN64 -#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2)) +#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD)) static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1, PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b) { DEFINE_COMPILER; sljit_u8 instruction[8]; +/* The AVX2 code path is currently disabled. */ +/* sljit_s32 reg_type = sljit_has_cpu_feature(SLJIT_HAS_AVX2) ? SLJIT_SIMD_REG_256 : SLJIT_SIMD_REG_128; */ +sljit_s32 reg_type = SLJIT_SIMD_REG_128; +sljit_s32 value; vector_compare_type compare1_type = vector_compare_match1; vector_compare_type compare2_type = vector_compare_match1; sljit_u32 bit1 = 0; sljit_u32 bit2 = 0; sljit_u32 diff = IN_UCHARS(offs1 - offs2); -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 tmp2_reg_ind = sljit_get_register_index(TMP2); -sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); -sljit_s32 data1_ind = 0; -sljit_s32 data2_ind = 1; -sljit_s32 tmp1_ind = 2; -sljit_s32 tmp2_ind = 3; -sljit_s32 cmp1a_ind = 4; -sljit_s32 cmp1b_ind = 5; -sljit_s32 cmp2a_ind = 6; -sljit_s32 cmp2b_ind = 7; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 data1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR0); +sljit_s32 data2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR1); +sljit_s32 cmp1a_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR2); +sljit_s32 cmp2a_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR3); +sljit_s32 cmp1b_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR4); +sljit_s32 cmp2b_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR5); +sljit_s32 tmp1_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_FR6); +sljit_s32 tmp2_ind = sljit_get_register_index(SLJIT_FLOAT_REGISTER, SLJIT_TMP_FR0); struct sljit_label *start; #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 struct sljit_label *restart; @@ -526,9 +503,8 @@ struct sljit_label *restart; struct sljit_jump *jump[2]; int i; -SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2); -SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset())); -SLJIT_ASSERT(tmp1_reg_ind < 8 && tmp2_reg_ind == 1); +SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2 && offs2 >= 0); +SLJIT_ASSERT(diff <= (unsigned)IN_UCHARS(max_fast_forward_char_pair_offset())); /* Initialize. */ if (common->match_end_ptr != 0) @@ -538,17 +514,12 @@ if (common->match_end_ptr != 0) OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0); - CMOV(SLJIT_LESS, STR_END, TMP1, 0); + SELECT(SLJIT_LESS, STR_END, TMP1, 0, STR_END); } OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); -/* MOVD xmm, r/m32 */ -instruction[0] = 0x66; -instruction[1] = 0x0f; -instruction[2] = 0x6e; - if (char1a == char1b) OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a)); else @@ -569,14 +540,11 @@ else } } -instruction[3] = 0xc0 | (cmp1a_ind << 3) | tmp1_reg_ind; -sljit_emit_op_custom(compiler, instruction, 4); +value = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32 | SLJIT_SIMD_LANE_ZERO; +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR2, 0, TMP1, 0); if (char1a != char1b) - { - instruction[3] = 0xc0 | (cmp1b_ind << 3) | tmp2_reg_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR4, 0, TMP2, 0); if (char2a == char2b) OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a)); @@ -598,38 +566,18 @@ else } } -instruction[3] = 0xc0 | (cmp2a_ind << 3) | tmp1_reg_ind; -sljit_emit_op_custom(compiler, instruction, 4); +sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR3, 0, TMP1, 0); if (char2a != char2b) - { - instruction[3] = 0xc0 | (cmp2b_ind << 3) | tmp2_reg_ind; - sljit_emit_op_custom(compiler, instruction, 4); - } - -/* PSHUFD xmm1, xmm2/m128, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x70; -instruction[4] = 0; - -instruction[3] = 0xc0 | (cmp1a_ind << 3) | cmp1a_ind; -sljit_emit_op_custom(compiler, instruction, 5); + sljit_emit_simd_lane_mov(compiler, value, SLJIT_FR5, 0, TMP2, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR2, SLJIT_FR2, 0); if (char1a != char1b) - { - instruction[3] = 0xc0 | (cmp1b_ind << 3) | cmp1b_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } - -instruction[3] = 0xc0 | (cmp2a_ind << 3) | cmp2a_ind; -sljit_emit_op_custom(compiler, instruction, 5); + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR4, SLJIT_FR4, 0); +sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR3, SLJIT_FR3, 0); if (char2a != char2b) - { - instruction[3] = 0xc0 | (cmp2b_ind << 3) | cmp2b_ind; - sljit_emit_op_custom(compiler, instruction, 5); - } + sljit_emit_simd_lane_replicate(compiler, reg_type | SLJIT_SIMD_ELEM_32, SLJIT_FR5, SLJIT_FR5, 0); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 restart = LABEL(); @@ -637,55 +585,91 @@ restart = LABEL(); OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, diff); OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); -OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf); +value = (reg_type == SLJIT_SIMD_REG_256) ? ~0x1f : ~0xf; +OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); -load_from_mem_sse2(compiler, data1_ind, str_ptr_reg_ind, 0); +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0); -load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff); +sljit_emit_simd_mov(compiler, reg_type, SLJIT_FR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); jump[1] = JUMP(SLJIT_JUMP); JUMPHERE(jump[0]); -/* MOVDQA xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x6f; -instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind; -sljit_emit_op_custom(compiler, instruction, 4); +if (reg_type == SLJIT_SIMD_REG_256) + { + if (diff != 16) + { + /* PSLLDQ ymm1, ymm2, imm8 */ + instruction[0] = 0xc5; + instruction[1] = (sljit_u8)(0xf9 ^ (data2_ind << 3)); + instruction[2] = 0x73; + instruction[3] = 0xc0 | (7 << 3) | data1_ind; + instruction[4] = diff & 0xf; + sljit_emit_op_custom(compiler, instruction, 5); + } -/* PSLLDQ xmm1, imm8 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0x73; -instruction[3] = 0xc0 | (7 << 3) | data2_ind; -instruction[4] = diff; -sljit_emit_op_custom(compiler, instruction, 5); + instruction[0] = 0xc4; + instruction[1] = 0xe3; + if (diff < 16) + { + /* VINSERTI128 xmm1, xmm2, xmm3/m128 */ + /* instruction[0] = 0xc4; */ + /* instruction[1] = 0xe3; */ + instruction[2] = (sljit_u8)(0x7d ^ (data2_ind << 3)); + instruction[3] = 0x38; + SLJIT_ASSERT(sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR) <= 7); + instruction[4] = 0x40 | (data2_ind << 3) | sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); + instruction[5] = (sljit_u8)(16 - diff); + instruction[6] = 1; + sljit_emit_op_custom(compiler, instruction, 7); + } + else + { + /* VPERM2I128 xmm1, xmm2, xmm3/m128 */ + /* instruction[0] = 0xc4; */ + /* instruction[1] = 0xe3; */ + value = (diff == 16) ? data1_ind : data2_ind; + instruction[2] = (sljit_u8)(0x7d ^ (value << 3)); + instruction[3] = 0x46; + instruction[4] = 0xc0 | (data2_ind << 3) | value; + instruction[5] = 0x08; + sljit_emit_op_custom(compiler, instruction, 6); + } + } +else + { + /* MOVDQA xmm1, xmm2/m128 */ + instruction[0] = 0x66; + instruction[1] = 0x0f; + instruction[2] = 0x6f; + instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind; + sljit_emit_op_custom(compiler, instruction, 4); + + /* PSLLDQ xmm1, imm8 */ + /* instruction[0] = 0x66; */ + /* instruction[1] = 0x0f; */ + instruction[2] = 0x73; + instruction[3] = 0xc0 | (7 << 3) | data2_ind; + instruction[4] = diff; + sljit_emit_op_custom(compiler, instruction, 5); + } JUMPHERE(jump[1]); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); +value = (reg_type == SLJIT_SIMD_REG_256) ? 0x1f : 0xf; +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, value); for (i = 0; i < 4; i++) { - fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind); - fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind); + fast_forward_char_pair_sse2_compare(compiler, compare2_type, reg_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind); + fast_forward_char_pair_sse2_compare(compiler, compare1_type, reg_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind); } -/* PAND xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xdb; -instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | 0; -sljit_emit_op_custom(compiler, instruction, 4); +sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_FR0, SLJIT_FR0, SLJIT_FR1); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); /* Ignore matches before the first STR_PTR. */ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); @@ -698,36 +682,28 @@ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); /* Main loop. */ start = LABEL(); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); +value = (reg_type == SLJIT_SIMD_REG_256) ? 32 : 16; +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, value); add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); -load_from_mem_sse2(compiler, data1_ind, str_ptr_reg_ind, 0); -load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff); +value = (reg_type == SLJIT_SIMD_REG_256) ? SLJIT_SIMD_MEM_ALIGNED_256 : SLJIT_SIMD_MEM_ALIGNED_128; +sljit_emit_simd_mov(compiler, reg_type | value, SLJIT_FR0, SLJIT_MEM1(STR_PTR), 0); +sljit_emit_simd_mov(compiler, reg_type, SLJIT_FR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff); for (i = 0; i < 4; i++) { - fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind); - fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind); + fast_forward_char_pair_sse2_compare(compiler, compare1_type, reg_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind); + fast_forward_char_pair_sse2_compare(compiler, compare2_type, reg_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind); } -/* PAND xmm1, xmm2/m128 */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xdb; -instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind; -sljit_emit_op_custom(compiler, instruction, 4); - -/* PMOVMSKB reg, xmm */ -/* instruction[0] = 0x66; */ -/* instruction[1] = 0x0f; */ -instruction[2] = 0xd7; -instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | 0; -sljit_emit_op_custom(compiler, instruction, 4); +sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_FR0, SLJIT_FR0, SLJIT_FR1); +sljit_emit_simd_sign(compiler, SLJIT_SIMD_STORE | reg_type | SLJIT_SIMD_ELEM_8, SLJIT_FR0, TMP1, 0); CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); JUMPHERE(jump[0]); +SLJIT_ASSERT(tmp1_reg_ind < 8); /* BSF r32, r/m32 */ instruction[0] = 0x0f; instruction[1] = 0xbc; @@ -762,7 +738,7 @@ if (common->match_end_ptr != 0) #endif /* !_WIN64 */ -#undef SSE2_COMPARE_TYPE_INDEX +#undef SIMD_COMPARE_TYPE_INDEX #endif /* SLJIT_CONFIG_X86 */ @@ -865,14 +841,14 @@ static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, P { DEFINE_COMPILER; int_char ic; -struct sljit_jump *partial_quit; +struct sljit_jump *partial_quit, *quit; /* Save temporary registers. */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP3, 0); /* Prepare function arguments */ OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0); -OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0); +GET_LOCAL_BASE(SLJIT_R1, 0, LOCALS0); OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, offset); if (char1 == char2) @@ -944,9 +920,14 @@ if (common->mode == PCRE2_JIT_COMPLETE) /* Fast forward STR_PTR to the result of memchr. */ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); - if (common->mode != PCRE2_JIT_COMPLETE) + { + quit = CMP(SLJIT_NOT_ZERO, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0); JUMPHERE(partial_quit); + OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); + JUMPHERE(quit); + } } typedef enum { @@ -1068,10 +1049,10 @@ else OP2(SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, SLJIT_R0, 0); - CMOV(SLJIT_LESS, SLJIT_R0, STR_END, 0); + SELECT(SLJIT_LESS, SLJIT_R0, STR_END, 0, SLJIT_R0); } -OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0); +GET_LOCAL_BASE(SLJIT_R1, 0, LOCALS0); OP1(SLJIT_MOV_S32, SLJIT_R2, 0, SLJIT_IMM, offs1); OP1(SLJIT_MOV_S32, SLJIT_R3, 0, SLJIT_IMM, offs2); ic.c.c1 = char1a; @@ -1177,7 +1158,7 @@ if (step == 0) OP1(SLJIT_MOV, tmp_general_reg, 0, SLJIT_IMM, chr); /* VLVG */ - instruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4) | sljit_get_register_index(tmp_general_reg)); + instruction[0] = (sljit_u16)(0xe700 | (dst_vreg << 4) | sljit_get_register_index(SLJIT_GP_REGISTER, tmp_general_reg)); instruction[1] = 0; instruction[2] = (sljit_u16)((VECTOR_ELEMENT_SIZE << 12) | (0x8 << 8) | 0x22); sljit_emit_op_custom(compiler, instruction, 6); @@ -1256,8 +1237,8 @@ struct sljit_label *restart; struct sljit_jump *quit; struct sljit_jump *partial_quit[2]; vector_compare_type compare_type = vector_compare_match1; -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); sljit_s32 data_ind = 0; sljit_s32 tmp_ind = 1; sljit_s32 cmp1_ind = 2; @@ -1419,7 +1400,7 @@ if (common->mode != PCRE2_JIT_COMPLETE) JUMPHERE(partial_quit[0]); JUMPHERE(partial_quit[1]); OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); - CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); } else add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); @@ -1454,8 +1435,8 @@ struct sljit_label *start; struct sljit_jump *quit; jump_list *not_found = NULL; vector_compare_type compare_type = vector_compare_match1; -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 tmp3_reg_ind = sljit_get_register_index(TMP3); +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 tmp3_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP3); sljit_s32 data_ind = 0; sljit_s32 tmp_ind = 1; sljit_s32 cmp1_ind = 2; @@ -1624,9 +1605,9 @@ vector_compare_type compare2_type = vector_compare_match1; sljit_u32 bit1 = 0; sljit_u32 bit2 = 0; sljit_s32 diff = IN_UCHARS(offs2 - offs1); -sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1); -sljit_s32 tmp2_reg_ind = sljit_get_register_index(TMP2); -sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR); +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 tmp2_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP2); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); sljit_s32 data1_ind = 0; sljit_s32 data2_ind = 1; sljit_s32 tmp1_ind = 2; @@ -1674,7 +1655,7 @@ if (common->match_end_ptr != 0) OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1)); OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0); - CMOV(SLJIT_LESS, STR_END, TMP1, 0); + SELECT(SLJIT_LESS, STR_END, TMP1, 0, STR_END); } OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); @@ -1855,4 +1836,520 @@ if (common->match_end_ptr != 0) #endif /* SLJIT_CONFIG_S390X */ +#if (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) + +#ifdef __linux__ +/* Using getauxval(AT_HWCAP) under Linux for detecting whether LSX is available */ +#include +#define LOONGARCH_HWCAP_LSX (1 << 4) +#define HAS_LSX_SUPPORT ((getauxval(AT_HWCAP) & LOONGARCH_HWCAP_LSX) != 0) +#else +#define HAS_LSX_SUPPORT 0 +#endif + +typedef sljit_ins sljit_u32; + +#define SI12_IMM_MASK 0x003ffc00 +#define UI5_IMM_MASK 0x00007c00 +#define UI2_IMM_MASK 0x00000c00 + +#define VD(vd) ((sljit_ins)vd << 0) +#define VJ(vj) ((sljit_ins)vj << 5) +#define VK(vk) ((sljit_ins)vk << 10) +#define RD_V(rd) ((sljit_ins)rd << 0) +#define RJ_V(rj) ((sljit_ins)rj << 5) + +#define IMM_SI12(imm) (((sljit_ins)(imm) << 10) & SI12_IMM_MASK) +#define IMM_UI5(imm) (((sljit_ins)(imm) << 10) & UI5_IMM_MASK) +#define IMM_UI2(imm) (((sljit_ins)(imm) << 10) & UI2_IMM_MASK) + +// LSX OPCODES: +#define VLD 0x2c000000 +#define VOR_V 0x71268000 +#define VAND_V 0x71260000 +#define VBSLL_V 0x728e0000 +#define VMSKLTZ_B 0x729c4000 +#define VPICKVE2GR_WU 0x72f3e000 + +#if PCRE2_CODE_UNIT_WIDTH == 8 +#define VREPLGR2VR 0x729f0000 +#define VSEQ 0x70000000 +#elif PCRE2_CODE_UNIT_WIDTH == 16 +#define VREPLGR2VR 0x729f0400 +#define VSEQ 0x70008000 +#else +#define VREPLGR2VR 0x729f0800 +#define VSEQ 0x70010000 +#endif + +static void fast_forward_char_pair_lsx_compare(struct sljit_compiler *compiler, vector_compare_type compare_type, + sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind) +{ +if (compare_type != vector_compare_match2) + { + if (compare_type == vector_compare_match1i) + { + /* VOR.V vd, vj, vk */ + push_inst(compiler, VOR_V | VD(dst_ind) | VJ(cmp2_ind) | VK(dst_ind)); + } + + /* VSEQ.B/H/W vd, vj, vk */ + push_inst(compiler, VSEQ | VD(dst_ind) | VJ(dst_ind) | VK(cmp1_ind)); + return; + } + +/* VBSLL.V vd, vj, ui5 */ +push_inst(compiler, VBSLL_V | VD(tmp_ind) | VJ(dst_ind) | IMM_UI5(0)); + +/* VSEQ.B/H/W vd, vj, vk */ +push_inst(compiler, VSEQ | VD(dst_ind) | VJ(dst_ind) | VK(cmp1_ind)); + +/* VSEQ.B/H/W vd, vj, vk */ +push_inst(compiler, VSEQ | VD(tmp_ind) | VJ(tmp_ind) | VK(cmp2_ind)); + +/* VOR vd, vj, vk */ +push_inst(compiler, VOR_V | VD(dst_ind) | VJ(tmp_ind) | VK(dst_ind)); +return; +} + +#define JIT_HAS_FAST_FORWARD_CHAR_SIMD HAS_LSX_SUPPORT + +static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset) +{ +DEFINE_COMPILER; +struct sljit_label *start; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_label *restart; +#endif +struct sljit_jump *quit; +struct sljit_jump *partial_quit[2]; +vector_compare_type compare_type = vector_compare_match1; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); +sljit_s32 data_ind = 0; +sljit_s32 tmp_ind = 1; +sljit_s32 cmp1_ind = 2; +sljit_s32 cmp2_ind = 3; +sljit_u32 bit = 0; + +SLJIT_UNUSED_ARG(offset); + +if (char1 != char2) + { + bit = char1 ^ char2; + compare_type = vector_compare_match1i; + + if (!is_powerof2(bit)) + { + bit = 0; + compare_type = vector_compare_match2; + } + } + +partial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, &common->failed_match, partial_quit[0]); + +/* First part (unaligned start) */ + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1 | bit); + +/* VREPLGR2VR.B/H/W vd, rj */ +push_inst(compiler, VREPLGR2VR | VD(cmp1_ind) | RJ_V(tmp1_reg_ind)); + +if (char1 != char2) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, bit != 0 ? bit : char2); + + /* VREPLGR2VR.B/H/W vd, rj */ + push_inst(compiler, VREPLGR2VR | VD(cmp2_ind) | RJ_V(tmp1_reg_ind)); + } + +OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +restart = LABEL(); +#endif + +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); +fast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0)); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); + +quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0); + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* Second part (aligned) */ +start = LABEL(); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); + +partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +if (common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, &common->failed_match, partial_quit[1]); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); +fast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0)); + +CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); + +JUMPHERE(quit); + +/* CTZ.W rd, rj */ +push_inst(compiler, CTZ_W | RD_V(tmp1_reg_ind) | RJ_V(tmp1_reg_ind)); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + +if (common->mode != PCRE2_JIT_COMPLETE) + { + JUMPHERE(partial_quit[0]); + JUMPHERE(partial_quit[1]); + OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0); + SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR); + } +else + add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +if (common->utf && offset > 0) + { + SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE); + + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset)); + + quit = jump_if_utf_char_start(compiler, TMP1); + + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); + JUMPTO(SLJIT_JUMP, restart); + + JUMPHERE(quit); + } +#endif +} + +#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD HAS_LSX_SUPPORT + +static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2) +{ +DEFINE_COMPILER; +struct sljit_label *start; +struct sljit_jump *quit; +jump_list *not_found = NULL; +vector_compare_type compare_type = vector_compare_match1; +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); +sljit_s32 data_ind = 0; +sljit_s32 tmp_ind = 1; +sljit_s32 cmp1_ind = 2; +sljit_s32 cmp2_ind = 3; +sljit_u32 bit = 0; + +if (char1 != char2) + { + bit = char1 ^ char2; + compare_type = vector_compare_match1i; + + if (!is_powerof2(bit)) + { + bit = 0; + compare_type = vector_compare_match2; + } + } + +add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0)); +OP1(SLJIT_MOV, TMP2, 0, TMP1, 0); +OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + +/* First part (unaligned start) */ + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1 | bit); + +/* VREPLGR2VR vd, rj */ +push_inst(compiler, VREPLGR2VR | VD(cmp1_ind) | RJ_V(tmp1_reg_ind)); + +if (char1 != char2) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, bit != 0 ? bit : char2); + /* VREPLGR2VR vd, rj */ + push_inst(compiler, VREPLGR2VR | VD(cmp2_ind) | RJ_V(tmp1_reg_ind)); + } + +OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); +fast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0)); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); + +quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0); + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* Second part (aligned) */ +start = LABEL(); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); + +add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); +fast_forward_char_pair_lsx_compare(compiler, compare_type, data_ind, cmp1_ind, cmp2_ind, tmp_ind); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp_ind) | VJ(data_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp_ind) | IMM_UI2(0)); + +CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); + +JUMPHERE(quit); + +/* CTZ.W rd, rj */ +push_inst(compiler, CTZ_W | RD_V(tmp1_reg_ind) | RJ_V(tmp1_reg_ind)); + +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, STR_PTR, 0); +add_jump(compiler, ¬_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0)); + +OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); +return not_found; +} + +#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD HAS_LSX_SUPPORT + +static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1, + PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b) +{ +DEFINE_COMPILER; +vector_compare_type compare1_type = vector_compare_match1; +vector_compare_type compare2_type = vector_compare_match1; +sljit_u32 bit1 = 0; +sljit_u32 bit2 = 0; +sljit_u32 diff = IN_UCHARS(offs1 - offs2); +sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1); +sljit_s32 tmp2_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP2); +sljit_s32 str_ptr_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, STR_PTR); +sljit_s32 data1_ind = 0; +sljit_s32 data2_ind = 1; +sljit_s32 tmp1_ind = 2; +sljit_s32 tmp2_ind = 3; +sljit_s32 cmp1a_ind = 4; +sljit_s32 cmp1b_ind = 5; +sljit_s32 cmp2a_ind = 6; +sljit_s32 cmp2b_ind = 7; +struct sljit_label *start; +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_label *restart; +#endif +struct sljit_jump *jump[2]; + +SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2); +SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset())); + +/* Initialize. */ +if (common->match_end_ptr != 0) + { + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1)); + OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + + OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0); + SELECT(SLJIT_LESS, STR_END, TMP1, 0, STR_END); + } + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); +add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +if (char1a == char1b) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1a); +else + { + bit1 = char1a ^ char1b; + if (is_powerof2(bit1)) + { + compare1_type = vector_compare_match1i; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1a | bit1); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, bit1); + } + else + { + compare1_type = vector_compare_match2; + bit1 = 0; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1a); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, char1b); + } + } + +/* VREPLGR2VR vd, rj */ +push_inst(compiler, VREPLGR2VR | VD(cmp1a_ind) | RJ_V(tmp1_reg_ind)); + +if (char1a != char1b) + { + /* VREPLGR2VR vd, rj */ + push_inst(compiler, VREPLGR2VR | VD(cmp1b_ind) | RJ_V(tmp2_reg_ind)); + } + +if (char2a == char2b) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char2a); +else + { + bit2 = char2a ^ char2b; + if (is_powerof2(bit2)) + { + compare2_type = vector_compare_match1i; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char2a | bit2); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, bit2); + } + else + { + compare2_type = vector_compare_match2; + bit2 = 0; + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char2a); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, char2b); + } + } + +/* VREPLGR2VR vd, rj */ +push_inst(compiler, VREPLGR2VR | VD(cmp2a_ind) | RJ_V(tmp1_reg_ind)); + +if (char2a != char2b) + { + /* VREPLGR2VR vd, rj */ + push_inst(compiler, VREPLGR2VR | VD(cmp2b_ind) | RJ_V(tmp2_reg_ind)); + } + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +restart = LABEL(); +#endif + +OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, diff); +OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data1_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); + +jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data2_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(-(sljit_s8)diff)); +jump[1] = JUMP(SLJIT_JUMP); + +JUMPHERE(jump[0]); + +/* VBSLL.V vd, vj, ui5 */ +push_inst(compiler, VBSLL_V | VD(data2_ind) | VJ(data1_ind) | IMM_UI5(diff)); + +JUMPHERE(jump[1]); + +fast_forward_char_pair_lsx_compare(compiler, compare2_type, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind); +fast_forward_char_pair_lsx_compare(compiler, compare1_type, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind); + +/* VAND vd, vj, vk */ +push_inst(compiler, VOR_V | VD(data1_ind) | VJ(data1_ind) | VK(data2_ind)); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp1_ind) | VJ(data1_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp1_ind) | IMM_UI2(0)); + +/* Ignore matches before the first STR_PTR. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); +OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0); + +jump[0] = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0); + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + +/* Main loop. */ +start = LABEL(); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16); +add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +/* VLD vd, rj, si12 */ +push_inst(compiler, VLD | VD(data1_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(0)); +push_inst(compiler, VLD | VD(data2_ind) | RJ_V(str_ptr_reg_ind) | IMM_SI12(-(sljit_s8)diff)); + +fast_forward_char_pair_lsx_compare(compiler, compare1_type, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind); +fast_forward_char_pair_lsx_compare(compiler, compare2_type, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind); + +/* VAND.V vd, vj, vk */ +push_inst(compiler, VAND_V | VD(data1_ind) | VJ(data1_ind) | VK(data2_ind)); + +/* VMSKLTZ.B vd, vj */ +push_inst(compiler, VMSKLTZ_B | VD(tmp1_ind) | VJ(data1_ind)); + +/* VPICKVE2GR.WU rd, vj, ui2 */ +push_inst(compiler, VPICKVE2GR_WU | RD_V(tmp1_reg_ind) | VJ(tmp1_ind) | IMM_UI2(0)); + +CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start); + +JUMPHERE(jump[0]); + +/* CTZ.W rd, rj */ +push_inst(compiler, CTZ_W | RD_V(tmp1_reg_ind) | RJ_V(tmp1_reg_ind)); + +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + +add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +if (common->utf) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1)); + + jump[0] = jump_if_utf_char_start(compiler, TMP1); + + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart); + + add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP)); + + JUMPHERE(jump[0]); + } +#endif + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1)); + +if (common->match_end_ptr != 0) + OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); +} + +#endif /* SLJIT_CONFIG_LOONGARCH_64 */ + #endif /* !SUPPORT_VALGRIND */ diff --git a/src/3rdparty/pcre2/src/pcre2_maketables.c b/src/3rdparty/pcre2/src/pcre2_maketables.c index 56d24940232..ac8b63b8097 100644 --- a/src/3rdparty/pcre2/src/pcre2_maketables.c +++ b/src/3rdparty/pcre2/src/pcre2_maketables.c @@ -52,8 +52,6 @@ PCRE2_DFTABLES is defined. */ # include "pcre2_internal.h" #endif - - /************************************************* * Create PCRE2 character tables * *************************************************/ @@ -98,7 +96,11 @@ for (i = 0; i < 256; i++) *p++ = tolower(i); /* Next the case-flipping table */ -for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i); +for (i = 0; i < 256; i++) + { + int c = islower(i)? toupper(i) : tolower(i); + *p++ = (c < 256)? c : i; + } /* Then the character class tables. Don't try to be clever and save effort on exclusive ones - in some locales things may be different. diff --git a/src/3rdparty/pcre2/src/pcre2_match.c b/src/3rdparty/pcre2/src/pcre2_match.c index 168b9fad019..b4a970313d7 100644 --- a/src/3rdparty/pcre2/src/pcre2_match.c +++ b/src/3rdparty/pcre2/src/pcre2_match.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2015-2022 University of Cambridge + New API code Copyright (c) 2015-2024 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -43,6 +43,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "config.h" #endif +#include "pcre2_internal.h" + /* These defines enable debugging code */ /* #define DEBUG_FRAMES_DISPLAY */ @@ -53,6 +55,10 @@ POSSIBILITY OF SUCH DAMAGE. #include #endif +#ifdef DEBUG_SHOW_OPS +static const char *OP_names[] = { OP_NAME_LIST }; +#endif + /* These defines identify the name of the block containing "static" information, and fields within it. */ @@ -60,8 +66,6 @@ information, and fields within it. */ #define PSSTART start_subject /* Field containing processed string start */ #define PSEND end_subject /* Field containing processed string end */ -#include "pcre2_internal.h" - #define RECURSE_UNSET 0xffffffffu /* Bigger than max group number */ /* Masks for identifying the public options that are permitted at match time. */ @@ -69,7 +73,8 @@ information, and fields within it. */ #define PUBLIC_MATCH_OPTIONS \ (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \ PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \ - PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT|PCRE2_COPY_MATCHED_SUBJECT) + PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT|PCRE2_COPY_MATCHED_SUBJECT| \ + PCRE2_DISABLE_RECURSELOOP_CHECK) #define PUBLIC_JIT_MATCH_OPTIONS \ (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\ @@ -150,7 +155,7 @@ changed, the code at RETURN_SWITCH below must be updated in sync. */ enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20, RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30, - RM31, RM32, RM33, RM34, RM35, RM36 }; + RM31, RM32, RM33, RM34, RM35, RM36, RM37 }; #ifdef SUPPORT_WIDE_CHARS enum { RM100=100, RM101 }; @@ -597,11 +602,12 @@ heapframe *P = NULL; heapframe *frames_top; /* End of frames vector */ heapframe *assert_accept_frame = NULL; /* For passing back a frame with captures */ -PCRE2_SIZE heapframes_size; /* Usable size of frames vector */ PCRE2_SIZE frame_copy_size; /* Amount to copy when creating a new frame */ /* Local variables that do not need to be preserved over calls to RRMATCH(). */ +PCRE2_SPTR branch_end = NULL; +PCRE2_SPTR branch_start; PCRE2_SPTR bracode; /* Temp pointer to start of group */ PCRE2_SIZE offset; /* Used for group offsets */ PCRE2_SIZE length; /* Used for various length calculations */ @@ -635,13 +641,10 @@ copied when a new frame is created. */ frame_copy_size = frame_size - offsetof(heapframe, eptr); -/* Set up the first frame and the end of the frames vector. We set the local -heapframes_size to the usuable amount of the vector, that is, a whole number of -frames. */ +/* Set up the first frame and the end of the frames vector. */ F = match_data->heapframes; -heapframes_size = (match_data->heapframes_size / frame_size) * frame_size; -frames_top = (heapframe *)((char *)F + heapframes_size); +frames_top = (heapframe *)((char *)F + match_data->heapframes_size); Frdepth = 0; /* "Recursion" depth */ Fcapture_last = 0; /* Number of most recent capture */ @@ -662,35 +665,54 @@ MATCH_RECURSE: doubling the size, but constrained by the heap limit (which is in KiB). */ N = (heapframe *)((char *)F + frame_size); -if (N >= frames_top) +if ((heapframe *)((char *)N + frame_size) >= frames_top) { heapframe *new; - PCRE2_SIZE newsize = match_data->heapframes_size * 2; + PCRE2_SIZE newsize; + PCRE2_SIZE usedsize = (char *)N - (char *)(match_data->heapframes); - if (newsize > mb->heap_limit) + if (match_data->heapframes_size >= PCRE2_SIZE_MAX / 2) { - PCRE2_SIZE maxsize = (mb->heap_limit/frame_size) * frame_size; - if (match_data->heapframes_size >= maxsize) return PCRE2_ERROR_HEAPLIMIT; - newsize = maxsize; + if (match_data->heapframes_size == PCRE2_SIZE_MAX - 1) + return PCRE2_ERROR_NOMEMORY; + newsize = PCRE2_SIZE_MAX - 1; + } + else + newsize = match_data->heapframes_size * 2; + + if (newsize / 1024 >= mb->heap_limit) + { + PCRE2_SIZE old_size = match_data->heapframes_size / 1024; + if (mb->heap_limit <= old_size) + return PCRE2_ERROR_HEAPLIMIT; + else + { + PCRE2_SIZE max_delta = 1024 * (mb->heap_limit - old_size); + int over_bytes = match_data->heapframes_size % 1024; + if (over_bytes) max_delta -= (1024 - over_bytes); + newsize = match_data->heapframes_size + max_delta; + } } + /* With a heap limit set, the permitted additional size may not be enough for + another frame, so do a final check. */ + + if (newsize - usedsize < frame_size) return PCRE2_ERROR_HEAPLIMIT; new = match_data->memctl.malloc(newsize, match_data->memctl.memory_data); if (new == NULL) return PCRE2_ERROR_NOMEMORY; - memcpy(new, match_data->heapframes, heapframes_size); + memcpy(new, match_data->heapframes, usedsize); - F = (heapframe *)((char *)new + ((char *)F - (char *)match_data->heapframes)); - N = (heapframe *)((char *)F + frame_size); + N = (heapframe *)((char *)new + usedsize); + F = (heapframe *)((char *)N - frame_size); match_data->memctl.free(match_data->heapframes, match_data->memctl.memory_data); match_data->heapframes = new; match_data->heapframes_size = newsize; - - heapframes_size = (newsize / frame_size) * frame_size; - frames_top = (heapframe *)((char *)new + heapframes_size); + frames_top = (heapframe *)((char *)new + newsize); } #ifdef DEBUG_SHOW_RMATCH -fprintf(stderr, "++ RMATCH %2d frame=%d", Freturn_id, Frdepth + 1); +fprintf(stderr, "++ RMATCH %d frame=%d", Freturn_id, Frdepth + 1); if (group_frame_type != 0) { fprintf(stderr, " type=%x ", group_frame_type); @@ -760,10 +782,16 @@ opcodes. */ if (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT; if (Frdepth >= mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT; +#ifdef DEBUG_SHOW_OPS +fprintf(stderr, "\n++ New frame: type=0x%x subject offset %ld\n", + GF_IDMASK(Fgroup_frame_type), Feptr - mb->start_subject); +#endif + for (;;) { #ifdef DEBUG_SHOW_OPS -fprintf(stderr, "++ op=%d\n", *Fecode); +fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, + OP_names[*Fecode]); #endif Fop = (uint8_t)(*Fecode); /* Cast needed for 16-bit and 32-bit modes */ @@ -811,15 +839,16 @@ fprintf(stderr, "++ op=%d\n", *Fecode); assert_accept_frame = F; RRETURN(MATCH_ACCEPT); - /* If recursing, we have to find the most recent recursion. */ + /* For ACCEPT within a recursion, we have to find the most recent + recursion. If not in a recursion, fall through to code that is common with + OP_END. */ case OP_ACCEPT: - case OP_END: - - /* Handle end of a recursion. */ - if (Fcurrent_recurse != RECURSE_UNSET) { +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ Accept within recursion\n"); +#endif offset = Flast_group_offset; for(;;) { @@ -842,27 +871,49 @@ fprintf(stderr, "++ op=%d\n", *Fecode); Fecode += 1 + LINK_SIZE; continue; } + /* Fall through */ - /* Not a recursion. Fail for an empty string match if either PCRE2_NOTEMPTY - is set, or if PCRE2_NOTEMPTY_ATSTART is set and we have matched at the - start of the subject. In both cases, backtracking will then try other - alternatives, if any. */ + /* OP_END itself can never be reached within a recursion because that is + picked up when the OP_KET that always precedes OP_END is reached. */ + + case OP_END: + + /* Fail for an empty string match if either PCRE2_NOTEMPTY is set, or if + PCRE2_NOTEMPTY_ATSTART is set and we have matched at the start of the + subject. In both cases, backtracking will then try other alternatives, if + any. */ if (Feptr == Fstart_match && ((mb->moptions & PCRE2_NOTEMPTY) != 0 || ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) != 0 && Fstart_match == mb->start_subject + mb->start_offset))) + { +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ Backtrack because empty string\n"); +#endif RRETURN(MATCH_NOMATCH); + } - /* Also fail if PCRE2_ENDANCHORED is set and the end of the match is not + /* Fail if PCRE2_ENDANCHORED is set and the end of the match is not the end of the subject. After (*ACCEPT) we fail the entire match (at this - position) but backtrack on reaching the end of the pattern. */ + position) but backtrack if we've reached the end of the pattern. This + applies whether or not we are in a recursion. */ if (Feptr < mb->end_subject && ((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0) { - if (Fop == OP_END) RRETURN(MATCH_NOMATCH); - return MATCH_NOMATCH; + if (Fop == OP_END) + { +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ Backtrack because not at end (endanchored set)\n"); +#endif + RRETURN(MATCH_NOMATCH); + } + +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ Failed ACCEPT not at end (endanchnored set)\n"); +#endif + return MATCH_NOMATCH; /* (*ACCEPT) */ } /* We have a successful match of the whole pattern. Record the result and @@ -2435,6 +2486,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); GETCHARINCTEST(fc, Feptr); { const uint32_t *cp; + uint32_t chartype; const ucd_record *prop = GET_UCD(fc); BOOL notmatch = Fop == OP_NOTPROP; @@ -2445,9 +2497,10 @@ fprintf(stderr, "++ op=%d\n", *Fecode); break; case PT_LAMP: - if ((prop->chartype == ucp_Lu || - prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt) == notmatch) + chartype = prop->chartype; + if ((chartype == ucp_Lu || + chartype == ucp_Ll || + chartype == ucp_Lt) == notmatch) RRETURN(MATCH_NOMATCH); break; @@ -2477,8 +2530,9 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* These are specials */ case PT_ALNUM: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N) == notmatch) + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N) == notmatch) RRETURN(MATCH_NOMATCH); break; @@ -2503,13 +2557,22 @@ fprintf(stderr, "++ op=%d\n", *Fecode); break; case PT_WORD: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || - fc == CHAR_UNDERSCORE) == notmatch) + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || + chartype == ucp_Pc) == notmatch) RRETURN(MATCH_NOMATCH); break; case PT_CLIST: +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (fc > MAX_UTF_CODE_POINT) + { + if (notmatch) break;; + RRETURN(MATCH_NOMATCH); + } +#endif cp = PRIV(ucd_caseless_sets) + Fecode[2]; for (;;) { @@ -2805,16 +2868,17 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case PT_WORD: for (i = 1; i <= Lmin; i++) { - int category; + int chartype, category; if (Feptr >= mb->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); - category = UCD_CATEGORY(fc); + chartype = UCD_CHARTYPE(fc); + category = PRIV(ucp_gentype)[chartype]; if ((category == ucp_L || category == ucp_N || - fc == CHAR_UNDERSCORE) == notmatch) + chartype == ucp_Mn || chartype == ucp_Pc) == notmatch) RRETURN(MATCH_NOMATCH); } break; @@ -2829,6 +2893,13 @@ fprintf(stderr, "++ op=%d\n", *Fecode); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (fc > MAX_UTF_CODE_POINT) + { + if (notmatch) continue; + RRETURN(MATCH_NOMATCH); + } +#endif cp = PRIV(ucd_caseless_sets) + Lpropvalue; for (;;) { @@ -3609,7 +3680,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case PT_WORD: for (;;) { - int category; + int chartype, category; RMATCH(Fecode, RM215); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH); @@ -3619,10 +3690,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); - category = UCD_CATEGORY(fc); + chartype = UCD_CHARTYPE(fc); + category = PRIV(ucp_gentype)[chartype]; if ((category == ucp_L || category == ucp_N || - fc == CHAR_UNDERSCORE) == (Lctype == OP_NOTPROP)) + chartype == ucp_Mn || + chartype == ucp_Pc) == (Lctype == OP_NOTPROP)) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ @@ -3640,6 +3713,13 @@ fprintf(stderr, "++ op=%d\n", *Fecode); RRETURN(MATCH_NOMATCH); } GETCHARINCTEST(fc, Feptr); +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (fc > MAX_UTF_CODE_POINT) + { + if (Lctype == OP_NOTPROP) continue; + RRETURN(MATCH_NOMATCH); + } +#endif cp = PRIV(ucd_caseless_sets) + Lpropvalue; for (;;) { @@ -4190,7 +4270,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case PT_WORD: for (i = Lmin; i < Lmax; i++) { - int category; + int chartype, category; int len = 1; if (Feptr >= mb->end_subject) { @@ -4198,9 +4278,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode); break; } GETCHARLENTEST(fc, Feptr, len); - category = UCD_CATEGORY(fc); - if ((category == ucp_L || category == ucp_N || - fc == CHAR_UNDERSCORE) == notmatch) + chartype = UCD_CHARTYPE(fc); + category = PRIV(ucp_gentype)[chartype]; + if ((category == ucp_L || + category == ucp_N || + chartype == ucp_Mn || + chartype == ucp_Pc) == notmatch) break; Feptr+= len; } @@ -4217,14 +4300,24 @@ fprintf(stderr, "++ op=%d\n", *Fecode); break; } GETCHARLENTEST(fc, Feptr, len); - cp = PRIV(ucd_caseless_sets) + Lpropvalue; - for (;;) +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (fc > MAX_UTF_CODE_POINT) { - if (fc < *cp) - { if (notmatch) break; else goto GOT_MAX; } - if (fc == *cp++) - { if (notmatch) goto GOT_MAX; else break; } + if (!notmatch) goto GOT_MAX; } + else +#endif + { + cp = PRIV(ucd_caseless_sets) + Lpropvalue; + for (;;) + { + if (fc < *cp) + { if (notmatch) break; else goto GOT_MAX; } + if (fc == *cp++) + { if (notmatch) goto GOT_MAX; else break; } + } + } + Feptr += len; } GOT_MAX: @@ -5322,9 +5415,11 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* ===================================================================== */ - /* Recursion either matches the current regex, or some subexpression. The - offset data is the offset to the starting bracket from the start of the - whole pattern. (This is so that it works from duplicated subpatterns.) */ + /* Pattern recursion either matches the current regex, or some + subexpression. The offset data is the offset to the starting bracket from + the start of the whole pattern. This is so that it works from duplicated + subpatterns. For a whole-pattern recursion, we have to infer the number + zero. */ #define Lframe_type F->temp_32[0] #define Lstart_branch F->temp_sptr[0] @@ -5333,9 +5428,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode); bracode = mb->start_code + GET(Fecode, 1); number = (bracode == mb->start_code)? 0 : GET2(bracode, 1 + LINK_SIZE); - /* If we are already in a recursion, check for repeating the same one - without advancing the subject pointer. This should catch convoluted mutual - recursions. (Some simple cases are caught at compile time.) */ + /* If we are already in a pattern recursion, check for repeating the same + one without changing the subject pointer or the last referenced character + in the subject. This should catch convoluted mutual recursions; some + simple cases are caught at compile time. However, there are rare cases when + this check needs to be turned off. In this case, actual recursion loops + will be caught by the match or heap limits. */ if (Fcurrent_recurse != RECURSE_UNSET) { @@ -5346,15 +5444,19 @@ fprintf(stderr, "++ op=%d\n", *Fecode); P = (heapframe *)((char *)N - frame_size); if (N->group_frame_type == (GF_RECURSE | number)) { - if (Feptr == P->eptr) return PCRE2_ERROR_RECURSELOOP; + if (Feptr == P->eptr && mb->last_used_ptr == P->recurse_last_used && + (mb->moptions & PCRE2_DISABLE_RECURSELOOP_CHECK) == 0) + return PCRE2_ERROR_RECURSELOOP; break; } offset = P->last_group_offset; } } - /* Now run the recursion, branch by branch. */ + /* Remember the current last referenced character and then run the + recursion branch by branch. */ + F->recurse_last_used = mb->last_used_ptr; Lstart_branch = bracode; Lframe_type = GF_RECURSE | number; @@ -5683,13 +5785,13 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* ===================================================================== */ - /* Move the subject pointer back. This occurs only at the start of each - branch of a lookbehind assertion. If we are too close to the start to move - back, fail. When working with UTF-8 we move back a number of characters, - not bytes. */ + /* Move the subject pointer back by one fixed amount. This occurs at the + start of each branch that has a fixed length in a lookbehind assertion. If + we are too close to the start to move back, fail. When working with UTF-8 + we move back a number of characters, not bytes. */ case OP_REVERSE: - number = GET(Fecode, 1); + number = GET2(Fecode, 1); #ifdef SUPPORT_UNICODE if (utf) { @@ -5703,7 +5805,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); else #endif - /* No UTF-8 support, or not in UTF-8 mode: count is code unit count */ + /* No UTF support, or not in UTF mode: count is code unit count */ { if ((ptrdiff_t)number > Feptr - mb->start_subject) RRETURN(MATCH_NOMATCH); @@ -5713,15 +5815,84 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* Save the earliest consulted character, then skip to next opcode */ if (Feptr < mb->start_used_ptr) mb->start_used_ptr = Feptr; - Fecode += 1 + LINK_SIZE; + Fecode += 1 + IMM2_SIZE; break; + /* ===================================================================== */ + /* Move the subject pointer back by a variable amount. This occurs at the + start of each branch of a lookbehind assertion when the branch has a + variable, but limited, length. A loop is needed to try matching the branch + after moving back different numbers of characters. If we are too close to + the start to move back even the minimum amount, fail. When working with + UTF-8 we move back a number of characters, not bytes. */ + +#define Lmin F->temp_32[0] +#define Lmax F->temp_32[1] +#define Leptr F->temp_sptr[0] + + case OP_VREVERSE: + Lmin = GET2(Fecode, 1); + Lmax = GET2(Fecode, 1 + IMM2_SIZE); + Leptr = Feptr; + + /* Move back by the maximum branch length and then work forwards. This + ensures that items such as \d{3,5} get the maximum length, which is + relevant for captures, and makes for Perl compatibility. */ + +#ifdef SUPPORT_UNICODE + if (utf) + { + for (i = 0; i < Lmax; i++) + { + if (Feptr == mb->start_subject) + { + if (i < Lmin) RRETURN(MATCH_NOMATCH); + Lmax = i; + break; + } + Feptr--; + BACKCHAR(Feptr); + } + } + else +#endif + + /* No UTF support or not in UTF mode */ + + { + ptrdiff_t diff = Feptr - mb->start_subject; + uint32_t available = (diff > 65535)? 65535 : ((diff > 0)? diff : 0); + if (Lmin > available) RRETURN(MATCH_NOMATCH); + if (Lmax > available) Lmax = available; + Feptr -= Lmax; + } + + /* Now try matching, moving forward one character on failure, until we + reach the mimimum back length. */ + + for (;;) + { + RMATCH(Fecode + 1 + 2 * IMM2_SIZE, RM37); + if (rrc != MATCH_NOMATCH) RRETURN(rrc); + if (Lmax-- <= Lmin) RRETURN(MATCH_NOMATCH); + Feptr++; +#ifdef SUPPORT_UNICODE + if (utf) { FORWARDCHARTEST(Feptr, mb->end_subject); } +#endif + } + /* Control never reaches here */ + +#undef Lmin +#undef Lmax +#undef Leptr + /* ===================================================================== */ /* An alternation is the end of a branch; scan along to find the end of the bracketed group. */ case OP_ALT: + branch_end = Fecode; do Fecode += GET(Fecode,1); while (*Fecode == OP_ALT); break; @@ -5729,7 +5900,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* ===================================================================== */ /* The end of a parenthesized group. For all but OP_BRA and OP_COND, the starting frame was added to the chained frames in order to remember the - starting subject position for the group. */ + starting subject position for the group. (Not true for OP_BRA when it's a + whole pattern recursion, but that is handled separately below.)*/ case OP_KET: case OP_KETRMIN: @@ -5738,8 +5910,14 @@ fprintf(stderr, "++ op=%d\n", *Fecode); bracode = Fecode - GET(Fecode, 1); - /* Point N to the frame at the start of the most recent group. - Remember the subject pointer at the start of the group. */ + if (branch_end == NULL) branch_end = Fecode; + branch_start = bracode; + while (branch_start + GET(branch_start, 1) != branch_end) + branch_start += GET(branch_start, 1); + branch_end = NULL; + + /* Point N to the frame at the start of the most recent group, and P to its + predecessor. Remember the subject pointer at the start of the group. */ if (*bracode != OP_BRA && *bracode != OP_COND) { @@ -5775,27 +5953,64 @@ fprintf(stderr, "++ op=%d\n", *Fecode); switch (*bracode) { - case OP_BRA: /* No need to do anything for these */ - case OP_COND: + /* Whole pattern recursion is handled as a recursion into group 0, but + the entire pattern is wrapped in OP_BRA/OP_KET rather than a capturing + group - a design mistake: it should perhaps have been capture group 0. + Anyway, that means the end of such recursion must be handled here. It is + detected by checking for an immediately following OP_END when we are + recursing in group 0. If this is not the end of a whole-pattern + recursion, there is nothing to be done. */ + + case OP_BRA: + if (Fcurrent_recurse != 0 || Fecode[1+LINK_SIZE] != OP_END) break; + + /* It is the end of whole-pattern recursion. */ + + offset = Flast_group_offset; + if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL; + N = (heapframe *)((char *)match_data->heapframes + offset); + P = (heapframe *)((char *)N - frame_size); + Flast_group_offset = P->last_group_offset; + + /* Reinstate the previous set of captures and then carry on after the + recursion call. */ + + memcpy((char *)F + offsetof(heapframe, ovector), P->ovector, + Foffset_top * sizeof(PCRE2_SIZE)); + Foffset_top = P->offset_top; + Fcapture_last = P->capture_last; + Fcurrent_recurse = P->current_recurse; + Fecode = P->ecode + 1 + LINK_SIZE; + continue; /* With next opcode */ + + case OP_COND: /* No need to do anything for these */ case OP_SCOND: break; /* Non-atomic positive assertions are like OP_BRA, except that the subject pointer must be put back to where it was at the start of the - assertion. */ + assertion. For a variable lookbehind, check its end point. */ + + case OP_ASSERTBACK_NA: + if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) + RRETURN(MATCH_NOMATCH); + /* Fall through */ case OP_ASSERT_NA: - case OP_ASSERTBACK_NA: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; Feptr = P->eptr; break; /* Atomic positive assertions are like OP_ONCE, except that in addition the subject pointer must be put back to where it was at the start of the - assertion. */ + assertion. For a variable lookbehind, check its end point. */ + + case OP_ASSERTBACK: + if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) + RRETURN(MATCH_NOMATCH); + /* Fall through */ case OP_ASSERT: - case OP_ASSERTBACK: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; Feptr = P->eptr; /* Fall through */ @@ -5816,10 +6031,15 @@ fprintf(stderr, "++ op=%d\n", *Fecode); break; /* A matching negative assertion returns MATCH, which is turned into - NOMATCH at the assertion level. */ + NOMATCH at the assertion level. For a variable lookbehind, check its end + point. */ + + case OP_ASSERTBACK_NOT: + if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) + RRETURN(MATCH_NOMATCH); + /* Fall through */ case OP_ASSERT_NOT: - case OP_ASSERTBACK_NOT: RRETURN(MATCH_MATCH); /* At the end of a script run, apply the script-checking rules. This code @@ -5830,9 +6050,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (!PRIV(script_run)(P->eptr, Feptr, utf)) RRETURN(MATCH_NOMATCH); break; - /* Whole-pattern recursion is coded as a recurse into group 0, so it - won't be picked up here. Instead, we catch it when the OP_END is reached. - Other recursion is handled here. */ + /* Whole-pattern recursion is coded as a recurse into group 0, and is + handled with OP_BRA above. Other recursion is handled here. */ case OP_CBRA: case OP_CBRAPOS: @@ -5847,7 +6066,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); { P = (heapframe *)((char *)N - frame_size); memcpy((char *)F + offsetof(heapframe, ovector), P->ovector, - P->offset_top * sizeof(PCRE2_SIZE)); + Foffset_top * sizeof(PCRE2_SIZE)); Foffset_top = P->offset_top; Fcapture_last = P->capture_last; Fcurrent_recurse = P->current_recurse; @@ -5930,10 +6149,10 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS; /* Fall through */ - /* Unconditional end of subject assertion (\z) */ + /* Unconditional end of subject assertion (\z). */ case OP_EOD: - if (Feptr < mb->end_subject) RRETURN(MATCH_NOMATCH); + if (Feptr < mb->true_end_subject) RRETURN(MATCH_NOMATCH); if (mb->partial != 0) { mb->hitend = TRUE; @@ -6045,6 +6264,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: if (Feptr == mb->check_subject) prev_is_word = FALSE; else { PCRE2_SPTR lastptr = Feptr - 1; @@ -6059,13 +6280,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode); fc = *lastptr; if (lastptr < mb->start_used_ptr) mb->start_used_ptr = lastptr; #ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) + if (Fop == OP_UCP_WORD_BOUNDARY || Fop == OP_NOT_UCP_WORD_BOUNDARY) { - if (fc == '_') prev_is_word = TRUE; else - { - int cat = UCD_CATEGORY(fc); - prev_is_word = (cat == ucp_L || cat == ucp_N); - } + int chartype = UCD_CHARTYPE(fc); + int category = PRIV(ucp_gentype)[chartype]; + prev_is_word = (category == ucp_L || category == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc); } else #endif /* SUPPORT_UNICODE */ @@ -6093,13 +6313,12 @@ fprintf(stderr, "++ op=%d\n", *Fecode); fc = *Feptr; if (nextptr > mb->last_used_ptr) mb->last_used_ptr = nextptr; #ifdef SUPPORT_UNICODE - if ((mb->poptions & PCRE2_UCP) != 0) + if (Fop == OP_UCP_WORD_BOUNDARY || Fop == OP_NOT_UCP_WORD_BOUNDARY) { - if (fc == '_') cur_is_word = TRUE; else - { - int cat = UCD_CATEGORY(fc); - cur_is_word = (cat == ucp_L || cat == ucp_N); - } + int chartype = UCD_CHARTYPE(fc); + int category = PRIV(ucp_gentype)[chartype]; + cur_is_word = (category == ucp_L || category == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc); } else #endif /* SUPPORT_UNICODE */ @@ -6108,7 +6327,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); /* Now see if the situation is what we want */ - if ((*Fecode++ == OP_WORD_BOUNDARY)? + if ((*Fecode++ == OP_WORD_BOUNDARY || Fop == OP_UCP_WORD_BOUNDARY)? cur_is_word == prev_is_word : cur_is_word != prev_is_word) RRETURN(MATCH_NOMATCH); break; @@ -6254,7 +6473,7 @@ F = (heapframe *)((char *)F - Fback_frame); /* Backtrack */ mb->cb->callout_flags |= PCRE2_CALLOUT_BACKTRACK; /* Note for callouts */ #ifdef DEBUG_SHOW_RMATCH -fprintf(stderr, "++ RETURN %d to %d\n", rrc, Freturn_id); +fprintf(stderr, "++ RETURN %d to RM%d\n", rrc, Freturn_id); #endif switch (Freturn_id) @@ -6263,7 +6482,7 @@ switch (Freturn_id) LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16) LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24) LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32) - LBL(33) LBL(34) LBL(35) LBL(36) + LBL(33) LBL(34) LBL(35) LBL(36) LBL(37) #ifdef SUPPORT_WIDE_CHARS LBL(100) LBL(101) @@ -6551,6 +6770,7 @@ if (use_jit) match_data, mcontext); if (rc != PCRE2_ERROR_JIT_BADOPTION) { + match_data->subject_length = length; if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0) { length = CU2BYTES(length + was_zero_terminated); @@ -6719,7 +6939,7 @@ if (mcontext == NULL) else mb->memctl = mcontext->memctl; anchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0; -firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0; +firstline = !anchored && (re->overall_options & PCRE2_FIRSTLINE) != 0; startline = (re->flags & PCRE2_STARTLINE) != 0; bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)? true_end_subject : subject + mcontext->offset_limit; @@ -6742,6 +6962,7 @@ mb->callout_data = mcontext->callout_data; mb->start_subject = subject; mb->start_offset = start_offset; mb->end_subject = end_subject; +mb->true_end_subject = true_end_subject; mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0; mb->allowemptypartial = (re->max_lookbehind > 0) || (re->flags & PCRE2_MATCH_EMPTY) != 0; @@ -6801,7 +7022,7 @@ the pattern. It is not used at all if there are no capturing parentheses. frame_size is the total size of each frame match_data->heapframes is the pointer to the frames vector - match_data->heapframes_size is the total size of the vector + match_data->heapframes_size is the allocated size of the vector We must pad the frame_size for alignment to ensure subsequent frames are as aligned as heapframe. Whilst ovector is word-aligned due to being a PCRE2_SIZE @@ -6816,7 +7037,7 @@ frame_size = (offsetof(heapframe, ovector) + smaller. */ mb->heap_limit = ((mcontext->heap_limit < re->limit_heap)? - mcontext->heap_limit : re->limit_heap) * 1024; + mcontext->heap_limit : re->limit_heap); mb->match_limit = (mcontext->match_limit < re->limit_match)? mcontext->match_limit : re->limit_match; @@ -6827,19 +7048,19 @@ mb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)? /* If a pattern has very many capturing parentheses, the frame size may be very large. Set the initial frame vector size to ensure that there are at least 10 available frames, but enforce a minimum of START_FRAMES_SIZE. If this is -greater than the heap limit, get as large a vector as possible. Always round -the size to a multiple of the frame size. */ +greater than the heap limit, get as large a vector as possible. */ heapframes_size = frame_size * 10; if (heapframes_size < START_FRAMES_SIZE) heapframes_size = START_FRAMES_SIZE; -if (heapframes_size > mb->heap_limit) +if (heapframes_size / 1024 > mb->heap_limit) { - if (frame_size > mb->heap_limit ) return PCRE2_ERROR_HEAPLIMIT; - heapframes_size = mb->heap_limit; + PCRE2_SIZE max_size = 1024 * mb->heap_limit; + if (max_size < frame_size) return PCRE2_ERROR_HEAPLIMIT; + heapframes_size = max_size; } /* If an existing frame vector in the match_data block is large enough, we can -use it.Otherwise, free any pre-existing vector and get a new one. */ +use it. Otherwise, free any pre-existing vector and get a new one. */ if (match_data->heapframes_size < heapframes_size) { @@ -7286,9 +7507,17 @@ for(;;) mb->end_offset_top = 0; mb->skip_arg_count = 0; +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ Calling match()\n"); +#endif + rc = match(start_match, mb->start_code, re->top_bracket, frame_size, match_data, mb); +#ifdef DEBUG_SHOW_OPS + fprintf(stderr, "++ match() returned %d\n\n", rc); +#endif + if (mb->hitend && start_partial == NULL) { start_partial = mb->start_used_ptr; @@ -7436,6 +7665,7 @@ if (utf && end_subject != true_end_subject && if (start_match >= true_end_subject) { rc = MATCH_NOMATCH; /* In case it was partial */ + match_partial = NULL; break; } @@ -7485,6 +7715,7 @@ if (rc == MATCH_MATCH) { match_data->rc = ((int)mb->end_offset_top >= 2 * match_data->oveccount)? 0 : (int)mb->end_offset_top/2 + 1; + match_data->subject_length = length; match_data->startchar = start_match - subject; match_data->leftchar = mb->start_used_ptr - subject; match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)? @@ -7499,6 +7730,7 @@ if (rc == MATCH_MATCH) match_data->flags |= PCRE2_MD_COPIED_SUBJECT; } else match_data->subject = subject; + return match_data->rc; } @@ -7520,6 +7752,7 @@ PCRE2_ERROR_PARTIAL. */ else if (match_partial != NULL) { match_data->subject = subject; + match_data->subject_length = length; match_data->ovector[0] = match_partial - subject; match_data->ovector[1] = end_subject - subject; match_data->startchar = match_partial - subject; diff --git a/src/3rdparty/pcre2/src/pcre2_match_data.c b/src/3rdparty/pcre2/src/pcre2_match_data.c index fa129b8bc5e..757dab9df51 100644 --- a/src/3rdparty/pcre2/src/pcre2_match_data.c +++ b/src/3rdparty/pcre2/src/pcre2_match_data.c @@ -170,4 +170,16 @@ return offsetof(pcre2_match_data, ovector) + 2 * (match_data->oveccount) * sizeof(PCRE2_SIZE); } + + +/************************************************* +* Get heapframes size * +*************************************************/ + +PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION +pcre2_get_match_data_heapframes_size(pcre2_match_data *match_data) +{ +return match_data->heapframes_size; +} + /* End of pcre2_match_data.c */ diff --git a/src/3rdparty/pcre2/src/pcre2_study.c b/src/3rdparty/pcre2/src/pcre2_study.c index 4db3ad11842..792e696dad7 100644 --- a/src/3rdparty/pcre2/src/pcre2_study.c +++ b/src/3rdparty/pcre2/src/pcre2_study.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2021 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -256,6 +256,7 @@ for (;;) /* Skip over things that don't match chars */ case OP_REVERSE: + case OP_VREVERSE: case OP_CREF: case OP_DNCREF: case OP_RREF: @@ -273,6 +274,8 @@ for (;;) case OP_DOLLM: case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: cc += PRIV(OP_lengths)[*cc]; break; @@ -976,6 +979,7 @@ do while (try_next) /* Loop for items in this branch */ { int rc; + PCRE2_SPTR ncode; uint8_t *classmap = NULL; #ifdef SUPPORT_WIDE_CHARS PCRE2_UCHAR xclassflags; @@ -1054,6 +1058,7 @@ do case OP_REF: case OP_REFI: case OP_REVERSE: + case OP_VREVERSE: case OP_RREF: case OP_SCOND: case OP_SET_SOM: @@ -1101,13 +1106,100 @@ do case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: tcode++; break; - /* If we hit a bracket or a positive lookahead assertion, recurse to set - bits from within the subpattern. If it can't find anything, we have to - give up. If it finds some mandatory character(s), we are done for this - branch. Otherwise, carry on scanning after the subpattern. */ + /* For a positive lookahead assertion, inspect what immediately follows, + ignoring intermediate assertions and callouts. If the next item is one + that sets a mandatory character, skip this assertion. Otherwise, treat it + the same as other bracket groups. */ + + case OP_ASSERT: + case OP_ASSERT_NA: + ncode = tcode + GET(tcode, 1); + while (*ncode == OP_ALT) ncode += GET(ncode, 1); + ncode += 1 + LINK_SIZE; + + /* Skip irrelevant items */ + + for (BOOL done = FALSE; !done;) + { + switch (*ncode) + { + case OP_ASSERT: + case OP_ASSERT_NOT: + case OP_ASSERTBACK: + case OP_ASSERTBACK_NOT: + case OP_ASSERT_NA: + case OP_ASSERTBACK_NA: + ncode += GET(ncode, 1); + while (*ncode == OP_ALT) ncode += GET(ncode, 1); + ncode += 1 + LINK_SIZE; + break; + + case OP_WORD_BOUNDARY: + case OP_NOT_WORD_BOUNDARY: + case OP_UCP_WORD_BOUNDARY: + case OP_NOT_UCP_WORD_BOUNDARY: + ncode++; + break; + + case OP_CALLOUT: + ncode += PRIV(OP_lengths)[OP_CALLOUT]; + break; + + case OP_CALLOUT_STR: + ncode += GET(ncode, 1 + 2*LINK_SIZE); + break; + + default: + done = TRUE; + break; + } + } + + /* Now check the next significant item. */ + + switch(*ncode) + { + default: + break; + + case OP_PROP: + if (ncode[1] != PT_CLIST) break; + /* Fall through */ + case OP_ANYNL: + case OP_CHAR: + case OP_CHARI: + case OP_EXACT: + case OP_EXACTI: + case OP_HSPACE: + case OP_MINPLUS: + case OP_MINPLUSI: + case OP_PLUS: + case OP_PLUSI: + case OP_POSPLUS: + case OP_POSPLUSI: + case OP_VSPACE: + /* Note that these types will only be present in non-UCP mode. */ + case OP_DIGIT: + case OP_NOT_DIGIT: + case OP_WORDCHAR: + case OP_NOT_WORDCHAR: + case OP_WHITESPACE: + case OP_NOT_WHITESPACE: + tcode = ncode; + continue; /* With the following significant opcode */ + } + /* Fall through */ + + /* For a group bracket or a positive assertion without an immediately + following mandatory setting, recurse to set bits from within the + subpattern. If it can't find anything, we have to give up. If it finds + some mandatory character(s), we are done for this branch. Otherwise, + carry on scanning after the subpattern. */ case OP_BRA: case OP_SBRA: @@ -1119,8 +1211,6 @@ do case OP_SCBRAPOS: case OP_ONCE: case OP_SCRIPT_RUN: - case OP_ASSERT: - case OP_ASSERT_NA: rc = set_start_bits(re, tcode, utf, ucp, depthptr); if (rc == SSB_DONE) { diff --git a/src/3rdparty/pcre2/src/pcre2_substring.c b/src/3rdparty/pcre2/src/pcre2_substring.c index ddf5774e150..14e919dce93 100644 --- a/src/3rdparty/pcre2/src/pcre2_substring.c +++ b/src/3rdparty/pcre2/src/pcre2_substring.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2018 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -309,6 +309,7 @@ Returns: if successful: 0 PCRE2_ERROR_NOSUBSTRING: no such substring PCRE2_ERROR_UNAVAILABLE: ovector is too small PCRE2_ERROR_UNSET: substring is not set + PCRE2_ERROR_INVALIDOFFSET: internal error, should not occur */ PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION @@ -341,6 +342,8 @@ else /* Matched using pcre2_dfa_match() */ left = match_data->ovector[stringnumber*2]; right = match_data->ovector[stringnumber*2+1]; +if (left > match_data->subject_length || right > match_data->subject_length) + return PCRE2_ERROR_INVALIDOFFSET; if (sizeptr != NULL) *sizeptr = (left > right)? 0 : right - left; return 0; } @@ -442,7 +445,7 @@ Returns: nothing */ PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION -pcre2_substring_list_free(PCRE2_SPTR *list) +pcre2_substring_list_free(PCRE2_UCHAR **list) { if (list != NULL) { diff --git a/src/3rdparty/pcre2/src/pcre2_ucd.c b/src/3rdparty/pcre2/src/pcre2_ucd.c index 5e0fc37c359..97dbc8b26f3 100644 --- a/src/3rdparty/pcre2/src/pcre2_ucd.c +++ b/src/3rdparty/pcre2/src/pcre2_ucd.c @@ -68,15 +68,15 @@ the tables when not needed. But don't leave a totally empty module because some compilers barf at that. Instead, just supply some small dummy tables. */ #ifndef SUPPORT_UNICODE -const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0 }}; +const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0}}; const uint16_t PRIV(ucd_stage1)[] = {0}; const uint16_t PRIV(ucd_stage2)[] = {0}; const uint32_t PRIV(ucd_caseless_sets)[] = {0}; #else -/* Total size: 111116 bytes, block size: 128. */ +/* Total size: 112564 bytes, block size: 128. */ -const char *PRIV(unicode_version) = "14.0.0"; +const char *PRIV(unicode_version) = "15.0.0"; /* When recompiling tables with a new Unicode version, please check the types in this structure definition with those in pcre2_internal.h (the actual field @@ -152,16 +152,16 @@ decimal digits. It is used to ensure that all the digits in a script run come from the same set. */ const uint32_t PRIV(ucd_digit_sets)[] = { - 66, /* Number of subsequent values */ + 68, /* Number of subsequent values */ 0x00039, 0x00669, 0x006f9, 0x007c9, 0x0096f, 0x009ef, 0x00a6f, 0x00aef, 0x00b6f, 0x00bef, 0x00c6f, 0x00cef, 0x00d6f, 0x00def, 0x00e59, 0x00ed9, 0x00f29, 0x01049, 0x01099, 0x017e9, 0x01819, 0x0194f, 0x019d9, 0x01a89, 0x01a99, 0x01b59, 0x01bb9, 0x01c49, 0x01c59, 0x0a629, 0x0a8d9, 0x0a909, 0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x1106f, 0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, 0x116c9, - 0x11739, 0x118e9, 0x11959, 0x11c59, 0x11d59, 0x11da9, 0x16a69, 0x16ac9, - 0x16b59, 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9, - 0x1e959, 0x1fbf9, + 0x11739, 0x118e9, 0x11959, 0x11c59, 0x11d59, 0x11da9, 0x11f59, 0x16a69, + 0x16ac9, 0x16b59, 0x1d7d7, 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, + 0x1e2f9, 0x1e4f9, 0x1e959, 0x1fbf9, }; /* This vector is a list of script bitsets for the Script Extension property. @@ -323,6 +323,7 @@ const uint32_t PRIV(ucd_boolprop_sets)[] = { 0x21004024u, 0x00040000u, 0x20808004u, 0x00040000u, 0x60800944u, 0x000c0004u, + 0x60800064u, 0x000c0004u, 0x60802004u, 0x000c0000u, 0x60800344u, 0x000c8000u, 0x22808000u, 0x00040000u, @@ -334,7 +335,6 @@ const uint32_t PRIV(ucd_boolprop_sets)[] = { 0x01008020u, 0x00000000u, 0x21408024u, 0x00040000u, 0x00808000u, 0x00000000u, - 0x60800064u, 0x000c0004u, 0x60800044u, 0x000c1004u, 0x60800064u, 0x000c1004u, 0x01002020u, 0x00000001u, @@ -424,7 +424,7 @@ offset to multichar other cases or zero (8 bits), offset to other case or zero (32 bits, signed), bidi class (5 bits) and script extension (11 bits) packed into a 16-bit field, and offset in binary properties table (16 bits). */ -const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ +const ucd_record PRIV(ucd_records)[] = { /* 17076 bytes, record size 12 */ { 69, 0, 2, 0, 0, 6144, 2, }, /* 0 */ { 69, 0, 2, 0, 0, 43008, 4, }, /* 1 */ { 69, 0, 1, 0, 0, 4096, 4, }, /* 2 */ @@ -498,7 +498,7 @@ const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ { 0, 5, 12, 0, 0, 18432, 60, }, /* 70 */ { 0, 5, 12, 0, 0, 18432, 80, }, /* 71 */ { 0, 9, 12, 0, -121, 18432, 74, }, /* 72 */ - { 0, 5, 12, 1, -268, 18432, 70, }, /* 73 */ + { 0, 5, 12, 1, 0, 18432, 70, }, /* 73 */ { 0, 5, 12, 0, 195, 18432, 76, }, /* 74 */ { 0, 9, 12, 0, 210, 18432, 74, }, /* 75 */ { 0, 9, 12, 0, 206, 18432, 74, }, /* 76 */ @@ -819,57 +819,57 @@ const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ { 11, 23, 12, 0, 0, 14336, 68, }, /* 391 */ { 12, 12, 3, 0, 0, 26624, 130, }, /* 392 */ { 12, 10, 5, 0, 0, 18432, 144, }, /* 393 */ - { 12, 12, 3, 0, 0, 26624, 102, }, /* 394 */ - { 12, 7, 12, 0, 0, 18432, 82, }, /* 395 */ - { 12, 12, 3, 0, 0, 26624, 96, }, /* 396 */ - { 12, 12, 3, 0, 0, 26624, 146, }, /* 397 */ - { 12, 13, 12, 0, 0, 18432, 138, }, /* 398 */ - { 12, 21, 12, 0, 0, 18432, 68, }, /* 399 */ - { 12, 15, 12, 0, 0, 28672, 68, }, /* 400 */ - { 12, 26, 12, 0, 0, 18432, 68, }, /* 401 */ - { 13, 7, 12, 0, 0, 18432, 82, }, /* 402 */ - { 13, 12, 3, 0, 0, 26624, 130, }, /* 403 */ - { 13, 10, 5, 0, 0, 18432, 144, }, /* 404 */ - { 13, 21, 12, 0, 0, 18432, 68, }, /* 405 */ - { 13, 12, 3, 0, 0, 26624, 96, }, /* 406 */ - { 13, 12, 3, 0, 0, 18432, 130, }, /* 407 */ - { 13, 10, 3, 0, 0, 18432, 148, }, /* 408 */ - { 13, 12, 3, 0, 0, 26624, 146, }, /* 409 */ - { 13, 13, 12, 0, 0, 18528, 138, }, /* 410 */ - { 14, 12, 3, 0, 0, 26624, 130, }, /* 411 */ - { 14, 10, 5, 0, 0, 18432, 144, }, /* 412 */ - { 14, 7, 12, 0, 0, 18432, 82, }, /* 413 */ - { 14, 12, 3, 0, 0, 26624, 146, }, /* 414 */ - { 14, 10, 3, 0, 0, 18432, 148, }, /* 415 */ - { 14, 7, 4, 0, 0, 18432, 82, }, /* 416 */ - { 14, 26, 12, 0, 0, 18432, 68, }, /* 417 */ - { 14, 15, 12, 0, 0, 18432, 68, }, /* 418 */ - { 14, 13, 12, 0, 0, 18432, 138, }, /* 419 */ - { 15, 12, 3, 0, 0, 26624, 130, }, /* 420 */ - { 15, 10, 5, 0, 0, 18432, 144, }, /* 421 */ - { 15, 7, 12, 0, 0, 18432, 82, }, /* 422 */ - { 15, 12, 3, 0, 0, 26624, 146, }, /* 423 */ - { 15, 10, 3, 0, 0, 18432, 148, }, /* 424 */ - { 15, 13, 12, 0, 0, 18432, 138, }, /* 425 */ - { 15, 21, 12, 0, 0, 18432, 68, }, /* 426 */ - { 72, 7, 12, 0, 0, 18432, 82, }, /* 427 */ - { 72, 12, 3, 0, 0, 26624, 130, }, /* 428 */ - { 72, 7, 5, 0, 0, 18432, 152, }, /* 429 */ - { 72, 12, 3, 0, 0, 26624, 154, }, /* 430 */ - { 69, 23, 12, 0, 0, 14336, 68, }, /* 431 */ - { 72, 7, 12, 0, 0, 18432, 156, }, /* 432 */ - { 72, 6, 12, 0, 0, 18432, 136, }, /* 433 */ - { 72, 12, 3, 0, 0, 26624, 96, }, /* 434 */ - { 72, 21, 12, 0, 0, 18432, 68, }, /* 435 */ - { 72, 13, 12, 0, 0, 18432, 138, }, /* 436 */ - { 72, 21, 12, 0, 0, 18432, 106, }, /* 437 */ - { 73, 7, 12, 0, 0, 18432, 82, }, /* 438 */ - { 73, 12, 3, 0, 0, 26624, 130, }, /* 439 */ - { 73, 7, 5, 0, 0, 18432, 152, }, /* 440 */ - { 73, 12, 3, 0, 0, 26624, 146, }, /* 441 */ - { 73, 7, 12, 0, 0, 18432, 156, }, /* 442 */ - { 73, 6, 12, 0, 0, 18432, 136, }, /* 443 */ - { 73, 12, 3, 0, 0, 26624, 96, }, /* 444 */ + { 12, 7, 12, 0, 0, 18432, 82, }, /* 394 */ + { 12, 12, 3, 0, 0, 26624, 96, }, /* 395 */ + { 12, 12, 3, 0, 0, 26624, 146, }, /* 396 */ + { 12, 13, 12, 0, 0, 18432, 138, }, /* 397 */ + { 12, 21, 12, 0, 0, 18432, 68, }, /* 398 */ + { 12, 15, 12, 0, 0, 28672, 68, }, /* 399 */ + { 12, 26, 12, 0, 0, 18432, 68, }, /* 400 */ + { 13, 7, 12, 0, 0, 18432, 82, }, /* 401 */ + { 13, 12, 3, 0, 0, 26624, 130, }, /* 402 */ + { 13, 10, 5, 0, 0, 18432, 144, }, /* 403 */ + { 13, 21, 12, 0, 0, 18432, 68, }, /* 404 */ + { 13, 12, 3, 0, 0, 26624, 96, }, /* 405 */ + { 13, 12, 3, 0, 0, 18432, 130, }, /* 406 */ + { 13, 10, 3, 0, 0, 18432, 148, }, /* 407 */ + { 13, 12, 3, 0, 0, 26624, 146, }, /* 408 */ + { 13, 13, 12, 0, 0, 18528, 138, }, /* 409 */ + { 14, 12, 3, 0, 0, 26624, 130, }, /* 410 */ + { 14, 10, 5, 0, 0, 18432, 144, }, /* 411 */ + { 14, 7, 12, 0, 0, 18432, 82, }, /* 412 */ + { 14, 12, 3, 0, 0, 26624, 146, }, /* 413 */ + { 14, 10, 3, 0, 0, 18432, 148, }, /* 414 */ + { 14, 7, 4, 0, 0, 18432, 82, }, /* 415 */ + { 14, 26, 12, 0, 0, 18432, 68, }, /* 416 */ + { 14, 15, 12, 0, 0, 18432, 68, }, /* 417 */ + { 14, 13, 12, 0, 0, 18432, 138, }, /* 418 */ + { 15, 12, 3, 0, 0, 26624, 130, }, /* 419 */ + { 15, 10, 5, 0, 0, 18432, 144, }, /* 420 */ + { 15, 7, 12, 0, 0, 18432, 82, }, /* 421 */ + { 15, 12, 3, 0, 0, 26624, 146, }, /* 422 */ + { 15, 10, 3, 0, 0, 18432, 148, }, /* 423 */ + { 15, 13, 12, 0, 0, 18432, 138, }, /* 424 */ + { 15, 21, 12, 0, 0, 18432, 68, }, /* 425 */ + { 72, 7, 12, 0, 0, 18432, 82, }, /* 426 */ + { 72, 12, 3, 0, 0, 26624, 130, }, /* 427 */ + { 72, 7, 5, 0, 0, 18432, 152, }, /* 428 */ + { 72, 12, 3, 0, 0, 26624, 154, }, /* 429 */ + { 69, 23, 12, 0, 0, 14336, 68, }, /* 430 */ + { 72, 7, 12, 0, 0, 18432, 156, }, /* 431 */ + { 72, 6, 12, 0, 0, 18432, 136, }, /* 432 */ + { 72, 12, 3, 0, 0, 26624, 96, }, /* 433 */ + { 72, 21, 12, 0, 0, 18432, 68, }, /* 434 */ + { 72, 13, 12, 0, 0, 18432, 138, }, /* 435 */ + { 72, 21, 12, 0, 0, 18432, 106, }, /* 436 */ + { 73, 7, 12, 0, 0, 18432, 82, }, /* 437 */ + { 73, 12, 3, 0, 0, 26624, 130, }, /* 438 */ + { 73, 7, 5, 0, 0, 18432, 152, }, /* 439 */ + { 73, 12, 3, 0, 0, 26624, 146, }, /* 440 */ + { 73, 7, 12, 0, 0, 18432, 156, }, /* 441 */ + { 73, 6, 12, 0, 0, 18432, 136, }, /* 442 */ + { 73, 12, 3, 0, 0, 26624, 96, }, /* 443 */ + { 73, 12, 3, 0, 0, 26624, 102, }, /* 444 */ { 73, 13, 12, 0, 0, 18432, 138, }, /* 445 */ { 74, 7, 12, 0, 0, 18432, 82, }, /* 446 */ { 74, 26, 12, 0, 0, 18432, 68, }, /* 447 */ @@ -884,431 +884,431 @@ const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ { 74, 12, 3, 0, 0, 26624, 130, }, /* 456 */ { 74, 12, 3, 0, 0, 26624, 162, }, /* 457 */ { 74, 10, 5, 0, 0, 18432, 144, }, /* 458 */ - { 74, 12, 3, 0, 0, 26624, 146, }, /* 459 */ - { 69, 26, 12, 0, 0, 18432, 68, }, /* 460 */ - { 16, 7, 12, 0, 0, 18432, 82, }, /* 461 */ - { 16, 10, 12, 0, 0, 18432, 144, }, /* 462 */ - { 16, 12, 3, 0, 0, 26624, 130, }, /* 463 */ - { 16, 10, 5, 0, 0, 18432, 144, }, /* 464 */ - { 16, 12, 3, 0, 0, 26624, 96, }, /* 465 */ - { 16, 12, 3, 0, 0, 26624, 146, }, /* 466 */ - { 16, 13, 12, 0, 0, 18549, 138, }, /* 467 */ - { 16, 21, 12, 0, 0, 18432, 124, }, /* 468 */ - { 16, 21, 12, 0, 0, 18432, 68, }, /* 469 */ - { 16, 10, 12, 0, 0, 18432, 164, }, /* 470 */ - { 16, 12, 3, 0, 0, 26624, 128, }, /* 471 */ - { 16, 13, 12, 0, 0, 18432, 138, }, /* 472 */ - { 16, 26, 12, 0, 0, 18432, 68, }, /* 473 */ - { 17, 9, 12, 0, 7264, 18432, 74, }, /* 474 */ - { 17, 5, 12, 0, 3008, 18432, 166, }, /* 475 */ - { 69, 21, 12, 0, 0, 18510, 68, }, /* 476 */ - { 17, 6, 12, 0, 0, 18432, 142, }, /* 477 */ - { 18, 7, 6, 0, 0, 18432, 82, }, /* 478 */ - { 18, 7, 6, 0, 0, 18432, 168, }, /* 479 */ - { 18, 7, 7, 0, 0, 18432, 168, }, /* 480 */ - { 18, 7, 7, 0, 0, 18432, 82, }, /* 481 */ - { 18, 7, 8, 0, 0, 18432, 82, }, /* 482 */ - { 75, 7, 12, 0, 0, 18432, 82, }, /* 483 */ - { 75, 12, 3, 0, 0, 26624, 96, }, /* 484 */ - { 75, 21, 12, 0, 0, 18432, 68, }, /* 485 */ - { 75, 21, 12, 0, 0, 18432, 106, }, /* 486 */ - { 75, 21, 12, 0, 0, 18432, 124, }, /* 487 */ - { 75, 15, 12, 0, 0, 18432, 138, }, /* 488 */ - { 75, 15, 12, 0, 0, 18432, 68, }, /* 489 */ - { 75, 26, 12, 0, 0, 28672, 68, }, /* 490 */ - { 76, 9, 12, 0, 38864, 18432, 170, }, /* 491 */ - { 76, 9, 12, 0, 8, 18432, 170, }, /* 492 */ - { 76, 5, 12, 0, -8, 18432, 70, }, /* 493 */ - { 77, 17, 12, 0, 0, 28672, 126, }, /* 494 */ - { 77, 7, 12, 0, 0, 18432, 82, }, /* 495 */ - { 77, 26, 12, 0, 0, 18432, 68, }, /* 496 */ - { 77, 21, 12, 0, 0, 18432, 124, }, /* 497 */ - { 78, 29, 12, 0, 0, 45056, 52, }, /* 498 */ - { 78, 7, 12, 0, 0, 18432, 82, }, /* 499 */ - { 78, 22, 12, 0, 0, 28672, 158, }, /* 500 */ - { 78, 18, 12, 0, 0, 28672, 158, }, /* 501 */ - { 79, 7, 12, 0, 0, 18432, 82, }, /* 502 */ - { 69, 21, 12, 0, 0, 18432, 106, }, /* 503 */ - { 79, 14, 12, 0, 0, 18432, 82, }, /* 504 */ - { 25, 7, 12, 0, 0, 18432, 82, }, /* 505 */ - { 25, 12, 3, 0, 0, 26624, 130, }, /* 506 */ - { 25, 12, 3, 0, 0, 26624, 146, }, /* 507 */ - { 25, 10, 5, 0, 0, 18432, 172, }, /* 508 */ - { 26, 7, 12, 0, 0, 18432, 82, }, /* 509 */ - { 26, 12, 3, 0, 0, 26624, 130, }, /* 510 */ - { 26, 10, 5, 0, 0, 18432, 174, }, /* 511 */ - { 69, 21, 12, 0, 0, 18573, 124, }, /* 512 */ - { 27, 7, 12, 0, 0, 18432, 82, }, /* 513 */ - { 27, 12, 3, 0, 0, 26624, 130, }, /* 514 */ - { 28, 7, 12, 0, 0, 18432, 82, }, /* 515 */ - { 28, 12, 3, 0, 0, 26624, 130, }, /* 516 */ - { 80, 7, 12, 0, 0, 18432, 82, }, /* 517 */ - { 80, 7, 12, 0, 0, 18432, 140, }, /* 518 */ - { 80, 12, 3, 0, 0, 26624, 100, }, /* 519 */ - { 80, 10, 5, 0, 0, 18432, 144, }, /* 520 */ - { 80, 12, 3, 0, 0, 26624, 130, }, /* 521 */ - { 80, 12, 3, 0, 0, 26624, 96, }, /* 522 */ - { 80, 12, 3, 0, 0, 26624, 146, }, /* 523 */ - { 80, 21, 12, 0, 0, 18432, 106, }, /* 524 */ - { 80, 6, 12, 0, 0, 18432, 142, }, /* 525 */ - { 80, 21, 12, 0, 0, 18432, 68, }, /* 526 */ - { 80, 23, 12, 0, 0, 14336, 68, }, /* 527 */ - { 80, 13, 12, 0, 0, 18432, 138, }, /* 528 */ - { 80, 15, 12, 0, 0, 28672, 68, }, /* 529 */ - { 19, 21, 12, 0, 0, 28672, 68, }, /* 530 */ - { 69, 21, 12, 0, 0, 28777, 106, }, /* 531 */ - { 69, 21, 12, 0, 0, 28777, 124, }, /* 532 */ - { 19, 21, 12, 0, 0, 28672, 106, }, /* 533 */ - { 19, 17, 12, 0, 0, 28672, 126, }, /* 534 */ - { 19, 21, 12, 0, 0, 28672, 124, }, /* 535 */ - { 19, 21, 12, 0, 0, 28672, 176, }, /* 536 */ - { 19, 12, 3, 0, 0, 26624, 178, }, /* 537 */ - { 19, 1, 2, 0, 0, 6144, 66, }, /* 538 */ - { 19, 13, 12, 0, 0, 18432, 138, }, /* 539 */ - { 19, 7, 12, 0, 0, 18432, 82, }, /* 540 */ - { 19, 6, 12, 0, 0, 18432, 136, }, /* 541 */ - { 19, 12, 3, 0, 0, 26624, 180, }, /* 542 */ - { 19, 12, 3, 0, 0, 26624, 130, }, /* 543 */ - { 29, 7, 12, 0, 0, 18432, 82, }, /* 544 */ - { 29, 12, 3, 0, 0, 26624, 130, }, /* 545 */ - { 29, 10, 5, 0, 0, 18432, 144, }, /* 546 */ - { 29, 12, 3, 0, 0, 26624, 96, }, /* 547 */ - { 29, 26, 12, 0, 0, 28672, 68, }, /* 548 */ - { 29, 21, 12, 0, 0, 28672, 124, }, /* 549 */ - { 29, 13, 12, 0, 0, 18432, 138, }, /* 550 */ - { 30, 7, 12, 0, 0, 18432, 82, }, /* 551 */ - { 89, 7, 12, 0, 0, 18432, 82, }, /* 552 */ - { 89, 7, 12, 0, 0, 18432, 156, }, /* 553 */ - { 89, 13, 12, 0, 0, 18432, 138, }, /* 554 */ - { 89, 15, 12, 0, 0, 18432, 138, }, /* 555 */ - { 89, 26, 12, 0, 0, 28672, 68, }, /* 556 */ - { 80, 26, 12, 0, 0, 28672, 68, }, /* 557 */ - { 33, 7, 12, 0, 0, 18432, 82, }, /* 558 */ - { 33, 12, 3, 0, 0, 26624, 130, }, /* 559 */ - { 33, 10, 5, 0, 0, 18432, 144, }, /* 560 */ - { 33, 21, 12, 0, 0, 18432, 68, }, /* 561 */ - { 106, 7, 12, 0, 0, 18432, 82, }, /* 562 */ - { 106, 10, 5, 0, 0, 18432, 144, }, /* 563 */ - { 106, 12, 3, 0, 0, 26624, 130, }, /* 564 */ - { 106, 12, 3, 0, 0, 26624, 182, }, /* 565 */ - { 106, 10, 12, 0, 0, 18432, 144, }, /* 566 */ - { 106, 12, 3, 0, 0, 26624, 96, }, /* 567 */ - { 106, 13, 12, 0, 0, 18432, 138, }, /* 568 */ - { 106, 21, 12, 0, 0, 18432, 68, }, /* 569 */ - { 106, 6, 12, 0, 0, 18432, 136, }, /* 570 */ - { 106, 21, 12, 0, 0, 18432, 124, }, /* 571 */ - { 84, 11, 3, 0, 0, 26624, 184, }, /* 572 */ - { 84, 12, 3, 0, 0, 26624, 130, }, /* 573 */ - { 93, 12, 3, 0, 0, 26624, 130, }, /* 574 */ - { 93, 10, 5, 0, 0, 18432, 144, }, /* 575 */ - { 93, 7, 12, 0, 0, 18432, 82, }, /* 576 */ - { 93, 12, 3, 0, 0, 26624, 96, }, /* 577 */ - { 93, 10, 3, 0, 0, 18432, 148, }, /* 578 */ - { 93, 10, 5, 0, 0, 18432, 172, }, /* 579 */ - { 93, 13, 12, 0, 0, 18432, 138, }, /* 580 */ - { 93, 21, 12, 0, 0, 18432, 124, }, /* 581 */ - { 93, 21, 12, 0, 0, 18432, 68, }, /* 582 */ - { 93, 21, 12, 0, 0, 18432, 106, }, /* 583 */ - { 93, 26, 12, 0, 0, 18432, 68, }, /* 584 */ - { 96, 12, 3, 0, 0, 26624, 130, }, /* 585 */ - { 96, 10, 5, 0, 0, 18432, 144, }, /* 586 */ - { 96, 7, 12, 0, 0, 18432, 82, }, /* 587 */ - { 96, 10, 5, 0, 0, 18432, 172, }, /* 588 */ - { 96, 12, 3, 0, 0, 26624, 146, }, /* 589 */ - { 96, 13, 12, 0, 0, 18432, 138, }, /* 590 */ - { 119, 7, 12, 0, 0, 18432, 82, }, /* 591 */ - { 119, 12, 3, 0, 0, 26624, 102, }, /* 592 */ - { 119, 10, 5, 0, 0, 18432, 144, }, /* 593 */ - { 119, 12, 3, 0, 0, 26624, 130, }, /* 594 */ - { 119, 10, 5, 0, 0, 18432, 174, }, /* 595 */ - { 119, 21, 12, 0, 0, 18432, 68, }, /* 596 */ - { 97, 7, 12, 0, 0, 18432, 82, }, /* 597 */ - { 97, 10, 5, 0, 0, 18432, 144, }, /* 598 */ - { 97, 12, 3, 0, 0, 26624, 130, }, /* 599 */ - { 97, 12, 3, 0, 0, 26624, 186, }, /* 600 */ - { 97, 12, 3, 0, 0, 26624, 96, }, /* 601 */ - { 97, 21, 12, 0, 0, 18432, 124, }, /* 602 */ - { 97, 21, 12, 0, 0, 18432, 106, }, /* 603 */ - { 97, 13, 12, 0, 0, 18432, 138, }, /* 604 */ - { 98, 13, 12, 0, 0, 18432, 138, }, /* 605 */ - { 98, 7, 12, 0, 0, 18432, 82, }, /* 606 */ - { 98, 6, 12, 0, 0, 18432, 92, }, /* 607 */ - { 98, 6, 12, 0, 0, 18432, 94, }, /* 608 */ - { 98, 21, 12, 0, 0, 18432, 124, }, /* 609 */ - { 2, 5, 12, 63, -6222, 18432, 70, }, /* 610 */ - { 2, 5, 12, 67, -6221, 18432, 70, }, /* 611 */ - { 2, 5, 12, 71, -6212, 18432, 70, }, /* 612 */ - { 2, 5, 12, 75, -6210, 18432, 70, }, /* 613 */ - { 2, 5, 12, 79, -6210, 18432, 70, }, /* 614 */ - { 2, 5, 12, 79, -6211, 18432, 70, }, /* 615 */ - { 2, 5, 12, 84, -6204, 18432, 70, }, /* 616 */ - { 2, 5, 12, 88, -6180, 18432, 70, }, /* 617 */ - { 2, 5, 12, 108, 35267, 18432, 70, }, /* 618 */ - { 17, 9, 12, 0, -3008, 18432, 74, }, /* 619 */ - { 96, 21, 12, 0, 0, 18432, 68, }, /* 620 */ - { 84, 12, 3, 0, 0, 26762, 96, }, /* 621 */ - { 84, 12, 3, 0, 0, 26630, 96, }, /* 622 */ - { 69, 21, 12, 0, 0, 18498, 188, }, /* 623 */ - { 84, 12, 3, 0, 0, 26666, 96, }, /* 624 */ - { 84, 12, 3, 0, 0, 26696, 96, }, /* 625 */ - { 84, 12, 3, 0, 0, 26780, 96, }, /* 626 */ - { 69, 10, 5, 0, 0, 18474, 160, }, /* 627 */ - { 69, 7, 12, 0, 0, 18501, 82, }, /* 628 */ - { 69, 7, 12, 0, 0, 18474, 82, }, /* 629 */ - { 69, 7, 12, 0, 0, 18438, 82, }, /* 630 */ - { 69, 7, 12, 0, 0, 18594, 82, }, /* 631 */ - { 69, 7, 12, 0, 0, 18498, 82, }, /* 632 */ - { 84, 12, 3, 0, 0, 26750, 96, }, /* 633 */ - { 69, 10, 5, 0, 0, 18435, 160, }, /* 634 */ - { 84, 12, 3, 0, 0, 26690, 96, }, /* 635 */ - { 69, 7, 12, 0, 0, 18453, 82, }, /* 636 */ - { 2, 5, 12, 0, 0, 18432, 60, }, /* 637 */ - { 1, 6, 12, 0, 0, 18432, 88, }, /* 638 */ - { 2, 6, 12, 0, 0, 18432, 190, }, /* 639 */ - { 0, 5, 12, 0, 35332, 18432, 76, }, /* 640 */ - { 0, 5, 12, 0, 3814, 18432, 76, }, /* 641 */ - { 0, 5, 12, 0, 35384, 18432, 76, }, /* 642 */ - { 0, 5, 12, 0, 0, 18432, 192, }, /* 643 */ - { 0, 6, 12, 0, 0, 18432, 190, }, /* 644 */ - { 0, 6, 12, 0, 0, 18432, 194, }, /* 645 */ - { 1, 6, 12, 0, 0, 18432, 190, }, /* 646 */ - { 84, 12, 3, 0, 0, 26636, 102, }, /* 647 */ - { 84, 12, 3, 0, 0, 26687, 96, }, /* 648 */ - { 84, 12, 3, 0, 0, 26648, 96, }, /* 649 */ - { 0, 9, 12, 92, 1, 18432, 74, }, /* 650 */ - { 0, 5, 12, 92, -1, 18432, 76, }, /* 651 */ - { 0, 5, 12, 0, 0, 18432, 70, }, /* 652 */ - { 0, 5, 12, 92, -58, 18432, 70, }, /* 653 */ - { 0, 9, 12, 0, -7615, 18432, 74, }, /* 654 */ - { 1, 5, 12, 0, 8, 18432, 76, }, /* 655 */ - { 1, 9, 12, 0, -8, 18432, 74, }, /* 656 */ - { 1, 5, 12, 0, 74, 18432, 76, }, /* 657 */ - { 1, 5, 12, 0, 86, 18432, 76, }, /* 658 */ - { 1, 5, 12, 0, 100, 18432, 76, }, /* 659 */ - { 1, 5, 12, 0, 128, 18432, 76, }, /* 660 */ - { 1, 5, 12, 0, 112, 18432, 76, }, /* 661 */ - { 1, 5, 12, 0, 126, 18432, 76, }, /* 662 */ - { 1, 5, 12, 0, 8, 18432, 70, }, /* 663 */ - { 1, 8, 12, 0, -8, 18432, 86, }, /* 664 */ - { 1, 5, 12, 0, 0, 18432, 70, }, /* 665 */ - { 1, 5, 12, 0, 9, 18432, 70, }, /* 666 */ - { 1, 9, 12, 0, -74, 18432, 74, }, /* 667 */ - { 1, 8, 12, 0, -9, 18432, 86, }, /* 668 */ - { 1, 5, 12, 21, -7173, 18432, 76, }, /* 669 */ - { 1, 9, 12, 0, -86, 18432, 74, }, /* 670 */ - { 1, 9, 12, 0, -100, 18432, 74, }, /* 671 */ - { 1, 9, 12, 0, -112, 18432, 74, }, /* 672 */ - { 1, 9, 12, 0, -128, 18432, 74, }, /* 673 */ - { 1, 9, 12, 0, -126, 18432, 74, }, /* 674 */ - { 69, 29, 12, 0, 0, 45056, 52, }, /* 675 */ - { 84, 1, 3, 0, 0, 6144, 196, }, /* 676 */ - { 84, 1, 13, 0, 0, 6144, 198, }, /* 677 */ - { 69, 1, 2, 0, 0, 18432, 200, }, /* 678 */ - { 69, 1, 2, 0, 0, 34816, 200, }, /* 679 */ - { 69, 17, 12, 0, 0, 28672, 202, }, /* 680 */ - { 69, 21, 12, 0, 0, 28672, 64, }, /* 681 */ - { 69, 20, 12, 0, 0, 28672, 204, }, /* 682 */ - { 69, 19, 12, 0, 0, 28672, 204, }, /* 683 */ - { 69, 22, 12, 0, 0, 28672, 206, }, /* 684 */ - { 69, 20, 12, 0, 0, 28672, 206, }, /* 685 */ - { 69, 19, 12, 0, 0, 28672, 206, }, /* 686 */ - { 69, 21, 12, 0, 0, 28672, 208, }, /* 687 */ - { 69, 27, 2, 0, 0, 45056, 50, }, /* 688 */ - { 69, 28, 2, 0, 0, 4096, 50, }, /* 689 */ - { 69, 1, 2, 0, 0, 20480, 134, }, /* 690 */ - { 69, 1, 2, 0, 0, 36864, 134, }, /* 691 */ - { 69, 1, 2, 0, 0, 30720, 134, }, /* 692 */ - { 69, 1, 2, 0, 0, 24576, 134, }, /* 693 */ - { 69, 1, 2, 0, 0, 40960, 134, }, /* 694 */ - { 69, 29, 12, 0, 0, 8291, 52, }, /* 695 */ - { 69, 21, 12, 0, 0, 14336, 54, }, /* 696 */ - { 69, 21, 12, 0, 0, 14336, 64, }, /* 697 */ - { 69, 21, 14, 0, 0, 28672, 210, }, /* 698 */ - { 69, 21, 12, 0, 0, 28672, 212, }, /* 699 */ - { 69, 16, 12, 0, 0, 28672, 138, }, /* 700 */ - { 69, 16, 12, 0, 0, 28672, 214, }, /* 701 */ - { 69, 25, 12, 0, 0, 8192, 64, }, /* 702 */ - { 69, 22, 12, 0, 0, 28672, 216, }, /* 703 */ - { 69, 18, 12, 0, 0, 28672, 216, }, /* 704 */ - { 69, 21, 12, 0, 0, 28672, 202, }, /* 705 */ - { 69, 1, 2, 0, 0, 6144, 218, }, /* 706 */ - { 68, 2, 2, 0, 0, 6144, 220, }, /* 707 */ - { 69, 1, 2, 0, 0, 22528, 134, }, /* 708 */ - { 69, 1, 2, 0, 0, 38912, 134, }, /* 709 */ - { 69, 1, 2, 0, 0, 16384, 134, }, /* 710 */ - { 69, 1, 2, 0, 0, 32768, 134, }, /* 711 */ - { 69, 1, 2, 0, 0, 6144, 222, }, /* 712 */ - { 69, 25, 12, 0, 0, 12288, 118, }, /* 713 */ - { 69, 25, 12, 0, 0, 12288, 224, }, /* 714 */ - { 69, 25, 12, 0, 0, 28672, 118, }, /* 715 */ - { 69, 22, 12, 0, 0, 28672, 226, }, /* 716 */ - { 69, 18, 12, 0, 0, 28672, 226, }, /* 717 */ - { 68, 2, 12, 0, 0, 14336, 0, }, /* 718 */ - { 84, 12, 3, 0, 0, 26624, 228, }, /* 719 */ - { 84, 11, 3, 0, 0, 26624, 120, }, /* 720 */ - { 84, 11, 3, 0, 0, 26624, 230, }, /* 721 */ - { 84, 12, 3, 0, 0, 26753, 102, }, /* 722 */ - { 69, 26, 12, 0, 0, 28672, 68, }, /* 723 */ - { 69, 9, 12, 0, 0, 18432, 112, }, /* 724 */ - { 69, 5, 12, 0, 0, 18432, 232, }, /* 725 */ - { 69, 25, 12, 0, 0, 28672, 234, }, /* 726 */ - { 69, 26, 14, 0, 0, 28672, 236, }, /* 727 */ - { 1, 9, 12, 96, -7517, 18432, 74, }, /* 728 */ - { 69, 26, 12, 0, 0, 28672, 118, }, /* 729 */ - { 0, 9, 12, 100, -8383, 18432, 74, }, /* 730 */ - { 0, 9, 12, 104, -8262, 18432, 74, }, /* 731 */ - { 69, 26, 12, 0, 0, 14336, 238, }, /* 732 */ - { 0, 9, 12, 0, 28, 18432, 74, }, /* 733 */ - { 69, 7, 12, 0, 0, 18432, 240, }, /* 734 */ - { 69, 5, 14, 0, 0, 18432, 242, }, /* 735 */ - { 69, 5, 12, 0, 0, 18432, 244, }, /* 736 */ - { 0, 5, 12, 0, -28, 18432, 76, }, /* 737 */ - { 0, 14, 12, 0, 16, 18432, 74, }, /* 738 */ - { 0, 14, 12, 0, -16, 18432, 76, }, /* 739 */ - { 0, 14, 12, 0, 0, 18432, 82, }, /* 740 */ - { 69, 25, 14, 0, 0, 28672, 246, }, /* 741 */ - { 69, 26, 14, 0, 0, 28672, 246, }, /* 742 */ - { 69, 26, 12, 0, 0, 28672, 64, }, /* 743 */ - { 69, 25, 12, 0, 0, 28672, 248, }, /* 744 */ - { 69, 25, 12, 0, 0, 12288, 250, }, /* 745 */ - { 69, 22, 12, 0, 0, 28672, 248, }, /* 746 */ - { 69, 18, 12, 0, 0, 28672, 248, }, /* 747 */ - { 69, 26, 14, 0, 0, 28672, 252, }, /* 748 */ - { 69, 22, 12, 0, 0, 28672, 254, }, /* 749 */ - { 69, 18, 12, 0, 0, 28672, 254, }, /* 750 */ - { 69, 26, 12, 0, 0, 18432, 54, }, /* 751 */ - { 69, 26, 14, 0, 0, 28672, 256, }, /* 752 */ - { 68, 2, 12, 0, 0, 18432, 258, }, /* 753 */ - { 69, 26, 12, 0, 26, 18432, 260, }, /* 754 */ - { 69, 26, 14, 0, 26, 18432, 262, }, /* 755 */ - { 69, 26, 12, 0, -26, 18432, 264, }, /* 756 */ - { 69, 25, 14, 0, 0, 28672, 266, }, /* 757 */ - { 69, 26, 14, 0, 0, 28672, 268, }, /* 758 */ - { 69, 26, 14, 0, 0, 28672, 270, }, /* 759 */ - { 69, 25, 14, 0, 0, 28672, 268, }, /* 760 */ - { 69, 26, 14, 0, 0, 18432, 256, }, /* 761 */ - { 69, 26, 14, 0, 0, 28672, 272, }, /* 762 */ - { 88, 26, 12, 0, 0, 18432, 54, }, /* 763 */ - { 69, 26, 12, 0, 0, 28672, 216, }, /* 764 */ - { 35, 9, 12, 0, 48, 18432, 74, }, /* 765 */ - { 35, 5, 12, 0, -48, 18432, 76, }, /* 766 */ - { 0, 9, 12, 0, -10743, 18432, 74, }, /* 767 */ - { 0, 9, 12, 0, -3814, 18432, 74, }, /* 768 */ - { 0, 9, 12, 0, -10727, 18432, 74, }, /* 769 */ - { 0, 5, 12, 0, -10795, 18432, 76, }, /* 770 */ - { 0, 5, 12, 0, -10792, 18432, 76, }, /* 771 */ - { 0, 9, 12, 0, -10780, 18432, 74, }, /* 772 */ - { 0, 9, 12, 0, -10749, 18432, 74, }, /* 773 */ - { 0, 9, 12, 0, -10783, 18432, 74, }, /* 774 */ - { 0, 9, 12, 0, -10782, 18432, 74, }, /* 775 */ - { 0, 9, 12, 0, -10815, 18432, 74, }, /* 776 */ - { 34, 5, 12, 0, 0, 18432, 60, }, /* 777 */ - { 34, 26, 12, 0, 0, 28672, 68, }, /* 778 */ - { 34, 12, 3, 0, 0, 26624, 96, }, /* 779 */ - { 34, 21, 12, 0, 0, 28672, 68, }, /* 780 */ - { 34, 15, 12, 0, 0, 28672, 68, }, /* 781 */ - { 17, 5, 12, 0, -7264, 18432, 76, }, /* 782 */ - { 90, 7, 12, 0, 0, 18432, 82, }, /* 783 */ - { 90, 6, 12, 0, 0, 18432, 142, }, /* 784 */ - { 90, 21, 12, 0, 0, 18432, 68, }, /* 785 */ - { 90, 12, 3, 0, 0, 26624, 182, }, /* 786 */ - { 2, 12, 3, 0, 0, 26624, 130, }, /* 787 */ - { 69, 20, 12, 0, 0, 28672, 216, }, /* 788 */ - { 69, 19, 12, 0, 0, 28672, 216, }, /* 789 */ - { 69, 6, 12, 0, 0, 28672, 274, }, /* 790 */ - { 69, 21, 12, 0, 0, 28672, 276, }, /* 791 */ - { 69, 21, 12, 0, 0, 28726, 54, }, /* 792 */ - { 23, 26, 12, 0, 0, 28672, 278, }, /* 793 */ - { 69, 26, 12, 0, 0, 28672, 280, }, /* 794 */ - { 69, 26, 12, 0, 0, 28672, 282, }, /* 795 */ - { 69, 21, 12, 0, 0, 28825, 276, }, /* 796 */ - { 69, 21, 12, 0, 0, 28825, 212, }, /* 797 */ - { 69, 21, 12, 0, 0, 28819, 54, }, /* 798 */ - { 23, 6, 12, 0, 0, 18432, 136, }, /* 799 */ - { 69, 7, 12, 0, 0, 18447, 284, }, /* 800 */ - { 23, 14, 12, 0, 0, 18432, 284, }, /* 801 */ - { 69, 22, 12, 0, 0, 28825, 216, }, /* 802 */ - { 69, 18, 12, 0, 0, 28825, 216, }, /* 803 */ - { 69, 22, 12, 0, 0, 28825, 62, }, /* 804 */ - { 69, 18, 12, 0, 0, 28825, 62, }, /* 805 */ - { 69, 26, 12, 0, 0, 28819, 54, }, /* 806 */ - { 69, 17, 12, 0, 0, 28819, 202, }, /* 807 */ - { 69, 22, 12, 0, 0, 28819, 206, }, /* 808 */ - { 69, 18, 12, 0, 0, 28819, 206, }, /* 809 */ - { 84, 12, 3, 0, 0, 26669, 96, }, /* 810 */ - { 18, 10, 3, 0, 0, 18432, 286, }, /* 811 */ - { 69, 17, 14, 0, 0, 28819, 288, }, /* 812 */ - { 69, 6, 12, 0, 0, 18525, 136, }, /* 813 */ - { 69, 26, 12, 0, 0, 28819, 68, }, /* 814 */ - { 23, 6, 12, 0, 0, 18432, 142, }, /* 815 */ - { 69, 7, 12, 0, 0, 18564, 82, }, /* 816 */ - { 69, 21, 14, 0, 0, 28804, 236, }, /* 817 */ - { 69, 26, 12, 0, 0, 28687, 68, }, /* 818 */ - { 20, 7, 12, 0, 0, 18432, 82, }, /* 819 */ - { 84, 12, 3, 0, 0, 26717, 96, }, /* 820 */ - { 69, 24, 12, 0, 0, 28765, 290, }, /* 821 */ - { 20, 6, 12, 0, 0, 18432, 136, }, /* 822 */ - { 69, 17, 12, 0, 0, 28765, 126, }, /* 823 */ - { 21, 7, 12, 0, 0, 18432, 82, }, /* 824 */ - { 69, 21, 12, 0, 0, 28825, 68, }, /* 825 */ - { 69, 6, 12, 0, 0, 18525, 94, }, /* 826 */ - { 21, 6, 12, 0, 0, 18432, 136, }, /* 827 */ - { 22, 7, 12, 0, 0, 18432, 82, }, /* 828 */ - { 18, 7, 12, 0, 0, 18432, 82, }, /* 829 */ - { 18, 7, 12, 0, 0, 18432, 168, }, /* 830 */ - { 69, 26, 12, 0, 0, 18447, 68, }, /* 831 */ - { 69, 15, 12, 0, 0, 18447, 68, }, /* 832 */ - { 18, 26, 12, 0, 0, 18432, 68, }, /* 833 */ - { 18, 26, 12, 0, 0, 28672, 68, }, /* 834 */ - { 69, 15, 12, 0, 0, 18432, 68, }, /* 835 */ - { 69, 26, 14, 0, 0, 18447, 236, }, /* 836 */ - { 21, 26, 12, 0, 0, 18432, 68, }, /* 837 */ - { 23, 7, 12, 0, 0, 18432, 292, }, /* 838 */ - { 24, 7, 12, 0, 0, 18432, 82, }, /* 839 */ - { 24, 6, 12, 0, 0, 18432, 136, }, /* 840 */ - { 24, 26, 12, 0, 0, 28672, 68, }, /* 841 */ - { 111, 7, 12, 0, 0, 18432, 82, }, /* 842 */ - { 111, 6, 12, 0, 0, 18432, 142, }, /* 843 */ - { 111, 21, 12, 0, 0, 18432, 106, }, /* 844 */ - { 111, 21, 12, 0, 0, 18432, 124, }, /* 845 */ - { 99, 7, 12, 0, 0, 18432, 82, }, /* 846 */ - { 99, 6, 12, 0, 0, 18432, 136, }, /* 847 */ - { 99, 21, 12, 0, 0, 28672, 106, }, /* 848 */ - { 99, 21, 12, 0, 0, 28672, 124, }, /* 849 */ - { 99, 13, 12, 0, 0, 18432, 138, }, /* 850 */ - { 2, 9, 12, 108, 1, 18432, 74, }, /* 851 */ - { 2, 5, 12, 108, -35267, 18432, 76, }, /* 852 */ - { 2, 7, 12, 0, 0, 18432, 82, }, /* 853 */ - { 2, 21, 12, 0, 0, 28672, 68, }, /* 854 */ - { 2, 12, 3, 0, 0, 26624, 96, }, /* 855 */ - { 2, 6, 12, 0, 0, 28672, 92, }, /* 856 */ - { 2, 6, 12, 0, 0, 18432, 88, }, /* 857 */ - { 112, 7, 12, 0, 0, 18432, 82, }, /* 858 */ - { 112, 14, 12, 0, 0, 18432, 82, }, /* 859 */ - { 112, 12, 3, 0, 0, 26624, 96, }, /* 860 */ - { 112, 21, 12, 0, 0, 18432, 68, }, /* 861 */ - { 112, 21, 12, 0, 0, 18432, 124, }, /* 862 */ - { 112, 21, 12, 0, 0, 18432, 106, }, /* 863 */ - { 69, 24, 12, 0, 0, 28762, 56, }, /* 864 */ - { 0, 9, 12, 0, -35332, 18432, 74, }, /* 865 */ - { 69, 24, 12, 0, 0, 18432, 56, }, /* 866 */ - { 0, 9, 12, 0, -42280, 18432, 74, }, /* 867 */ - { 0, 5, 12, 0, 48, 18432, 76, }, /* 868 */ - { 0, 9, 12, 0, -42308, 18432, 74, }, /* 869 */ - { 0, 9, 12, 0, -42319, 18432, 74, }, /* 870 */ - { 0, 9, 12, 0, -42315, 18432, 74, }, /* 871 */ - { 0, 9, 12, 0, -42305, 18432, 74, }, /* 872 */ - { 0, 9, 12, 0, -42258, 18432, 74, }, /* 873 */ - { 0, 9, 12, 0, -42282, 18432, 74, }, /* 874 */ - { 0, 9, 12, 0, -42261, 18432, 74, }, /* 875 */ - { 0, 9, 12, 0, 928, 18432, 74, }, /* 876 */ - { 0, 9, 12, 0, -48, 18432, 74, }, /* 877 */ - { 0, 9, 12, 0, -42307, 18432, 74, }, /* 878 */ - { 0, 9, 12, 0, -35384, 18432, 74, }, /* 879 */ - { 0, 6, 12, 0, 0, 18432, 142, }, /* 880 */ + { 74, 12, 3, 0, 0, 26624, 128, }, /* 459 */ + { 74, 12, 3, 0, 0, 26624, 146, }, /* 460 */ + { 69, 26, 12, 0, 0, 18432, 68, }, /* 461 */ + { 16, 7, 12, 0, 0, 18432, 82, }, /* 462 */ + { 16, 10, 12, 0, 0, 18432, 144, }, /* 463 */ + { 16, 12, 3, 0, 0, 26624, 130, }, /* 464 */ + { 16, 10, 5, 0, 0, 18432, 144, }, /* 465 */ + { 16, 12, 3, 0, 0, 26624, 96, }, /* 466 */ + { 16, 12, 3, 0, 0, 26624, 146, }, /* 467 */ + { 16, 13, 12, 0, 0, 18549, 138, }, /* 468 */ + { 16, 21, 12, 0, 0, 18432, 124, }, /* 469 */ + { 16, 21, 12, 0, 0, 18432, 68, }, /* 470 */ + { 16, 10, 12, 0, 0, 18432, 164, }, /* 471 */ + { 16, 12, 3, 0, 0, 26624, 128, }, /* 472 */ + { 16, 13, 12, 0, 0, 18432, 138, }, /* 473 */ + { 16, 26, 12, 0, 0, 18432, 68, }, /* 474 */ + { 17, 9, 12, 0, 7264, 18432, 74, }, /* 475 */ + { 17, 5, 12, 0, 3008, 18432, 166, }, /* 476 */ + { 69, 21, 12, 0, 0, 18510, 68, }, /* 477 */ + { 17, 6, 12, 0, 0, 18432, 168, }, /* 478 */ + { 18, 7, 6, 0, 0, 18432, 82, }, /* 479 */ + { 18, 7, 6, 0, 0, 18432, 170, }, /* 480 */ + { 18, 7, 7, 0, 0, 18432, 170, }, /* 481 */ + { 18, 7, 7, 0, 0, 18432, 82, }, /* 482 */ + { 18, 7, 8, 0, 0, 18432, 82, }, /* 483 */ + { 75, 7, 12, 0, 0, 18432, 82, }, /* 484 */ + { 75, 12, 3, 0, 0, 26624, 96, }, /* 485 */ + { 75, 21, 12, 0, 0, 18432, 68, }, /* 486 */ + { 75, 21, 12, 0, 0, 18432, 106, }, /* 487 */ + { 75, 21, 12, 0, 0, 18432, 124, }, /* 488 */ + { 75, 15, 12, 0, 0, 18432, 138, }, /* 489 */ + { 75, 15, 12, 0, 0, 18432, 68, }, /* 490 */ + { 75, 26, 12, 0, 0, 28672, 68, }, /* 491 */ + { 76, 9, 12, 0, 38864, 18432, 172, }, /* 492 */ + { 76, 9, 12, 0, 8, 18432, 172, }, /* 493 */ + { 76, 5, 12, 0, -8, 18432, 70, }, /* 494 */ + { 77, 17, 12, 0, 0, 28672, 126, }, /* 495 */ + { 77, 7, 12, 0, 0, 18432, 82, }, /* 496 */ + { 77, 26, 12, 0, 0, 18432, 68, }, /* 497 */ + { 77, 21, 12, 0, 0, 18432, 124, }, /* 498 */ + { 78, 29, 12, 0, 0, 45056, 52, }, /* 499 */ + { 78, 7, 12, 0, 0, 18432, 82, }, /* 500 */ + { 78, 22, 12, 0, 0, 28672, 158, }, /* 501 */ + { 78, 18, 12, 0, 0, 28672, 158, }, /* 502 */ + { 79, 7, 12, 0, 0, 18432, 82, }, /* 503 */ + { 69, 21, 12, 0, 0, 18432, 106, }, /* 504 */ + { 79, 14, 12, 0, 0, 18432, 82, }, /* 505 */ + { 25, 7, 12, 0, 0, 18432, 82, }, /* 506 */ + { 25, 12, 3, 0, 0, 26624, 130, }, /* 507 */ + { 25, 12, 3, 0, 0, 26624, 146, }, /* 508 */ + { 25, 10, 5, 0, 0, 18432, 174, }, /* 509 */ + { 26, 7, 12, 0, 0, 18432, 82, }, /* 510 */ + { 26, 12, 3, 0, 0, 26624, 130, }, /* 511 */ + { 26, 10, 5, 0, 0, 18432, 176, }, /* 512 */ + { 69, 21, 12, 0, 0, 18573, 124, }, /* 513 */ + { 27, 7, 12, 0, 0, 18432, 82, }, /* 514 */ + { 27, 12, 3, 0, 0, 26624, 130, }, /* 515 */ + { 28, 7, 12, 0, 0, 18432, 82, }, /* 516 */ + { 28, 12, 3, 0, 0, 26624, 130, }, /* 517 */ + { 80, 7, 12, 0, 0, 18432, 82, }, /* 518 */ + { 80, 7, 12, 0, 0, 18432, 140, }, /* 519 */ + { 80, 12, 3, 0, 0, 26624, 100, }, /* 520 */ + { 80, 10, 5, 0, 0, 18432, 144, }, /* 521 */ + { 80, 12, 3, 0, 0, 26624, 130, }, /* 522 */ + { 80, 12, 3, 0, 0, 26624, 96, }, /* 523 */ + { 80, 12, 3, 0, 0, 26624, 146, }, /* 524 */ + { 80, 21, 12, 0, 0, 18432, 106, }, /* 525 */ + { 80, 6, 12, 0, 0, 18432, 142, }, /* 526 */ + { 80, 21, 12, 0, 0, 18432, 68, }, /* 527 */ + { 80, 23, 12, 0, 0, 14336, 68, }, /* 528 */ + { 80, 13, 12, 0, 0, 18432, 138, }, /* 529 */ + { 80, 15, 12, 0, 0, 28672, 68, }, /* 530 */ + { 19, 21, 12, 0, 0, 28672, 68, }, /* 531 */ + { 69, 21, 12, 0, 0, 28777, 106, }, /* 532 */ + { 69, 21, 12, 0, 0, 28777, 124, }, /* 533 */ + { 19, 21, 12, 0, 0, 28672, 106, }, /* 534 */ + { 19, 17, 12, 0, 0, 28672, 126, }, /* 535 */ + { 19, 21, 12, 0, 0, 28672, 124, }, /* 536 */ + { 19, 21, 12, 0, 0, 28672, 178, }, /* 537 */ + { 19, 12, 3, 0, 0, 26624, 180, }, /* 538 */ + { 19, 1, 2, 0, 0, 6144, 66, }, /* 539 */ + { 19, 13, 12, 0, 0, 18432, 138, }, /* 540 */ + { 19, 7, 12, 0, 0, 18432, 82, }, /* 541 */ + { 19, 6, 12, 0, 0, 18432, 136, }, /* 542 */ + { 19, 12, 3, 0, 0, 26624, 182, }, /* 543 */ + { 19, 12, 3, 0, 0, 26624, 130, }, /* 544 */ + { 29, 7, 12, 0, 0, 18432, 82, }, /* 545 */ + { 29, 12, 3, 0, 0, 26624, 130, }, /* 546 */ + { 29, 10, 5, 0, 0, 18432, 144, }, /* 547 */ + { 29, 12, 3, 0, 0, 26624, 96, }, /* 548 */ + { 29, 26, 12, 0, 0, 28672, 68, }, /* 549 */ + { 29, 21, 12, 0, 0, 28672, 124, }, /* 550 */ + { 29, 13, 12, 0, 0, 18432, 138, }, /* 551 */ + { 30, 7, 12, 0, 0, 18432, 82, }, /* 552 */ + { 89, 7, 12, 0, 0, 18432, 82, }, /* 553 */ + { 89, 7, 12, 0, 0, 18432, 156, }, /* 554 */ + { 89, 13, 12, 0, 0, 18432, 138, }, /* 555 */ + { 89, 15, 12, 0, 0, 18432, 138, }, /* 556 */ + { 89, 26, 12, 0, 0, 28672, 68, }, /* 557 */ + { 80, 26, 12, 0, 0, 28672, 68, }, /* 558 */ + { 33, 7, 12, 0, 0, 18432, 82, }, /* 559 */ + { 33, 12, 3, 0, 0, 26624, 130, }, /* 560 */ + { 33, 10, 5, 0, 0, 18432, 144, }, /* 561 */ + { 33, 21, 12, 0, 0, 18432, 68, }, /* 562 */ + { 106, 7, 12, 0, 0, 18432, 82, }, /* 563 */ + { 106, 10, 5, 0, 0, 18432, 144, }, /* 564 */ + { 106, 12, 3, 0, 0, 26624, 130, }, /* 565 */ + { 106, 12, 3, 0, 0, 26624, 184, }, /* 566 */ + { 106, 10, 12, 0, 0, 18432, 144, }, /* 567 */ + { 106, 12, 3, 0, 0, 26624, 96, }, /* 568 */ + { 106, 13, 12, 0, 0, 18432, 138, }, /* 569 */ + { 106, 21, 12, 0, 0, 18432, 68, }, /* 570 */ + { 106, 6, 12, 0, 0, 18432, 136, }, /* 571 */ + { 106, 21, 12, 0, 0, 18432, 124, }, /* 572 */ + { 84, 11, 3, 0, 0, 26624, 186, }, /* 573 */ + { 84, 12, 3, 0, 0, 26624, 130, }, /* 574 */ + { 93, 12, 3, 0, 0, 26624, 130, }, /* 575 */ + { 93, 10, 5, 0, 0, 18432, 144, }, /* 576 */ + { 93, 7, 12, 0, 0, 18432, 82, }, /* 577 */ + { 93, 12, 3, 0, 0, 26624, 96, }, /* 578 */ + { 93, 10, 3, 0, 0, 18432, 148, }, /* 579 */ + { 93, 10, 5, 0, 0, 18432, 174, }, /* 580 */ + { 93, 13, 12, 0, 0, 18432, 138, }, /* 581 */ + { 93, 21, 12, 0, 0, 18432, 124, }, /* 582 */ + { 93, 21, 12, 0, 0, 18432, 68, }, /* 583 */ + { 93, 21, 12, 0, 0, 18432, 106, }, /* 584 */ + { 93, 26, 12, 0, 0, 18432, 68, }, /* 585 */ + { 96, 12, 3, 0, 0, 26624, 130, }, /* 586 */ + { 96, 10, 5, 0, 0, 18432, 144, }, /* 587 */ + { 96, 7, 12, 0, 0, 18432, 82, }, /* 588 */ + { 96, 10, 5, 0, 0, 18432, 174, }, /* 589 */ + { 96, 12, 3, 0, 0, 26624, 146, }, /* 590 */ + { 96, 13, 12, 0, 0, 18432, 138, }, /* 591 */ + { 119, 7, 12, 0, 0, 18432, 82, }, /* 592 */ + { 119, 12, 3, 0, 0, 26624, 102, }, /* 593 */ + { 119, 10, 5, 0, 0, 18432, 144, }, /* 594 */ + { 119, 12, 3, 0, 0, 26624, 130, }, /* 595 */ + { 119, 10, 5, 0, 0, 18432, 176, }, /* 596 */ + { 119, 21, 12, 0, 0, 18432, 68, }, /* 597 */ + { 97, 7, 12, 0, 0, 18432, 82, }, /* 598 */ + { 97, 10, 5, 0, 0, 18432, 144, }, /* 599 */ + { 97, 12, 3, 0, 0, 26624, 130, }, /* 600 */ + { 97, 12, 3, 0, 0, 26624, 188, }, /* 601 */ + { 97, 12, 3, 0, 0, 26624, 96, }, /* 602 */ + { 97, 21, 12, 0, 0, 18432, 124, }, /* 603 */ + { 97, 21, 12, 0, 0, 18432, 106, }, /* 604 */ + { 97, 13, 12, 0, 0, 18432, 138, }, /* 605 */ + { 98, 13, 12, 0, 0, 18432, 138, }, /* 606 */ + { 98, 7, 12, 0, 0, 18432, 82, }, /* 607 */ + { 98, 6, 12, 0, 0, 18432, 92, }, /* 608 */ + { 98, 6, 12, 0, 0, 18432, 94, }, /* 609 */ + { 98, 21, 12, 0, 0, 18432, 124, }, /* 610 */ + { 2, 5, 12, 63, -6222, 18432, 70, }, /* 611 */ + { 2, 5, 12, 67, -6221, 18432, 70, }, /* 612 */ + { 2, 5, 12, 71, -6212, 18432, 70, }, /* 613 */ + { 2, 5, 12, 75, -6210, 18432, 70, }, /* 614 */ + { 2, 5, 12, 79, -6210, 18432, 70, }, /* 615 */ + { 2, 5, 12, 79, -6211, 18432, 70, }, /* 616 */ + { 2, 5, 12, 84, -6204, 18432, 70, }, /* 617 */ + { 2, 5, 12, 88, -6180, 18432, 70, }, /* 618 */ + { 2, 5, 12, 108, 35267, 18432, 70, }, /* 619 */ + { 17, 9, 12, 0, -3008, 18432, 74, }, /* 620 */ + { 96, 21, 12, 0, 0, 18432, 68, }, /* 621 */ + { 84, 12, 3, 0, 0, 26762, 96, }, /* 622 */ + { 84, 12, 3, 0, 0, 26630, 96, }, /* 623 */ + { 69, 21, 12, 0, 0, 18498, 190, }, /* 624 */ + { 84, 12, 3, 0, 0, 26666, 96, }, /* 625 */ + { 84, 12, 3, 0, 0, 26696, 96, }, /* 626 */ + { 84, 12, 3, 0, 0, 26780, 96, }, /* 627 */ + { 69, 10, 5, 0, 0, 18474, 160, }, /* 628 */ + { 69, 7, 12, 0, 0, 18501, 82, }, /* 629 */ + { 69, 7, 12, 0, 0, 18474, 82, }, /* 630 */ + { 69, 7, 12, 0, 0, 18438, 82, }, /* 631 */ + { 69, 7, 12, 0, 0, 18594, 82, }, /* 632 */ + { 69, 7, 12, 0, 0, 18498, 82, }, /* 633 */ + { 84, 12, 3, 0, 0, 26750, 96, }, /* 634 */ + { 69, 10, 5, 0, 0, 18435, 160, }, /* 635 */ + { 84, 12, 3, 0, 0, 26690, 96, }, /* 636 */ + { 69, 7, 12, 0, 0, 18453, 82, }, /* 637 */ + { 2, 5, 12, 0, 0, 18432, 60, }, /* 638 */ + { 1, 6, 12, 0, 0, 18432, 88, }, /* 639 */ + { 2, 6, 12, 0, 0, 18432, 168, }, /* 640 */ + { 0, 5, 12, 0, 35332, 18432, 76, }, /* 641 */ + { 0, 5, 12, 0, 3814, 18432, 76, }, /* 642 */ + { 0, 5, 12, 0, 35384, 18432, 76, }, /* 643 */ + { 0, 5, 12, 0, 0, 18432, 192, }, /* 644 */ + { 0, 6, 12, 0, 0, 18432, 168, }, /* 645 */ + { 0, 6, 12, 0, 0, 18432, 194, }, /* 646 */ + { 1, 6, 12, 0, 0, 18432, 168, }, /* 647 */ + { 84, 12, 3, 0, 0, 26636, 102, }, /* 648 */ + { 84, 12, 3, 0, 0, 26687, 96, }, /* 649 */ + { 84, 12, 3, 0, 0, 26648, 96, }, /* 650 */ + { 0, 9, 12, 92, 1, 18432, 74, }, /* 651 */ + { 0, 5, 12, 92, -1, 18432, 76, }, /* 652 */ + { 0, 5, 12, 0, 0, 18432, 70, }, /* 653 */ + { 0, 5, 12, 92, -58, 18432, 70, }, /* 654 */ + { 0, 9, 12, 0, -7615, 18432, 74, }, /* 655 */ + { 1, 5, 12, 0, 8, 18432, 76, }, /* 656 */ + { 1, 9, 12, 0, -8, 18432, 74, }, /* 657 */ + { 1, 5, 12, 0, 74, 18432, 76, }, /* 658 */ + { 1, 5, 12, 0, 86, 18432, 76, }, /* 659 */ + { 1, 5, 12, 0, 100, 18432, 76, }, /* 660 */ + { 1, 5, 12, 0, 128, 18432, 76, }, /* 661 */ + { 1, 5, 12, 0, 112, 18432, 76, }, /* 662 */ + { 1, 5, 12, 0, 126, 18432, 76, }, /* 663 */ + { 1, 5, 12, 0, 8, 18432, 70, }, /* 664 */ + { 1, 8, 12, 0, -8, 18432, 86, }, /* 665 */ + { 1, 5, 12, 0, 0, 18432, 70, }, /* 666 */ + { 1, 5, 12, 0, 9, 18432, 70, }, /* 667 */ + { 1, 9, 12, 0, -74, 18432, 74, }, /* 668 */ + { 1, 8, 12, 0, -9, 18432, 86, }, /* 669 */ + { 1, 5, 12, 21, -7173, 18432, 76, }, /* 670 */ + { 1, 9, 12, 0, -86, 18432, 74, }, /* 671 */ + { 1, 9, 12, 0, -100, 18432, 74, }, /* 672 */ + { 1, 9, 12, 0, -112, 18432, 74, }, /* 673 */ + { 1, 9, 12, 0, -128, 18432, 74, }, /* 674 */ + { 1, 9, 12, 0, -126, 18432, 74, }, /* 675 */ + { 69, 29, 12, 0, 0, 45056, 52, }, /* 676 */ + { 84, 1, 3, 0, 0, 6144, 196, }, /* 677 */ + { 84, 1, 13, 0, 0, 6144, 198, }, /* 678 */ + { 69, 1, 2, 0, 0, 18432, 200, }, /* 679 */ + { 69, 1, 2, 0, 0, 34816, 200, }, /* 680 */ + { 69, 17, 12, 0, 0, 28672, 202, }, /* 681 */ + { 69, 21, 12, 0, 0, 28672, 64, }, /* 682 */ + { 69, 20, 12, 0, 0, 28672, 204, }, /* 683 */ + { 69, 19, 12, 0, 0, 28672, 204, }, /* 684 */ + { 69, 22, 12, 0, 0, 28672, 206, }, /* 685 */ + { 69, 20, 12, 0, 0, 28672, 206, }, /* 686 */ + { 69, 19, 12, 0, 0, 28672, 206, }, /* 687 */ + { 69, 21, 12, 0, 0, 28672, 208, }, /* 688 */ + { 69, 27, 2, 0, 0, 45056, 50, }, /* 689 */ + { 69, 28, 2, 0, 0, 4096, 50, }, /* 690 */ + { 69, 1, 2, 0, 0, 20480, 134, }, /* 691 */ + { 69, 1, 2, 0, 0, 36864, 134, }, /* 692 */ + { 69, 1, 2, 0, 0, 30720, 134, }, /* 693 */ + { 69, 1, 2, 0, 0, 24576, 134, }, /* 694 */ + { 69, 1, 2, 0, 0, 40960, 134, }, /* 695 */ + { 69, 29, 12, 0, 0, 8291, 52, }, /* 696 */ + { 69, 21, 12, 0, 0, 14336, 54, }, /* 697 */ + { 69, 21, 12, 0, 0, 14336, 64, }, /* 698 */ + { 69, 21, 14, 0, 0, 28672, 210, }, /* 699 */ + { 69, 21, 12, 0, 0, 28672, 212, }, /* 700 */ + { 69, 16, 12, 0, 0, 28672, 138, }, /* 701 */ + { 69, 16, 12, 0, 0, 28672, 214, }, /* 702 */ + { 69, 25, 12, 0, 0, 8192, 64, }, /* 703 */ + { 69, 22, 12, 0, 0, 28672, 216, }, /* 704 */ + { 69, 18, 12, 0, 0, 28672, 216, }, /* 705 */ + { 69, 21, 12, 0, 0, 28672, 202, }, /* 706 */ + { 69, 1, 2, 0, 0, 6144, 218, }, /* 707 */ + { 68, 2, 2, 0, 0, 6144, 220, }, /* 708 */ + { 69, 1, 2, 0, 0, 22528, 134, }, /* 709 */ + { 69, 1, 2, 0, 0, 38912, 134, }, /* 710 */ + { 69, 1, 2, 0, 0, 16384, 134, }, /* 711 */ + { 69, 1, 2, 0, 0, 32768, 134, }, /* 712 */ + { 69, 1, 2, 0, 0, 6144, 222, }, /* 713 */ + { 69, 25, 12, 0, 0, 12288, 118, }, /* 714 */ + { 69, 25, 12, 0, 0, 12288, 224, }, /* 715 */ + { 69, 25, 12, 0, 0, 28672, 118, }, /* 716 */ + { 69, 22, 12, 0, 0, 28672, 226, }, /* 717 */ + { 69, 18, 12, 0, 0, 28672, 226, }, /* 718 */ + { 68, 2, 12, 0, 0, 14336, 0, }, /* 719 */ + { 84, 12, 3, 0, 0, 26624, 228, }, /* 720 */ + { 84, 11, 3, 0, 0, 26624, 120, }, /* 721 */ + { 84, 11, 3, 0, 0, 26624, 230, }, /* 722 */ + { 84, 12, 3, 0, 0, 26753, 102, }, /* 723 */ + { 69, 26, 12, 0, 0, 28672, 68, }, /* 724 */ + { 69, 9, 12, 0, 0, 18432, 112, }, /* 725 */ + { 69, 5, 12, 0, 0, 18432, 232, }, /* 726 */ + { 69, 25, 12, 0, 0, 28672, 234, }, /* 727 */ + { 69, 26, 14, 0, 0, 28672, 236, }, /* 728 */ + { 1, 9, 12, 96, -7517, 18432, 74, }, /* 729 */ + { 69, 26, 12, 0, 0, 28672, 118, }, /* 730 */ + { 0, 9, 12, 100, 0, 18432, 74, }, /* 731 */ + { 0, 9, 12, 104, -8262, 18432, 74, }, /* 732 */ + { 69, 26, 12, 0, 0, 14336, 238, }, /* 733 */ + { 0, 9, 12, 0, 28, 18432, 74, }, /* 734 */ + { 69, 7, 12, 0, 0, 18432, 240, }, /* 735 */ + { 69, 5, 14, 0, 0, 18432, 242, }, /* 736 */ + { 69, 5, 12, 0, 0, 18432, 244, }, /* 737 */ + { 0, 5, 12, 0, -28, 18432, 76, }, /* 738 */ + { 0, 14, 12, 0, 16, 18432, 74, }, /* 739 */ + { 0, 14, 12, 0, -16, 18432, 76, }, /* 740 */ + { 0, 14, 12, 0, 0, 18432, 82, }, /* 741 */ + { 69, 25, 14, 0, 0, 28672, 246, }, /* 742 */ + { 69, 26, 14, 0, 0, 28672, 246, }, /* 743 */ + { 69, 26, 12, 0, 0, 28672, 64, }, /* 744 */ + { 69, 25, 12, 0, 0, 28672, 248, }, /* 745 */ + { 69, 25, 12, 0, 0, 12288, 250, }, /* 746 */ + { 69, 22, 12, 0, 0, 28672, 248, }, /* 747 */ + { 69, 18, 12, 0, 0, 28672, 248, }, /* 748 */ + { 69, 26, 14, 0, 0, 28672, 252, }, /* 749 */ + { 69, 22, 12, 0, 0, 28672, 254, }, /* 750 */ + { 69, 18, 12, 0, 0, 28672, 254, }, /* 751 */ + { 69, 26, 12, 0, 0, 18432, 54, }, /* 752 */ + { 69, 26, 14, 0, 0, 28672, 256, }, /* 753 */ + { 68, 2, 12, 0, 0, 18432, 258, }, /* 754 */ + { 69, 26, 12, 0, 26, 18432, 260, }, /* 755 */ + { 69, 26, 14, 0, 26, 18432, 262, }, /* 756 */ + { 69, 26, 12, 0, -26, 18432, 264, }, /* 757 */ + { 69, 25, 14, 0, 0, 28672, 266, }, /* 758 */ + { 69, 26, 14, 0, 0, 28672, 268, }, /* 759 */ + { 69, 26, 14, 0, 0, 28672, 270, }, /* 760 */ + { 69, 25, 14, 0, 0, 28672, 268, }, /* 761 */ + { 69, 26, 14, 0, 0, 18432, 256, }, /* 762 */ + { 69, 26, 14, 0, 0, 28672, 272, }, /* 763 */ + { 88, 26, 12, 0, 0, 18432, 54, }, /* 764 */ + { 69, 26, 12, 0, 0, 28672, 216, }, /* 765 */ + { 35, 9, 12, 0, 48, 18432, 74, }, /* 766 */ + { 35, 5, 12, 0, -48, 18432, 76, }, /* 767 */ + { 0, 9, 12, 0, -10743, 18432, 74, }, /* 768 */ + { 0, 9, 12, 0, -3814, 18432, 74, }, /* 769 */ + { 0, 9, 12, 0, -10727, 18432, 74, }, /* 770 */ + { 0, 5, 12, 0, -10795, 18432, 76, }, /* 771 */ + { 0, 5, 12, 0, -10792, 18432, 76, }, /* 772 */ + { 0, 9, 12, 0, -10780, 18432, 74, }, /* 773 */ + { 0, 9, 12, 0, -10749, 18432, 74, }, /* 774 */ + { 0, 9, 12, 0, -10783, 18432, 74, }, /* 775 */ + { 0, 9, 12, 0, -10782, 18432, 74, }, /* 776 */ + { 0, 9, 12, 0, -10815, 18432, 74, }, /* 777 */ + { 34, 5, 12, 0, 0, 18432, 60, }, /* 778 */ + { 34, 26, 12, 0, 0, 28672, 68, }, /* 779 */ + { 34, 12, 3, 0, 0, 26624, 96, }, /* 780 */ + { 34, 21, 12, 0, 0, 28672, 68, }, /* 781 */ + { 34, 15, 12, 0, 0, 28672, 68, }, /* 782 */ + { 17, 5, 12, 0, -7264, 18432, 76, }, /* 783 */ + { 90, 7, 12, 0, 0, 18432, 82, }, /* 784 */ + { 90, 6, 12, 0, 0, 18432, 142, }, /* 785 */ + { 90, 21, 12, 0, 0, 18432, 68, }, /* 786 */ + { 90, 12, 3, 0, 0, 26624, 184, }, /* 787 */ + { 2, 12, 3, 0, 0, 26624, 130, }, /* 788 */ + { 69, 20, 12, 0, 0, 28672, 216, }, /* 789 */ + { 69, 19, 12, 0, 0, 28672, 216, }, /* 790 */ + { 69, 6, 12, 0, 0, 28672, 274, }, /* 791 */ + { 69, 21, 12, 0, 0, 28672, 276, }, /* 792 */ + { 69, 21, 12, 0, 0, 28726, 54, }, /* 793 */ + { 23, 26, 12, 0, 0, 28672, 278, }, /* 794 */ + { 69, 26, 12, 0, 0, 28672, 280, }, /* 795 */ + { 69, 26, 12, 0, 0, 28672, 282, }, /* 796 */ + { 69, 21, 12, 0, 0, 28825, 276, }, /* 797 */ + { 69, 21, 12, 0, 0, 28825, 212, }, /* 798 */ + { 69, 21, 12, 0, 0, 28819, 54, }, /* 799 */ + { 23, 6, 12, 0, 0, 18432, 136, }, /* 800 */ + { 69, 7, 12, 0, 0, 18447, 284, }, /* 801 */ + { 23, 14, 12, 0, 0, 18432, 284, }, /* 802 */ + { 69, 22, 12, 0, 0, 28825, 216, }, /* 803 */ + { 69, 18, 12, 0, 0, 28825, 216, }, /* 804 */ + { 69, 22, 12, 0, 0, 28825, 62, }, /* 805 */ + { 69, 18, 12, 0, 0, 28825, 62, }, /* 806 */ + { 69, 26, 12, 0, 0, 28819, 54, }, /* 807 */ + { 69, 17, 12, 0, 0, 28819, 202, }, /* 808 */ + { 69, 22, 12, 0, 0, 28819, 206, }, /* 809 */ + { 69, 18, 12, 0, 0, 28819, 206, }, /* 810 */ + { 84, 12, 3, 0, 0, 26669, 96, }, /* 811 */ + { 18, 10, 3, 0, 0, 18432, 286, }, /* 812 */ + { 69, 17, 14, 0, 0, 28819, 288, }, /* 813 */ + { 69, 6, 12, 0, 0, 18525, 136, }, /* 814 */ + { 69, 26, 12, 0, 0, 28819, 68, }, /* 815 */ + { 23, 6, 12, 0, 0, 18432, 142, }, /* 816 */ + { 69, 7, 12, 0, 0, 18564, 82, }, /* 817 */ + { 69, 21, 14, 0, 0, 28804, 236, }, /* 818 */ + { 69, 26, 12, 0, 0, 28687, 68, }, /* 819 */ + { 20, 7, 12, 0, 0, 18432, 82, }, /* 820 */ + { 84, 12, 3, 0, 0, 26717, 96, }, /* 821 */ + { 69, 24, 12, 0, 0, 28765, 290, }, /* 822 */ + { 20, 6, 12, 0, 0, 18432, 136, }, /* 823 */ + { 69, 17, 12, 0, 0, 28765, 126, }, /* 824 */ + { 21, 7, 12, 0, 0, 18432, 82, }, /* 825 */ + { 69, 21, 12, 0, 0, 28825, 68, }, /* 826 */ + { 69, 6, 12, 0, 0, 18525, 94, }, /* 827 */ + { 21, 6, 12, 0, 0, 18432, 136, }, /* 828 */ + { 22, 7, 12, 0, 0, 18432, 82, }, /* 829 */ + { 18, 7, 12, 0, 0, 18432, 82, }, /* 830 */ + { 18, 7, 12, 0, 0, 18432, 170, }, /* 831 */ + { 69, 26, 12, 0, 0, 18447, 68, }, /* 832 */ + { 69, 15, 12, 0, 0, 18447, 68, }, /* 833 */ + { 18, 26, 12, 0, 0, 18432, 68, }, /* 834 */ + { 18, 26, 12, 0, 0, 28672, 68, }, /* 835 */ + { 69, 15, 12, 0, 0, 18432, 68, }, /* 836 */ + { 69, 26, 14, 0, 0, 18447, 236, }, /* 837 */ + { 21, 26, 12, 0, 0, 18432, 68, }, /* 838 */ + { 23, 7, 12, 0, 0, 18432, 292, }, /* 839 */ + { 24, 7, 12, 0, 0, 18432, 82, }, /* 840 */ + { 24, 6, 12, 0, 0, 18432, 136, }, /* 841 */ + { 24, 26, 12, 0, 0, 28672, 68, }, /* 842 */ + { 111, 7, 12, 0, 0, 18432, 82, }, /* 843 */ + { 111, 6, 12, 0, 0, 18432, 142, }, /* 844 */ + { 111, 21, 12, 0, 0, 18432, 106, }, /* 845 */ + { 111, 21, 12, 0, 0, 18432, 124, }, /* 846 */ + { 99, 7, 12, 0, 0, 18432, 82, }, /* 847 */ + { 99, 6, 12, 0, 0, 18432, 136, }, /* 848 */ + { 99, 21, 12, 0, 0, 28672, 106, }, /* 849 */ + { 99, 21, 12, 0, 0, 28672, 124, }, /* 850 */ + { 99, 13, 12, 0, 0, 18432, 138, }, /* 851 */ + { 2, 9, 12, 108, 1, 18432, 74, }, /* 852 */ + { 2, 5, 12, 108, -35267, 18432, 76, }, /* 853 */ + { 2, 7, 12, 0, 0, 18432, 82, }, /* 854 */ + { 2, 21, 12, 0, 0, 28672, 68, }, /* 855 */ + { 2, 12, 3, 0, 0, 26624, 96, }, /* 856 */ + { 2, 6, 12, 0, 0, 28672, 92, }, /* 857 */ + { 2, 6, 12, 0, 0, 18432, 88, }, /* 858 */ + { 112, 7, 12, 0, 0, 18432, 82, }, /* 859 */ + { 112, 14, 12, 0, 0, 18432, 82, }, /* 860 */ + { 112, 12, 3, 0, 0, 26624, 96, }, /* 861 */ + { 112, 21, 12, 0, 0, 18432, 68, }, /* 862 */ + { 112, 21, 12, 0, 0, 18432, 124, }, /* 863 */ + { 112, 21, 12, 0, 0, 18432, 106, }, /* 864 */ + { 69, 24, 12, 0, 0, 28762, 56, }, /* 865 */ + { 0, 9, 12, 0, -35332, 18432, 74, }, /* 866 */ + { 69, 24, 12, 0, 0, 18432, 56, }, /* 867 */ + { 0, 9, 12, 0, -42280, 18432, 74, }, /* 868 */ + { 0, 5, 12, 0, 48, 18432, 76, }, /* 869 */ + { 0, 9, 12, 0, -42308, 18432, 74, }, /* 870 */ + { 0, 9, 12, 0, -42319, 18432, 74, }, /* 871 */ + { 0, 9, 12, 0, -42315, 18432, 74, }, /* 872 */ + { 0, 9, 12, 0, -42305, 18432, 74, }, /* 873 */ + { 0, 9, 12, 0, -42258, 18432, 74, }, /* 874 */ + { 0, 9, 12, 0, -42282, 18432, 74, }, /* 875 */ + { 0, 9, 12, 0, -42261, 18432, 74, }, /* 876 */ + { 0, 9, 12, 0, 928, 18432, 74, }, /* 877 */ + { 0, 9, 12, 0, -48, 18432, 74, }, /* 878 */ + { 0, 9, 12, 0, -42307, 18432, 74, }, /* 879 */ + { 0, 9, 12, 0, -35384, 18432, 74, }, /* 880 */ { 36, 7, 12, 0, 0, 18432, 82, }, /* 881 */ { 36, 12, 3, 0, 0, 26624, 130, }, /* 882 */ - { 36, 12, 3, 0, 0, 26624, 182, }, /* 883 */ + { 36, 12, 3, 0, 0, 26624, 184, }, /* 883 */ { 36, 10, 5, 0, 0, 18432, 144, }, /* 884 */ { 36, 26, 12, 0, 0, 28672, 68, }, /* 885 */ { 69, 15, 12, 0, 0, 18612, 68, }, /* 886 */ @@ -1331,18 +1331,18 @@ const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ { 39, 7, 12, 0, 0, 18432, 82, }, /* 903 */ { 39, 12, 3, 0, 0, 26624, 130, }, /* 904 */ { 39, 12, 3, 0, 0, 26624, 96, }, /* 905 */ - { 69, 21, 12, 0, 0, 18567, 188, }, /* 906 */ + { 69, 21, 12, 0, 0, 18567, 190, }, /* 906 */ { 39, 21, 12, 0, 0, 18432, 124, }, /* 907 */ { 101, 7, 12, 0, 0, 18432, 82, }, /* 908 */ { 101, 12, 3, 0, 0, 26624, 130, }, /* 909 */ { 101, 10, 5, 0, 0, 18432, 144, }, /* 910 */ - { 101, 10, 5, 0, 0, 18432, 172, }, /* 911 */ + { 101, 10, 5, 0, 0, 18432, 174, }, /* 911 */ { 101, 21, 12, 0, 0, 18432, 68, }, /* 912 */ { 40, 12, 3, 0, 0, 26624, 130, }, /* 913 */ { 40, 10, 5, 0, 0, 18432, 144, }, /* 914 */ { 40, 7, 12, 0, 0, 18432, 82, }, /* 915 */ { 40, 12, 3, 0, 0, 26624, 96, }, /* 916 */ - { 40, 10, 5, 0, 0, 18432, 172, }, /* 917 */ + { 40, 10, 5, 0, 0, 18432, 174, }, /* 917 */ { 40, 21, 12, 0, 0, 18432, 68, }, /* 918 */ { 40, 21, 12, 0, 0, 18432, 106, }, /* 919 */ { 40, 21, 12, 0, 0, 18432, 124, }, /* 920 */ @@ -1370,470 +1370,484 @@ const ucd_record PRIV(ucd_records)[] = { /* 16908 bytes, record size 12 */ { 113, 6, 12, 0, 0, 18432, 136, }, /* 942 */ { 113, 12, 3, 0, 0, 26624, 146, }, /* 943 */ { 0, 5, 12, 0, -928, 18432, 76, }, /* 944 */ - { 0, 6, 12, 0, 0, 18432, 92, }, /* 945 */ - { 76, 5, 12, 0, -38864, 18432, 70, }, /* 946 */ - { 113, 10, 5, 0, 0, 18432, 160, }, /* 947 */ - { 113, 13, 12, 0, 0, 18432, 138, }, /* 948 */ - { 18, 7, 9, 0, 0, 18432, 82, }, /* 949 */ - { 18, 7, 10, 0, 0, 18432, 82, }, /* 950 */ - { 68, 4, 12, 0, 0, 18432, 0, }, /* 951 */ - { 68, 3, 12, 0, 0, 18432, 0, }, /* 952 */ - { 23, 7, 12, 0, 0, 18432, 284, }, /* 953 */ - { 71, 25, 12, 0, 0, 12288, 118, }, /* 954 */ - { 3, 7, 12, 0, 0, 0, 296, }, /* 955 */ - { 69, 18, 12, 0, 0, 28705, 54, }, /* 956 */ - { 69, 22, 12, 0, 0, 28705, 54, }, /* 957 */ - { 68, 2, 12, 0, 0, 6144, 298, }, /* 958 */ - { 3, 7, 12, 0, 0, 39, 82, }, /* 959 */ - { 3, 26, 12, 0, 0, 28711, 68, }, /* 960 */ - { 84, 12, 3, 0, 0, 26624, 178, }, /* 961 */ - { 84, 12, 3, 0, 0, 26624, 300, }, /* 962 */ - { 69, 21, 12, 0, 0, 28672, 68, }, /* 963 */ - { 69, 21, 12, 0, 0, 28672, 122, }, /* 964 */ - { 69, 22, 12, 0, 0, 28672, 68, }, /* 965 */ - { 69, 18, 12, 0, 0, 28672, 68, }, /* 966 */ - { 69, 17, 12, 0, 0, 28672, 126, }, /* 967 */ - { 69, 22, 12, 0, 0, 28672, 302, }, /* 968 */ - { 69, 18, 12, 0, 0, 28672, 302, }, /* 969 */ - { 69, 21, 12, 0, 0, 8192, 106, }, /* 970 */ - { 69, 21, 12, 0, 0, 8192, 304, }, /* 971 */ - { 69, 21, 12, 0, 0, 8192, 306, }, /* 972 */ - { 69, 21, 12, 0, 0, 28672, 124, }, /* 973 */ - { 69, 22, 12, 0, 0, 28672, 158, }, /* 974 */ - { 69, 18, 12, 0, 0, 28672, 158, }, /* 975 */ - { 69, 21, 12, 0, 0, 14336, 68, }, /* 976 */ - { 69, 21, 12, 0, 0, 28672, 118, }, /* 977 */ - { 69, 17, 12, 0, 0, 12288, 224, }, /* 978 */ - { 69, 25, 12, 0, 0, 28672, 226, }, /* 979 */ - { 69, 21, 12, 0, 0, 28672, 302, }, /* 980 */ - { 69, 21, 12, 0, 0, 28672, 308, }, /* 981 */ - { 69, 17, 12, 0, 0, 12288, 126, }, /* 982 */ - { 69, 21, 12, 0, 0, 8192, 68, }, /* 983 */ - { 69, 13, 12, 0, 0, 10240, 310, }, /* 984 */ - { 0, 9, 12, 0, 32, 18432, 312, }, /* 985 */ - { 69, 24, 12, 0, 0, 28672, 314, }, /* 986 */ - { 0, 5, 12, 0, -32, 18432, 316, }, /* 987 */ - { 69, 21, 12, 0, 0, 28825, 124, }, /* 988 */ - { 69, 22, 12, 0, 0, 28825, 318, }, /* 989 */ - { 69, 18, 12, 0, 0, 28825, 318, }, /* 990 */ - { 69, 21, 12, 0, 0, 28825, 106, }, /* 991 */ - { 69, 6, 3, 0, 0, 18525, 320, }, /* 992 */ - { 69, 1, 2, 0, 0, 28672, 322, }, /* 993 */ - { 31, 7, 12, 0, 0, 18432, 82, }, /* 994 */ - { 69, 21, 12, 0, 0, 18552, 68, }, /* 995 */ - { 69, 21, 12, 0, 0, 28792, 68, }, /* 996 */ - { 69, 21, 12, 0, 0, 18483, 68, }, /* 997 */ - { 69, 15, 12, 0, 0, 18555, 68, }, /* 998 */ - { 69, 26, 12, 0, 0, 18483, 68, }, /* 999 */ - { 1, 14, 12, 0, 0, 28672, 82, }, /* 1000 */ - { 1, 15, 12, 0, 0, 28672, 68, }, /* 1001 */ - { 1, 26, 12, 0, 0, 28672, 68, }, /* 1002 */ - { 1, 26, 12, 0, 0, 18432, 68, }, /* 1003 */ - { 102, 7, 12, 0, 0, 18432, 82, }, /* 1004 */ - { 103, 7, 12, 0, 0, 18432, 82, }, /* 1005 */ - { 84, 12, 3, 0, 0, 26651, 96, }, /* 1006 */ - { 69, 15, 12, 0, 0, 10267, 68, }, /* 1007 */ - { 81, 7, 12, 0, 0, 18432, 82, }, /* 1008 */ - { 81, 15, 12, 0, 0, 18432, 68, }, /* 1009 */ - { 82, 7, 12, 0, 0, 18432, 82, }, /* 1010 */ - { 82, 14, 12, 0, 0, 18432, 82, }, /* 1011 */ - { 53, 7, 12, 0, 0, 18432, 82, }, /* 1012 */ - { 53, 12, 3, 0, 0, 26624, 130, }, /* 1013 */ - { 85, 7, 12, 0, 0, 18432, 82, }, /* 1014 */ - { 85, 21, 12, 0, 0, 18432, 106, }, /* 1015 */ - { 91, 7, 12, 0, 0, 18432, 82, }, /* 1016 */ - { 91, 21, 12, 0, 0, 18432, 106, }, /* 1017 */ - { 91, 14, 12, 0, 0, 18432, 82, }, /* 1018 */ - { 83, 9, 12, 0, 40, 18432, 74, }, /* 1019 */ - { 83, 5, 12, 0, -40, 18432, 76, }, /* 1020 */ - { 86, 7, 12, 0, 0, 18432, 82, }, /* 1021 */ - { 87, 7, 12, 0, 0, 18432, 82, }, /* 1022 */ - { 87, 13, 12, 0, 0, 18432, 138, }, /* 1023 */ - { 145, 9, 12, 0, 40, 18432, 74, }, /* 1024 */ - { 145, 5, 12, 0, -40, 18432, 76, }, /* 1025 */ - { 127, 7, 12, 0, 0, 18432, 82, }, /* 1026 */ - { 125, 7, 12, 0, 0, 18432, 82, }, /* 1027 */ - { 125, 21, 12, 0, 0, 18432, 68, }, /* 1028 */ - { 161, 9, 12, 0, 39, 18432, 74, }, /* 1029 */ - { 161, 5, 12, 0, -39, 18432, 76, }, /* 1030 */ - { 49, 7, 12, 0, 0, 18432, 82, }, /* 1031 */ - { 0, 6, 12, 0, 0, 18432, 94, }, /* 1032 */ - { 32, 7, 12, 0, 0, 34816, 82, }, /* 1033 */ - { 114, 7, 12, 0, 0, 34816, 82, }, /* 1034 */ - { 114, 21, 12, 0, 0, 34816, 106, }, /* 1035 */ - { 114, 15, 12, 0, 0, 34816, 68, }, /* 1036 */ - { 133, 7, 12, 0, 0, 34816, 82, }, /* 1037 */ - { 133, 26, 12, 0, 0, 34816, 68, }, /* 1038 */ - { 133, 15, 12, 0, 0, 34816, 68, }, /* 1039 */ - { 132, 7, 12, 0, 0, 34816, 82, }, /* 1040 */ - { 132, 15, 12, 0, 0, 34816, 68, }, /* 1041 */ - { 139, 7, 12, 0, 0, 34816, 82, }, /* 1042 */ - { 139, 15, 12, 0, 0, 34816, 68, }, /* 1043 */ - { 95, 7, 12, 0, 0, 34816, 82, }, /* 1044 */ - { 95, 15, 12, 0, 0, 34816, 68, }, /* 1045 */ - { 95, 21, 12, 0, 0, 28672, 106, }, /* 1046 */ - { 104, 7, 12, 0, 0, 34816, 82, }, /* 1047 */ - { 104, 21, 12, 0, 0, 34816, 68, }, /* 1048 */ - { 122, 7, 12, 0, 0, 34816, 82, }, /* 1049 */ - { 121, 7, 12, 0, 0, 34816, 82, }, /* 1050 */ - { 121, 15, 12, 0, 0, 34816, 68, }, /* 1051 */ - { 92, 7, 12, 0, 0, 34816, 82, }, /* 1052 */ - { 92, 12, 3, 0, 0, 26624, 130, }, /* 1053 */ - { 92, 12, 3, 0, 0, 26624, 102, }, /* 1054 */ - { 92, 12, 3, 0, 0, 26624, 182, }, /* 1055 */ - { 92, 15, 12, 0, 0, 34816, 68, }, /* 1056 */ - { 92, 21, 12, 0, 0, 34816, 68, }, /* 1057 */ - { 92, 21, 12, 0, 0, 34816, 124, }, /* 1058 */ - { 115, 7, 12, 0, 0, 34816, 82, }, /* 1059 */ - { 115, 15, 12, 0, 0, 34816, 68, }, /* 1060 */ - { 115, 21, 12, 0, 0, 34816, 68, }, /* 1061 */ - { 131, 7, 12, 0, 0, 34816, 82, }, /* 1062 */ - { 131, 15, 12, 0, 0, 34816, 68, }, /* 1063 */ - { 51, 7, 12, 0, 0, 34816, 82, }, /* 1064 */ - { 51, 26, 12, 0, 0, 34816, 68, }, /* 1065 */ - { 51, 12, 3, 0, 0, 26624, 96, }, /* 1066 */ - { 51, 15, 12, 0, 0, 34816, 68, }, /* 1067 */ - { 51, 21, 12, 0, 0, 34816, 106, }, /* 1068 */ - { 51, 21, 12, 0, 0, 34918, 106, }, /* 1069 */ - { 51, 21, 12, 0, 0, 34816, 68, }, /* 1070 */ - { 108, 7, 12, 0, 0, 34816, 82, }, /* 1071 */ - { 108, 21, 12, 0, 0, 28672, 68, }, /* 1072 */ - { 108, 21, 12, 0, 0, 28672, 106, }, /* 1073 */ - { 116, 7, 12, 0, 0, 34816, 82, }, /* 1074 */ - { 116, 15, 12, 0, 0, 34816, 68, }, /* 1075 */ - { 117, 7, 12, 0, 0, 34816, 82, }, /* 1076 */ - { 117, 15, 12, 0, 0, 34816, 68, }, /* 1077 */ - { 54, 7, 12, 0, 0, 34816, 82, }, /* 1078 */ - { 54, 21, 12, 0, 0, 34816, 106, }, /* 1079 */ - { 54, 15, 12, 0, 0, 34816, 68, }, /* 1080 */ - { 118, 7, 12, 0, 0, 34816, 82, }, /* 1081 */ - { 140, 9, 12, 0, 64, 34816, 74, }, /* 1082 */ - { 140, 5, 12, 0, -64, 34816, 76, }, /* 1083 */ - { 140, 15, 12, 0, 0, 34816, 68, }, /* 1084 */ - { 62, 7, 12, 0, 0, 0, 82, }, /* 1085 */ - { 62, 7, 12, 0, 0, 0, 294, }, /* 1086 */ - { 62, 12, 3, 0, 0, 26624, 128, }, /* 1087 */ - { 62, 13, 12, 0, 0, 2048, 138, }, /* 1088 */ - { 3, 15, 12, 0, 0, 2048, 68, }, /* 1089 */ - { 65, 7, 12, 0, 0, 34816, 82, }, /* 1090 */ - { 65, 12, 3, 0, 0, 26624, 130, }, /* 1091 */ - { 65, 17, 12, 0, 0, 34816, 126, }, /* 1092 */ - { 152, 7, 12, 0, 0, 34816, 82, }, /* 1093 */ - { 152, 15, 12, 0, 0, 34816, 68, }, /* 1094 */ - { 63, 7, 12, 0, 0, 0, 82, }, /* 1095 */ - { 63, 12, 3, 0, 0, 26624, 96, }, /* 1096 */ - { 63, 15, 12, 0, 0, 0, 68, }, /* 1097 */ - { 63, 21, 12, 0, 0, 0, 124, }, /* 1098 */ - { 67, 7, 12, 0, 0, 34816, 82, }, /* 1099 */ - { 67, 12, 3, 0, 0, 26624, 96, }, /* 1100 */ - { 67, 21, 12, 0, 0, 34816, 124, }, /* 1101 */ - { 156, 7, 12, 0, 0, 34816, 82, }, /* 1102 */ - { 156, 15, 12, 0, 0, 34816, 68, }, /* 1103 */ - { 153, 7, 12, 0, 0, 34816, 82, }, /* 1104 */ - { 120, 10, 5, 0, 0, 18432, 144, }, /* 1105 */ - { 120, 12, 3, 0, 0, 26624, 130, }, /* 1106 */ - { 120, 7, 12, 0, 0, 18432, 82, }, /* 1107 */ - { 120, 12, 3, 0, 0, 26624, 146, }, /* 1108 */ - { 120, 21, 12, 0, 0, 18432, 124, }, /* 1109 */ - { 120, 21, 12, 0, 0, 18432, 106, }, /* 1110 */ - { 120, 15, 12, 0, 0, 28672, 68, }, /* 1111 */ - { 120, 13, 12, 0, 0, 18432, 138, }, /* 1112 */ - { 120, 12, 3, 0, 0, 26624, 182, }, /* 1113 */ - { 41, 12, 3, 0, 0, 26624, 102, }, /* 1114 */ - { 41, 10, 5, 0, 0, 18432, 144, }, /* 1115 */ - { 41, 7, 12, 0, 0, 18432, 82, }, /* 1116 */ - { 41, 12, 3, 0, 0, 26624, 130, }, /* 1117 */ - { 41, 12, 3, 0, 0, 26624, 146, }, /* 1118 */ - { 41, 12, 3, 0, 0, 26624, 96, }, /* 1119 */ - { 41, 21, 12, 0, 0, 18432, 68, }, /* 1120 */ - { 41, 1, 4, 0, 0, 18432, 132, }, /* 1121 */ - { 41, 21, 12, 0, 0, 18432, 124, }, /* 1122 */ - { 124, 7, 12, 0, 0, 18432, 82, }, /* 1123 */ - { 124, 13, 12, 0, 0, 18432, 138, }, /* 1124 */ - { 43, 12, 3, 0, 0, 26624, 130, }, /* 1125 */ - { 43, 7, 12, 0, 0, 18432, 82, }, /* 1126 */ - { 43, 10, 5, 0, 0, 18432, 144, }, /* 1127 */ - { 43, 12, 3, 0, 0, 26624, 146, }, /* 1128 */ - { 43, 13, 12, 0, 0, 18432, 138, }, /* 1129 */ - { 43, 21, 12, 0, 0, 18432, 68, }, /* 1130 */ - { 43, 21, 12, 0, 0, 18432, 124, }, /* 1131 */ - { 50, 7, 12, 0, 0, 18432, 82, }, /* 1132 */ - { 50, 12, 3, 0, 0, 26624, 96, }, /* 1133 */ - { 50, 21, 12, 0, 0, 18432, 68, }, /* 1134 */ - { 44, 12, 3, 0, 0, 26624, 130, }, /* 1135 */ - { 44, 10, 5, 0, 0, 18432, 144, }, /* 1136 */ - { 44, 7, 12, 0, 0, 18432, 82, }, /* 1137 */ - { 44, 10, 5, 0, 0, 18432, 172, }, /* 1138 */ - { 44, 7, 4, 0, 0, 18432, 82, }, /* 1139 */ - { 44, 21, 12, 0, 0, 18432, 124, }, /* 1140 */ - { 44, 21, 12, 0, 0, 18432, 68, }, /* 1141 */ - { 44, 12, 3, 0, 0, 26624, 102, }, /* 1142 */ - { 44, 12, 3, 0, 0, 26624, 96, }, /* 1143 */ - { 44, 13, 12, 0, 0, 18432, 138, }, /* 1144 */ - { 15, 15, 12, 0, 0, 18432, 68, }, /* 1145 */ - { 48, 7, 12, 0, 0, 18432, 82, }, /* 1146 */ - { 48, 10, 5, 0, 0, 18432, 144, }, /* 1147 */ - { 48, 12, 3, 0, 0, 26624, 130, }, /* 1148 */ - { 48, 10, 5, 0, 0, 18432, 172, }, /* 1149 */ - { 48, 12, 3, 0, 0, 26624, 96, }, /* 1150 */ - { 48, 21, 12, 0, 0, 18432, 124, }, /* 1151 */ - { 48, 21, 12, 0, 0, 18432, 106, }, /* 1152 */ - { 48, 21, 12, 0, 0, 18432, 68, }, /* 1153 */ - { 57, 7, 12, 0, 0, 18432, 82, }, /* 1154 */ - { 57, 21, 12, 0, 0, 18432, 124, }, /* 1155 */ - { 55, 7, 12, 0, 0, 18432, 82, }, /* 1156 */ - { 55, 12, 3, 0, 0, 26624, 130, }, /* 1157 */ - { 55, 10, 5, 0, 0, 18432, 144, }, /* 1158 */ - { 55, 12, 3, 0, 0, 26624, 96, }, /* 1159 */ - { 55, 12, 3, 0, 0, 26624, 146, }, /* 1160 */ - { 55, 13, 12, 0, 0, 18432, 138, }, /* 1161 */ - { 47, 12, 3, 0, 0, 26624, 130, }, /* 1162 */ - { 47, 12, 3, 0, 0, 26705, 130, }, /* 1163 */ - { 47, 10, 5, 0, 0, 18432, 144, }, /* 1164 */ - { 47, 10, 5, 0, 0, 18513, 144, }, /* 1165 */ - { 47, 7, 12, 0, 0, 18432, 82, }, /* 1166 */ - { 84, 12, 3, 0, 0, 26705, 102, }, /* 1167 */ - { 47, 12, 3, 0, 0, 26705, 96, }, /* 1168 */ - { 47, 10, 3, 0, 0, 18432, 148, }, /* 1169 */ - { 47, 10, 5, 0, 0, 18432, 172, }, /* 1170 */ - { 47, 7, 12, 0, 0, 18432, 324, }, /* 1171 */ - { 47, 12, 3, 0, 0, 26624, 96, }, /* 1172 */ - { 144, 7, 12, 0, 0, 18432, 82, }, /* 1173 */ - { 144, 10, 5, 0, 0, 18432, 144, }, /* 1174 */ - { 144, 12, 3, 0, 0, 26624, 130, }, /* 1175 */ - { 144, 12, 3, 0, 0, 26624, 146, }, /* 1176 */ - { 144, 12, 3, 0, 0, 26624, 96, }, /* 1177 */ - { 144, 21, 12, 0, 0, 18432, 124, }, /* 1178 */ - { 144, 21, 12, 0, 0, 18432, 106, }, /* 1179 */ - { 144, 21, 12, 0, 0, 18432, 68, }, /* 1180 */ - { 144, 13, 12, 0, 0, 18432, 138, }, /* 1181 */ - { 144, 12, 3, 0, 0, 26624, 102, }, /* 1182 */ - { 56, 7, 12, 0, 0, 18432, 82, }, /* 1183 */ - { 56, 10, 3, 0, 0, 18432, 148, }, /* 1184 */ - { 56, 10, 5, 0, 0, 18432, 144, }, /* 1185 */ - { 56, 12, 3, 0, 0, 26624, 130, }, /* 1186 */ - { 56, 12, 3, 0, 0, 26624, 146, }, /* 1187 */ - { 56, 12, 3, 0, 0, 26624, 96, }, /* 1188 */ - { 56, 21, 12, 0, 0, 18432, 68, }, /* 1189 */ - { 56, 13, 12, 0, 0, 18432, 138, }, /* 1190 */ - { 135, 7, 12, 0, 0, 18432, 82, }, /* 1191 */ - { 135, 10, 3, 0, 0, 18432, 148, }, /* 1192 */ - { 135, 10, 5, 0, 0, 18432, 144, }, /* 1193 */ - { 135, 12, 3, 0, 0, 26624, 130, }, /* 1194 */ - { 135, 12, 3, 0, 0, 26624, 146, }, /* 1195 */ - { 135, 12, 3, 0, 0, 26624, 96, }, /* 1196 */ - { 135, 21, 12, 0, 0, 18432, 68, }, /* 1197 */ - { 135, 21, 12, 0, 0, 18432, 124, }, /* 1198 */ - { 135, 21, 12, 0, 0, 18432, 106, }, /* 1199 */ - { 135, 21, 12, 0, 0, 18432, 176, }, /* 1200 */ - { 52, 7, 12, 0, 0, 18432, 82, }, /* 1201 */ - { 52, 10, 5, 0, 0, 18432, 144, }, /* 1202 */ - { 52, 12, 3, 0, 0, 26624, 130, }, /* 1203 */ - { 52, 12, 3, 0, 0, 26624, 146, }, /* 1204 */ - { 52, 21, 12, 0, 0, 18432, 124, }, /* 1205 */ - { 52, 21, 12, 0, 0, 18432, 68, }, /* 1206 */ - { 52, 13, 12, 0, 0, 18432, 138, }, /* 1207 */ - { 45, 7, 12, 0, 0, 18432, 82, }, /* 1208 */ - { 45, 12, 3, 0, 0, 26624, 130, }, /* 1209 */ - { 45, 10, 5, 0, 0, 18432, 144, }, /* 1210 */ - { 45, 10, 5, 0, 0, 18432, 172, }, /* 1211 */ - { 45, 12, 3, 0, 0, 26624, 96, }, /* 1212 */ - { 45, 21, 12, 0, 0, 18432, 68, }, /* 1213 */ - { 45, 13, 12, 0, 0, 18432, 138, }, /* 1214 */ - { 137, 7, 12, 0, 0, 18432, 82, }, /* 1215 */ - { 137, 12, 3, 0, 0, 26624, 130, }, /* 1216 */ - { 137, 10, 12, 0, 0, 18432, 144, }, /* 1217 */ - { 137, 10, 5, 0, 0, 18432, 144, }, /* 1218 */ - { 137, 12, 3, 0, 0, 26624, 146, }, /* 1219 */ - { 137, 13, 12, 0, 0, 18432, 138, }, /* 1220 */ - { 137, 15, 12, 0, 0, 18432, 68, }, /* 1221 */ - { 137, 21, 12, 0, 0, 18432, 124, }, /* 1222 */ - { 137, 26, 12, 0, 0, 18432, 68, }, /* 1223 */ - { 60, 7, 12, 0, 0, 18432, 82, }, /* 1224 */ - { 60, 10, 5, 0, 0, 18432, 144, }, /* 1225 */ - { 60, 12, 3, 0, 0, 26624, 130, }, /* 1226 */ - { 60, 12, 3, 0, 0, 26624, 146, }, /* 1227 */ - { 60, 12, 3, 0, 0, 26624, 96, }, /* 1228 */ - { 60, 21, 12, 0, 0, 18432, 68, }, /* 1229 */ - { 136, 9, 12, 0, 32, 18432, 74, }, /* 1230 */ - { 136, 5, 12, 0, -32, 18432, 76, }, /* 1231 */ - { 136, 13, 12, 0, 0, 18432, 138, }, /* 1232 */ - { 136, 15, 12, 0, 0, 18432, 68, }, /* 1233 */ - { 136, 7, 12, 0, 0, 18432, 82, }, /* 1234 */ - { 157, 7, 12, 0, 0, 18432, 82, }, /* 1235 */ - { 157, 10, 3, 0, 0, 18432, 148, }, /* 1236 */ - { 157, 10, 5, 0, 0, 18432, 144, }, /* 1237 */ - { 157, 12, 3, 0, 0, 26624, 130, }, /* 1238 */ - { 157, 10, 5, 0, 0, 18432, 172, }, /* 1239 */ - { 157, 12, 3, 0, 0, 26624, 146, }, /* 1240 */ - { 157, 7, 4, 0, 0, 18432, 82, }, /* 1241 */ - { 157, 12, 3, 0, 0, 26624, 96, }, /* 1242 */ - { 157, 21, 12, 0, 0, 18432, 124, }, /* 1243 */ - { 157, 21, 12, 0, 0, 18432, 68, }, /* 1244 */ - { 157, 13, 12, 0, 0, 18432, 138, }, /* 1245 */ - { 64, 7, 12, 0, 0, 18432, 82, }, /* 1246 */ - { 64, 10, 5, 0, 0, 18432, 144, }, /* 1247 */ - { 64, 12, 3, 0, 0, 26624, 130, }, /* 1248 */ - { 64, 12, 3, 0, 0, 26624, 146, }, /* 1249 */ - { 64, 21, 12, 0, 0, 18432, 68, }, /* 1250 */ - { 149, 7, 12, 0, 0, 18432, 82, }, /* 1251 */ - { 149, 12, 3, 0, 0, 26624, 130, }, /* 1252 */ - { 149, 12, 3, 0, 0, 18432, 130, }, /* 1253 */ - { 149, 12, 3, 0, 0, 26624, 102, }, /* 1254 */ - { 149, 12, 3, 0, 0, 26624, 146, }, /* 1255 */ - { 149, 10, 5, 0, 0, 18432, 144, }, /* 1256 */ - { 149, 7, 4, 0, 0, 18432, 82, }, /* 1257 */ - { 149, 21, 12, 0, 0, 18432, 68, }, /* 1258 */ - { 149, 21, 12, 0, 0, 18432, 124, }, /* 1259 */ - { 148, 7, 12, 0, 0, 18432, 82, }, /* 1260 */ - { 148, 12, 3, 0, 0, 26624, 130, }, /* 1261 */ - { 148, 10, 5, 0, 0, 18432, 144, }, /* 1262 */ - { 148, 7, 4, 0, 0, 18432, 82, }, /* 1263 */ - { 148, 12, 3, 0, 0, 26624, 326, }, /* 1264 */ - { 148, 12, 3, 0, 0, 26624, 146, }, /* 1265 */ - { 148, 21, 12, 0, 0, 18432, 68, }, /* 1266 */ - { 148, 21, 12, 0, 0, 18432, 124, }, /* 1267 */ - { 148, 21, 12, 0, 0, 18432, 106, }, /* 1268 */ - { 134, 7, 12, 0, 0, 18432, 82, }, /* 1269 */ - { 142, 7, 12, 0, 0, 18432, 82, }, /* 1270 */ - { 142, 10, 5, 0, 0, 18432, 144, }, /* 1271 */ - { 142, 12, 3, 0, 0, 26624, 130, }, /* 1272 */ - { 142, 12, 3, 0, 0, 18432, 146, }, /* 1273 */ - { 142, 21, 12, 0, 0, 18432, 124, }, /* 1274 */ - { 142, 21, 12, 0, 0, 18432, 106, }, /* 1275 */ - { 142, 21, 12, 0, 0, 18432, 68, }, /* 1276 */ - { 142, 13, 12, 0, 0, 18432, 138, }, /* 1277 */ - { 142, 15, 12, 0, 0, 18432, 68, }, /* 1278 */ - { 143, 21, 12, 0, 0, 18432, 68, }, /* 1279 */ - { 143, 21, 12, 0, 0, 18432, 106, }, /* 1280 */ - { 143, 7, 12, 0, 0, 18432, 82, }, /* 1281 */ - { 143, 12, 3, 0, 0, 26624, 130, }, /* 1282 */ - { 143, 10, 5, 0, 0, 18432, 144, }, /* 1283 */ - { 59, 7, 12, 0, 0, 18432, 82, }, /* 1284 */ - { 59, 12, 3, 0, 0, 26624, 130, }, /* 1285 */ - { 59, 12, 3, 0, 0, 26624, 96, }, /* 1286 */ - { 59, 12, 3, 0, 0, 26624, 146, }, /* 1287 */ - { 59, 7, 4, 0, 0, 18432, 82, }, /* 1288 */ - { 59, 13, 12, 0, 0, 18432, 138, }, /* 1289 */ - { 61, 7, 12, 0, 0, 18432, 82, }, /* 1290 */ - { 61, 10, 5, 0, 0, 18432, 144, }, /* 1291 */ - { 61, 12, 3, 0, 0, 26624, 130, }, /* 1292 */ - { 61, 12, 3, 0, 0, 26624, 146, }, /* 1293 */ - { 61, 13, 12, 0, 0, 18432, 138, }, /* 1294 */ - { 150, 7, 12, 0, 0, 18432, 82, }, /* 1295 */ - { 150, 12, 3, 0, 0, 26624, 130, }, /* 1296 */ - { 150, 10, 5, 0, 0, 18432, 144, }, /* 1297 */ - { 150, 21, 12, 0, 0, 18432, 124, }, /* 1298 */ - { 11, 15, 12, 0, 0, 18432, 68, }, /* 1299 */ - { 11, 21, 12, 0, 0, 18432, 68, }, /* 1300 */ - { 94, 7, 12, 0, 0, 18432, 82, }, /* 1301 */ - { 94, 14, 12, 0, 0, 18432, 82, }, /* 1302 */ - { 94, 21, 12, 0, 0, 18432, 106, }, /* 1303 */ - { 66, 7, 12, 0, 0, 18432, 82, }, /* 1304 */ - { 66, 21, 12, 0, 0, 18432, 68, }, /* 1305 */ - { 109, 7, 12, 0, 0, 18432, 82, }, /* 1306 */ - { 109, 1, 2, 0, 0, 18432, 322, }, /* 1307 */ - { 138, 7, 12, 0, 0, 18432, 82, }, /* 1308 */ - { 130, 7, 12, 0, 0, 18432, 82, }, /* 1309 */ - { 130, 13, 12, 0, 0, 18432, 138, }, /* 1310 */ - { 130, 21, 12, 0, 0, 18432, 124, }, /* 1311 */ - { 159, 7, 12, 0, 0, 18432, 82, }, /* 1312 */ - { 159, 13, 12, 0, 0, 18432, 138, }, /* 1313 */ - { 126, 7, 12, 0, 0, 18432, 82, }, /* 1314 */ - { 126, 12, 3, 0, 0, 26624, 96, }, /* 1315 */ - { 126, 21, 12, 0, 0, 18432, 124, }, /* 1316 */ - { 128, 7, 12, 0, 0, 18432, 82, }, /* 1317 */ - { 128, 12, 3, 0, 0, 26624, 96, }, /* 1318 */ - { 128, 21, 12, 0, 0, 18432, 124, }, /* 1319 */ - { 128, 21, 12, 0, 0, 18432, 106, }, /* 1320 */ - { 128, 21, 12, 0, 0, 18432, 68, }, /* 1321 */ - { 128, 26, 12, 0, 0, 18432, 68, }, /* 1322 */ - { 128, 6, 12, 0, 0, 18432, 142, }, /* 1323 */ - { 128, 6, 12, 0, 0, 18432, 136, }, /* 1324 */ - { 128, 13, 12, 0, 0, 18432, 138, }, /* 1325 */ - { 128, 15, 12, 0, 0, 18432, 68, }, /* 1326 */ - { 151, 9, 12, 0, 32, 18432, 74, }, /* 1327 */ - { 151, 5, 12, 0, -32, 18432, 76, }, /* 1328 */ - { 151, 15, 12, 0, 0, 18432, 68, }, /* 1329 */ - { 151, 21, 12, 0, 0, 18432, 106, }, /* 1330 */ - { 151, 21, 12, 0, 0, 18432, 124, }, /* 1331 */ - { 151, 21, 12, 0, 0, 18432, 68, }, /* 1332 */ - { 123, 7, 12, 0, 0, 18432, 82, }, /* 1333 */ - { 123, 12, 3, 0, 0, 26624, 130, }, /* 1334 */ - { 123, 10, 5, 0, 0, 18432, 144, }, /* 1335 */ - { 123, 12, 3, 0, 0, 26624, 128, }, /* 1336 */ - { 123, 6, 12, 0, 0, 18432, 92, }, /* 1337 */ - { 146, 6, 12, 0, 0, 18432, 136, }, /* 1338 */ - { 147, 6, 12, 0, 0, 18432, 136, }, /* 1339 */ - { 23, 21, 12, 0, 0, 28672, 68, }, /* 1340 */ - { 158, 12, 3, 0, 0, 26624, 328, }, /* 1341 */ - { 23, 10, 5, 0, 0, 18432, 164, }, /* 1342 */ - { 146, 7, 12, 0, 0, 18432, 284, }, /* 1343 */ - { 158, 7, 12, 0, 0, 18432, 284, }, /* 1344 */ - { 21, 6, 12, 0, 0, 18432, 92, }, /* 1345 */ - { 147, 7, 12, 0, 0, 18432, 284, }, /* 1346 */ - { 46, 7, 12, 0, 0, 18432, 82, }, /* 1347 */ - { 46, 26, 12, 0, 0, 18432, 68, }, /* 1348 */ - { 46, 12, 3, 0, 0, 26624, 102, }, /* 1349 */ - { 46, 12, 3, 0, 0, 26624, 130, }, /* 1350 */ - { 46, 21, 12, 0, 0, 18432, 124, }, /* 1351 */ - { 69, 1, 2, 0, 0, 6153, 66, }, /* 1352 */ - { 69, 10, 3, 0, 0, 18432, 330, }, /* 1353 */ - { 69, 10, 5, 0, 0, 18432, 138, }, /* 1354 */ - { 69, 10, 5, 0, 0, 18432, 160, }, /* 1355 */ - { 69, 10, 3, 0, 0, 18432, 286, }, /* 1356 */ - { 1, 12, 3, 0, 0, 26624, 102, }, /* 1357 */ - { 69, 25, 12, 0, 0, 18432, 118, }, /* 1358 */ - { 69, 13, 12, 0, 0, 10240, 214, }, /* 1359 */ - { 141, 26, 12, 0, 0, 18432, 68, }, /* 1360 */ - { 141, 12, 3, 0, 0, 26624, 102, }, /* 1361 */ - { 141, 21, 12, 0, 0, 18432, 106, }, /* 1362 */ - { 141, 21, 12, 0, 0, 18432, 124, }, /* 1363 */ - { 141, 21, 12, 0, 0, 18432, 68, }, /* 1364 */ - { 35, 12, 3, 0, 0, 26624, 130, }, /* 1365 */ - { 154, 7, 12, 0, 0, 18432, 82, }, /* 1366 */ - { 154, 12, 3, 0, 0, 26624, 96, }, /* 1367 */ - { 154, 6, 12, 0, 0, 18432, 142, }, /* 1368 */ - { 154, 6, 12, 0, 0, 18432, 136, }, /* 1369 */ - { 154, 13, 12, 0, 0, 18432, 138, }, /* 1370 */ - { 154, 26, 12, 0, 0, 18432, 68, }, /* 1371 */ - { 160, 7, 12, 0, 0, 18432, 82, }, /* 1372 */ - { 160, 12, 3, 0, 0, 26624, 96, }, /* 1373 */ - { 155, 7, 12, 0, 0, 18432, 82, }, /* 1374 */ - { 155, 12, 3, 0, 0, 26624, 96, }, /* 1375 */ - { 155, 13, 12, 0, 0, 18432, 138, }, /* 1376 */ - { 155, 23, 12, 0, 0, 14336, 68, }, /* 1377 */ - { 129, 7, 12, 0, 0, 34816, 82, }, /* 1378 */ - { 129, 15, 12, 0, 0, 34816, 68, }, /* 1379 */ - { 129, 12, 3, 0, 0, 26624, 96, }, /* 1380 */ - { 58, 9, 12, 0, 34, 34816, 74, }, /* 1381 */ - { 58, 5, 12, 0, -34, 34816, 76, }, /* 1382 */ - { 58, 12, 3, 0, 0, 26624, 150, }, /* 1383 */ - { 58, 12, 3, 0, 0, 26624, 130, }, /* 1384 */ - { 58, 12, 3, 0, 0, 26624, 96, }, /* 1385 */ - { 58, 6, 12, 0, 0, 34816, 142, }, /* 1386 */ - { 58, 13, 12, 0, 0, 34816, 138, }, /* 1387 */ - { 58, 21, 12, 0, 0, 34816, 68, }, /* 1388 */ - { 69, 15, 12, 0, 0, 0, 68, }, /* 1389 */ - { 69, 26, 12, 0, 0, 0, 68, }, /* 1390 */ - { 69, 23, 12, 0, 0, 0, 68, }, /* 1391 */ - { 3, 7, 12, 0, 0, 0, 240, }, /* 1392 */ - { 69, 26, 14, 0, 0, 28672, 332, }, /* 1393 */ - { 69, 26, 14, 0, 0, 28672, 334, }, /* 1394 */ - { 68, 2, 14, 0, 0, 18432, 336, }, /* 1395 */ - { 69, 26, 12, 0, 0, 18432, 338, }, /* 1396 */ - { 69, 26, 14, 0, 0, 18432, 340, }, /* 1397 */ - { 69, 26, 14, 0, 0, 18432, 334, }, /* 1398 */ - { 69, 26, 11, 0, 0, 18432, 342, }, /* 1399 */ - { 20, 26, 12, 0, 0, 18432, 68, }, /* 1400 */ - { 69, 26, 14, 0, 0, 18432, 236, }, /* 1401 */ - { 69, 26, 14, 0, 0, 18447, 334, }, /* 1402 */ - { 69, 26, 14, 0, 0, 28672, 344, }, /* 1403 */ - { 69, 26, 14, 0, 0, 28672, 346, }, /* 1404 */ - { 69, 24, 3, 0, 0, 28672, 348, }, /* 1405 */ - { 69, 26, 14, 0, 0, 28672, 350, }, /* 1406 */ - { 69, 13, 12, 0, 0, 10240, 138, }, /* 1407 */ - { 69, 1, 3, 0, 0, 6144, 352, }, /* 1408 */ + { 76, 5, 12, 0, -38864, 18432, 70, }, /* 945 */ + { 113, 10, 5, 0, 0, 18432, 160, }, /* 946 */ + { 113, 13, 12, 0, 0, 18432, 138, }, /* 947 */ + { 18, 7, 9, 0, 0, 18432, 82, }, /* 948 */ + { 18, 7, 10, 0, 0, 18432, 82, }, /* 949 */ + { 68, 4, 12, 0, 0, 18432, 0, }, /* 950 */ + { 68, 3, 12, 0, 0, 18432, 0, }, /* 951 */ + { 23, 7, 12, 0, 0, 18432, 284, }, /* 952 */ + { 71, 25, 12, 0, 0, 12288, 118, }, /* 953 */ + { 3, 7, 12, 0, 0, 0, 296, }, /* 954 */ + { 69, 18, 12, 0, 0, 28705, 54, }, /* 955 */ + { 69, 22, 12, 0, 0, 28705, 54, }, /* 956 */ + { 68, 2, 12, 0, 0, 6144, 298, }, /* 957 */ + { 3, 7, 12, 0, 0, 39, 82, }, /* 958 */ + { 3, 26, 12, 0, 0, 28711, 68, }, /* 959 */ + { 84, 12, 3, 0, 0, 26624, 180, }, /* 960 */ + { 84, 12, 3, 0, 0, 26624, 300, }, /* 961 */ + { 69, 21, 12, 0, 0, 28672, 68, }, /* 962 */ + { 69, 21, 12, 0, 0, 28672, 122, }, /* 963 */ + { 69, 22, 12, 0, 0, 28672, 68, }, /* 964 */ + { 69, 18, 12, 0, 0, 28672, 68, }, /* 965 */ + { 69, 17, 12, 0, 0, 28672, 126, }, /* 966 */ + { 69, 22, 12, 0, 0, 28672, 302, }, /* 967 */ + { 69, 18, 12, 0, 0, 28672, 302, }, /* 968 */ + { 69, 21, 12, 0, 0, 8192, 106, }, /* 969 */ + { 69, 21, 12, 0, 0, 8192, 304, }, /* 970 */ + { 69, 21, 12, 0, 0, 8192, 306, }, /* 971 */ + { 69, 21, 12, 0, 0, 28672, 124, }, /* 972 */ + { 69, 22, 12, 0, 0, 28672, 158, }, /* 973 */ + { 69, 18, 12, 0, 0, 28672, 158, }, /* 974 */ + { 69, 21, 12, 0, 0, 14336, 68, }, /* 975 */ + { 69, 21, 12, 0, 0, 28672, 118, }, /* 976 */ + { 69, 17, 12, 0, 0, 12288, 224, }, /* 977 */ + { 69, 25, 12, 0, 0, 28672, 226, }, /* 978 */ + { 69, 21, 12, 0, 0, 28672, 302, }, /* 979 */ + { 69, 21, 12, 0, 0, 28672, 308, }, /* 980 */ + { 69, 17, 12, 0, 0, 12288, 126, }, /* 981 */ + { 69, 21, 12, 0, 0, 8192, 68, }, /* 982 */ + { 69, 13, 12, 0, 0, 10240, 310, }, /* 983 */ + { 0, 9, 12, 0, 32, 18432, 312, }, /* 984 */ + { 69, 24, 12, 0, 0, 28672, 314, }, /* 985 */ + { 0, 5, 12, 0, -32, 18432, 316, }, /* 986 */ + { 69, 21, 12, 0, 0, 28825, 124, }, /* 987 */ + { 69, 22, 12, 0, 0, 28825, 318, }, /* 988 */ + { 69, 18, 12, 0, 0, 28825, 318, }, /* 989 */ + { 69, 21, 12, 0, 0, 28825, 106, }, /* 990 */ + { 69, 6, 3, 0, 0, 18525, 320, }, /* 991 */ + { 69, 1, 2, 0, 0, 28672, 322, }, /* 992 */ + { 31, 7, 12, 0, 0, 18432, 82, }, /* 993 */ + { 69, 21, 12, 0, 0, 18552, 68, }, /* 994 */ + { 69, 21, 12, 0, 0, 28792, 68, }, /* 995 */ + { 69, 21, 12, 0, 0, 18483, 68, }, /* 996 */ + { 69, 15, 12, 0, 0, 18555, 68, }, /* 997 */ + { 69, 26, 12, 0, 0, 18483, 68, }, /* 998 */ + { 1, 14, 12, 0, 0, 28672, 82, }, /* 999 */ + { 1, 15, 12, 0, 0, 28672, 68, }, /* 1000 */ + { 1, 26, 12, 0, 0, 28672, 68, }, /* 1001 */ + { 1, 26, 12, 0, 0, 18432, 68, }, /* 1002 */ + { 102, 7, 12, 0, 0, 18432, 82, }, /* 1003 */ + { 103, 7, 12, 0, 0, 18432, 82, }, /* 1004 */ + { 84, 12, 3, 0, 0, 26651, 96, }, /* 1005 */ + { 69, 15, 12, 0, 0, 10267, 68, }, /* 1006 */ + { 81, 7, 12, 0, 0, 18432, 82, }, /* 1007 */ + { 81, 15, 12, 0, 0, 18432, 68, }, /* 1008 */ + { 82, 7, 12, 0, 0, 18432, 82, }, /* 1009 */ + { 82, 14, 12, 0, 0, 18432, 82, }, /* 1010 */ + { 53, 7, 12, 0, 0, 18432, 82, }, /* 1011 */ + { 53, 12, 3, 0, 0, 26624, 130, }, /* 1012 */ + { 85, 7, 12, 0, 0, 18432, 82, }, /* 1013 */ + { 85, 21, 12, 0, 0, 18432, 106, }, /* 1014 */ + { 91, 7, 12, 0, 0, 18432, 82, }, /* 1015 */ + { 91, 21, 12, 0, 0, 18432, 106, }, /* 1016 */ + { 91, 14, 12, 0, 0, 18432, 82, }, /* 1017 */ + { 83, 9, 12, 0, 40, 18432, 74, }, /* 1018 */ + { 83, 5, 12, 0, -40, 18432, 76, }, /* 1019 */ + { 86, 7, 12, 0, 0, 18432, 82, }, /* 1020 */ + { 87, 7, 12, 0, 0, 18432, 82, }, /* 1021 */ + { 87, 13, 12, 0, 0, 18432, 138, }, /* 1022 */ + { 145, 9, 12, 0, 40, 18432, 74, }, /* 1023 */ + { 145, 5, 12, 0, -40, 18432, 76, }, /* 1024 */ + { 127, 7, 12, 0, 0, 18432, 82, }, /* 1025 */ + { 125, 7, 12, 0, 0, 18432, 82, }, /* 1026 */ + { 125, 21, 12, 0, 0, 18432, 68, }, /* 1027 */ + { 161, 9, 12, 0, 39, 18432, 74, }, /* 1028 */ + { 161, 5, 12, 0, -39, 18432, 76, }, /* 1029 */ + { 49, 7, 12, 0, 0, 18432, 82, }, /* 1030 */ + { 0, 6, 12, 0, 0, 18432, 94, }, /* 1031 */ + { 32, 7, 12, 0, 0, 34816, 82, }, /* 1032 */ + { 114, 7, 12, 0, 0, 34816, 82, }, /* 1033 */ + { 114, 21, 12, 0, 0, 34816, 106, }, /* 1034 */ + { 114, 15, 12, 0, 0, 34816, 68, }, /* 1035 */ + { 133, 7, 12, 0, 0, 34816, 82, }, /* 1036 */ + { 133, 26, 12, 0, 0, 34816, 68, }, /* 1037 */ + { 133, 15, 12, 0, 0, 34816, 68, }, /* 1038 */ + { 132, 7, 12, 0, 0, 34816, 82, }, /* 1039 */ + { 132, 15, 12, 0, 0, 34816, 68, }, /* 1040 */ + { 139, 7, 12, 0, 0, 34816, 82, }, /* 1041 */ + { 139, 15, 12, 0, 0, 34816, 68, }, /* 1042 */ + { 95, 7, 12, 0, 0, 34816, 82, }, /* 1043 */ + { 95, 15, 12, 0, 0, 34816, 68, }, /* 1044 */ + { 95, 21, 12, 0, 0, 28672, 106, }, /* 1045 */ + { 104, 7, 12, 0, 0, 34816, 82, }, /* 1046 */ + { 104, 21, 12, 0, 0, 34816, 68, }, /* 1047 */ + { 122, 7, 12, 0, 0, 34816, 82, }, /* 1048 */ + { 121, 7, 12, 0, 0, 34816, 82, }, /* 1049 */ + { 121, 15, 12, 0, 0, 34816, 68, }, /* 1050 */ + { 92, 7, 12, 0, 0, 34816, 82, }, /* 1051 */ + { 92, 12, 3, 0, 0, 26624, 130, }, /* 1052 */ + { 92, 12, 3, 0, 0, 26624, 102, }, /* 1053 */ + { 92, 12, 3, 0, 0, 26624, 184, }, /* 1054 */ + { 92, 15, 12, 0, 0, 34816, 68, }, /* 1055 */ + { 92, 21, 12, 0, 0, 34816, 68, }, /* 1056 */ + { 92, 21, 12, 0, 0, 34816, 124, }, /* 1057 */ + { 115, 7, 12, 0, 0, 34816, 82, }, /* 1058 */ + { 115, 15, 12, 0, 0, 34816, 68, }, /* 1059 */ + { 115, 21, 12, 0, 0, 34816, 68, }, /* 1060 */ + { 131, 7, 12, 0, 0, 34816, 82, }, /* 1061 */ + { 131, 15, 12, 0, 0, 34816, 68, }, /* 1062 */ + { 51, 7, 12, 0, 0, 34816, 82, }, /* 1063 */ + { 51, 26, 12, 0, 0, 34816, 68, }, /* 1064 */ + { 51, 12, 3, 0, 0, 26624, 96, }, /* 1065 */ + { 51, 15, 12, 0, 0, 34816, 68, }, /* 1066 */ + { 51, 21, 12, 0, 0, 34816, 106, }, /* 1067 */ + { 51, 21, 12, 0, 0, 34918, 106, }, /* 1068 */ + { 51, 21, 12, 0, 0, 34816, 68, }, /* 1069 */ + { 108, 7, 12, 0, 0, 34816, 82, }, /* 1070 */ + { 108, 21, 12, 0, 0, 28672, 68, }, /* 1071 */ + { 108, 21, 12, 0, 0, 28672, 106, }, /* 1072 */ + { 116, 7, 12, 0, 0, 34816, 82, }, /* 1073 */ + { 116, 15, 12, 0, 0, 34816, 68, }, /* 1074 */ + { 117, 7, 12, 0, 0, 34816, 82, }, /* 1075 */ + { 117, 15, 12, 0, 0, 34816, 68, }, /* 1076 */ + { 54, 7, 12, 0, 0, 34816, 82, }, /* 1077 */ + { 54, 21, 12, 0, 0, 34816, 106, }, /* 1078 */ + { 54, 15, 12, 0, 0, 34816, 68, }, /* 1079 */ + { 118, 7, 12, 0, 0, 34816, 82, }, /* 1080 */ + { 140, 9, 12, 0, 64, 34816, 74, }, /* 1081 */ + { 140, 5, 12, 0, -64, 34816, 76, }, /* 1082 */ + { 140, 15, 12, 0, 0, 34816, 68, }, /* 1083 */ + { 62, 7, 12, 0, 0, 0, 82, }, /* 1084 */ + { 62, 7, 12, 0, 0, 0, 294, }, /* 1085 */ + { 62, 12, 3, 0, 0, 26624, 128, }, /* 1086 */ + { 62, 13, 12, 0, 0, 2048, 138, }, /* 1087 */ + { 3, 15, 12, 0, 0, 2048, 68, }, /* 1088 */ + { 65, 7, 12, 0, 0, 34816, 82, }, /* 1089 */ + { 65, 12, 3, 0, 0, 26624, 130, }, /* 1090 */ + { 65, 17, 12, 0, 0, 34816, 126, }, /* 1091 */ + { 152, 7, 12, 0, 0, 34816, 82, }, /* 1092 */ + { 152, 15, 12, 0, 0, 34816, 68, }, /* 1093 */ + { 63, 7, 12, 0, 0, 0, 82, }, /* 1094 */ + { 63, 12, 3, 0, 0, 26624, 96, }, /* 1095 */ + { 63, 15, 12, 0, 0, 0, 68, }, /* 1096 */ + { 63, 21, 12, 0, 0, 0, 124, }, /* 1097 */ + { 67, 7, 12, 0, 0, 34816, 82, }, /* 1098 */ + { 67, 12, 3, 0, 0, 26624, 96, }, /* 1099 */ + { 67, 21, 12, 0, 0, 34816, 124, }, /* 1100 */ + { 156, 7, 12, 0, 0, 34816, 82, }, /* 1101 */ + { 156, 15, 12, 0, 0, 34816, 68, }, /* 1102 */ + { 153, 7, 12, 0, 0, 34816, 82, }, /* 1103 */ + { 120, 10, 5, 0, 0, 18432, 144, }, /* 1104 */ + { 120, 12, 3, 0, 0, 26624, 130, }, /* 1105 */ + { 120, 7, 12, 0, 0, 18432, 82, }, /* 1106 */ + { 120, 12, 3, 0, 0, 26624, 146, }, /* 1107 */ + { 120, 21, 12, 0, 0, 18432, 124, }, /* 1108 */ + { 120, 21, 12, 0, 0, 18432, 106, }, /* 1109 */ + { 120, 15, 12, 0, 0, 28672, 68, }, /* 1110 */ + { 120, 13, 12, 0, 0, 18432, 138, }, /* 1111 */ + { 120, 12, 3, 0, 0, 26624, 184, }, /* 1112 */ + { 41, 12, 3, 0, 0, 26624, 130, }, /* 1113 */ + { 41, 10, 5, 0, 0, 18432, 144, }, /* 1114 */ + { 41, 7, 12, 0, 0, 18432, 82, }, /* 1115 */ + { 41, 12, 3, 0, 0, 26624, 146, }, /* 1116 */ + { 41, 12, 3, 0, 0, 26624, 96, }, /* 1117 */ + { 41, 21, 12, 0, 0, 18432, 68, }, /* 1118 */ + { 41, 1, 4, 0, 0, 18432, 132, }, /* 1119 */ + { 41, 21, 12, 0, 0, 18432, 124, }, /* 1120 */ + { 124, 7, 12, 0, 0, 18432, 82, }, /* 1121 */ + { 124, 13, 12, 0, 0, 18432, 138, }, /* 1122 */ + { 43, 12, 3, 0, 0, 26624, 130, }, /* 1123 */ + { 43, 7, 12, 0, 0, 18432, 82, }, /* 1124 */ + { 43, 10, 5, 0, 0, 18432, 144, }, /* 1125 */ + { 43, 12, 3, 0, 0, 26624, 146, }, /* 1126 */ + { 43, 13, 12, 0, 0, 18432, 138, }, /* 1127 */ + { 43, 21, 12, 0, 0, 18432, 68, }, /* 1128 */ + { 43, 21, 12, 0, 0, 18432, 124, }, /* 1129 */ + { 50, 7, 12, 0, 0, 18432, 82, }, /* 1130 */ + { 50, 12, 3, 0, 0, 26624, 96, }, /* 1131 */ + { 50, 21, 12, 0, 0, 18432, 68, }, /* 1132 */ + { 44, 12, 3, 0, 0, 26624, 130, }, /* 1133 */ + { 44, 10, 5, 0, 0, 18432, 144, }, /* 1134 */ + { 44, 7, 12, 0, 0, 18432, 82, }, /* 1135 */ + { 44, 10, 5, 0, 0, 18432, 174, }, /* 1136 */ + { 44, 7, 4, 0, 0, 18432, 82, }, /* 1137 */ + { 44, 21, 12, 0, 0, 18432, 124, }, /* 1138 */ + { 44, 21, 12, 0, 0, 18432, 68, }, /* 1139 */ + { 44, 12, 3, 0, 0, 26624, 102, }, /* 1140 */ + { 44, 12, 3, 0, 0, 26624, 96, }, /* 1141 */ + { 44, 13, 12, 0, 0, 18432, 138, }, /* 1142 */ + { 15, 15, 12, 0, 0, 18432, 68, }, /* 1143 */ + { 48, 7, 12, 0, 0, 18432, 82, }, /* 1144 */ + { 48, 10, 5, 0, 0, 18432, 144, }, /* 1145 */ + { 48, 12, 3, 0, 0, 26624, 130, }, /* 1146 */ + { 48, 10, 5, 0, 0, 18432, 174, }, /* 1147 */ + { 48, 12, 3, 0, 0, 26624, 96, }, /* 1148 */ + { 48, 21, 12, 0, 0, 18432, 124, }, /* 1149 */ + { 48, 21, 12, 0, 0, 18432, 106, }, /* 1150 */ + { 48, 21, 12, 0, 0, 18432, 68, }, /* 1151 */ + { 57, 7, 12, 0, 0, 18432, 82, }, /* 1152 */ + { 57, 21, 12, 0, 0, 18432, 124, }, /* 1153 */ + { 55, 7, 12, 0, 0, 18432, 82, }, /* 1154 */ + { 55, 12, 3, 0, 0, 26624, 130, }, /* 1155 */ + { 55, 10, 5, 0, 0, 18432, 144, }, /* 1156 */ + { 55, 12, 3, 0, 0, 26624, 96, }, /* 1157 */ + { 55, 12, 3, 0, 0, 26624, 146, }, /* 1158 */ + { 55, 13, 12, 0, 0, 18432, 138, }, /* 1159 */ + { 47, 12, 3, 0, 0, 26624, 130, }, /* 1160 */ + { 47, 12, 3, 0, 0, 26705, 130, }, /* 1161 */ + { 47, 10, 5, 0, 0, 18432, 144, }, /* 1162 */ + { 47, 10, 5, 0, 0, 18513, 144, }, /* 1163 */ + { 47, 7, 12, 0, 0, 18432, 82, }, /* 1164 */ + { 84, 12, 3, 0, 0, 26705, 102, }, /* 1165 */ + { 47, 12, 3, 0, 0, 26705, 96, }, /* 1166 */ + { 47, 10, 3, 0, 0, 18432, 148, }, /* 1167 */ + { 47, 10, 5, 0, 0, 18432, 174, }, /* 1168 */ + { 47, 7, 12, 0, 0, 18432, 324, }, /* 1169 */ + { 47, 12, 3, 0, 0, 26624, 96, }, /* 1170 */ + { 144, 7, 12, 0, 0, 18432, 82, }, /* 1171 */ + { 144, 10, 5, 0, 0, 18432, 144, }, /* 1172 */ + { 144, 12, 3, 0, 0, 26624, 130, }, /* 1173 */ + { 144, 12, 3, 0, 0, 26624, 146, }, /* 1174 */ + { 144, 12, 3, 0, 0, 26624, 96, }, /* 1175 */ + { 144, 21, 12, 0, 0, 18432, 124, }, /* 1176 */ + { 144, 21, 12, 0, 0, 18432, 106, }, /* 1177 */ + { 144, 21, 12, 0, 0, 18432, 68, }, /* 1178 */ + { 144, 13, 12, 0, 0, 18432, 138, }, /* 1179 */ + { 144, 12, 3, 0, 0, 26624, 102, }, /* 1180 */ + { 56, 7, 12, 0, 0, 18432, 82, }, /* 1181 */ + { 56, 10, 3, 0, 0, 18432, 148, }, /* 1182 */ + { 56, 10, 5, 0, 0, 18432, 144, }, /* 1183 */ + { 56, 12, 3, 0, 0, 26624, 130, }, /* 1184 */ + { 56, 12, 3, 0, 0, 26624, 146, }, /* 1185 */ + { 56, 12, 3, 0, 0, 26624, 96, }, /* 1186 */ + { 56, 21, 12, 0, 0, 18432, 68, }, /* 1187 */ + { 56, 13, 12, 0, 0, 18432, 138, }, /* 1188 */ + { 135, 7, 12, 0, 0, 18432, 82, }, /* 1189 */ + { 135, 10, 3, 0, 0, 18432, 148, }, /* 1190 */ + { 135, 10, 5, 0, 0, 18432, 144, }, /* 1191 */ + { 135, 12, 3, 0, 0, 26624, 130, }, /* 1192 */ + { 135, 12, 3, 0, 0, 26624, 146, }, /* 1193 */ + { 135, 12, 3, 0, 0, 26624, 96, }, /* 1194 */ + { 135, 21, 12, 0, 0, 18432, 68, }, /* 1195 */ + { 135, 21, 12, 0, 0, 18432, 124, }, /* 1196 */ + { 135, 21, 12, 0, 0, 18432, 106, }, /* 1197 */ + { 135, 21, 12, 0, 0, 18432, 178, }, /* 1198 */ + { 52, 7, 12, 0, 0, 18432, 82, }, /* 1199 */ + { 52, 10, 5, 0, 0, 18432, 144, }, /* 1200 */ + { 52, 12, 3, 0, 0, 26624, 130, }, /* 1201 */ + { 52, 12, 3, 0, 0, 26624, 146, }, /* 1202 */ + { 52, 21, 12, 0, 0, 18432, 124, }, /* 1203 */ + { 52, 21, 12, 0, 0, 18432, 68, }, /* 1204 */ + { 52, 13, 12, 0, 0, 18432, 138, }, /* 1205 */ + { 45, 7, 12, 0, 0, 18432, 82, }, /* 1206 */ + { 45, 12, 3, 0, 0, 26624, 130, }, /* 1207 */ + { 45, 10, 5, 0, 0, 18432, 144, }, /* 1208 */ + { 45, 10, 5, 0, 0, 18432, 174, }, /* 1209 */ + { 45, 12, 3, 0, 0, 26624, 96, }, /* 1210 */ + { 45, 21, 12, 0, 0, 18432, 68, }, /* 1211 */ + { 45, 13, 12, 0, 0, 18432, 138, }, /* 1212 */ + { 137, 7, 12, 0, 0, 18432, 82, }, /* 1213 */ + { 137, 12, 3, 0, 0, 26624, 130, }, /* 1214 */ + { 137, 10, 12, 0, 0, 18432, 144, }, /* 1215 */ + { 137, 10, 5, 0, 0, 18432, 144, }, /* 1216 */ + { 137, 12, 3, 0, 0, 26624, 146, }, /* 1217 */ + { 137, 13, 12, 0, 0, 18432, 138, }, /* 1218 */ + { 137, 15, 12, 0, 0, 18432, 68, }, /* 1219 */ + { 137, 21, 12, 0, 0, 18432, 124, }, /* 1220 */ + { 137, 26, 12, 0, 0, 18432, 68, }, /* 1221 */ + { 60, 7, 12, 0, 0, 18432, 82, }, /* 1222 */ + { 60, 10, 5, 0, 0, 18432, 144, }, /* 1223 */ + { 60, 12, 3, 0, 0, 26624, 130, }, /* 1224 */ + { 60, 12, 3, 0, 0, 26624, 146, }, /* 1225 */ + { 60, 12, 3, 0, 0, 26624, 96, }, /* 1226 */ + { 60, 21, 12, 0, 0, 18432, 68, }, /* 1227 */ + { 136, 9, 12, 0, 32, 18432, 74, }, /* 1228 */ + { 136, 5, 12, 0, -32, 18432, 76, }, /* 1229 */ + { 136, 13, 12, 0, 0, 18432, 138, }, /* 1230 */ + { 136, 15, 12, 0, 0, 18432, 68, }, /* 1231 */ + { 136, 7, 12, 0, 0, 18432, 82, }, /* 1232 */ + { 157, 7, 12, 0, 0, 18432, 82, }, /* 1233 */ + { 157, 10, 3, 0, 0, 18432, 148, }, /* 1234 */ + { 157, 10, 5, 0, 0, 18432, 144, }, /* 1235 */ + { 157, 12, 3, 0, 0, 26624, 130, }, /* 1236 */ + { 157, 10, 5, 0, 0, 18432, 174, }, /* 1237 */ + { 157, 12, 3, 0, 0, 26624, 146, }, /* 1238 */ + { 157, 7, 4, 0, 0, 18432, 82, }, /* 1239 */ + { 157, 12, 3, 0, 0, 26624, 96, }, /* 1240 */ + { 157, 21, 12, 0, 0, 18432, 124, }, /* 1241 */ + { 157, 21, 12, 0, 0, 18432, 68, }, /* 1242 */ + { 157, 13, 12, 0, 0, 18432, 138, }, /* 1243 */ + { 64, 7, 12, 0, 0, 18432, 82, }, /* 1244 */ + { 64, 10, 5, 0, 0, 18432, 144, }, /* 1245 */ + { 64, 12, 3, 0, 0, 26624, 130, }, /* 1246 */ + { 64, 12, 3, 0, 0, 26624, 146, }, /* 1247 */ + { 64, 21, 12, 0, 0, 18432, 68, }, /* 1248 */ + { 149, 7, 12, 0, 0, 18432, 82, }, /* 1249 */ + { 149, 12, 3, 0, 0, 26624, 130, }, /* 1250 */ + { 149, 12, 3, 0, 0, 18432, 130, }, /* 1251 */ + { 149, 12, 3, 0, 0, 26624, 102, }, /* 1252 */ + { 149, 12, 3, 0, 0, 26624, 146, }, /* 1253 */ + { 149, 10, 5, 0, 0, 18432, 144, }, /* 1254 */ + { 149, 7, 4, 0, 0, 18432, 82, }, /* 1255 */ + { 149, 21, 12, 0, 0, 18432, 68, }, /* 1256 */ + { 149, 21, 12, 0, 0, 18432, 124, }, /* 1257 */ + { 148, 7, 12, 0, 0, 18432, 82, }, /* 1258 */ + { 148, 12, 3, 0, 0, 26624, 130, }, /* 1259 */ + { 148, 10, 5, 0, 0, 18432, 144, }, /* 1260 */ + { 148, 7, 4, 0, 0, 18432, 82, }, /* 1261 */ + { 148, 12, 3, 0, 0, 26624, 326, }, /* 1262 */ + { 148, 12, 3, 0, 0, 26624, 146, }, /* 1263 */ + { 148, 21, 12, 0, 0, 18432, 68, }, /* 1264 */ + { 148, 21, 12, 0, 0, 18432, 124, }, /* 1265 */ + { 148, 21, 12, 0, 0, 18432, 106, }, /* 1266 */ + { 134, 7, 12, 0, 0, 18432, 82, }, /* 1267 */ + { 142, 7, 12, 0, 0, 18432, 82, }, /* 1268 */ + { 142, 10, 5, 0, 0, 18432, 144, }, /* 1269 */ + { 142, 12, 3, 0, 0, 26624, 130, }, /* 1270 */ + { 142, 12, 3, 0, 0, 18432, 146, }, /* 1271 */ + { 142, 21, 12, 0, 0, 18432, 124, }, /* 1272 */ + { 142, 21, 12, 0, 0, 18432, 106, }, /* 1273 */ + { 142, 21, 12, 0, 0, 18432, 68, }, /* 1274 */ + { 142, 13, 12, 0, 0, 18432, 138, }, /* 1275 */ + { 142, 15, 12, 0, 0, 18432, 68, }, /* 1276 */ + { 143, 21, 12, 0, 0, 18432, 68, }, /* 1277 */ + { 143, 21, 12, 0, 0, 18432, 106, }, /* 1278 */ + { 143, 7, 12, 0, 0, 18432, 82, }, /* 1279 */ + { 143, 12, 3, 0, 0, 26624, 130, }, /* 1280 */ + { 143, 10, 5, 0, 0, 18432, 144, }, /* 1281 */ + { 59, 7, 12, 0, 0, 18432, 82, }, /* 1282 */ + { 59, 12, 3, 0, 0, 26624, 130, }, /* 1283 */ + { 59, 12, 3, 0, 0, 26624, 96, }, /* 1284 */ + { 59, 12, 3, 0, 0, 26624, 146, }, /* 1285 */ + { 59, 7, 4, 0, 0, 18432, 82, }, /* 1286 */ + { 59, 13, 12, 0, 0, 18432, 138, }, /* 1287 */ + { 61, 7, 12, 0, 0, 18432, 82, }, /* 1288 */ + { 61, 10, 5, 0, 0, 18432, 144, }, /* 1289 */ + { 61, 12, 3, 0, 0, 26624, 130, }, /* 1290 */ + { 61, 12, 3, 0, 0, 26624, 146, }, /* 1291 */ + { 61, 13, 12, 0, 0, 18432, 138, }, /* 1292 */ + { 150, 7, 12, 0, 0, 18432, 82, }, /* 1293 */ + { 150, 12, 3, 0, 0, 26624, 130, }, /* 1294 */ + { 150, 10, 5, 0, 0, 18432, 144, }, /* 1295 */ + { 150, 21, 12, 0, 0, 18432, 124, }, /* 1296 */ + { 162, 12, 3, 0, 0, 26624, 130, }, /* 1297 */ + { 162, 7, 4, 0, 0, 18432, 82, }, /* 1298 */ + { 162, 10, 5, 0, 0, 18432, 144, }, /* 1299 */ + { 162, 7, 12, 0, 0, 18432, 82, }, /* 1300 */ + { 162, 10, 5, 0, 0, 18432, 176, }, /* 1301 */ + { 162, 12, 3, 0, 0, 26624, 184, }, /* 1302 */ + { 162, 21, 12, 0, 0, 18432, 124, }, /* 1303 */ + { 162, 21, 12, 0, 0, 18432, 68, }, /* 1304 */ + { 162, 13, 12, 0, 0, 18432, 138, }, /* 1305 */ + { 11, 15, 12, 0, 0, 18432, 68, }, /* 1306 */ + { 11, 21, 12, 0, 0, 18432, 68, }, /* 1307 */ + { 94, 7, 12, 0, 0, 18432, 82, }, /* 1308 */ + { 94, 14, 12, 0, 0, 18432, 82, }, /* 1309 */ + { 94, 21, 12, 0, 0, 18432, 106, }, /* 1310 */ + { 66, 7, 12, 0, 0, 18432, 82, }, /* 1311 */ + { 66, 21, 12, 0, 0, 18432, 68, }, /* 1312 */ + { 109, 7, 12, 0, 0, 18432, 82, }, /* 1313 */ + { 109, 1, 2, 0, 0, 18432, 322, }, /* 1314 */ + { 109, 12, 3, 0, 0, 26624, 102, }, /* 1315 */ + { 109, 12, 3, 0, 0, 26624, 96, }, /* 1316 */ + { 138, 7, 12, 0, 0, 18432, 82, }, /* 1317 */ + { 130, 7, 12, 0, 0, 18432, 82, }, /* 1318 */ + { 130, 13, 12, 0, 0, 18432, 138, }, /* 1319 */ + { 130, 21, 12, 0, 0, 18432, 124, }, /* 1320 */ + { 159, 7, 12, 0, 0, 18432, 82, }, /* 1321 */ + { 159, 13, 12, 0, 0, 18432, 138, }, /* 1322 */ + { 126, 7, 12, 0, 0, 18432, 82, }, /* 1323 */ + { 126, 12, 3, 0, 0, 26624, 96, }, /* 1324 */ + { 126, 21, 12, 0, 0, 18432, 124, }, /* 1325 */ + { 128, 7, 12, 0, 0, 18432, 82, }, /* 1326 */ + { 128, 12, 3, 0, 0, 26624, 96, }, /* 1327 */ + { 128, 21, 12, 0, 0, 18432, 124, }, /* 1328 */ + { 128, 21, 12, 0, 0, 18432, 106, }, /* 1329 */ + { 128, 21, 12, 0, 0, 18432, 68, }, /* 1330 */ + { 128, 26, 12, 0, 0, 18432, 68, }, /* 1331 */ + { 128, 6, 12, 0, 0, 18432, 142, }, /* 1332 */ + { 128, 6, 12, 0, 0, 18432, 136, }, /* 1333 */ + { 128, 13, 12, 0, 0, 18432, 138, }, /* 1334 */ + { 128, 15, 12, 0, 0, 18432, 68, }, /* 1335 */ + { 151, 9, 12, 0, 32, 18432, 74, }, /* 1336 */ + { 151, 5, 12, 0, -32, 18432, 76, }, /* 1337 */ + { 151, 15, 12, 0, 0, 18432, 68, }, /* 1338 */ + { 151, 21, 12, 0, 0, 18432, 106, }, /* 1339 */ + { 151, 21, 12, 0, 0, 18432, 124, }, /* 1340 */ + { 151, 21, 12, 0, 0, 18432, 68, }, /* 1341 */ + { 123, 7, 12, 0, 0, 18432, 82, }, /* 1342 */ + { 123, 12, 3, 0, 0, 26624, 130, }, /* 1343 */ + { 123, 10, 5, 0, 0, 18432, 144, }, /* 1344 */ + { 123, 12, 3, 0, 0, 26624, 128, }, /* 1345 */ + { 123, 6, 12, 0, 0, 18432, 92, }, /* 1346 */ + { 146, 6, 12, 0, 0, 18432, 136, }, /* 1347 */ + { 147, 6, 12, 0, 0, 18432, 136, }, /* 1348 */ + { 23, 21, 12, 0, 0, 28672, 68, }, /* 1349 */ + { 158, 12, 3, 0, 0, 26624, 328, }, /* 1350 */ + { 23, 10, 5, 0, 0, 18432, 164, }, /* 1351 */ + { 146, 7, 12, 0, 0, 18432, 284, }, /* 1352 */ + { 158, 7, 12, 0, 0, 18432, 284, }, /* 1353 */ + { 21, 6, 12, 0, 0, 18432, 92, }, /* 1354 */ + { 147, 7, 12, 0, 0, 18432, 284, }, /* 1355 */ + { 46, 7, 12, 0, 0, 18432, 82, }, /* 1356 */ + { 46, 26, 12, 0, 0, 18432, 68, }, /* 1357 */ + { 46, 12, 3, 0, 0, 26624, 102, }, /* 1358 */ + { 46, 12, 3, 0, 0, 26624, 130, }, /* 1359 */ + { 46, 21, 12, 0, 0, 18432, 124, }, /* 1360 */ + { 69, 1, 2, 0, 0, 6153, 66, }, /* 1361 */ + { 69, 10, 3, 0, 0, 18432, 330, }, /* 1362 */ + { 69, 10, 5, 0, 0, 18432, 138, }, /* 1363 */ + { 69, 10, 5, 0, 0, 18432, 160, }, /* 1364 */ + { 69, 10, 3, 0, 0, 18432, 286, }, /* 1365 */ + { 1, 12, 3, 0, 0, 26624, 102, }, /* 1366 */ + { 69, 25, 12, 0, 0, 18432, 118, }, /* 1367 */ + { 69, 13, 12, 0, 0, 10240, 214, }, /* 1368 */ + { 141, 26, 12, 0, 0, 18432, 68, }, /* 1369 */ + { 141, 12, 3, 0, 0, 26624, 102, }, /* 1370 */ + { 141, 21, 12, 0, 0, 18432, 106, }, /* 1371 */ + { 141, 21, 12, 0, 0, 18432, 124, }, /* 1372 */ + { 141, 21, 12, 0, 0, 18432, 68, }, /* 1373 */ + { 35, 12, 3, 0, 0, 26624, 130, }, /* 1374 */ + { 2, 6, 12, 0, 0, 18432, 90, }, /* 1375 */ + { 154, 7, 12, 0, 0, 18432, 82, }, /* 1376 */ + { 154, 12, 3, 0, 0, 26624, 96, }, /* 1377 */ + { 154, 6, 12, 0, 0, 18432, 142, }, /* 1378 */ + { 154, 6, 12, 0, 0, 18432, 136, }, /* 1379 */ + { 154, 13, 12, 0, 0, 18432, 138, }, /* 1380 */ + { 154, 26, 12, 0, 0, 18432, 68, }, /* 1381 */ + { 160, 7, 12, 0, 0, 18432, 82, }, /* 1382 */ + { 160, 12, 3, 0, 0, 26624, 96, }, /* 1383 */ + { 155, 7, 12, 0, 0, 18432, 82, }, /* 1384 */ + { 155, 12, 3, 0, 0, 26624, 96, }, /* 1385 */ + { 155, 13, 12, 0, 0, 18432, 138, }, /* 1386 */ + { 155, 23, 12, 0, 0, 14336, 68, }, /* 1387 */ + { 163, 7, 12, 0, 0, 18432, 82, }, /* 1388 */ + { 163, 6, 12, 0, 0, 18432, 142, }, /* 1389 */ + { 163, 12, 3, 0, 0, 26624, 102, }, /* 1390 */ + { 163, 13, 12, 0, 0, 18432, 138, }, /* 1391 */ + { 129, 7, 12, 0, 0, 34816, 82, }, /* 1392 */ + { 129, 15, 12, 0, 0, 34816, 68, }, /* 1393 */ + { 129, 12, 3, 0, 0, 26624, 96, }, /* 1394 */ + { 58, 9, 12, 0, 34, 34816, 74, }, /* 1395 */ + { 58, 5, 12, 0, -34, 34816, 76, }, /* 1396 */ + { 58, 12, 3, 0, 0, 26624, 150, }, /* 1397 */ + { 58, 12, 3, 0, 0, 26624, 130, }, /* 1398 */ + { 58, 12, 3, 0, 0, 26624, 96, }, /* 1399 */ + { 58, 6, 12, 0, 0, 34816, 142, }, /* 1400 */ + { 58, 13, 12, 0, 0, 34816, 138, }, /* 1401 */ + { 58, 21, 12, 0, 0, 34816, 68, }, /* 1402 */ + { 69, 15, 12, 0, 0, 0, 68, }, /* 1403 */ + { 69, 26, 12, 0, 0, 0, 68, }, /* 1404 */ + { 69, 23, 12, 0, 0, 0, 68, }, /* 1405 */ + { 3, 7, 12, 0, 0, 0, 240, }, /* 1406 */ + { 69, 26, 14, 0, 0, 28672, 332, }, /* 1407 */ + { 69, 26, 14, 0, 0, 28672, 334, }, /* 1408 */ + { 68, 2, 14, 0, 0, 18432, 336, }, /* 1409 */ + { 69, 26, 12, 0, 0, 18432, 338, }, /* 1410 */ + { 69, 26, 14, 0, 0, 18432, 340, }, /* 1411 */ + { 69, 26, 14, 0, 0, 18432, 334, }, /* 1412 */ + { 69, 26, 11, 0, 0, 18432, 342, }, /* 1413 */ + { 20, 26, 12, 0, 0, 18432, 68, }, /* 1414 */ + { 69, 26, 14, 0, 0, 18432, 236, }, /* 1415 */ + { 69, 26, 14, 0, 0, 18447, 334, }, /* 1416 */ + { 69, 26, 14, 0, 0, 28672, 344, }, /* 1417 */ + { 69, 26, 14, 0, 0, 28672, 346, }, /* 1418 */ + { 69, 24, 3, 0, 0, 28672, 348, }, /* 1419 */ + { 69, 26, 14, 0, 0, 28672, 350, }, /* 1420 */ + { 69, 13, 12, 0, 0, 10240, 138, }, /* 1421 */ + { 69, 1, 3, 0, 0, 6144, 352, }, /* 1422 */ }; const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ @@ -1872,35 +1886,35 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 142,143,144,145,146,147,148,149,150,151,152,153,154,154,155,156, /* U+10000 */ 157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172, /* U+10800 */ 173,174,175,176,177,178,179,146,180,181,146,182,183,184,185,146, /* U+11000 */ -186,187,188,189,190,191,146,146,192,193,194,195,146,196,146,197, /* U+11800 */ -198,198,198,198,198,198,198,199,200,198,201,146,146,146,146,146, /* U+12000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,202, /* U+12800 */ -203,203,203,203,203,203,203,203,204,146,146,146,146,146,146,146, /* U+13000 */ +186,187,188,189,190,191,192,146,193,194,195,196,146,197,198,199, /* U+11800 */ +200,200,200,200,200,200,200,201,202,200,203,146,146,146,146,146, /* U+12000 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,204, /* U+12800 */ +205,205,205,205,205,205,205,205,206,146,146,146,146,146,146,146, /* U+13000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+13800 */ -146,146,146,146,146,146,146,146,205,205,205,205,206,146,146,146, /* U+14000 */ +146,146,146,146,146,146,146,146,207,207,207,207,208,146,146,146, /* U+14000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+14800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+15800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+16000 */ -207,207,207,207,208,209,210,211,146,146,146,146,212,213,214,215, /* U+16800 */ -216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, /* U+17000 */ -216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216, /* U+17800 */ -216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,217, /* U+18000 */ -216,216,216,216,216,216,218,218,218,219,220,146,146,146,146,146, /* U+18800 */ +209,209,209,209,210,211,212,213,146,146,146,146,214,215,216,217, /* U+16800 */ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, /* U+17000 */ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218, /* U+17800 */ +218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,219, /* U+18000 */ +218,218,218,218,218,218,220,220,220,221,222,146,146,146,146,146, /* U+18800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+19800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1A000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,221, /* U+1A800 */ -222,223,224,225,225,226,146,146,146,146,146,146,146,146,146,146, /* U+1B000 */ -146,146,146,146,146,146,146,146,227,228,146,146,146,146,146,146, /* U+1B800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,223, /* U+1A800 */ +224,225,226,227,227,228,146,146,146,146,146,146,146,146,146,146, /* U+1B000 */ +146,146,146,146,146,146,146,146,229,230,146,146,146,146,146,146, /* U+1B800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+1C000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,229,230, /* U+1C800 */ -231,232,233,234,235,236,237,146,238,239,240,241,242,243,244,245, /* U+1D000 */ -246,246,246,246,247,248,146,146,146,146,146,146,146,146,249,146, /* U+1D800 */ -250,146,251,146,146,252,146,146,146,146,146,146,146,146,146,253, /* U+1E000 */ -254,255,256,168,168,168,168,168,257,258,259,168,260,261,168,168, /* U+1E800 */ -262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277, /* U+1F000 */ -278,279,280,281,282,283,284,285,267,267,267,267,267,267,267,286, /* U+1F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,231,232, /* U+1C800 */ +233,234,235,236,237,238,239,146,240,241,242,243,244,245,246,247, /* U+1D000 */ +248,248,248,248,249,250,146,146,146,146,146,146,146,146,251,146, /* U+1D800 */ +252,253,254,146,146,255,146,146,146,256,146,146,146,146,146,257, /* U+1E000 */ +258,259,260,168,168,168,168,168,261,262,263,168,264,265,168,168, /* U+1E800 */ +266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281, /* U+1F000 */ +282,283,284,285,286,287,288,289,271,271,271,271,271,271,271,290, /* U+1F800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+20800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+21000 */ @@ -1921,23 +1935,23 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+28800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+29800 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,287,101,101, /* U+2A000 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,291,101,101, /* U+2A000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2A800 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,101,288,101, /* U+2B000 */ -289,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2B800 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,101,292,101, /* U+2B000 */ +293,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2B800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2C000 */ -101,101,101,101,101,101,101,101,101,101,101,101,101,290,101,101, /* U+2C800 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,294,101,101, /* U+2C800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2D800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+2E000 */ -101,101,101,101,101,101,101,291,146,146,146,146,146,146,146,146, /* U+2E800 */ +101,101,101,101,101,101,101,295,146,146,146,146,146,146,146,146, /* U+2E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+2F000 */ -129,129,129,129,292,146,146,146,146,146,146,146,146,146,146,293, /* U+2F800 */ +129,129,129,129,296,146,146,146,146,146,146,146,146,146,146,297, /* U+2F800 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30000 */ 101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+30800 */ -101,101,101,101,101,101,294,146,146,146,146,146,146,146,146,146, /* U+31000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+31800 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+32000 */ +101,101,101,101,101,101,298,101,101,101,101,101,101,101,101,101, /* U+31000 */ +101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101, /* U+31800 */ +101,101,101,101,101,101,101,299,146,146,146,146,146,146,146,146, /* U+32000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+32800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+33800 */ @@ -1964,7 +1978,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+3F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+3F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+3F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+40800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+41000 */ @@ -1996,7 +2010,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+4F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+4F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+4F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+50800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+51000 */ @@ -2028,7 +2042,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+5F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+5F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+5F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+60800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+61000 */ @@ -2060,7 +2074,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+6F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+6F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+6F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+70800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+71000 */ @@ -2092,7 +2106,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+7F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+7F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+7F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+80800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+81000 */ @@ -2124,7 +2138,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+8F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+8F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+8F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+90800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+91000 */ @@ -2156,7 +2170,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9E800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+9F000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+9F800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+9F800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+A1000 */ @@ -2188,7 +2202,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+AF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+AF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+AF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+B1000 */ @@ -2220,7 +2234,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+BF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+BF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+BF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+C1000 */ @@ -2252,7 +2266,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+CF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+CF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+CF800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+D1000 */ @@ -2284,9 +2298,9 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+DF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+DF800 */ -295,296,297,298,296,296,296,296,296,296,296,296,296,296,296,296, /* U+E0000 */ -296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296, /* U+E0800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+DF800 */ +300,301,302,303,301,301,301,301,301,301,301,301,301,301,301,301, /* U+E0000 */ +301,301,301,301,301,301,301,301,301,301,301,301,301,301,301,301, /* U+E0800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E1800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+E2000 */ @@ -2316,7 +2330,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE000 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EE800 */ 146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146, /* U+EF000 */ -146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,293, /* U+EF800 */ +146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,297, /* U+EF800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F0800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+F1000 */ @@ -2348,7 +2362,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FE800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+FF000 */ -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,299, /* U+FF800 */ +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,304, /* U+FF800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+100800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+101000 */ @@ -2380,10 +2394,10 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E000 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10E800 */ 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, /* U+10F000 */ -128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,299, /* U+10F800 */ +128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,304, /* U+10F800 */ }; -const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ +const uint16_t PRIV(ucd_stage2)[] = { /* 78080 bytes, block = 128 */ /* block 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 3, 4, 0, 0, @@ -2626,62 +2640,62 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 388,388,388,389,390,390,390,390,390,391,390,163,163,163,163,163, /* block 24 */ -392,393,393,393,394,395,395,395,395,395,395,395,395,163,395,395, -395,163,395,395,395,395,395,395,395,395,395,395,395,395,395,395, -395,395,395,395,395,395,395,395,395,163,395,395,395,395,395,395, -395,395,395,395,395,395,395,395,395,395,163,163,396,395,392,392, -392,393,393,393,393,163,392,392,392,163,392,392,392,397,163,163, -163,163,163,163,163,392,392,163,395,395,395,163,163,395,163,163, -395,395,392,392,163,163,398,398,398,398,398,398,398,398,398,398, -163,163,163,163,163,163,163,399,400,400,400,400,400,400,400,401, +392,393,393,393,392,394,394,394,394,394,394,394,394,163,394,394, +394,163,394,394,394,394,394,394,394,394,394,394,394,394,394,394, +394,394,394,394,394,394,394,394,394,163,394,394,394,394,394,394, +394,394,394,394,394,394,394,394,394,394,163,163,395,394,392,392, +392,393,393,393,393,163,392,392,392,163,392,392,392,396,163,163, +163,163,163,163,163,392,392,163,394,394,394,163,163,394,163,163, +394,394,392,392,163,163,397,397,397,397,397,397,397,397,397,397, +163,163,163,163,163,163,163,398,399,399,399,399,399,399,399,400, /* block 25 */ -402,403,404,404,405,402,402,402,402,402,402,402,402,163,402,402, -402,163,402,402,402,402,402,402,402,402,402,402,402,402,402,402, -402,402,402,402,402,402,402,402,402,163,402,402,402,402,402,402, -402,402,402,402,163,402,402,402,402,402,163,163,406,402,404,407, -404,404,408,404,404,163,407,404,404,163,404,404,403,409,163,163, -163,163,163,163,163,408,408,163,163,163,163,163,163,402,402,163, -402,402,403,403,163,163,410,410,410,410,410,410,410,410,410,410, -163,402,402,163,163,163,163,163,163,163,163,163,163,163,163,163, +401,402,403,403,404,401,401,401,401,401,401,401,401,163,401,401, +401,163,401,401,401,401,401,401,401,401,401,401,401,401,401,401, +401,401,401,401,401,401,401,401,401,163,401,401,401,401,401,401, +401,401,401,401,163,401,401,401,401,401,163,163,405,401,403,406, +403,403,407,403,403,163,406,403,403,163,403,403,402,408,163,163, +163,163,163,163,163,407,407,163,163,163,163,163,163,401,401,163, +401,401,402,402,163,163,409,409,409,409,409,409,409,409,409,409, +163,401,401,403,163,163,163,163,163,163,163,163,163,163,163,163, /* block 26 */ -411,411,412,412,413,413,413,413,413,413,413,413,413,163,413,413, -413,163,413,413,413,413,413,413,413,413,413,413,413,413,413,413, -413,413,413,413,413,413,413,413,413,413,413,413,413,413,413,413, -413,413,413,413,413,413,413,413,413,413,413,414,414,413,415,412, -412,411,411,411,411,163,412,412,412,163,412,412,412,414,416,417, -163,163,163,163,413,413,413,415,418,418,418,418,418,418,418,413, -413,413,411,411,163,163,419,419,419,419,419,419,419,419,419,419, -418,418,418,418,418,418,418,418,418,417,413,413,413,413,413,413, +410,410,411,411,412,412,412,412,412,412,412,412,412,163,412,412, +412,163,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,412,412,412,412,413,413,412,414,411, +411,410,410,410,410,163,411,411,411,163,411,411,411,413,415,416, +163,163,163,163,412,412,412,414,417,417,417,417,417,417,417,412, +412,412,410,410,163,163,418,418,418,418,418,418,418,418,418,418, +417,417,417,417,417,417,417,417,417,416,412,412,412,412,412,412, /* block 27 */ -163,420,421,421,163,422,422,422,422,422,422,422,422,422,422,422, -422,422,422,422,422,422,422,163,163,163,422,422,422,422,422,422, -422,422,422,422,422,422,422,422,422,422,422,422,422,422,422,422, -422,422,163,422,422,422,422,422,422,422,422,422,163,422,163,163, -422,422,422,422,422,422,422,163,163,163,423,163,163,163,163,424, -421,421,420,420,420,163,420,163,421,421,421,421,421,421,421,424, -163,163,163,163,163,163,425,425,425,425,425,425,425,425,425,425, -163,163,421,421,426,163,163,163,163,163,163,163,163,163,163,163, +163,419,420,420,163,421,421,421,421,421,421,421,421,421,421,421, +421,421,421,421,421,421,421,163,163,163,421,421,421,421,421,421, +421,421,421,421,421,421,421,421,421,421,421,421,421,421,421,421, +421,421,163,421,421,421,421,421,421,421,421,421,163,421,163,163, +421,421,421,421,421,421,421,163,163,163,422,163,163,163,163,423, +420,420,419,419,419,163,419,163,420,420,420,420,420,420,420,423, +163,163,163,163,163,163,424,424,424,424,424,424,424,424,424,424, +163,163,420,420,425,163,163,163,163,163,163,163,163,163,163,163, /* block 28 */ -163,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427, -427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427, -427,427,427,427,427,427,427,427,427,427,427,427,427,427,427,427, -427,428,427,429,428,428,428,428,428,428,430,163,163,163,163,431, -432,432,432,432,432,427,433,434,434,434,434,434,434,428,434,435, -436,436,436,436,436,436,436,436,436,436,437,437,163,163,163,163, +163,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,427,426,428,427,427,427,427,427,427,429,163,163,163,163,430, +431,431,431,431,431,426,432,433,433,433,433,433,433,427,433,434, +435,435,435,435,435,435,435,435,435,435,436,436,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 29 */ -163,438,438,163,438,163,438,438,438,438,438,163,438,438,438,438, -438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438, -438,438,438,438,163,438,163,438,438,438,438,438,438,438,438,438, -438,439,438,440,439,439,439,439,439,439,441,439,439,438,163,163, -442,442,442,442,442,163,443,163,444,444,444,444,444,439,163,163, -445,445,445,445,445,445,445,445,445,445,163,163,438,438,438,438, +163,437,437,163,437,163,437,437,437,437,437,163,437,437,437,437, +437,437,437,437,437,437,437,437,437,437,437,437,437,437,437,437, +437,437,437,437,163,437,163,437,437,437,437,437,437,437,437,437, +437,438,437,439,438,438,438,438,438,438,440,438,438,437,163,163, +441,441,441,441,441,163,442,163,443,443,443,443,443,438,444,163, +445,445,445,445,445,445,445,445,445,445,163,163,437,437,437,437, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, @@ -2696,274 +2710,274 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 163,456,456,456,456,456,456,457,456,457,456,456,456,456,456,458, /* block 31 */ -456,456,450,450,459,448,450,450,446,446,446,446,446,456,456,456, +456,456,459,459,460,448,450,450,446,446,446,446,446,456,456,456, 456,456,456,456,456,456,456,456,163,456,456,456,456,456,456,456, 456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456, 456,456,456,456,456,456,456,456,456,456,456,456,456,163,447,447, 447,447,447,447,447,447,450,447,447,447,447,447,447,163,447,447, -448,448,448,448,448,460,460,460,460,448,448,163,163,163,163,163, +448,448,448,448,448,461,461,461,461,448,448,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 32 */ -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -461,461,461,461,461,461,461,461,461,461,461,462,462,463,463,463, -463,464,463,463,463,463,463,465,462,466,466,464,464,463,463,461, -467,467,467,467,467,467,467,467,467,467,468,468,469,469,469,469, -461,461,461,461,461,461,464,464,463,463,461,461,461,461,463,463, -463,461,462,470,470,461,461,462,462,470,470,470,470,470,461,461, -461,463,463,463,463,461,461,461,461,461,461,461,461,461,461,461, +462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, +462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, +462,462,462,462,462,462,462,462,462,462,462,463,463,464,464,464, +464,465,464,464,464,464,464,466,463,467,467,465,465,464,464,462, +468,468,468,468,468,468,468,468,468,468,469,469,470,470,470,470, +462,462,462,462,462,462,465,465,464,464,462,462,462,462,464,464, +464,462,463,471,471,462,462,463,463,471,471,471,471,471,462,462, +462,464,464,464,464,462,462,462,462,462,462,462,462,462,462,462, /* block 33 */ -461,461,463,462,464,463,463,470,470,470,470,470,470,471,461,470, -472,472,472,472,472,472,472,472,472,472,470,470,462,463,473,473, -474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474, -474,474,474,474,474,474,474,474,474,474,474,474,474,474,474,474, -474,474,474,474,474,474,163,474,163,163,163,163,163,474,163,163, +462,462,464,463,465,464,464,471,471,471,471,471,471,472,462,471, +473,473,473,473,473,473,473,473,473,473,471,471,463,464,474,474, 475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, 475,475,475,475,475,475,475,475,475,475,475,475,475,475,475,475, -475,475,475,475,475,475,475,475,475,475,475,476,477,475,475,475, +475,475,475,475,475,475,163,475,163,163,163,163,163,475,163,163, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,476,476,476,476,476, +476,476,476,476,476,476,476,476,476,476,476,477,478,476,476,476, /* block 34 */ -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,479, -480,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, -481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,480, +481,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, /* block 35 */ -481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, -481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, -481,481,481,481,481,481,481,481,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, 482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, 482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, +482,482,482,482,482,482,482,482,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, /* block 36 */ -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,163,483,483,483,483,163,163, -483,483,483,483,483,483,483,163,483,163,483,483,483,483,163,163, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,163,484,484,484,484,163,163, +484,484,484,484,484,484,484,163,484,163,484,484,484,484,163,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, /* block 37 */ -483,483,483,483,483,483,483,483,483,163,483,483,483,483,163,163, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,163,483,483,483,483,163,163,483,483,483,483,483,483,483,163, -483,163,483,483,483,483,163,163,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +484,484,484,484,484,484,484,484,484,163,484,484,484,484,163,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,163, +484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, /* block 38 */ -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,163,483,483,483,483,163,163,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,483,483,483,483,163,163,484,484,484, -485,486,487,486,486,486,486,487,487,488,488,488,488,488,488,488, -488,488,489,489,489,489,489,489,489,489,489,489,489,163,163,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,163,484,484,484,484,163,163,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,484,484,484,484,163,163,485,485,485, +486,487,488,487,487,487,487,488,488,489,489,489,489,489,489,489, +489,489,490,490,490,490,490,490,490,490,490,490,490,163,163,163, /* block 39 */ -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -490,490,490,490,490,490,490,490,490,490,163,163,163,163,163,163, -491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, -491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, -491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, -491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, -491,491,491,491,491,491,491,491,491,491,491,491,491,491,491,491, -492,492,492,492,492,492,163,163,493,493,493,493,493,493,163,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +491,491,491,491,491,491,491,491,491,491,163,163,163,163,163,163, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +492,492,492,492,492,492,492,492,492,492,492,492,492,492,492,492, +493,493,493,493,493,493,163,163,494,494,494,494,494,494,163,163, /* block 40 */ -494,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, +495,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, /* block 41 */ -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, /* block 42 */ -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,496,497,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,497,498,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, /* block 43 */ -498,499,499,499,499,499,499,499,499,499,499,499,499,499,499,499, -499,499,499,499,499,499,499,499,499,499,499,500,501,163,163,163, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, -502,502,502,502,502,502,502,502,502,502,502,503,503,503,504,504, -504,502,502,502,502,502,502,502,502,163,163,163,163,163,163,163, +499,500,500,500,500,500,500,500,500,500,500,500,500,500,500,500, +500,500,500,500,500,500,500,500,500,500,500,501,502,163,163,163, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,503,503,503,503,503, +503,503,503,503,503,503,503,503,503,503,503,504,504,504,505,505, +505,503,503,503,503,503,503,503,503,163,163,163,163,163,163,163, /* block 44 */ -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,506,506,507,508,163,163,163,163,163,163,163,163,163,505, -509,509,509,509,509,509,509,509,509,509,509,509,509,509,509,509, -509,509,510,510,511,512,512,163,163,163,163,163,163,163,163,163, -513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, -513,513,514,514,163,163,163,163,163,163,163,163,163,163,163,163, -515,515,515,515,515,515,515,515,515,515,515,515,515,163,515,515, -515,163,516,516,163,163,163,163,163,163,163,163,163,163,163,163, +506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, +506,506,507,507,508,509,163,163,163,163,163,163,163,163,163,506, +510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +510,510,511,511,512,513,513,163,163,163,163,163,163,163,163,163, +514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, +514,514,515,515,163,163,163,163,163,163,163,163,163,163,163,163, +516,516,516,516,516,516,516,516,516,516,516,516,516,163,516,516, +516,163,517,517,163,163,163,163,163,163,163,163,163,163,163,163, /* block 45 */ -517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,518,518,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,517,519,519,520,521,521,521,521,521,521,521,520,520, -520,520,520,520,520,520,521,520,520,522,522,522,522,522,522,522, -522,522,523,522,524,524,524,525,526,526,524,527,517,522,163,163, -528,528,528,528,528,528,528,528,528,528,163,163,163,163,163,163, +518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518, +518,518,518,518,518,518,518,518,518,518,518,518,518,518,518,518, +518,518,518,519,519,518,518,518,518,518,518,518,518,518,518,518, +518,518,518,518,520,520,521,522,522,522,522,522,522,522,521,521, +521,521,521,521,521,521,522,521,521,523,523,523,523,523,523,523, +523,523,524,523,525,525,525,526,527,527,525,528,518,523,163,163, 529,529,529,529,529,529,529,529,529,529,163,163,163,163,163,163, +530,530,530,530,530,530,530,530,530,530,163,163,163,163,163,163, /* block 46 */ -530,530,531,532,533,531,534,530,533,535,536,537,537,537,538,537, -539,539,539,539,539,539,539,539,539,539,163,163,163,163,163,163, -540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,541,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,163,163,163,163,163,163,163, +531,531,532,533,534,532,535,531,534,536,537,538,538,538,539,538, +540,540,540,540,540,540,540,540,540,540,163,163,163,163,163,163, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,542,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,163,163,163,163,163,163,163, /* block 47 */ -540,540,540,540,540,542,542,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,540,540,540,540,540,540,540, -540,540,540,540,540,540,540,540,540,543,540,163,163,163,163,163, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -495,495,495,495,495,495,163,163,163,163,163,163,163,163,163,163, +541,541,541,541,541,543,543,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,541,541,541,541,541,541,541, +541,541,541,541,541,541,541,541,541,544,541,163,163,163,163,163, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +496,496,496,496,496,496,163,163,163,163,163,163,163,163,163,163, /* block 48 */ -544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,544, -544,544,544,544,544,544,544,544,544,544,544,544,544,544,544,163, -545,545,545,546,546,546,546,545,545,546,546,546,163,163,163,163, -546,546,545,546,546,546,546,546,546,547,547,547,163,163,163,163, -548,163,163,163,549,549,550,550,550,550,550,550,550,550,550,550, -551,551,551,551,551,551,551,551,551,551,551,551,551,551,551,551, -551,551,551,551,551,551,551,551,551,551,551,551,551,551,163,163, -551,551,551,551,551,163,163,163,163,163,163,163,163,163,163,163, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,163, +546,546,546,547,547,547,547,546,546,547,547,547,163,163,163,163, +547,547,546,547,547,547,547,547,547,548,548,548,163,163,163,163, +549,163,163,163,550,550,551,551,551,551,551,551,551,551,551,551, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, +552,552,552,552,552,552,552,552,552,552,552,552,552,552,163,163, +552,552,552,552,552,163,163,163,163,163,163,163,163,163,163,163, /* block 49 */ -552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,552,552,163,163,163,163, -552,552,552,552,552,553,553,553,552,552,553,552,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,163,163,163,163,163,163, -554,554,554,554,554,554,554,554,554,554,555,163,163,163,556,556, -557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, -557,557,557,557,557,557,557,557,557,557,557,557,557,557,557,557, +553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,553,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,553,553,163,163,163,163, +553,553,553,553,553,554,554,554,553,553,554,553,553,553,553,553, +553,553,553,553,553,553,553,553,553,553,163,163,163,163,163,163, +555,555,555,555,555,555,555,555,555,555,556,163,163,163,557,557, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, +558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, /* block 50 */ -558,558,558,558,558,558,558,558,558,558,558,558,558,558,558,558, -558,558,558,558,558,558,558,559,559,560,560,559,163,163,561,561, -562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, -562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, -562,562,562,562,562,562,562,562,562,562,562,562,562,562,562,562, -562,562,562,562,562,563,564,563,564,564,564,564,564,564,564,163, -565,566,564,566,566,564,564,564,564,564,564,564,564,563,563,563, -563,563,563,564,564,567,567,567,567,567,567,567,567,163,163,567, +559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559, +559,559,559,559,559,559,559,560,560,561,561,560,163,163,562,562, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,564,565,564,565,565,565,565,565,565,565,163, +566,567,565,567,567,565,565,565,565,565,565,565,565,564,564,564, +564,564,564,565,565,568,568,568,568,568,568,568,568,163,163,568, /* block 51 */ -568,568,568,568,568,568,568,568,568,568,163,163,163,163,163,163, -568,568,568,568,568,568,568,568,568,568,163,163,163,163,163,163, -569,569,569,569,569,569,569,570,571,571,571,571,569,569,163,163, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,572,573, -573,154,154,154,154,154,154,154,154,154,154,154,573,573,573,163, +569,569,569,569,569,569,569,569,569,569,163,163,163,163,163,163, +569,569,569,569,569,569,569,569,569,569,163,163,163,163,163,163, +570,570,570,570,570,570,570,571,572,572,572,572,570,570,163,163, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,573,574, +574,154,154,154,154,154,154,154,154,154,154,154,574,574,574,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 52 */ -574,574,574,574,575,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, -576,576,576,576,577,578,574,574,574,574,574,575,574,575,575,575, -575,575,574,575,579,576,576,576,576,576,576,576,576,163,163,163, -580,580,580,580,580,580,580,580,580,580,581,581,582,583,581,581, -582,584,584,584,584,584,584,584,584,584,584,577,577,577,577,577, -577,577,577,577,584,584,584,584,584,584,584,584,584,581,581,163, +575,575,575,575,576,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,578,579,575,575,575,575,575,576,575,576,576,576, +576,576,575,576,580,577,577,577,577,577,577,577,577,163,163,163, +581,581,581,581,581,581,581,581,581,581,582,582,583,584,582,582, +583,585,585,585,585,585,585,585,585,585,585,578,578,578,578,578, +578,578,578,578,585,585,585,585,585,585,585,585,585,582,582,163, /* block 53 */ -585,585,586,587,587,587,587,587,587,587,587,587,587,587,587,587, -587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587, -587,586,585,585,585,585,586,586,585,585,588,589,585,585,587,587, -590,590,590,590,590,590,590,590,590,590,587,587,587,587,587,587, -591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,591,591,591,591,591,591,591,591,591,591, -591,591,591,591,591,591,592,593,594,594,593,593,593,594,593,594, -594,594,595,595,163,163,163,163,163,163,163,163,596,596,596,596, +586,586,587,588,588,588,588,588,588,588,588,588,588,588,588,588, +588,588,588,588,588,588,588,588,588,588,588,588,588,588,588,588, +588,587,586,586,586,586,587,587,586,586,589,590,586,586,588,588, +591,591,591,591,591,591,591,591,591,591,588,588,588,588,588,588, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,593,594,595,595,594,594,594,595,594,595, +595,595,596,596,163,163,163,163,163,163,163,163,597,597,597,597, /* block 54 */ -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,598,598,598,598,598,598,598,598,599,599,599,599, -599,599,599,599,598,598,600,601,163,163,163,602,602,603,603,603, -604,604,604,604,604,604,604,604,604,604,163,163,163,597,597,597, -605,605,605,605,605,605,605,605,605,605,606,606,606,606,606,606, -606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606, -606,606,606,606,606,606,606,606,607,607,607,608,607,607,609,609, +598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598, +598,598,598,598,598,598,598,598,598,598,598,598,598,598,598,598, +598,598,598,598,599,599,599,599,599,599,599,599,600,600,600,600, +600,600,600,600,599,599,601,602,163,163,163,603,603,604,604,604, +605,605,605,605,605,605,605,605,605,605,163,163,163,598,598,598, +606,606,606,606,606,606,606,606,606,606,607,607,607,607,607,607, +607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607, +607,607,607,607,607,607,607,607,608,608,608,609,608,608,610,610, /* block 55 */ -610,611,612,613,614,615,616,617,618,163,163,163,163,163,163,163, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,163,163,619,619,619, -620,620,620,620,620,620,620,620,163,163,163,163,163,163,163,163, -621,622,621,623,622,624,624,625,624,625,626,622,625,625,622,622, -625,627,622,622,622,622,622,622,622,628,629,630,630,624,630,630, -630,630,631,632,633,629,629,634,635,635,636,163,163,163,163,163, +611,612,613,614,615,616,617,618,619,163,163,163,163,163,163,163, +620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, +620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, +620,620,620,620,620,620,620,620,620,620,620,163,163,620,620,620, +621,621,621,621,621,621,621,621,163,163,163,163,163,163,163,163, +622,623,622,624,623,625,625,626,625,626,627,623,626,626,623,623, +626,628,623,623,623,623,623,623,623,629,630,631,631,625,631,631, +631,631,632,633,634,630,630,635,636,636,637,163,163,163,163,163, /* block 56 */ 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70,221,221,221,221,221,637,147,147,147,147, + 70, 70, 70, 70, 70, 70,221,221,221,221,221,638,147,147,147,147, 147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, 147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, -147,147,147,147,147,147,147,147,147,147,147,147,147,638,638,638, -638,638,148,147,147,147,638,638,638,638,638, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70,639,640, 70, 70, 70,641, 70, 70, +147,147,147,147,147,147,147,147,147,147,147,147,147,639,639,639, +639,639,148,147,147,147,639,639,639,639,639, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70,640,641, 70, 70, 70,642, 70, 70, /* block 57 */ - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,642, 70, - 70, 70, 70, 70, 70, 70,643, 70, 70, 70, 70,644,644,644,644,644, -644,644,644,644,645,644,644,644,645,644,644,644,644,644,644,644, -644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,646, -647,647,158,158,154,154,154,154,154,154,154,154,154,154,154,154, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,643, 70, + 70, 70, 70, 70, 70, 70,644, 70, 70, 70, 70,645,645,645,645,645, +645,645,645,645,646,645,645,645,646,645,645,645,645,645,645,645, +645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,647, +648,648,158,158,154,154,154,154,154,154,154,154,154,154,154,154, 158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158, -158,158,158,158,158,158,158,573,573,573,573,573,573,573,573,573, -573,573,573,573,573,154,154,154,648,154,649,154,154,154,154,154, +158,158,158,158,158,158,158,574,574,574,574,574,574,574,574,574, +574,574,574,574,574,154,154,154,649,154,650,154,154,154,154,154, /* block 58 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, @@ -2972,12 +2986,12 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, -650,651, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, +651,652, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, /* block 59 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 69, 69, 69, 69,652,653, 70, 70,654, 70, + 65, 66, 65, 66, 65, 66, 69, 69, 69, 69,653,654, 70, 70,655, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 67, 65, 66, 65, 66, @@ -2986,123 +3000,123 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, /* block 60 */ -655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656, -655,655,655,655,655,655,163,163,656,656,656,656,656,656,163,163, -655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656, -655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656, -655,655,655,655,655,655,163,163,656,656,656,656,656,656,163,163, -173,655,173,655,173,655,173,655,163,656,163,656,163,656,163,656, -655,655,655,655,655,655,655,655,656,656,656,656,656,656,656,656, -657,657,658,658,658,658,659,659,660,660,661,661,662,662,163,163, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +656,656,656,656,656,656,163,163,657,657,657,657,657,657,163,163, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +656,656,656,656,656,656,163,163,657,657,657,657,657,657,163,163, +173,656,173,656,173,656,173,656,163,657,163,657,163,657,163,657, +656,656,656,656,656,656,656,656,657,657,657,657,657,657,657,657, +658,658,659,659,659,659,660,660,661,661,662,662,663,663,163,163, /* block 61 */ -663,663,663,663,663,663,663,663,664,664,664,664,664,664,664,664, -663,663,663,663,663,663,663,663,664,664,664,664,664,664,664,664, -663,663,663,663,663,663,663,663,664,664,664,664,664,664,664,664, -655,655,665,666,665,163,173,665,656,656,667,667,668,162,669,162, -162,162,665,666,665,163,173,665,670,670,670,670,668,162,162,162, -655,655,173,173,163,163,173,173,656,656,671,671,163,162,162,162, -655,655,173,173,173,215,173,173,656,656,672,672,220,162,162,162, -163,163,665,666,665,163,173,665,673,673,674,674,668,162,162,163, +664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, +664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, +664,664,664,664,664,664,664,664,665,665,665,665,665,665,665,665, +656,656,666,667,666,163,173,666,657,657,668,668,669,162,670,162, +162,162,666,667,666,163,173,666,671,671,671,671,669,162,162,162, +656,656,173,173,163,163,173,173,657,657,672,672,163,162,162,162, +656,656,173,173,173,215,173,173,657,657,673,673,220,162,162,162, +163,163,666,667,666,163,173,666,674,674,675,675,669,162,162,163, /* block 62 */ -675,675,675,675,675,675,675,675,675,675,675, 51,676,677,678,679, -680,680,680,680,680,680,681, 43,682,683,684,685,685,686,684,685, - 43, 43, 43, 43,687, 43, 43,687,688,689,690,691,692,693,694,695, -696,696,697,697,697, 43, 43, 43, 43, 49, 57, 43,698,699, 43,700, -701, 43, 43, 43,702,703,704,699,699,698, 43, 43, 43, 43, 43, 43, - 43, 43, 50,705,700, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,675, - 51,706,706,706,706,707,708,709,710,711,712,712,712,712,712,712, - 54,645,163,163, 54, 54, 54, 54, 54, 54,713,714,715,716,717,644, +676,676,676,676,676,676,676,676,676,676,676, 51,677,678,679,680, +681,681,681,681,681,681,682, 43,683,684,685,686,686,687,685,686, + 43, 43, 43, 43,688, 43, 43,688,689,690,691,692,693,694,695,696, +697,697,698,698,698, 43, 43, 43, 43, 49, 57, 43,699,700, 43,701, +702, 43, 43, 43,703,704,705,700,700,699, 43, 43, 43, 43, 43, 43, + 43, 43, 50,706,701, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,676, + 51,707,707,707,707,708,709,710,711,712,713,713,713,713,713,713, + 54,646,163,163, 54, 54, 54, 54, 54, 54,714,715,716,717,718,645, /* block 63 */ - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,713,714,715,716,717,163, -644,644,644,644,644,644,644,644,644,644,644,644,644,163,163,163, -431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431, -431,431,431,431,431,431,431,431,431,431,431,431,431,431,431,431, -431,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718, -719,719,719,719,719,719,719,719,719,719,719,719,719,720,720,720, -720,719,720,721,720,719,719,158,158,158,158,719,719,719,719,719, -722,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,714,715,716,717,718,163, +645,645,645,645,645,645,645,645,645,645,645,645,645,163,163,163, +430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, +430,430,430,430,430,430,430,430,430,430,430,430,430,430,430,430, +430,719,719,719,719,719,719,719,719,719,719,719,719,719,719,719, +720,720,720,720,720,720,720,720,720,720,720,720,720,721,721,721, +721,720,721,722,721,720,720,158,158,158,158,720,720,720,720,720, +723,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 64 */ -723,723,724,723,723,723,723,724,723,723,725,724,724,724,725,725, -724,724,724,725,723,724,723,723,726,724,724,724,724,724,723,723, -723,723,727,723,724,723,728,723,724,729,730,731,724,724,732,725, -724,724,733,724,725,734,734,734,734,735,723,723,725,725,724,724, -715,715,715,715,715,724,725,725,736,736,723,715,723,723,737,460, +724,724,725,724,724,724,724,725,724,724,726,725,725,725,726,726, +725,725,725,726,724,725,724,724,727,725,725,725,725,725,724,724, +724,724,728,724,725,724,729,724,725,730,731,732,725,725,733,726, +725,725,734,725,726,735,735,735,735,736,724,724,726,726,725,725, +716,716,716,716,716,725,726,726,737,737,724,716,724,724,738,461, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,738, 739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739, +740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740, /* block 65 */ -740,740,740, 65, 66,740,740,740,740, 58,723,723,163,163,163,163, - 50, 50, 50, 50,741,742,742,742,742,742, 50, 50,743,743,743,743, - 50,743,743, 50,743,743, 50,743, 45,742,742,743,743,743, 50, 45, -743,743, 45, 45, 45, 45,743,743, 45, 45, 45, 45,743,743,743,743, -743,743,743,743,743,743,743,743,743,743,743,743,743,743, 50, 50, -743,743, 50,743, 50,743,743,743,743,743,743,743, 45,743, 45, 45, - 45, 45, 45, 45,743,743, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +741,741,741, 65, 66,741,741,741,741, 58,724,724,163,163,163,163, + 50, 50, 50, 50,742,743,743,743,743,743, 50, 50,744,744,744,744, + 50,744,744, 50,744,744, 50,744, 45,743,743,744,744,744, 50, 45, +744,744, 45, 45, 45, 45,744,744, 45, 45, 45, 45,744,744,744,744, +744,744,744,744,744,744,744,744,744,744,744,744,744,744, 50, 50, +744,744, 50,744, 50,744,744,744,744,744,744,744, 45,744, 45, 45, + 45, 45, 45, 45,744,744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 66 */ - 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744,744,744, 50, 50, - 50, 50,745, 53, 50,744, 50, 50, 50, 50, 50, 50, 50, 50, 50,744, -744,744,744, 50,744, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744, 50, 50, - 50, 50, 50,744, 50,744, 50, 50, 50, 50, 50, 50,744, 50, 50, 50, - 50, 50,744,744,744,744, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,744,744,744,744,744,744,744,744, 50, 50,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, + 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745,745, 50, 50, + 50, 50,746, 53, 50,745, 50, 50, 50, 50, 50, 50, 50, 50, 50,745, +745,745,745, 50,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745, 50, 50, + 50, 50, 50,745, 50,745, 50, 50, 50, 50, 50, 50,745, 50, 50, 50, + 50, 50,745,745,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50,745,745,745,745,745,745,745,745, 50, 50,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, /* block 67 */ -744,744,744,744,744,744,744,744,744,744,744,744, 50, 50, 50,744, -744,744,744, 50, 50, 50, 50, 50,744, 50, 50, 50, 50, 50, 50, 50, - 50, 50,744,744, 50, 50,744, 50,744,744, 50,744, 50, 50, 50, 50, -744,744,744,744,744,744,744,744,744, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744,744, 50, 50, -744,744, 50, 50, 50, 50,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744, 50, 50, -744,744,744,744,744, 50,744,744, 50, 50,744,744,744,744,744, 50, +745,745,745,745,745,745,745,745,745,745,745,745, 50, 50, 50,745, +745,745,745, 50, 50, 50, 50, 50,745, 50, 50, 50, 50, 50, 50, 50, + 50, 50,745,745, 50, 50,745, 50,745,745, 50,745, 50, 50, 50, 50, +745,745,745,745,745,745,745,745,745, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745, 50, 50, +745,745, 50, 50, 50, 50,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745, 50, 50, +745,745,745,745,745, 50,745,745, 50, 50,745,745,745,745,745, 50, /* block 68 */ - 45, 45, 45, 45, 45, 45, 45, 45,746,747,746,747, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,748,748, 45, 45, 45, 45, - 50, 50, 45, 45, 45, 45, 45, 45, 47,749,750, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45,751,751,751,751,751,751,751,751,751,751, -751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751, -751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751, -751,751,751,751,751,751,751,751,751,751,751,751,751,751,751,751, -751,751,751,751,751,751,751,751,751,751,751, 45, 50, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45,747,748,747,748, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749,749, 45, 45, 45, 45, + 50, 50, 45, 45, 45, 45, 45, 45, 47,750,751, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, +752,752,752,752,752,752,752,752,752,752,752, 45, 50, 45, 45, 45, /* block 69 */ - 45, 45, 45, 45, 45, 45, 45, 45,752, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45,751, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, + 45, 45, 45, 45, 45, 45, 45, 45,753, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45,752, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,743,743, 45,743, 45, 45, 45, 45, 45, 45, 45, 45, + 50, 50, 50, 50,744,744, 45,744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, -743, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, - 50, 50,743, 45, 45, 45, 45, 45, 45,748,748,748,748, 47, 47, 47, -748, 47, 47,748, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, +744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, + 50, 50,744, 45, 45, 45, 45, 45, 45,749,749,749,749, 47, 47, 47, +749, 47, 47,749, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, /* block 70 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45,753,753,753,753,753,753,753,753,753, -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,753,753,753,753,753, -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, + 45, 45, 45, 45, 45, 45, 45,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 71 */ 58, 58, 58, 58, 58, 58, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,754,754,754,754,754,754,754,754,754,754, -754,754,755,754,754,754,754,754,754,754,754,754,754,754,754,754, -756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756, -756,756,756,756,756,756,756,756,756,756, 58, 58, 58, 58, 58, 58, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,755,755,755,755,755,755,755,755,755,755, +755,755,756,755,755,755,755,755,755,755,755,755,755,755,755,755, +757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757, +757,757,757,757,757,757,757,757,757,757, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 72 */ @@ -3118,132 +3132,132 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ /* block 73 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -743,743, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45,743,743, -743,743,743,743,743,743,742, 50, 45, 45, 45, 45,743,743,743,743, -742, 50, 45, 45, 45, 45,743,743, 45, 45,743,743, 45, 45, 45,743, -743,743,743,743, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45,743, 45,743, 45, 45,743,743,743,743,743,743, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50,741,741,757,757, 50, +744,744, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45,744,744, +744,744,744,744,744,744,743, 50, 45, 45, 45, 45,744,744,744,744, +743, 50, 45, 45, 45, 45,744,744, 45, 45,744,744, 45, 45, 45,744, +744,744,744,744, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45,744, 45,744, 45, 45,744,744,744,744,744,744, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50,742,742,758,758, 50, /* block 74 */ - 47, 47, 47, 47, 47,758,743,752,752,752,752,752,752,752, 47,752, -752, 47,752, 45,748,748,752,752, 47,752,752,752,752,759,752,752, - 47,752, 47, 47,752,752, 47,752,752,752, 47,752,752,752, 47, 47, -752,752,752,752,752,752,752,752, 47, 47, 47,752,752,752,752,752, -742,752,742,752,752,752,752,752,748,748,748,748,748,748,748,748, -748,748,748,748,752,752,752,752,752,752,752,752,752,752,752, 47, -742,758,758,742,752, 47, 47,752, 47,752,752,752,752,758,758,760, -752,752,752,752,752,752,752,752,752,752,752, 47,752,752, 47,748, + 47, 47, 47, 47, 47,759,744,753,753,753,753,753,753,753, 47,753, +753, 47,753, 45,749,749,753,753, 47,753,753,753,753,760,753,753, + 47,753, 47, 47,753,753, 47,753,753,753, 47,753,753,753, 47, 47, +753,753,753,753,753,753,753,753, 47, 47, 47,753,753,753,753,753, +743,753,743,753,753,753,753,753,749,749,749,749,749,749,749,749, +749,749,749,749,753,753,753,753,753,753,753,753,753,753,753, 47, +743,759,759,743,753, 47, 47,753, 47,753,753,753,753,759,759,761, +753,753,753,753,753,753,753,753,753,753,753, 47,753,753, 47,749, /* block 75 */ -752,752,752,752,752,752, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -752,752, 47,748, 47, 47, 47, 47,752, 47,752, 47, 47,752,752,752, - 47,748,752,752,752,752,752, 47,752,752,748,748,761,752,752,752, - 47, 47,752,752,752,752,752,752,752,752,752,752,752,748,748,752, -752,752,752,752,748,748,752,752, 47,752,752,752,752,752,748, 47, -752, 47,752, 47,748,752,752,752,752,752,752,752,752,752,752,752, -752,752,752,752,752,752,752,752,752, 47,748,752,752,752,752,752, - 47, 47,748,748, 47,748,752, 47, 47,759,748,752,752,748,752,752, +753,753,753,753,753,753, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +753,753, 47,749, 47, 47, 47, 47,753, 47,753, 47, 47,753,753,753, + 47,749,753,753,753,753,753, 47,753,753,749,749,762,753,753,753, + 47, 47,753,753,753,753,753,753,753,753,753,753,753,749,749,753, +753,753,753,753,749,749,753,753, 47,753,753,753,753,753,749, 47, +753, 47,753, 47,749,753,753,753,753,753,753,753,753,753,753,753, +753,753,753,753,753,753,753,753,753, 47,749,753,753,753,753,753, + 47, 47,749,749, 47,749,753, 47, 47,760,749,753,753,749,753,753, /* block 76 */ -752,752, 47,752,752,748, 45, 45, 47, 47,762,762,759,759,752, 47, -752,752, 47, 45, 47, 45, 47, 45, 45, 45, 45, 45, 45, 47, 45, 45, - 45, 47, 45, 45, 45, 45, 45, 45,748, 45, 45, 45, 45, 45, 45, 45, +753,753, 47,753,753,749, 45, 45, 47, 47,763,763,760,760,753, 47, +753,753, 47, 45, 47, 45, 47, 45, 45, 45, 45, 45, 45, 47, 45, 45, + 45, 47, 45, 45, 45, 45, 45, 45,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 47, 45, 45, 47, 45, 45, 45, 45,748, 45,748, 45, - 45, 45, 45,748,748,748, 45,748, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 47, 47,752,752,752,703,704,703,704,703,704,703,704, -703,704,703,704,703,704, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 45, 45, 45, 45, 47, 45, 45, 47, 45, 45, 45, 45,749, 45,749, 45, + 45, 45, 45,749,749,749, 45,749, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 47, 47,753,753,753,704,705,704,705,704,705,704,705, +704,705,704,705,704,705, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, /* block 77 */ 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 58, 58, 45,748,748,748, 45, 45, 45, 45, 45, 45, 45, 45, + 58, 58, 58, 58, 45,749,749,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 47, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, -748, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,748, - 50, 50, 50,744,744,746,747, 50,744,744, 50,744, 50,744, 50, 50, - 50, 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50,744,744,744, 50, - 50, 50,744,744,744,744,746,747,746,747,746,747,746,747,746,747, +749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749, + 50, 50, 50,745,745,747,748, 50,745,745, 50,745, 50,745, 50, 50, + 50, 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50,745,745,745, 50, + 50, 50,745,745,745,745,747,748,747,748,747,748,747,748,747,748, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 78 */ -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, -763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, +764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, /* block 79 */ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,741,741, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50,742,742, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, /* block 80 */ - 50, 50, 50,746,747,746,747,746,747,746,747,746,747,746,747,746, -747,746,747,746,747,746,747,746,747, 50, 50,744, 50, 50, 50, 50, -744, 50, 50,744,744,744, 50, 50,744,744,744,744,744,744,744,744, - 50, 50, 50, 50, 50, 50, 50, 50,744, 50, 50, 50, 50, 50, 50, 50, -744,744, 50, 50,744,744, 50, 50, 50, 50, 50, 50, 50, 50, 50,744, -744,744,744, 50,744,744, 50, 50,746,747,746,747, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50,744, 50, 50,744,744, 50, 50,746,747, 50, 50, + 50, 50, 50,747,748,747,748,747,748,747,748,747,748,747,748,747, +748,747,748,747,748,747,748,747,748, 50, 50,745, 50, 50, 50, 50, +745, 50, 50,745,745,745, 50, 50,745,745,745,745,745,745,745,745, + 50, 50, 50, 50, 50, 50, 50, 50,745, 50, 50, 50, 50, 50, 50, 50, +745,745, 50, 50,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50,745, +745,745,745, 50,745,745, 50, 50,747,748,747,748, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50,745, 50, 50,745,745, 50, 50,747,748, 50, 50, /* block 81 */ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744, 50, - 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50, 50,744,744, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745, 50, + 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50,744,744, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50,744,744,744,744,744,744,744, + 50, 50, 50, 50,745,745, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50,745,745,745,745,745,745,745, /* block 82 */ -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744, 50, 50, 50,744,744,744,744,744,744,744,744, 50,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744, -744,744,744,744,744,744,744, 50, 50, 50, 50, 50, 50, 50,744, 50, - 50, 50, 50,744,744,744, 50, 50, 50, 50, 50, 50,744,744,744, 50, - 50, 50, 50, 50, 50, 50, 50,744,744,744,744, 50, 50, 50, 50, 50, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745, 50, 50, 50,745,745,745,745,745,745,745,745, 50,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745,745,745,745,745,745,745,745,745,745, +745,745,745,745,745,745,745, 50, 50, 50, 50, 50, 50, 50,745, 50, + 50, 50, 50,745,745,745, 50, 50, 50, 50, 50, 50,745,745,745, 50, + 50, 50, 50, 50, 50, 50, 50,745,745,745,745, 50, 50, 50, 50, 50, /* block 83 */ 45, 45, 45, 45, 45, 47, 47, 47, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,748,748, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,749,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 45, 45, 50, 50, 50, 50, 50, 50, 45, 45, 45, -748, 45, 45, 45, 45,748, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, +749, 45, 45, 45, 45,749, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45,753,753, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45,754,754, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, /* block 84 */ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45,753, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45,754, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,764, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,765, 45, /* block 85 */ -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, -765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765, 766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, 766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, 766,766,766,766,766,766,766,766,766,766,766,766,766,766,766,766, - 65, 66,767,768,769,770,771, 65, 66, 65, 66, 65, 66,772,773,774, -775, 70, 65, 66, 70, 65, 66, 70, 70, 70, 70, 70,645,644,776,776, +767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, +767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, +767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767, + 65, 66,768,769,770,771,772, 65, 66, 65, 66, 65, 66,773,774,775, +776, 70, 65, 66, 70, 65, 66, 70, 70, 70, 70, 70,646,645,777,777, /* block 86 */ 211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, @@ -3252,248 +3266,248 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, 211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, 211,212,211,212,211,212,211,212,211,212,211,212,211,212,211,212, -211,212,211,212,777,778,778,778,778,778,778,211,212,211,212,779, -779,779,211,212,163,163,163,163,163,780,780,780,780,781,780,780, +211,212,211,212,778,779,779,779,779,779,779,211,212,211,212,780, +780,780,211,212,163,163,163,163,163,781,781,781,781,782,781,781, /* block 87 */ -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, -782,782,782,782,782,782,163,782,163,163,163,163,163,782,163,163, 783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, 783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,783,783,783,783,783,783,783,783,783,783,783,783, -783,783,783,783,783,783,783,783,163,163,163,163,163,163,163,784, -785,163,163,163,163,163,163,163,163,163,163,163,163,163,163,786, +783,783,783,783,783,783,163,783,163,163,163,163,163,783,163,163, +784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, +784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, +784,784,784,784,784,784,784,784,784,784,784,784,784,784,784,784, +784,784,784,784,784,784,784,784,163,163,163,163,163,163,163,785, +786,163,163,163,163,163,163,163,163,163,163,163,163,163,163,787, /* block 88 */ -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, -483,483,483,483,483,483,483,163,163,163,163,163,163,163,163,163, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163, -787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787, -787,787,787,787,787,787,787,787,787,787,787,787,787,787,787,787, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,484, +484,484,484,484,484,484,484,163,163,163,163,163,163,163,163,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, +788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, +788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788, /* block 89 */ - 43, 43,788,789,788,789, 43, 43, 43,788,789, 43,788,789, 43, 43, - 43, 43, 43, 43, 43, 43, 43,680, 43, 43,680, 43,788,789, 43, 43, -788,789,703,704,703,704,703,704,703,704, 43, 43, 43, 43,699,790, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,680,680,699, 43, 43, 43, -680,791,684,792, 43, 43, 43, 43, 43, 43, 43, 43,791, 43,791,791, - 45, 45, 43,699,699,703,704,703,704,703,704,703,704,680,753,753, -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, -753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753, + 43, 43,789,790,789,790, 43, 43, 43,789,790, 43,789,790, 43, 43, + 43, 43, 43, 43, 43, 43, 43,681, 43, 43,681, 43,789,790, 43, 43, +789,790,704,705,704,705,704,705,704,705, 43, 43, 43, 43,700,791, + 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,681,681,700, 43, 43, 43, +681,792,685,793, 43, 43, 43, 43, 43, 43, 43, 43,792, 43,792,792, + 45, 45, 43,700,700,704,705,704,705,704,705,704,705,681,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, +754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754, /* block 90 */ -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,163,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,163,163,163,163,163,163,163,163,163,163,163,163, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,163,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,163,163,163,163,163,163,163,163,163,163,163,163, /* block 91 */ -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, /* block 92 */ -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, -793,793,793,793,793,793,163,163,163,163,163,163,163,163,163,163, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,794,794,794,794,794,794,794,794,794,794, +794,794,794,794,794,794,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -794,794,795,795,794,794,794,794,794,794,794,794,163,163,163,163, +795,795,796,796,795,795,795,795,795,795,795,795,163,163,163,163, /* block 93 */ -675,796,797,798,723,799,800,801,802,803,802,803,804,805,804,805, -802,803, 45,806,802,803,802,803,802,803,802,803,807,808,809,809, - 45,801,801,801,801,801,801,801,801,801,810,810,810,810,811,811, -812,813,813,813,813,813,723,814,801,801,801,815,816,817,818,818, -163,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +676,797,798,799,724,800,801,802,803,804,803,804,805,806,805,806, +803,804, 45,807,803,804,803,804,803,804,803,804,808,809,810,810, + 45,802,802,802,802,802,802,802,802,802,811,811,811,811,812,812, +813,814,814,814,814,814,724,815,802,802,802,816,817,818,819,819, +163,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, /* block 94 */ -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,163,163,820,820,821,821,822,822,819, -823,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,825,826,827,827,824, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,163,163,821,821,822,822,823,823,820, +824,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,826,827,828,828,825, /* block 95 */ -163,163,163,163,163,828,828,828,828,828,828,828,828,828,828,828, -828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828, -828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828, -163,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +163,163,163,163,163,829,829,829,829,829,829,829,829,829,829,829, 829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, 829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,829,830,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +163,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,831,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, /* block 96 */ -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,163, -831,831,832,832,832,832,831,831,831,831,831,831,831,831,831,831, -828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828, -828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828, -818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818, -818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818, -818,818,818,818,163,163,163,163,163,163,163,163,163,163,163,163, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,163, +832,832,833,833,833,833,832,832,832,832,832,832,832,832,832,832, +829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, +819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +819,819,819,819,163,163,163,163,163,163,163,163,163,163,163,163, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, /* block 97 */ -833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833, -833,833,833,833,833,833,833,833,833,833,833,833,833,834,834,163, -832,832,832,832,832,832,832,832,832,832,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,835,835,835,835,835,835,835,835, -723, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833, -833,833,833,833,833,833,833,833,833,833,833,833,834,834,834,460, +834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, +834,834,834,834,834,834,834,834,834,834,834,834,834,835,835,163, +833,833,833,833,833,833,833,833,833,833,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,836,836,836,836,836,836,836,836, +724, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834, +834,834,834,834,834,834,834,834,834,834,834,834,835,835,835,461, /* block 98 */ -832,832,832,832,832,832,832,832,832,832,831,831,831,831,831,831, -831,831,831,831,831,831,831,836,831,836,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, -831,831,831,831,831,831,831,831,831,831,831,831,723,723,723,723, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,831, +833,833,833,833,833,833,833,833,833,833,832,832,832,832,832,832, +832,832,832,832,832,832,832,837,832,837,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, +832,832,832,832,832,832,832,832,832,832,832,832,724,724,724,724, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,832, /* block 99 */ -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,460,460,460,460,460,460,723,723,723,723,831,831,831,831,831, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +838,838,838,838,838,838,838,838,832,832,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832,461,461,461,461,461,461,724,724,724,724,832,832,832,832,832, /* block 100 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,723,723, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,723, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,724,724, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, +832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,724, /* block 101 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 102 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 103 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,840,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,841,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, /* block 104 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, -839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, +840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840, /* block 105 */ -839,839,839,839,839,839,839,839,839,839,839,839,839,163,163,163, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,163,163,163,163,163,163,163,163,163, +840,840,840,840,840,840,840,840,840,840,840,840,840,163,163,163, 842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, 842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, -842,842,842,842,842,842,842,842,843,843,843,843,843,843,844,845, +842,842,842,842,842,842,842,842,842,842,842,842,842,842,842,842, +842,842,842,842,842,842,842,163,163,163,163,163,163,163,163,163, +843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843, +843,843,843,843,843,843,843,843,843,843,843,843,843,843,843,843, +843,843,843,843,843,843,843,843,844,844,844,844,844,844,845,846, /* block 106 */ -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, /* block 107 */ -846,846,846,846,846,846,846,846,846,846,846,846,847,848,849,849, -846,846,846,846,846,846,846,846,846,846,846,846,846,846,846,846, -850,850,850,850,850,850,850,850,850,850,846,846,163,163,163,163, +847,847,847,847,847,847,847,847,847,847,847,847,848,849,850,850, +847,847,847,847,847,847,847,847,847,847,847,847,847,847,847,847, +851,851,851,851,851,851,851,851,851,851,847,847,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -240,241,240,241,240,241,240,241,240,241,851,852,240,241,240,241, +240,241,240,241,240,241,240,241,240,241,852,853,240,241,240,241, 240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,240,241,853,246, -248,248,248,854,787,787,787,787,787,787,787,787,855,855,854,856, +240,241,240,241,240,241,240,241,240,241,240,241,240,241,854,246, +248,248,248,855,788,788,788,788,788,788,788,788,856,856,855,857, /* block 108 */ 240,241,240,241,240,241,240,241,240,241,240,241,240,241,240,241, -240,241,240,241,240,241,240,241,240,241,240,241,857,857,787,787, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,859,859,859,859,859,859,859,859,859,859, -860,860,861,862,863,863,863,862,163,163,163,163,163,163,163,163, +240,241,240,241,240,241,240,241,240,241,240,241,858,858,788,788, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,860,860,860,860,860,860,860,860,860,860, +861,861,862,863,864,864,864,863,163,163,163,163,163,163,163,163, /* block 109 */ -864,864,864,864,864,864,864,864, 46, 46, 46, 46, 46, 46, 46, 46, +865,865,865,865,865,865,865,865, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,149,149,149,149,149,149,149,149,149, 46, 46, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 70, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, -644, 70, 70, 70, 70, 70, 70, 70, 70, 65, 66, 65, 66,865, 65, 66, +645, 70, 70, 70, 70, 70, 70, 70, 70, 65, 66, 65, 66,866, 65, 66, /* block 110 */ - 65, 66, 65, 66, 65, 66, 65, 66,149,866,866, 65, 66,867, 70, 92, - 65, 66, 65, 66,868, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,869,870,871,872,869, 70, -873,874,875,876, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, - 65, 66, 65, 66,877,878,879, 65, 66, 65, 66,163,163,163,163,163, + 65, 66, 65, 66, 65, 66, 65, 66,149,867,867, 65, 66,868, 70, 92, + 65, 66, 65, 66,869, 70, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66, 65, 66, 65, 66, 65, 66,870,871,872,873,870, 70, +874,875,876,877, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, 65, 66, + 65, 66, 65, 66,878,879,880, 65, 66, 65, 66,163,163,163,163,163, 65, 66,163, 70,163, 70, 65, 66, 65, 66,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,880,880,880, 65, 66, 92,147,147, 70, 92, 92, 92, 92, 92, +163,163,645,645,645, 65, 66, 92,147,147, 70, 92, 92, 92, 92, 92, /* block 111 */ 881,881,882,881,881,881,883,881,881,881,881,882,881,881,881,881, @@ -3522,8 +3536,8 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 908,908,908,908,908,908,908,908,908,908,908,908,908,908,908,908, 908,908,908,908,908,908,908,909,909,909,909,909,909,909,909,909, 909,909,910,911,163,163,163,163,163,163,163,163,163,163,163,912, -478,478,478,478,478,478,478,478,478,478,478,478,478,478,478,478, -478,478,478,478,478,478,478,478,478,478,478,478,478,163,163,163, +479,479,479,479,479,479,479,479,479,479,479,479,479,479,479,479, +479,479,479,479,479,479,479,479,479,479,479,479,479,163,163,163, /* block 114 */ 913,913,913,914,915,915,915,915,915,915,915,915,915,915,915,915, @@ -3532,8 +3546,8 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 915,915,915,916,914,914,913,913,913,913,914,914,913,913,914,914, 917,918,918,918,918,918,918,919,920,920,918,918,918,918,163,921, 922,922,922,922,922,922,922,922,922,922,163,163,163,163,918,918, -461,461,461,461,461,471,923,461,461,461,461,461,461,461,461,461, -472,472,472,472,472,472,472,472,472,472,461,461,461,461,461,163, +462,462,462,462,462,472,923,462,462,462,462,462,462,462,462,462, +473,473,473,473,473,473,473,473,473,473,462,462,462,462,462,163, /* block 115 */ 924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924, @@ -3542,8 +3556,8 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 926,925,925,926,926,925,925,163,163,163,163,163,163,163,163,163, 924,924,924,925,924,924,924,924,924,924,924,924,925,926,163,163, 927,927,927,927,927,927,927,927,927,927,163,163,928,929,929,929, -461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, -923,461,461,461,461,461,461,473,473,473,461,470,471,470,461,461, +462,462,462,462,462,462,462,462,462,462,462,462,462,462,462,462, +923,462,462,462,462,462,462,474,474,474,462,471,472,471,462,462, /* block 116 */ 930,930,930,930,930,930,930,930,930,930,930,930,930,930,930,930, @@ -3556,159 +3570,159 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 941,941,938,942,942,939,943,163,163,163,163,163,163,163,163,163, /* block 117 */ -163,483,483,483,483,483,483,163,163,483,483,483,483,483,483,163, -163,483,483,483,483,483,483,163,163,163,163,163,163,163,163,163, -483,483,483,483,483,483,483,163,483,483,483,483,483,483,483,163, +163,484,484,484,484,484,484,163,163,484,484,484,484,484,484,163, +163,484,484,484,484,484,484,163,163,163,163,163,163,163,163,163, +484,484,484,484,484,484,484,163,484,484,484,484,484,484,484,163, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,944, 70, 70, 70, 70, 70, 70, 70,866,147,147,147,147, - 70, 70, 70, 70, 70,221, 70, 70, 70,945, 46, 46,163,163,163,163, -946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946, + 70, 70, 70,944, 70, 70, 70, 70, 70, 70, 70,867,147,147,147,147, + 70, 70, 70, 70, 70,221, 70, 70, 70,147, 46, 46,163,163,163,163, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, /* block 118 */ -946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946, -946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946, -946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946, -946,946,946,946,946,946,946,946,946,946,946,946,946,946,946,946, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, +945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945, 938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, 938,938,938,938,938,938,938,938,938,938,938,938,938,938,938,938, -938,938,938,939,939,940,939,939,940,939,939,941,947,943,163,163, -948,948,948,948,948,948,948,948,948,948,163,163,163,163,163,163, +938,938,938,939,939,940,939,939,940,939,939,941,946,943,163,163, +947,947,947,947,947,947,947,947,947,947,163,163,163,163,163,163, /* block 119 */ -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 120 */ -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, /* block 121 */ -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 122 */ -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, /* block 123 */ -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 124 */ -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, /* block 125 */ -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -949,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,949,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,949,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,948,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,948,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, /* block 126 */ -950,950,950,950,950,950,950,950,949,950,950,950,950,950,950,950, -950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, -950,950,950,950,163,163,163,163,163,163,163,163,163,163,163,163, -481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, -481,481,481,481,481,481,481,163,163,163,163,482,482,482,482,482, +949,949,949,949,949,949,949,949,948,949,949,949,949,949,949,949, +949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949, +949,949,949,949,163,163,163,163,163,163,163,163,163,163,163,163, 482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,482,482,482,482, -482,482,482,482,482,482,482,482,482,482,482,482,163,163,163,163, +482,482,482,482,482,482,482,163,163,163,163,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,483, +483,483,483,483,483,483,483,483,483,483,483,483,163,163,163,163, /* block 127 */ -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, -951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, +950,950,950,950,950,950,950,950,950,950,950,950,950,950,950,950, /* block 128 */ -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, /* block 129 */ -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, /* block 130 */ -953,953,953,953,953,953,953,953,953,953,953,953,953,953,838,838, -953,838,953,838,838,953,953,953,953,953,953,953,953,953,953,838, -953,838,953,838,838,953,953,838,838,838,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,163,163, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,839,839, +952,839,952,839,839,952,952,952,952,952,952,952,952,952,952,839, +952,839,952,839,839,952,952,839,839,839,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,163,163, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, /* block 131 */ -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,163,163,163,163,163,163, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 132 */ -652,652,652,652,652,652,652,163,163,163,163,163,163,163,163,163, +653,653,653,653,653,653,653,163,163,163,163,163,163,163,163,163, 163,163,163,257,257,257,257,257,163,163,163,163,163,270,265,270, -270,270,270,270,270,270,270,270,270,954,270,270,270,270,270,270, +270,270,270,270,270,270,270,270,270,953,270,270,270,270,270,270, 270,270,270,270,270,270,270,262,270,270,270,270,270,262,270,262, 270,270,262,270,270,262,270,270,270,270,270,270,270,270,270,270, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, @@ -3731,8 +3745,8 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,955,955, -955,955,955,955,286,286,286,286,286,286,286,286,286,286,286,286, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,954,954, +954,954,954,954,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, /* block 135 */ @@ -3749,7 +3763,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, -286,286,286,286,286,286,286,286,286,286,286,286,286,286,956,957, +286,286,286,286,286,286,286,286,286,286,286,286,286,286,955,956, 280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, @@ -3761,19 +3775,19 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, 286,286,286,286,286,286,286,286,302,302,302,302,302,302,302,280, -958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, -958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958, -286,286,959,286,286,286,286,286,286,286,955,955,277,960,280,280, +957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957, +957,957,957,957,957,957,957,957,957,957,957,957,957,957,957,957, +286,286,958,286,286,286,286,286,286,286,954,954,277,959,280,280, /* block 138 */ -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,962, -963,963,963,964,963,963,963,965,966,963,163,163,163,163,163,163, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,855,855, -963,967,967,700,700,965,966,965,966,965,966,965,966,965,966,965, -966,968,969,968,969,798,798,965,966,963,963,963,963,700,700,700, -970,166,971,163,166,972,973,973,967,974,975,974,975,974,975,976, -963,977,713,978,979,979,715,163,977,431,976,963,163,163,163,163, -955,286,955,286,955,302,955,286,955,286,955,286,955,286,955,286, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,961, +962,962,962,963,962,962,962,964,965,962,163,163,163,163,163,163, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,856,856, +962,966,966,701,701,964,965,964,965,964,965,964,965,964,965,964, +965,967,968,967,968,799,799,964,965,962,962,962,962,701,701,701, +969,166,970,163,166,971,972,972,966,973,974,973,974,973,974,975, +962,976,714,977,978,978,716,163,976,430,975,962,163,163,163,163, +954,286,954,286,954,302,954,286,954,286,954,286,954,286,954,286, /* block 139 */ 286,286,286,286,286,286,286,286,286,286,286,286,286,286,286,286, @@ -3786,64 +3800,64 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 286,286,286,286,286,286,286,286,286,286,286,286,286,302,302, 51, /* block 140 */ -163,973,980,976,431,976,963,981,974,975,963,713,970,982,971,983, -984,984,984,984,984,984,984,984,984,984,972,166,979,715,979,973, -963,985,985,985,985,985,985, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,974,977,975,986,700, - 46,987,987,987,987,987,987, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,974,715,975,715,974, -975,988,989,990,991,825,824,824,824,824,824,824,824,824,824,824, -826,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, +163,972,979,975,430,975,962,980,973,974,962,714,969,981,970,982, +983,983,983,983,983,983,983,983,983,983,971,166,978,716,978,972, +962,984,984,984,984,984,984, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,973,976,974,985,701, + 46,986,986,986,986,986,986, 62, 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,973,716,974,716,973, +974,987,988,989,990,826,825,825,825,825,825,825,825,825,825,825, +827,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, /* block 141 */ -824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824, -824,824,824,824,824,824,824,824,824,824,824,824,824,824,992,992, -830,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,163, -163,163,829,829,829,829,829,829,163,163,829,829,829,829,829,829, -163,163,829,829,829,829,829,829,163,163,829,829,829,163,163,163, -431,431,715, 46,723,431,431,163,723,715,715,715,715,723,723,163, -707,707,707,707,707,707,707,707,707,993,993,993,723,723,958,958, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,825,825, +825,825,825,825,825,825,825,825,825,825,825,825,825,825,991,991, +831,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,163, +163,163,830,830,830,830,830,830,163,163,830,830,830,830,830,830, +163,163,830,830,830,830,830,830,163,163,830,830,830,163,163,163, +430,430,716, 46,724,430,430,163,724,716,716,716,716,724,724,163, +708,708,708,708,708,708,708,708,708,992,992,992,724,724,957,957, /* block 142 */ -994,994,994,994,994,994,994,994,994,994,994,994,163,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,163,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,163,994,994,163,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,163,163, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,163,163, +993,993,993,993,993,993,993,993,993,993,993,993,163,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,163,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,163,993,993,163,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,163,163, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 143 */ -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,994,994,994,994,994, -994,994,994,994,994,994,994,994,994,994,994,163,163,163,163,163, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,993,993,993,993,993, +993,993,993,993,993,993,993,993,993,993,993,163,163,163,163,163, /* block 144 */ -995,996,997,163,163,163,163,998,998,998,998,998,998,998,998,998, -998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998, -998,998,998,998,998,998,998,998,998,998,998,998,998,998,998,998, -998,998,998,998,163,163,163,999,999,999,999,999,999,999,999,999, -1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000, -1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000, -1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000, -1000,1000,1000,1000,1000,1001,1001,1001,1001,1002,1002,1002,1002,1002,1002,1002, +994,995,996,163,163,163,163,997,997,997,997,997,997,997,997,997, +997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, +997,997,997,997,997,997,997,997,997,997,997,997,997,997,997,997, +997,997,997,997,163,163,163,998,998,998,998,998,998,998,998,998, +999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, +999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, +999,999,999,999,999,999,999,999,999,999,999,999,999,999,999,999, +999,999,999,999,999,1000,1000,1000,1000,1001,1001,1001,1001,1001,1001,1001, /* block 145 */ -1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1001,1001,1002,1003,1003,163, -723,723,723,723,723,723,723,723,723,723,723,723,723,163,163,163, -1002,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1000,1000,1001,1002,1002,163, +724,724,724,724,724,724,724,724,724,724,724,724,724,163,163,163, +1001,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,158,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,158,163,163, /* block 146 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, @@ -3856,97 +3870,97 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 147 */ +1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003, +1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,1003,163,163,163, 1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, -1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,163,163,163, -1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005, -1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005, -1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005,1005, -1005,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1006,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007, -1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,163,163,163,163, +1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, +1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004,1004, +1004,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1005,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006, +1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,1006,163,163,163,163, /* block 148 */ -1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008, -1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008,1008, -1009,1009,1009,1009,163,163,163,163,163,163,163,163,163,1008,1008,1008, -1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010,1010, -1010,1011,1010,1010,1010,1010,1010,1010,1010,1010,1011,163,163,163,163,163, -1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012, -1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012,1012, -1012,1012,1012,1012,1012,1012,1013,1013,1013,1013,1013,163,163,163,163,163, +1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007, +1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007,1007, +1008,1008,1008,1008,163,163,163,163,163,163,163,163,163,1007,1007,1007, +1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009,1009, +1009,1010,1009,1009,1009,1009,1009,1009,1009,1009,1010,163,163,163,163,163, +1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, +1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011,1011, +1011,1011,1011,1011,1011,1011,1012,1012,1012,1012,1012,163,163,163,163,163, /* block 149 */ -1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014, -1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,1014,163,1015, -1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016, -1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016,1016, -1016,1016,1016,1016,163,163,163,163,1016,1016,1016,1016,1016,1016,1016,1016, -1017,1018,1018,1018,1018,1018,163,163,163,163,163,163,163,163,163,163, +1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013, +1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,1013,163,1014, +1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015, +1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015,1015, +1015,1015,1015,1015,163,163,163,163,1015,1015,1015,1015,1015,1015,1015,1015, +1016,1017,1017,1017,1017,1017,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 150 */ +1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, +1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018,1018, +1018,1018,1018,1018,1018,1018,1018,1018,1019,1019,1019,1019,1019,1019,1019,1019, 1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019, 1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019,1019, -1019,1019,1019,1019,1019,1019,1019,1019,1020,1020,1020,1020,1020,1020,1020,1020, 1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, 1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, -1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021, -1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021, -1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021, +1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020,1020, /* block 151 */ -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022, -1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,163,163, -1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,163,163,163,163,163,163, +1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021, +1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,1021,163,163, +1022,1022,1022,1022,1022,1022,1022,1022,1022,1022,163,163,163,163,163,163, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023,1023, +1023,1023,1023,1023,163,163,163,163,1024,1024,1024,1024,1024,1024,1024,1024, 1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024, -1024,1024,1024,1024,163,163,163,163,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, -1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,163,163,163,163, +1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,1024,163,163,163,163, /* block 152 */ +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025,1025, +1025,1025,1025,1025,1025,1025,1025,1025,163,163,163,163,163,163,163,163, 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, 1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, -1026,1026,1026,1026,1026,1026,1026,1026,163,163,163,163,163,163,163,163, -1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027, -1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027, -1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027,1027, -1027,1027,1027,1027,163,163,163,163,163,163,163,163,163,163,163,1028, -1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,163,1029,1029,1029,1029, +1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026,1026, +1026,1026,1026,1026,163,163,163,163,163,163,163,163,163,163,163,1027, +1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,163,1028,1028,1028,1028, /* block 153 */ -1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,163,1029,1029,1029,1029, -1029,1029,1029,163,1029,1029,163,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,163,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, -1030,1030,163,1030,1030,1030,1030,1030,1030,1030,163,1030,1030,163,163,163, +1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,1028,163,1028,1028,1028,1028, +1028,1028,1028,163,1028,1028,163,1029,1029,1029,1029,1029,1029,1029,1029,1029, +1029,1029,163,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029,1029, +1029,1029,163,1029,1029,1029,1029,1029,1029,1029,163,1029,1029,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 154 */ -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, /* block 155 */ -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,1031,163,163,163,163,163,163,163,163,163, -1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031,1031, -1031,1031,1031,1031,1031,1031,163,163,163,163,163,163,163,163,163,163, -1031,1031,1031,1031,1031,1031,1031,1031,163,163,163,163,163,163,163,163, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163,163, +1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030,1030, +1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163,163,163, +1030,1030,1030,1030,1030,1030,1030,1030,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 156 */ -147,1032,1032,147,147,147,163,147,147,147,147,147,147,147,147,147, +147,1031,1031,147,147,147,163,147,147,147,147,147,147,147,147,147, 147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, 147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147, 147,163,147,147,147,147,147,147,147,147,147,163,163,163,163,163, @@ -3956,79 +3970,79 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 157 */ -1033,1033,1033,1033,1033,1033,262,262,1033,262,1033,1033,1033,1033,1033,1033, +1032,1032,1032,1032,1032,1032,262,262,1032,262,1032,1032,1032,1032,1032,1032, +1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, +1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032,1032, +1032,1032,1032,1032,1032,1032,262,1032,1032,262,262,262,1032,262,262,1032, 1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033, -1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033,1033, -1033,1033,1033,1033,1033,1033,262,1033,1033,262,262,262,1033,262,262,1033, -1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034,1034, -1034,1034,1034,1034,1034,1034,262,1035,1036,1036,1036,1036,1036,1036,1036,1036, -1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037,1037, -1037,1037,1037,1037,1037,1037,1037,1038,1038,1039,1039,1039,1039,1039,1039,1039, +1033,1033,1033,1033,1033,1033,262,1034,1035,1035,1035,1035,1035,1035,1035,1035, +1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036,1036, +1036,1036,1036,1036,1036,1036,1036,1037,1037,1038,1038,1038,1038,1038,1038,1038, /* block 158 */ -1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040, -1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,1040,262, -262,262,262,262,262,262,262,1041,1041,1041,1041,1041,1041,1041,1041,1041, +1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039, +1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,1039,262, +262,262,262,262,262,262,262,1040,1040,1040,1040,1040,1040,1040,1040,1040, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042,1042, -1042,1042,1042,262,1042,1042,262,262,262,262,262,1043,1043,1043,1043,1043, +1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041,1041, +1041,1041,1041,262,1041,1041,262,262,262,262,262,1042,1042,1042,1042,1042, /* block 159 */ -1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044,1044, -1044,1044,1044,1044,1044,1044,1045,1045,1045,1045,1045,1045,262,262,262,1046, -1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,1047, -1047,1047,1047,1047,1047,1047,1047,1047,1047,1047,262,262,262,262,262,1048, +1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043,1043, +1043,1043,1043,1043,1043,1043,1044,1044,1044,1044,1044,1044,262,262,262,1045, +1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,1046, +1046,1046,1046,1046,1046,1046,1046,1046,1046,1046,262,262,262,262,262,1047, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 160 */ +1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048, +1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048,1048, 1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049, -1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049,1049, +1049,1049,1049,1049,1049,1049,1049,1049,262,262,262,262,1050,1050,1049,1049, +1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, +262,262,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, +1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, 1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050,1050, -1050,1050,1050,1050,1050,1050,1050,1050,262,262,262,262,1051,1051,1050,1050, -1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, -262,262,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, -1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, -1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, /* block 161 */ -1052,1053,1053,1053,262,1053,1053,262,262,262,262,262,1053,1053,1053,1053, -1052,1052,1052,1052,262,1052,1052,1052,262,1052,1052,1052,1052,1052,1052,1052, -1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052,1052, -1052,1052,1052,1052,1052,1052,262,262,1054,1054,1054,262,262,262,262,1055, -1056,1056,1056,1056,1056,1056,1056,1056,1056,262,262,262,262,262,262,262, -1057,1057,1057,1057,1057,1057,1058,1058,1057,262,262,262,262,262,262,262, -1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059, -1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1059,1060,1060,1061, +1051,1052,1052,1052,262,1052,1052,262,262,262,262,262,1052,1052,1052,1052, +1051,1051,1051,1051,262,1051,1051,1051,262,1051,1051,1051,1051,1051,1051,1051, +1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051,1051, +1051,1051,1051,1051,1051,1051,262,262,1053,1053,1053,262,262,262,262,1054, +1055,1055,1055,1055,1055,1055,1055,1055,1055,262,262,262,262,262,262,262, +1056,1056,1056,1056,1056,1056,1057,1057,1056,262,262,262,262,262,262,262, +1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058, +1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1058,1059,1059,1060, /* block 162 */ -1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062, -1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1062,1063,1063,1063, +1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061, +1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1061,1062,1062,1062, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1064,1064,1064,1064,1064,1064,1064,1064,1065,1064,1064,1064,1064,1064,1064,1064, -1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064,1064, -1064,1064,1064,1064,1064,1066,1066,262,262,262,262,1067,1067,1067,1067,1067, -1068,1068,1069,1068,1068,1068,1070,262,262,262,262,262,262,262,262,262, +1063,1063,1063,1063,1063,1063,1063,1063,1064,1063,1063,1063,1063,1063,1063,1063, +1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063,1063, +1063,1063,1063,1063,1063,1065,1065,262,262,262,262,1066,1066,1066,1066,1066, +1067,1067,1068,1067,1067,1067,1069,262,262,262,262,262,262,262,262,262, /* block 163 */ -1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071, -1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071, -1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071,1071, -1071,1071,1071,1071,1071,1071,262,262,262,1072,1073,1073,1073,1073,1073,1073, -1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074,1074, -1074,1074,1074,1074,1074,1074,262,262,1075,1075,1075,1075,1075,1075,1075,1075, -1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076,1076, -1076,1076,1076,262,262,262,262,262,1077,1077,1077,1077,1077,1077,1077,1077, +1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, +1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, +1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070,1070, +1070,1070,1070,1070,1070,1070,262,262,262,1071,1072,1072,1072,1072,1072,1072, +1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073,1073, +1073,1073,1073,1073,1073,1073,262,262,1074,1074,1074,1074,1074,1074,1074,1074, +1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075,1075, +1075,1075,1075,262,262,262,262,262,1076,1076,1076,1076,1076,1076,1076,1076, /* block 164 */ -1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078,1078, -1078,1078,262,262,262,262,262,262,262,1079,1079,1079,1079,262,262,262, -262,262,262,262,262,262,262,262,262,1080,1080,1080,1080,1080,1080,1080, +1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077,1077, +1077,1077,262,262,262,262,262,262,262,1078,1078,1078,1078,262,262,262, +262,262,262,262,262,262,262,262,262,1079,1079,1079,1079,1079,1079,1079, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, @@ -4036,30 +4050,30 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 165 */ -1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, -1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, -1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, -1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, -1081,1081,1081,1081,1081,1081,1081,1081,1081,262,262,262,262,262,262,262, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080,1080, +1080,1080,1080,1080,1080,1080,1080,1080,1080,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, /* block 166 */ +1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, +1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, +1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081,1081, +1081,1081,1081,262,262,262,262,262,262,262,262,262,262,262,262,262, 1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, 1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, 1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082,1082, -1082,1082,1082,262,262,262,262,262,262,262,262,262,262,262,262,262, -1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083, -1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083, -1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083,1083, -1083,1083,1083,262,262,262,262,262,262,262,1084,1084,1084,1084,1084,1084, +1082,1082,1082,262,262,262,262,262,262,262,1083,1083,1083,1083,1083,1083, /* block 167 */ -1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085, -1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085,1085, -1085,1085,1086,1086,1087,1087,1087,1087,302,302,302,302,302,302,302,302, -1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,302,302,302,302,302,302, +1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084, +1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084,1084, +1084,1084,1085,1085,1086,1086,1086,1086,302,302,302,302,302,302,302,302, +1087,1087,1087,1087,1087,1087,1087,1087,1087,1087,302,302,302,302,302,302, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, @@ -4082,174 +4096,174 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, -1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,262, +1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088, +1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,1088,262, /* block 170 */ -1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090, -1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,1090, -1090,1090,1090,1090,1090,1090,1090,1090,1090,1090,262,1091,1091,1092,262,262, -1090,1090,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, +1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,1089, +1089,1089,1089,1089,1089,1089,1089,1089,1089,1089,262,1090,1090,1091,262,262, +1089,1089,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, +302,302,302,302,302,302,302,302,302,302,302,302,302,291,291,291, /* block 171 */ -1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093, -1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1093,1094,1094,1094, -1094,1094,1094,1094,1094,1094,1094,1093,262,262,262,262,262,262,262,262, -1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095, -1095,1095,1095,1095,1095,1095,1096,1096,1096,1096,1096,1096,1096,1096,1096,1096, -1096,1097,1097,1097,1097,1098,1098,1098,1098,1098,302,302,302,302,302,302, +1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092, +1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1092,1093,1093,1093, +1093,1093,1093,1093,1093,1093,1093,1092,262,262,262,262,262,262,262,262, +1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094,1094, +1094,1094,1094,1094,1094,1094,1095,1095,1095,1095,1095,1095,1095,1095,1095,1095, +1095,1096,1096,1096,1096,1097,1097,1097,1097,1097,302,302,302,302,302,302, 302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099,1099, +1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098,1098, /* block 172 */ -1099,1099,1100,1100,1100,1100,1101,1101,1101,1101,262,262,262,262,262,262, +1098,1098,1099,1099,1099,1099,1100,1100,1100,1100,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102,1102, -1102,1102,1102,1102,1102,1103,1103,1103,1103,1103,1103,1103,262,262,262,262, +1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101,1101, +1101,1101,1101,1101,1101,1102,1102,1102,1102,1102,1102,1102,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104,1104, -1104,1104,1104,1104,1104,1104,1104,262,262,262,262,262,262,262,262,262, +1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103,1103, +1103,1103,1103,1103,1103,1103,1103,262,262,262,262,262,262,262,262,262, /* block 173 */ -1105,1106,1105,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107,1107, -1107,1107,1107,1107,1107,1107,1107,1107,1106,1106,1106,1106,1106,1106,1106,1106, -1106,1106,1106,1106,1106,1106,1108,1109,1109,1110,1110,1110,1110,1110,163,163, -163,163,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111, -1111,1111,1111,1111,1111,1111,1112,1112,1112,1112,1112,1112,1112,1112,1112,1112, -1108,1107,1107,1106,1106,1107,163,163,163,163,163,163,163,163,163,1113, +1104,1105,1104,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106,1106, +1106,1106,1106,1106,1106,1106,1106,1106,1105,1105,1105,1105,1105,1105,1105,1105, +1105,1105,1105,1105,1105,1105,1107,1108,1108,1109,1109,1109,1109,1109,163,163, +163,163,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110,1110, +1110,1110,1110,1110,1110,1110,1111,1111,1111,1111,1111,1111,1111,1111,1111,1111, +1107,1106,1106,1105,1105,1106,163,163,163,163,163,163,163,163,163,1112, /* block 174 */ -1114,1114,1115,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116, -1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116, -1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116,1116, -1115,1115,1115,1117,1117,1117,1117,1115,1115,1118,1119,1120,1120,1121,1122,1122, -1122,1122,1117,163,163,163,163,163,163,163,163,163,163,1121,163,163, -1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123,1123, -1123,1123,1123,1123,1123,1123,1123,1123,1123,163,163,163,163,163,163,163, -1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,163,163,163,163,163,163, +1113,1113,1114,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, +1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, +1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115,1115, +1114,1114,1114,1113,1113,1113,1113,1114,1114,1116,1117,1118,1118,1119,1120,1120, +1120,1120,1113,163,163,163,163,163,163,163,163,163,163,1119,163,163, +1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121,1121, +1121,1121,1121,1121,1121,1121,1121,1121,1121,163,163,163,163,163,163,163, +1122,1122,1122,1122,1122,1122,1122,1122,1122,1122,163,163,163,163,163,163, /* block 175 */ -1125,1125,1125,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126, -1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126,1126, -1126,1126,1126,1126,1126,1126,1126,1125,1125,1125,1125,1125,1127,1125,1125,1125, -1125,1125,1125,1128,1128,163,1129,1129,1129,1129,1129,1129,1129,1129,1129,1129, -1130,1131,1131,1131,1126,1127,1127,1126,163,163,163,163,163,163,163,163, -1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132, -1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132,1132, -1132,1132,1132,1133,1134,1134,1132,163,163,163,163,163,163,163,163,163, +1123,1123,1123,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124, +1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124,1124, +1124,1124,1124,1124,1124,1124,1124,1123,1123,1123,1123,1123,1125,1123,1123,1123, +1123,1123,1123,1126,1126,163,1127,1127,1127,1127,1127,1127,1127,1127,1127,1127, +1128,1129,1129,1129,1124,1125,1125,1124,163,163,163,163,163,163,163,163, +1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130, +1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130,1130, +1130,1130,1130,1131,1132,1132,1130,163,163,163,163,163,163,163,163,163, /* block 176 */ -1135,1135,1136,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137, -1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137, -1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137,1137, -1137,1137,1137,1136,1136,1136,1135,1135,1135,1135,1135,1135,1135,1135,1135,1136, -1138,1137,1139,1139,1137,1140,1140,1141,1141,1142,1143,1143,1143,1140,1136,1135, -1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1137,1141,1137,1141,1140,1140, -163,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145,1145, -1145,1145,1145,1145,1145,163,163,163,163,163,163,163,163,163,163,163, +1133,1133,1134,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, +1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, +1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135,1135, +1135,1135,1135,1134,1134,1134,1133,1133,1133,1133,1133,1133,1133,1133,1133,1134, +1136,1135,1137,1137,1135,1138,1138,1139,1139,1140,1141,1141,1141,1138,1134,1133, +1142,1142,1142,1142,1142,1142,1142,1142,1142,1142,1135,1139,1135,1139,1138,1138, +163,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143,1143, +1143,1143,1143,1143,1143,163,163,163,163,163,163,163,163,163,163,163, /* block 177 */ -1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146, -1146,1146,163,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146, -1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1146,1147,1147,1147,1148, -1148,1148,1147,1147,1148,1149,1150,1148,1151,1151,1152,1151,1151,1153,1148,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144, +1144,1144,163,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144, +1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1144,1145,1145,1145,1146, +1146,1146,1145,1145,1146,1147,1148,1146,1149,1149,1150,1149,1149,1151,1146,1144, +1144,1146,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 178 */ -1154,1154,1154,1154,1154,1154,1154,163,1154,163,1154,1154,1154,1154,163,1154, -1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,163,1154, -1154,1154,1154,1154,1154,1154,1154,1154,1154,1155,163,163,163,163,163,163, -1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156, -1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156, -1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1156,1157, -1158,1158,1158,1157,1157,1157,1157,1157,1157,1159,1160,163,163,163,163,163, -1161,1161,1161,1161,1161,1161,1161,1161,1161,1161,163,163,163,163,163,163, +1152,1152,1152,1152,1152,1152,1152,163,1152,163,1152,1152,1152,1152,163,1152, +1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,1152,163,1152, +1152,1152,1152,1152,1152,1152,1152,1152,1152,1153,163,163,163,163,163,163, +1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154, +1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154, +1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1154,1155, +1156,1156,1156,1155,1155,1155,1155,1155,1155,1157,1158,163,163,163,163,163, +1159,1159,1159,1159,1159,1159,1159,1159,1159,1159,163,163,163,163,163,163, /* block 179 */ -1162,1163,1164,1165,163,1166,1166,1166,1166,1166,1166,1166,1166,163,163,1166, -1166,163,163,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166,1166, -1166,1166,1166,1166,1166,1166,1166,1166,1166,163,1166,1166,1166,1166,1166,1166, -1166,163,1166,1166,163,1166,1166,1166,1166,1166,163,1167,1168,1166,1169,1164, -1162,1164,1164,1164,1164,163,163,1164,1164,163,163,1164,1164,1170,163,163, -1166,163,163,163,163,163,163,1169,163,163,163,163,163,1171,1166,1166, -1166,1166,1164,1164,163,163,1172,1172,1172,1172,1172,1172,1172,163,163,163, -1172,1172,1172,1172,1172,163,163,163,163,163,163,163,163,163,163,163, +1160,1161,1162,1163,163,1164,1164,1164,1164,1164,1164,1164,1164,163,163,1164, +1164,163,163,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164,1164, +1164,1164,1164,1164,1164,1164,1164,1164,1164,163,1164,1164,1164,1164,1164,1164, +1164,163,1164,1164,163,1164,1164,1164,1164,1164,163,1165,1166,1164,1167,1162, +1160,1162,1162,1162,1162,163,163,1162,1162,163,163,1162,1162,1168,163,163, +1164,163,163,163,163,163,163,1167,163,163,163,163,163,1169,1164,1164, +1164,1164,1162,1162,163,163,1170,1170,1170,1170,1170,1170,1170,163,163,163, +1170,1170,1170,1170,1170,163,163,163,163,163,163,163,163,163,163,163, /* block 180 */ -1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173, -1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173, -1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173,1173, -1173,1173,1173,1173,1173,1174,1174,1174,1175,1175,1175,1175,1175,1175,1175,1175, -1174,1174,1176,1175,1175,1174,1177,1173,1173,1173,1173,1178,1178,1179,1180,1180, -1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1179,1179,163,1180,1182,1173, -1173,1173,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, +1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, +1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171,1171, +1171,1171,1171,1171,1171,1172,1172,1172,1173,1173,1173,1173,1173,1173,1173,1173, +1172,1172,1174,1173,1173,1172,1175,1171,1171,1171,1171,1176,1176,1177,1178,1178, +1179,1179,1179,1179,1179,1179,1179,1179,1179,1179,1177,1177,163,1178,1180,1171, +1171,1171,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 181 */ -1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183, -1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183, -1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183,1183, -1184,1185,1185,1186,1186,1186,1186,1186,1186,1185,1186,1185,1185,1184,1185,1186, -1186,1185,1187,1188,1183,1183,1189,1183,163,163,163,163,163,163,163,163, -1190,1190,1190,1190,1190,1190,1190,1190,1190,1190,163,163,163,163,163,163, +1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, +1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, +1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181,1181, +1182,1183,1183,1184,1184,1184,1184,1184,1184,1183,1184,1183,1183,1182,1183,1184, +1184,1183,1185,1186,1181,1181,1187,1181,163,163,163,163,163,163,163,163, +1188,1188,1188,1188,1188,1188,1188,1188,1188,1188,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 182 */ -1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191, -1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191, -1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1191,1192, -1193,1193,1194,1194,1194,1194,163,163,1193,1193,1193,1193,1194,1194,1193,1195, -1196,1197,1198,1198,1199,1199,1200,1200,1200,1198,1198,1198,1198,1198,1198,1198, -1198,1198,1198,1198,1198,1198,1198,1198,1191,1191,1191,1191,1194,1194,163,163, +1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189, +1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189, +1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1189,1190, +1191,1191,1192,1192,1192,1192,163,163,1191,1191,1191,1191,1192,1192,1191,1193, +1194,1195,1196,1196,1197,1197,1198,1198,1198,1196,1196,1196,1196,1196,1196,1196, +1196,1196,1196,1196,1196,1196,1196,1196,1189,1189,1189,1189,1192,1192,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 183 */ -1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201, -1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201, -1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201,1201, -1202,1202,1202,1203,1203,1203,1203,1203,1203,1203,1203,1202,1202,1203,1202,1204, -1203,1205,1205,1206,1201,163,163,163,163,163,163,163,163,163,163,163, -1207,1207,1207,1207,1207,1207,1207,1207,1207,1207,163,163,163,163,163,163, -530,530,530,530,530,530,530,530,530,530,530,530,530,163,163,163, +1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, +1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, +1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199,1199, +1200,1200,1200,1201,1201,1201,1201,1201,1201,1201,1201,1200,1200,1201,1200,1202, +1201,1203,1203,1204,1199,163,163,163,163,163,163,163,163,163,163,163, +1205,1205,1205,1205,1205,1205,1205,1205,1205,1205,163,163,163,163,163,163, +531,531,531,531,531,531,531,531,531,531,531,531,531,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 184 */ -1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208, -1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208, -1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1208,1209,1210,1209,1210,1210, -1209,1209,1209,1209,1209,1209,1211,1212,1208,1213,163,163,163,163,163,163, -1214,1214,1214,1214,1214,1214,1214,1214,1214,1214,163,163,163,163,163,163, +1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206, +1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206, +1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1206,1207,1208,1207,1208,1208, +1207,1207,1207,1207,1207,1207,1209,1210,1206,1211,163,163,163,163,163,163, +1212,1212,1212,1212,1212,1212,1212,1212,1212,1212,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 185 */ -1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215, -1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,1215,163,163,1216,1216,1216, -1217,1217,1216,1216,1216,1216,1218,1216,1216,1216,1216,1219,163,163,163,163, -1220,1220,1220,1220,1220,1220,1220,1220,1220,1220,1221,1221,1222,1222,1222,1223, -1215,1215,1215,1215,1215,1215,1215,163,163,163,163,163,163,163,163,163, +1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213, +1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,1213,163,163,1214,1214,1214, +1215,1215,1214,1214,1214,1214,1216,1214,1214,1214,1214,1217,163,163,163,163, +1218,1218,1218,1218,1218,1218,1218,1218,1218,1218,1219,1219,1220,1220,1220,1221, +1213,1213,1213,1213,1213,1213,1213,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 186 */ -1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224, -1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224, -1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1224,1225,1225,1225,1226, -1226,1226,1226,1226,1226,1226,1226,1226,1225,1227,1228,1229,163,163,163,163, +1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222, +1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222, +1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1222,1223,1223,1223,1224, +1224,1224,1224,1224,1224,1224,1224,1224,1223,1225,1226,1227,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, @@ -4258,266 +4272,266 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ /* block 187 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230, -1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1230, -1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231, -1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231,1231, -1232,1232,1232,1232,1232,1232,1232,1232,1232,1232,1233,1233,1233,1233,1233,1233, -1233,1233,1233,163,163,163,163,163,163,163,163,163,163,163,163,1234, +1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228, +1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228,1228, +1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229, +1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229,1229, +1230,1230,1230,1230,1230,1230,1230,1230,1230,1230,1231,1231,1231,1231,1231,1231, +1231,1231,1231,163,163,163,163,163,163,163,163,163,163,163,163,1232, /* block 188 */ -1235,1235,1235,1235,1235,1235,1235,163,163,1235,163,163,1235,1235,1235,1235, -1235,1235,1235,1235,163,1235,1235,163,1235,1235,1235,1235,1235,1235,1235,1235, -1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235,1235, -1236,1237,1237,1237,1237,1237,163,1237,1237,163,163,1238,1238,1239,1240,1241, -1237,1241,1237,1242,1243,1244,1243,163,163,163,163,163,163,163,163,163, -1245,1245,1245,1245,1245,1245,1245,1245,1245,1245,163,163,163,163,163,163, +1233,1233,1233,1233,1233,1233,1233,163,163,1233,163,163,1233,1233,1233,1233, +1233,1233,1233,1233,163,1233,1233,163,1233,1233,1233,1233,1233,1233,1233,1233, +1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233,1233, +1234,1235,1235,1235,1235,1235,163,1235,1235,163,163,1236,1236,1237,1238,1239, +1235,1239,1235,1240,1241,1242,1241,163,163,163,163,163,163,163,163,163, +1243,1243,1243,1243,1243,1243,1243,1243,1243,1243,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 189 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1246,1246,1246,1246,1246,1246,1246,1246,163,163,1246,1246,1246,1246,1246,1246, -1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246, -1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246,1246, -1246,1247,1247,1247,1248,1248,1248,1248,163,163,1248,1248,1247,1247,1247,1247, -1249,1246,1250,1246,1247,163,163,163,163,163,163,163,163,163,163,163, +1244,1244,1244,1244,1244,1244,1244,1244,163,163,1244,1244,1244,1244,1244,1244, +1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244, +1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244,1244, +1244,1245,1245,1245,1246,1246,1246,1246,163,163,1246,1246,1245,1245,1245,1245, +1247,1244,1248,1244,1245,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 190 */ -1251,1252,1252,1252,1252,1252,1252,1253,1253,1252,1252,1251,1251,1251,1251,1251, -1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251, -1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251,1251, -1251,1251,1251,1254,1255,1252,1252,1252,1252,1256,1257,1252,1252,1252,1252,1258, -1258,1258,1259,1259,1258,1258,1258,1255,163,163,163,163,163,163,163,163, -1260,1261,1261,1261,1261,1261,1261,1262,1262,1261,1261,1261,1260,1260,1260,1260, -1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260, -1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260,1260, +1249,1250,1250,1250,1250,1250,1250,1251,1251,1250,1250,1249,1249,1249,1249,1249, +1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249, +1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249,1249, +1249,1249,1249,1252,1253,1250,1250,1250,1250,1254,1255,1250,1250,1250,1250,1256, +1256,1256,1257,1257,1256,1256,1256,1253,163,163,163,163,163,163,163,163, +1258,1259,1259,1259,1259,1259,1259,1260,1260,1259,1259,1259,1258,1258,1258,1258, +1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258, +1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258,1258, /* block 191 */ -1260,1260,1260,1260,1263,1263,1263,1263,1263,1263,1261,1261,1261,1261,1261,1261, -1261,1261,1261,1261,1261,1261,1261,1262,1264,1265,1266,1267,1267,1260,1266,1266, -1266,1268,1268,163,163,163,163,163,163,163,163,163,163,163,163,163, -495,495,495,495,495,495,495,495,495,495,495,495,495,495,495,495, -1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269, -1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269, -1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269,1269, -1269,1269,1269,1269,1269,1269,1269,1269,1269,163,163,163,163,163,163,163, +1258,1258,1258,1258,1261,1261,1261,1261,1261,1261,1259,1259,1259,1259,1259,1259, +1259,1259,1259,1259,1259,1259,1259,1260,1262,1263,1264,1265,1265,1258,1264,1264, +1264,1266,1266,163,163,163,163,163,163,163,163,163,163,163,163,163, +496,496,496,496,496,496,496,496,496,496,496,496,496,496,496,496, +1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, +1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, +1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267,1267, +1267,1267,1267,1267,1267,1267,1267,1267,1267,163,163,163,163,163,163,163, /* block 192 */ -1270,1270,1270,1270,1270,1270,1270,1270,1270,163,1270,1270,1270,1270,1270,1270, -1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270, -1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1270,1271, -1272,1272,1272,1272,1272,1272,1272,163,1272,1272,1272,1272,1272,1272,1271,1273, -1270,1274,1274,1275,1276,1276,163,163,163,163,163,163,163,163,163,163, -1277,1277,1277,1277,1277,1277,1277,1277,1277,1277,1278,1278,1278,1278,1278,1278, -1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,1278,163,163,163, -1279,1280,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281, +343,343,343,343,343,343,343,343,343,343,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 193 */ -1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281,1281, -163,163,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, -1282,1282,1282,1282,1282,1282,1282,1282,163,1283,1282,1282,1282,1282,1282,1282, -1282,1283,1282,1282,1283,1282,1282,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1268,1268,1268,1268,1268,1268,1268,1268,1268,163,1268,1268,1268,1268,1268,1268, +1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268, +1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1268,1269, +1270,1270,1270,1270,1270,1270,1270,163,1270,1270,1270,1270,1270,1270,1269,1271, +1268,1272,1272,1273,1274,1274,163,163,163,163,163,163,163,163,163,163, +1275,1275,1275,1275,1275,1275,1275,1275,1275,1275,1276,1276,1276,1276,1276,1276, +1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,1276,163,163,163, +1277,1278,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279, /* block 194 */ -1284,1284,1284,1284,1284,1284,1284,163,1284,1284,163,1284,1284,1284,1284,1284, -1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284, -1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284,1284, -1284,1285,1285,1285,1285,1285,1285,163,163,163,1285,163,1285,1285,163,1285, -1285,1285,1286,1285,1287,1287,1288,1285,163,163,163,163,163,163,163,163, -1289,1289,1289,1289,1289,1289,1289,1289,1289,1289,163,163,163,163,163,163, -1290,1290,1290,1290,1290,1290,163,1290,1290,163,1290,1290,1290,1290,1290,1290, -1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1290, +1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279,1279, +163,163,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280,1280, +1280,1280,1280,1280,1280,1280,1280,1280,163,1281,1280,1280,1280,1280,1280,1280, +1280,1281,1280,1280,1281,1280,1280,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 195 */ -1290,1290,1290,1290,1290,1290,1290,1290,1290,1290,1291,1291,1291,1291,1291,163, -1292,1292,163,1291,1291,1292,1291,1293,1290,163,163,163,163,163,163,163, -1294,1294,1294,1294,1294,1294,1294,1294,1294,1294,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1282,1282,1282,1282,1282,1282,1282,163,1282,1282,163,1282,1282,1282,1282,1282, +1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, +1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282,1282, +1282,1283,1283,1283,1283,1283,1283,163,163,163,1283,163,1283,1283,163,1283, +1283,1283,1284,1283,1285,1285,1286,1283,163,163,163,163,163,163,163,163, +1287,1287,1287,1287,1287,1287,1287,1287,1287,1287,163,163,163,163,163,163, +1288,1288,1288,1288,1288,1288,163,1288,1288,163,1288,1288,1288,1288,1288,1288, +1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1288, /* block 196 */ +1288,1288,1288,1288,1288,1288,1288,1288,1288,1288,1289,1289,1289,1289,1289,163, +1290,1290,163,1289,1289,1290,1289,1291,1288,163,163,163,163,163,163,163, +1292,1292,1292,1292,1292,1292,1292,1292,1292,1292,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295,1295, -1295,1295,1295,1296,1296,1297,1297,1298,1298,163,163,163,163,163,163,163, /* block 197 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -842,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299,1299, -388,388,1299,388,1299,390,390,390,390,390,390,390,390,391,391,391, -391,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390, -390,390,163,163,163,163,163,163,163,163,163,163,163,163,163,1300, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293,1293, +1293,1293,1293,1294,1294,1295,1295,1296,1296,163,163,163,163,163,163,163, /* block 198 */ -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, +1297,1297,1298,1299,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1300,163,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300,1300, +1300,1300,1300,1300,1299,1299,1297,1297,1297,1297,1297,163,163,163,1299,1299, +1297,1301,1302,1303,1303,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, +1305,1305,1305,1305,1305,1305,1305,1305,1305,1305,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 199 */ -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +843,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, +388,388,1306,388,1306,390,390,390,390,390,390,390,390,391,391,391, +391,390,390,390,390,390,390,390,390,390,390,390,390,390,390,390, +390,390,163,163,163,163,163,163,163,163,163,163,163,163,163,1307, /* block 200 */ -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302, -1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,1302,163, -1303,1303,1303,1303,1303,163,163,163,163,163,163,163,163,163,163,163, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, /* block 201 */ -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301,1301, -1301,1301,1301,1301,163,163,163,163,163,163,163,163,163,163,163,163, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 202 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304,1304, -1304,1305,1305,163,163,163,163,163,163,163,163,163,163,163,163,163, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, +1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,163, +1310,1310,1310,1310,1310,163,163,163,163,163,163,163,163,163,163,163, /* block 203 */ -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1308,1308,1308,1308,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 204 */ -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306, -1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,1306,163, -1307,1307,1307,1307,1307,1307,1307,1307,1307,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311,1311, +1311,1312,1312,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 205 */ -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, /* block 206 */ -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308,1308, -1308,1308,1308,1308,1308,1308,1308,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,1313, +1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314, +1315,1313,1313,1313,1313,1313,1313,1316,1316,1316,1316,1316,1316,1316,1316,1316, +1316,1316,1316,1316,1316,1316,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 207 */ -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, /* block 208 */ -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, -858,858,858,858,858,858,858,858,858,163,163,163,163,163,163,163, -1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309, -1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,1309,163, -1310,1310,1310,1310,1310,1310,1310,1310,1310,1310,163,163,163,163,1311,1311, -1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, +1317,1317,1317,1317,1317,1317,1317,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 209 */ -1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312, -1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312, -1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312, -1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,1312,163, -1313,1313,1313,1313,1313,1313,1313,1313,1313,1313,163,163,163,163,163,163, -1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314, -1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,1314,163,163, -1315,1315,1315,1315,1315,1316,163,163,163,163,163,163,163,163,163,163, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, /* block 210 */ -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1318,1318,1318,1318,1318,1318,1318,1319,1319,1320,1321,1321,1322,1322,1322,1322, -1323,1323,1324,1324,1319,1322,163,163,163,163,163,163,163,163,163,163, -1325,1325,1325,1325,1325,1325,1325,1325,1325,1325,163,1326,1326,1326,1326,1326, -1326,1326,163,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -1317,1317,1317,1317,1317,1317,1317,1317,163,163,163,163,163,1317,1317,1317, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,859,163,163,163,163,163,163,163, +1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318, +1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,1318,163, +1319,1319,1319,1319,1319,1319,1319,1319,1319,1319,163,163,163,163,1320,1320, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, /* block 211 */ -1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317,1317, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321, +1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,1321,163, +1322,1322,1322,1322,1322,1322,1322,1322,1322,1322,163,163,163,163,163,163, +1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323, +1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,1323,163,163, +1324,1324,1324,1324,1324,1325,163,163,163,163,163,163,163,163,163,163, /* block 212 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327, -1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327,1327, -1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328, -1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328,1328, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1327,1327,1327,1327,1327,1327,1327,1328,1328,1329,1330,1330,1331,1331,1331,1331, +1332,1332,1333,1333,1328,1331,163,163,163,163,163,163,163,163,163,163, +1334,1334,1334,1334,1334,1334,1334,1334,1334,1334,163,1335,1335,1335,1335,1335, +1335,1335,163,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +1326,1326,1326,1326,1326,1326,1326,1326,163,163,163,163,163,1326,1326,1326, /* block 213 */ -1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329,1329, -1329,1329,1329,1329,1329,1329,1329,1330,1331,1332,1332,163,163,163,163,163, +1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326,1326, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, @@ -4526,369 +4540,369 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 214 */ -1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333, -1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333, -1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333, -1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333, -1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,1333,163,163,163,163,1334, -1333,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335, -1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335, -1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335,1335, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336, +1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336,1336, +1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337, +1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337, /* block 215 */ -1335,1335,1335,1335,1335,1335,1335,1335,163,163,163,163,163,163,163,1336, -1336,1336,1336,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337,1337, +1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338,1338, +1338,1338,1338,1338,1338,1338,1338,1339,1340,1341,1341,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1338,1339,1340,799,1341,163,163,163,163,163,163,163,163,163,163,163, -1342,1342,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 216 */ -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342, +1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,1342,163,163,163,163,1343, +1342,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, +1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, +1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, /* block 217 */ -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343,1343, -1343,1343,1343,1343,1343,1343,1343,1343,163,163,163,163,163,163,163,163, +1344,1344,1344,1344,1344,1344,1344,1344,163,163,163,163,163,163,163,1345, +1345,1345,1345,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1347,1348,1349,800,1350,163,163,163,163,163,163,163,163,163,163,163, +1351,1351,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 218 */ -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, /* block 219 */ -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344,1344, -1344,1344,1344,1344,1344,1344,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352,1352, +1352,1352,1352,1352,1352,1352,1352,1352,163,163,163,163,163,163,163,163, /* block 220 */ -1343,1343,1343,1343,1343,1343,1343,1343,1343,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, /* block 221 */ +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353,1353, +1353,1353,1353,1353,1353,1353,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1345,1345,1345,1345,163,1345,1345,1345,1345,1345,1345,1345,163,1345,1345,163, /* block 222 */ -824,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +1352,1352,1352,1352,1352,1352,1352,1352,1352,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 223 */ -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1354,1354,1354,1354,163,1354,1354,1354,1354,1354,1354,1354,163,1354,1354,163, /* block 224 */ -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -819,819,819,819,819,819,819,819,819,819,819,819,819,819,819,819, -824,824,824,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -819,819,819,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,824,824,824,824,163,163,163,163,163,163,163,163, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, +825,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, /* block 225 */ -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, /* block 226 */ -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346, -1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,1346,163,163,163,163, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +825,825,825,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,820,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +820,820,820,163,163,825,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,825,825,825,825,163,163,163,163,163,163,163,163, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, /* block 227 */ -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,163,163,163, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,163, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, /* block 228 */ -1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,163,163,163,163,163, -1347,1347,1347,1347,1347,1347,1347,1347,1347,1347,163,163,1348,1349,1350,1351, -1352,1352,1352,1352,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355, +1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,1355,163,163,163,163, /* block 229 */ -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,163,163, -154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, -154,154,154,154,154,154,154,163,163,163,163,163,163,163,163,163, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163,163,163, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163, /* block 230 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,163,163,163,163,163,163,163,163,163,163,163,163, +1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,163,163,163,163,163, +1356,1356,1356,1356,1356,1356,1356,1356,1356,1356,163,163,1357,1358,1359,1360, +1361,1361,1361,1361,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 231 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,163,163, +154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154, +154,154,154,154,154,154,154,163,163,163,163,163,163,163,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, /* block 232 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,163,163,163,163,163,163,163,163,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 233 */ -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,163,163,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,1353,1354,154,154,154,460,460,460,1355,1356,1356, -1356,1356,1356, 51, 51, 51, 51, 51, 51, 51, 51,154,154,154,154,154, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, /* block 234 */ -154,154,154,460,460,154,154,154,154,154,154,154,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,154,154,154,154,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,723,723,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,163,163,163,163,163,163,163,163,163,163, /* block 235 */ -1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002, -1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002, -1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002, -1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002,1002, -1002,1002,1357,1357,1357,1002,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,163,163,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,1362,1363,154,154,154,461,461,461,1364,1365,1365, +1365,1365,1365, 51, 51, 51, 51, 51, 51, 51, 51,154,154,154,154,154, /* block 236 */ +154,154,154,461,461,154,154,154,154,154,154,154,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,154,154,154,154,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,724,724,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835, -835,835,835,835,163,163,163,163,163,163,163,163,163,163,163,163, /* block 237 */ -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,163,163,163,163,163,163,163,163,163, -832,832,832,832,832,832,832,832,832,832,832,832,832,832,832,832, -832,832,835,835,835,835,835,835,835,163,163,163,163,163,163,163, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001,1001, +1001,1001,1366,1366,1366,1001,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 238 */ -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725, -725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,725,725, -725,725,725,725,725,163,736,736,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836, +836,836,836,836,163,163,163,163,163,163,163,163,163,163,163,163, +836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836, +836,836,836,836,163,163,163,163,163,163,163,163,163,163,163,163, /* block 239 */ -724,724,725,725,725,725,725,725,725,725,736,736,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,724,163,724,724, -163,163,724,163,163,724,724,163,163,724,724,724,724,163,724,724, -724,724,724,724,724,724,725,725,725,725,163,725,163,725,736,736, -725,725,725,725,163,725,725,725,725,725,725,725,725,725,725,725, 724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725, -725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,163,163,163,163,163,163,163,163,163, +833,833,833,833,833,833,833,833,833,833,833,833,833,833,833,833, +833,833,836,836,836,836,836,836,836,163,163,163,163,163,163,163, /* block 240 */ -725,725,725,725,724,724,163,724,724,724,724,163,163,724,724,724, -724,724,724,724,724,163,724,724,724,724,724,724,724,163,725,725, -725,725,725,725,725,725,736,736,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,724,724,163,724,724,724,724,163, -724,724,724,724,724,163,724,163,163,163,724,724,724,724,724,724, -724,163,725,725,725,725,725,725,725,725,736,736,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,726,726, +726,726,726,726,726,163,737,737,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, /* block 241 */ -724,724,724,724,724,724,725,725,725,725,725,725,725,725,736,736, +725,725,726,726,726,726,726,726,726,726,737,737,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,725,163,725,725, +163,163,725,163,163,725,725,163,163,725,725,725,725,163,725,725, +725,725,725,725,725,725,726,726,726,726,163,726,163,726,737,737, +726,726,726,726,163,726,726,726,726,726,726,726,726,726,726,726, 725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725, -725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,725,725, -725,725,725,725,725,725,736,736,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, /* block 242 */ -725,725,725,725,725,725,725,725,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,725,725,725,725,725,725,725,725,736,736,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,725,725,725,725,725,725,725,725,736,736, +726,726,726,726,725,725,163,725,725,725,725,163,163,725,725,725, +725,725,725,725,725,163,725,725,725,725,725,725,725,163,726,726, +726,726,726,726,726,726,737,737,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,725,725,163,725,725,725,725,163, +725,725,725,725,725,163,725,163,163,163,725,725,725,725,725,725, +725,163,726,726,726,726,726,726,726,726,737,737,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,725,725,725,725, 725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 243 */ -724,724,724,724,724,724,724,724,724,724,725,725,725,725,725,725, -725,725,736,736,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,163,163,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,1358,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,715,725,725,725,725, -725,725,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,1358,725,725,725,725, +725,725,725,725,725,725,726,726,726,726,726,726,726,726,737,737, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,726,726, +726,726,726,726,726,726,737,737,726,726,726,726,726,726,726,726, /* block 244 */ +726,726,726,726,726,726,726,726,725,725,725,725,725,725,725,725, 725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,715,725,725,725,725,725,725,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,1358,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,715, -725,725,725,725,725,725,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,1358, +725,725,726,726,726,726,726,726,726,726,737,737,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,726,726,726,726,726,726,726,726,737,737, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, 725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, /* block 245 */ -725,725,725,725,725,725,725,725,725,715,725,725,725,725,725,725, -724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, -724,724,724,724,724,724,724,724,724,1358,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,726,726,726,726,726,726, +726,726,737,737,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,163,163,725,725,725,725,725,725,725,725, 725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,715,725,725,725,725,725,725,724,725,163,163,1359,1359, -1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359, -1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359, -1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359,1359, +725,1367,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,716,726,726,726,726, +726,726,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,1367,726,726,726,726, /* block 246 */ -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, -1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,716,726,726,726,726,726,726,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,1367,726,726,726,726,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,716, +726,726,726,726,726,726,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,1367, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, /* block 247 */ -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1360,1360,1360,1360,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1360,1360,1360, -1360,1360,1360,1360,1360,1361,1360,1360,1360,1360,1360,1360,1360,1360,1360,1360, +726,726,726,726,726,726,726,726,726,716,726,726,726,726,726,726, +725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725, +725,725,725,725,725,725,725,725,725,1367,726,726,726,726,726,726, +726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726, +726,726,726,716,726,726,726,726,726,726,725,726,163,163,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, +1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368,1368, /* block 248 */ -1360,1360,1360,1360,1361,1360,1360,1362,1363,1362,1362,1364,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,1361,1361,1361,1361,1361, -163,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361,1361, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, +1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, /* block 249 */ - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 92, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,643, 70, 70, 70, 70,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1369,1369,1369,1369,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, +1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1369,1369,1369, +1369,1369,1369,1369,1369,1370,1369,1369,1369,1369,1369,1369,1369,1369,1369,1369, /* block 250 */ -1365,1365,1365,1365,1365,1365,1365,163,1365,1365,1365,1365,1365,1365,1365,1365, -1365,1365,1365,1365,1365,1365,1365,1365,1365,163,163,1365,1365,1365,1365,1365, -1365,1365,163,1365,1365,163,1365,1365,1365,1365,1365,163,163,163,163,163, +1369,1369,1369,1369,1370,1369,1369,1371,1372,1371,1371,1373,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,1370,1370,1370,1370,1370, +163,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,1370, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, @@ -4896,494 +4910,544 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 76800 bytes, block = 128 */ 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 251 */ -1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366, -1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366, -1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,1366,163,163,163, -1367,1367,1367,1367,1367,1367,1367,1368,1368,1368,1368,1368,1369,1369,163,163, -1370,1370,1370,1370,1370,1370,1370,1370,1370,1370,163,163,163,163,1366,1371, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 92, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,644, 70, 70, 70, 70,163, +163,163,163,163,163, 70, 70, 70, 70, 70, 70,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 252 */ +1374,1374,1374,1374,1374,1374,1374,163,1374,1374,1374,1374,1374,1374,1374,1374, +1374,1374,1374,1374,1374,1374,1374,1374,1374,163,163,1374,1374,1374,1374,1374, +1374,1374,163,1374,1374,163,1374,1374,1374,1374,1374,163,163,163,163,163, +858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +858,858,858,858,858,858,858,858,858,858,858,858,1375,1375,858,858, +858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +858,858,858,858,858,858,858,858,1375,858,858,858,858,858,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372, -1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1372,1373,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374, -1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374, -1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1374,1375,1375,1375,1375, -1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,163,163,163,163,163,1377, /* block 253 */ +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,788, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -483,483,483,483,483,483,483,163,483,483,483,483,163,483,483,163, -483,483,483,483,483,483,483,483,483,483,483,483,483,483,483,163, /* block 254 */ -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, +1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376, +1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376, +1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,1376,163,163,163, +1377,1377,1377,1377,1377,1377,1377,1378,1378,1378,1378,1378,1379,1379,163,163, +1380,1380,1380,1380,1380,1380,1380,1380,1380,1380,163,163,163,163,1376,1381, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 255 */ -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378,1378, -1378,1378,1378,1378,1378,262,262,1379,1379,1379,1379,1379,1379,1379,1379,1379, -1380,1380,1380,1380,1380,1380,1380,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382, +1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1383,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384, +1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384, +1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1384,1385,1385,1385,1385, +1386,1386,1386,1386,1386,1386,1386,1386,1386,1386,163,163,163,163,163,1387, /* block 256 */ -1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381, -1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381,1381, -1381,1381,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382, -1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382,1382, -1382,1382,1382,1382,1383,1383,1383,1384,1385,1385,1385,1386,262,262,262,262, -1387,1387,1387,1387,1387,1387,1387,1387,1387,1387,262,262,262,262,1388,1388, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388, +1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1388,1389,1390,1390,1390,1390, +1391,1391,1391,1391,1391,1391,1391,1391,1391,1391,163,163,163,163,163,163, /* block 257 */ -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -302,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +484,484,484,484,484,484,484,163,484,484,484,484,163,484,484,163, +484,484,484,484,484,484,484,484,484,484,484,484,484,484,484,163, /* block 258 */ -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389, -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389, -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1390,1389,1389,1389, -1391,1389,1389,1389,1389,302,302,302,302,302,302,302,302,302,302,302, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, + +/* block 259 */ +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, +1392,1392,1392,1392,1392,262,262,1393,1393,1393,1393,1393,1393,1393,1393,1393, +1394,1394,1394,1394,1394,1394,1394,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, + +/* block 260 */ +1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1395,1395,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, +1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, +1396,1396,1396,1396,1397,1397,1397,1398,1399,1399,1399,1400,262,262,262,262, +1401,1401,1401,1401,1401,1401,1401,1401,1401,1401,262,262,262,262,1402,1402, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, + +/* block 261 */ +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, +302,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, + +/* block 262 */ +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1404,1403,1403,1403, +1405,1403,1403,1403,1403,302,302,302,302,302,302,302,302,302,302,302, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -/* block 259 */ -302,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389, -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389, -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1390,1389, -1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,1389,302,302, +/* block 263 */ +302,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1404,1403, +1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,302,302, 302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, 262,262,262,262,262,262,262,262,262,262,262,262,262,262,262,262, -/* block 260 */ -1392,1392,1392,1392,302,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392, -302,1392,1392,302,1392,302,302,1392,302,1392,1392,1392,1392,1392,1392,1392, -1392,1392,1392,302,1392,1392,1392,1392,302,1392,302,1392,302,302,302,302, -302,302,1392,302,302,302,302,1392,302,1392,302,1392,302,1392,1392,1392, -302,1392,1392,302,1392,302,302,1392,302,1392,302,1392,302,1392,302,1392, -302,1392,1392,302,1392,302,302,1392,1392,1392,1392,302,1392,1392,1392,1392, -1392,1392,1392,302,1392,1392,1392,1392,302,1392,1392,1392,1392,302,1392,302, +/* block 264 */ +1406,1406,1406,1406,302,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406, +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406, +302,1406,1406,302,1406,302,302,1406,302,1406,1406,1406,1406,1406,1406,1406, +1406,1406,1406,302,1406,1406,1406,1406,302,1406,302,1406,302,302,302,302, +302,302,1406,302,302,302,302,1406,302,1406,302,1406,302,1406,1406,1406, +302,1406,1406,302,1406,302,302,1406,302,1406,302,1406,302,1406,302,1406, +302,1406,1406,302,1406,302,302,1406,1406,1406,1406,302,1406,1406,1406,1406, +1406,1406,1406,302,1406,1406,1406,1406,302,1406,1406,1406,1406,302,1406,302, -/* block 261 */ -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,302,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,302,302,302,302, -302,1392,1392,1392,302,1392,1392,1392,1392,1392,302,1392,1392,1392,1392,1392, -1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,1392,302,302,302,302, +/* block 265 */ +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,1406,1406,1406,1406,1406, +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,302,302,302, +302,1406,1406,1406,302,1406,1406,1406,1406,1406,302,1406,1406,1406,1406,1406, +1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,1406,302,302,302,302, 302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, 302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, 302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, 274,274,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -/* block 262 */ -1393,1393,1393,1393,1394,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1395,1395,1395,1395, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, - -/* block 263 */ -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1395, -1395,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1395,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1394, -1395,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, - -/* block 264 */ - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 58, 58,1393,1393,1393, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,1393, -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,460,460,460,460,460,460, -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396, -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,723,723,1393,1393,1393,1393, -1397,1397,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,1397,1397, - -/* block 265 */ -1396,1396,1396,1396,1396,1396,1396,1396,1396,1396,460,460,460,460,1398,460, -460,1398,1398,1398,1398,1398,1398,1398,1398,1398,1398,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,1393,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399, -1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399,1399, - /* block 266 */ -1400,1398,1401,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -460,460,460,460,460,460,460,460,460,460,1398,460,460,460,460,460, -460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,1398, -460,460,1398,1398,1398,1398,1398,1401,1398,1398,1398,460,1395,1395,1395,1395, -460,460,460,460,460,460,460,460,460,1395,1395,1395,1395,1395,1395,1395, -1402,1402,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1393,1393,1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1407,1407,1407,1407,1408,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, /* block 267 */ -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409, +1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1408, +1409,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 268 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,727,1393,1393,727,727,727,727,727,727,727,727,727,1394,1394,1394, -1394,1394,1394,1394,1394,1394,727,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,727,1394,1394, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 58, 58,1407,1407,1407, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,1407, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,461,461,461,461,461,461, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,724,724,1407,1407,1407,1407, +1411,1411,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,1411,1411, /* block 269 */ -1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1393,1393,727,727,1393,727,727,727,1393,1393,727,727, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1403,1403,1403,1394,1394,1403,1394,1394,1403,1404,1404,727,727,1394, -1394,1394,1394,1394,727,727,727,727,727,727,727,727,727,727,727,727, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1393,1393,727,1394,727,1393,727,1394,1394,1394,1405,1405,1405,1405,1405, +1410,1410,1410,1410,1410,1410,1410,1410,1410,1410,461,461,461,461,1412,461, +461,1412,1412,1412,1412,1412,1412,1412,1412,1412,1412,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,1407,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, +1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413,1413, /* block 270 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,727, -1394,727,1403,1403,1394,1394,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, -1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403, -1403,1403,1403,1403,1403,1403,1403,1403,1403,1394,1394,1394,1403,1394,1394,1394, +1414,1412,1415,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +461,461,461,461,461,461,461,461,461,461,1412,461,461,461,461,461, +461,461,461,461,461,461,461,461,461,461,461,461,461,461,461,1412, +461,461,1412,1412,1412,1412,1412,1415,1412,1412,1412,461,1409,1409,1409,1409, +461,461,461,461,461,461,461,461,461,1409,1409,1409,1409,1409,1409,1409, +1416,1416,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 271 */ -1394,1403,1403,1403,1394,1403,1403,1403,1394,1394,1394,1394,1394,1394,1394,1403, -1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,727,1393,1394, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 272 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,723,723, -723,723,723,723,723,723,1393,1393,1393,727,727,1394,1394,1394,1394,1393, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1393,1393,1393,1393,1393,1393,1393,727, -727,1393,1393,727,1404,1404,727,727,727,727,1403,1393,1393,1393,1393,1393, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,728,1407,1407,728,728,728,728,728,728,728,728,728,1408,1408,1408, +1408,1408,1408,1408,1408,1408,728,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728,1408,1408, /* block 273 */ -1393,1393,1393,1393,1393,1393,1393,727,1393,1393,727,727,727,727,1393,1393, -1404,1393,1393,1393,1393,1403,1403,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1394,727,1393,1393,727,1393,1393,1393,1393,1393,1393,1393, -1393,727,727,1393,1393,1393,1393,1393,1393,1393,1393,1393,727,1393,1393,1393, -1393,1393,727,727,727,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,727,727,727,1393,1393,1393,1393,1393,1393,1393,1393,727,727,727,1393, -1393,727,1393,727,1393,1393,1393,1393,727,1393,1393,1393,1393,1393,1393,727, -1393,1393,1393,727,1393,1393,1393,1393,1393,1393,727,1394,1394,1394,1394,1394, +1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1407,1407,728,728,1407,728,728,728,1407,1407,728,728, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1417,1417,1417,1408,1408,1417,1408,1408,1417,1418,1418,728,728,1408, +1408,1408,1408,1408,728,728,728,728,728,728,728,728,728,728,728,728, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1407,1407,728,1408,728,1407,728,1408,1408,1408,1419,1419,1419,1419,1419, /* block 274 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1403,1403,1403,1394,1394,1394,1403,1403,1403,1403,1403, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728, +1408,728,1417,1417,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417, +1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417, +1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,1408,1408,1417,1408,1408,1408, /* block 275 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1403,1403,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1403,1394,1394,1394,1394,1394,1393,1393,1393,1393,1393,727,1403,727,727,727, -1394,1394,1394,1393,1393,1394,1394,1394,1395,1395,1395,1395,1395,1394,1394,1394, -727,727,727,727,727,727,1393,1393,1393,727,1393,1394,1394,1395,1395,1395, -727,1393,1393,727,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395, +1408,1417,1417,1417,1408,1417,1417,1417,1408,1408,1408,1408,1408,1408,1408,1417, +1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,728,1407,1408, /* block 276 */ -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,724,724, +724,724,724,724,724,724,1407,1407,1407,728,728,1408,1408,1408,1408,1407, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1407,1407,1407,1407,1407,1407,1407,728, +728,1407,1407,728,1418,1418,728,728,728,728,1417,1407,1407,1407,1407,1407, /* block 277 */ -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395, -1394,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1407,1407,1407,1407,1407,1407,1407,728,1407,1407,728,728,728,728,1407,1407, +1418,1407,1407,1407,1407,1417,1417,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1408,728,1407,1407,728,1407,1407,1407,1407,1407,1407,1407, +1407,728,728,1407,1407,1407,1407,1407,1407,1407,1407,1407,728,1407,1407,1407, +1407,1407,728,728,728,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,728,728,728,1407,1407,1407,1407,1407,1407,1407,1407,728,728,728,1407, +1407,728,1407,728,1407,1407,1407,1407,728,1407,1407,1407,1407,1407,1407,728, +1407,1407,1407,728,1407,1407,1407,1407,1407,1407,728,1408,1408,1408,1408,1408, /* block 278 */ -723,723,723,723,723,723,723,723,723,723,723,723,1395,1395,1395,1395, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,1395,1395,1395,1395,1395,1395,1395,1395, -723,723,723,723,723,723,723,723,723,723,1395,1395,1395,1395,1395,1395, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1417,1417,1417,1408,1408,1408,1417,1417,1417,1417,1417, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 279 */ -723,723,723,723,723,723,723,723,1395,1395,1395,1395,1395,1395,1395,1395, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,1395,1395, -1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1417,1417,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1417,1408,1408,1408,1408,1408,1407,1407,1407,1407,1407,728,1417,728,728,728, +1408,1408,1408,1407,1407,1408,1408,1408,1409,1409,1409,1409,1408,1408,1408,1408, +728,728,728,728,728,728,1407,1407,1407,728,1407,1408,1408,1409,1409,1409, +728,1407,1407,728,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409, /* block 280 */ -723,723,723,723,723,723,723,723,723,723,723,723,1403,1394,1394,1403, -1394,1394,1394,1394,1394,1394,1394,1394,1403,1403,1403,1403,1403,1403,1403,1403, -1394,1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1394,723,1403,1403,1403,1394, -1394,1394,1394,1394,1394,1394,723,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1403,1394,1394,1394,1394,1394,1394,1394,1394, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,1407,1407,1407,1409,1409,1409,1409,1407,1407,1407,1407,1407, /* block 281 */ -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1406,1406,1406,1406,1394,1403,1403,1394,1403,1403,1394,1403,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1403,1403,1403, -1394,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1403,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,1407,1407,1407,1407,1407,1409,1409,1409,1409,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409, +1408,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 282 */ -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393, -1393,1393,1393,1393,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1393,1395,1395, -1394,1394,1394,1394,1394,1395,1395,1395,1394,1394,1394,1394,1394,1395,1395,1395, +724,724,724,724,724,724,724,724,724,724,724,724,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 283 */ -1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395, -1394,1394,1394,1403,1403,1403,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1394,1394,1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395,1395, -1394,1394,1394,1394,1394,1394,1394,1394,1395,1395,1395,1395,1395,1395,1395,1395, -1403,1403,1403,1403,1403,1403,1403,1395,1395,1395,1395,1395,1395,1395,1395,1395, +724,724,724,724,724,724,724,724,1409,1409,1409,1409,1409,1409,1409,1409, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,1409,1409, +1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, /* block 284 */ -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, +724,724,724,724,724,724,724,724,724,724,724,724,1417,1408,1408,1417, +1408,1408,1408,1408,1408,1408,1408,1408,1417,1417,1417,1417,1417,1417,1417,1417, +1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,724,1417,1417,1417,1408, +1408,1408,1408,1408,1408,1408,724,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1417,1408,1408,1408,1408,1408,1408,1408,1408, /* block 285 */ -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,163,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,723,723,723,723,723, -723,723,723,723,723,723,723,723,723,723,723,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,163,163,163,163,163,163, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1420,1420,1420,1420,1408,1417,1417,1408,1417,1417,1408,1417,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1417,1417,1417, +1408,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1417,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, /* block 286 */ -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395, -1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,1395,958,958, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407, +1407,1407,1407,1407,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1407,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409, /* block 287 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409,1409,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1408, +1408,1408,1408,1417,1417,1417,1409,1409,1409,1409,1409,1409,1409,1409,1408,1408, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409, +1408,1408,1408,1408,1408,1408,1408,1408,1408,1409,1409,1409,1409,1409,1409,1409, +1417,1417,1417,1417,1417,1417,1417,1417,1417,1409,1409,1409,1409,1409,1409,1409, /* block 288 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,163,163,163,163,163,163,163, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, /* block 289 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,163,163, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,163,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +1421,1421,1421,1421,1421,1421,1421,1421,1421,1421,163,163,163,163,163,163, /* block 290 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409, +1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,1409,957,957, /* block 291 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, 163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 292 */ -953,953,953,953,953,953,953,953,953,953,953,953,953,953,953,953, -953,953,953,953,953,953,953,953,953,953,953,953,953,953,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 293 */ -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,958,958, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 294 */ -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, -163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 295 */ -707,712,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, -1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408,1408, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 296 */ -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, +952,952,952,952,952,952,952,952,952,952,952,952,952,952,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, /* block 297 */ -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,957,957, /* block 298 */ -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -961,961,961,961,961,961,961,961,961,961,961,961,961,961,961,961, -707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,163,163,163,163,163, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, /* block 299 */ -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,952,952, -952,952,952,952,952,952,952,952,952,952,952,952,952,952,958,958, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +839,839,839,839,839,839,839,839,839,839,839,839,839,839,839,839, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, +163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163, + +/* block 300 */ +708,713,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, +1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422,1422, + +/* block 301 */ +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, + +/* block 302 */ +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, + +/* block 303 */ +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960, +708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708, + +/* block 304 */ +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,951,951, +951,951,951,951,951,951,951,951,951,951,951,951,951,951,957,957, }; #if UCD_BLOCK_SIZE != 128 diff --git a/src/3rdparty/pcre2/src/pcre2_ucp.h b/src/3rdparty/pcre2/src/pcre2_ucp.h index 282238982dc..9ccc8297508 100644 --- a/src/3rdparty/pcre2/src/pcre2_ucp.h +++ b/src/3rdparty/pcre2/src/pcre2_ucp.h @@ -166,29 +166,29 @@ enum { /* These are the bidi class values. */ enum { - ucp_bidiAL, /* Arabic letter */ - ucp_bidiAN, /* Arabic number */ - ucp_bidiB, /* Paragraph separator */ - ucp_bidiBN, /* Boundary neutral */ - ucp_bidiCS, /* Common separator */ - ucp_bidiEN, /* European number */ - ucp_bidiES, /* European separator */ - ucp_bidiET, /* European terminator */ - ucp_bidiFSI, /* First strong isolate */ - ucp_bidiL, /* Left to right */ - ucp_bidiLRE, /* Left to right embedding */ - ucp_bidiLRI, /* Left to right isolate */ - ucp_bidiLRO, /* Left to right override */ - ucp_bidiNSM, /* Non-spacing mark */ - ucp_bidiON, /* Other neutral */ - ucp_bidiPDF, /* Pop directional format */ - ucp_bidiPDI, /* Pop directional isolate */ - ucp_bidiR, /* Right to left */ - ucp_bidiRLE, /* Right to left embedding */ - ucp_bidiRLI, /* Right to left isolate */ - ucp_bidiRLO, /* Right to left override */ - ucp_bidiS, /* Segment separator */ - ucp_bidiWS, /* White space */ + ucp_bidiAL, /* Arabic_Letter */ + ucp_bidiAN, /* Arabic_Number */ + ucp_bidiB, /* Paragraph_Separator */ + ucp_bidiBN, /* Boundary_Neutral */ + ucp_bidiCS, /* Common_Separator */ + ucp_bidiEN, /* European_Number */ + ucp_bidiES, /* European_Separator */ + ucp_bidiET, /* European_Terminator */ + ucp_bidiFSI, /* First_Strong_Isolate */ + ucp_bidiL, /* Left_To_Right */ + ucp_bidiLRE, /* Left_To_Right_Embedding */ + ucp_bidiLRI, /* Left_To_Right_Isolate */ + ucp_bidiLRO, /* Left_To_Right_Override */ + ucp_bidiNSM, /* Nonspacing_Mark */ + ucp_bidiON, /* Other_Neutral */ + ucp_bidiPDF, /* Pop_Directional_Format */ + ucp_bidiPDI, /* Pop_Directional_Isolate */ + ucp_bidiR, /* Right_To_Left */ + ucp_bidiRLE, /* Right_To_Left_Embedding */ + ucp_bidiRLI, /* Right_To_Left_Isolate */ + ucp_bidiRLO, /* Right_To_Left_Override */ + ucp_bidiS, /* Segment_Separator */ + ucp_bidiWS, /* White_Space */ }; /* These are grapheme break properties. The Extended Pictographic property @@ -380,6 +380,8 @@ enum { ucp_Tangsa, ucp_Toto, ucp_Vithkuqi, + ucp_Kawi, + ucp_Nag_Mundari, /* This must be last */ ucp_Script_Count diff --git a/src/3rdparty/pcre2/src/pcre2_ucptables.c b/src/3rdparty/pcre2/src/pcre2_ucptables.c index bd1b67a9f1b..2110014c29e 100644 --- a/src/3rdparty/pcre2/src/pcre2_ucptables.c +++ b/src/3rdparty/pcre2/src/pcre2_ucptables.c @@ -265,6 +265,7 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_kana0 STR_k STR_a STR_n STR_a "\0" #define STRING_kannada0 STR_k STR_a STR_n STR_n STR_a STR_d STR_a "\0" #define STRING_katakana0 STR_k STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0" +#define STRING_kawi0 STR_k STR_a STR_w STR_i "\0" #define STRING_kayahli0 STR_k STR_a STR_y STR_a STR_h STR_l STR_i "\0" #define STRING_khar0 STR_k STR_h STR_a STR_r "\0" #define STRING_kharoshthi0 STR_k STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0" @@ -347,6 +348,8 @@ the "loose matching" rules that Unicode advises and Perl uses. */ #define STRING_mymr0 STR_m STR_y STR_m STR_r "\0" #define STRING_n0 STR_n "\0" #define STRING_nabataean0 STR_n STR_a STR_b STR_a STR_t STR_a STR_e STR_a STR_n "\0" +#define STRING_nagm0 STR_n STR_a STR_g STR_m "\0" +#define STRING_nagmundari0 STR_n STR_a STR_g STR_m STR_u STR_n STR_d STR_a STR_r STR_i "\0" #define STRING_nand0 STR_n STR_a STR_n STR_d "\0" #define STRING_nandinagari0 STR_n STR_a STR_n STR_d STR_i STR_n STR_a STR_g STR_a STR_r STR_i "\0" #define STRING_narb0 STR_n STR_a STR_r STR_b "\0" @@ -753,6 +756,7 @@ const char PRIV(utt_names)[] = STRING_kana0 STRING_kannada0 STRING_katakana0 + STRING_kawi0 STRING_kayahli0 STRING_khar0 STRING_kharoshthi0 @@ -835,6 +839,8 @@ const char PRIV(utt_names)[] = STRING_mymr0 STRING_n0 STRING_nabataean0 + STRING_nagm0 + STRING_nagmundari0 STRING_nand0 STRING_nandinagari0 STRING_narb0 @@ -1241,280 +1247,283 @@ const ucp_type_table PRIV(utt)[] = { { 1665, PT_SCX, ucp_Katakana }, { 1670, PT_SCX, ucp_Kannada }, { 1678, PT_SCX, ucp_Katakana }, - { 1687, PT_SCX, ucp_Kayah_Li }, - { 1695, PT_SC, ucp_Kharoshthi }, + { 1687, PT_SC, ucp_Kawi }, + { 1692, PT_SCX, ucp_Kayah_Li }, { 1700, PT_SC, ucp_Kharoshthi }, - { 1711, PT_SC, ucp_Khitan_Small_Script }, - { 1729, PT_SC, ucp_Khmer }, - { 1735, PT_SC, ucp_Khmer }, - { 1740, PT_SCX, ucp_Khojki }, + { 1705, PT_SC, ucp_Kharoshthi }, + { 1716, PT_SC, ucp_Khitan_Small_Script }, + { 1734, PT_SC, ucp_Khmer }, + { 1740, PT_SC, ucp_Khmer }, { 1745, PT_SCX, ucp_Khojki }, - { 1752, PT_SCX, ucp_Khudawadi }, - { 1762, PT_SC, ucp_Khitan_Small_Script }, - { 1767, PT_SCX, ucp_Kannada }, - { 1772, PT_SCX, ucp_Kaithi }, - { 1777, PT_GC, ucp_L }, - { 1779, PT_LAMP, 0 }, - { 1782, PT_SC, ucp_Tai_Tham }, - { 1787, PT_SC, ucp_Lao }, - { 1791, PT_SC, ucp_Lao }, - { 1796, PT_SCX, ucp_Latin }, - { 1802, PT_SCX, ucp_Latin }, - { 1807, PT_LAMP, 0 }, - { 1810, PT_SC, ucp_Lepcha }, + { 1750, PT_SCX, ucp_Khojki }, + { 1757, PT_SCX, ucp_Khudawadi }, + { 1767, PT_SC, ucp_Khitan_Small_Script }, + { 1772, PT_SCX, ucp_Kannada }, + { 1777, PT_SCX, ucp_Kaithi }, + { 1782, PT_GC, ucp_L }, + { 1784, PT_LAMP, 0 }, + { 1787, PT_SC, ucp_Tai_Tham }, + { 1792, PT_SC, ucp_Lao }, + { 1796, PT_SC, ucp_Lao }, + { 1801, PT_SCX, ucp_Latin }, + { 1807, PT_SCX, ucp_Latin }, + { 1812, PT_LAMP, 0 }, { 1815, PT_SC, ucp_Lepcha }, - { 1822, PT_SCX, ucp_Limbu }, + { 1820, PT_SC, ucp_Lepcha }, { 1827, PT_SCX, ucp_Limbu }, - { 1833, PT_SCX, ucp_Linear_A }, - { 1838, PT_SCX, ucp_Linear_B }, - { 1843, PT_SCX, ucp_Linear_A }, - { 1851, PT_SCX, ucp_Linear_B }, - { 1859, PT_SC, ucp_Lisu }, - { 1864, PT_PC, ucp_Ll }, - { 1867, PT_PC, ucp_Lm }, - { 1870, PT_PC, ucp_Lo }, - { 1873, PT_BOOL, ucp_Logical_Order_Exception }, - { 1877, PT_BOOL, ucp_Logical_Order_Exception }, - { 1899, PT_BOOL, ucp_Lowercase }, - { 1905, PT_BOOL, ucp_Lowercase }, - { 1915, PT_PC, ucp_Lt }, - { 1918, PT_PC, ucp_Lu }, - { 1921, PT_SC, ucp_Lycian }, + { 1832, PT_SCX, ucp_Limbu }, + { 1838, PT_SCX, ucp_Linear_A }, + { 1843, PT_SCX, ucp_Linear_B }, + { 1848, PT_SCX, ucp_Linear_A }, + { 1856, PT_SCX, ucp_Linear_B }, + { 1864, PT_SC, ucp_Lisu }, + { 1869, PT_PC, ucp_Ll }, + { 1872, PT_PC, ucp_Lm }, + { 1875, PT_PC, ucp_Lo }, + { 1878, PT_BOOL, ucp_Logical_Order_Exception }, + { 1882, PT_BOOL, ucp_Logical_Order_Exception }, + { 1904, PT_BOOL, ucp_Lowercase }, + { 1910, PT_BOOL, ucp_Lowercase }, + { 1920, PT_PC, ucp_Lt }, + { 1923, PT_PC, ucp_Lu }, { 1926, PT_SC, ucp_Lycian }, - { 1933, PT_SC, ucp_Lydian }, + { 1931, PT_SC, ucp_Lycian }, { 1938, PT_SC, ucp_Lydian }, - { 1945, PT_GC, ucp_M }, - { 1947, PT_SCX, ucp_Mahajani }, - { 1956, PT_SCX, ucp_Mahajani }, - { 1961, PT_SC, ucp_Makasar }, + { 1943, PT_SC, ucp_Lydian }, + { 1950, PT_GC, ucp_M }, + { 1952, PT_SCX, ucp_Mahajani }, + { 1961, PT_SCX, ucp_Mahajani }, { 1966, PT_SC, ucp_Makasar }, - { 1974, PT_SCX, ucp_Malayalam }, - { 1984, PT_SCX, ucp_Mandaic }, + { 1971, PT_SC, ucp_Makasar }, + { 1979, PT_SCX, ucp_Malayalam }, { 1989, PT_SCX, ucp_Mandaic }, - { 1997, PT_SCX, ucp_Manichaean }, + { 1994, PT_SCX, ucp_Mandaic }, { 2002, PT_SCX, ucp_Manichaean }, - { 2013, PT_SC, ucp_Marchen }, + { 2007, PT_SCX, ucp_Manichaean }, { 2018, PT_SC, ucp_Marchen }, - { 2026, PT_SCX, ucp_Masaram_Gondi }, - { 2039, PT_BOOL, ucp_Math }, - { 2044, PT_PC, ucp_Mc }, - { 2047, PT_PC, ucp_Me }, - { 2050, PT_SC, ucp_Medefaidrin }, - { 2062, PT_SC, ucp_Medefaidrin }, - { 2067, PT_SC, ucp_Meetei_Mayek }, - { 2079, PT_SC, ucp_Mende_Kikakui }, + { 2023, PT_SC, ucp_Marchen }, + { 2031, PT_SCX, ucp_Masaram_Gondi }, + { 2044, PT_BOOL, ucp_Math }, + { 2049, PT_PC, ucp_Mc }, + { 2052, PT_PC, ucp_Me }, + { 2055, PT_SC, ucp_Medefaidrin }, + { 2067, PT_SC, ucp_Medefaidrin }, + { 2072, PT_SC, ucp_Meetei_Mayek }, { 2084, PT_SC, ucp_Mende_Kikakui }, - { 2097, PT_SC, ucp_Meroitic_Cursive }, - { 2102, PT_SC, ucp_Meroitic_Hieroglyphs }, - { 2107, PT_SC, ucp_Meroitic_Cursive }, - { 2123, PT_SC, ucp_Meroitic_Hieroglyphs }, - { 2143, PT_SC, ucp_Miao }, - { 2148, PT_SCX, ucp_Malayalam }, - { 2153, PT_PC, ucp_Mn }, - { 2156, PT_SCX, ucp_Modi }, - { 2161, PT_SCX, ucp_Mongolian }, + { 2089, PT_SC, ucp_Mende_Kikakui }, + { 2102, PT_SC, ucp_Meroitic_Cursive }, + { 2107, PT_SC, ucp_Meroitic_Hieroglyphs }, + { 2112, PT_SC, ucp_Meroitic_Cursive }, + { 2128, PT_SC, ucp_Meroitic_Hieroglyphs }, + { 2148, PT_SC, ucp_Miao }, + { 2153, PT_SCX, ucp_Malayalam }, + { 2158, PT_PC, ucp_Mn }, + { 2161, PT_SCX, ucp_Modi }, { 2166, PT_SCX, ucp_Mongolian }, - { 2176, PT_SC, ucp_Mro }, - { 2180, PT_SC, ucp_Mro }, - { 2185, PT_SC, ucp_Meetei_Mayek }, - { 2190, PT_SCX, ucp_Multani }, + { 2171, PT_SCX, ucp_Mongolian }, + { 2181, PT_SC, ucp_Mro }, + { 2185, PT_SC, ucp_Mro }, + { 2190, PT_SC, ucp_Meetei_Mayek }, { 2195, PT_SCX, ucp_Multani }, - { 2203, PT_SCX, ucp_Myanmar }, - { 2211, PT_SCX, ucp_Myanmar }, - { 2216, PT_GC, ucp_N }, - { 2218, PT_SC, ucp_Nabataean }, - { 2228, PT_SCX, ucp_Nandinagari }, - { 2233, PT_SCX, ucp_Nandinagari }, - { 2245, PT_SC, ucp_Old_North_Arabian }, - { 2250, PT_SC, ucp_Nabataean }, - { 2255, PT_BOOL, ucp_Noncharacter_Code_Point }, - { 2261, PT_PC, ucp_Nd }, - { 2264, PT_SC, ucp_Newa }, - { 2269, PT_SC, ucp_New_Tai_Lue }, - { 2279, PT_SCX, ucp_Nko }, - { 2283, PT_SCX, ucp_Nko }, - { 2288, PT_PC, ucp_Nl }, - { 2291, PT_PC, ucp_No }, - { 2294, PT_BOOL, ucp_Noncharacter_Code_Point }, - { 2316, PT_SC, ucp_Nushu }, - { 2321, PT_SC, ucp_Nushu }, - { 2327, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, - { 2348, PT_SC, ucp_Ogham }, - { 2353, PT_SC, ucp_Ogham }, - { 2359, PT_SC, ucp_Ol_Chiki }, - { 2367, PT_SC, ucp_Ol_Chiki }, - { 2372, PT_SC, ucp_Old_Hungarian }, - { 2385, PT_SC, ucp_Old_Italic }, - { 2395, PT_SC, ucp_Old_North_Arabian }, - { 2411, PT_SCX, ucp_Old_Permic }, - { 2421, PT_SC, ucp_Old_Persian }, - { 2432, PT_SC, ucp_Old_Sogdian }, - { 2443, PT_SC, ucp_Old_South_Arabian }, - { 2459, PT_SC, ucp_Old_Turkic }, - { 2469, PT_SCX, ucp_Old_Uyghur }, - { 2479, PT_SCX, ucp_Oriya }, - { 2485, PT_SC, ucp_Old_Turkic }, - { 2490, PT_SCX, ucp_Oriya }, - { 2495, PT_SC, ucp_Osage }, - { 2501, PT_SC, ucp_Osage }, - { 2506, PT_SC, ucp_Osmanya }, - { 2511, PT_SC, ucp_Osmanya }, - { 2519, PT_SCX, ucp_Old_Uyghur }, - { 2524, PT_GC, ucp_P }, - { 2526, PT_SC, ucp_Pahawh_Hmong }, - { 2538, PT_SC, ucp_Palmyrene }, - { 2543, PT_SC, ucp_Palmyrene }, - { 2553, PT_BOOL, ucp_Pattern_Syntax }, - { 2560, PT_BOOL, ucp_Pattern_Syntax }, - { 2574, PT_BOOL, ucp_Pattern_White_Space }, - { 2592, PT_BOOL, ucp_Pattern_White_Space }, - { 2598, PT_SC, ucp_Pau_Cin_Hau }, - { 2603, PT_SC, ucp_Pau_Cin_Hau }, - { 2613, PT_PC, ucp_Pc }, - { 2616, PT_BOOL, ucp_Prepended_Concatenation_Mark }, - { 2620, PT_PC, ucp_Pd }, - { 2623, PT_PC, ucp_Pe }, - { 2626, PT_SCX, ucp_Old_Permic }, - { 2631, PT_PC, ucp_Pf }, - { 2634, PT_SCX, ucp_Phags_Pa }, - { 2639, PT_SCX, ucp_Phags_Pa }, - { 2647, PT_SC, ucp_Inscriptional_Pahlavi }, - { 2652, PT_SCX, ucp_Psalter_Pahlavi }, - { 2657, PT_SC, ucp_Phoenician }, - { 2662, PT_SC, ucp_Phoenician }, - { 2673, PT_PC, ucp_Pi }, - { 2676, PT_SC, ucp_Miao }, - { 2681, PT_PC, ucp_Po }, - { 2684, PT_BOOL, ucp_Prepended_Concatenation_Mark }, - { 2711, PT_SC, ucp_Inscriptional_Parthian }, - { 2716, PT_PC, ucp_Ps }, - { 2719, PT_SCX, ucp_Psalter_Pahlavi }, - { 2734, PT_SCX, ucp_Coptic }, - { 2739, PT_SC, ucp_Inherited }, - { 2744, PT_BOOL, ucp_Quotation_Mark }, - { 2750, PT_BOOL, ucp_Quotation_Mark }, - { 2764, PT_BOOL, ucp_Radical }, - { 2772, PT_BOOL, ucp_Regional_Indicator }, - { 2790, PT_SC, ucp_Rejang }, - { 2797, PT_BOOL, ucp_Regional_Indicator }, - { 2800, PT_SC, ucp_Rejang }, - { 2805, PT_SCX, ucp_Hanifi_Rohingya }, - { 2810, PT_SC, ucp_Runic }, - { 2816, PT_SC, ucp_Runic }, - { 2821, PT_GC, ucp_S }, - { 2823, PT_SC, ucp_Samaritan }, - { 2833, PT_SC, ucp_Samaritan }, - { 2838, PT_SC, ucp_Old_South_Arabian }, - { 2843, PT_SC, ucp_Saurashtra }, - { 2848, PT_SC, ucp_Saurashtra }, - { 2859, PT_PC, ucp_Sc }, - { 2862, PT_BOOL, ucp_Soft_Dotted }, - { 2865, PT_BOOL, ucp_Sentence_Terminal }, - { 2882, PT_SC, ucp_SignWriting }, - { 2887, PT_SCX, ucp_Sharada }, - { 2895, PT_SC, ucp_Shavian }, - { 2903, PT_SC, ucp_Shavian }, + { 2200, PT_SCX, ucp_Multani }, + { 2208, PT_SCX, ucp_Myanmar }, + { 2216, PT_SCX, ucp_Myanmar }, + { 2221, PT_GC, ucp_N }, + { 2223, PT_SC, ucp_Nabataean }, + { 2233, PT_SC, ucp_Nag_Mundari }, + { 2238, PT_SC, ucp_Nag_Mundari }, + { 2249, PT_SCX, ucp_Nandinagari }, + { 2254, PT_SCX, ucp_Nandinagari }, + { 2266, PT_SC, ucp_Old_North_Arabian }, + { 2271, PT_SC, ucp_Nabataean }, + { 2276, PT_BOOL, ucp_Noncharacter_Code_Point }, + { 2282, PT_PC, ucp_Nd }, + { 2285, PT_SC, ucp_Newa }, + { 2290, PT_SC, ucp_New_Tai_Lue }, + { 2300, PT_SCX, ucp_Nko }, + { 2304, PT_SCX, ucp_Nko }, + { 2309, PT_PC, ucp_Nl }, + { 2312, PT_PC, ucp_No }, + { 2315, PT_BOOL, ucp_Noncharacter_Code_Point }, + { 2337, PT_SC, ucp_Nushu }, + { 2342, PT_SC, ucp_Nushu }, + { 2348, PT_SC, ucp_Nyiakeng_Puachue_Hmong }, + { 2369, PT_SC, ucp_Ogham }, + { 2374, PT_SC, ucp_Ogham }, + { 2380, PT_SC, ucp_Ol_Chiki }, + { 2388, PT_SC, ucp_Ol_Chiki }, + { 2393, PT_SC, ucp_Old_Hungarian }, + { 2406, PT_SC, ucp_Old_Italic }, + { 2416, PT_SC, ucp_Old_North_Arabian }, + { 2432, PT_SCX, ucp_Old_Permic }, + { 2442, PT_SC, ucp_Old_Persian }, + { 2453, PT_SC, ucp_Old_Sogdian }, + { 2464, PT_SC, ucp_Old_South_Arabian }, + { 2480, PT_SC, ucp_Old_Turkic }, + { 2490, PT_SCX, ucp_Old_Uyghur }, + { 2500, PT_SCX, ucp_Oriya }, + { 2506, PT_SC, ucp_Old_Turkic }, + { 2511, PT_SCX, ucp_Oriya }, + { 2516, PT_SC, ucp_Osage }, + { 2522, PT_SC, ucp_Osage }, + { 2527, PT_SC, ucp_Osmanya }, + { 2532, PT_SC, ucp_Osmanya }, + { 2540, PT_SCX, ucp_Old_Uyghur }, + { 2545, PT_GC, ucp_P }, + { 2547, PT_SC, ucp_Pahawh_Hmong }, + { 2559, PT_SC, ucp_Palmyrene }, + { 2564, PT_SC, ucp_Palmyrene }, + { 2574, PT_BOOL, ucp_Pattern_Syntax }, + { 2581, PT_BOOL, ucp_Pattern_Syntax }, + { 2595, PT_BOOL, ucp_Pattern_White_Space }, + { 2613, PT_BOOL, ucp_Pattern_White_Space }, + { 2619, PT_SC, ucp_Pau_Cin_Hau }, + { 2624, PT_SC, ucp_Pau_Cin_Hau }, + { 2634, PT_PC, ucp_Pc }, + { 2637, PT_BOOL, ucp_Prepended_Concatenation_Mark }, + { 2641, PT_PC, ucp_Pd }, + { 2644, PT_PC, ucp_Pe }, + { 2647, PT_SCX, ucp_Old_Permic }, + { 2652, PT_PC, ucp_Pf }, + { 2655, PT_SCX, ucp_Phags_Pa }, + { 2660, PT_SCX, ucp_Phags_Pa }, + { 2668, PT_SC, ucp_Inscriptional_Pahlavi }, + { 2673, PT_SCX, ucp_Psalter_Pahlavi }, + { 2678, PT_SC, ucp_Phoenician }, + { 2683, PT_SC, ucp_Phoenician }, + { 2694, PT_PC, ucp_Pi }, + { 2697, PT_SC, ucp_Miao }, + { 2702, PT_PC, ucp_Po }, + { 2705, PT_BOOL, ucp_Prepended_Concatenation_Mark }, + { 2732, PT_SC, ucp_Inscriptional_Parthian }, + { 2737, PT_PC, ucp_Ps }, + { 2740, PT_SCX, ucp_Psalter_Pahlavi }, + { 2755, PT_SCX, ucp_Coptic }, + { 2760, PT_SC, ucp_Inherited }, + { 2765, PT_BOOL, ucp_Quotation_Mark }, + { 2771, PT_BOOL, ucp_Quotation_Mark }, + { 2785, PT_BOOL, ucp_Radical }, + { 2793, PT_BOOL, ucp_Regional_Indicator }, + { 2811, PT_SC, ucp_Rejang }, + { 2818, PT_BOOL, ucp_Regional_Indicator }, + { 2821, PT_SC, ucp_Rejang }, + { 2826, PT_SCX, ucp_Hanifi_Rohingya }, + { 2831, PT_SC, ucp_Runic }, + { 2837, PT_SC, ucp_Runic }, + { 2842, PT_GC, ucp_S }, + { 2844, PT_SC, ucp_Samaritan }, + { 2854, PT_SC, ucp_Samaritan }, + { 2859, PT_SC, ucp_Old_South_Arabian }, + { 2864, PT_SC, ucp_Saurashtra }, + { 2869, PT_SC, ucp_Saurashtra }, + { 2880, PT_PC, ucp_Sc }, + { 2883, PT_BOOL, ucp_Soft_Dotted }, + { 2886, PT_BOOL, ucp_Sentence_Terminal }, + { 2903, PT_SC, ucp_SignWriting }, { 2908, PT_SCX, ucp_Sharada }, - { 2913, PT_SC, ucp_Siddham }, - { 2918, PT_SC, ucp_Siddham }, - { 2926, PT_SC, ucp_SignWriting }, - { 2938, PT_SCX, ucp_Khudawadi }, - { 2943, PT_SCX, ucp_Sinhala }, - { 2948, PT_SCX, ucp_Sinhala }, - { 2956, PT_PC, ucp_Sk }, - { 2959, PT_PC, ucp_Sm }, - { 2962, PT_PC, ucp_So }, - { 2965, PT_BOOL, ucp_Soft_Dotted }, - { 2976, PT_SCX, ucp_Sogdian }, - { 2981, PT_SCX, ucp_Sogdian }, - { 2989, PT_SC, ucp_Old_Sogdian }, - { 2994, PT_SC, ucp_Sora_Sompeng }, - { 2999, PT_SC, ucp_Sora_Sompeng }, - { 3011, PT_SC, ucp_Soyombo }, - { 3016, PT_SC, ucp_Soyombo }, - { 3024, PT_BOOL, ucp_White_Space }, - { 3030, PT_BOOL, ucp_Sentence_Terminal }, - { 3036, PT_SC, ucp_Sundanese }, - { 3041, PT_SC, ucp_Sundanese }, - { 3051, PT_SCX, ucp_Syloti_Nagri }, - { 3056, PT_SCX, ucp_Syloti_Nagri }, - { 3068, PT_SCX, ucp_Syriac }, - { 3073, PT_SCX, ucp_Syriac }, - { 3080, PT_SCX, ucp_Tagalog }, - { 3088, PT_SCX, ucp_Tagbanwa }, - { 3093, PT_SCX, ucp_Tagbanwa }, - { 3102, PT_SCX, ucp_Tai_Le }, - { 3108, PT_SC, ucp_Tai_Tham }, - { 3116, PT_SC, ucp_Tai_Viet }, - { 3124, PT_SCX, ucp_Takri }, - { 3129, PT_SCX, ucp_Takri }, - { 3135, PT_SCX, ucp_Tai_Le }, - { 3140, PT_SC, ucp_New_Tai_Lue }, - { 3145, PT_SCX, ucp_Tamil }, - { 3151, PT_SCX, ucp_Tamil }, - { 3156, PT_SC, ucp_Tangut }, - { 3161, PT_SC, ucp_Tangsa }, - { 3168, PT_SC, ucp_Tangut }, - { 3175, PT_SC, ucp_Tai_Viet }, - { 3180, PT_SCX, ucp_Telugu }, - { 3185, PT_SCX, ucp_Telugu }, - { 3192, PT_BOOL, ucp_Terminal_Punctuation }, - { 3197, PT_BOOL, ucp_Terminal_Punctuation }, - { 3217, PT_SC, ucp_Tifinagh }, - { 3222, PT_SCX, ucp_Tagalog }, - { 3227, PT_SCX, ucp_Thaana }, - { 3232, PT_SCX, ucp_Thaana }, - { 3239, PT_SC, ucp_Thai }, - { 3244, PT_SC, ucp_Tibetan }, - { 3252, PT_SC, ucp_Tibetan }, - { 3257, PT_SC, ucp_Tifinagh }, - { 3266, PT_SCX, ucp_Tirhuta }, - { 3271, PT_SCX, ucp_Tirhuta }, - { 3279, PT_SC, ucp_Tangsa }, - { 3284, PT_SC, ucp_Toto }, - { 3289, PT_SC, ucp_Ugaritic }, - { 3294, PT_SC, ucp_Ugaritic }, - { 3303, PT_BOOL, ucp_Unified_Ideograph }, - { 3309, PT_BOOL, ucp_Unified_Ideograph }, - { 3326, PT_SC, ucp_Unknown }, - { 3334, PT_BOOL, ucp_Uppercase }, - { 3340, PT_BOOL, ucp_Uppercase }, - { 3350, PT_SC, ucp_Vai }, - { 3354, PT_SC, ucp_Vai }, - { 3359, PT_BOOL, ucp_Variation_Selector }, - { 3377, PT_SC, ucp_Vithkuqi }, - { 3382, PT_SC, ucp_Vithkuqi }, - { 3391, PT_BOOL, ucp_Variation_Selector }, - { 3394, PT_SC, ucp_Wancho }, - { 3401, PT_SC, ucp_Warang_Citi }, - { 3406, PT_SC, ucp_Warang_Citi }, - { 3417, PT_SC, ucp_Wancho }, - { 3422, PT_BOOL, ucp_White_Space }, - { 3433, PT_BOOL, ucp_White_Space }, - { 3440, PT_ALNUM, 0 }, - { 3444, PT_BOOL, ucp_XID_Continue }, - { 3449, PT_BOOL, ucp_XID_Continue }, - { 3461, PT_BOOL, ucp_XID_Start }, - { 3466, PT_BOOL, ucp_XID_Start }, - { 3475, PT_SC, ucp_Old_Persian }, - { 3480, PT_PXSPACE, 0 }, - { 3484, PT_SPACE, 0 }, - { 3488, PT_SC, ucp_Cuneiform }, - { 3493, PT_UCNC, 0 }, - { 3497, PT_WORD, 0 }, - { 3501, PT_SCX, ucp_Yezidi }, - { 3506, PT_SCX, ucp_Yezidi }, - { 3513, PT_SCX, ucp_Yi }, - { 3516, PT_SCX, ucp_Yi }, - { 3521, PT_GC, ucp_Z }, - { 3523, PT_SC, ucp_Zanabazar_Square }, - { 3539, PT_SC, ucp_Zanabazar_Square }, - { 3544, PT_SC, ucp_Inherited }, - { 3549, PT_PC, ucp_Zl }, - { 3552, PT_PC, ucp_Zp }, - { 3555, PT_PC, ucp_Zs }, - { 3558, PT_SC, ucp_Common }, - { 3563, PT_SC, ucp_Unknown } + { 2916, PT_SC, ucp_Shavian }, + { 2924, PT_SC, ucp_Shavian }, + { 2929, PT_SCX, ucp_Sharada }, + { 2934, PT_SC, ucp_Siddham }, + { 2939, PT_SC, ucp_Siddham }, + { 2947, PT_SC, ucp_SignWriting }, + { 2959, PT_SCX, ucp_Khudawadi }, + { 2964, PT_SCX, ucp_Sinhala }, + { 2969, PT_SCX, ucp_Sinhala }, + { 2977, PT_PC, ucp_Sk }, + { 2980, PT_PC, ucp_Sm }, + { 2983, PT_PC, ucp_So }, + { 2986, PT_BOOL, ucp_Soft_Dotted }, + { 2997, PT_SCX, ucp_Sogdian }, + { 3002, PT_SCX, ucp_Sogdian }, + { 3010, PT_SC, ucp_Old_Sogdian }, + { 3015, PT_SC, ucp_Sora_Sompeng }, + { 3020, PT_SC, ucp_Sora_Sompeng }, + { 3032, PT_SC, ucp_Soyombo }, + { 3037, PT_SC, ucp_Soyombo }, + { 3045, PT_BOOL, ucp_White_Space }, + { 3051, PT_BOOL, ucp_Sentence_Terminal }, + { 3057, PT_SC, ucp_Sundanese }, + { 3062, PT_SC, ucp_Sundanese }, + { 3072, PT_SCX, ucp_Syloti_Nagri }, + { 3077, PT_SCX, ucp_Syloti_Nagri }, + { 3089, PT_SCX, ucp_Syriac }, + { 3094, PT_SCX, ucp_Syriac }, + { 3101, PT_SCX, ucp_Tagalog }, + { 3109, PT_SCX, ucp_Tagbanwa }, + { 3114, PT_SCX, ucp_Tagbanwa }, + { 3123, PT_SCX, ucp_Tai_Le }, + { 3129, PT_SC, ucp_Tai_Tham }, + { 3137, PT_SC, ucp_Tai_Viet }, + { 3145, PT_SCX, ucp_Takri }, + { 3150, PT_SCX, ucp_Takri }, + { 3156, PT_SCX, ucp_Tai_Le }, + { 3161, PT_SC, ucp_New_Tai_Lue }, + { 3166, PT_SCX, ucp_Tamil }, + { 3172, PT_SCX, ucp_Tamil }, + { 3177, PT_SC, ucp_Tangut }, + { 3182, PT_SC, ucp_Tangsa }, + { 3189, PT_SC, ucp_Tangut }, + { 3196, PT_SC, ucp_Tai_Viet }, + { 3201, PT_SCX, ucp_Telugu }, + { 3206, PT_SCX, ucp_Telugu }, + { 3213, PT_BOOL, ucp_Terminal_Punctuation }, + { 3218, PT_BOOL, ucp_Terminal_Punctuation }, + { 3238, PT_SC, ucp_Tifinagh }, + { 3243, PT_SCX, ucp_Tagalog }, + { 3248, PT_SCX, ucp_Thaana }, + { 3253, PT_SCX, ucp_Thaana }, + { 3260, PT_SC, ucp_Thai }, + { 3265, PT_SC, ucp_Tibetan }, + { 3273, PT_SC, ucp_Tibetan }, + { 3278, PT_SC, ucp_Tifinagh }, + { 3287, PT_SCX, ucp_Tirhuta }, + { 3292, PT_SCX, ucp_Tirhuta }, + { 3300, PT_SC, ucp_Tangsa }, + { 3305, PT_SC, ucp_Toto }, + { 3310, PT_SC, ucp_Ugaritic }, + { 3315, PT_SC, ucp_Ugaritic }, + { 3324, PT_BOOL, ucp_Unified_Ideograph }, + { 3330, PT_BOOL, ucp_Unified_Ideograph }, + { 3347, PT_SC, ucp_Unknown }, + { 3355, PT_BOOL, ucp_Uppercase }, + { 3361, PT_BOOL, ucp_Uppercase }, + { 3371, PT_SC, ucp_Vai }, + { 3375, PT_SC, ucp_Vai }, + { 3380, PT_BOOL, ucp_Variation_Selector }, + { 3398, PT_SC, ucp_Vithkuqi }, + { 3403, PT_SC, ucp_Vithkuqi }, + { 3412, PT_BOOL, ucp_Variation_Selector }, + { 3415, PT_SC, ucp_Wancho }, + { 3422, PT_SC, ucp_Warang_Citi }, + { 3427, PT_SC, ucp_Warang_Citi }, + { 3438, PT_SC, ucp_Wancho }, + { 3443, PT_BOOL, ucp_White_Space }, + { 3454, PT_BOOL, ucp_White_Space }, + { 3461, PT_ALNUM, 0 }, + { 3465, PT_BOOL, ucp_XID_Continue }, + { 3470, PT_BOOL, ucp_XID_Continue }, + { 3482, PT_BOOL, ucp_XID_Start }, + { 3487, PT_BOOL, ucp_XID_Start }, + { 3496, PT_SC, ucp_Old_Persian }, + { 3501, PT_PXSPACE, 0 }, + { 3505, PT_SPACE, 0 }, + { 3509, PT_SC, ucp_Cuneiform }, + { 3514, PT_UCNC, 0 }, + { 3518, PT_WORD, 0 }, + { 3522, PT_SCX, ucp_Yezidi }, + { 3527, PT_SCX, ucp_Yezidi }, + { 3534, PT_SCX, ucp_Yi }, + { 3537, PT_SCX, ucp_Yi }, + { 3542, PT_GC, ucp_Z }, + { 3544, PT_SC, ucp_Zanabazar_Square }, + { 3560, PT_SC, ucp_Zanabazar_Square }, + { 3565, PT_SC, ucp_Inherited }, + { 3570, PT_PC, ucp_Zl }, + { 3573, PT_PC, ucp_Zp }, + { 3576, PT_PC, ucp_Zs }, + { 3579, PT_SC, ucp_Common }, + { 3584, PT_SC, ucp_Unknown } }; const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table); diff --git a/src/3rdparty/pcre2/src/pcre2_valid_utf.c b/src/3rdparty/pcre2/src/pcre2_valid_utf.c index e47ea78f161..de411b919e1 100644 --- a/src/3rdparty/pcre2/src/pcre2_valid_utf.c +++ b/src/3rdparty/pcre2/src/pcre2_valid_utf.c @@ -171,7 +171,7 @@ for (p = string; length > 0; p++) if (((d = *(++p)) & 0xc0) != 0x80) { - *erroroffset = (int)(p - string) - 1; + *erroroffset = (PCRE2_SIZE)(p - string) - 1; return PCRE2_ERROR_UTF8_ERR6; } @@ -186,7 +186,7 @@ for (p = string; length > 0; p++) case 1: if ((c & 0x3e) == 0) { - *erroroffset = (int)(p - string) - 1; + *erroroffset = (PCRE2_SIZE)(p - string) - 1; return PCRE2_ERROR_UTF8_ERR15; } break; @@ -198,17 +198,17 @@ for (p = string; length > 0; p++) case 2: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR7; } if (c == 0xe0 && (d & 0x20) == 0) { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR16; } if (c == 0xed && d >= 0xa0) { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR14; } break; @@ -220,22 +220,22 @@ for (p = string; length > 0; p++) case 3: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR7; } if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ { - *erroroffset = (int)(p - string) - 3; + *erroroffset = (PCRE2_SIZE)(p - string) - 3; return PCRE2_ERROR_UTF8_ERR8; } if (c == 0xf0 && (d & 0x30) == 0) { - *erroroffset = (int)(p - string) - 3; + *erroroffset = (PCRE2_SIZE)(p - string) - 3; return PCRE2_ERROR_UTF8_ERR17; } if (c > 0xf4 || (c == 0xf4 && d > 0x8f)) { - *erroroffset = (int)(p - string) - 3; + *erroroffset = (PCRE2_SIZE)(p - string) - 3; return PCRE2_ERROR_UTF8_ERR13; } break; @@ -251,22 +251,22 @@ for (p = string; length > 0; p++) case 4: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR7; } if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ { - *erroroffset = (int)(p - string) - 3; + *erroroffset = (PCRE2_SIZE)(p - string) - 3; return PCRE2_ERROR_UTF8_ERR8; } if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ { - *erroroffset = (int)(p - string) - 4; + *erroroffset = (PCRE2_SIZE)(p - string) - 4; return PCRE2_ERROR_UTF8_ERR9; } if (c == 0xf8 && (d & 0x38) == 0) { - *erroroffset = (int)(p - string) - 4; + *erroroffset = (PCRE2_SIZE)(p - string) - 4; return PCRE2_ERROR_UTF8_ERR18; } break; @@ -277,27 +277,27 @@ for (p = string; length > 0; p++) case 5: if ((*(++p) & 0xc0) != 0x80) /* Third byte */ { - *erroroffset = (int)(p - string) - 2; + *erroroffset = (PCRE2_SIZE)(p - string) - 2; return PCRE2_ERROR_UTF8_ERR7; } if ((*(++p) & 0xc0) != 0x80) /* Fourth byte */ { - *erroroffset = (int)(p - string) - 3; + *erroroffset = (PCRE2_SIZE)(p - string) - 3; return PCRE2_ERROR_UTF8_ERR8; } if ((*(++p) & 0xc0) != 0x80) /* Fifth byte */ { - *erroroffset = (int)(p - string) - 4; + *erroroffset = (PCRE2_SIZE)(p - string) - 4; return PCRE2_ERROR_UTF8_ERR9; } if ((*(++p) & 0xc0) != 0x80) /* Sixth byte */ { - *erroroffset = (int)(p - string) - 5; + *erroroffset = (PCRE2_SIZE)(p - string) - 5; return PCRE2_ERROR_UTF8_ERR10; } if (c == 0xfc && (d & 0x3c) == 0) { - *erroroffset = (int)(p - string) - 5; + *erroroffset = (PCRE2_SIZE)(p - string) - 5; return PCRE2_ERROR_UTF8_ERR19; } break; @@ -309,7 +309,7 @@ for (p = string; length > 0; p++) if (ab > 3) { - *erroroffset = (int)(p - string) - ab; + *erroroffset = (PCRE2_SIZE)(p - string) - ab; return (ab == 4)? PCRE2_ERROR_UTF8_ERR11 : PCRE2_ERROR_UTF8_ERR12; } } @@ -340,21 +340,21 @@ for (p = string; length > 0; p++) /* High surrogate. Must be a followed by a low surrogate. */ if (length == 0) { - *erroroffset = p - string; + *erroroffset = (PCRE2_SIZE)(p - string); return PCRE2_ERROR_UTF16_ERR1; } p++; length--; if ((*p & 0xfc00) != 0xdc00) { - *erroroffset = p - string - 1; + *erroroffset = (PCRE2_SIZE)(p - string) - 1; return PCRE2_ERROR_UTF16_ERR2; } } else { /* Isolated low surrogate. Always an error. */ - *erroroffset = p - string; + *erroroffset = (PCRE2_SIZE)(p - string); return PCRE2_ERROR_UTF16_ERR3; } } @@ -379,14 +379,14 @@ for (p = string; length > 0; length--, p++) /* Normal UTF-32 code point. Neither high nor low surrogate. */ if (c > 0x10ffffu) { - *erroroffset = p - string; + *erroroffset = (PCRE2_SIZE)(p - string); return PCRE2_ERROR_UTF32_ERR2; } } else { /* A surrogate */ - *erroroffset = p - string; + *erroroffset = (PCRE2_SIZE)(p - string); return PCRE2_ERROR_UTF32_ERR1; } } diff --git a/src/3rdparty/pcre2/src/pcre2_xclass.c b/src/3rdparty/pcre2/src/pcre2_xclass.c index bb57196449a..5df25d2c8df 100644 --- a/src/3rdparty/pcre2/src/pcre2_xclass.c +++ b/src/3rdparty/pcre2/src/pcre2_xclass.c @@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language. Written by Philip Hazel Original API code Copyright (c) 1997-2012 University of Cambridge - New API code Copyright (c) 2016-2022 University of Cambridge + New API code Copyright (c) 2016-2023 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -133,6 +133,7 @@ while ((t = *data++) != XCL_END) #ifdef SUPPORT_UNICODE else /* XCL_PROP & XCL_NOTPROP */ { + int chartype; const ucd_record *prop = GET_UCD(c); BOOL isprop = t == XCL_PROP; BOOL ok; @@ -144,8 +145,9 @@ while ((t = *data++) != XCL_END) break; case PT_LAMP: - if ((prop->chartype == ucp_Lu || prop->chartype == ucp_Ll || - prop->chartype == ucp_Lt) == isprop) return !negated; + chartype = prop->chartype; + if ((chartype == ucp_Lu || chartype == ucp_Ll || + chartype == ucp_Lt) == isprop) return !negated; break; case PT_GC: @@ -168,8 +170,9 @@ while ((t = *data++) != XCL_END) break; case PT_ALNUM: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N) == isprop) + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N) == isprop) return !negated; break; @@ -194,9 +197,10 @@ while ((t = *data++) != XCL_END) break; case PT_WORD: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L || - PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) - == isprop) + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] == ucp_L || + PRIV(ucp_gentype)[chartype] == ucp_N || + chartype == ucp_Mn || chartype == ucp_Pc) == isprop) return !negated; break; @@ -238,9 +242,10 @@ while ((t = *data++) != XCL_END) */ case PT_PXGRAPH: - if ((PRIV(ucp_gentype)[prop->chartype] != ucp_Z && - (PRIV(ucp_gentype)[prop->chartype] != ucp_C || - (prop->chartype == ucp_Cf && + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] != ucp_Z && + (PRIV(ucp_gentype)[chartype] != ucp_C || + (chartype == ucp_Cf && c != 0x061c && c != 0x180e && (c < 0x2066 || c > 0x2069)) )) == isprop) return !negated; @@ -250,10 +255,11 @@ while ((t = *data++) != XCL_END) not Zl and not Zp, and U+180E. */ case PT_PXPRINT: - if ((prop->chartype != ucp_Zl && - prop->chartype != ucp_Zp && - (PRIV(ucp_gentype)[prop->chartype] != ucp_C || - (prop->chartype == ucp_Cf && + chartype = prop->chartype; + if ((chartype != ucp_Zl && + chartype != ucp_Zp && + (PRIV(ucp_gentype)[chartype] != ucp_C || + (chartype == ucp_Cf && c != 0x061c && (c < 0x2066 || c > 0x2069)) )) == isprop) return !negated; @@ -264,8 +270,21 @@ while ((t = *data++) != XCL_END) compatibility (these are $+<=>^`|~). */ case PT_PXPUNCT: - if ((PRIV(ucp_gentype)[prop->chartype] == ucp_P || - (c < 128 && PRIV(ucp_gentype)[prop->chartype] == ucp_S)) == isprop) + chartype = prop->chartype; + if ((PRIV(ucp_gentype)[chartype] == ucp_P || + (c < 128 && PRIV(ucp_gentype)[chartype] == ucp_S)) == isprop) + return !negated; + break; + + /* Perl has two sets of hex digits */ + + case PT_PXXDIGIT: + if (((c >= CHAR_0 && c <= CHAR_9) || + (c >= CHAR_A && c <= CHAR_F) || + (c >= CHAR_a && c <= CHAR_f) || + (c >= 0xff10 && c <= 0xff19) || /* Fullwidth digits */ + (c >= 0xff21 && c <= 0xff26) || /* Fullwidth letters */ + (c >= 0xff41 && c <= 0xff46)) == isprop) return !negated; break; diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c new file mode 100644 index 00000000000..95b9842fa97 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c @@ -0,0 +1,133 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +/* + On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a + version where it's OK to have more than one JIT block or where MAP_JIT is + required. + On non-macOS systems, returns MAP_JIT if it is defined. +*/ +#include + +#if (defined(TARGET_OS_OSX) && TARGET_OS_OSX) || (TARGET_OS_MAC && !TARGET_OS_IPHONE) + +#if defined(SLJIT_CONFIG_X86) && SLJIT_CONFIG_X86 + +#include +#include + +#define SLJIT_MAP_JIT (get_map_jit_flag()) +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) + +static SLJIT_INLINE int get_map_jit_flag(void) +{ + size_t page_size; + void *ptr; + struct utsname name; + static int map_jit_flag = -1; + + if (map_jit_flag < 0) { + map_jit_flag = 0; + uname(&name); + + /* Kernel version for 10.14.0 (Mojave) or later */ + if (atoi(name.release) >= 18) { + page_size = get_page_alignment() + 1; + /* Only use MAP_JIT if a hardened runtime is used */ + ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANON, -1, 0); + + if (ptr != MAP_FAILED) + munmap(ptr, page_size); + else + map_jit_flag = MAP_JIT; + } + } + return map_jit_flag; +} + +#elif defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM + +#include +#include + +#define SLJIT_MAP_JIT (MAP_JIT) +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \ + apple_update_wx_flags(enable_exec) + +static SLJIT_INLINE void apple_update_wx_flags(sljit_s32 enable_exec) +{ +#if MAC_OS_X_VERSION_MIN_REQUIRED < 110000 + if (__builtin_available(macos 11, *)) +#endif /* BigSur */ + pthread_jit_write_protect_np(enable_exec); +} + +#elif defined(SLJIT_CONFIG_PPC) && SLJIT_CONFIG_PPC + +#define SLJIT_MAP_JIT (0) +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) + +#else +#error "Unsupported architecture" +#endif /* SLJIT_CONFIG */ + +#else /* !TARGET_OS_OSX */ + +#ifdef MAP_JIT +#define SLJIT_MAP_JIT (MAP_JIT) +#else +#define SLJIT_MAP_JIT (0) +#endif + +#endif /* TARGET_OS_OSX */ + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + void *retval; + int prot = PROT_READ | PROT_WRITE | PROT_EXEC; + int flags = MAP_PRIVATE; + int fd = -1; + + flags |= MAP_ANON | SLJIT_MAP_JIT; + + retval = mmap(NULL, size, prot, flags, fd, 0); + if (retval == MAP_FAILED) + return NULL; + + SLJIT_UPDATE_WX_FLAGS(retval, (uint8_t *)retval + size, 0); + + return retval; +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + munmap(chunk, size); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c new file mode 100644 index 00000000000..6cd391104c2 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c @@ -0,0 +1,330 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + This file contains a simple executable memory allocator + + It is assumed, that executable code blocks are usually medium (or sometimes + large) memory blocks, and the allocator is not too frequently called (less + optimized than other allocators). Thus, using it as a generic allocator is + not suggested. + + How does it work: + Memory is allocated in continuous memory areas called chunks by alloc_chunk() + Chunk format: + [ block ][ block ] ... [ block ][ block terminator ] + + All blocks and the block terminator is started with block_header. The block + header contains the size of the previous and the next block. These sizes + can also contain special values. + Block size: + 0 - The block is a free_block, with a different size member. + 1 - The block is a block terminator. + n - The block is used at the moment, and the value contains its size. + Previous block size: + 0 - This is the first block of the memory chunk. + n - The size of the previous block. + + Using these size values we can go forward or backward on the block chain. + The unused blocks are stored in a chain list pointed by free_blocks. This + list is useful if we need to find a suitable memory area when the allocator + is called. + + When a block is freed, the new free block is connected to its adjacent free + blocks if possible. + + [ free block ][ used block ][ free block ] + and "used block" is freed, the three blocks are connected together: + [ one big free block ] +*/ + +/* Expected functions: + alloc_chunk / free_chunk : + * allocate executable system memory chunks + * the size is always divisible by CHUNK_SIZE + SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK : + * provided as part of sljitUtils + * only the allocator requires this lock, sljit is fully thread safe + as it only uses local variables + + Supported defines: + SLJIT_HAS_CHUNK_HEADER - (optional) sljit_chunk_header is defined + SLJIT_HAS_EXECUTABLE_OFFSET - (optional) has executable offset data + SLJIT_UPDATE_WX_FLAGS - (optional) update WX flags +*/ + +#ifdef SLJIT_HAS_CHUNK_HEADER +#define CHUNK_HEADER_SIZE (sizeof(struct sljit_chunk_header)) +#else /* !SLJIT_HAS_CHUNK_HEADER */ +#define CHUNK_HEADER_SIZE 0 +#endif /* SLJIT_HAS_CHUNK_HEADER */ + +#ifndef SLJIT_UPDATE_WX_FLAGS +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) +#endif /* SLJIT_UPDATE_WX_FLAGS */ + +#ifndef CHUNK_SIZE +/* 64 KByte if not specified. */ +#define CHUNK_SIZE (sljit_uw)0x10000 +#endif /* CHUNK_SIZE */ + +struct block_header { + sljit_uw size; + sljit_uw prev_size; +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + sljit_sw executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ +}; + +struct free_block { + struct block_header header; + struct free_block *next; + struct free_block *prev; + sljit_uw size; +}; + +#define AS_BLOCK_HEADER(base, offset) \ + ((struct block_header*)(((sljit_u8*)base) + offset)) +#define AS_FREE_BLOCK(base, offset) \ + ((struct free_block*)(((sljit_u8*)base) + offset)) +#define MEM_START(base) ((void*)((base) + 1)) +#define CHUNK_MASK (~(CHUNK_SIZE - 1)) +#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7u) & ~(sljit_uw)7) +#define CHUNK_EXTRA_SIZE (sizeof(struct block_header) + CHUNK_HEADER_SIZE) + +static struct free_block* free_blocks; +static sljit_uw allocated_size; +static sljit_uw total_size; + +static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size) +{ + free_block->header.size = 0; + free_block->size = size; + + free_block->next = free_blocks; + free_block->prev = NULL; + if (free_blocks) + free_blocks->prev = free_block; + free_blocks = free_block; +} + +static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block) +{ + if (free_block->next) + free_block->next->prev = free_block->prev; + + if (free_block->prev) + free_block->prev->next = free_block->next; + else { + SLJIT_ASSERT(free_blocks == free_block); + free_blocks = free_block->next; + } +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) +{ + struct block_header *header; + struct block_header *next_header; + struct free_block *free_block; + sljit_uw chunk_size; + +#ifdef SLJIT_HAS_CHUNK_HEADER + struct sljit_chunk_header *chunk_header; +#else /* !SLJIT_HAS_CHUNK_HEADER */ + void *chunk_header; +#endif /* SLJIT_HAS_CHUNK_HEADER */ + +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + sljit_sw executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + + if (size < (64 - sizeof(struct block_header))) + size = (64 - sizeof(struct block_header)); + size = ALIGN_SIZE(size); + + SLJIT_ALLOCATOR_LOCK(); + free_block = free_blocks; + while (free_block) { + if (free_block->size >= size) { + chunk_size = free_block->size; + SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0); + if (chunk_size > size + 64) { + /* We just cut a block from the end of the free block. */ + chunk_size -= size; + free_block->size = chunk_size; + header = AS_BLOCK_HEADER(free_block, chunk_size); + header->prev_size = chunk_size; +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + header->executable_offset = free_block->header.executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + AS_BLOCK_HEADER(header, size)->prev_size = size; + } + else { + sljit_remove_free_block(free_block); + header = (struct block_header*)free_block; + size = chunk_size; + } + allocated_size += size; + header->size = size; + SLJIT_ALLOCATOR_UNLOCK(); + return MEM_START(header); + } + free_block = free_block->next; + } + + chunk_size = (size + CHUNK_EXTRA_SIZE + CHUNK_SIZE - 1) & CHUNK_MASK; + + chunk_header = alloc_chunk(chunk_size); + if (!chunk_header) { + SLJIT_ALLOCATOR_UNLOCK(); + return NULL; + } + +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + executable_offset = (sljit_sw)((sljit_u8*)chunk_header->executable - (sljit_u8*)chunk_header); +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + + chunk_size -= CHUNK_EXTRA_SIZE; + total_size += chunk_size; + + header = (struct block_header*)(((sljit_u8*)chunk_header) + CHUNK_HEADER_SIZE); + + header->prev_size = 0; +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + header->executable_offset = executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + + if (chunk_size > size + 64) { + /* Cut the allocated space into a free and a used block. */ + allocated_size += size; + header->size = size; + chunk_size -= size; + + free_block = AS_FREE_BLOCK(header, size); + free_block->header.prev_size = size; +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + free_block->header.executable_offset = executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + sljit_insert_free_block(free_block, chunk_size); + next_header = AS_BLOCK_HEADER(free_block, chunk_size); + } + else { + /* All space belongs to this allocation. */ + allocated_size += chunk_size; + header->size = chunk_size; + next_header = AS_BLOCK_HEADER(header, chunk_size); + } + SLJIT_ALLOCATOR_UNLOCK(); + next_header->size = 1; + next_header->prev_size = chunk_size; +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + next_header->executable_offset = executable_offset; +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + return MEM_START(header); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) +{ + struct block_header *header; + struct free_block* free_block; + + SLJIT_ALLOCATOR_LOCK(); + header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header)); +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET + header = AS_BLOCK_HEADER(header, -header->executable_offset); +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ + allocated_size -= header->size; + + SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0); + + /* Connecting free blocks together if possible. */ + + /* If header->prev_size == 0, free_block will equal to header. + In this case, free_block->header.size will be > 0. */ + free_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size); + if (SLJIT_UNLIKELY(!free_block->header.size)) { + free_block->size += header->size; + header = AS_BLOCK_HEADER(free_block, free_block->size); + header->prev_size = free_block->size; + } + else { + free_block = (struct free_block*)header; + sljit_insert_free_block(free_block, header->size); + } + + header = AS_BLOCK_HEADER(free_block, free_block->size); + if (SLJIT_UNLIKELY(!header->size)) { + free_block->size += ((struct free_block*)header)->size; + sljit_remove_free_block((struct free_block*)header); + header = AS_BLOCK_HEADER(free_block, free_block->size); + header->prev_size = free_block->size; + } + + /* The whole chunk is free. */ + if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) { + /* If this block is freed, we still have (allocated_size / 2) free space. */ + if (total_size - free_block->size > (allocated_size * 3 / 2)) { + total_size -= free_block->size; + sljit_remove_free_block(free_block); + free_chunk(free_block, free_block->size + CHUNK_EXTRA_SIZE); + } + } + + SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1); + SLJIT_ALLOCATOR_UNLOCK(); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) +{ + struct free_block* free_block; + struct free_block* next_free_block; + + SLJIT_ALLOCATOR_LOCK(); + SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0); + + free_block = free_blocks; + while (free_block) { + next_free_block = free_block->next; + if (!free_block->header.prev_size && + AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) { + total_size -= free_block->size; + sljit_remove_free_block(free_block); + free_chunk(free_block, free_block->size + CHUNK_EXTRA_SIZE); + } + free_block = next_free_block; + } + + SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks)); + SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1); + SLJIT_ALLOCATOR_UNLOCK(); +} + +#ifdef SLJIT_HAS_EXECUTABLE_OFFSET +SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr) +{ + return ((struct block_header *)(ptr))[-1].executable_offset; +} +#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */ diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c new file mode 100644 index 00000000000..3b93a4df76c --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c @@ -0,0 +1,89 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#ifdef PROC_WXMAP_CTL +static SLJIT_INLINE int sljit_is_wx_block(void) +{ + static int wx_block = -1; + if (wx_block < 0) { + int sljit_wx_enable = PROC_WX_MAPPINGS_PERMIT; + wx_block = !!procctl(P_PID, 0, PROC_WXMAP_CTL, &sljit_wx_enable); + } + return wx_block; +} + +#define SLJIT_IS_WX_BLOCK sljit_is_wx_block() +#else /* !PROC_WXMAP_CTL */ +#define SLJIT_IS_WX_BLOCK (1) +#endif /* PROC_WXMAP_CTL */ + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + void *retval; + int prot = PROT_READ | PROT_WRITE | PROT_EXEC; + int flags = MAP_PRIVATE; + int fd = -1; + +#ifdef PROT_MAX + prot |= PROT_MAX(prot); +#endif + +#ifdef MAP_ANON + flags |= MAP_ANON; +#else /* !MAP_ANON */ + if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) + return NULL; + + fd = dev_zero; +#endif /* MAP_ANON */ + +retry: + retval = mmap(NULL, size, prot, flags, fd, 0); + if (retval == MAP_FAILED) { + if (!SLJIT_IS_WX_BLOCK) + goto retry; + + return NULL; + } + + /* HardenedBSD's mmap lies, so check permissions again. */ + if (mprotect(retval, size, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) { + munmap(retval, size); + return NULL; + } + + return retval; +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + munmap(chunk, size); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c new file mode 100644 index 00000000000..a775f5629a5 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c @@ -0,0 +1,62 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + void *retval; + int prot = PROT_READ | PROT_WRITE | PROT_EXEC; + int flags = MAP_PRIVATE; + int fd = -1; + +#ifdef PROT_MAX + prot |= PROT_MAX(prot); +#endif + +#ifdef MAP_ANON + flags |= MAP_ANON; +#else /* !MAP_ANON */ + if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) + return NULL; + + fd = dev_zero; +#endif /* MAP_ANON */ + + retval = mmap(NULL, size, prot, flags, fd, 0); + if (retval == MAP_FAILED) + return NULL; + + return retval; +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + munmap(chunk, size); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c new file mode 100644 index 00000000000..f152a5a2cd4 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c @@ -0,0 +1,40 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) + +static SLJIT_INLINE void* alloc_chunk(sljit_uw size) +{ + return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + SLJIT_UNUSED_ARG(size); + VirtualFree(chunk, 0, MEM_RELEASE); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c new file mode 100644 index 00000000000..0b7fd577879 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c @@ -0,0 +1,72 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define SLJIT_HAS_CHUNK_HEADER +#define SLJIT_HAS_EXECUTABLE_OFFSET + +struct sljit_chunk_header { + void *executable; +}; + +/* + * MAP_REMAPDUP is a NetBSD extension available sinde 8.0, make sure to + * adjust your feature macros (ex: -D_NETBSD_SOURCE) as needed + */ +static SLJIT_INLINE struct sljit_chunk_header* alloc_chunk(sljit_uw size) +{ + struct sljit_chunk_header *retval; + + retval = (struct sljit_chunk_header *)mmap(NULL, size, + PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC), + MAP_ANON | MAP_SHARED, -1, 0); + + if (retval == MAP_FAILED) + return NULL; + + retval->executable = mremap(retval, size, NULL, size, MAP_REMAPDUP); + if (retval->executable == MAP_FAILED) { + munmap((void *)retval, size); + return NULL; + } + + if (mprotect(retval->executable, size, PROT_READ | PROT_EXEC) == -1) { + munmap(retval->executable, size); + munmap((void *)retval, size); + return NULL; + } + + return retval; +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + struct sljit_chunk_header *header = ((struct sljit_chunk_header *)chunk) - 1; + + munmap(header->executable, size); + munmap((void *)header, size); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c new file mode 100644 index 00000000000..f7cb6c56705 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c @@ -0,0 +1,172 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define SLJIT_HAS_CHUNK_HEADER +#define SLJIT_HAS_EXECUTABLE_OFFSET + +struct sljit_chunk_header { + void *executable; +}; + +#include +#include +#include +#include + +#ifndef O_NOATIME +#define O_NOATIME 0 +#endif + +/* this is a linux extension available since kernel 3.11 */ +#ifndef O_TMPFILE +#define O_TMPFILE 0x404000 +#endif + +#ifndef _GNU_SOURCE +char *secure_getenv(const char *name); +int mkostemp(char *template, int flags); +#endif + +static SLJIT_INLINE int create_tempfile(void) +{ + int fd; + char tmp_name[256]; + size_t tmp_name_len = 0; + char *dir; + struct stat st; +#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED + mode_t mode; +#endif + +#ifdef HAVE_MEMFD_CREATE + /* this is a GNU extension, make sure to use -D_GNU_SOURCE */ + fd = memfd_create("sljit", MFD_CLOEXEC); + if (fd != -1) { + fchmod(fd, 0); + return fd; + } +#endif + + dir = secure_getenv("TMPDIR"); + + if (dir) { + size_t len = strlen(dir); + if (len > 0 && len < sizeof(tmp_name)) { + if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode)) { + memcpy(tmp_name, dir, len + 1); + tmp_name_len = len; + } + } + } + +#ifdef P_tmpdir + if (!tmp_name_len) { + tmp_name_len = strlen(P_tmpdir); + if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)) + strcpy(tmp_name, P_tmpdir); + } +#endif + if (!tmp_name_len) { + strcpy(tmp_name, "/tmp"); + tmp_name_len = 4; + } + + SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)); + + if (tmp_name_len > 1 && tmp_name[tmp_name_len - 1] == '/') + tmp_name[--tmp_name_len] = '\0'; + + fd = open(tmp_name, O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0); + if (fd != -1) + return fd; + + if (tmp_name_len >= sizeof(tmp_name) - 7) + return -1; + + strcpy(tmp_name + tmp_name_len, "/XXXXXX"); +#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED + mode = umask(0777); +#endif + fd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME); +#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED + umask(mode); +#else + fchmod(fd, 0); +#endif + + if (fd == -1) + return -1; + + if (unlink(tmp_name)) { + close(fd); + return -1; + } + + return fd; +} + +static SLJIT_INLINE struct sljit_chunk_header* alloc_chunk(sljit_uw size) +{ + struct sljit_chunk_header *retval; + int fd; + + fd = create_tempfile(); + if (fd == -1) + return NULL; + + if (ftruncate(fd, (off_t)size)) { + close(fd); + return NULL; + } + + retval = (struct sljit_chunk_header *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + if (retval == MAP_FAILED) { + close(fd); + return NULL; + } + + retval->executable = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0); + + if (retval->executable == MAP_FAILED) { + munmap((void *)retval, size); + close(fd); + return NULL; + } + + close(fd); + return retval; +} + +static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) +{ + struct sljit_chunk_header *header = ((struct sljit_chunk_header *)chunk) - 1; + + munmap(header->executable, size); + munmap((void *)header, size); +} + +#include "sljitExecAllocatorCore.c" diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c new file mode 100644 index 00000000000..36d301434a4 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c @@ -0,0 +1,141 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + This file contains a simple W^X executable memory allocator + + In *NIX, MAP_ANON is required (that is considered a feature) so make + sure to set the right availability macros for your system or the code + will fail to build. + + If your system doesn't support mapping of anonymous pages (ex: IRIX) it + is also likely that it doesn't need this allocator and should be using + the standard one instead. + + It allocates a separate map for each code block and may waste a lot of + memory, because whatever was requested, will be rounded up to the page + size (minimum 4KB, but could be even bigger). + + It changes the page permissions (RW <-> RX) as needed and therefore, if you + will be updating the code after it has been generated, need to make sure to + block any concurrent execution, or could result in a SIGBUS, that could + even manifest itself at a different address than the one that was being + modified. + + Only use if you are unable to use the regular allocator because of security + restrictions and adding exceptions to your application or the system are + not possible. +*/ + +#include +#include + +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \ + sljit_update_wx_flags((from), (to), (enable_exec)) + +#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) +#include +#define SLJIT_SE_LOCK() pthread_mutex_lock(&se_lock) +#define SLJIT_SE_UNLOCK() pthread_mutex_unlock(&se_lock) +#else +#define SLJIT_SE_LOCK() +#define SLJIT_SE_UNLOCK() +#endif /* !SLJIT_SINGLE_THREADED */ + +#define SLJIT_WX_IS_BLOCK(ptr, size) generic_check_is_wx_block(ptr, size) + +static SLJIT_INLINE int generic_check_is_wx_block(void *ptr, sljit_uw size) +{ + if (SLJIT_LIKELY(!mprotect(ptr, size, PROT_EXEC))) + return !!mprotect(ptr, size, PROT_READ | PROT_WRITE); + + return 1; +} + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) +{ +#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) + static pthread_mutex_t se_lock = PTHREAD_MUTEX_INITIALIZER; +#endif + static int wx_block = -1; + int prot = PROT_READ | PROT_WRITE; + sljit_uw* ptr; + + if (SLJIT_UNLIKELY(wx_block > 0)) + return NULL; + +#ifdef PROT_MAX + prot |= PROT_MAX(PROT_READ | PROT_WRITE | PROT_EXEC); +#endif + + size += sizeof(sljit_uw); + ptr = (sljit_uw*)mmap(NULL, size, prot, MAP_PRIVATE | MAP_ANON, -1, 0); + + if (ptr == MAP_FAILED) + return NULL; + + if (SLJIT_UNLIKELY(wx_block < 0)) { + SLJIT_SE_LOCK(); + wx_block = SLJIT_WX_IS_BLOCK(ptr, size); + SLJIT_SE_UNLOCK(); + if (SLJIT_UNLIKELY(wx_block)) { + munmap((void *)ptr, size); + return NULL; + } + } + + *ptr++ = size; + return ptr; +} + +#undef SLJIT_SE_UNLOCK +#undef SLJIT_SE_LOCK + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) +{ + sljit_uw *start_ptr = ((sljit_uw*)ptr) - 1; + munmap((void*)start_ptr, *start_ptr); +} + +static void sljit_update_wx_flags(void *from, void *to, int enable_exec) +{ + sljit_uw page_mask = (sljit_uw)get_page_alignment(); + sljit_uw start = (sljit_uw)from; + sljit_uw end = (sljit_uw)to; + int prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE); + + SLJIT_ASSERT(start < end); + + start &= ~page_mask; + end = (end + page_mask) & ~page_mask; + + mprotect((void*)start, end - start, prot); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) +{ + /* This allocator does not keep unused memory for future allocations. */ +} diff --git a/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c new file mode 100644 index 00000000000..a9553bd7da4 --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c @@ -0,0 +1,102 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + This file contains a simple W^X executable memory allocator + + In *NIX, MAP_ANON is required (that is considered a feature) so make + sure to set the right availability macros for your system or the code + will fail to build. + + If your system doesn't support mapping of anonymous pages (ex: IRIX) it + is also likely that it doesn't need this allocator and should be using + the standard one instead. + + It allocates a separate map for each code block and may waste a lot of + memory, because whatever was requested, will be rounded up to the page + size (minimum 4KB, but could be even bigger). + + It changes the page permissions (RW <-> RX) as needed and therefore, if you + will be updating the code after it has been generated, need to make sure to + block any concurrent execution, or could result in a SIGBUS, that could + even manifest itself at a different address than the one that was being + modified. + + Only use if you are unable to use the regular allocator because of security + restrictions and adding exceptions to your application or the system are + not possible. +*/ + +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \ + sljit_update_wx_flags((from), (to), (enable_exec)) + +SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) +{ + sljit_uw *ptr; + + size += sizeof(sljit_uw); + ptr = (sljit_uw*)VirtualAlloc(NULL, size, + MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); + + if (!ptr) + return NULL; + + *ptr++ = size; + + return ptr; +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) +{ + sljit_uw start = (sljit_uw)ptr - sizeof(sljit_uw); +#if defined(SLJIT_DEBUG) && SLJIT_DEBUG + sljit_uw page_mask = (sljit_uw)get_page_alignment(); + + SLJIT_ASSERT(!(start & page_mask)); +#endif + VirtualFree((void*)start, 0, MEM_RELEASE); +} + +static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec) +{ + DWORD oldprot; + sljit_uw page_mask = (sljit_uw)get_page_alignment(); + sljit_uw start = (sljit_uw)from; + sljit_uw end = (sljit_uw)to; + DWORD prot = enable_exec ? PAGE_EXECUTE : PAGE_READWRITE; + + SLJIT_ASSERT(start < end); + + start &= ~page_mask; + end = (end + page_mask) & ~page_mask; + + VirtualProtect((void*)start, end - start, prot, &oldprot); +} + +SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void) +{ + /* This allocator does not keep unused memory for future allocations. */ +} diff --git a/src/3rdparty/pcre2/src/sljit/sljitConfig.h b/src/3rdparty/pcre2/src/sljit/sljitConfig.h index 5fba7aa6380..364c8bb7884 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitConfig.h +++ b/src/3rdparty/pcre2/src/sljit/sljitConfig.h @@ -38,28 +38,6 @@ extern "C" { non-zero value. */ -/* --------------------------------------------------------------------- */ -/* Architecture */ -/* --------------------------------------------------------------------- */ - -/* Architecture selection. */ -/* #define SLJIT_CONFIG_X86_32 1 */ -/* #define SLJIT_CONFIG_X86_64 1 */ -/* #define SLJIT_CONFIG_ARM_V5 1 */ -/* #define SLJIT_CONFIG_ARM_V7 1 */ -/* #define SLJIT_CONFIG_ARM_THUMB2 1 */ -/* #define SLJIT_CONFIG_ARM_64 1 */ -/* #define SLJIT_CONFIG_PPC_32 1 */ -/* #define SLJIT_CONFIG_PPC_64 1 */ -/* #define SLJIT_CONFIG_MIPS_32 1 */ -/* #define SLJIT_CONFIG_MIPS_64 1 */ -/* #define SLJIT_CONFIG_RISCV_32 1 */ -/* #define SLJIT_CONFIG_RISCV_64 1 */ -/* #define SLJIT_CONFIG_S390X 1 */ - -/* #define SLJIT_CONFIG_AUTO 1 */ -/* #define SLJIT_CONFIG_UNSUPPORTED 1 */ - /* --------------------------------------------------------------------- */ /* Utilities */ /* --------------------------------------------------------------------- */ @@ -96,7 +74,9 @@ extern "C" { /* Executable code allocation: If SLJIT_EXECUTABLE_ALLOCATOR is not defined, the application should - define SLJIT_MALLOC_EXEC, SLJIT_FREE_EXEC, and SLJIT_EXEC_OFFSET. */ + define SLJIT_MALLOC_EXEC and SLJIT_FREE_EXEC. + Optionally, depending on the implementation used for the allocator, + SLJIT_EXEC_OFFSET and SLJIT_UPDATE_WX_FLAGS might also be needed. */ #ifndef SLJIT_EXECUTABLE_ALLOCATOR /* Enabled by default. */ #define SLJIT_EXECUTABLE_ALLOCATOR 1 diff --git a/src/3rdparty/pcre2/src/sljit/sljitConfigCPU.h b/src/3rdparty/pcre2/src/sljit/sljitConfigCPU.h new file mode 100644 index 00000000000..2720bdab0bd --- /dev/null +++ b/src/3rdparty/pcre2/src/sljit/sljitConfigCPU.h @@ -0,0 +1,188 @@ +/* + * Stack-less Just-In-Time compiler + * + * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SLJIT_CONFIG_CPU_H_ +#define SLJIT_CONFIG_CPU_H_ + +/* --------------------------------------------------------------------- */ +/* Architecture */ +/* --------------------------------------------------------------------- */ + +/* Architecture selection. */ +/* #define SLJIT_CONFIG_X86_32 1 */ +/* #define SLJIT_CONFIG_X86_64 1 */ +/* #define SLJIT_CONFIG_ARM_V6 1 */ +/* #define SLJIT_CONFIG_ARM_V7 1 */ +/* #define SLJIT_CONFIG_ARM_THUMB2 1 */ +/* #define SLJIT_CONFIG_ARM_64 1 */ +/* #define SLJIT_CONFIG_PPC_32 1 */ +/* #define SLJIT_CONFIG_PPC_64 1 */ +/* #define SLJIT_CONFIG_MIPS_32 1 */ +/* #define SLJIT_CONFIG_MIPS_64 1 */ +/* #define SLJIT_CONFIG_RISCV_32 1 */ +/* #define SLJIT_CONFIG_RISCV_64 1 */ +/* #define SLJIT_CONFIG_S390X 1 */ +/* #define SLJIT_CONFIG_LOONGARCH_64 */ + +/* #define SLJIT_CONFIG_AUTO 1 */ +/* #define SLJIT_CONFIG_UNSUPPORTED 1 */ + +/*****************/ +/* Sanity check. */ +/*****************/ + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + + (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) \ + + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + + (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ + + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ + + (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \ + + (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ + + (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + + (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) \ + + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ + + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 +#error "Multiple architectures are selected" +#endif + +#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ + && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ + && !(defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) \ + && !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + && !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ + && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ + && !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + && !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ + && !(defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \ + && !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ + && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + && !(defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) \ + && !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \ + && !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) +#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO +#error "An architecture must be selected" +#else /* SLJIT_CONFIG_AUTO */ +#define SLJIT_CONFIG_AUTO 1 +#endif /* !SLJIT_CONFIG_AUTO */ +#endif /* !SLJIT_CONFIG */ + +/********************************************************/ +/* Automatic CPU detection (requires compiler support). */ +/********************************************************/ + +#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) +#ifndef _WIN32 + +#if defined(__i386__) || defined(__i386) +#define SLJIT_CONFIG_X86_32 1 +#elif defined(__x86_64__) +#define SLJIT_CONFIG_X86_64 1 +#elif defined(__aarch64__) +#define SLJIT_CONFIG_ARM_64 1 +#elif defined(__thumb2__) +#define SLJIT_CONFIG_ARM_THUMB2 1 +#elif (defined(__ARM_ARCH) && __ARM_ARCH >= 7) || \ + ((defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7S__)) \ + || (defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8R__)) \ + || (defined(__ARM_ARCH_9A__))) +#define SLJIT_CONFIG_ARM_V7 1 +#elif defined(__arm__) || defined (__ARM__) +#define SLJIT_CONFIG_ARM_V6 1 +#elif defined(__ppc64__) || defined(__powerpc64__) || (defined(_ARCH_PPC64) && defined(__64BIT__)) || (defined(_POWER) && defined(__64BIT__)) +#define SLJIT_CONFIG_PPC_64 1 +#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER) +#define SLJIT_CONFIG_PPC_32 1 +#elif defined(__mips__) && !defined(_LP64) +#define SLJIT_CONFIG_MIPS_32 1 +#elif defined(__mips64) +#define SLJIT_CONFIG_MIPS_64 1 +#elif defined (__riscv_xlen) && (__riscv_xlen == 32) +#define SLJIT_CONFIG_RISCV_32 1 +#elif defined (__riscv_xlen) && (__riscv_xlen == 64) +#define SLJIT_CONFIG_RISCV_64 1 +#elif defined (__loongarch_lp64) +#define SLJIT_CONFIG_LOONGARCH_64 1 +#elif defined(__s390x__) +#define SLJIT_CONFIG_S390X 1 +#else +/* Unsupported architecture */ +#define SLJIT_CONFIG_UNSUPPORTED 1 +#endif + +#else /* _WIN32 */ + +#if defined(_M_X64) || defined(__x86_64__) +#define SLJIT_CONFIG_X86_64 1 +#elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__) +#define SLJIT_CONFIG_ARM_THUMB2 1 +#elif (defined(_M_ARM) && _M_ARM >= 7) +#define SLJIT_CONFIG_ARM_V7 1 +#elif defined(_ARM_) +#define SLJIT_CONFIG_ARM_V6 1 +#elif defined(_M_ARM64) || defined(__aarch64__) +#define SLJIT_CONFIG_ARM_64 1 +#else +#define SLJIT_CONFIG_X86_32 1 +#endif + +#endif /* !_WIN32 */ +#endif /* SLJIT_CONFIG_AUTO */ + +#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) +#undef SLJIT_EXECUTABLE_ALLOCATOR +#endif /* SLJIT_CONFIG_UNSUPPORTED */ + +/******************************/ +/* CPU family type detection. */ +/******************************/ + +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ + || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) +#define SLJIT_CONFIG_ARM_32 1 +#endif + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) +#define SLJIT_CONFIG_X86 1 +#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) +#define SLJIT_CONFIG_ARM 1 +#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_CONFIG_PPC 1 +#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) +#define SLJIT_CONFIG_MIPS 1 +#elif (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) +#define SLJIT_CONFIG_RISCV 1 +#elif (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) +#define SLJIT_CONFIG_LOONGARCH 1 +#endif + +#endif /* SLJIT_CONFIG_CPU_H_ */ diff --git a/src/3rdparty/pcre2/src/sljit/sljitConfigInternal.h b/src/3rdparty/pcre2/src/sljit/sljitConfigInternal.h index cd3ce697346..ce4e7b04ec4 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitConfigInternal.h +++ b/src/3rdparty/pcre2/src/sljit/sljitConfigInternal.h @@ -61,6 +61,8 @@ extern "C" { SLJIT_BIG_ENDIAN : big endian architecture SLJIT_UNALIGNED : unaligned memory accesses for non-fpu operations are supported SLJIT_FPU_UNALIGNED : unaligned memory accesses for fpu operations are supported + SLJIT_MASKED_SHIFT : all word shifts are always masked + SLJIT_MASKED_SHIFT32 : all 32 bit shifts are always masked SLJIT_INDIRECT_CALL : see SLJIT_FUNC_ADDR() for more information Constants: @@ -70,6 +72,8 @@ extern "C" { SLJIT_NUMBER_OF_FLOAT_REGISTERS : number of available floating point registers SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS : number of available floating point scratch registers SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS : number of available floating point saved registers + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS : number of available temporary registers + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS : number of available temporary floating point registers SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index SLJIT_F32_SHIFT : the shift required to apply when accessing a single precision floating point array by index @@ -79,141 +83,27 @@ extern "C" { the scratch register index of ecx is stored in this variable SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET) SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address + SLJIT_CONV_MAX_FLOAT : result when a floating point value is converted to integer + and the floating point value is higher than the maximum integer value + (possible values: SLJIT_CONV_RESULT_MAX_INT or SLJIT_CONV_RESULT_MIN_INT) + SLJIT_CONV_MIN_FLOAT : result when a floating point value is converted to integer + and the floating point value is lower than the minimum integer value + (possible values: SLJIT_CONV_RESULT_MAX_INT or SLJIT_CONV_RESULT_MIN_INT) + SLJIT_CONV_NAN_FLOAT : result when a NaN floating point value is converted to integer + (possible values: SLJIT_CONV_RESULT_MAX_INT, SLJIT_CONV_RESULT_MIN_INT, + or SLJIT_CONV_RESULT_ZERO) Other macros: + SLJIT_TMP_R0 .. R9 : accessing temporary registers + SLJIT_TMP_R(i) : accessing temporary registers + SLJIT_TMP_FR0 .. FR9 : accessing temporary floating point registers + SLJIT_TMP_FR(i) : accessing temporary floating point registers SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper) + SLJIT_F64_SECOND(reg) : provides the register index of the second 32 bit part of a 64 bit + floating point register when SLJIT_HAS_F64_AS_F32_PAIR returns non-zero */ -/*****************/ -/* Sanity check. */ -/*****************/ - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ - + (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ - + (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ - + (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ - + (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ - + (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ - + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ - + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ - + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ - + (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \ - + (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ - + (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ - + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ - + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 -#error "Multiple architectures are selected" -#endif - -#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \ - && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ - && !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \ - && !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ - && !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \ - && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ - && !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ - && !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ - && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ - && !(defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) \ - && !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ - && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ - && !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \ - && !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) -#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO -#error "An architecture must be selected" -#else /* SLJIT_CONFIG_AUTO */ -#define SLJIT_CONFIG_AUTO 1 -#endif /* !SLJIT_CONFIG_AUTO */ -#endif /* !SLJIT_CONFIG */ - -/********************************************************/ -/* Automatic CPU detection (requires compiler support). */ -/********************************************************/ - -#if (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) - -#ifndef _WIN32 - -#if defined(__i386__) || defined(__i386) -#define SLJIT_CONFIG_X86_32 1 -#elif defined(__x86_64__) -#define SLJIT_CONFIG_X86_64 1 -#elif defined(__arm__) || defined(__ARM__) -#ifdef __thumb2__ -#define SLJIT_CONFIG_ARM_THUMB2 1 -#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) -#define SLJIT_CONFIG_ARM_V7 1 -#else -#define SLJIT_CONFIG_ARM_V5 1 -#endif -#elif defined (__aarch64__) -#define SLJIT_CONFIG_ARM_64 1 -#elif defined(__ppc64__) || defined(__powerpc64__) || (defined(_ARCH_PPC64) && defined(__64BIT__)) || (defined(_POWER) && defined(__64BIT__)) -#define SLJIT_CONFIG_PPC_64 1 -#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER) -#define SLJIT_CONFIG_PPC_32 1 -#elif defined(__mips__) && !defined(_LP64) -#define SLJIT_CONFIG_MIPS_32 1 -#elif defined(__mips64) -#define SLJIT_CONFIG_MIPS_64 1 -#elif defined (__riscv_xlen) && (__riscv_xlen == 32) -#define SLJIT_CONFIG_RISCV_32 1 -#elif defined (__riscv_xlen) && (__riscv_xlen == 64) -#define SLJIT_CONFIG_RISCV_64 1 -#elif defined(__s390x__) -#define SLJIT_CONFIG_S390X 1 -#else -/* Unsupported architecture */ -#define SLJIT_CONFIG_UNSUPPORTED 1 -#endif - -#else /* _WIN32 */ - -#if defined(_M_X64) || defined(__x86_64__) -#define SLJIT_CONFIG_X86_64 1 -#elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__) -#define SLJIT_CONFIG_ARM_THUMB2 1 -#elif (defined(_M_ARM) && _M_ARM >= 7) -#define SLJIT_CONFIG_ARM_V7 1 -#elif defined(_ARM_) -#define SLJIT_CONFIG_ARM_V5 1 -#elif defined(_M_ARM64) || defined(__aarch64__) -#define SLJIT_CONFIG_ARM_64 1 -#else -#define SLJIT_CONFIG_X86_32 1 -#endif - -#endif /* !_WIN32 */ -#endif /* SLJIT_CONFIG_AUTO */ - -#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) -#undef SLJIT_EXECUTABLE_ALLOCATOR -#endif - -/******************************/ -/* CPU family type detection. */ -/******************************/ - -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \ - || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) -#define SLJIT_CONFIG_ARM_32 1 -#endif - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -#define SLJIT_CONFIG_X86 1 -#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) -#define SLJIT_CONFIG_ARM 1 -#elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define SLJIT_CONFIG_PPC 1 -#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) -#define SLJIT_CONFIG_MIPS 1 -#elif (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) -#define SLJIT_CONFIG_RISCV 1 -#endif - /***********************************************************/ /* Intel Control-flow Enforcement Technology (CET) spport. */ /***********************************************************/ @@ -328,6 +218,10 @@ extern "C" { /* Instruction cache flush. */ /****************************/ +#ifdef __APPLE__ +#include +#endif + /* * TODO: * @@ -368,7 +262,7 @@ extern "C" { /* Not required to implement on archs with unified caches. */ #define SLJIT_CACHE_FLUSH(from, to) -#elif defined __APPLE__ +#elif defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 /* Supported by all macs since Mac OS 10.5. However, it does not work on non-jailbroken iOS devices, @@ -433,14 +327,15 @@ typedef signed int sljit_s32; #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) /* Just to have something. */ #define SLJIT_WORD_SHIFT 0 -typedef unsigned long int sljit_uw; -typedef long int sljit_sw; +typedef unsigned int sljit_uw; +typedef int sljit_sw; #elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \ && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \ && !(defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) \ - && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + && !(defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64) #define SLJIT_32BIT_ARCHITECTURE 1 #define SLJIT_WORD_SHIFT 2 typedef unsigned int sljit_uw; @@ -476,12 +371,42 @@ typedef double sljit_f64; #define SLJIT_F32_SHIFT 2 #define SLJIT_F64_SHIFT 3 +#define SLJIT_CONV_RESULT_MAX_INT 0 +#define SLJIT_CONV_RESULT_MIN_INT 1 +#define SLJIT_CONV_RESULT_ZERO 2 + +#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#elif (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_ZERO +#elif (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MAX_INT +#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MAX_INT +#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) +#define SLJIT_CONV_MAX_FLOAT SLJIT_CONV_RESULT_MAX_INT +#define SLJIT_CONV_MIN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#define SLJIT_CONV_NAN_FLOAT SLJIT_CONV_RESULT_MIN_INT +#else +#error "Result for float to integer conversion is not defined" +#endif + #ifndef SLJIT_W /* Defining long constants. */ -#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) -#define SLJIT_W(w) (w##l) -#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) #ifdef _WIN64 #define SLJIT_W(w) (w##ll) #else /* !windows */ @@ -521,9 +446,10 @@ typedef double sljit_f64; /* Auto detecting mips revision. */ #if (defined __mips_isa_rev) && (__mips_isa_rev >= 6) #define SLJIT_MIPS_REV 6 -#elif (defined __mips_isa_rev && __mips_isa_rev >= 1) \ - || (defined __clang__ && defined _MIPS_ARCH_OCTEON) \ - || (defined __clang__ && defined _MIPS_ARCH_P5600) +#elif defined(__mips_isa_rev) && __mips_isa_rev >= 1 +#define SLJIT_MIPS_REV __mips_isa_rev +#elif defined(__clang__) \ + && (defined(_MIPS_ARCH_OCTEON) || defined(_MIPS_ARCH_P5600)) /* clang either forgets to define (clang-7) __mips_isa_rev at all * or sets it to zero (clang-8,-9) for -march=octeon (MIPS64 R2+) * and -march=p5600 (MIPS32 R5). @@ -562,7 +488,8 @@ typedef double sljit_f64; || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \ || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ - || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + || (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) #define SLJIT_UNALIGNED 1 #endif @@ -574,7 +501,8 @@ typedef double sljit_f64; || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \ || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \ || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ - || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + || (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) #define SLJIT_FPU_UNALIGNED 1 #endif @@ -594,6 +522,19 @@ typedef double sljit_f64; #define SLJIT_FUNC #endif /* !SLJIT_FUNC */ +/* Disable instrumentation for these functions as they may not be sound */ +#ifndef SLJIT_FUNC_ATTRIBUTE +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#define SLJIT_FUNC_ATTRIBUTE __attribute__((no_sanitize("memory"))) +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ +#endif + +#ifndef SLJIT_FUNC_ATTRIBUTE +#define SLJIT_FUNC_ATTRIBUTE +#endif + #ifndef SLJIT_INDIRECT_CALL #if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (!defined _CALL_ELF || _CALL_ELF == 1)) \ || ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX) @@ -631,12 +572,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void); #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_EXEC_OFFSET(ptr) sljit_exec_offset(ptr) -#else -#define SLJIT_EXEC_OFFSET(ptr) 0 #endif #endif /* SLJIT_EXECUTABLE_ALLOCATOR */ +#ifndef SLJIT_EXEC_OFFSET +#define SLJIT_EXEC_OFFSET(ptr) 0 +#endif + /**********************************************/ /* Registers and locals offset determination. */ /**********************************************/ @@ -645,15 +588,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_NUMBER_OF_REGISTERS 12 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 7 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 1 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 7 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1 #define SLJIT_LOCALS_OFFSET_BASE (8 * SSIZE_OF(sw)) #define SLJIT_PREF_SHIFT_REG SLJIT_R2 +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 #elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #define SLJIT_NUMBER_OF_REGISTERS 13 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 2 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1 #ifndef _WIN64 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 6 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0 @@ -664,37 +613,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_LOCALS_OFFSET_BASE (4 * SSIZE_OF(sw)) #endif /* !_WIN64 */ #define SLJIT_PREF_SHIFT_REG SLJIT_R3 +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 -#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - -#define SLJIT_NUMBER_OF_REGISTERS 12 -#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 -#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14 -#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8 -#define SLJIT_LOCALS_OFFSET_BASE 0 - -#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) +#elif (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) #define SLJIT_NUMBER_OF_REGISTERS 12 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 2 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 14 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 #define SLJIT_LOCALS_OFFSET_BASE 0 #elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) #define SLJIT_NUMBER_OF_REGISTERS 26 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 10 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 #define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof(sljit_sw)) +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 #elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) #define SLJIT_NUMBER_OF_REGISTERS 23 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 17 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 18 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX) #define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * (sljit_s32)sizeof(sljit_sw)) #elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) @@ -717,14 +668,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 29 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8 #endif +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 3 +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 #elif (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) #define SLJIT_NUMBER_OF_REGISTERS 23 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 12 -#define SLJIT_LOCALS_OFFSET_BASE 0 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 +#define SLJIT_LOCALS_OFFSET_BASE 0 +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) @@ -751,16 +710,34 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_NUMBER_OF_REGISTERS 12 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 8 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 3 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1 #define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE +#define SLJIT_MASKED_SHIFT 1 + +#elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) + +#define SLJIT_NUMBER_OF_REGISTERS 23 +#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5 +#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30 +#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2 +#define SLJIT_LOCALS_OFFSET_BASE 0 +#define SLJIT_MASKED_SHIFT 1 +#define SLJIT_MASKED_SHIFT32 1 #elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) +/* Just to have something. */ #define SLJIT_NUMBER_OF_REGISTERS 0 #define SLJIT_NUMBER_OF_SAVED_REGISTERS 0 +#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 0 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 0 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0 +#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 0 #define SLJIT_LOCALS_OFFSET_BASE 0 #endif @@ -773,6 +750,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); #define SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS \ (SLJIT_NUMBER_OF_FLOAT_REGISTERS - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS) +/**********************************/ +/* Temporary register management. */ +/**********************************/ + +#define SLJIT_TMP_REGISTER_BASE (SLJIT_NUMBER_OF_REGISTERS + 2) +#define SLJIT_TMP_FREGISTER_BASE (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) + +/* WARNING: Accessing temporary registers is not recommended, because they + are also used by the JIT compiler for various computations. Using them + might have any side effects including incorrect operations and crashes, + so use them at your own risk. The machine registers themselves might have + limitations, e.g. the r0 register on s390x / ppc cannot be used as + base address for memory operations. */ + +/* Temporary registers */ +#define SLJIT_TMP_R0 (SLJIT_TMP_REGISTER_BASE + 0) +#define SLJIT_TMP_R1 (SLJIT_TMP_REGISTER_BASE + 1) +#define SLJIT_TMP_R2 (SLJIT_TMP_REGISTER_BASE + 2) +#define SLJIT_TMP_R3 (SLJIT_TMP_REGISTER_BASE + 3) +#define SLJIT_TMP_R4 (SLJIT_TMP_REGISTER_BASE + 4) +#define SLJIT_TMP_R5 (SLJIT_TMP_REGISTER_BASE + 5) +#define SLJIT_TMP_R6 (SLJIT_TMP_REGISTER_BASE + 6) +#define SLJIT_TMP_R7 (SLJIT_TMP_REGISTER_BASE + 7) +#define SLJIT_TMP_R8 (SLJIT_TMP_REGISTER_BASE + 8) +#define SLJIT_TMP_R9 (SLJIT_TMP_REGISTER_BASE + 9) +#define SLJIT_TMP_R(i) (SLJIT_TMP_REGISTER_BASE + (i)) + +#define SLJIT_TMP_FR0 (SLJIT_TMP_FREGISTER_BASE + 0) +#define SLJIT_TMP_FR1 (SLJIT_TMP_FREGISTER_BASE + 1) +#define SLJIT_TMP_FR2 (SLJIT_TMP_FREGISTER_BASE + 2) +#define SLJIT_TMP_FR3 (SLJIT_TMP_FREGISTER_BASE + 3) +#define SLJIT_TMP_FR4 (SLJIT_TMP_FREGISTER_BASE + 4) +#define SLJIT_TMP_FR5 (SLJIT_TMP_FREGISTER_BASE + 5) +#define SLJIT_TMP_FR6 (SLJIT_TMP_FREGISTER_BASE + 6) +#define SLJIT_TMP_FR7 (SLJIT_TMP_FREGISTER_BASE + 7) +#define SLJIT_TMP_FR8 (SLJIT_TMP_FREGISTER_BASE + 8) +#define SLJIT_TMP_FR9 (SLJIT_TMP_FREGISTER_BASE + 9) +#define SLJIT_TMP_FR(i) (SLJIT_TMP_FREGISTER_BASE + (i)) + /********************************/ /* CPU status flags management. */ /********************************/ @@ -781,10 +797,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr); || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \ || (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \ || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ - || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + || (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) #define SLJIT_HAS_STATUS_FLAGS_STATE 1 #endif +/***************************************/ +/* Floating point register management. */ +/***************************************/ + +#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \ + || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define SLJIT_F64_SECOND(reg) \ + ((reg) + SLJIT_FS0 + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS) +#else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */ +#define SLJIT_F64_SECOND(reg) \ + (reg) +#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */ + /*************************************/ /* Debug and verbose related macros. */ /*************************************/ diff --git a/src/3rdparty/pcre2/src/sljit/sljitLir.c b/src/3rdparty/pcre2/src/sljit/sljitLir.c index abafe1add97..6f19300081a 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitLir.c +++ b/src/3rdparty/pcre2/src/sljit/sljitLir.c @@ -93,7 +93,8 @@ #define SSIZE_OF(type) ((sljit_s32)sizeof(sljit_ ## type)) #define VARIABLE_FLAG_SHIFT (10) -#define VARIABLE_FLAG_MASK (0x3f << VARIABLE_FLAG_SHIFT) +/* All variable flags are even. */ +#define VARIABLE_FLAG_MASK (0x3e << VARIABLE_FLAG_SHIFT) #define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT) #define GET_OPCODE(op) \ @@ -122,25 +123,34 @@ #endif /* Parameter parsing. */ -#define REG_MASK 0x3f +#define REG_MASK 0x7f #define OFFS_REG(reg) (((reg) >> 8) & REG_MASK) #define OFFS_REG_MASK (REG_MASK << 8) #define TO_OFFS_REG(reg) ((reg) << 8) -/* When reg cannot be unused. */ -#define FAST_IS_REG(reg) ((reg) <= REG_MASK) +#define FAST_IS_REG(reg) ((reg) < REG_MASK) /* Mask for argument types. */ #define SLJIT_ARG_MASK 0x7 #define SLJIT_ARG_FULL_MASK (SLJIT_ARG_MASK | SLJIT_ARG_TYPE_SCRATCH_REG) -/* Mask for sljit_emit_mem. */ -#define REG_PAIR_MASK 0xff00 -#define REG_PAIR_FIRST(reg) ((reg) & 0xff) +/* Mask for register pairs. */ +#define REG_PAIR_MASK 0x7f00 +#define REG_PAIR_FIRST(reg) ((reg) & 0x7f) #define REG_PAIR_SECOND(reg) ((reg) >> 8) /* Mask for sljit_emit_enter. */ #define SLJIT_KEPT_SAVEDS_COUNT(options) ((options) & 0x3) +/* Getters for simd operations, which returns with log2(size). */ +#define SLJIT_SIMD_GET_OPCODE(type) ((type) & 0xff) +#define SLJIT_SIMD_GET_REG_SIZE(type) (((type) >> 12) & 0x3f) +#define SLJIT_SIMD_GET_ELEM_SIZE(type) (((type) >> 18) & 0x3f) +#define SLJIT_SIMD_GET_ELEM2_SIZE(type) (((type) >> 24) & 0x3f) + +#define SLJIT_SIMD_CHECK_REG(type) (((type) & 0x3f000) >= SLJIT_SIMD_REG_64 && ((type) & 0x3f000) <= SLJIT_SIMD_REG_512) +#define SLJIT_SIMD_TYPE_MASK(m) ((sljit_s32)0xff000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m))) +#define SLJIT_SIMD_TYPE_MASK2(m) ((sljit_s32)0xc0000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m))) + /* Jump flags. */ #define JUMP_LABEL 0x1 #define JUMP_ADDR 0x2 @@ -155,14 +165,14 @@ # define TYPE_SHIFT 13 #endif /* SLJIT_CONFIG_X86 */ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) # define IS_BL 0x4 # define PATCH_B 0x8 -#endif /* SLJIT_CONFIG_ARM_V5 || SLJIT_CONFIG_ARM_V7 */ +#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V6 */ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) # define CPOOL_SIZE 512 -#endif /* SLJIT_CONFIG_ARM_V5 */ +#endif /* SLJIT_CONFIG_ARM_V6 */ #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) # define IS_COND 0x04 @@ -248,15 +258,27 @@ #endif /* SLJIT_CONFIG_RISCV_64 */ #endif /* SLJIT_CONFIG_RISCV */ +#if (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) +# define IS_COND 0x004 +# define IS_CALL 0x008 + +# define PATCH_B 0x010 +# define PATCH_J 0x020 + +# define PATCH_REL32 0x040 +# define PATCH_ABS32 0x080 +# define PATCH_ABS52 0x100 + +#endif /* SLJIT_CONFIG_LOONGARCH */ /* Stack management. */ #define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \ (((scratches < SLJIT_NUMBER_OF_SCRATCH_REGISTERS ? 0 : (scratches - SLJIT_NUMBER_OF_SCRATCH_REGISTERS)) + \ (saveds) + (sljit_s32)(extra)) * (sljit_s32)sizeof(sljit_sw)) -#define GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, size) \ +#define GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, type) \ (((fscratches < SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS ? 0 : (fscratches - SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)) + \ - (fsaveds)) * (sljit_s32)(size)) + (fsaveds)) * SSIZE_OF(type)) #define ADJUST_LOCAL_OFFSET(p, i) \ if ((p) == (SLJIT_MEM1(SLJIT_SP))) \ @@ -272,25 +294,49 @@ #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) -#include "sljitProtExecAllocator.c" -#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR) -#include "sljitWXExecAllocator.c" + +#if defined(__NetBSD__) +#include "allocator_src/sljitProtExecAllocatorNetBSD.c" #else -#include "sljitExecAllocator.c" +#include "allocator_src/sljitProtExecAllocatorPosix.c" +#endif + +#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR) + +#if defined(_WIN32) +#include "allocator_src/sljitWXExecAllocatorWindows.c" +#else +#include "allocator_src/sljitWXExecAllocatorPosix.c" +#endif + +#else + +#if defined(_WIN32) +#include "allocator_src/sljitExecAllocatorWindows.c" +#elif defined(__APPLE__) +#include "allocator_src/sljitExecAllocatorApple.c" +#elif defined(__FreeBSD__) +#include "allocator_src/sljitExecAllocatorFreeBSD.c" +#else +#include "allocator_src/sljitExecAllocatorPosix.c" #endif #endif +#else /* !SLJIT_EXECUTABLE_ALLOCATOR */ + +#ifndef SLJIT_UPDATE_WX_FLAGS +#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) +#endif + +#endif /* SLJIT_EXECUTABLE_ALLOCATOR */ + #if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr) + (exec_offset)) #else #define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr)) #endif -#ifndef SLJIT_UPDATE_WX_FLAGS -#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) -#endif - /* Argument checking features. */ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -422,9 +468,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) compiler->args_size = -1; -#endif +#endif /* SLJIT_CONFIG_X86_32 */ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) compiler->cpool = (sljit_uw*)SLJIT_MALLOC(CPOOL_SIZE * sizeof(sljit_uw) + CPOOL_SIZE * sizeof(sljit_u8), allocator_data); if (!compiler->cpool) { @@ -435,18 +481,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo } compiler->cpool_unique = (sljit_u8*)(compiler->cpool + CPOOL_SIZE); compiler->cpool_diff = 0xffffffff; -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) compiler->delay_slot = UNMOVABLE_INS; -#endif +#endif /* SLJIT_CONFIG_MIPS */ #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \ || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->last_flags = 0; compiler->last_return = -1; compiler->logical_local_size = 0; -#endif +#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */ #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT) if (!compiler_initialized) { @@ -479,7 +525,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile SLJIT_FREE(curr, allocator_data); } -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) SLJIT_FREE(compiler->cpool, allocator_data); #endif SLJIT_FREE(compiler, allocator_data); @@ -802,11 +848,8 @@ static sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratch #define FUNCTION_CHECK_IS_REG(r) \ (((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) \ - || ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0)) - -#define FUNCTION_CHECK_IS_FREG(fr) \ - (((fr) >= SLJIT_FR0 && (fr) < (SLJIT_FR0 + compiler->fscratches)) \ - || ((fr) > (SLJIT_FS0 - compiler->fsaveds) && (fr) <= SLJIT_FS0)) + || ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0) \ + || ((r) >= SLJIT_TMP_REGISTER_BASE && (r) < (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS))) #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #define CHECK_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8) @@ -816,7 +859,7 @@ static sljit_s32 function_check_arguments(sljit_s32 arg_types, sljit_s32 scratch static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if (compiler->scratches == -1 || compiler->saveds == -1) + if (compiler->scratches == -1) return 0; if (!(p & SLJIT_MEM)) @@ -853,7 +896,7 @@ static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s static sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if (compiler->scratches == -1 || compiler->saveds == -1) + if (compiler->scratches == -1) return 0; if (FUNCTION_CHECK_IS_REG(p)) @@ -870,7 +913,7 @@ static sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if (compiler->scratches == -1 || compiler->saveds == -1) + if (compiler->scratches == -1) return 0; if (FUNCTION_CHECK_IS_REG(p)) @@ -882,19 +925,59 @@ static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p #define FUNCTION_CHECK_DST(p, i) \ CHECK_ARGUMENT(function_check_dst(compiler, p, i)); -static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) +#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \ + || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + +#define FUNCTION_CHECK_IS_FREG(fr, is_32) \ + function_check_is_freg(compiler, (fr), (is_32)) + +static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32); + +#define FUNCTION_FCHECK(p, i, is_32) \ + CHECK_ARGUMENT(function_fcheck(compiler, (p), (i), (is_32))); + +static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 is_32) { - if (compiler->scratches == -1 || compiler->saveds == -1) + if (compiler->scratches == -1) return 0; - if (FUNCTION_CHECK_IS_FREG(p)) + if (FUNCTION_CHECK_IS_FREG(p, is_32)) return (i == 0); return function_check_src_mem(compiler, p, i); } -#define FUNCTION_FCHECK(p, i) \ - CHECK_ARGUMENT(function_fcheck(compiler, p, i)); +#else /* !SLJIT_CONFIG_ARM_32 && !SLJIT_CONFIG_MIPS_32 */ +#define FUNCTION_CHECK_IS_FREG(fr, is_32) \ + function_check_is_freg(compiler, (fr)) + +static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr) +{ + if (compiler->scratches == -1) + return 0; + + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) + || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); +} + +#define FUNCTION_FCHECK(p, i, is_32) \ + CHECK_ARGUMENT(function_fcheck(compiler, (p), (i))); + +static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) +{ + if (compiler->scratches == -1) + return 0; + + if ((p >= SLJIT_FR0 && p < (SLJIT_FR0 + compiler->fscratches)) + || (p > (SLJIT_FS0 - compiler->fsaveds) && p <= SLJIT_FS0) + || (p >= SLJIT_TMP_FREGISTER_BASE && p < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS))) + return (i == 0); + + return function_check_src_mem(compiler, p, i); +} + +#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */ #endif /* SLJIT_ARGUMENT_CHECKS */ @@ -923,23 +1006,35 @@ static void sljit_verbose_reg(struct sljit_compiler *compiler, sljit_s32 r) { if (r < (SLJIT_R0 + compiler->scratches)) fprintf(compiler->verbose, "r%d", r - SLJIT_R0); - else if (r != SLJIT_SP) + else if (r < SLJIT_SP) fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - r); - else + else if (r == SLJIT_SP) fprintf(compiler->verbose, "sp"); + else + fprintf(compiler->verbose, "t%d", r - SLJIT_TMP_REGISTER_BASE); } static void sljit_verbose_freg(struct sljit_compiler *compiler, sljit_s32 r) { +#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \ + || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + if (r >= SLJIT_F64_SECOND(SLJIT_FR0)) { + fprintf(compiler->verbose, "^"); + r -= SLJIT_F64_SECOND(0); + } +#endif /* SLJIT_CONFIG_ARM_32 || SLJIT_CONFIG_MIPS_32 */ + if (r < (SLJIT_FR0 + compiler->fscratches)) fprintf(compiler->verbose, "fr%d", r - SLJIT_FR0); - else + else if (r < SLJIT_TMP_FREGISTER_BASE) fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - r); + else + fprintf(compiler->verbose, "ft%d", r - SLJIT_TMP_FREGISTER_BASE); } static void sljit_verbose_param(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i) { - if ((p) & SLJIT_IMM) + if ((p) == SLJIT_IMM) fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); else if ((p) & SLJIT_MEM) { if ((p) & REG_MASK) { @@ -991,9 +1086,17 @@ static const char* op0_names[] = { }; static const char* op1_names[] = { + "mov", "mov", "mov", "mov", + "mov", "mov", "mov", "mov", + "mov", "clz", "ctz", "rev", + "rev", "rev", "rev", "rev" +}; + +static const char* op1_types[] = { "", ".u8", ".s8", ".u16", ".s16", ".u32", ".s32", "32", - ".p", "not", "clz", "ctz" + ".p", "", "", "", + ".u16", ".s16", ".u32", ".s32" }; static const char* op2_names[] = { @@ -1003,22 +1106,36 @@ static const char* op2_names[] = { "ashr", "mashr", "rotl", "rotr" }; -static const char* op_src_names[] = { +static const char* op_src_dst_names[] = { "fast_return", "skip_frames_before_fast_return", "prefetch_l1", "prefetch_l2", "prefetch_l3", "prefetch_once", + "fast_enter", "get_return_address" }; static const char* fop1_names[] = { "mov", "conv", "conv", "conv", - "conv", "conv", "cmp", "neg", - "abs", + "conv", "conv", "conv", "conv", + "cmp", "neg", "abs", +}; + +static const char* fop1_conv_types[] = { + "sw", "s32", "sw", "s32", + "uw", "u32" }; static const char* fop2_names[] = { "add", "sub", "mul", "div" }; +static const char* fop2r_names[] = { + "copysign" +}; + +static const char* simd_op2_names[] = { + "and", "or", "xor" +}; + static const char* jump_names[] = { "equal", "not_equal", "less", "greater_equal", @@ -1026,7 +1143,8 @@ static const char* jump_names[] = { "sig_less", "sig_greater_equal", "sig_greater", "sig_less_equal", "overflow", "not_overflow", - "carry", "", + "carry", "not_carry", + "atomic_stored", "atomic_not_stored", "f_equal", "f_not_equal", "f_less", "f_greater_equal", "f_greater", "f_less_equal", @@ -1126,7 +1244,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compil fprintf(compiler->verbose, " keep:%d,", SLJIT_KEPT_SAVEDS_COUNT(options)); } - fprintf(compiler->verbose, "scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n", + fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n", scratches, saveds, fscratches, fsaveds, local_size); } #endif @@ -1198,7 +1316,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_void(struct sljit_ } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_VOID); + CHECK_ARGUMENT(compiler->last_return == SLJIT_ARG_TYPE_RET_VOID); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) @@ -1241,7 +1359,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi if (GET_OPCODE(op) < SLJIT_MOV_F64) { FUNCTION_CHECK_SRC(src, srcw); } else { - FUNCTION_FCHECK(src, srcw); + FUNCTION_FCHECK(src, srcw, op & SLJIT_32); } compiler->last_flags = 0; #endif @@ -1249,7 +1367,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return(struct sljit_compi if (SLJIT_UNLIKELY(!!compiler->verbose)) { if (GET_OPCODE(op) < SLJIT_MOV_F64) { fprintf(compiler->verbose, " return%s%s ", !(op & SLJIT_32) ? "" : "32", - op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE]); + op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]); sljit_verbose_param(compiler, src, srcw); } else { fprintf(compiler->verbose, " return%s ", !(op & SLJIT_32) ? ".f64" : ".f32"); @@ -1277,22 +1395,6 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_to(struct sljit_co CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) -{ -#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - FUNCTION_CHECK_DST(dst, dstw); - compiler->last_flags = 0; -#endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) - if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " fast_enter "); - sljit_verbose_param(compiler, dst, dstw); - fprintf(compiler->verbose, "\n"); - } -#endif - CHECK_RETURN_OK; -} - static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) @@ -1326,16 +1428,16 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_CTZ); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_REV_S32); switch (GET_OPCODE(op)) { - case SLJIT_NOT: - /* Only SLJIT_32 and SLJIT_SET_Z are allowed. */ - CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)); - break; case SLJIT_MOV: case SLJIT_MOV_U32: + case SLJIT_MOV_S32: + case SLJIT_MOV32: case SLJIT_MOV_P: + case SLJIT_REV_U32: + case SLJIT_REV_S32: /* Nothing allowed */ CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))); break; @@ -1347,25 +1449,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler FUNCTION_CHECK_DST(dst, dstw); FUNCTION_CHECK_SRC(src, srcw); - - if (GET_OPCODE(op) >= SLJIT_NOT) { - CHECK_ARGUMENT(src != SLJIT_IMM); - compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_32 | SLJIT_SET_Z)); - } #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - if (GET_OPCODE(op) <= SLJIT_MOV_P) - { - fprintf(compiler->verbose, " mov%s%s ", !(op & SLJIT_32) ? "" : "32", - op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE]); - } - else - { - fprintf(compiler->verbose, " %s%s%s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & SLJIT_32) ? "" : "32", - !(op & SLJIT_SET_Z) ? "" : ".z", !(op & VARIABLE_FLAG_MASK) ? "" : ".", - !(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op)]); - } + fprintf(compiler->verbose, " %s%s%s ", op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE], + !(op & SLJIT_32) ? "" : "32", op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", "); @@ -1376,6 +1464,94 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler CHECK_RETURN_OK; } +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC)); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P); + CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32); + + /* All arguments must be valid registers. */ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg)); + + if (op == SLJIT_MOV32_U8 || op == SLJIT_MOV32_U16) { + /* Only SLJIT_32 is allowed. */ + CHECK_ARGUMENT(!(op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z))); + } else { + /* Nothing allowed. */ + CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))); + } + + compiler->last_flags = 0; +#endif /* SLJIT_ARGUMENT_CHECKS */ +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " atomic_load%s%s ", !(op & SLJIT_32) ? "" : "32", + op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]); + sljit_verbose_reg(compiler, dst_reg); + fprintf(compiler->verbose, ", ["); + sljit_verbose_reg(compiler, mem_reg); + fprintf(compiler->verbose, "]\n"); + } +#endif /* SLJIT_VERBOSE */ + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC)); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOV_P); + CHECK_ARGUMENT(GET_OPCODE(op) != SLJIT_MOV_S8 && GET_OPCODE(op) != SLJIT_MOV_S16 && GET_OPCODE(op) != SLJIT_MOV_S32); + + /* All arguments must be valid registers. */ + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src_reg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(mem_reg) && !CHECK_IF_VIRTUAL_REGISTER(mem_reg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(temp_reg) && src_reg != temp_reg); + + CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE(op) == SLJIT_ATOMIC_STORED); + + if (GET_OPCODE(op) == SLJIT_MOV_U8 || GET_OPCODE(op) == SLJIT_MOV_U16) { + /* Only SLJIT_32, SLJIT_ATOMIC_STORED are allowed. */ + CHECK_ARGUMENT(!(op & SLJIT_SET_Z)); + } else { + /* Only SLJIT_ATOMIC_STORED is allowed. */ + CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z))); + } + + compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32); +#endif /* SLJIT_ARGUMENT_CHECKS */ +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " atomic_store%s%s%s ", !(op & SLJIT_32) ? "" : "32", + op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE], !(op & VARIABLE_FLAG_MASK) ? "" : ".stored"); + sljit_verbose_reg(compiler, src_reg); + fprintf(compiler->verbose, ", ["); + sljit_verbose_reg(compiler, mem_reg); + fprintf(compiler->verbose, "], "); + sljit_verbose_reg(compiler, temp_reg); + fprintf(compiler->verbose, "\n"); + } +#endif /* SLJIT_VERBOSE */ + CHECK_RETURN_OK; +} + static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 unset, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, @@ -1461,28 +1637,33 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_LSHR || GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR); CHECK_ARGUMENT((op & ~(0xff | SLJIT_32 | SLJIT_SHIFT_INTO_NON_ZERO)) == 0); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src_dst)); - FUNCTION_CHECK_SRC(src1, src1w); - FUNCTION_CHECK_SRC(src2, src2w); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src1_reg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg)); + FUNCTION_CHECK_SRC(src3, src3w); + CHECK_ARGUMENT(dst_reg != src2_reg); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.into%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32", (op & SLJIT_SHIFT_INTO_NON_ZERO) ? ".nz" : ""); - sljit_verbose_reg(compiler, src_dst); + sljit_verbose_reg(compiler, dst_reg); fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src1, src1w); + sljit_verbose_reg(compiler, src1_reg); fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src2, src2w); + sljit_verbose_reg(compiler, src2_reg); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, src3, src3w); fprintf(compiler->verbose, "\n"); } #endif @@ -1496,19 +1677,16 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compi CHECK_ARGUMENT(op >= SLJIT_FAST_RETURN && op <= SLJIT_PREFETCH_ONCE); FUNCTION_CHECK_SRC(src, srcw); - if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN) - { + if (op == SLJIT_FAST_RETURN || op == SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN) { CHECK_ARGUMENT(src != SLJIT_IMM); compiler->last_flags = 0; - } - else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE) - { + } else if (op >= SLJIT_PREFETCH_L1 && op <= SLJIT_PREFETCH_ONCE) { CHECK_ARGUMENT(src & SLJIT_MEM); } #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s ", op_src_names[op - SLJIT_OP_SRC_BASE]); + fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]); sljit_verbose_param(compiler, src, srcw); fprintf(compiler->verbose, "\n"); } @@ -1516,20 +1694,39 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compi CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 reg) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - SLJIT_UNUSED_ARG(reg); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS); + CHECK_ARGUMENT(op >= SLJIT_FAST_ENTER && op <= SLJIT_GET_RETURN_ADDRESS); + FUNCTION_CHECK_DST(dst, dstw); + + if (op == SLJIT_FAST_ENTER) + compiler->last_flags = 0; +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s ", op_src_dst_names[op - SLJIT_OP_SRC_DST_BASE]); + sljit_verbose_param(compiler, dst, dstw); + fprintf(compiler->verbose, "\n"); + } #endif CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_float_register_index(sljit_s32 reg) +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { + SLJIT_UNUSED_ARG(type); SLJIT_UNUSED_ARG(reg); #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - CHECK_ARGUMENT(reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS); + if (type == SLJIT_GP_REGISTER) { + CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_REGISTERS) + || (reg >= SLJIT_TMP_REGISTER_BASE && reg <= (SLJIT_TMP_REGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_REGISTERS))); + } else { + CHECK_ARGUMENT(type == SLJIT_FLOAT_REGISTER || ((type >> 12) == 0 || ((type >> 12) >= 3 && (type >> 12) <= 6))); + CHECK_ARGUMENT((reg > 0 && reg <= SLJIT_NUMBER_OF_FLOAT_REGISTERS) + || (reg >= SLJIT_TMP_FREGISTER_BASE && reg <= (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS))); + } #endif CHECK_RETURN_OK; } @@ -1583,8 +1780,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_MOV_F64 && GET_OPCODE(op) <= SLJIT_ABS_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); - FUNCTION_FCHECK(src, srcw); - FUNCTION_FCHECK(dst, dstw); + FUNCTION_FCHECK(src, srcw, op & SLJIT_32); + FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { @@ -1623,8 +1820,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_cmp(struct sljit_com CHECK_ARGUMENT(!(op & SLJIT_SET_Z)); CHECK_ARGUMENT((op & VARIABLE_FLAG_MASK) || (GET_FLAG_TYPE(op) >= SLJIT_F_EQUAL && GET_FLAG_TYPE(op) <= SLJIT_ORDERED_LESS_EQUAL)); - FUNCTION_FCHECK(src1, src1w); - FUNCTION_FCHECK(src2, src2w); + FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); + FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { @@ -1653,15 +1850,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(str #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CONV_S32_FROM_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); - FUNCTION_FCHECK(src, srcw); + FUNCTION_FCHECK(src, srcw, op & SLJIT_32); FUNCTION_CHECK_DST(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], - (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) ? ".s32" : ".sw", + fop1_conv_types[GET_OPCODE(op) - SLJIT_CONV_SW_FROM_F64], (op & SLJIT_32) ? ".f32" : ".f64"); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", "); @@ -1672,7 +1868,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(str CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { @@ -1683,16 +1879,15 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_sw(str #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); - CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_SW && GET_OPCODE(op) <= SLJIT_CONV_F64_FROM_S32); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); FUNCTION_CHECK_SRC(src, srcw); - FUNCTION_FCHECK(dst, dstw); + FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s.from%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], + fprintf(compiler->verbose, " %s%s.from.%s ", fop1_names[GET_OPCODE(op) - SLJIT_FOP1_BASE], (op & SLJIT_32) ? ".f32" : ".f64", - (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? ".s32" : ".sw"); + fop1_conv_types[GET_OPCODE(op) - SLJIT_CONV_SW_FROM_F64]); sljit_verbose_fparam(compiler, dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(compiler, src, srcw); @@ -1707,13 +1902,18 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) { + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_ADD_F64 && GET_OPCODE(op) <= SLJIT_DIV_F64); CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); - FUNCTION_FCHECK(src1, src1w); - FUNCTION_FCHECK(src2, src2w); - FUNCTION_FCHECK(dst, dstw); + FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); + FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); + FUNCTION_FCHECK(dst, dstw, op & SLJIT_32); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { @@ -1729,6 +1929,138 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile CHECK_RETURN_OK; } +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); + CHECK_ARGUMENT(GET_OPCODE(op) == SLJIT_COPYSIGN_F64); + FUNCTION_FCHECK(src1, src1w, op & SLJIT_32); + FUNCTION_FCHECK(src2, src2w, op & SLJIT_32); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, op & SLJIT_32)); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " %s%s ", fop2r_names[GET_OPCODE(op) - SLJIT_FOP2R_BASE], (op & SLJIT_32) ? ".f32" : ".f64"); + sljit_verbose_freg(compiler, dst_freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src2, src2w); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) +{ + SLJIT_UNUSED_ARG(value); + + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 1)); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fset32 "); + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", %f\n", value); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + SLJIT_UNUSED_ARG(value); + + if (SLJIT_UNLIKELY(compiler->skip_checks)) { + compiler->skip_checks = 0; + CHECK_RETURN_OK; + } + +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fset64 "); + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", %f\n", value); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); + CHECK_ARGUMENT(GET_OPCODE(op) >= SLJIT_COPY_TO_F64 && GET_OPCODE(op) <= SLJIT_COPY_FROM_F64); + CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, op & SLJIT_32)); + +#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg)); +#else /* !SLJIT_64BIT_ARCHITECTURE */ + switch (op) { + case SLJIT_COPY32_TO_F32: + case SLJIT_COPY32_FROM_F32: + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg)); + break; + case SLJIT_COPY_TO_F64: + case SLJIT_COPY_FROM_F64: + if (reg & REG_PAIR_MASK) { + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_FIRST(reg))); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(REG_PAIR_SECOND(reg))); + + if (op == SLJIT_COPY_TO_F64) + break; + + CHECK_ARGUMENT(REG_PAIR_FIRST(reg) != REG_PAIR_SECOND(reg)); + break; + } + + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg)); + break; + } +#endif /* SLJIT_64BIT_ARCHITECTURE */ +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " copy%s_%s_f%s ", (op & SLJIT_32) ? "32" : "", + GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? "to" : "from", (op & SLJIT_32) ? "32" : "64"); + + sljit_verbose_freg(compiler, freg); + + if (reg & REG_PAIR_MASK) { + fprintf(compiler->verbose, ", {"); + sljit_verbose_reg(compiler, REG_PAIR_FIRST(reg)); + fprintf(compiler->verbose, ", "); + sljit_verbose_reg(compiler, REG_PAIR_SECOND(reg)); + fprintf(compiler->verbose, "}\n"); + } else { + fprintf(compiler->verbose, ", "); + sljit_verbose_reg(compiler, reg); + fprintf(compiler->verbose, "\n"); + } + } +#endif + CHECK_RETURN_OK; +} + static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compiler *compiler) { SLJIT_UNUSED_ARG(compiler); @@ -1753,7 +2085,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compil #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ || (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) #define CHECK_UNORDERED(type, last_flags) \ - ((((type) & 0xff) == SLJIT_UNORDERED || ((type) & 0xff) == SLJIT_ORDERED) && \ + ((((type) & 0xfe) == SLJIT_ORDERED) && \ ((last_flags) & 0xff) >= SLJIT_UNORDERED && ((last_flags) & 0xff) <= SLJIT_ORDERED_LESS_EQUAL) #else #define CHECK_UNORDERED(type, last_flags) 0 @@ -1775,11 +2107,10 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compile if ((type & 0xff) <= SLJIT_NOT_ZERO) CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z); else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) { - CHECK_ARGUMENT((type & 0xff) == SLJIT_CARRY || (type & 0xff) == SLJIT_NOT_CARRY); + CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY); compiler->last_flags = 0; } else - CHECK_ARGUMENT((type & 0xff) == (compiler->last_flags & 0xff) - || ((type & 0xff) == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW) + CHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(type, compiler->last_flags)); } #endif @@ -1863,10 +2194,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compile #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32))); - CHECK_ARGUMENT((type & 0xff) >= SLJIT_F_EQUAL && (type & 0xff) <= SLJIT_ORDERED_LESS_EQUAL - && ((type & 0xff) <= SLJIT_ORDERED || sljit_cmp_info(type & 0xff))); - FUNCTION_FCHECK(src1, src1w); - FUNCTION_FCHECK(src2, src2w); + CHECK_ARGUMENT((type & 0xff) >= SLJIT_F_EQUAL && (type & 0xff) <= SLJIT_ORDERED_LESS_EQUAL); + FUNCTION_FCHECK(src1, src1w, type & SLJIT_32); + FUNCTION_FCHECK(src2, src2w, type & SLJIT_32); compiler->last_flags = 0; #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) @@ -1961,9 +2291,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com if (type <= SLJIT_NOT_ZERO) CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z); else - CHECK_ARGUMENT(type == (compiler->last_flags & 0xff) - || (type == SLJIT_NOT_CARRY && (compiler->last_flags & 0xff) == SLJIT_CARRY) - || (type == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW) + CHECK_ARGUMENT((type & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(type, compiler->last_flags)); FUNCTION_CHECK_DST(dst, dstw); @@ -1975,7 +2303,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " flags.%s%s%s ", GET_OPCODE(op) < SLJIT_OP2_BASE ? "mov" : op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], - GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_32) ? "32" : ""), + GET_OPCODE(op) < SLJIT_OP2_BASE ? op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE] : ((op & SLJIT_32) ? "32" : ""), !(op & SLJIT_SET_Z) ? "" : ".z"); sljit_verbose_param(compiler, dst, dstw); fprintf(compiler->verbose, ", %s\n", jump_names[type]); @@ -1984,9 +2312,10 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_com CHECK_RETURN_OK; } -static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) sljit_s32 cond = type & ~SLJIT_32; @@ -1995,27 +2324,68 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmov(struct sljit_compile CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg)); - if (src != SLJIT_IMM) { - CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src)); - CHECK_ARGUMENT(srcw == 0); - } + FUNCTION_CHECK_SRC(src1, src1w); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg)); if (cond <= SLJIT_NOT_ZERO) CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z); - else - CHECK_ARGUMENT(cond == (compiler->last_flags & 0xff) - || (cond == SLJIT_NOT_CARRY && (compiler->last_flags & 0xff) == SLJIT_CARRY) - || (cond == SLJIT_NOT_OVERFLOW && (compiler->last_flags & 0xff) == SLJIT_OVERFLOW) + else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) { + CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY); + compiler->last_flags = 0; + } else + CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff) || CHECK_UNORDERED(cond, compiler->last_flags)); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " cmov%s %s, ", + fprintf(compiler->verbose, " select%s %s, ", !(type & SLJIT_32) ? "" : "32", jump_names[type & ~SLJIT_32]); sljit_verbose_reg(compiler, dst_reg); fprintf(compiler->verbose, ", "); - sljit_verbose_param(compiler, src, srcw); + sljit_verbose_param(compiler, src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_reg(compiler, src2_reg); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + sljit_s32 cond = type & ~SLJIT_32; + + CHECK_ARGUMENT(cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL); + + CHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, type & SLJIT_32)); + FUNCTION_FCHECK(src1, src1w, type & SLJIT_32); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src2_freg, type & SLJIT_32)); + + if (cond <= SLJIT_NOT_ZERO) + CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z); + else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) { + CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY); + compiler->last_flags = 0; + } else + CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff) + || CHECK_UNORDERED(cond, compiler->last_flags)); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + fprintf(compiler->verbose, " fselect%s %s, ", + !(type & SLJIT_32) ? "" : "32", + jump_names[type & ~SLJIT_32]); + sljit_verbose_freg(compiler, dst_freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src1, src1w); + fprintf(compiler->verbose, ", "); + sljit_verbose_freg(compiler, src2_freg); fprintf(compiler->verbose, "\n"); } #endif @@ -2026,33 +2396,35 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler sljit_s32 reg, sljit_s32 mem, sljit_sw memw) { +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + sljit_s32 allowed_flags; +#endif /* SLJIT_ARGUMENT_CHECKS */ + if (SLJIT_UNLIKELY(compiler->skip_checks)) { compiler->skip_checks = 0; CHECK_RETURN_OK; } #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) - sljit_s32 allowed_flags; - if (type & SLJIT_MEM_UNALIGNED) { - CHECK_ARGUMENT(!(type & (SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32))); - } else if (type & SLJIT_MEM_UNALIGNED_16) { - CHECK_ARGUMENT(!(type & SLJIT_MEM_UNALIGNED_32)); + CHECK_ARGUMENT(!(type & (SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32))); + } else if (type & SLJIT_MEM_ALIGNED_16) { + CHECK_ARGUMENT(!(type & SLJIT_MEM_ALIGNED_32)); } else { - CHECK_ARGUMENT((reg & REG_PAIR_MASK) || (type & SLJIT_MEM_UNALIGNED_32)); + CHECK_ARGUMENT((reg & REG_PAIR_MASK) || (type & SLJIT_MEM_ALIGNED_32)); } allowed_flags = SLJIT_MEM_UNALIGNED; switch (type & 0xff) { + case SLJIT_MOV_P: + case SLJIT_MOV: + allowed_flags |= SLJIT_MEM_ALIGNED_32; + /* fallthrough */ case SLJIT_MOV_U32: case SLJIT_MOV_S32: case SLJIT_MOV32: - allowed_flags = SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16; - break; - case SLJIT_MOV: - case SLJIT_MOV_P: - allowed_flags = SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32; + allowed_flags |= SLJIT_MEM_ALIGNED_16; break; } @@ -2079,15 +2451,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler else fprintf(compiler->verbose, " %s%s%s", (type & SLJIT_MEM_STORE) ? "store" : "load", - !(type & SLJIT_32) ? "" : "32", - op1_names[(type & 0xff) - SLJIT_OP1_BASE]); + !(type & SLJIT_32) ? "" : "32", op1_types[(type & 0xff) - SLJIT_OP1_BASE]); if (type & SLJIT_MEM_UNALIGNED) - printf(".un"); - else if (type & SLJIT_MEM_UNALIGNED_16) - printf(".un16"); - else if (type & SLJIT_MEM_UNALIGNED_32) - printf(".un32"); + printf(".unal"); + else if (type & SLJIT_MEM_ALIGNED_16) + printf(".al16"); + else if (type & SLJIT_MEM_ALIGNED_32) + printf(".al32"); if (reg & REG_PAIR_MASK) { fprintf(compiler->verbose, " {"); @@ -2140,7 +2511,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem_update(struct sljit_c fprintf(compiler->verbose, " %s%s%s.%s ", (type & SLJIT_MEM_STORE) ? "store" : "load", !(type & SLJIT_32) ? "" : "32", - op1_names[(type & 0xff) - SLJIT_OP1_BASE], + op1_types[(type & 0xff) - SLJIT_OP1_BASE], (type & SLJIT_MEM_POST) ? "post" : "pre"); sljit_verbose_reg(compiler, reg); @@ -2157,19 +2528,20 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compile sljit_s32 mem, sljit_sw memw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64); if (type & SLJIT_MEM_UNALIGNED) { - CHECK_ARGUMENT(!(type & (SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32))); - } else if (type & SLJIT_MEM_UNALIGNED_16) { - CHECK_ARGUMENT(!(type & SLJIT_MEM_UNALIGNED_32)); + CHECK_ARGUMENT(!(type & (SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32))); + } else if (type & SLJIT_MEM_ALIGNED_16) { + CHECK_ARGUMENT(!(type & SLJIT_MEM_ALIGNED_32)); } else { - CHECK_ARGUMENT(type & SLJIT_MEM_UNALIGNED_32); + CHECK_ARGUMENT(type & SLJIT_MEM_ALIGNED_32); CHECK_ARGUMENT(!(type & SLJIT_32)); } - CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32))); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg)); + CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32))); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32)); FUNCTION_CHECK_SRC_MEM(mem, memw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) @@ -2179,11 +2551,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compile !(type & SLJIT_32) ? "f64" : "f32"); if (type & SLJIT_MEM_UNALIGNED) - printf(".un"); - else if (type & SLJIT_MEM_UNALIGNED_16) - printf(".un16"); - else if (type & SLJIT_MEM_UNALIGNED_32) - printf(".un32"); + printf(".unal"); + else if (type & SLJIT_MEM_ALIGNED_16) + printf(".al16"); + else if (type & SLJIT_MEM_ALIGNED_32) + printf(".al32"); fprintf(compiler->verbose, " "); sljit_verbose_freg(compiler, freg); @@ -2200,10 +2572,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_ sljit_s32 mem, sljit_sw memw) { #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU)); CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64); CHECK_ARGUMENT((type & ~(0xff | SLJIT_32 | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_POST)) == 0); FUNCTION_CHECK_SRC_MEM(mem, memw); - CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, type & SLJIT_32)); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { @@ -2226,7 +2599,297 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem_update(struct sljit_ } #endif CHECK_RETURN_OK; +} +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(SLJIT_SIMD_STORE)) == 0); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) <= (srcdst & SLJIT_MEM) ? SLJIT_SIMD_GET_REG_SIZE(type) : 0); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + FUNCTION_FCHECK(srcdst, srcdstw, 0); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_mov(compiler, type | SLJIT_SIMD_TEST, freg, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_mem: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_%s.%d.%s%d", + (type & SLJIT_SIMD_STORE) ? "store" : "load", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + if ((type & 0x3f000000) == SLJIT_SIMD_MEM_UNALIGNED) + fprintf(compiler->verbose, ".unal "); + else + fprintf(compiler->verbose, ".al%d ", (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, srcdst, srcdstw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + + if (type & SLJIT_SIMD_FLOAT) { + if (src == SLJIT_IMM) { + CHECK_ARGUMENT(srcw == 0); + } else { + FUNCTION_FCHECK(src, srcw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2); + } + } else if (src != SLJIT_IMM) { + FUNCTION_CHECK_DST(src, srcw); + } +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_dup: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_replicate.%d.%s%d ", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", "); + if (type & SLJIT_SIMD_FLOAT) + sljit_verbose_fparam(compiler, src, srcw); + else + sljit_verbose_param(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO | SLJIT_SIMD_LANE_SIGNED | SLJIT_32)) == 0); + CHECK_ARGUMENT((type & (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO)) != (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_ZERO)); + CHECK_ARGUMENT((type & (SLJIT_SIMD_STORE | SLJIT_SIMD_LANE_SIGNED)) != SLJIT_SIMD_LANE_SIGNED); + CHECK_ARGUMENT(!(type & SLJIT_SIMD_FLOAT) || !(type & (SLJIT_SIMD_LANE_SIGNED | SLJIT_32))); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(!(type & SLJIT_32) || SLJIT_SIMD_GET_ELEM_SIZE(type) <= 2); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + CHECK_ARGUMENT(lane_index >= 0 && lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type)))); + + if (type & SLJIT_SIMD_FLOAT) { + FUNCTION_FCHECK(srcdst, srcdstw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2); + } else if ((type & SLJIT_SIMD_STORE) || srcdst != SLJIT_IMM) { + FUNCTION_CHECK_DST(srcdst, srcdstw); + } +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_lane_mov(compiler, type | SLJIT_SIMD_TEST, freg, lane_index, srcdst, srcdstw) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_move_lane: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_%s_lane%s%s%s.%d.%s%d ", + (type & SLJIT_SIMD_STORE) ? "store" : "load", + (type & SLJIT_32) ? "32" : "", + (type & SLJIT_SIMD_LANE_ZERO) ? "_z" : "", + (type & SLJIT_SIMD_LANE_SIGNED) ? "_s" : "", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, "[%d], ", lane_index); + if (type & SLJIT_SIMD_FLOAT) + sljit_verbose_fparam(compiler, srcdst, srcdstw); + else + sljit_verbose_param(compiler, srcdst, srcdstw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) == 0); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src, 0)); + CHECK_ARGUMENT(src_lane_index >= 0 && src_lane_index < (1 << (SLJIT_SIMD_GET_REG_SIZE(type) - SLJIT_SIMD_GET_ELEM_SIZE(type)))); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_lane_replicate(compiler, type | SLJIT_SIMD_TEST, freg, src, src_lane_index) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_lane_replicate: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_lane_replicate.%d.%s%d ", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_freg(compiler, src); + fprintf(compiler->verbose, "[%d]\n", src_lane_index); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK2(SLJIT_SIMD_EXTEND_SIGNED)) == 0); + CHECK_ARGUMENT((type & (SLJIT_SIMD_EXTEND_SIGNED | SLJIT_SIMD_FLOAT)) != (SLJIT_SIMD_EXTEND_SIGNED | SLJIT_SIMD_FLOAT)); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM2_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_ELEM2_SIZE(type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + FUNCTION_FCHECK(src, srcw, SLJIT_SIMD_GET_ELEM_SIZE(type) == 2); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_extend(compiler, type | SLJIT_SIMD_TEST, freg, src, srcw) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_extend: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_load_extend%s.%d.%s%d.%s%d ", + (type & SLJIT_SIMD_EXTEND_SIGNED) ? "_s" : "", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM2_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_fparam(compiler, src, srcw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(SLJIT_32)) == SLJIT_SIMD_STORE); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) < SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, 0)); + FUNCTION_CHECK_DST(dst, dstw); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_sign(compiler, type | SLJIT_SIMD_TEST, freg, dst, dstw) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_sign: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_store_sign%s.%d.%s%d ", + (type & SLJIT_32) ? "32" : "", + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_param(compiler, dst, dstw); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; +} + +static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_SIMD)); + CHECK_ARGUMENT((type & SLJIT_SIMD_TYPE_MASK(0)) >= SLJIT_SIMD_OP2_AND && (type & SLJIT_SIMD_TYPE_MASK(0)) <= SLJIT_SIMD_OP2_XOR); + CHECK_ARGUMENT(SLJIT_SIMD_CHECK_REG(type)); + CHECK_ARGUMENT(SLJIT_SIMD_GET_ELEM_SIZE(type) <= SLJIT_SIMD_GET_REG_SIZE(type)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(dst_freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src1_freg, 0)); + CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(src2_freg, 0)); +#endif +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) + if (SLJIT_UNLIKELY(!!compiler->verbose)) { + if (type & SLJIT_SIMD_TEST) + CHECK_RETURN_OK; + if (sljit_emit_simd_op2(compiler, type | SLJIT_SIMD_TEST, dst_freg, src1_freg, src2_freg) == SLJIT_ERR_UNSUPPORTED) { + fprintf(compiler->verbose, " # simd_op2: unsupported form, no instructions are emitted\n"); + CHECK_RETURN_OK; + } + + fprintf(compiler->verbose, " simd_%s.%d.%s%d ", + simd_op2_names[SLJIT_SIMD_GET_OPCODE(type) - 1], + (8 << SLJIT_SIMD_GET_REG_SIZE(type)), + (type & SLJIT_SIMD_FLOAT) ? "f" : "", + (8 << SLJIT_SIMD_GET_ELEM_SIZE(type))); + + sljit_verbose_freg(compiler, dst_freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_freg(compiler, src1_freg); + fprintf(compiler->verbose, ", "); + sljit_verbose_freg(compiler, src2_freg); + fprintf(compiler->verbose, "\n"); + } +#endif + CHECK_RETURN_OK; } static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) @@ -2286,7 +2949,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_co #endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */ #define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \ - SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1), \ + SLJIT_COMPILE_ASSERT(!(SLJIT_CONV_SW_FROM_F64 & 0x1) && !(SLJIT_CONV_F64_FROM_SW & 0x1) && !(SLJIT_CONV_F64_FROM_UW & 0x1), \ invalid_float_opcodes); \ if (GET_OPCODE(op) >= SLJIT_CONV_SW_FROM_F64 && GET_OPCODE(op) <= SLJIT_CMP_F64) { \ if (GET_OPCODE(op) == SLJIT_CMP_F64) { \ @@ -2301,48 +2964,22 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_co ADJUST_LOCAL_OFFSET(src, srcw); \ return sljit_emit_fop1_conv_sw_from_f64(compiler, op, dst, dstw, src, srcw); \ } \ - CHECK(check_sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw)); \ + if ((GET_OPCODE(op) | 0x1) == SLJIT_CONV_F64_FROM_S32) { \ + CHECK(check_sljit_emit_fop1_conv_f64_from_w(compiler, op, dst, dstw, src, srcw)); \ + ADJUST_LOCAL_OFFSET(dst, dstw); \ + ADJUST_LOCAL_OFFSET(src, srcw); \ + return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \ + } \ + CHECK(check_sljit_emit_fop1_conv_f64_from_w(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); \ - return sljit_emit_fop1_conv_f64_from_sw(compiler, op, dst, dstw, src, srcw); \ + return sljit_emit_fop1_conv_f64_from_uw(compiler, op, dst, dstw, src, srcw); \ } \ CHECK(check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw)); \ ADJUST_LOCAL_OFFSET(dst, dstw); \ ADJUST_LOCAL_OFFSET(src, srcw); -#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ - || (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \ - || ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)) \ - || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ - || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) - -static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) -{ - struct sljit_label *label; - struct sljit_jump *jump; - sljit_s32 op = (type & SLJIT_32) ? SLJIT_MOV32 : SLJIT_MOV; - - SLJIT_SKIP_CHECKS(compiler); - jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1); - FAIL_IF(!jump); - - SLJIT_SKIP_CHECKS(compiler); - FAIL_IF(sljit_emit_op1(compiler, op, dst_reg, 0, src, srcw)); - - SLJIT_SKIP_CHECKS(compiler); - label = sljit_emit_label(compiler); - FAIL_IF(!label); - - sljit_set_label(jump, label); - return SLJIT_SUCCESS; -} - -#endif - -#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) \ - && !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) static sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, @@ -2355,7 +2992,7 @@ static sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit return sljit_emit_op1(compiler, type & (0xff | SLJIT_32), reg, 0, mem, memw); } -#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) && !SLJIT_CONFIG_ARM_V5 */ +#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) */ #if (!(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) || (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6)) \ && !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) @@ -2401,7 +3038,7 @@ static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, slji #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) # include "sljitNativeX86_common.c" -#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#elif (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) # include "sljitNativeARM_32.c" #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) # include "sljitNativeARM_32.c" @@ -2417,6 +3054,8 @@ static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, slji # include "sljitNativeRISCV_common.c" #elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) # include "sljitNativeS390X.c" +#elif (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) +# include "sljitNativeLOONGARCH_64.c" #endif static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) @@ -2463,8 +3102,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp return sljit_emit_return_void(compiler); } +#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ + && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \ + && !(defined(SLJIT_CONFIG_LOONGARCH_64) && SLJIT_CONFIG_LOONGARCH_64) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + + SLJIT_SKIP_CHECKS(compiler); + return sljit_emit_fop2(compiler, op, dst_freg, 0, src1, src1w, src2, src2w); +} + +#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X && !SLJIT_CONFIG_LOONGARCH_64 */ + #if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \ - && !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) + && !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \ + && !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src1, sljit_sw src1w, @@ -2480,18 +3140,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler condition = type & 0xff; #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) if ((condition == SLJIT_EQUAL || condition == SLJIT_NOT_EQUAL)) { - if ((src1 & SLJIT_IMM) && !src1w) { + if (src1 == SLJIT_IMM && !src1w) { src1 = src2; src1w = src2w; src2 = SLJIT_IMM; src2w = 0; } - if ((src2 & SLJIT_IMM) && !src2w) + if (src2 == SLJIT_IMM && !src2w) return emit_cmp_to0(compiler, type, src1, src1w); } #endif - if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) { + if (SLJIT_UNLIKELY(src1 == SLJIT_IMM && src2 != SLJIT_IMM)) { /* Immediate is preferred as second argument by most architectures. */ switch (condition) { case SLJIT_LESS: @@ -2532,7 +3192,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler if (condition <= SLJIT_NOT_ZERO) flags = SLJIT_SET_Z; else - flags = condition << VARIABLE_FLAG_SHIFT; + flags = (condition & 0xfe) << VARIABLE_FLAG_SHIFT; SLJIT_SKIP_CHECKS(compiler); PTR_FAIL_IF(sljit_emit_op2u(compiler, @@ -2544,20 +3204,17 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler #endif /* !SLJIT_CONFIG_MIPS */ -#if (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) +#if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - if (type < SLJIT_UNORDERED || type > SLJIT_ORDERED_LESS_EQUAL) - return 0; - switch (type) { case SLJIT_UNORDERED_OR_EQUAL: case SLJIT_ORDERED_NOT_EQUAL: - return 0; + return 1; } - return 1; + return 0; } #endif /* SLJIT_CONFIG_ARM */ @@ -2570,7 +3227,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile CHECK_PTR(check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w)); SLJIT_SKIP_CHECKS(compiler); - sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xff) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_32), src1, src1w, src2, src2w); + sljit_emit_fop1(compiler, SLJIT_CMP_F64 | ((type & 0xfe) << VARIABLE_FLAG_SHIFT) | (type & SLJIT_32), src1, src1w, src2, src2w); SLJIT_SKIP_CHECKS(compiler); return sljit_emit_jump(compiler, type); @@ -2629,6 +3286,158 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler #endif /* !SLJIT_CONFIG_ARM_64 && !SLJIT_CONFIG_PPC */ +#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ + && !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \ + && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(srcdst); + SLJIT_UNUSED_ARG(srcdstw); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(lane_index); + SLJIT_UNUSED_ARG(srcdst); + SLJIT_UNUSED_ARG(srcdstw); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(src_lane_index); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(src); + SLJIT_UNUSED_ARG(srcw); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(freg); + SLJIT_UNUSED_ARG(dst); + SLJIT_UNUSED_ARG(dstw); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(type); + SLJIT_UNUSED_ARG(dst_freg); + SLJIT_UNUSED_ARG(src1_freg); + SLJIT_UNUSED_ARG(src2_freg); + + return SLJIT_ERR_UNSUPPORTED; +} + +#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM */ + +#if !(defined(SLJIT_CONFIG_X86) && SLJIT_CONFIG_X86) \ + && !(defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM) \ + && !(defined(SLJIT_CONFIG_S390X) && SLJIT_CONFIG_S390X) \ + && !(defined(SLJIT_CONFIG_LOONGARCH) && SLJIT_CONFIG_LOONGARCH) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, + sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(dst_reg); + SLJIT_UNUSED_ARG(mem_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + return SLJIT_ERR_UNSUPPORTED; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, + sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + SLJIT_UNUSED_ARG(compiler); + SLJIT_UNUSED_ARG(op); + SLJIT_UNUSED_ARG(src_reg); + SLJIT_UNUSED_ARG(mem_reg); + SLJIT_UNUSED_ARG(temp_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + + return SLJIT_ERR_UNSUPPORTED; +} + +#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM && !SLJIT_CONFIG_S390X && !SLJIT_CONFIG_LOONGARCH */ + #if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \ && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) @@ -2646,491 +3455,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *c return sljit_emit_op1(compiler, SLJIT_MOV, dst, dstw, SLJIT_SP, 0); } -#endif - -#else /* SLJIT_CONFIG_UNSUPPORTED */ - -/* Empty function bodies for those machines, which are not (yet) supported. */ - -SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) -{ - return "unsupported"; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data) -{ - SLJIT_UNUSED_ARG(allocator_data); - SLJIT_UNUSED_ARG(exec_allocator_data); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(size); - SLJIT_UNREACHABLE(); - return NULL; -} - -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) -SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(verbose); - SLJIT_UNREACHABLE(); -} -#endif - -SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) -{ - SLJIT_UNUSED_ARG(feature_type); - SLJIT_UNREACHABLE(); - return 0; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) -{ - SLJIT_UNUSED_ARG(type); - SLJIT_UNREACHABLE(); - return 0; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data) -{ - SLJIT_UNUSED_ARG(code); - SLJIT_UNUSED_ARG(exec_allocator_data); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(options); - SLJIT_UNUSED_ARG(arg_types); - SLJIT_UNUSED_ARG(scratches); - SLJIT_UNUSED_ARG(saveds); - SLJIT_UNUSED_ARG(fscratches); - SLJIT_UNUSED_ARG(fsaveds); - SLJIT_UNUSED_ARG(local_size); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler, - sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, - sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(options); - SLJIT_UNUSED_ARG(arg_types); - SLJIT_UNUSED_ARG(scratches); - SLJIT_UNUSED_ARG(saveds); - SLJIT_UNUSED_ARG(fscratches); - SLJIT_UNUSED_ARG(fsaveds); - SLJIT_UNUSED_ARG(local_size); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(src_dst); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) -{ - SLJIT_UNREACHABLE(); - return reg; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_u32 size) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(instruction); - SLJIT_UNUSED_ARG(size); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(current_flags); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 arg_types) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(arg_types); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(src1); - SLJIT_UNUSED_ARG(src1w); - SLJIT_UNUSED_ARG(src2); - SLJIT_UNUSED_ARG(src2w); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label) -{ - SLJIT_UNUSED_ARG(jump); - SLJIT_UNUSED_ARG(label); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target) -{ - SLJIT_UNUSED_ARG(jump); - SLJIT_UNUSED_ARG(target); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label) -{ - SLJIT_UNUSED_ARG(put_label); - SLJIT_UNUSED_ARG(label); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 arg_types, - sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(arg_types); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 type) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(op); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(type); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(dst_reg); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(reg); - SLJIT_UNUSED_ARG(mem); - SLJIT_UNUSED_ARG(memw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(reg); - SLJIT_UNUSED_ARG(mem); - SLJIT_UNUSED_ARG(memw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(freg); - SLJIT_UNUSED_ARG(mem); - SLJIT_UNUSED_ARG(memw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(type); - SLJIT_UNUSED_ARG(freg); - SLJIT_UNUSED_ARG(mem); - SLJIT_UNUSED_ARG(memw); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(offset); - SLJIT_UNREACHABLE(); - return SLJIT_ERR_UNSUPPORTED; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw initval) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(initval); - SLJIT_UNREACHABLE(); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) -{ - SLJIT_UNUSED_ARG(compiler); - SLJIT_UNUSED_ARG(dst); - SLJIT_UNUSED_ARG(dstw); - return NULL; -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) -{ - SLJIT_UNUSED_ARG(addr); - SLJIT_UNUSED_ARG(new_target); - SLJIT_UNUSED_ARG(executable_offset); - SLJIT_UNREACHABLE(); -} - -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset) -{ - SLJIT_UNUSED_ARG(addr); - SLJIT_UNUSED_ARG(new_constant); - SLJIT_UNUSED_ARG(executable_offset); - SLJIT_UNREACHABLE(); -} +#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM_64 */ #endif /* !SLJIT_CONFIG_UNSUPPORTED */ diff --git a/src/3rdparty/pcre2/src/sljit/sljitLir.h b/src/3rdparty/pcre2/src/sljit/sljitLir.h index c6a0832ef87..2ba6683c74b 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitLir.h +++ b/src/3rdparty/pcre2/src/sljit/sljitLir.h @@ -72,6 +72,7 @@ #include "sljitConfigPre.h" #endif /* SLJIT_HAVE_CONFIG_PRE */ +#include "sljitConfigCPU.h" #include "sljitConfig.h" /* The following header file defines useful macros for fine tuning @@ -107,9 +108,9 @@ extern "C" { /* Cannot allocate executable memory. Only sljit_generate_code() returns with this error code. */ #define SLJIT_ERR_EX_ALLOC_FAILED 3 -/* Return value for SLJIT_CONFIG_UNSUPPORTED placeholder architecture. */ +/* Unsupported instruction form. */ #define SLJIT_ERR_UNSUPPORTED 4 -/* An ivalid argument is passed to any SLJIT function. */ +/* An invalid argument is passed to any SLJIT function. */ #define SLJIT_ERR_BAD_ARGUMENT 5 /* --------------------------------------------------------------------- */ @@ -127,40 +128,40 @@ extern "C" { is the first saved register, the one before the last is the second saved register, and so on. - If an architecture provides two scratch and three saved registers, - its scratch and saved register sets are the following: + For example, in an architecture with only five registers (A-E), if two + are scratch and three saved registers, they will be defined as follows: - R0 | | R0 is always a scratch register - R1 | | R1 is always a scratch register - [R2] | S2 | R2 and S2 represent the same physical register - [R3] | S1 | R3 and S1 represent the same physical register - [R4] | S0 | R4 and S0 represent the same physical register + A | R0 | | R0 always represent scratch register A + B | R1 | | R1 always represent scratch register B + C | [R2] | S2 | R2 and S2 represent the same physical register C + D | [R3] | S1 | R3 and S1 represent the same physical register D + E | [R4] | S0 | R4 and S0 represent the same physical register E - Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS would be 2 and - SLJIT_NUMBER_OF_SAVED_REGISTERS would be 3 for this architecture. + Note: SLJIT_NUMBER_OF_SCRATCH_REGISTERS will be 2 and + SLJIT_NUMBER_OF_SAVED_REGISTERS will be 3. - Note: On all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 12 + Note: For all supported architectures SLJIT_NUMBER_OF_REGISTERS >= 12 and SLJIT_NUMBER_OF_SAVED_REGISTERS >= 6. However, 6 registers are virtual on x86-32. See below. The purpose of this definition is convenience: saved registers can - be used as extra scratch registers. For example four registers can - be specified as scratch registers and the fifth one as saved register - on the CPU above and any user code which requires four scratch - registers can run unmodified. The SLJIT compiler automatically saves - the content of the two extra scratch register on the stack. Scratch - registers can also be preserved by saving their value on the stack - but this needs to be done manually. + be used as extra scratch registers. For example, building in the + previous example, four registers can be specified as scratch registers + and the fifth one as saved register, allowing any user code which requires + four scratch registers to run unmodified. The SLJIT compiler automatically + saves the content of the two extra scratch register on the stack. Scratch + registers can also be preserved by saving their value on the stack but + that needs to be done manually. Note: To emphasize that registers assigned to R2-R4 are saved registers, they are enclosed by square brackets. - Note: sljit_emit_enter and sljit_set_context defines whether a register - is S or R register. E.g: when 3 scratches and 1 saved is mapped - by sljit_emit_enter, the allowed register set will be: R0-R2 and - S0. Although S2 is mapped to the same position as R2, it does not - available in the current configuration. Furthermore the S1 register - is not available at all. + Note: sljit_emit_enter and sljit_set_context define whether a register + is S or R register. E.g: if in the previous example 3 scratches and + 1 saved are mapped by sljit_emit_enter, the allowed register set + will be: R0-R2 and S0. Although S2 is mapped to the same register + than R2, it is not available in that configuration. Furthermore + the S1 register cannot be used at all. */ /* Scratch registers. */ @@ -209,7 +210,7 @@ extern "C" { /* The SLJIT_SP provides direct access to the linear stack space allocated by sljit_emit_enter. It can only be used in the following form: SLJIT_MEM1(SLJIT_SP). The immediate offset is extended by the relative stack offset automatically. - The sljit_get_local_base can be used to obtain the real address of a value. */ + sljit_get_local_base can be used to obtain the real address of a value. */ #define SLJIT_SP (SLJIT_NUMBER_OF_REGISTERS + 1) /* Return with machine word. */ @@ -221,7 +222,7 @@ extern "C" { /* --------------------------------------------------------------------- */ /* Each floating point register can store a 32 or a 64 bit precision - value. The FR and FS register sets are overlap in the same way as R + value. The FR and FS register sets overlap in the same way as R and S register sets. See above. */ /* Floating point scratch registers. */ @@ -231,6 +232,10 @@ extern "C" { #define SLJIT_FR3 4 #define SLJIT_FR4 5 #define SLJIT_FR5 6 +#define SLJIT_FR6 7 +#define SLJIT_FR7 8 +#define SLJIT_FR8 9 +#define SLJIT_FR9 10 /* All FR registers provided by the architecture can be accessed by SLJIT_FR(i) The i parameter must be >= 0 and < SLJIT_NUMBER_OF_FLOAT_REGISTERS. */ #define SLJIT_FR(i) (1 + (i)) @@ -242,6 +247,10 @@ extern "C" { #define SLJIT_FS3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 3) #define SLJIT_FS4 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 4) #define SLJIT_FS5 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 5) +#define SLJIT_FS6 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 6) +#define SLJIT_FS7 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 7) +#define SLJIT_FS8 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 8) +#define SLJIT_FS9 (SLJIT_NUMBER_OF_FLOAT_REGISTERS - 9) /* All S registers provided by the architecture can be accessed by SLJIT_FS(i) The i parameter must be >= 0 and < SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS. */ #define SLJIT_FS(i) (SLJIT_NUMBER_OF_FLOAT_REGISTERS - (i)) @@ -260,23 +269,39 @@ extern "C" { /* The following argument type definitions are used by sljit_emit_enter, sljit_set_context, sljit_emit_call, and sljit_emit_icall functions. - As for sljit_emit_call and sljit_emit_icall, the first integer argument + For sljit_emit_call and sljit_emit_icall, the first integer argument must be placed into SLJIT_R0, the second one into SLJIT_R1, and so on. Similarly the first floating point argument must be placed into SLJIT_FR0, the second one into SLJIT_FR1, and so on. - As for sljit_emit_enter, the integer arguments can be stored in scratch - or saved registers. The first integer argument without _R postfix is - stored in SLJIT_S0, the next one in SLJIT_S1, and so on. The integer - arguments with _R postfix are placed into scratch registers. The index - of the scratch register is the count of the previous integer arguments - starting from SLJIT_R0. The floating point arguments are always placed - into SLJIT_FR0, SLJIT_FR1, and so on. + For sljit_emit_enter, the integer arguments can be stored in scratch + or saved registers. Scratch registers are identified by a _R suffix. - Note: if a function is called by sljit_emit_call/sljit_emit_icall and - an argument is stored in a scratch register by sljit_emit_enter, - that argument uses the same scratch register index for both - integer and floating point arguments. + If only saved registers are used, then the allocation mirrors what is + done for the "call" functions but using saved registers, meaning that + the first integer argument goes to SLJIT_S0, the second one goes into + SLJIT_S1, and so on. + + If scratch registers are used, then the way the integer registers are + allocated changes so that SLJIT_S0, SLJIT_S1, etc; will be assigned + only for the arguments not using scratch registers, while SLJIT_R + will be used for the ones using scratch registers. + + Furthermore, the index (shown as "n" above) that will be used for the + scratch register depends on how many previous integer registers + (scratch or saved) were used already, starting with SLJIT_R0. + Eventhough some indexes will be likely skipped, they still need to be + accounted for in the scratches parameter of sljit_emit_enter. See below + for some examples. + + The floating point arguments always use scratch registers (but not the + _R suffix like the integer arguments) and must use SLJIT_FR0, SLJIT_FR1, + just like in the "call" functions. + + Note: the mapping for scratch registers is part of the compiler context + and therefore a new context after sljit_emit_call/sljit_emit_icall + could remove access to some scratch registers that were used as + arguments. Example function definition: sljit_f32 SLJIT_FUNC example_c_callback(void *arg_a, @@ -288,29 +313,33 @@ extern "C" { | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_32, 3) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_F32, 4) Short form of argument type definition: - SLJIT_ARGS4(32, P, F64, 32, F32) + SLJIT_ARGS4(F32, P, F64, 32, F32) Argument passing: arg_a must be placed in SLJIT_R0 - arg_c must be placed in SLJIT_R1 arg_b must be placed in SLJIT_FR0 + arg_c must be placed in SLJIT_R1 arg_d must be placed in SLJIT_FR1 Examples for argument processing by sljit_emit_enter: - SLJIT_ARGS4(VOID, P, 32_R, F32, W) + SLJIT_ARGS4V(P, 32_R, F32, W) Arguments are placed into: SLJIT_S0, SLJIT_R1, SLJIT_FR0, SLJIT_S1 + The type of the result is void. - SLJIT_ARGS4(VOID, W, W_R, W, W_R) + SLJIT_ARGS4(F32, W, W_R, W, W_R) Arguments are placed into: SLJIT_S0, SLJIT_R1, SLJIT_S1, SLJIT_R3 + The type of the result is sljit_f32. - SLJIT_ARGS4(VOID, F64, W, F32, W_R) + SLJIT_ARGS4(P, W, F32, P_R) Arguments are placed into: SLJIT_FR0, SLJIT_S0, SLJIT_FR1, SLJIT_R1 + The type of the result is pointer. Note: it is recommended to pass the scratch arguments first followed by the saved arguments: - SLJIT_ARGS4(VOID, W_R, W_R, W, W) + SLJIT_ARGS4(W, W_R, W_R, W, W) Arguments are placed into: SLJIT_R0, SLJIT_R1, SLJIT_S0, SLJIT_S1 + The type of the result is sljit_sw / sljit_uw. */ /* The following flag is only allowed for the integer arguments of @@ -318,21 +347,21 @@ extern "C" { stored in a scratch register instead of a saved register. */ #define SLJIT_ARG_TYPE_SCRATCH_REG 0x8 -/* Void result, can only be used by SLJIT_ARG_RETURN. */ -#define SLJIT_ARG_TYPE_VOID 0 +/* No return value, only supported by SLJIT_ARG_RETURN. */ +#define SLJIT_ARG_TYPE_RET_VOID 0 /* Machine word sized integer argument or result. */ -#define SLJIT_ARG_TYPE_W 1 +#define SLJIT_ARG_TYPE_W 1 #define SLJIT_ARG_TYPE_W_R (SLJIT_ARG_TYPE_W | SLJIT_ARG_TYPE_SCRATCH_REG) /* 32 bit integer argument or result. */ -#define SLJIT_ARG_TYPE_32 2 +#define SLJIT_ARG_TYPE_32 2 #define SLJIT_ARG_TYPE_32_R (SLJIT_ARG_TYPE_32 | SLJIT_ARG_TYPE_SCRATCH_REG) /* Pointer sized integer argument or result. */ -#define SLJIT_ARG_TYPE_P 3 +#define SLJIT_ARG_TYPE_P 3 #define SLJIT_ARG_TYPE_P_R (SLJIT_ARG_TYPE_P | SLJIT_ARG_TYPE_SCRATCH_REG) /* 64 bit floating point argument or result. */ -#define SLJIT_ARG_TYPE_F64 4 +#define SLJIT_ARG_TYPE_F64 4 /* 32 bit floating point argument or result. */ -#define SLJIT_ARG_TYPE_F32 5 +#define SLJIT_ARG_TYPE_F32 5 #define SLJIT_ARG_SHIFT 4 #define SLJIT_ARG_RETURN(type) (type) @@ -345,24 +374,40 @@ extern "C" { can be shortened to: SLJIT_ARGS1(W, F32) + + Another example where no value is returned: + SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_RET_VOID) | SLJIT_ARG_VALUE(SLJIT_ARG_TYPE_W_R, 1) + + can be shortened to: + SLJIT_ARGS1V(W_R) */ #define SLJIT_ARG_TO_TYPE(type) SLJIT_ARG_TYPE_ ## type #define SLJIT_ARGS0(ret) \ SLJIT_ARG_RETURN(SLJIT_ARG_TO_TYPE(ret)) +#define SLJIT_ARGS0V() \ + SLJIT_ARG_RETURN(SLJIT_ARG_TYPE_RET_VOID) #define SLJIT_ARGS1(ret, arg1) \ (SLJIT_ARGS0(ret) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg1), 1)) +#define SLJIT_ARGS1V(arg1) \ + (SLJIT_ARGS0V() | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg1), 1)) #define SLJIT_ARGS2(ret, arg1, arg2) \ (SLJIT_ARGS1(ret, arg1) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg2), 2)) +#define SLJIT_ARGS2V(arg1, arg2) \ + (SLJIT_ARGS1V(arg1) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg2), 2)) #define SLJIT_ARGS3(ret, arg1, arg2, arg3) \ (SLJIT_ARGS2(ret, arg1, arg2) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg3), 3)) +#define SLJIT_ARGS3V(arg1, arg2, arg3) \ + (SLJIT_ARGS2V(arg1, arg2) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg3), 3)) #define SLJIT_ARGS4(ret, arg1, arg2, arg3, arg4) \ (SLJIT_ARGS3(ret, arg1, arg2, arg3) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg4), 4)) +#define SLJIT_ARGS4V(arg1, arg2, arg3, arg4) \ + (SLJIT_ARGS3V(arg1, arg2, arg3) | SLJIT_ARG_VALUE(SLJIT_ARG_TO_TYPE(arg4), 4)) /* --------------------------------------------------------------------- */ /* Main structures and functions */ @@ -457,7 +502,7 @@ struct sljit_compiler { sljit_s32 mode32; #endif -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) /* Constant pool handling. */ sljit_uw *cpool; sljit_u8 *cpool_unique; @@ -468,10 +513,10 @@ struct sljit_compiler { sljit_uw patches; #endif -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Temporary fields. */ sljit_uw shift_imm; -#endif /* SLJIT_CONFIG_ARM_V5 || SLJIT_CONFIG_ARM_V7 */ +#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V6 */ #if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__) sljit_uw args_size; @@ -501,6 +546,11 @@ struct sljit_compiler { sljit_s32 mode; #endif +#if (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH) + sljit_s32 cache_arg; + sljit_sw cache_argw; +#endif + #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) FILE* verbose; #endif @@ -558,8 +608,7 @@ static SLJIT_INLINE sljit_s32 sljit_get_compiler_error(struct sljit_compiler *co after the code is compiled. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compiler *compiler); -/* - Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit, +/* Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit, and <= 128 bytes on 64 bit architectures. The memory area is owned by the compiler, and freed by sljit_free_compiler. The returned pointer is sizeof(sljit_sw) aligned. Excellent for allocating small blocks during @@ -567,19 +616,21 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi to contain at most 16 pointers. If the size is outside of the range, the function will return with NULL. However, this return value does not indicate that there is no more memory (does not set the current error code - of the compiler to out-of-memory status). -*/ + of the compiler to out-of-memory status). */ SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_s32 size); +/* Returns the allocator data passed to sljit_create_compiler. These pointers + may contain context data even if the normal/exec allocator ignores it. */ +static SLJIT_INLINE void* sljit_get_allocator_data(struct sljit_compiler *compiler) { return compiler->allocator_data; } +static SLJIT_INLINE void* sljit_get_exec_allocator_data(struct sljit_compiler *compiler) { return compiler->exec_allocator_data; } + #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) /* Passing NULL disables verbose. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *compiler, FILE* verbose); #endif -/* - Create executable code from the instruction stream. This is the final step - of the code generation so no more instructions can be emitted after this call. -*/ +/* Create executable code from the instruction stream. This is the final step + of the code generation so no more instructions can be emitted after this call. */ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler); @@ -587,8 +638,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data); -/* - When the protected executable allocator is used the JIT code is mapped +/* When the protected executable allocator is used the JIT code is mapped twice. The first mapping has read/write and the second mapping has read/exec permissions. This function returns with the relative offset of the executable mapping using the writable mapping as the base after the machine code is @@ -596,16 +646,13 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_d allocator, since it uses only one mapping with read/write/exec permissions. Dynamic code modifications requires this value. - Before a successful code generation, this function returns with 0. -*/ + Before a successful code generation, this function returns with 0. */ static SLJIT_INLINE sljit_sw sljit_get_executable_offset(struct sljit_compiler *compiler) { return compiler->executable_offset; } -/* - The executable memory consumption of the generated code can be retrieved by +/* The executable memory consumption of the generated code can be retrieved by this function. The returned value can be used for statistical purposes. - Before a successful code generation, this function returns with 0. -*/ + Before a successful code generation, this function returns with 0. */ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; } /* Returns with non-zero if the feature or limitation type passed as its @@ -628,30 +675,49 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler #define SLJIT_HAS_CLZ 3 /* [Emulated] Count trailing zero is supported. */ #define SLJIT_HAS_CTZ 4 +/* [Emulated] Reverse the order of bytes is supported. */ +#define SLJIT_HAS_REV 5 /* [Emulated] Rotate left/right is supported. */ -#define SLJIT_HAS_ROT 5 +#define SLJIT_HAS_ROT 6 /* [Emulated] Conditional move is supported. */ -#define SLJIT_HAS_CMOV 6 +#define SLJIT_HAS_CMOV 7 /* [Emulated] Prefetch instruction is available (emulated as a nop). */ -#define SLJIT_HAS_PREFETCH 7 +#define SLJIT_HAS_PREFETCH 8 +/* [Emulated] Copy from/to f32 operation is available (see sljit_emit_fcopy). */ +#define SLJIT_HAS_COPY_F32 9 +/* [Emulated] Copy from/to f64 operation is available (see sljit_emit_fcopy). */ +#define SLJIT_HAS_COPY_F64 10 +/* [Not emulated] The 64 bit floating point registers can be used as + two separate 32 bit floating point registers (e.g. ARM32). The + second 32 bit part can be accessed by SLJIT_F64_SECOND. */ +#define SLJIT_HAS_F64_AS_F32_PAIR 11 +/* [Not emulated] Some SIMD operations are supported by the compiler. */ +#define SLJIT_HAS_SIMD 12 +/* [Not emulated] SIMD registers are mapped to a pair of double precision + floating point registers. E.g. passing either SLJIT_FR0 or SLJIT_FR1 to + a simd operation represents the same 128 bit register, and both SLJIT_FR0 + and SLJIT_FR1 are overwritten. */ +#define SLJIT_SIMD_REGS_ARE_PAIRS 13 +/* [Not emulated] Atomic support is available (fine-grained). */ +#define SLJIT_HAS_ATOMIC 14 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) -/* [Not emulated] SSE2 support is available on x86. */ -#define SLJIT_HAS_SSE2 100 +/* [Not emulated] AVX support is available on x86. */ +#define SLJIT_HAS_AVX 100 +/* [Not emulated] AVX2 support is available on x86. */ +#define SLJIT_HAS_AVX2 101 #endif SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type); /* If type is between SLJIT_ORDERED_EQUAL and SLJIT_ORDERED_LESS_EQUAL, - sljit_cmp_info returns one, if the cpu supports the passed floating - point comparison type. + sljit_cmp_info returns with: + zero - if the cpu supports the floating point comparison type + one - if the comparison requires two machine instructions + two - if the comparison requires more than two machine instructions - If type is SLJIT_UNORDERED or SLJIT_ORDERED, sljit_cmp_info returns - one, if the cpu supports checking the unordered comparison result - regardless of the comparison type passed to the comparison instruction. - The returned value is always one, if there is at least one type between - SLJIT_ORDERED_EQUAL and SLJIT_ORDERED_LESS_EQUAL where sljit_cmp_info - returns with a zero value. + When the result is non-zero, it is recommended to avoid + using the specified comparison type if it is easy to do so. Otherwise it returns zero. */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); @@ -662,7 +728,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); /* The executable code is a function from the viewpoint of the C - language. The function calls must obey to the ABI (Application + language. The function calls must conform to the ABI (Application Binary Interface) of the platform, which specify the purpose of machine registers and stack handling among other things. The sljit_emit_enter function emits the necessary instructions for @@ -721,7 +787,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type); #define SLJIT_ENTER_REG_ARG 0x00000004 /* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */ -#define SLJIT_MAX_LOCAL_SIZE 65536 +#define SLJIT_MAX_LOCAL_SIZE 1048576 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, @@ -732,9 +798,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi by sljit_emit_enter. Several functions (such as sljit_emit_return) requires this context to be able to generate the appropriate code. However, some code fragments (compiled separately) may have no - normal entry point so their context is unknown for the compiler. + normal entry point so their context is unknown to the compiler. - The sljit_set_context and sljit_emit_enter have the same arguments, + sljit_set_context and sljit_emit_enter have the same arguments, but sljit_set_context does not generate any machine code. Note: every call of sljit_emit_enter and sljit_set_context overwrites @@ -767,28 +833,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw); -/* Generating entry and exit points for fast call functions (see SLJIT_FAST_CALL). - Both sljit_emit_fast_enter and SLJIT_FAST_RETURN operations preserve the - values of all registers and stack frame. The return address is stored in the - dst argument of sljit_emit_fast_enter, and this return address can be passed - to SLJIT_FAST_RETURN to continue the execution after the fast call. - - Fast calls are cheap operations (usually only a single call instruction is - emitted) but they do not preserve any registers. However the callee function - can freely use / update any registers and the local area which can be - efficiently exploited by various optimizations. Registers can be saved - and restored manually if needed. - - Although returning to different address by SLJIT_FAST_RETURN is possible, - this address usually cannot be predicted by the return address predictor of - modern CPUs which may reduce performance. Furthermore certain security - enhancement technologies such as Intel Control-flow Enforcement Technology - (CET) may disallow returning to a different address. - - Flags: - (does not modify flags). */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw); - /* Source and destination operands for arithmetical instructions imm - a simple immediate value (cannot be used as a destination) @@ -816,7 +860,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * Note: Different architectures have different addressing limitations. A single instruction is enough for the following addressing - modes. Other adrressing modes are emulated by instruction + modes. Other addressing modes are emulated by instruction sequences. This information could help to improve those code generators which focuses only a few architectures. @@ -847,6 +891,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * s390x: [reg+imm], -2^19 <= imm < 2^19 [reg+reg] is supported Write-back is not supported + loongarch: [reg+imm], -2048 <= imm <= 2047 + [reg+reg] is supported + Write-back is not supported */ /* Macros for specifying operand types. */ @@ -854,9 +901,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * #define SLJIT_MEM0() (SLJIT_MEM) #define SLJIT_MEM1(r1) (SLJIT_MEM | (r1)) #define SLJIT_MEM2(r1, r2) (SLJIT_MEM | (r1) | ((r2) << 8)) -#define SLJIT_IMM 0x40 +#define SLJIT_IMM 0x7f #define SLJIT_REG_PAIR(r1, r2) ((r1) | ((r2) << 8)) +/* Macros for checking operand types (only for valid arguments). */ +#define SLJIT_IS_REG(arg) ((arg) > 0 && (arg) < SLJIT_IMM) +#define SLJIT_IS_MEM(arg) ((arg) & SLJIT_MEM) +#define SLJIT_IS_MEM0(arg) ((arg) == SLJIT_MEM) +#define SLJIT_IS_MEM1(arg) ((arg) > SLJIT_MEM && (arg) < (SLJIT_MEM << 1)) +#define SLJIT_IS_MEM2(arg) (((arg) & SLJIT_MEM) && (arg) >= (SLJIT_MEM << 1)) +#define SLJIT_IS_IMM(arg) ((arg) == SLJIT_IMM) +#define SLJIT_IS_REG_PAIR(arg) (!((arg) & SLJIT_MEM) && (arg) >= (SLJIT_MEM << 1)) + /* Sets 32 bit operation mode on 64 bit CPUs. This option is ignored on 32 bit CPUs. When this option is set for an arithmetic operation, only the lower 32 bits of the input registers are used, and the CPU status @@ -1057,27 +1113,57 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile Note: loads a pointer sized data, useful on x32 mode (a 64 bit mode on x86-64 which uses 32 bit pointers) or similar compiling modes */ #define SLJIT_MOV_P (SLJIT_OP1_BASE + 8) -/* Flags: Z - Note: immediate source argument is not supported */ -#define SLJIT_NOT (SLJIT_OP1_BASE + 9) -#define SLJIT_NOT32 (SLJIT_NOT | SLJIT_32) /* Count leading zeroes Flags: - (may destroy flags) Note: immediate source argument is not supported */ -#define SLJIT_CLZ (SLJIT_OP1_BASE + 10) +#define SLJIT_CLZ (SLJIT_OP1_BASE + 9) #define SLJIT_CLZ32 (SLJIT_CLZ | SLJIT_32) /* Count trailing zeroes Flags: - (may destroy flags) Note: immediate source argument is not supported */ -#define SLJIT_CTZ (SLJIT_OP1_BASE + 11) +#define SLJIT_CTZ (SLJIT_OP1_BASE + 10) #define SLJIT_CTZ32 (SLJIT_CTZ | SLJIT_32) +/* Reverse the order of bytes + Flags: - (may destroy flags) + Note: converts between little and big endian formats + Note: immediate source argument is not supported */ +#define SLJIT_REV (SLJIT_OP1_BASE + 11) +#define SLJIT_REV32 (SLJIT_REV | SLJIT_32) +/* Reverse the order of bytes in the lower 16 bit and extend as unsigned + Flags: - (may destroy flags) + Note: converts between little and big endian formats + Note: immediate source argument is not supported */ +#define SLJIT_REV_U16 (SLJIT_OP1_BASE + 12) +#define SLJIT_REV32_U16 (SLJIT_REV_U16 | SLJIT_32) +/* Reverse the order of bytes in the lower 16 bit and extend as signed + Flags: - (may destroy flags) + Note: converts between little and big endian formats + Note: immediate source argument is not supported */ +#define SLJIT_REV_S16 (SLJIT_OP1_BASE + 13) +#define SLJIT_REV32_S16 (SLJIT_REV_S16 | SLJIT_32) +/* Reverse the order of bytes in the lower 32 bit and extend as unsigned + Flags: - (may destroy flags) + Note: converts between little and big endian formats + Note: immediate source argument is not supported */ +#define SLJIT_REV_U32 (SLJIT_OP1_BASE + 14) +/* Reverse the order of bytes in the lower 32 bit and extend as signed + Flags: - (may destroy flags) + Note: converts between little and big endian formats + Note: immediate source argument is not supported */ +#define SLJIT_REV_S32 (SLJIT_OP1_BASE + 15) + +/* The following unary operations are supported by using sljit_emit_op2: + - binary not: SLJIT_XOR with immedate -1 as src1 or src2 + - negate: SLJIT_SUB with immedate 0 as src1 + Note: these operations are optimized by the compiler if the + target CPU has specialized instruction forms for them. */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw); /* Starting index of opcodes for sljit_emit_op2. */ -#define SLJIT_OP2_BASE 96 +#define SLJIT_OP2_BASE 64 /* Flags: Z | OVERFLOW | CARRY */ #define SLJIT_ADD (SLJIT_OP2_BASE + 0) @@ -1174,80 +1260,97 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil op must be one of the following operations: SLJIT_SHL or SLJIT_SHL32: - src_dst <<= src2 - src_dst |= ((src1 >> 1) >> (src2 ^ value_mask)) + dst_reg = src1_reg << src3_reg + dst_reg |= ((src2_reg >> 1) >> (src3 ^ value_mask)) SLJIT_MSHL or SLJIT_MSHL32: - src2 &= value_mask + src3 &= value_mask perform the SLJIT_SHL or SLJIT_SHL32 operation SLJIT_LSHR or SLJIT_LSHR32: - src_dst >>= src2 - src_dst |= ((src1 << 1) << (src2 ^ value_mask)) + dst_reg = src1_reg >> src3_reg + dst_reg |= ((src2_reg << 1) << (src3 ^ value_mask)) SLJIT_MLSHR or SLJIT_MLSHR32: - src2 &= value_mask + src3 &= value_mask perform the SLJIT_LSHR or SLJIT_LSHR32 operation op can be combined (or'ed) with SLJIT_SHIFT_INTO_NON_ZERO - src_dst must be a register which content is updated after - the operation is completed - src1 / src1w contains the bits which shifted into src_dst - src2 / src2w contains the shift amount + dst_reg specifies the destination register, where dst_reg + and src2_reg cannot be the same registers + src1_reg specifies the source register + src2_reg specifies the register which is shifted into src1_reg + src3 / src3w contains the shift amount - Note: a rotate operation can be performed if src_dst and - src1 are set to the same register + Note: a rotate operation is performed if src1_reg and + src2_reg are the same registers Flags: - (may destroy flags) */ -/* The src2 contains a non-zero value. Improves the generated - code on certain architectures, which provides a small - performance improvement. */ +/* The src3 operand contains a non-zero value. Improves + the generated code on certain architectures, which + provides a small performance improvement. */ #define SLJIT_SHIFT_INTO_NON_ZERO 0x200 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w); + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w); -/* Starting index of opcodes for sljit_emit_op2. */ -#define SLJIT_OP_SRC_BASE 128 +/* Starting index of opcodes for sljit_emit_op_src + and sljit_emit_op_dst. */ +#define SLJIT_OP_SRC_DST_BASE 96 -/* Note: src cannot be an immedate value +/* Fast return, see SLJIT_FAST_CALL for more details. + Note: src cannot be an immedate value Flags: - (does not modify flags) */ -#define SLJIT_FAST_RETURN (SLJIT_OP_SRC_BASE + 0) +#define SLJIT_FAST_RETURN (SLJIT_OP_SRC_DST_BASE + 0) /* Skip stack frames before fast return. Note: src cannot be an immedate value Flags: may destroy flags. */ -#define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN (SLJIT_OP_SRC_BASE + 1) +#define SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN (SLJIT_OP_SRC_DST_BASE + 1) /* Prefetch value into the level 1 data cache Note: if the target CPU does not support data prefetch, no instructions are emitted. Note: this instruction never fails, even if the memory address is invalid. Flags: - (does not modify flags) */ -#define SLJIT_PREFETCH_L1 (SLJIT_OP_SRC_BASE + 2) +#define SLJIT_PREFETCH_L1 (SLJIT_OP_SRC_DST_BASE + 2) /* Prefetch value into the level 2 data cache Note: same as SLJIT_PREFETCH_L1 if the target CPU does not support this instruction form. Note: this instruction never fails, even if the memory address is invalid. Flags: - (does not modify flags) */ -#define SLJIT_PREFETCH_L2 (SLJIT_OP_SRC_BASE + 3) +#define SLJIT_PREFETCH_L2 (SLJIT_OP_SRC_DST_BASE + 3) /* Prefetch value into the level 3 data cache Note: same as SLJIT_PREFETCH_L2 if the target CPU does not support this instruction form. Note: this instruction never fails, even if the memory address is invalid. Flags: - (does not modify flags) */ -#define SLJIT_PREFETCH_L3 (SLJIT_OP_SRC_BASE + 4) +#define SLJIT_PREFETCH_L3 (SLJIT_OP_SRC_DST_BASE + 4) /* Prefetch a value which is only used once (and can be discarded afterwards) Note: same as SLJIT_PREFETCH_L1 if the target CPU does not support this instruction form. Note: this instruction never fails, even if the memory address is invalid. Flags: - (does not modify flags) */ -#define SLJIT_PREFETCH_ONCE (SLJIT_OP_SRC_BASE + 5) +#define SLJIT_PREFETCH_ONCE (SLJIT_OP_SRC_DST_BASE + 5) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw); +/* Fast enter, see SLJIT_FAST_CALL for more details. + Flags: - (does not modify flags) */ +#define SLJIT_FAST_ENTER (SLJIT_OP_SRC_DST_BASE + 6) + +/* Copies the return address into dst. The return address is the + address where the execution continues after the called function + returns (see: sljit_emit_return / sljit_emit_return_void). + Flags: - (does not modify flags) */ +#define SLJIT_GET_RETURN_ADDRESS (SLJIT_OP_SRC_DST_BASE + 7) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw); + /* Starting index of opcodes for sljit_emit_fop1. */ -#define SLJIT_FOP1_BASE 160 +#define SLJIT_FOP1_BASE 128 /* Flags: - (does not modify flags) */ #define SLJIT_MOV_F64 (SLJIT_FOP1_BASE + 0) @@ -1270,15 +1373,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp /* Flags: - (may destroy flags) */ #define SLJIT_CONV_F64_FROM_S32 (SLJIT_FOP1_BASE + 5) #define SLJIT_CONV_F32_FROM_S32 (SLJIT_CONV_F64_FROM_S32 | SLJIT_32) +/* Flags: - (may destroy flags) */ +#define SLJIT_CONV_F64_FROM_UW (SLJIT_FOP1_BASE + 6) +#define SLJIT_CONV_F32_FROM_UW (SLJIT_CONV_F64_FROM_UW | SLJIT_32) +/* Flags: - (may destroy flags) */ +#define SLJIT_CONV_F64_FROM_U32 (SLJIT_FOP1_BASE + 7) +#define SLJIT_CONV_F32_FROM_U32 (SLJIT_CONV_F64_FROM_U32 | SLJIT_32) /* Note: dst is the left and src is the right operand for SLJIT_CMP_F32/64. Flags: EQUAL_F | LESS_F | GREATER_EQUAL_F | GREATER_F | LESS_EQUAL_F */ -#define SLJIT_CMP_F64 (SLJIT_FOP1_BASE + 6) +#define SLJIT_CMP_F64 (SLJIT_FOP1_BASE + 8) #define SLJIT_CMP_F32 (SLJIT_CMP_F64 | SLJIT_32) /* Flags: - (may destroy flags) */ -#define SLJIT_NEG_F64 (SLJIT_FOP1_BASE + 7) +#define SLJIT_NEG_F64 (SLJIT_FOP1_BASE + 9) #define SLJIT_NEG_F32 (SLJIT_NEG_F64 | SLJIT_32) /* Flags: - (may destroy flags) */ -#define SLJIT_ABS_F64 (SLJIT_FOP1_BASE + 8) +#define SLJIT_ABS_F64 (SLJIT_FOP1_BASE + 10) #define SLJIT_ABS_F32 (SLJIT_ABS_F64 | SLJIT_32) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, @@ -1286,7 +1395,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil sljit_s32 src, sljit_sw srcw); /* Starting index of opcodes for sljit_emit_fop2. */ -#define SLJIT_FOP2_BASE 192 +#define SLJIT_FOP2_BASE 160 /* Flags: - (may destroy flags) */ #define SLJIT_ADD_F64 (SLJIT_FOP2_BASE + 0) @@ -1306,10 +1415,90 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w); +/* Starting index of opcodes for sljit_emit_fop2r. */ +#define SLJIT_FOP2R_BASE 168 + +/* Flags: - (may destroy flags) */ +#define SLJIT_COPYSIGN_F64 (SLJIT_FOP2R_BASE + 0) +#define SLJIT_COPYSIGN_F32 (SLJIT_COPYSIGN_F64 | SLJIT_32) + +/* Similar to sljit_emit_fop2, except the destination is always a register. */ +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w); + +/* Sets a floating point register to an immediate value. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value); + +/* The following opcodes are used by sljit_emit_fcopy(). */ + +/* 64 bit: copy a 64 bit value from an integer register into a + 64 bit floating point register without any modifications. + 32 bit: copy a 32 bit register or register pair into a 64 bit + floating point register without any modifications. The + register, or the first register of the register pair + replaces the high order 32 bit of the floating point + register. If a register pair is passed, the low + order 32 bit is replaced by the second register. + Otherwise, the low order 32 bit is unchanged. */ +#define SLJIT_COPY_TO_F64 1 +/* Copy a 32 bit value from an integer register into a 32 bit + floating point register without any modifications. */ +#define SLJIT_COPY32_TO_F32 (SLJIT_COPY_TO_F64 | SLJIT_32) +/* 64 bit: copy the value of a 64 bit floating point register into + an integer register without any modifications. + 32 bit: copy a 64 bit floating point register into a 32 bit register + or a 32 bit register pair without any modifications. The + high order 32 bit of the floating point register is copied + into the register, or the first register of the register + pair. If a register pair is passed, the low order 32 bit + is copied into the second register. */ +#define SLJIT_COPY_FROM_F64 2 +/* Copy the value of a 32 bit floating point register into an integer + register without any modifications. The register should be processed + with 32 bit operations later. */ +#define SLJIT_COPY32_FROM_F32 (SLJIT_COPY_FROM_F64 | SLJIT_32) + +/* Special data copy which involves floating point registers. + + op must be between SLJIT_COPY_TO_F64 and SLJIT_COPY32_FROM_F32 + freg must be a floating point register + reg must be a register or register pair */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg); + /* Label and jump instructions. */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler); +/* The SLJIT_FAST_CALL is a calling method for creating lightweight function + calls. This type of calls preserve the values of all registers and stack + frame. Unlike normal function calls, the enter and return operations must + be performed by the SLJIT_FAST_ENTER and SLJIT_FAST_RETURN operations + respectively. The return address is stored in the dst argument of the + SLJIT_FAST_ENTER operation, and this return address should be passed as + the src argument for the SLJIT_FAST_RETURN operation to return from the + called function. + + Fast calls are cheap operations (usually only a single call instruction is + emitted) but they do not preserve any registers. However the callee function + can freely use / update any registers and the locals area which can be + efficiently exploited by various optimizations. Registers can be saved + and restored manually if needed. + + Although returning to different address by SLJIT_FAST_RETURN is possible, + this address usually cannot be predicted by the return address predictor of + modern CPUs which may reduce performance. Furthermore certain security + enhancement technologies such as Intel Control-flow Enforcement Technology + (CET) may disallow returning to a different address (indirect jumps + can be used instead, see SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN). */ + /* Invert (negate) conditional type: xor (^) with 0x1 */ /* Integer comparison types. */ @@ -1321,19 +1510,19 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #define SLJIT_LESS 2 #define SLJIT_SET_LESS SLJIT_SET(SLJIT_LESS) #define SLJIT_GREATER_EQUAL 3 -#define SLJIT_SET_GREATER_EQUAL SLJIT_SET(SLJIT_GREATER_EQUAL) +#define SLJIT_SET_GREATER_EQUAL SLJIT_SET(SLJIT_LESS) #define SLJIT_GREATER 4 #define SLJIT_SET_GREATER SLJIT_SET(SLJIT_GREATER) #define SLJIT_LESS_EQUAL 5 -#define SLJIT_SET_LESS_EQUAL SLJIT_SET(SLJIT_LESS_EQUAL) +#define SLJIT_SET_LESS_EQUAL SLJIT_SET(SLJIT_GREATER) #define SLJIT_SIG_LESS 6 #define SLJIT_SET_SIG_LESS SLJIT_SET(SLJIT_SIG_LESS) #define SLJIT_SIG_GREATER_EQUAL 7 -#define SLJIT_SET_SIG_GREATER_EQUAL SLJIT_SET(SLJIT_SIG_GREATER_EQUAL) +#define SLJIT_SET_SIG_GREATER_EQUAL SLJIT_SET(SLJIT_SIG_LESS) #define SLJIT_SIG_GREATER 8 #define SLJIT_SET_SIG_GREATER SLJIT_SET(SLJIT_SIG_GREATER) #define SLJIT_SIG_LESS_EQUAL 9 -#define SLJIT_SET_SIG_LESS_EQUAL SLJIT_SET(SLJIT_SIG_LESS_EQUAL) +#define SLJIT_SET_SIG_LESS_EQUAL SLJIT_SET(SLJIT_SIG_GREATER) #define SLJIT_OVERFLOW 10 #define SLJIT_SET_OVERFLOW SLJIT_SET(SLJIT_OVERFLOW) @@ -1344,70 +1533,74 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #define SLJIT_SET_CARRY SLJIT_SET(SLJIT_CARRY) #define SLJIT_NOT_CARRY 13 +#define SLJIT_ATOMIC_STORED 14 +#define SLJIT_SET_ATOMIC_STORED SLJIT_SET(SLJIT_ATOMIC_STORED) +#define SLJIT_ATOMIC_NOT_STORED 15 + /* Basic floating point comparison types. Note: when the comparison result is unordered, their behaviour is unspecified. */ -#define SLJIT_F_EQUAL 14 +#define SLJIT_F_EQUAL 16 #define SLJIT_SET_F_EQUAL SLJIT_SET(SLJIT_F_EQUAL) -#define SLJIT_F_NOT_EQUAL 15 -#define SLJIT_SET_F_NOT_EQUAL SLJIT_SET(SLJIT_F_NOT_EQUAL) -#define SLJIT_F_LESS 16 +#define SLJIT_F_NOT_EQUAL 17 +#define SLJIT_SET_F_NOT_EQUAL SLJIT_SET(SLJIT_F_EQUAL) +#define SLJIT_F_LESS 18 #define SLJIT_SET_F_LESS SLJIT_SET(SLJIT_F_LESS) -#define SLJIT_F_GREATER_EQUAL 17 -#define SLJIT_SET_F_GREATER_EQUAL SLJIT_SET(SLJIT_F_GREATER_EQUAL) -#define SLJIT_F_GREATER 18 +#define SLJIT_F_GREATER_EQUAL 19 +#define SLJIT_SET_F_GREATER_EQUAL SLJIT_SET(SLJIT_F_LESS) +#define SLJIT_F_GREATER 20 #define SLJIT_SET_F_GREATER SLJIT_SET(SLJIT_F_GREATER) -#define SLJIT_F_LESS_EQUAL 19 -#define SLJIT_SET_F_LESS_EQUAL SLJIT_SET(SLJIT_F_LESS_EQUAL) +#define SLJIT_F_LESS_EQUAL 21 +#define SLJIT_SET_F_LESS_EQUAL SLJIT_SET(SLJIT_F_GREATER) /* Jumps when either argument contains a NaN value. */ -#define SLJIT_UNORDERED 20 +#define SLJIT_UNORDERED 22 #define SLJIT_SET_UNORDERED SLJIT_SET(SLJIT_UNORDERED) /* Jumps when neither argument contains a NaN value. */ -#define SLJIT_ORDERED 21 -#define SLJIT_SET_ORDERED SLJIT_SET(SLJIT_ORDERED) +#define SLJIT_ORDERED 23 +#define SLJIT_SET_ORDERED SLJIT_SET(SLJIT_UNORDERED) /* Ordered / unordered floating point comparison types. Note: each comparison type has an ordered and unordered form. Some architectures supports only either of them (see: sljit_cmp_info). */ -#define SLJIT_ORDERED_EQUAL 22 +#define SLJIT_ORDERED_EQUAL 24 #define SLJIT_SET_ORDERED_EQUAL SLJIT_SET(SLJIT_ORDERED_EQUAL) -#define SLJIT_UNORDERED_OR_NOT_EQUAL 23 -#define SLJIT_SET_UNORDERED_OR_NOT_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_NOT_EQUAL) -#define SLJIT_ORDERED_LESS 24 +#define SLJIT_UNORDERED_OR_NOT_EQUAL 25 +#define SLJIT_SET_UNORDERED_OR_NOT_EQUAL SLJIT_SET(SLJIT_ORDERED_EQUAL) +#define SLJIT_ORDERED_LESS 26 #define SLJIT_SET_ORDERED_LESS SLJIT_SET(SLJIT_ORDERED_LESS) -#define SLJIT_UNORDERED_OR_GREATER_EQUAL 25 -#define SLJIT_SET_UNORDERED_OR_GREATER_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_GREATER_EQUAL) -#define SLJIT_ORDERED_GREATER 26 +#define SLJIT_UNORDERED_OR_GREATER_EQUAL 27 +#define SLJIT_SET_UNORDERED_OR_GREATER_EQUAL SLJIT_SET(SLJIT_ORDERED_LESS) +#define SLJIT_ORDERED_GREATER 28 #define SLJIT_SET_ORDERED_GREATER SLJIT_SET(SLJIT_ORDERED_GREATER) -#define SLJIT_UNORDERED_OR_LESS_EQUAL 27 -#define SLJIT_SET_UNORDERED_OR_LESS_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_LESS_EQUAL) +#define SLJIT_UNORDERED_OR_LESS_EQUAL 29 +#define SLJIT_SET_UNORDERED_OR_LESS_EQUAL SLJIT_SET(SLJIT_ORDERED_GREATER) -#define SLJIT_UNORDERED_OR_EQUAL 28 +#define SLJIT_UNORDERED_OR_EQUAL 30 #define SLJIT_SET_UNORDERED_OR_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_EQUAL) -#define SLJIT_ORDERED_NOT_EQUAL 29 -#define SLJIT_SET_ORDERED_NOT_EQUAL SLJIT_SET(SLJIT_ORDERED_NOT_EQUAL) -#define SLJIT_UNORDERED_OR_LESS 30 +#define SLJIT_ORDERED_NOT_EQUAL 31 +#define SLJIT_SET_ORDERED_NOT_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_EQUAL) +#define SLJIT_UNORDERED_OR_LESS 32 #define SLJIT_SET_UNORDERED_OR_LESS SLJIT_SET(SLJIT_UNORDERED_OR_LESS) -#define SLJIT_ORDERED_GREATER_EQUAL 31 -#define SLJIT_SET_ORDERED_GREATER_EQUAL SLJIT_SET(SLJIT_ORDERED_GREATER_EQUAL) -#define SLJIT_UNORDERED_OR_GREATER 32 +#define SLJIT_ORDERED_GREATER_EQUAL 33 +#define SLJIT_SET_ORDERED_GREATER_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_LESS) +#define SLJIT_UNORDERED_OR_GREATER 34 #define SLJIT_SET_UNORDERED_OR_GREATER SLJIT_SET(SLJIT_UNORDERED_OR_GREATER) -#define SLJIT_ORDERED_LESS_EQUAL 33 -#define SLJIT_SET_ORDERED_LESS_EQUAL SLJIT_SET(SLJIT_ORDERED_LESS_EQUAL) +#define SLJIT_ORDERED_LESS_EQUAL 35 +#define SLJIT_SET_ORDERED_LESS_EQUAL SLJIT_SET(SLJIT_UNORDERED_OR_GREATER) /* Unconditional jump types. */ -#define SLJIT_JUMP 34 -/* Fast calling method. See sljit_emit_fast_enter / SLJIT_FAST_RETURN. */ -#define SLJIT_FAST_CALL 35 +#define SLJIT_JUMP 36 +/* Fast calling method. See the description above. */ +#define SLJIT_FAST_CALL 37 /* Default C calling convention. */ -#define SLJIT_CALL 36 +#define SLJIT_CALL 38 /* Called function must be compiled by SLJIT. See SLJIT_ENTER_REG_ARG option. */ -#define SLJIT_CALL_REG_ARG 37 +#define SLJIT_CALL_REG_ARG 39 /* The target can be changed during runtime (see: sljit_set_jump_addr). */ #define SLJIT_REWRITABLE_JUMP 0x1000 @@ -1497,19 +1690,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_s32 dst, sljit_sw dstw, sljit_s32 type); -/* Emit a conditional mov instruction which moves source to destination, - if the condition is satisfied. Unlike other arithmetic operations this - instruction does not support memory access. +/* Emit a conditional select instruction which moves src1 to dst_reg, + if the condition is satisfied, or src2_reg to dst_reg otherwise. type must be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL - type can be combined (or'ed) with SLJIT_32 - dst_reg must be a valid register - src must be a valid register or immediate (SLJIT_IMM) + type can be combined (or'ed) with SLJIT_32 to move 32 bit + register values instead of word sized ones + dst_reg and src2_reg must be valid registers + src1 must be valid operand + + Note: if src1 is a memory operand, its value + might be loaded even if the condition is false. Flags: - (does not modify flags) */ -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw); + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg); + +/* Emit a conditional floating point select instruction which moves + src1 to dst_reg, if the condition is satisfied, or src2_reg to + dst_reg otherwise. + + type must be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL + type can be combined (or'ed) with SLJIT_32 to move 32 bit + floating point values instead of 64 bit ones + dst_freg and src2_freg must be valid floating point registers + src1 must be valid operand + + Note: if src1 is a memory operand, its value + might be loaded even if the condition is false. + + Flags: - (does not modify flags) */ +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg); /* The following flags are used by sljit_emit_mem(), sljit_emit_mem_update(), sljit_emit_fmem(), and sljit_emit_fmem_update(). */ @@ -1524,9 +1740,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil /* Load or stora data from an unaligned (byte aligned) address. */ #define SLJIT_MEM_UNALIGNED 0x000400 /* Load or stora data from a 16 bit aligned address. */ -#define SLJIT_MEM_UNALIGNED_16 0x000800 +#define SLJIT_MEM_ALIGNED_16 0x000800 /* Load or stora data from a 32 bit aligned address. */ -#define SLJIT_MEM_UNALIGNED_32 0x001000 +#define SLJIT_MEM_ALIGNED_32 0x001000 /* The following flags are used by sljit_emit_mem_update(), and sljit_emit_fmem_update(). */ @@ -1544,8 +1760,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil /* The sljit_emit_mem emits instructions for various memory operations: - When SLJIT_MEM_UNALIGNED / SLJIT_MEM_UNALIGNED_16 / - SLJIT_MEM_UNALIGNED_32 is set in type argument: + When SLJIT_MEM_UNALIGNED / SLJIT_MEM_ALIGNED_16 / + SLJIT_MEM_ALIGNED_32 is set in type argument: Emit instructions for unaligned memory loads or stores. When SLJIT_UNALIGNED is not defined, the only way to access unaligned memory data is using sljit_emit_mem. Otherwise all operations (e.g. @@ -1560,8 +1776,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil location specified by the mem/memw arguments, and the end address of this operation is the starting address of the data transfer between the second register and memory. The type argument must - be SLJIT_MOV. The SLJIT_MEM_UNALIGNED* options are allowed for - this operation. + be SLJIT_MOV. The SLJIT_MEM_UNALIGNED / SLJIT_MEM_ALIGNED_* + options are allowed for this operation. type must be between SLJIT_MOV and SLJIT_MOV_P and can be combined (or'ed) with SLJIT_MEM_* flags @@ -1625,6 +1841,286 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler sljit_s32 freg, sljit_s32 mem, sljit_sw memw); +/* The following options are used by several simd operations. */ + +/* Load data into a simd register, this is the default */ +#define SLJIT_SIMD_LOAD 0x000000 +/* Store data from a simd register */ +#define SLJIT_SIMD_STORE 0x000001 +/* The simd register contains floating point values */ +#define SLJIT_SIMD_FLOAT 0x000400 +/* Tests whether the operation is available */ +#define SLJIT_SIMD_TEST 0x000800 +/* Move data to/from a 64 bit (8 byte) long SIMD register */ +#define SLJIT_SIMD_REG_64 (3 << 12) +/* Move data to/from a 128 bit (16 byte) long SIMD register */ +#define SLJIT_SIMD_REG_128 (4 << 12) +/* Move data to/from a 256 bit (32 byte) long SIMD register */ +#define SLJIT_SIMD_REG_256 (5 << 12) +/* Move data to/from a 512 bit (64 byte) long SIMD register */ +#define SLJIT_SIMD_REG_512 (6 << 12) +/* Element size is 8 bit long (this is the default), usually cannot be combined with SLJIT_SIMD_FLOAT */ +#define SLJIT_SIMD_ELEM_8 (0 << 18) +/* Element size is 16 bit long, usually cannot be combined with SLJIT_SIMD_FLOAT */ +#define SLJIT_SIMD_ELEM_16 (1 << 18) +/* Element size is 32 bit long */ +#define SLJIT_SIMD_ELEM_32 (2 << 18) +/* Element size is 64 bit long */ +#define SLJIT_SIMD_ELEM_64 (3 << 18) +/* Element size is 128 bit long */ +#define SLJIT_SIMD_ELEM_128 (4 << 18) +/* Element size is 256 bit long */ +#define SLJIT_SIMD_ELEM_256 (5 << 18) + +/* The following options are used by sljit_emit_simd_mov(). */ + +/* Memory address is unaligned (this is the default) */ +#define SLJIT_SIMD_MEM_UNALIGNED (0 << 24) +/* Memory address is 16 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_16 (1 << 24) +/* Memory address is 32 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_32 (2 << 24) +/* Memory address is 64 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_64 (3 << 24) +/* Memory address is 128 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_128 (4 << 24) +/* Memory address is 256 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_256 (5 << 24) +/* Memory address is 512 bit aligned */ +#define SLJIT_SIMD_MEM_ALIGNED_512 (6 << 24) + +/* Moves data between a simd register and memory. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* and + SLJIT_SIMD_MEM_* options + freg is the source or destination simd register + of the operation + srcdst must be a memory operand or a simd register + + Note: + The alignment and element size must be + less or equal than simd register size. + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw); + +/* Replicates a scalar value to all lanes of a simd + register. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* options + except SLJIT_SIMD_STORE. + freg is the destination simd register of the operation + src is the value which is replicated + + Note: + The src == SLJIT_IMM and srcw == 0 can be used to + clear a register even when SLJIT_SIMD_FLOAT is set. + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw); + +/* The following options are used by sljit_emit_simd_lane_mov(). */ + +/* Clear all bits of the simd register before loading the lane. */ +#define SLJIT_SIMD_LANE_ZERO 0x000002 +/* Sign extend the integer value stored from the lane. */ +#define SLJIT_SIMD_LANE_SIGNED 0x000004 + +/* Moves data between a simd register lane and a register or + memory. If the srcdst argument is a register, it must be + a floating point register when SLJIT_SIMD_FLOAT is specified, + or a general purpose register otherwise. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* options + Further options: + SLJIT_32 - when SLJIT_SIMD_FLOAT is not set + SLJIT_SIMD_LANE_SIGNED - when SLJIT_SIMD_STORE + is set and SLJIT_SIMD_FLOAT is not set + SLJIT_SIMD_LANE_ZERO - when SLJIT_SIMD_LOAD + is specified + freg is the source or destination simd register + of the operation + lane_index is the index of the lane + srcdst is the destination operand for loads, and + source operand for stores + + Note: + The elem size must be lower than register size. + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw); + +/* Replicates a scalar value from a lane to all lanes + of a simd register. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* options + except SLJIT_SIMD_STORE. + freg is the destination simd register of the operation + src is the simd register which lane is replicated + src_lane_index is the lane index of the src register + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index); + +/* The following options are used by sljit_emit_simd_load_extend(). */ + +/* Sign extend the integer elements */ +#define SLJIT_SIMD_EXTEND_SIGNED 0x000002 +/* Extend data to 16 bit */ +#define SLJIT_SIMD_EXTEND_16 (1 << 24) +/* Extend data to 32 bit */ +#define SLJIT_SIMD_EXTEND_32 (2 << 24) +/* Extend data to 64 bit */ +#define SLJIT_SIMD_EXTEND_64 (3 << 24) + +/* Extend elements and stores them in a simd register. + The extension operation increases the size of the + elements (e.g. from 16 bit to 64 bit). For integer + values, the extension can be signed or unsigned. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_*, and + SLJIT_SIMD_EXTEND_* options except SLJIT_SIMD_STORE + freg is the destination simd register of the operation + src must be a memory operand or a simd register. + In the latter case, the source elements are stored + in the lower half of the register. + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw); + +/* Extract the highest bit (usually the sign bit) from + each elements of a vector. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* and SLJIT_32 + options except SLJIT_SIMD_LOAD + freg is the source simd register of the operation + dst is the destination operand + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw); + +/* The following options are used by sljit_emit_simd_op2(). */ + +/* Binary 'and' operation */ +#define SLJIT_SIMD_OP2_AND 0x000001 +/* Binary 'or' operation */ +#define SLJIT_SIMD_OP2_OR 0x000002 +/* Binary 'xor' operation */ +#define SLJIT_SIMD_OP2_XOR 0x000003 + +/* Perform simd operations using simd registers. + + If the operation is not supported, it returns with + SLJIT_ERR_UNSUPPORTED. If SLJIT_SIMD_TEST is passed, + it does not emit any instructions. + + type must be a combination of SLJIT_SIMD_* and SLJIT_SIMD_OP2_ + options except SLJIT_SIMD_LOAD and SLJIT_SIMD_STORE + dst_freg is the destination register of the operation + src1_freg is the first source register of the operation + src1_freg is the second source register of the operation + + Flags: - (does not modify flags) */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg); + +/* The sljit_emit_atomic_load and sljit_emit_atomic_store operation pair + can perform an atomic read-modify-write operation. First, an unsigned + value must be loaded from memory using sljit_emit_atomic_load. Then, + the updated value must be written back to the same memory location by + sljit_emit_atomic_store. A thread can only perform a single atomic + operation at a time. + + Note: atomic operations are experimental, and not implemented + for all cpus. + + The following conditions must be satisfied, or the operation + is undefined: + - the address provided in mem_reg must be divisible by the size of + the value (only naturally aligned updates are supported) + - no memory writes are allowed between the load and store operations + regardless of its target address (currently read operations are + allowed, but this might change in the future) + - the memory operation (op) and the base address (stored in mem_reg) + passed to the load/store operations must be the same (the mem_reg + can be a different register, only its value must be the same) + - an store must always follow a load for the same transaction. + + op must be between SLJIT_MOV and SLJIT_MOV_P, excluding all + signed loads such as SLJIT_MOV32_S16 + dst_reg is the register where the data will be loaded into + mem_reg is the base address of the memory load (it cannot be + SLJIT_SP or a virtual register on x86-32) + + Flags: - (does not modify flags) */ +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg); + +/* The sljit_emit_atomic_load and sljit_emit_atomic_store operations + allows performing an atomic read-modify-write operation. See the + description of sljit_emit_atomic_load. + + op must be between SLJIT_MOV and SLJIT_MOV_P, excluding all signed + loads such as SLJIT_MOV32_S16 + src_reg is the register which value is stored into the memory + mem_reg is the base address of the memory store (it cannot be + SLJIT_SP or a virtual register on x86-32) + temp_reg is a not preserved scratch register, which must be + initialized with the value loaded into the dst_reg during the + corresponding sljit_emit_atomic_load operation, or the operation + is undefined + + Flags: ATOMIC_STORED is set if the operation is successful, + otherwise the memory remains unchanged. */ +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg); + /* Copies the base address of SLJIT_SP + offset to dst. The offset can represent the starting address of a value in the local data (stack). The offset is not limited by the local data limits, it can be any value. @@ -1665,30 +2161,39 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta /* CPU specific functions */ /* --------------------------------------------------------------------- */ -/* The following function is a helper function for sljit_emit_op_custom. - It returns with the real machine register index ( >=0 ) of any SLJIT_R, - SLJIT_S and SLJIT_SP registers. +/* Types for sljit_get_register_index */ - Note: it returns with -1 for virtual registers (only on x86-32). */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg); +/* General purpose (integer) registers. */ +#define SLJIT_GP_REGISTER 0 +/* Floating point registers. */ +#define SLJIT_FLOAT_REGISTER 1 /* The following function is a helper function for sljit_emit_op_custom. - It returns with the real machine register ( >= 0 ) index of any SLJIT_FR, - and SLJIT_FS register. + It returns with the real machine register index ( >=0 ) of any registers. - Note: the index is always an even number on ARM-32, MIPS. */ + When type is SLJIT_GP_REGISTER: + reg must be an SLJIT_R(i), SLJIT_S(i), or SLJIT_SP register -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg); + When type is SLJIT_FLOAT_REGISTER: + reg must be an SLJIT_FR(i) or SLJIT_FS(i) register + + When type is SLJIT_SIMD_REG_64 / 128 / 256 / 512 : + reg must be an SLJIT_FR(i) or SLJIT_FS(i) register + + Note: it returns with -1 for unknown registers, such as virtual + registers on x86-32 or unsupported simd registers. */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg); /* Any instruction can be inserted into the instruction stream by sljit_emit_op_custom. It has a similar purpose as inline assembly. The size parameter must match to the instruction size of the target architecture: - x86: 0 < size <= 15. The instruction argument can be byte aligned. + x86: 0 < size <= 15, the instruction argument can be byte aligned. Thumb2: if size == 2, the instruction argument must be 2 byte aligned. if size == 4, the instruction argument must be 4 byte aligned. + s390x: size can be 2, 4, or 6, the instruction argument can be byte aligned. Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -1725,7 +2230,8 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *com to know the type of the code generator. */ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void); -/* Portable helper function to get an offset of a member. */ +/* Portable helper function to get an offset of a member. + Same as offsetof() macro defined in stddef.h */ #define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10) #if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_32.c index 54b8ade0636..d44616d800f 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_32.c @@ -34,13 +34,16 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) return "ARMv7" SLJIT_CPUINFO ARM_ABI_INFO; -#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - return "ARMv5" SLJIT_CPUINFO ARM_ABI_INFO; +#elif (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + return "ARMv6" SLJIT_CPUINFO ARM_ABI_INFO; #else #error "Internal error: Unknown ARM architecture" #endif } +/* Length of an instruction word. */ +typedef sljit_u32 sljit_ins; + /* Last register + 1. */ #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) @@ -55,27 +58,39 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) #define CONST_POOL_EMPTY 0xffffffff #define ALIGN_INSTRUCTION(ptr) \ - (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1)) + (sljit_ins*)(((sljit_ins)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_ins)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_ins)) - 1)) #define MAX_DIFFERENCE(max_diff) \ - (((max_diff) / (sljit_s32)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) + (((max_diff) / (sljit_s32)sizeof(sljit_ins)) - (CONST_POOL_ALIGNMENT - 1)) /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15 }; -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { - 0, 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, 6, 7 +static const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = { + 0, + 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, + 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6 }; -#define RM(rm) ((sljit_uw)reg_map[rm]) -#define RM8(rm) ((sljit_uw)reg_map[rm] << 8) -#define RD(rd) ((sljit_uw)reg_map[rd] << 12) -#define RN(rn) ((sljit_uw)reg_map[rn] << 16) +static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = { + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1 +}; -#define VM(rm) ((sljit_uw)freg_map[rm]) -#define VD(rd) ((sljit_uw)freg_map[rd] << 12) -#define VN(rn) ((sljit_uw)freg_map[rn] << 16) +#define RM(rm) ((sljit_ins)reg_map[rm]) +#define RM8(rm) ((sljit_ins)reg_map[rm] << 8) +#define RD(rd) ((sljit_ins)reg_map[rd] << 12) +#define RN(rn) ((sljit_ins)reg_map[rn] << 16) + +#define VM(vm) (((sljit_ins)freg_map[vm]) | ((sljit_ins)freg_ebit_map[vm] << 5)) +#define VD(vd) (((sljit_ins)freg_map[vd] << 12) | ((sljit_ins)freg_ebit_map[vd] << 22)) +#define VN(vn) (((sljit_ins)freg_map[vn] << 16) | ((sljit_ins)freg_ebit_map[vn] << 7)) /* --------------------------------------------------------------------- */ /* Instrucion forms */ @@ -92,16 +107,19 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define AND 0xe0000000 #define B 0xea000000 #define BIC 0xe1c00000 +#define BKPT 0xe1200070 #define BL 0xeb000000 #define BLX 0xe12fff30 #define BX 0xe12fff10 #define CLZ 0xe16f0f10 #define CMN 0xe1600000 #define CMP 0xe1400000 -#define BKPT 0xe1200070 #define EOR 0xe0200000 #define LDR 0xe5100000 #define LDR_POST 0xe4100000 +#define LDREX 0xe1900f9f +#define LDREXB 0xe1d00f9f +#define LDREXH 0xe1f00f9f #define MOV 0xe1a00000 #define MUL 0xe0000090 #define MVN 0xe1e00000 @@ -109,50 +127,89 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define ORR 0xe1800000 #define PUSH 0xe92d0000 #define POP 0xe8bd0000 -#define RBIT 0xe6ff0f30 +#define REV 0xe6bf0f30 +#define REV16 0xe6bf0fb0 #define RSB 0xe0600000 #define RSC 0xe0e00000 #define SBC 0xe0c00000 #define SMULL 0xe0c00090 #define STR 0xe5000000 +#define STREX 0xe1800f90 +#define STREXB 0xe1c00f90 +#define STREXH 0xe1e00f90 #define SUB 0xe0400000 +#define SXTB 0xe6af0070 +#define SXTH 0xe6bf0070 #define TST 0xe1000000 #define UMULL 0xe0800090 +#define UXTB 0xe6ef0070 +#define UXTH 0xe6ff0070 #define VABS_F32 0xeeb00ac0 #define VADD_F32 0xee300a00 +#define VAND 0xf2000110 #define VCMP_F32 0xeeb40a40 #define VCVT_F32_S32 0xeeb80ac0 +#define VCVT_F32_U32 0xeeb80a40 #define VCVT_F64_F32 0xeeb70ac0 #define VCVT_S32_F32 0xeebd0ac0 #define VDIV_F32 0xee800a00 +#define VDUP 0xee800b10 +#define VDUP_s 0xf3b00c00 +#define VEOR 0xf3000110 +#define VLD1 0xf4200000 +#define VLD1_r 0xf4a00c00 +#define VLD1_s 0xf4a00000 #define VLDR_F32 0xed100a00 #define VMOV_F32 0xeeb00a40 #define VMOV 0xee000a10 #define VMOV2 0xec400a10 +#define VMOV_i 0xf2800010 +#define VMOV_s 0xee000b10 +#define VMOVN 0xf3b20200 #define VMRS 0xeef1fa10 #define VMUL_F32 0xee200a00 #define VNEG_F32 0xeeb10a40 +#define VORR 0xf2200110 #define VPOP 0xecbd0b00 #define VPUSH 0xed2d0b00 +#define VSHLL 0xf2800a10 +#define VSHR 0xf2800010 +#define VSRA 0xf2800110 +#define VST1 0xf4000000 +#define VST1_s 0xf4800000 #define VSTR_F32 0xed000a00 #define VSUB_F32 0xee300a40 #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Arm v7 specific instructions. */ -#define MOVW 0xe3000000 #define MOVT 0xe3400000 -#define SXTB 0xe6af0070 -#define SXTH 0xe6bf0070 -#define UXTB 0xe6ef0070 -#define UXTH 0xe6ff0070 +#define MOVW 0xe3000000 +#define RBIT 0xe6ff0f30 #endif -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + +static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32) +{ + if (compiler->scratches == -1) + return 0; + + if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) + fr -= SLJIT_F64_SECOND(0); + + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) + || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); +} + +#endif /* SLJIT_ARGUMENT_CHECKS */ + +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) static sljit_s32 push_cpool(struct sljit_compiler *compiler) { /* Pushing the constant pool into the instruction stream. */ - sljit_uw* inst; + sljit_ins* inst; sljit_uw* cpool_ptr; sljit_uw* cpool_end; sljit_s32 i; @@ -162,13 +219,13 @@ static sljit_s32 push_cpool(struct sljit_compiler *compiler) compiler->last_label->size += compiler->cpool_fill + (CONST_POOL_ALIGNMENT - 1) + 1; SLJIT_ASSERT(compiler->cpool_fill > 0 && compiler->cpool_fill <= CPOOL_SIZE); - inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + inst = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!inst); compiler->size++; *inst = 0xff000000 | compiler->cpool_fill; for (i = 0; i < CONST_POOL_ALIGNMENT - 1; i++) { - inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + inst = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!inst); compiler->size++; *inst = 0; @@ -177,7 +234,7 @@ static sljit_s32 push_cpool(struct sljit_compiler *compiler) cpool_ptr = compiler->cpool; cpool_end = cpool_ptr + compiler->cpool_fill; while (cpool_ptr < cpool_end) { - inst = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + inst = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!inst); compiler->size++; *inst = *cpool_ptr++; @@ -187,23 +244,23 @@ static sljit_s32 push_cpool(struct sljit_compiler *compiler) return SLJIT_SUCCESS; } -static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins inst) { - sljit_uw* ptr; + sljit_ins* ptr; if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092))) FAIL_IF(push_cpool(compiler)); - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); compiler->size++; *ptr = inst; return SLJIT_SUCCESS; } -static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_ins inst, sljit_uw literal) { - sljit_uw* ptr; + sljit_ins* ptr; sljit_uw cpool_index = CPOOL_SIZE; sljit_uw* cpool_ptr; sljit_uw* cpool_end; @@ -239,7 +296,7 @@ static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_u } SLJIT_ASSERT((inst & 0xfff) == 0); - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); compiler->size++; *ptr = inst | cpool_index; @@ -251,14 +308,15 @@ static sljit_s32 push_inst_with_literal(struct sljit_compiler *compiler, sljit_u return SLJIT_SUCCESS; } -static sljit_s32 push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +static sljit_s32 push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_ins inst, sljit_uw literal) { - sljit_uw* ptr; + sljit_ins* ptr; + if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE)) FAIL_IF(push_cpool(compiler)); SLJIT_ASSERT(compiler->cpool_fill < CPOOL_SIZE && (inst & 0xfff) == 0); - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); compiler->size++; *ptr = inst | compiler->cpool_fill; @@ -305,7 +363,7 @@ static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ while (last_pc_patch < code_ptr) { /* Data transfer instruction with Rn == r15. */ - if ((*last_pc_patch & 0x0c0f0000) == 0x040f0000) { + if ((*last_pc_patch & 0x0e0f0000) == 0x040f0000) { diff = (sljit_uw)(const_pool - last_pc_patch); ind = (*last_pc_patch) & 0xfff; @@ -395,11 +453,11 @@ static sljit_s32 resolve_const_pool_index(struct sljit_compiler *compiler, struc #else -static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_uw inst) +static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins inst) { - sljit_uw* ptr; + sljit_ins* ptr; - ptr = (sljit_uw*)ensure_buf(compiler, sizeof(sljit_uw)); + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); compiler->size++; *ptr = inst; @@ -421,7 +479,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw if (jump->flags & SLJIT_REWRITABLE_JUMP) return 0; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (jump->flags & IS_BL) code_ptr--; @@ -449,7 +507,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw jump->flags |= PATCH_B; } } -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ if (jump->flags & JUMP_ADDR) diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr - executable_offset); else { @@ -467,16 +525,16 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw jump->flags |= PATCH_B; return 1; } -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ return 0; } static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw executable_offset, sljit_uw new_addr, sljit_s32 flush_cache) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_uw *ptr = (sljit_uw *)jump_ptr; - sljit_uw *inst = (sljit_uw *)ptr[0]; - sljit_uw mov_pc = ptr[1]; +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + sljit_ins *ptr = (sljit_ins*)jump_ptr; + sljit_ins *inst = (sljit_ins*)ptr[0]; + sljit_ins mov_pc = ptr[1]; sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC); sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2); @@ -491,7 +549,7 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff); if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } else { @@ -502,7 +560,7 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut inst[1] = NOP; if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } } @@ -521,14 +579,14 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut if (!bl) { if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } else { inst[1] = BLX | RM(TMP_REG1); if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } } @@ -544,8 +602,8 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1); } } -#else - sljit_uw *inst = (sljit_uw*)jump_ptr; +#else /* !SLJIT_CONFIG_ARM_V6 */ + sljit_ins *inst = (sljit_ins*)jump_ptr; SLJIT_UNUSED_ARG(executable_offset); @@ -560,10 +618,10 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ } static sljit_uw get_imm(sljit_uw imm); @@ -572,9 +630,9 @@ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, s static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_offset, sljit_uw new_constant, sljit_s32 flush_cache) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_uw *ptr = (sljit_uw*)addr; - sljit_uw *inst = (sljit_uw*)ptr[0]; +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + sljit_ins *ptr = (sljit_ins*)addr; + sljit_ins *inst = (sljit_ins*)ptr[0]; sljit_uw ldr_literal = ptr[1]; sljit_uw src2; @@ -590,7 +648,7 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } return; @@ -606,7 +664,7 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } return; @@ -626,7 +684,7 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 1); } } @@ -640,8 +698,8 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1); } -#else - sljit_uw *inst = (sljit_uw*)addr; +#else /* !SLJIT_CONFIG_ARM_V6 */ + sljit_ins *inst = (sljit_ins*)addr; SLJIT_UNUSED_ARG(executable_offset); @@ -656,30 +714,30 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off if (flush_cache) { SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1); - inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); + inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset); SLJIT_CACHE_FLUSH(inst, inst + 2); } -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ } SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler) { struct sljit_memory_fragment *buf; - sljit_uw *code; - sljit_uw *code_ptr; - sljit_uw *buf_ptr; - sljit_uw *buf_end; + sljit_ins *code; + sljit_ins *code_ptr; + sljit_ins *buf_ptr; + sljit_ins *buf_end; sljit_uw size; sljit_uw word_count; sljit_uw next_addr; sljit_sw executable_offset; sljit_uw addr; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) sljit_uw cpool_size; sljit_uw cpool_skip_alignment; sljit_uw cpool_current_index; - sljit_uw *cpool_start_address; - sljit_uw *last_pc_patch; + sljit_ins *cpool_start_address; + sljit_ins *last_pc_patch; struct future_patch *first_patch; #endif @@ -693,25 +751,25 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil reverse_buf(compiler); /* Second code generation pass. */ -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) size = compiler->size + (compiler->patches << 1); if (compiler->cpool_fill > 0) size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ size = compiler->size; -#endif - code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw), compiler->exec_allocator_data); +#endif /* SLJIT_CONFIG_ARM_V6 */ + code = (sljit_ins*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_ins), compiler->exec_allocator_data); PTR_FAIL_WITH_EXEC_IF(code); buf = compiler->buf; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) cpool_size = 0; cpool_skip_alignment = 0; cpool_current_index = 0; cpool_start_address = NULL; first_patch = NULL; last_pc_patch = code; -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ code_ptr = code; word_count = 0; @@ -729,11 +787,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } do { - buf_ptr = (sljit_uw*)buf->memory; + buf_ptr = (sljit_ins*)buf->memory; buf_end = buf_ptr + (buf->used_size >> 2); do { word_count++; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (cpool_size > 0) { if (cpool_skip_alignment > 0) { buf_ptr++; @@ -761,7 +819,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } } else if ((*buf_ptr & 0xff000000) != PUSH_POOL) { -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ *code_ptr = *buf_ptr++; if (next_addr == word_count) { SLJIT_ASSERT(!label || label->size >= word_count); @@ -771,15 +829,15 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* These structures are ordered by their address. */ if (jump && jump->addr == word_count) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (detect_jump_type(jump, code_ptr, code, executable_offset)) code_ptr--; jump->addr = (sljit_uw)code_ptr; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ jump->addr = (sljit_uw)(code_ptr - 2); if (detect_jump_type(jump, code_ptr, code, executable_offset)) code_ptr -= 2; -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ jump = jump->next; } if (label && label->size == word_count) { @@ -789,11 +847,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = label->next; } if (const_ && const_->addr == word_count) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) const_->addr = (sljit_uw)code_ptr; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ const_->addr = (sljit_uw)(code_ptr - 1); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ const_ = const_->next; } if (put_label && put_label->addr == word_count) { @@ -804,9 +862,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil next_addr = compute_next_addr(label, jump, const_, put_label); } code_ptr++; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - } - else { +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + } else { /* Fortunately, no need to shift. */ cpool_size = *buf_ptr++ & ~PUSH_POOL; SLJIT_ASSERT(cpool_size > 0); @@ -814,14 +871,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, cpool_size); if (cpool_current_index > 0) { /* Unconditional branch. */ - *code_ptr = B | (((sljit_uw)(cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL); - code_ptr = (sljit_uw*)(cpool_start_address + cpool_current_index); + *code_ptr = B | (((sljit_ins)(cpool_start_address - code_ptr) + cpool_current_index - 2) & ~PUSH_POOL); + code_ptr = (sljit_ins*)(cpool_start_address + cpool_current_index); } cpool_skip_alignment = CONST_POOL_ALIGNMENT - 1; cpool_current_index = 0; last_pc_patch = code_ptr; } -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ } while (buf_ptr < buf_end); buf = buf->next; } while (buf); @@ -831,13 +888,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!const_); SLJIT_ASSERT(!put_label); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) SLJIT_ASSERT(cpool_size == 0); if (compiler->cpool_fill > 0) { cpool_start_address = ALIGN_INSTRUCTION(code_ptr); cpool_current_index = patch_pc_relative_loads(last_pc_patch, code_ptr, cpool_start_address, compiler->cpool_fill); if (cpool_current_index > 0) - code_ptr = (sljit_uw*)(cpool_start_address + cpool_current_index); + code_ptr = (sljit_ins*)(cpool_start_address + cpool_current_index); buf_ptr = compiler->cpool; buf_end = buf_ptr + compiler->cpool_fill; @@ -857,7 +914,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = compiler->jumps; while (jump) { - buf_ptr = (sljit_uw *)jump->addr; + buf_ptr = (sljit_ins*)jump->addr; if (jump->flags & PATCH_B) { addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset); @@ -872,18 +929,17 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } } else if (jump->flags & SLJIT_REWRITABLE_JUMP) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) jump->addr = (sljit_uw)code_ptr; - code_ptr[0] = (sljit_uw)buf_ptr; + code_ptr[0] = (sljit_ins)buf_ptr; code_ptr[1] = *buf_ptr; inline_set_jump_addr((sljit_uw)code_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); code_ptr += 2; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); -#endif - } - else { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#endif /* SLJIT_CONFIG_ARM_V6 */ + } else { +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (jump->flags & IS_BL) buf_ptr--; if (*buf_ptr & (1 << 23)) @@ -891,20 +947,20 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil else buf_ptr += 1; *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ inline_set_jump_addr((sljit_uw)buf_ptr, executable_offset, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ } jump = jump->next; } -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) const_ = compiler->consts; while (const_) { - buf_ptr = (sljit_uw*)const_->addr; + buf_ptr = (sljit_ins*)const_->addr; const_->addr = (sljit_uw)code_ptr; - code_ptr[0] = (sljit_uw)buf_ptr; + code_ptr[0] = (sljit_ins)buf_ptr; code_ptr[1] = *buf_ptr; if (*buf_ptr & (1 << 23)) buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2; @@ -916,21 +972,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil const_ = const_->next; } -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ put_label = compiler->put_labels; while (put_label) { addr = put_label->label->addr; - buf_ptr = (sljit_uw*)put_label->addr; + buf_ptr = (sljit_ins*)put_label->addr; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) SLJIT_ASSERT((buf_ptr[0] & 0xffff0000) == 0xe59f0000); buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ SLJIT_ASSERT((buf_ptr[-1] & 0xfff00000) == MOVW && (buf_ptr[0] & 0xfff00000) == MOVT); buf_ptr[-1] |= ((addr << 4) & 0xf0000) | (addr & 0xfff); buf_ptr[0] |= ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ put_label = put_label->next; } @@ -940,8 +996,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil compiler->executable_offset = executable_offset; compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_uw); - code = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); - code_ptr = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); + code = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); + code_ptr = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); SLJIT_CACHE_FLUSH(code, code_ptr); SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1); @@ -952,26 +1008,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) { switch (feature_type) { case SLJIT_HAS_FPU: + case SLJIT_HAS_F64_AS_F32_PAIR: #ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; + return (SLJIT_IS_FPU_AVAILABLE) != 0; #else /* Available by default. */ return 1; -#endif +#endif /* SLJIT_IS_FPU_AVAILABLE */ + case SLJIT_HAS_SIMD: +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + return 0; +#else +#ifdef SLJIT_IS_FPU_AVAILABLE + return (SLJIT_IS_FPU_AVAILABLE) != 0; +#else + /* Available by default. */ + return 1; +#endif /* SLJIT_IS_FPU_AVAILABLE */ +#endif /* SLJIT_CONFIG_ARM_V6 */ + case SLJIT_SIMD_REGS_ARE_PAIRS: case SLJIT_HAS_CLZ: case SLJIT_HAS_ROT: case SLJIT_HAS_CMOV: -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - case SLJIT_HAS_CTZ: + case SLJIT_HAS_REV: case SLJIT_HAS_PREFETCH: -#endif + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: + case SLJIT_HAS_ATOMIC: return 1; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) case SLJIT_HAS_CTZ: +#if defined(SLJIT_CONFIG_ARM_V6) && SLJIT_CONFIG_ARM_V6 return 2; -#endif +#else + return 1; +#endif /* SLJIT_CONFIG_ARM_V6 */ default: return 0; @@ -991,17 +1063,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) #define LOAD_DATA 0x08 /* Flag bits for emit_op. */ -#define ALLOW_IMM 0x10 -#define ALLOW_INV_IMM 0x20 -#define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM) -#define ALLOW_NEG_IMM 0x40 +#define ALLOW_IMM 0x10 +#define ALLOW_INV_IMM 0x20 +#define ALLOW_ANY_IMM (ALLOW_IMM | ALLOW_INV_IMM) +#define ALLOW_NEG_IMM 0x40 +#define ALLOW_DOUBLE_IMM 0x80 /* s/l - store/load (1 bit) u/s - signed/unsigned (1 bit) w/b/h/N - word/byte/half/NOT allowed (2 bit) Storing signed and unsigned values are the same operations. */ -static const sljit_uw data_transfer_insts[16] = { +static const sljit_ins data_transfer_insts[16] = { /* s u w */ 0xe5000000 /* str */, /* s u b */ 0xe5400000 /* strb */, /* s u h */ 0xe10000b0 /* strh */, @@ -1022,7 +1095,7 @@ static const sljit_uw data_transfer_insts[16] = { }; #define EMIT_DATA_TRANSFER(type, add, target_reg, base_reg, arg) \ - (data_transfer_insts[(type) & 0xf] | ((add) << 23) | RD(target_reg) | RN(base_reg) | (sljit_uw)(arg)) + (data_transfer_insts[(type) & 0xf] | ((add) << 23) | RD(target_reg) | RN(base_reg) | (sljit_ins)(arg)) /* Normal ldr/str instruction. Type2: ldrsb, ldrh, ldrsh */ @@ -1032,7 +1105,7 @@ static const sljit_uw data_transfer_insts[16] = { (((imm) & 0xf) | (((imm) & 0xf0) << 4) | (1 << 22)) #define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \ - ((sljit_uw)(opcode) | (sljit_uw)(mode) | VD(dst) | VM(src1) | VN(src2)) + ((sljit_ins)(opcode) | (sljit_ins)(mode) | VD(dst) | VM(src1) | VN(src2)) /* Flags for emit_op: */ /* Arguments are swapped. */ @@ -1104,12 +1177,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) { - FAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); + FAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_ins)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); } else { if (fsaveds > 0) - FAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); + FAIL_IF(push_inst(compiler, VPUSH | VD(SLJIT_FS0) | ((sljit_ins)fsaveds << 1))); if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) - FAIL_IF(push_inst(compiler, VPUSH | VD(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); + FAIL_IF(push_inst(compiler, VPUSH | VD(fscratches) | ((sljit_ins)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); } } @@ -1138,7 +1211,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi FAIL_IF(push_inst(compiler, VMOV2 | (offset << 10) | ((offset + sizeof(sljit_sw)) << 14) | float_arg_count)); else FAIL_IF(push_inst(compiler, VLDR_F32 | 0x800100 | RN(SLJIT_SP) - | (float_arg_count << 12) | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2))); + | (float_arg_count << 12) | ((offset + (sljit_ins)size - 4 * sizeof(sljit_sw)) >> 2))); float_arg_count++; offset += sizeof(sljit_f64) - sizeof(sljit_sw); break; @@ -1147,7 +1220,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi FAIL_IF(push_inst(compiler, VMOV | (float_arg_count << 16) | (offset << 10))); else FAIL_IF(push_inst(compiler, VLDR_F32 | 0x800000 | RN(SLJIT_SP) - | (float_arg_count << 12) | ((offset + (sljit_uw)size - 4 * sizeof(sljit_sw)) >> 2))); + | (float_arg_count << 12) | ((offset + (sljit_ins)size - 4 * sizeof(sljit_sw)) >> 2))); float_arg_count++; break; default: @@ -1164,7 +1237,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (offset < 4 * sizeof(sljit_sw)) FAIL_IF(push_inst(compiler, MOV | RD(tmp) | (offset >> 2))); else - FAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(tmp) | (offset + (sljit_uw)size - 4 * sizeof(sljit_sw)))); + FAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(tmp) | (offset + (sljit_ins)size - 4 * sizeof(sljit_sw)))); break; } @@ -1217,7 +1290,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #endif if (local_size > 0) - FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size)); + FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM | ALLOW_DOUBLE_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size)); return SLJIT_SUCCESS; } @@ -1234,6 +1307,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); + /* Doubles are saved, so alignment is unaffected. */ if ((size & SSIZE_OF(sw)) != 0 && (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)) size += SSIZE_OF(sw); @@ -1245,13 +1319,8 @@ static sljit_s32 emit_add_sp(struct sljit_compiler *compiler, sljit_uw imm) { sljit_uw imm2 = get_imm(imm); - if (imm2 == 0) { - imm2 = (imm & ~(sljit_uw)0x3ff) >> 10; - imm = (imm & 0x3ff) >> 2; - - FAIL_IF(push_inst(compiler, ADD | SRC2_IMM | RD(SLJIT_SP) | RN(SLJIT_SP) | 0xb00 | imm2)); - return push_inst(compiler, ADD | SRC2_IMM | RD(SLJIT_SP) | RN(SLJIT_SP) | 0xf00 | (imm & 0xff)); - } + if (imm2 == 0) + return emit_op(compiler, SLJIT_ADD, ALLOW_IMM | ALLOW_DOUBLE_IMM, SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, (sljit_sw)imm); return push_inst(compiler, ADD | RD(SLJIT_SP) | RN(SLJIT_SP) | imm2); } @@ -1274,12 +1343,12 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit FAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size)); if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) { - FAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); + FAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_ins)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); } else { if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) - FAIL_IF(push_inst(compiler, VPOP | VD(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); + FAIL_IF(push_inst(compiler, VPOP | VD(fscratches) | ((sljit_ins)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); if (fsaveds > 0) - FAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); + FAIL_IF(push_inst(compiler, VPOP | VD(SLJIT_FS0) | ((sljit_ins)fsaveds << 1))); } local_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1) & 0x7; @@ -1330,10 +1399,10 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit if (frame_size == 0) return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | 0x800008); if (frame_size > 2 * SSIZE_OF(sw)) - return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)(frame_size - (2 * SSIZE_OF(sw)))); + return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)(frame_size - (2 * SSIZE_OF(sw)))); } - FAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)local_size)); + FAIL_IF(push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)local_size)); tmp = 1; } else if (frame_size == 0) { frame_size = (restored_reg == TMP_REG2) ? SSIZE_OF(sw) : 2 * SSIZE_OF(sw); @@ -1349,7 +1418,7 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit local_size += SSIZE_OF(sw); if (frame_size > local_size) - FAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | (sljit_uw)(frame_size - local_size))); + FAIL_IF(push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | (sljit_ins)(frame_size - local_size))); else if (frame_size < local_size) FAIL_IF(emit_add_sp(compiler, (sljit_uw)(local_size - frame_size))); @@ -1361,11 +1430,11 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit if (restored_reg != TMP_REG2) frame_size -= SSIZE_OF(sw); - return push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)frame_size); + return push_inst(compiler, LDR | 0x800000 | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)frame_size); } tmp = (restored_reg == TMP_REG2) ? 0x800004 : 0x800008; - return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_uw)tmp); + return push_inst(compiler, LDR_POST | RN(SLJIT_SP) | RD(restored_reg) | (sljit_ins)tmp); } if (local_size > 0) @@ -1384,7 +1453,7 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit FAIL_IF(push_inst(compiler, POP | reg_list)); if (frame_size > 0) - return push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | ((sljit_uw)frame_size - sizeof(sljit_sw))); + return push_inst(compiler, SUB | RD(SLJIT_SP) | RN(SLJIT_SP) | (1 << 25) | ((sljit_ins)frame_size - sizeof(sljit_sw))); if (lr_dst != 0) return SLJIT_SUCCESS; @@ -1432,7 +1501,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl sljit_s32 is_masked; sljit_uw shift_type; - switch (GET_OPCODE(op)) { + switch (op) { case SLJIT_MOV: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); if (dst != src2) { @@ -1446,17 +1515,10 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl case SLJIT_MOV_U8: case SLJIT_MOV_S8: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); - if (flags & MOVE_REG_CONV) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (op == SLJIT_MOV_U8) - return push_inst(compiler, AND | RD(dst) | RN(src2) | SRC2_IMM | 0xff); - FAIL_IF(push_inst(compiler, MOV | RD(dst) | (24 << 7) | RM(src2))); - return push_inst(compiler, MOV | RD(dst) | (24 << 7) | (op == SLJIT_MOV_U8 ? 0x20 : 0x40) | RM(dst)); -#else + if (flags & MOVE_REG_CONV) return push_inst(compiler, (op == SLJIT_MOV_U8 ? UXTB : SXTB) | RD(dst) | RM(src2)); -#endif - } - else if (dst != src2) { + + if (dst != src2) { SLJIT_ASSERT(src2 & SRC2_IMM); return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2); } @@ -1465,26 +1527,15 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl case SLJIT_MOV_U16: case SLJIT_MOV_S16: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); - if (flags & MOVE_REG_CONV) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - FAIL_IF(push_inst(compiler, MOV | RD(dst) | (16 << 7) | RM(src2))); - return push_inst(compiler, MOV | RD(dst) | (16 << 7) | (op == SLJIT_MOV_U16 ? 0x20 : 0x40) | RM(dst)); -#else + if (flags & MOVE_REG_CONV) return push_inst(compiler, (op == SLJIT_MOV_U16 ? UXTH : SXTH) | RD(dst) | RM(src2)); -#endif - } - else if (dst != src2) { + + if (dst != src2) { SLJIT_ASSERT(src2 & SRC2_IMM); return push_inst(compiler, ((flags & INV_IMM) ? MVN : MOV) | RD(dst) | src2); } return SLJIT_SUCCESS; - case SLJIT_NOT: - if (src2 & SRC2_IMM) - return push_inst(compiler, ((flags & INV_IMM) ? MOV : MVN) | (flags & SET_FLAGS) | RD(dst) | src2); - - return push_inst(compiler, MVN | (flags & SET_FLAGS) | RD(dst) | RM(src2)); - case SLJIT_CLZ: SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2))); @@ -1493,17 +1544,30 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl case SLJIT_CTZ: SLJIT_ASSERT(!(flags & INV_IMM) && !(src2 & SRC2_IMM)); SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) FAIL_IF(push_inst(compiler, RSB | SRC2_IMM | RD(TMP_REG1) | RN(src2) | 0)); FAIL_IF(push_inst(compiler, AND | RD(TMP_REG2) | RN(src2) | RM(TMP_REG1))); FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(TMP_REG2))); FAIL_IF(push_inst(compiler, CMP | SET_FLAGS | SRC2_IMM | RN(dst) | 32)); return push_inst(compiler, (EOR ^ 0xf0000000) | SRC2_IMM | RD(dst) | RN(dst) | 0x1f); -#else /* !SLJIT_CONFIG_ARM_V5 */ +#else /* !SLJIT_CONFIG_ARM_V6 */ FAIL_IF(push_inst(compiler, RBIT | RD(dst) | RM(src2))); return push_inst(compiler, CLZ | RD(dst) | RM(dst)); -#endif /* SLJIT_CONFIG_ARM_V5 */ +#endif /* SLJIT_CONFIG_ARM_V6 */ + case SLJIT_REV: + case SLJIT_REV_U32: + case SLJIT_REV_S32: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); + return push_inst(compiler, REV | RD(dst) | RM(src2)); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED) && src2 != TMP_REG1 && dst != TMP_REG1); + FAIL_IF(push_inst(compiler, REV16 | RD(dst) | RM(src2))); + if (dst == TMP_REG2 || (src2 == TMP_REG2 && op == SLJIT_REV_U16)) + return SLJIT_SUCCESS; + return push_inst(compiler, (op == SLJIT_REV_U16 ? UXTH : SXTH) | RD(dst) | RM(dst)); case SLJIT_ADD: SLJIT_ASSERT(!(flags & INV_IMM)); @@ -1534,7 +1598,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(!(src2 & SRC2_IMM)); compiler->status_flags_state = 0; - if (!HAS_FLAGS(op)) + if (!(flags & SET_FLAGS)) return push_inst(compiler, MUL | RN(dst) | RM8(src2) | RM(src1)); FAIL_IF(push_inst(compiler, SMULL | RN(TMP_REG1) | RD(dst) | RM8(src2) | RM(src1))); @@ -1553,25 +1617,28 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return push_inst(compiler, ORR | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2))); case SLJIT_XOR: - SLJIT_ASSERT(!(flags & INV_IMM)); + if (flags & INV_IMM) { + SLJIT_ASSERT(src2 == SRC2_IMM); + return push_inst(compiler, MVN | (flags & SET_FLAGS) | RD(dst) | RM(src1)); + } return push_inst(compiler, EOR | (flags & SET_FLAGS) | RD(dst) | RN(src1) | ((src2 & SRC2_IMM) ? src2 : RM(src2))); case SLJIT_SHL: case SLJIT_MSHL: shift_type = 0; - is_masked = GET_OPCODE(op) == SLJIT_MSHL; + is_masked = op == SLJIT_MSHL; break; case SLJIT_LSHR: case SLJIT_MLSHR: shift_type = 1; - is_masked = GET_OPCODE(op) == SLJIT_MLSHR; + is_masked = op == SLJIT_MLSHR; break; case SLJIT_ASHR: case SLJIT_MASHR: shift_type = 2; - is_masked = GET_OPCODE(op) == SLJIT_MASHR; + is_masked = op == SLJIT_MASHR; break; case SLJIT_ROTL: @@ -1611,7 +1678,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } return push_inst(compiler, MOV | (flags & SET_FLAGS) | RD(dst) - | RM8(src2) | (sljit_uw)(shift_type << 5) | 0x10 | RM(src1)); + | RM8(src2) | (sljit_ins)(shift_type << 5) | 0x10 | RM(src1)); } #undef EMIT_SHIFT_INS_AND_RETURN @@ -1628,8 +1695,7 @@ static sljit_uw get_imm(sljit_uw imm) if (!(imm & 0xff000000)) { imm <<= 8; rol = 8; - } - else { + } else { imm = (imm << 24) | (imm >> 8); rol = 0; } @@ -1651,22 +1717,19 @@ static sljit_uw get_imm(sljit_uw imm) if (!(imm & 0x00ffffff)) return SRC2_IMM | (imm >> 24) | (rol << 8); - else - return 0; + return 0; } -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm, sljit_s32 positive) +static sljit_uw compute_imm(sljit_uw imm, sljit_uw* imm2) { sljit_uw mask; sljit_uw imm1; - sljit_uw imm2; sljit_uw rol; /* Step1: Search a zero byte (8 continous zero bit). */ mask = 0xff000000; rol = 8; - while(1) { + while (1) { if (!(imm & mask)) { /* Rol imm by rol. */ imm = (imm << rol) | (imm >> (32 - rol)); @@ -1674,6 +1737,7 @@ static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sl rol = 4 + (rol >> 1); break; } + rol += 2; mask >>= 2; if (mask & 0x3) { @@ -1703,9 +1767,8 @@ static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sl if (!(imm & 0xff000000)) { imm1 = SRC2_IMM | ((imm >> 16) & 0xff) | (((rol + 4) & 0xf) << 8); - imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8); - } - else if (imm & 0xc0000000) { + *imm2 = SRC2_IMM | ((imm >> 8) & 0xff) | (((rol + 8) & 0xf) << 8); + } else if (imm & 0xc0000000) { imm1 = SRC2_IMM | ((imm >> 24) & 0xff) | ((rol & 0xf) << 8); imm <<= 8; rol += 4; @@ -1726,11 +1789,10 @@ static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sl } if (!(imm & 0x00ffffff)) - imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); + *imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); else return 0; - } - else { + } else { if (!(imm & 0xf0000000)) { imm <<= 4; rol += 2; @@ -1756,25 +1818,23 @@ static sljit_s32 generate_int(struct sljit_compiler *compiler, sljit_s32 reg, sl } if (!(imm & 0x00ffffff)) - imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); + *imm2 = SRC2_IMM | (imm >> 24) | ((rol & 0xf) << 8); else return 0; } - FAIL_IF(push_inst(compiler, (positive ? MOV : MVN) | RD(reg) | imm1)); - FAIL_IF(push_inst(compiler, (positive ? ORR : BIC) | RD(reg) | RN(reg) | imm2)); - return 1; + return imm1; } -#endif static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm) { sljit_uw tmp; - -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) + sljit_uw imm1, imm2; +#else /* !SLJIT_CONFIG_ARM_V6 */ if (!(imm & ~(sljit_uw)0xffff)) return push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff)); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ /* Create imm by 1 inst. */ tmp = get_imm(imm); @@ -1785,19 +1845,28 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, if (tmp) return push_inst(compiler, MVN | RD(reg) | tmp); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) /* Create imm by 2 inst. */ - FAIL_IF(generate_int(compiler, reg, imm, 1)); - FAIL_IF(generate_int(compiler, reg, ~imm, 0)); + imm1 = compute_imm(imm, &imm2); + if (imm1 != 0) { + FAIL_IF(push_inst(compiler, MOV | RD(reg) | imm1)); + return push_inst(compiler, ORR | RD(reg) | RN(reg) | imm2); + } + + imm1 = compute_imm(~imm, &imm2); + if (imm1 != 0) { + FAIL_IF(push_inst(compiler, MVN | RD(reg) | imm1)); + return push_inst(compiler, BIC | RD(reg) | RN(reg) | imm2); + } /* Load integer. */ return push_inst_with_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), imm); -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff))); if (imm <= 0xffff) return SLJIT_SUCCESS; return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff)); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ } static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, @@ -1834,13 +1903,13 @@ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, s argw &= 0x3; if (argw != 0 && (mask == 0xff)) { - FAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg) | RM(offset_reg) | ((sljit_uw)argw << 7))); + FAIL_IF(push_inst(compiler, ADD | RD(tmp_reg) | RN(arg) | RM(offset_reg) | ((sljit_ins)argw << 7))); return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, tmp_reg, TYPE2_TRANSFER_IMM(0))); } /* Bit 25: RM is offset. */ return push_inst(compiler, EMIT_DATA_TRANSFER(flags, 1, reg, arg, - RM(offset_reg) | (mask == 0xff ? 0 : (1 << 25)) | ((sljit_uw)argw << 7))); + RM(offset_reg) | (mask == 0xff ? 0 : (1 << 25)) | ((sljit_ins)argw << 7))); } arg &= REG_MASK; @@ -1902,10 +1971,16 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 /* We prefers register and simple consts. */ sljit_s32 dst_reg; - sljit_s32 src1_reg; + sljit_s32 src1_reg = 0; sljit_s32 src2_reg = 0; sljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0; sljit_s32 neg_op = 0; + sljit_u32 imm2; + + op = GET_OPCODE(op); + + if (flags & SET_FLAGS) + inp_flags &= ~ALLOW_DOUBLE_IMM; if (dst == TMP_REG2) flags |= UNUSED_RETURN; @@ -1913,7 +1988,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 SLJIT_ASSERT(!(inp_flags & ALLOW_INV_IMM) || (inp_flags & ALLOW_IMM)); if (inp_flags & ALLOW_NEG_IMM) { - switch (GET_OPCODE(op)) { + switch (op) { case SLJIT_ADD: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; neg_op = SLJIT_SUB; @@ -1937,10 +2012,11 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 if (!(inp_flags & ALLOW_IMM)) break; - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { src2_reg = (sljit_s32)get_imm((sljit_uw)src2w); if (src2_reg) break; + if (inp_flags & ALLOW_INV_IMM) { src2_reg = (sljit_s32)get_imm(~(sljit_uw)src2w); if (src2_reg) { @@ -1948,8 +2024,9 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 break; } } + if (neg_op != 0) { - src2_reg = (sljit_s32)get_imm((sljit_uw)-src2w); + src2_reg = (sljit_s32)get_imm((neg_op == SLJIT_ADD || neg_op == SLJIT_SUB) ? (sljit_uw)-src2w : ~(sljit_uw)src2w); if (src2_reg) { op = neg_op | GET_ALL_FLAGS(op); break; @@ -1957,7 +2034,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 } } - if (src1 & SLJIT_IMM) { + if (src1 == SLJIT_IMM) { src2_reg = (sljit_s32)get_imm((sljit_uw)src1w); if (src2_reg) { flags |= ARGS_SWAPPED; @@ -1965,6 +2042,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 src1w = src2w; break; } + if (inp_flags & ALLOW_INV_IMM) { src2_reg = (sljit_s32)get_imm(~(sljit_uw)src1w); if (src2_reg) { @@ -1974,8 +2052,11 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 break; } } + if (neg_op >= SLJIT_SUB) { /* Note: additive operation (commutative). */ + SLJIT_ASSERT(op == SLJIT_ADD || op == SLJIT_ADDC); + src2_reg = (sljit_s32)get_imm((sljit_uw)-src1w); if (src2_reg) { src1 = src2; @@ -1993,8 +2074,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 else if (src1 & SLJIT_MEM) { FAIL_IF(emit_op_mem(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1)); src1_reg = TMP_REG1; - } - else { + } else if (!(inp_flags & ALLOW_DOUBLE_IMM) || src2_reg != 0 || op == SLJIT_SUB || op == SLJIT_SUBC) { FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); src1_reg = TMP_REG1; } @@ -2023,8 +2103,62 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 src2_reg = src2; else if (src2 & SLJIT_MEM) FAIL_IF(emit_op_mem(compiler, inp_flags | LOAD_DATA, src2_reg, src2, src2w, TMP_REG2)); - else + else if (!(inp_flags & ALLOW_DOUBLE_IMM)) FAIL_IF(load_immediate(compiler, src2_reg, (sljit_uw)src2w)); + else { + SLJIT_ASSERT(!(flags & SET_FLAGS)); + + if (src1_reg == 0) { + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); + src1_reg = TMP_REG1; + } + + src2_reg = (sljit_s32)compute_imm((sljit_uw)src2w, &imm2); + + if (src2_reg == 0 && neg_op != 0) { + src2_reg = (sljit_s32)compute_imm((sljit_uw)-src2w, &imm2); + if (src2_reg != 0) + op = neg_op; + } + + if (src2_reg == 0) { + FAIL_IF(load_immediate(compiler, TMP_REG2, (sljit_uw)src2w)); + src2_reg = TMP_REG2; + } else { + FAIL_IF(emit_single_op(compiler, op, flags, (sljit_uw)dst_reg, (sljit_uw)src1_reg, (sljit_uw)src2_reg)); + src1_reg = dst_reg; + src2_reg = (sljit_s32)imm2; + + if (op == SLJIT_ADDC) + op = SLJIT_ADD; + else if (op == SLJIT_SUBC) + op = SLJIT_SUB; + } + } + } + + if (src1_reg == 0) { + SLJIT_ASSERT((inp_flags & ALLOW_DOUBLE_IMM) && !(flags & SET_FLAGS)); + + src1_reg = (sljit_s32)compute_imm((sljit_uw)src1w, &imm2); + + if (src1_reg == 0 && neg_op != 0) { + src1_reg = (sljit_s32)compute_imm((sljit_uw)-src1w, &imm2); + if (src1_reg != 0) + op = neg_op; + } + + if (src1_reg == 0) { + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); + src1_reg = TMP_REG1; + } else { + FAIL_IF(emit_single_op(compiler, op, flags, (sljit_uw)dst_reg, (sljit_uw)src2_reg, (sljit_uw)src1_reg)); + src1_reg = dst_reg; + src2_reg = (sljit_s32)imm2; + + if (op == SLJIT_ADDC) + op = SLJIT_ADD; + } } FAIL_IF(emit_single_op(compiler, op, flags, (sljit_uw)dst_reg, (sljit_uw)src1_reg, (sljit_uw)src2_reg)); @@ -2114,7 +2248,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile SLJIT_ASSERT(saved_reg_list[1] < 8); FAIL_IF(push_inst(compiler, LDR | 0x8d0004 | (saved_reg_list[1] << 12) /* ldr rX, [sp, #4] */)); } - return push_inst(compiler, (LDR ^ (1 << 24)) | 0x8d0000 | (sljit_uw)(saved_reg_count >= 3 ? 16 : 8) + return push_inst(compiler, (LDR ^ (1 << 24)) | 0x8d0000 | (sljit_ins)(saved_reg_count >= 3 ? 16 : 8) | (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */); } return SLJIT_SUCCESS; @@ -2144,23 +2278,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_U8: - return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U8, ALLOW_ANY_IMM | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw); case SLJIT_MOV_S8: - return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_S8, ALLOW_ANY_IMM | SIGNED | BYTE_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw); case SLJIT_MOV_U16: - return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U16, ALLOW_ANY_IMM | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw); case SLJIT_MOV_S16: - return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); - - case SLJIT_NOT: - return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_S16, ALLOW_ANY_IMM | SIGNED | HALF_SIZE, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_CLZ: case SLJIT_CTZ: + case SLJIT_REV: + case SLJIT_REV_U32: + case SLJIT_REV_S32: return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + return emit_op(compiler, op, HALF_SIZE, dst, dstw, TMP_REG1, 0, src, srcw); } return SLJIT_SUCCESS; @@ -2171,6 +2309,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) { + sljit_s32 inp_flags; + CHECK_ERROR(); CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w)); ADJUST_LOCAL_OFFSET(dst, dstw); @@ -2182,11 +2322,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile case SLJIT_ADDC: case SLJIT_SUB: case SLJIT_SUBC: - return emit_op(compiler, op, ALLOW_IMM | ALLOW_NEG_IMM, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, op, ALLOW_IMM | ALLOW_NEG_IMM | ALLOW_DOUBLE_IMM, dst, dstw, src1, src1w, src2, src2w); case SLJIT_OR: + return emit_op(compiler, op, ALLOW_IMM | ALLOW_DOUBLE_IMM, dst, dstw, src1, src1w, src2, src2w); + case SLJIT_XOR: - return emit_op(compiler, op, ALLOW_IMM, dst, dstw, src1, src1w, src2, src2w); + inp_flags = ALLOW_IMM | ALLOW_DOUBLE_IMM; + if ((src1 == SLJIT_IMM && src1w == -1) || (src2 == SLJIT_IMM && src2w == -1)) { + inp_flags |= ALLOW_INV_IMM; + } + return emit_op(compiler, op, inp_flags, dst, dstw, src1, src1w, src2, src2w); case SLJIT_MUL: return emit_op(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w); @@ -2202,7 +2348,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile case SLJIT_MASHR: case SLJIT_ROTL: case SLJIT_ROTR: - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { compiler->shift_imm = src2w & 0x1f; return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src1, src1w); } else { @@ -2226,60 +2372,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_left; CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); op = GET_OPCODE(op); is_left = (op == SLJIT_SHL || op == SLJIT_MSHL); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); /* Shift type of ROR is 3. */ - if (src2 & SLJIT_IMM) { - src2w &= 0x1f; + if (src3 == SLJIT_IMM) { + src3w &= 0x1f; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src2, src2w, TMP_REG2)); - src2 = TMP_REG2; + + FAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | RM(src1_reg) | ((sljit_ins)(is_left ? 0 : 1) << 5) | ((sljit_ins)src3w << 7))); + src3w = (src3w ^ 0x1f) + 1; + return push_inst(compiler, ORR | RD(dst_reg) | RN(dst_reg) | RM(src2_reg) | ((sljit_ins)(is_left ? 1 : 0) << 5) | ((sljit_ins)src3w << 7)); } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); - src1 = TMP_REG1; + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src3, src3w, TMP_REG2)); + src3 = TMP_REG2; } - if (src2 & SLJIT_IMM) { - FAIL_IF(push_inst(compiler, MOV | RD(src_dst) | RM(src_dst) | ((sljit_uw)(is_left ? 0 : 1) << 5) | ((sljit_uw)src2w << 7))); - src2w = (src2w ^ 0x1f) + 1; - return push_inst(compiler, ORR | RD(src_dst) | RN(src_dst) | RM(src1) | ((sljit_uw)(is_left ? 1 : 0) << 5) | ((sljit_uw)src2w << 7)); + if (op == SLJIT_MSHL || op == SLJIT_MLSHR || dst_reg == src3) { + FAIL_IF(push_inst(compiler, AND | SRC2_IMM | RD(TMP_REG2) | RN(src3) | 0x1f)); + src3 = TMP_REG2; } - if (op == SLJIT_MSHL || op == SLJIT_MLSHR) { - FAIL_IF(push_inst(compiler, AND | SRC2_IMM | RD(TMP_REG2) | RN(src2) | 0x1f)); - src2 = TMP_REG2; - } - - FAIL_IF(push_inst(compiler, MOV | RD(src_dst) | RM8(src2) | ((sljit_uw)(is_left ? 0 : 1) << 5) | 0x10 | RM(src_dst))); - FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src1) | ((sljit_uw)(is_left ? 1 : 0) << 5) | (1 << 7))); - FAIL_IF(push_inst(compiler, EOR | SRC2_IMM | RD(TMP_REG2) | RN(src2) | 0x1f)); - return push_inst(compiler, ORR | RD(src_dst) | RN(src_dst) | RM(TMP_REG1) | ((sljit_uw)(is_left ? 1 : 0) << 5) | 0x10 | RM8(TMP_REG2)); + FAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | RM8(src3) | ((sljit_ins)(is_left ? 0 : 1) << 5) | 0x10 | RM(src1_reg))); + FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src2_reg) | ((sljit_ins)(is_left ? 1 : 0) << 5) | (1 << 7))); + FAIL_IF(push_inst(compiler, EOR | SRC2_IMM | RD(TMP_REG2) | RN(src3) | 0x1f)); + return push_inst(compiler, ORR | RD(dst_reg) | RN(dst_reg) | RM8(TMP_REG2) | ((sljit_ins)(is_left ? 1 : 0) << 5) | 0x10 | RM(TMP_REG1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, @@ -2305,27 +2443,67 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp case SLJIT_PREFETCH_L2: case SLJIT_PREFETCH_L3: case SLJIT_PREFETCH_ONCE: -#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) SLJIT_ASSERT(src & SLJIT_MEM); return emit_op_mem(compiler, PRELOAD | LOAD_DATA, TMP_PC, src, srcw, TMP_REG1); -#else /* !SLJIT_CONFIG_ARM_V7 */ - return SLJIT_SUCCESS; -#endif /* SLJIT_CONFIG_ARM_V7 */ } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 size, dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + SLJIT_ASSERT(reg_map[TMP_REG2] == 14); + + if (FAST_IS_REG(dst)) + return push_inst(compiler, MOV | RD(dst) | RM(TMP_REG2)); + break; + case SLJIT_GET_RETURN_ADDRESS: + size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 0); + + if (compiler->fsaveds > 0 || compiler->fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { + /* The size of pc is not added above. */ + if ((size & SSIZE_OF(sw)) == 0) + size += SSIZE_OF(sw); + + size += GET_SAVED_FLOAT_REGISTERS_SIZE(compiler->fscratches, compiler->fsaveds, f64); + } + + SLJIT_ASSERT(((compiler->local_size + size + SSIZE_OF(sw)) & 0x7) == 0); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + size, TMP_REG1)); + break; + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return (freg_map[reg] << 1); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type == SLJIT_FLOAT_REGISTER || type == SLJIT_SIMD_REG_64) + return freg_map[reg]; + + if (type != SLJIT_SIMD_REG_128) + return freg_map[reg] & ~0x1; + + return -1; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -2335,7 +2513,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); - return push_inst(compiler, *(sljit_uw*)instruction); + return push_inst(compiler, *(sljit_ins*)instruction); } /* --------------------------------------------------------------------- */ @@ -2344,18 +2522,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c #define FPU_LOAD (1 << 20) #define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \ - ((inst) | (sljit_uw)((add) << 23) | RN(base) | VD(freg) | (sljit_uw)(offs)) + ((inst) | (sljit_ins)((add) << 23) | RN(base) | VD(freg) | (sljit_ins)(offs)) static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw) { sljit_uw imm; - sljit_uw inst = VSTR_F32 | (flags & (SLJIT_32 | FPU_LOAD)); + sljit_ins inst = VSTR_F32 | (flags & (SLJIT_32 | FPU_LOAD)); SLJIT_ASSERT(arg & SLJIT_MEM); arg &= ~SLJIT_MEM; if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { - FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (((sljit_uw)argw & 0x3) << 7))); + FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (((sljit_ins)argw & 0x3) << 7))); arg = TMP_REG2; argw = 0; } @@ -2410,14 +2588,12 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - op ^= SLJIT_32; - if (FAST_IS_REG(src)) FAIL_IF(push_inst(compiler, VMOV | RD(src) | VN(TMP_FREG1))); else if (src & SLJIT_MEM) { @@ -2429,13 +2605,27 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp FAIL_IF(push_inst(compiler, VMOV | RD(TMP_REG1) | VN(TMP_FREG1))); } - FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCVT_F32_S32, op & SLJIT_32, dst_r, TMP_FREG1, 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(ins, ins & SLJIT_32, dst_r, TMP_FREG1, 0))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, (ins & SLJIT_32), TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + return sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_S32 | (~op & SLJIT_32), dst, dstw, src, srcw); +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + return sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_U32 | (~op & SLJIT_32), dst, dstw, src, srcw); +} + static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) @@ -2453,7 +2643,12 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile } FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_32, src1, src2, 0))); - return push_inst(compiler, VMRS); + FAIL_IF(push_inst(compiler, VMRS)); + + if (GET_FLAG_TYPE(op) != SLJIT_UNORDERED_OR_EQUAL) + return SLJIT_SUCCESS; + + return push_inst(compiler, (CMP - CONDITIONAL) | (0x60000000 /* VS */) | SET_FLAGS | RN(TMP_REG1) | RM(TMP_REG1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, @@ -2534,18 +2729,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_32, dst_r, src2, src1))); break; - case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_32, dst_r, src2, src1))); break; - case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_32, dst_r, src2, src1))); break; - case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_32, dst_r, src2, src1))); break; + case SLJIT_COPYSIGN_F64: + FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(src2) | RD(TMP_REG1) | ((op & SLJIT_32) ? (1 << 7) : 0))); + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_32, dst_r, src1, 0))); + FAIL_IF(push_inst(compiler, CMP | SET_FLAGS | RN(TMP_REG1) | SRC2_IMM | 0)); + return push_inst(compiler, EMIT_FPU_OPERATION((VNEG_F32 & ~COND_MASK) | 0xb0000000, op & SLJIT_32, dst_r, dst_r, 0)); } if (dst_r == TMP_FREG1) @@ -2556,42 +2753,120 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil #undef EMIT_FPU_DATA_TRANSFER -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { +#if defined(__ARM_NEON) && __ARM_NEON + sljit_u32 exp; + sljit_ins ins; +#endif /* NEON */ + union { + sljit_u32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - SLJIT_ASSERT(reg_map[TMP_REG2] == 14); + u.value = value; - if (FAST_IS_REG(dst)) - return push_inst(compiler, MOV | RD(dst) | RM(TMP_REG2)); +#if defined(__ARM_NEON) && __ARM_NEON + if ((u.imm << (32 - 19)) == 0) { + exp = (u.imm >> (23 + 2)) & 0x3f; - /* Memory. */ - return emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1); + if (exp == 0x20 || exp == 0x1f) { + ins = ((u.imm >> 24) & 0x80) | ((u.imm >> 19) & 0x7f); + return push_inst(compiler, (VMOV_F32 ^ (1 << 6)) | ((ins & 0xf0) << 12) | VD(freg) | (ins & 0xf)); + } + } +#endif /* NEON */ + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm)); + return push_inst(compiler, VMOV | VN(freg) | RD(TMP_REG1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ +#if defined(__ARM_NEON) && __ARM_NEON + sljit_u32 exp; + sljit_ins ins; +#endif /* NEON */ + union { + sljit_u32 imm[2]; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + +#if defined(__ARM_NEON) && __ARM_NEON + if (u.imm[0] == 0 && (u.imm[1] << (64 - 48)) == 0) { + exp = (u.imm[1] >> ((52 - 32) + 2)) & 0x1ff; + + if (exp == 0x100 || exp == 0xff) { + ins = ((u.imm[1] >> (56 - 32)) & 0x80) | ((u.imm[1] >> (48 - 32)) & 0x7f); + return push_inst(compiler, (VMOV_F32 ^ (1 << 6)) | (1 << 8) | ((ins & 0xf0) << 12) | VD(freg) | (ins & 0xf)); + } + } +#endif /* NEON */ + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0])); + if (u.imm[0] == u.imm[1]) + return push_inst(compiler, VMOV2 | RN(TMP_REG1) | RD(TMP_REG1) | VM(freg)); + + FAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1])); + return push_inst(compiler, VMOV2 | RN(TMP_REG2) | RD(TMP_REG1) | VM(freg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_s32 reg2; + sljit_ins inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + + inst = VMOV2 | RN(reg) | RD(reg2) | VM(freg); + } else { + inst = VMOV | VN(freg) | RD(reg); + + if (!(op & SLJIT_32)) + inst |= 1 << 7; + } + + if (GET_OPCODE(op) == SLJIT_COPY_FROM_F64) + inst |= 1 << 20; + + return push_inst(compiler, inst); } /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ -static sljit_uw get_cc(struct sljit_compiler *compiler, sljit_s32 type) +static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type) { switch (type) { case SLJIT_EQUAL: + case SLJIT_ATOMIC_STORED: case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: - case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */ + case SLJIT_UNORDERED_OR_EQUAL: return 0x00000000; case SLJIT_NOT_EQUAL: + case SLJIT_ATOMIC_NOT_STORED: case SLJIT_F_NOT_EQUAL: case SLJIT_UNORDERED_OR_NOT_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */ + case SLJIT_ORDERED_NOT_EQUAL: return 0x10000000; case SLJIT_CARRY: @@ -2696,7 +2971,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile SLJIT_ASSERT(reg_map[TMP_REG1] != 14); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (type >= SLJIT_FAST_CALL) PTR_FAIL_IF(prepare_blx(compiler)); PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, @@ -2714,13 +2989,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) jump->addr = compiler->size; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ if (type >= SLJIT_FAST_CALL) jump->flags |= IS_BL; PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(compiler, type))); jump->addr = compiler->size; -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ return jump; } @@ -2738,7 +3013,7 @@ static sljit_s32 softfloat_call_with_args(struct sljit_compiler *compiler, sljit sljit_u8 *offset_ptr = offsets; if (src && FAST_IS_REG(*src)) - src_offset = (sljit_uw)reg_map[*src] * sizeof(sljit_sw); + src_offset = (sljit_u32)reg_map[*src] * sizeof(sljit_sw); arg_types >>= SLJIT_ARG_SHIFT; @@ -2773,7 +3048,7 @@ static sljit_s32 softfloat_call_with_args(struct sljit_compiler *compiler, sljit if (is_tail_call) offset += sizeof(sljit_sw); - offset = ((offset - 4 * sizeof(sljit_sw)) + 0x7) & ~(sljit_uw)0x7; + offset = ((offset - 4 * sizeof(sljit_sw)) + 0x7) & ~(sljit_u32)0x7; *extra_space = offset; @@ -2903,8 +3178,6 @@ static sljit_s32 hardfloat_call_with_args(struct sljit_compiler *compiler, sljit #endif /* __SOFTFP__ */ -#undef EMIT_FPU_OPERATION - SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types) { @@ -2971,7 +3244,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi SLJIT_ASSERT(reg_map[TMP_REG1] != 14); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { if (FAST_IS_REG(src)) { SLJIT_ASSERT(reg_map[src] != 14); return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src)); @@ -2988,16 +3261,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0)); jump->u.target = (sljit_uw)srcw; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) if (type >= SLJIT_FAST_CALL) FAIL_IF(prepare_blx(compiler)); FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0)); if (type >= SLJIT_FAST_CALL) FAIL_IF(emit_blx(compiler)); -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ FAIL_IF(emit_imm(compiler, TMP_REG1, 0)); FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1))); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ jump->addr = compiler->size; return SLJIT_SUCCESS; } @@ -3096,7 +3369,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_s32 type) { sljit_s32 dst_reg, flags = GET_ALL_FLAGS(op); - sljit_uw cc, ins; + sljit_ins cc, ins; CHECK_ERROR(); CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type)); @@ -3132,61 +3405,114 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { - sljit_uw cc, tmp; + sljit_ins cc, tmp; CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (src2_reg != dst_reg && src1 == dst_reg) { + src1 = src2_reg; + src1w = 0; + src2_reg = dst_reg; + type ^= 0x1; + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, (src2_reg != dst_reg) ? dst_reg : TMP_REG1, src1, src1w, TMP_REG2)); + + if (src2_reg != dst_reg) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + src1 = TMP_REG1; + src1w = 0; + } + } else if (dst_reg != src2_reg) + FAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | RM(src2_reg))); cc = get_cc(compiler, type & ~SLJIT_32); - if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { - tmp = get_imm((sljit_uw)srcw); + if (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) { + tmp = get_imm((sljit_uw)src1w); if (tmp) return push_inst(compiler, ((MOV | RD(dst_reg) | tmp) & ~COND_MASK) | cc); - tmp = get_imm(~(sljit_uw)srcw); + tmp = get_imm(~(sljit_uw)src1w); if (tmp) return push_inst(compiler, ((MVN | RD(dst_reg) | tmp) & ~COND_MASK) | cc); #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) - tmp = (sljit_uw)srcw; + tmp = (sljit_ins)src1w; FAIL_IF(push_inst(compiler, (MOVW & ~COND_MASK) | cc | RD(dst_reg) | ((tmp << 4) & 0xf0000) | (tmp & 0xfff))); if (tmp <= 0xffff) return SLJIT_SUCCESS; return push_inst(compiler, (MOVT & ~COND_MASK) | cc | RD(dst_reg) | ((tmp >> 12) & 0xf0000) | ((tmp >> 16) & 0xfff)); -#else - FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); - src = TMP_REG1; -#endif +#else /* !SLJIT_CONFIG_ARM_V7 */ + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); + src1 = TMP_REG1; +#endif /* SLJIT_CONFIG_ARM_V7 */ } - return push_inst(compiler, ((MOV | RD(dst_reg) | RM(src)) & ~COND_MASK) | cc); + return push_inst(compiler, ((MOV | RD(dst_reg) | RM(src1)) & ~COND_MASK) | cc); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_ins cc; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + type ^= SLJIT_32; + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, (type & SLJIT_32), dst_freg, src2_freg, 0))); + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w)); + src1 = TMP_FREG1; + } + + cc = get_cc(compiler, type & ~SLJIT_32); + return push_inst(compiler, EMIT_FPU_OPERATION((VMOV_F32 & ~COND_MASK) | cc, (type & SLJIT_32), dst_freg, src1, 0)); +} + +#undef EMIT_FPU_OPERATION + static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s32 max_offset) { sljit_s32 arg = *mem; sljit_sw argw = *memw; sljit_uw imm, tmp; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_sw mask = max_offset >= 0xf00 ? 0xfff : 0xff; - sljit_sw sign = max_offset >= 0xf00 ? 0x1000 : 0x100; -#else /* !SLJIT_CONFIG_ARM_V5 */ sljit_sw mask = 0xfff; sljit_sw sign = 0x1000; SLJIT_ASSERT(max_offset >= 0xf00); -#endif /* SLJIT_CONFIG_ARM_V5 */ *mem = TMP_REG1; if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { *memw = 0; - return push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_uw)(argw & 0x3) << 7)); + return push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_ins)(argw & 0x3) << 7)); } arg &= REG_MASK; @@ -3234,158 +3560,6 @@ static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem return push_inst(compiler, ADD | RD(TMP_REG1) | RN(TMP_REG1) | RM(arg)); } -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - -static sljit_s32 sljit_emit_mem_unaligned(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 reg, - sljit_s32 mem, sljit_sw memw) -{ - sljit_s32 flags, steps, tmp_reg; - sljit_uw add, shift; - - switch (type & 0xff) { - case SLJIT_MOV_U8: - case SLJIT_MOV_S8: - flags = BYTE_SIZE; - if (!(type & SLJIT_MEM_STORE)) - flags |= LOAD_DATA; - if ((type & 0xff) == SLJIT_MOV_S8) - flags |= SIGNED; - - return emit_op_mem(compiler, flags, reg, mem, memw, TMP_REG1); - - case SLJIT_MOV_U16: - FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 1)); - flags = BYTE_SIZE; - steps = 1; - break; - - case SLJIT_MOV_S16: - FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xff - 1)); - flags = BYTE_SIZE | SIGNED; - steps = 1; - break; - - default: - if (type & SLJIT_MEM_UNALIGNED_32) { - flags = WORD_SIZE; - if (!(type & SLJIT_MEM_STORE)) - flags |= LOAD_DATA; - - return emit_op_mem(compiler, flags, reg, mem, memw, TMP_REG1); - } - - if (!(type & SLJIT_MEM_UNALIGNED_16)) { - FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 3)); - flags = BYTE_SIZE; - steps = 3; - break; - } - - FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xff - 2)); - - add = 1; - if (memw < 0) { - add = 0; - memw = -memw; - } - - tmp_reg = reg; - - if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE, add, reg, mem, TYPE2_TRANSFER_IMM(memw)))); - FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(reg) | (16 << 7) | (2 << 4))); - } else { - if (reg == mem) { - SLJIT_ASSERT(reg != TMP_REG1); - tmp_reg = TMP_REG1; - } - - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE | LOAD_DATA, add, tmp_reg, mem, TYPE2_TRANSFER_IMM(memw)))); - } - - if (!add) { - memw -= 2; - if (memw <= 0) { - memw = -memw; - add = 1; - } - } else - memw += 2; - - if (type & SLJIT_MEM_STORE) - return push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE, add, TMP_REG2, mem, TYPE2_TRANSFER_IMM(memw))); - - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(HALF_SIZE | LOAD_DATA, add, TMP_REG2, mem, TYPE2_TRANSFER_IMM(memw)))); - return push_inst(compiler, ORR | RD(reg) | RN(tmp_reg) | RM(TMP_REG2) | (16 << 7)); - } - - SLJIT_ASSERT(steps > 0); - - add = 1; - if (memw < 0) { - add = 0; - memw = -memw; - } - - if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE, add, reg, mem, memw))); - FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(reg) | (8 << 7) | (2 << 4))); - - while (1) { - if (!add) { - memw -= 1; - if (memw == 0) - add = 1; - } else - memw += 1; - - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE, add, TMP_REG2, mem, memw))); - - if (--steps == 0) - return SLJIT_SUCCESS; - - FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(TMP_REG2) | (8 << 7) | (2 << 4))); - } - } - - tmp_reg = reg; - - if (reg == mem) { - SLJIT_ASSERT(reg != TMP_REG1); - tmp_reg = TMP_REG1; - } - - shift = 8; - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE | LOAD_DATA, add, tmp_reg, mem, memw))); - - do { - if (!add) { - memw -= 1; - if (memw == 0) - add = 1; - } else - memw += 1; - - if (steps > 1) { - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(BYTE_SIZE | LOAD_DATA, add, TMP_REG2, mem, memw))); - FAIL_IF(push_inst(compiler, ORR | RD(tmp_reg) | RN(tmp_reg) | RM(TMP_REG2) | (shift << 7))); - shift += 8; - } - } while (--steps != 0); - - flags |= LOAD_DATA; - - if (flags & SIGNED) - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(flags, add, TMP_REG2, mem, TYPE2_TRANSFER_IMM(memw)))); - else - FAIL_IF(push_inst(compiler, EMIT_DATA_TRANSFER(flags, add, TMP_REG2, mem, memw))); - - return push_inst(compiler, ORR | RD(reg) | RN(tmp_reg) | RM(TMP_REG2) | (shift << 7)); -} - -#endif /* SLJIT_CONFIG_ARM_V5 */ - SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw) @@ -3395,30 +3569,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile CHECK_ERROR(); CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw)); - if (!(reg & REG_PAIR_MASK)) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - ADJUST_LOCAL_OFFSET(mem, memw); -#endif /* SLJIT_CONFIG_ARM_V5 */ - + if (!(reg & REG_PAIR_MASK)) return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw); - } ADJUST_LOCAL_OFFSET(mem, memw); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (type & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16)) { - FAIL_IF(update_mem_addr(compiler, &mem, &memw, (type & SLJIT_MEM_UNALIGNED_16) ? 0xfff - 6 : 0xfff - 7)); - - if (!(type & SLJIT_MEM_STORE) && REG_PAIR_FIRST(reg) == (mem & REG_MASK)) { - FAIL_IF(sljit_emit_mem_unaligned(compiler, type, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), memw + SSIZE_OF(sw))); - return sljit_emit_mem_unaligned(compiler, type, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw); - } - - FAIL_IF(sljit_emit_mem_unaligned(compiler, type, REG_PAIR_FIRST(reg), SLJIT_MEM1(mem), memw)); - return sljit_emit_mem_unaligned(compiler, type, REG_PAIR_SECOND(reg), SLJIT_MEM1(mem), memw + SSIZE_OF(sw)); - } -#endif /* SLJIT_CONFIG_ARM_V5 */ - FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4)); flags = WORD_SIZE; @@ -3441,7 +3596,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler * sljit_s32 mem, sljit_sw memw) { sljit_s32 flags; - sljit_uw is_type1_transfer, inst; + sljit_ins is_type1_transfer, inst; CHECK_ERROR(); CHECK(check_sljit_emit_mem_update(compiler, type, reg, mem, memw)); @@ -3500,7 +3655,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler * if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { memw &= 0x3; - inst = EMIT_DATA_TRANSFER(flags, 1, reg, mem & REG_MASK, RM(OFFS_REG(mem)) | ((sljit_uw)memw << 7)); + inst = EMIT_DATA_TRANSFER(flags, 1, reg, mem & REG_MASK, RM(OFFS_REG(mem)) | ((sljit_ins)memw << 7)); if (is_type1_transfer) inst |= (1 << 25); @@ -3526,7 +3681,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler * else memw = -memw; - return push_inst(compiler, inst | (sljit_uw)memw); + return push_inst(compiler, inst | (sljit_ins)memw); } if (memw >= 0) @@ -3534,76 +3689,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler * else memw = -memw; - return push_inst(compiler, inst | TYPE2_TRANSFER_IMM((sljit_uw)memw)); + return push_inst(compiler, inst | TYPE2_TRANSFER_IMM((sljit_ins)memw)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - sljit_s32 max_offset; - sljit_s32 dst; -#endif /* SLJIT_CONFIG_ARM_V5 */ - CHECK_ERROR(); CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw)); - if (type & SLJIT_MEM_UNALIGNED_32) + if (type & SLJIT_MEM_ALIGNED_32) return emit_fop_mem(compiler, ((type ^ SLJIT_32) & SLJIT_32) | ((type & SLJIT_MEM_STORE) ? 0 : FPU_LOAD), freg, mem, memw); -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | RD(TMP_REG2))); - - if (type & SLJIT_32) - return sljit_emit_mem_unaligned(compiler, SLJIT_MOV | SLJIT_MEM_STORE | (type & SLJIT_MEM_UNALIGNED_16), TMP_REG2, mem, memw); - - max_offset = 0xfff - 7; - if (type & SLJIT_MEM_UNALIGNED_16) - max_offset++; - - FAIL_IF(update_mem_addr(compiler, &mem, &memw, max_offset)); - mem |= SLJIT_MEM; - - FAIL_IF(sljit_emit_mem_unaligned(compiler, SLJIT_MOV | SLJIT_MEM_STORE | (type & SLJIT_MEM_UNALIGNED_16), TMP_REG2, mem, memw)); - - FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | 0x80 | RD(TMP_REG2))); - return sljit_emit_mem_unaligned(compiler, SLJIT_MOV | SLJIT_MEM_STORE | (type & SLJIT_MEM_UNALIGNED_16), TMP_REG2, mem, memw + 4); - } - - max_offset = (type & SLJIT_32) ? 0xfff - 3 : 0xfff - 7; - if (type & SLJIT_MEM_UNALIGNED_16) - max_offset++; - - FAIL_IF(update_mem_addr(compiler, &mem, &memw, max_offset)); - - dst = TMP_REG1; - - /* Stack offset adjustment is not needed because dst - is not stored on the stack when mem is SLJIT_SP. */ - - if (mem == TMP_REG1) { - dst = SLJIT_R3; - - if (compiler->scratches >= 4) - FAIL_IF(push_inst(compiler, STR | (1 << 21) | RN(SLJIT_SP) | RD(SLJIT_R3) | 8)); - } - - mem |= SLJIT_MEM; - - FAIL_IF(sljit_emit_mem_unaligned(compiler, SLJIT_MOV | (type & SLJIT_MEM_UNALIGNED_16), dst, mem, memw)); - FAIL_IF(push_inst(compiler, VMOV | VN(freg) | RD(dst))); - - if (!(type & SLJIT_32)) { - FAIL_IF(sljit_emit_mem_unaligned(compiler, SLJIT_MOV | (type & SLJIT_MEM_UNALIGNED_16), dst, mem, memw + 4)); - FAIL_IF(push_inst(compiler, VMOV | VN(freg) | 0x80 | RD(dst))); - } - - if (dst == SLJIT_R3 && compiler->scratches >= 4) - FAIL_IF(push_inst(compiler, (LDR ^ (0x1 << 24)) | (0x1 << 23) | RN(SLJIT_SP) | RD(SLJIT_R3) | 8)); - return SLJIT_SUCCESS; -#else /* !SLJIT_CONFIG_ARM_V5 */ if (type & SLJIT_MEM_STORE) { FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(freg) | RD(TMP_REG2))); @@ -3629,11 +3727,714 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, mem, memw, TMP_REG1)); FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, mem, memw + 4, TMP_REG1)); return push_inst(compiler, VMOV2 | VM(freg) | RD(TMP_REG2) | RN(TMP_REG1)); -#endif /* SLJIT_CONFIG_ARM_V5 */ +} + +static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, sljit_s32 *mem_ptr, sljit_sw memw) +{ + sljit_s32 mem = *mem_ptr; + sljit_uw imm; + + if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { + *mem_ptr = TMP_REG1; + return push_inst(compiler, ADD | RD(TMP_REG1) | RN(mem & REG_MASK) | RM(OFFS_REG(mem)) | ((sljit_ins)(memw & 0x3) << 7)); + } + + if (SLJIT_UNLIKELY(!(mem & REG_MASK))) { + *mem_ptr = TMP_REG1; + return load_immediate(compiler, TMP_REG1, (sljit_uw)memw); + } + + mem &= REG_MASK; + + if (memw == 0) { + *mem_ptr = mem; + return SLJIT_SUCCESS; + } + + *mem_ptr = TMP_REG1; + imm = get_imm((sljit_uw)(memw < 0 ? -memw : memw)); + + if (imm != 0) + return push_inst(compiler, ((memw < 0) ? SUB : ADD) | RD(TMP_REG1) | RN(mem) | imm); + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw)); + return push_inst(compiler, ADD | RD(TMP_REG1) | RN(TMP_REG1) | RM(mem)); +} + +static SLJIT_INLINE sljit_s32 simd_get_quad_reg_index(sljit_s32 freg) +{ + freg += freg & 0x1; + + SLJIT_ASSERT((freg_map[freg] & 0x1) == (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)); + + if (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS) + freg--; + + return freg; +} + +#define SLJIT_QUAD_OTHER_HALF(freg) ((((freg) & 0x1) << 1) - 1) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (!(srcdst & SLJIT_MEM)) { + if (reg_size == 4) + srcdst = simd_get_quad_reg_index(srcdst); + + if (type & SLJIT_SIMD_STORE) + ins = VD(srcdst) | VN(freg) | VM(freg); + else + ins = VD(freg) | VN(srcdst) | VM(srcdst); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst(compiler, VORR | ins); + } + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + if (elem_size > 3) + elem_size = 3; + + ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD(freg) + | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); + + SLJIT_ASSERT(reg_size >= alignment); + + if (alignment == 3) + ins |= 0x10; + else if (alignment >= 3) + ins |= 0x20; + + return push_inst(compiler, ins | RN(srcdst) | ((sljit_ins)elem_size) << 6 | 0xf); +} + +static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) +{ + sljit_ins result; + + if (elem_size > 1 && (sljit_u16)value == (value >> 16)) { + elem_size = 1; + value = (sljit_u16)value; + } + + if (elem_size == 1 && (sljit_u8)value == (value >> 8)) { + elem_size = 0; + value = (sljit_u8)value; + } + + switch (elem_size) { + case 0: + SLJIT_ASSERT(value <= 0xff); + result = 0xe00; + break; + case 1: + SLJIT_ASSERT(value <= 0xffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x800; + break; + } + + if ((value & 0xff) == 0) { + value >>= 8; + result |= 0xa00; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value ^= (sljit_uw)0xffff; + result = (1 << 5); + } + break; + default: + SLJIT_ASSERT(value <= 0xffffffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x000; + break; + } + + if ((value & ~(sljit_uw)0xff00) == 0) { + value >>= 8; + result |= 0x200; + break; + } + + if ((value & ~(sljit_uw)0xff0000) == 0) { + value >>= 16; + result |= 0x400; + break; + } + + if ((value & ~(sljit_uw)0xff000000) == 0) { + value >>= 24; + result |= 0x600; + break; + } + + if ((value & (sljit_uw)0xff) == 0xff && (value >> 16) == 0) { + value >>= 8; + result |= 0xc00; + break; + } + + if ((value & (sljit_uw)0xffff) == 0xffff && (value >> 24) == 0) { + value >>= 16; + result |= 0xd00; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value = ~value; + result = (1 << 5); + } + break; + } + + return ((sljit_ins)value & 0xf) | (((sljit_ins)value & 0x70) << 12) | (((sljit_ins)value & 0x80) << 17) | result; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imm; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (src == SLJIT_IMM && srcw == 0) + return push_inst(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD(freg)); + + if (SLJIT_UNLIKELY(elem_size == 3)) { + SLJIT_ASSERT(type & SLJIT_SIMD_FLOAT); + + if (src & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, freg, src, srcw)); + src = freg; + } else if (freg != src) + FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (freg != src) + return push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src)); + return SLJIT_SUCCESS; + } + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + + ins = (sljit_ins)(elem_size << 6); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 5; + + return push_inst(compiler, VLD1_r | ins | VD(freg) | RN(src) | 0xf); + } + + if (type & SLJIT_SIMD_FLOAT) { + SLJIT_ASSERT(elem_size == 2); + ins = ((sljit_ins)freg_ebit_map[src] << (16 + 2 + 1)) | ((sljit_ins)1 << (16 + 2)); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst(compiler, VDUP_s | ins | VD(freg) | (sljit_ins)freg_map[src]); + } + + if (src == SLJIT_IMM) { + if (elem_size < 2) + srcw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + imm = simd_get_imm(elem_size, (sljit_uw)srcw); + + if (imm != ~(sljit_ins)0) { + if (reg_size == 4) + imm |= (sljit_ins)1 << 6; + + return push_inst(compiler, VMOV_i | imm | VD(freg)); + } + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); + src = TMP_REG1; + } + + switch (elem_size) { + case 0: + ins = 1 << 22; + break; + case 1: + ins = 1 << 5; + break; + default: + ins = 0; + break; + } + + if (reg_size == 4) + ins |= (sljit_ins)1 << 21; + + return push_inst(compiler, VDUP | ins | VN(freg) | RD(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (type & SLJIT_SIMD_LANE_ZERO) { + ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 6); + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 3 && !(srcdst & SLJIT_MEM)) { + if (lane_index == 1) + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (srcdst != freg) + FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(srcdst) | VM(srcdst))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst(compiler, VMOV_i | VD(freg)); + } + + if (srcdst == freg || (elem_size == 3 && srcdst == (freg + SLJIT_QUAD_OTHER_HALF(freg)))) { + FAIL_IF(push_inst(compiler, VORR | ins | VD(TMP_FREG2) | VN(freg) | VM(freg))); + srcdst = TMP_FREG2; + srcdstw = 0; + } + } + + FAIL_IF(push_inst(compiler, VMOV_i | ins | VD(freg))); + } + + if (reg_size == 4 && lane_index >= (0x8 >> elem_size)) { + lane_index -= (0x8 >> elem_size); + freg += SLJIT_QUAD_OTHER_HALF(freg); + } + + if (srcdst & SLJIT_MEM) { + if (elem_size == 3) + return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, freg, srcdst, srcdstw); + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + lane_index = lane_index << elem_size; + ins = (sljit_ins)((elem_size << 10) | (lane_index << 5)); + return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD(freg) | RN(srcdst) | 0xf); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 3) { + if (type & SLJIT_SIMD_STORE) + return push_inst(compiler, VORR | VD(srcdst) | VN(freg) | VM(freg)); + return push_inst(compiler, VMOV_F32 | SLJIT_32 | VD(freg) | VM(srcdst)); + } + + if (type & SLJIT_SIMD_STORE) { + if (freg_ebit_map[freg] == 0) { + if (lane_index == 1) + freg = SLJIT_F64_SECOND(freg); + + return push_inst(compiler, VMOV_F32 | VD(srcdst) | VM(freg)); + } + + FAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN(freg) | RD(TMP_REG1))); + return push_inst(compiler, VMOV | VN(srcdst) | RD(TMP_REG1)); + } + + FAIL_IF(push_inst(compiler, VMOV | (1 << 20) | VN(srcdst) | RD(TMP_REG1))); + return push_inst(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN(freg) | RD(TMP_REG1)); + } + + if (srcdst == SLJIT_IMM) { + if (elem_size < 2) + srcdstw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcdstw)); + srcdst = TMP_REG1; + } + + if (elem_size == 0) + ins = 0x400000; + else if (elem_size == 1) + ins = 0x20; + else + ins = 0; + + lane_index = lane_index << elem_size; + ins |= (sljit_ins)(((lane_index & 0x4) << 19) | ((lane_index & 0x3) << 5)); + + if (type & SLJIT_SIMD_STORE) { + ins |= (1 << 20); + + if (elem_size < 2 && !(type & SLJIT_SIMD_LANE_SIGNED)) + ins |= (1 << 23); + } + + return push_inst(compiler, VMOV_s | ins | VN(freg) | RD(srcdst)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) { + freg = simd_get_quad_reg_index(freg); + src = simd_get_quad_reg_index(src); + + if (src_lane_index >= (0x8 >> elem_size)) { + src_lane_index -= (0x8 >> elem_size); + src += SLJIT_QUAD_OTHER_HALF(src); + } + } + + if (elem_size == 3) { + if (freg != src) + FAIL_IF(push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (freg != src) + return push_inst(compiler, VORR | VD(freg) | VN(src) | VM(src)); + return SLJIT_SUCCESS; + } + + ins = ((((sljit_ins)src_lane_index << 1) | 1) << (16 + elem_size)); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst(compiler, VDUP_s | ins | VD(freg) | VM(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_s32 dst_reg; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size != 2 || elem2_size != 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + if (reg_size == 4 && elem2_size - elem_size == 1) + FAIL_IF(push_inst(compiler, VLD1 | (0x7 << 8) | VD(freg) | RN(src) | 0xf)); + else + FAIL_IF(push_inst(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD(freg) | RN(src) | 0xf)); + src = freg; + } else if (reg_size == 4) + src = simd_get_quad_reg_index(src); + + if (!(type & SLJIT_SIMD_FLOAT)) { + dst_reg = (reg_size == 4) ? freg : TMP_FREG2; + + do { + FAIL_IF(push_inst(compiler, VSHLL | ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0 : (1 << 24)) + | ((sljit_ins)1 << (19 + elem_size)) | VD(dst_reg) | VM(src))); + src = dst_reg; + } while (++elem_size < elem2_size); + + if (dst_reg == TMP_FREG2) + return push_inst(compiler, VORR | VD(freg) | VN(TMP_FREG2) | VM(TMP_FREG2)); + return SLJIT_SUCCESS; + } + + /* No SIMD variant, must use VFP instead. */ + SLJIT_ASSERT(reg_size == 4); + + if (freg == src) { + freg += SLJIT_QUAD_OTHER_HALF(freg); + FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src) | 0x20)); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src)); + } + + FAIL_IF(push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src))); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst(compiler, VCVT_F64_F32 | VD(freg) | VM(src) | 0x20); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imms; + sljit_s32 dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + switch (elem_size) { + case 0: + imms = 0x243219; + ins = VSHR | (1 << 24) | (0x9 << 16); + break; + case 1: + imms = (reg_size == 4) ? 0x243219 : 0x2231; + ins = VSHR | (1 << 24) | (0x11 << 16); + break; + case 2: + imms = (reg_size == 4) ? 0x2231 : 0x21; + ins = VSHR | (1 << 24) | (0x21 << 16); + break; + default: + imms = 0x21; + ins = VSHR | (1 << 24) | (0x1 << 16) | (1 << 7); + break; + } + + if (reg_size == 4) { + freg = simd_get_quad_reg_index(freg); + ins |= (sljit_ins)1 << 6; + } + + SLJIT_ASSERT((freg_map[TMP_FREG2] & 0x1) == 0); + FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG2) | VM(freg))); + + if (reg_size == 4 && elem_size > 0) + FAIL_IF(push_inst(compiler, VMOVN | ((sljit_ins)(elem_size - 1) << 18) | VD(TMP_FREG2) | VM(TMP_FREG2))); + + ins = (reg_size == 4 && elem_size == 0) ? (1 << 6) : 0; + + while (imms >= 0x100) { + FAIL_IF(push_inst(compiler, VSRA | (1 << 24) | ins | ((imms & 0xff) << 16) | VD(TMP_FREG2) | VM(TMP_FREG2))); + imms >>= 8; + } + + FAIL_IF(push_inst(compiler, VSRA | (1 << 24) | ins | (1 << 7) | (imms << 16) | VD(TMP_FREG2) | VM(TMP_FREG2))); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + FAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RD(dst_r) | VN(TMP_FREG2))); + + if (reg_size == 4 && elem_size == 0) { + SLJIT_ASSERT(freg_map[TMP_FREG2] + 1 == freg_map[TMP_FREG1]); + FAIL_IF(push_inst(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RD(TMP_REG2) | VN(TMP_FREG1))); + FAIL_IF(push_inst(compiler, ORR | RD(dst_r) | RN(dst_r) | RM(TMP_REG2) | (0x8 << 7))); + } + + if (dst_r == TMP_REG1) + return emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + switch (SLJIT_SIMD_GET_OPCODE(type)) { + case SLJIT_SIMD_OP2_AND: + ins = VAND; + break; + case SLJIT_SIMD_OP2_OR: + ins = VORR; + break; + case SLJIT_SIMD_OP2_XOR: + ins = VEOR; + break; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) { + dst_freg = simd_get_quad_reg_index(dst_freg); + src1_freg = simd_get_quad_reg_index(src1_freg); + src2_freg = simd_get_quad_reg_index(src2_freg); + ins |= (sljit_ins)1 << 6; + } + + return push_inst(compiler, ins | VD(dst_freg) | VN(src1_freg) | VM(src2_freg)); } #undef FPU_LOAD +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + sljit_u32 ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV_U8: + ins = LDREXB; + break; + case SLJIT_MOV_U16: + ins = LDREXH; + break; + default: + ins = LDREX; + break; + } + + return push_inst(compiler, ins | RN(mem_reg) | RD(dst_reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_u32 ins; + + /* temp_reg == mem_reg is undefined so use another temp register */ + SLJIT_UNUSED_ARG(temp_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV_U8: + ins = STREXB; + break; + case SLJIT_MOV_U16: + ins = STREXH; + break; + default: + ins = STREX; + break; + } + + FAIL_IF(push_inst(compiler, ins | RN(mem_reg) | RD(TMP_REG1) | RM(src_reg))); + if (op & SLJIT_SET_ATOMIC_STORED) + return push_inst(compiler, CMP | SET_FLAGS | SRC2_IMM | RN(TMP_REG1)); + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; @@ -3645,13 +4446,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) PTR_FAIL_IF(push_inst_with_unique_literal(compiler, - EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), (sljit_uw)init_value)); + EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), (sljit_ins)init_value)); compiler->patches++; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value)); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); PTR_FAIL_IF(!const_); @@ -3673,12 +4474,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) +#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), 0)); compiler->patches++; -#else +#else /* !SLJIT_CONFIG_ARM_V6 */ PTR_FAIL_IF(emit_imm(compiler, dst_r, 0)); -#endif +#endif /* SLJIT_CONFIG_ARM_V6 */ put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label)); PTR_FAIL_IF(!put_label); diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c index 89f747e7c89..b268582f42c 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_64.c @@ -67,79 +67,123 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { /* Instrucion forms */ /* --------------------------------------------------------------------- */ -#define ADC 0x9a000000 -#define ADD 0x8b000000 -#define ADDE 0x8b200000 -#define ADDI 0x91000000 -#define AND 0x8a000000 -#define ANDI 0x92000000 -#define ASRV 0x9ac02800 -#define B 0x14000000 -#define B_CC 0x54000000 -#define BL 0x94000000 -#define BLR 0xd63f0000 -#define BR 0xd61f0000 -#define BRK 0xd4200000 -#define CBZ 0xb4000000 -#define CLZ 0xdac01000 -#define CSEL 0x9a800000 -#define CSINC 0x9a800400 -#define EOR 0xca000000 -#define EORI 0xd2000000 -#define EXTR 0x93c00000 -#define FABS 0x1e60c000 -#define FADD 0x1e602800 -#define FCMP 0x1e602000 -#define FCVT 0x1e224000 -#define FCVTZS 0x9e780000 -#define FDIV 0x1e601800 -#define FMOV 0x1e604000 -#define FMUL 0x1e600800 -#define FNEG 0x1e614000 -#define FSUB 0x1e603800 -#define LDRI 0xf9400000 -#define LDRI_F64 0xfd400000 -#define LDRI_POST 0xf8400400 -#define LDP 0xa9400000 -#define LDP_F64 0x6d400000 -#define LDP_POST 0xa8c00000 -#define LDR_PRE 0xf8400c00 -#define LSLV 0x9ac02000 -#define LSRV 0x9ac02400 -#define MADD 0x9b000000 -#define MOVK 0xf2800000 -#define MOVN 0x92800000 -#define MOVZ 0xd2800000 -#define NOP 0xd503201f -#define ORN 0xaa200000 -#define ORR 0xaa000000 -#define ORRI 0xb2000000 -#define RBIT 0xdac00000 -#define RET 0xd65f0000 -#define RORV 0x9ac02c00 -#define SBC 0xda000000 -#define SBFM 0x93000000 -#define SCVTF 0x9e620000 -#define SDIV 0x9ac00c00 -#define SMADDL 0x9b200000 -#define SMULH 0x9b403c00 -#define STP 0xa9000000 -#define STP_F64 0x6d000000 -#define STP_PRE 0xa9800000 -#define STRB 0x38206800 -#define STRBI 0x39000000 -#define STRI 0xf9000000 -#define STRI_F64 0xfd000000 -#define STR_FI 0x3d000000 -#define STR_FR 0x3c206800 -#define STUR_FI 0x3c000000 -#define STURBI 0x38000000 -#define SUB 0xcb000000 -#define SUBI 0xd1000000 -#define SUBS 0xeb000000 -#define UBFM 0xd3000000 -#define UDIV 0x9ac00800 -#define UMULH 0x9bc03c00 +#define ADC 0x9a000000 +#define ADD 0x8b000000 +#define ADDE 0x8b200000 +#define ADDI 0x91000000 +#define AND 0x8a000000 +#define ANDI 0x92000000 +#define AND_v 0x0e201c00 +#define ASRV 0x9ac02800 +#define B 0x14000000 +#define B_CC 0x54000000 +#define BL 0x94000000 +#define BLR 0xd63f0000 +#define BR 0xd61f0000 +#define BRK 0xd4200000 +#define CAS 0xc8a07c00 +#define CASB 0x08a07c00 +#define CASH 0x48a07c00 +#define CBZ 0xb4000000 +#define CCMPI 0xfa400800 +#define CLZ 0xdac01000 +#define CSEL 0x9a800000 +#define CSINC 0x9a800400 +#define DUP_e 0x0e000400 +#define DUP_g 0x0e000c00 +#define EOR 0xca000000 +#define EOR_v 0x2e201c00 +#define EORI 0xd2000000 +#define EXTR 0x93c00000 +#define FABS 0x1e60c000 +#define FADD 0x1e602800 +#define FCMP 0x1e602000 +#define FCSEL 0x1e600c00 +#define FCVT 0x1e224000 +#define FCVTL 0x0e217800 +#define FCVTZS 0x9e780000 +#define FDIV 0x1e601800 +#define FMOV 0x1e604000 +#define FMOV_R 0x9e660000 +#define FMOV_I 0x1e601000 +#define FMUL 0x1e600800 +#define FNEG 0x1e614000 +#define FSUB 0x1e603800 +#define INS 0x4e001c00 +#define INS_e 0x6e000400 +#define LD1 0x0c407000 +#define LD1_s 0x0d400000 +#define LD1R 0x0d40c000 +#define LDRI 0xf9400000 +#define LDRI_F64 0xfd400000 +#define LDRI_POST 0xf8400400 +#define LDP 0xa9400000 +#define LDP_F64 0x6d400000 +#define LDP_POST 0xa8c00000 +#define LDR_PRE 0xf8400c00 +#define LDXR 0xc85f7c00 +#define LDXRB 0x085f7c00 +#define LDXRH 0x485f7c00 +#define LSLV 0x9ac02000 +#define LSRV 0x9ac02400 +#define MADD 0x9b000000 +#define MOVI 0x0f000400 +#define MOVK 0xf2800000 +#define MOVN 0x92800000 +#define MOVZ 0xd2800000 +#define NOP 0xd503201f +#define ORN 0xaa200000 +#define ORR 0xaa000000 +#define ORR_v 0x0ea01c00 +#define ORRI 0xb2000000 +#define RBIT 0xdac00000 +#define RET 0xd65f0000 +#define REV 0xdac00c00 +#define REV16 0xdac00400 +#define RORV 0x9ac02c00 +#define SBC 0xda000000 +#define SBFM 0x93400000 +#define SCVTF 0x9e620000 +#define SDIV 0x9ac00c00 +#define SMADDL 0x9b200000 +#define SMOV 0x0e002c00 +#define SMULH 0x9b403c00 +#define SSHLL 0x0f00a400 +#define ST1 0x0c007000 +#define ST1_s 0x0d000000 +#define STP 0xa9000000 +#define STP_F64 0x6d000000 +#define STP_PRE 0xa9800000 +#define STRB 0x38206800 +#define STRBI 0x39000000 +#define STRI 0xf9000000 +#define STRI_F64 0xfd000000 +#define STR_FI 0x3d000000 +#define STR_FR 0x3c206800 +#define STUR_FI 0x3c000000 +#define STURBI 0x38000000 +#define STXR 0xc8007c00 +#define STXRB 0x8007c00 +#define STXRH 0x48007c00 +#define SUB 0xcb000000 +#define SUBI 0xd1000000 +#define SUBS 0xeb000000 +#define TBZ 0x36000000 +#define UBFM 0xd3400000 +#define UCVTF 0x9e630000 +#define UDIV 0x9ac00800 +#define UMOV 0x0e003c00 +#define UMULH 0x9bc03c00 +#define USHLL 0x2f00a400 +#define USHR 0x2f000400 +#define USRA 0x2f001400 +#define XTN 0x0e212800 + +#define CSET (CSINC | RM(TMP_ZERO) | RN(TMP_ZERO)) +#define LDR (STRI | (1 << 22)) +#define LDRB (STRBI | (1 << 22)) +#define LDRH (LDRB | (1 << 30)) +#define MOV (ORR | RN(TMP_ZERO)) static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins) { @@ -175,7 +219,7 @@ static SLJIT_INLINE sljit_sw detect_jump_type(struct sljit_jump *jump, sljit_ins target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset; } - diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4) - executable_offset; + diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr - 4) - executable_offset; if (jump->flags & IS_COND) { diff += SSIZE_OF(ins); @@ -385,8 +429,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) { switch (feature_type) { case SLJIT_HAS_FPU: + case SLJIT_HAS_SIMD: #ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; + return (SLJIT_IS_FPU_AVAILABLE) != 0; #else /* Available by default. */ return 1; @@ -394,9 +439,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) case SLJIT_HAS_CLZ: case SLJIT_HAS_CTZ: + case SLJIT_HAS_REV: case SLJIT_HAS_ROT: case SLJIT_HAS_CMOV: case SLJIT_HAS_PREFETCH: + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: + case SLJIT_HAS_ATOMIC: return 1; default: @@ -404,6 +453,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) } } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) +{ + switch (type) { + case SLJIT_UNORDERED_OR_EQUAL: + case SLJIT_ORDERED_NOT_EQUAL: + return 2; + } + + return 0; +} + /* --------------------------------------------------------------------- */ /* Core code generator functions. */ /* --------------------------------------------------------------------- */ @@ -636,6 +696,11 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s case SLJIT_MUL: case SLJIT_CLZ: case SLJIT_CTZ: + case SLJIT_REV: + case SLJIT_REV_U16: + case SLJIT_REV_S16: + case SLJIT_REV_U32: + case SLJIT_REV_S32: case SLJIT_ADDC: case SLJIT_SUBC: /* No form with immediate operand (except imm 0, which @@ -644,10 +709,6 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s case SLJIT_MOV: SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG1); return load_immediate(compiler, dst, imm); - case SLJIT_NOT: - SLJIT_ASSERT(flags & ARG2_IMM); - FAIL_IF(load_immediate(compiler, dst, (flags & INT_OP) ? (~imm & 0xffffffff) : ~imm)); - goto set_flags; case SLJIT_SUB: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB; if (flags & ARG1_IMM) @@ -694,8 +755,13 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s break; CHECK_FLAGS(3 << 29); return push_inst(compiler, (ANDI ^ inv_bits) | RD(dst) | RN(reg) | inst_bits); - case SLJIT_OR: case SLJIT_XOR: + if (imm == -1) { + FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(reg))); + goto set_flags; + } + /* fallthrough */ + case SLJIT_OR: inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32)); if (!inst_bits) break; @@ -718,6 +784,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s inst_bits = ((sljit_ins)1 << 22) | (((sljit_ins)-imm & 0x3f) << 16) | ((63 - (sljit_ins)imm) << 10); } + inv_bits |= inv_bits >> 9; FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg1) | inst_bits)); goto set_flags; case SLJIT_LSHR: @@ -727,6 +794,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s if (flags & ARG1_IMM) break; + inv_bits |= inv_bits >> 9; if (op >= SLJIT_ASHR) inv_bits |= 1 << 30; @@ -780,22 +848,22 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (dst == arg2) return SLJIT_SUCCESS; - return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2)); + return push_inst(compiler, MOV | RD(dst) | RM(arg2)); case SLJIT_MOV_U8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - return push_inst(compiler, (UBFM ^ W_OP) | RD(dst) | RN(arg2) | (7 << 10)); + inv_bits |= inv_bits >> 9; + return push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10)); case SLJIT_MOV_S8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (!(flags & INT_OP)) - inv_bits |= 1 << 22; + inv_bits |= inv_bits >> 9; return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10)); case SLJIT_MOV_U16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - return push_inst(compiler, (UBFM ^ W_OP) | RD(dst) | RN(arg2) | (15 << 10)); + inv_bits |= inv_bits >> 9; + return push_inst(compiler, (UBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10)); case SLJIT_MOV_S16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - if (!(flags & INT_OP)) - inv_bits |= 1 << 22; + inv_bits |= inv_bits >> 9; return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (15 << 10)); case SLJIT_MOV32: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); @@ -804,14 +872,10 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s /* fallthrough */ case SLJIT_MOV_U32: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - return push_inst(compiler, (ORR ^ W_OP) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); + return push_inst(compiler, (MOV ^ W_OP) | RD(dst) | RM(arg2)); case SLJIT_MOV_S32: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(arg2) | (31 << 10)); - case SLJIT_NOT: - SLJIT_ASSERT(arg1 == TMP_REG1); - FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(arg2))); - break; /* Set flags. */ case SLJIT_CLZ: SLJIT_ASSERT(arg1 == TMP_REG1); return push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(arg2)); @@ -819,6 +883,25 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s SLJIT_ASSERT(arg1 == TMP_REG1); FAIL_IF(push_inst(compiler, (RBIT ^ inv_bits) | RD(dst) | RN(arg2))); return push_inst(compiler, (CLZ ^ inv_bits) | RD(dst) | RN(dst)); + case SLJIT_REV: + SLJIT_ASSERT(arg1 == TMP_REG1); + inv_bits |= inv_bits >> 21; + return push_inst(compiler, (REV ^ inv_bits) | RD(dst) | RN(arg2)); + case SLJIT_REV_U16: + case SLJIT_REV_S16: + SLJIT_ASSERT(arg1 == TMP_REG1 && dst != TMP_REG2); + FAIL_IF(push_inst(compiler, (REV16 ^ (sljit_ins)0x80000000) | RD(dst) | RN(arg2))); + if (dst == TMP_REG1 || (arg2 == TMP_REG2 && op == SLJIT_REV_U16)) + return SLJIT_SUCCESS; + inv_bits |= inv_bits >> 9; + return push_inst(compiler, ((op == SLJIT_REV_U16 ? UBFM : SBFM) ^ inv_bits) | RD(dst) | RN(dst) | (15 << 10)); + case SLJIT_REV_U32: + case SLJIT_REV_S32: + SLJIT_ASSERT(arg1 == TMP_REG1 && dst != TMP_REG2); + FAIL_IF(push_inst(compiler, (REV ^ (sljit_ins)0x80000400) | RD(dst) | RN(arg2))); + if (op == SLJIT_REV_U32 || dst == TMP_REG1) + return SLJIT_SUCCESS; + return push_inst(compiler, SBFM | (1 << 22) | RD(dst) | RN(dst) | (31 << 10)); case SLJIT_ADD: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; CHECK_FLAGS(1 << 29); @@ -980,7 +1063,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 2); - saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, SSIZE_OF(f64)); + saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); local_size = (local_size + saved_regs_size + 0xf) & ~0xf; compiler->local_size = local_size; @@ -1065,7 +1148,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi while (arg_types) { if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) { if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) { - FAIL_IF(push_inst(compiler, ORR | RD(SLJIT_S0 - saved_arg_count) | RN(TMP_ZERO) | RM(tmp))); + FAIL_IF(push_inst(compiler, MOV | RD(SLJIT_S0 - saved_arg_count) | RM(tmp))); saved_arg_count++; } tmp++; @@ -1153,7 +1236,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); saved_regs_size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 2); - saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, SSIZE_OF(f64)); + saved_regs_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); compiler->local_size = (local_size + saved_regs_size + 0xf) & ~0xf; return SLJIT_SUCCESS; @@ -1272,7 +1355,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c src = TMP_REG1; srcw = 0; } else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) { - FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(src))); + FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src))); src = TMP_REG1; srcw = 0; } @@ -1302,12 +1385,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return push_inst(compiler, NOP); case SLJIT_LMUL_UW: case SLJIT_LMUL_SW: - FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); + FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(SLJIT_R0))); FAIL_IF(push_inst(compiler, MADD | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); return push_inst(compiler, (op == SLJIT_LMUL_UW ? UMULH : SMULH) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); case SLJIT_DIVMOD_UW: case SLJIT_DIVMOD_SW: - FAIL_IF(push_inst(compiler, (ORR ^ inv_bits) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(SLJIT_R0))); + FAIL_IF(push_inst(compiler, (MOV ^ inv_bits) | RD(TMP_REG1) | RM(SLJIT_R0))); FAIL_IF(push_inst(compiler, ((op == SLJIT_DIVMOD_UW ? UDIV : SDIV) ^ inv_bits) | RD(SLJIT_R0) | RN(SLJIT_R0) | RM(SLJIT_R1))); FAIL_IF(push_inst(compiler, (MADD ^ inv_bits) | RD(SLJIT_R1) | RN(SLJIT_R0) | RM(SLJIT_R1) | RT2(TMP_ZERO))); return push_inst(compiler, (SUB ^ inv_bits) | RD(SLJIT_R1) | RN(TMP_REG1) | RM(SLJIT_R1)); @@ -1349,33 +1432,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile break; case SLJIT_MOV_U8: mem_flags = BYTE_SIZE; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_u8)srcw; break; case SLJIT_MOV_S8: mem_flags = BYTE_SIZE | SIGNED; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_s8)srcw; break; case SLJIT_MOV_U16: mem_flags = HALF_SIZE; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_u16)srcw; break; case SLJIT_MOV_S16: mem_flags = HALF_SIZE | SIGNED; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_s16)srcw; break; case SLJIT_MOV_U32: mem_flags = INT_SIZE; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_u32)srcw; break; case SLJIT_MOV_S32: case SLJIT_MOV32: mem_flags = INT_SIZE | SIGNED; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_s32)srcw; break; default: @@ -1384,7 +1467,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile break; } - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw)); else if (!(src & SLJIT_MEM)) dst_r = src; @@ -1397,11 +1480,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile } flags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0; - mem_flags = WORD_SIZE; - if (op_flags & SLJIT_32) { - flags |= INT_OP; + switch (op) { + case SLJIT_REV_U16: + case SLJIT_REV_S16: + mem_flags = HALF_SIZE; + break; + case SLJIT_REV_U32: + case SLJIT_REV_S32: mem_flags = INT_SIZE; + break; + default: + mem_flags = WORD_SIZE; + + if (op_flags & SLJIT_32) { + flags |= INT_OP; + mem_flags = INT_SIZE; + } + break; } if (src & SLJIT_MEM) { @@ -1451,12 +1547,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile src2 = TMP_REG2; } - if (src1 & SLJIT_IMM) + if (src1 == SLJIT_IMM) flags |= ARG1_IMM; else src1w = src1; - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) flags |= ARG2_IMM; else src2w = src2; @@ -1480,57 +1576,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_ins inv_bits, imm; sljit_s32 is_left; sljit_sw mask; CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); inv_bits = (op & SLJIT_32) ? W_OP : 0; - mask = inv_bits ? 0x1f : 0x3f; - if (src2 & SLJIT_IMM) { - src2w &= mask; + if (src3 == SLJIT_IMM) { + mask = inv_bits ? 0x1f : 0x3f; + src3w &= mask; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG2, src2, src2w, TMP_REG2)); - src2 = TMP_REG2; - } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); - src1 = TMP_REG1; - } - - if (src2 & SLJIT_IMM) { if (is_left) - src2w = (src2w ^ mask) + 1; + src3w = (src3w ^ mask) + 1; - return push_inst(compiler, (EXTR ^ (inv_bits | (inv_bits >> 9))) | RD(src_dst) - | RN(is_left ? src_dst : src1) | RM(is_left ? src1 : src_dst) | ((sljit_ins)src2w << 10)); + return push_inst(compiler, (EXTR ^ (inv_bits | (inv_bits >> 9))) | RD(dst_reg) + | RN(is_left ? src1_reg : src2_reg) | RM(is_left ? src2_reg : src1_reg) | ((sljit_ins)src3w << 10)); } - FAIL_IF(push_inst(compiler, ((is_left ? LSLV : LSRV) ^ inv_bits) | RD(src_dst) | RN(src_dst) | RM(src2))); + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG2, src3, src3w, TMP_REG2)); + src3 = TMP_REG2; + } else if (dst_reg == src3) { + FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src3))); + src3 = TMP_REG2; + } + + FAIL_IF(push_inst(compiler, ((is_left ? LSLV : LSRV) ^ inv_bits) | RD(dst_reg) | RN(src1_reg) | RM(src3))); if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) { /* Shift left/right by 1. */ @@ -1539,18 +1630,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * else imm = (sljit_ins)(inv_bits ? ((31 << 16) | (30 << 10)) : ((63 << 16) | (62 << 10) | (1 << 22))); - FAIL_IF(push_inst(compiler, (UBFM ^ inv_bits) | RD(TMP_REG1) | RN(src1) | imm)); + FAIL_IF(push_inst(compiler, (UBFM ^ (inv_bits | (inv_bits >> 9))) | RD(TMP_REG1) | RN(src2_reg) | imm)); /* Set imm to mask. */ imm = (sljit_ins)(inv_bits ? (4 << 10) : ((5 << 10) | (1 << 22))); - FAIL_IF(push_inst(compiler, (EORI ^ inv_bits) | RD(TMP_REG2) | RN(src2) | imm)); + FAIL_IF(push_inst(compiler, (EORI ^ inv_bits) | RD(TMP_REG2) | RN(src3) | imm)); - src1 = TMP_REG1; + src2_reg = TMP_REG1; } else - FAIL_IF(push_inst(compiler, (SUB ^ inv_bits) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(src2))); + FAIL_IF(push_inst(compiler, (SUB ^ inv_bits) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(src3))); - FAIL_IF(push_inst(compiler, ((is_left ? LSRV : LSLV) ^ inv_bits) | RD(TMP_REG1) | RN(src1) | RM(TMP_REG2))); - return push_inst(compiler, (ORR ^ inv_bits) | RD(src_dst) | RN(src_dst) | RM(TMP_REG1)); + FAIL_IF(push_inst(compiler, ((is_left ? LSRV : LSLV) ^ inv_bits) | RD(TMP_REG1) | RN(src2_reg) | RM(TMP_REG2))); + return push_inst(compiler, (ORR ^ inv_bits) | RD(dst_reg) | RN(dst_reg) | RM(TMP_REG1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, @@ -1563,7 +1654,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp switch (op) { case SLJIT_FAST_RETURN: if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, ORR | RD(TMP_LR) | RN(TMP_ZERO) | RM(src))); + FAIL_IF(push_inst(compiler, MOV | RD(TMP_LR) | RM(src))); else FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1)); @@ -1593,15 +1684,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 dst_r = TMP_LR; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + if (FAST_IS_REG(dst)) + return push_inst(compiler, MOV | RD(dst) | RM(TMP_LR)); + break; + case SLJIT_GET_RETURN_ADDRESS: + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, dst_r, SLJIT_MEM1(SLJIT_SP), 0x8, TMP_REG2)); + break; + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type != SLJIT_FLOAT_REGISTER && type != SLJIT_SIMD_REG_64 && type != SLJIT_SIMD_REG_128) + return -1; + return freg_map[reg]; } @@ -1679,7 +1797,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp inv_bits |= W_OP; if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw)); src = TMP_FREG1; } @@ -1690,34 +1808,59 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0; - - if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) - inv_bits |= W_OP; if (src & SLJIT_MEM) { - emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw, TMP_REG1); + emit_op_mem(compiler, (ins & W_OP) ? WORD_SIZE : INT_SIZE, TMP_REG1, src, srcw, TMP_REG1); src = TMP_REG1; - } else if (src & SLJIT_IMM) { - if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) - srcw = (sljit_s32)srcw; - + } else if (src == SLJIT_IMM) { FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); src = TMP_REG1; } - FAIL_IF(push_inst(compiler, (SCVTF ^ inv_bits) | VD(dst_r) | RN(src))); + FAIL_IF(push_inst(compiler, ins | VD(dst_r) | RN(src))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, ((op & SLJIT_32) ? INT_SIZE : WORD_SIZE) | STORE, TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, ((ins & (1 << 22)) ? WORD_SIZE : INT_SIZE) | STORE, TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0; + + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) { + inv_bits |= W_OP; + + if (src == SLJIT_IMM) + srcw = (sljit_s32)srcw; + } + + return sljit_emit_fop1_conv_f64_from_w(compiler, SCVTF ^ inv_bits, dst, dstw, src, srcw); +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0; + + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) { + inv_bits |= W_OP; + + if (src == SLJIT_IMM) + srcw = (sljit_u32)srcw; + } + + return sljit_emit_fop1_conv_f64_from_w(compiler, UCVTF ^ inv_bits, dst, dstw, src, srcw); +} + static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) @@ -1726,16 +1869,22 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile sljit_ins inv_bits = (op & SLJIT_32) ? (1 << 22) : 0; if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); + FAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w); + FAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } - return push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2)); + FAIL_IF(push_inst(compiler, (FCMP ^ inv_bits) | VN(src1) | VM(src2))); + + if (GET_FLAG_TYPE(op) != SLJIT_UNORDERED_OR_EQUAL) + return SLJIT_SUCCESS; + + FAIL_IF(push_inst(compiler, CSINC | (0x0 << 12) | RD(TMP_REG1) | RN(TMP_ZERO) | RM(TMP_ZERO))); + return push_inst(compiler, CCMPI | (0x0 << 16) | (0x7 << 12) | RN(TMP_REG1) | 0x4); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, @@ -1754,7 +1903,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x1) : mem_flags, dst_r, src, srcw); + FAIL_IF(emit_fop_mem(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32) ? (mem_flags ^ 0x1) : mem_flags, dst_r, src, srcw)); src = dst_r; } @@ -1799,11 +1948,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w); + FAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w); + FAIL_IF(emit_fop_mem(compiler, mem_flags, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } @@ -1820,6 +1969,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, (FDIV ^ inv_bits) | VD(dst_r) | VN(src1) | VM(src2))); break; + case SLJIT_COPYSIGN_F64: + FAIL_IF(push_inst(compiler, (FMOV_R ^ ((op & SLJIT_32) ? (W_OP | (1 << 22)) : 0)) | VN(src2) | RD(TMP_REG1))); + FAIL_IF(push_inst(compiler, (FABS ^ inv_bits) | VD(dst_r) | VN(src1))); + FAIL_IF(push_inst(compiler, TBZ | ((op & SLJIT_32) ? 0 : ((sljit_ins)1 << 31)) | (0x1f << 19) | (2 << 5) | RT(TMP_REG1))); + return push_inst(compiler, (FNEG ^ inv_bits) | VD(dst_r) | VN(dst_r)); } if (!(dst & SLJIT_MEM)) @@ -1827,21 +1981,79 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return emit_fop_mem(compiler, mem_flags | STORE, TMP_FREG1, dst, dstw); } -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { + sljit_u32 exp; + union { + sljit_u32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - if (FAST_IS_REG(dst)) - return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(TMP_LR)); + u.value = value; - /* Memory. */ - return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_LR, dst, dstw, TMP_REG1); + if (u.imm == 0) + return push_inst(compiler, (FMOV_R ^ (W_OP | (1 << 22))) | RN(TMP_ZERO) | VD(freg) | (1 << 16)); + + if ((u.imm << (32 - 19)) == 0) { + exp = (u.imm >> (23 + 2)) & 0x3f; + + if (exp == 0x20 || exp == 0x1f) + return push_inst(compiler, (FMOV_I ^ (1 << 22)) | (sljit_ins)((((u.imm >> 24) & 0x80) | ((u.imm >> 19) & 0x7f)) << 13) | VD(freg)); + } + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_s32)u.imm)); + return push_inst(compiler, (FMOV_R ^ (W_OP | (1 << 22))) | RN(TMP_REG1) | VD(freg) | (1 << 16)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + sljit_uw exp; + union { + sljit_uw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm == 0) + return push_inst(compiler, FMOV_R | RN(TMP_ZERO) | VD(freg) | (sljit_ins)1 << 16); + + if ((u.imm << (64 - 48)) == 0) { + exp = (u.imm >> (52 + 2)) & 0x1ff; + + if (exp == 0x100 || exp == 0xff) + return push_inst(compiler, FMOV_I | (sljit_ins)((((u.imm >> 56) & 0x80) | ((u.imm >> 48) & 0x7f)) << 13) | VD(freg)); + } + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_sw)u.imm)); + return push_inst(compiler, FMOV_R | RN(TMP_REG1) | VD(freg) | (1 << 16)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_ins inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) + inst = FMOV_R | RN(reg) | VD(freg) | (1 << 16); + else + inst = FMOV_R | VN(freg) | RD(reg); + + if (op & SLJIT_32) + inst ^= W_OP | (1 << 22); + + return push_inst(compiler, inst); } /* --------------------------------------------------------------------- */ @@ -1852,15 +2064,17 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type) { switch (type) { case SLJIT_EQUAL: + case SLJIT_ATOMIC_STORED: case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: - case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */ + case SLJIT_UNORDERED_OR_EQUAL: return 0x1; case SLJIT_NOT_EQUAL: + case SLJIT_ATOMIC_NOT_STORED: case SLJIT_F_NOT_EQUAL: case SLJIT_UNORDERED_OR_NOT_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */ + case SLJIT_ORDERED_NOT_EQUAL: return 0x0; case SLJIT_CARRY: @@ -2011,7 +2225,7 @@ static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compi PTR_FAIL_IF(emit_op_mem(compiler, inv_bits ? INT_SIZE : WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1)); src = TMP_REG1; } - else if (src & SLJIT_IMM) { + else if (src == SLJIT_IMM) { PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); src = TMP_REG1; } @@ -2035,7 +2249,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { if (src & SLJIT_MEM) { ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1)); @@ -2071,7 +2285,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi if (type & SLJIT_CALL_RETURN) { if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) { - FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(src))); + FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src))); src = TMP_REG1; } @@ -2131,27 +2345,53 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { sljit_ins inv_bits = (type & SLJIT_32) ? W_OP : 0; sljit_ins cc; CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); - if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (src1 == SLJIT_IMM) { if (type & SLJIT_32) - srcw = (sljit_s32)srcw; - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - srcw = 0; + src1w = (sljit_s32)src1w; + FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); + src1 = TMP_REG1; + } else if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG2)); + src1 = TMP_REG1; } cc = get_cc(compiler, type & ~SLJIT_32); + return push_inst(compiler, (CSEL ^ inv_bits) | (cc << 12) | RD(dst_reg) | RN(src2_reg) | RM(src1)); +} - return push_inst(compiler, (CSEL ^ inv_bits) | (cc << 12) | RD(dst_reg) | RN(dst_reg) | RM(src)); +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_ins inv_bits = (type & SLJIT_32) ? (1 << 22) : 0; + sljit_ins cc; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src1, src1w)); + src1 = TMP_FREG1; + } + + cc = get_cc(compiler, type & ~SLJIT_32); + return push_inst(compiler, (FCSEL ^ inv_bits) | (cc << 12) | VD(dst_freg) | VN(src2_freg) | VM(src1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, @@ -2308,6 +2548,661 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler return push_inst(compiler, inst | VT(freg) | RN(mem & REG_MASK) | (sljit_ins)((memw & 0x1ff) << 12)); } +static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, sljit_s32 *mem_ptr, sljit_sw memw) +{ + sljit_ins ins; + sljit_s32 mem = *mem_ptr; + + if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { + *mem_ptr = TMP_REG1; + return push_inst(compiler, ADD | RD(TMP_REG1) | RN(mem & REG_MASK) | RM(OFFS_REG(mem)) | ((sljit_ins)(memw & 0x3) << 10)); + } + + if (!(mem & REG_MASK)) { + *mem_ptr = TMP_REG1; + return load_immediate(compiler, TMP_REG1, memw); + } + + mem &= REG_MASK; + + if (memw == 0) { + *mem_ptr = mem; + return SLJIT_SUCCESS; + } + + *mem_ptr = TMP_REG1; + + if (memw < -0xffffff || memw > 0xffffff) { + FAIL_IF(load_immediate(compiler, TMP_REG1, memw)); + return push_inst(compiler, ADD | RD(TMP_REG1) | RN(TMP_REG1) | RM(mem)); + } + + ins = ADDI; + + if (memw < 0) { + memw = -memw; + ins = SUBI; + } + + if (memw > 0xfff) { + FAIL_IF(push_inst(compiler, ins | (1 << 22) | RD(TMP_REG1) | RN(mem) | ((sljit_ins)(memw >> 12) << 10))); + + memw &= 0xfff; + if (memw == 0) + return SLJIT_SUCCESS; + + mem = TMP_REG1; + } + + return push_inst(compiler, ins | RD(TMP_REG1) | RN(mem) | ((sljit_ins)memw << 10)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (!(srcdst & SLJIT_MEM)) { + if (type & SLJIT_SIMD_STORE) + ins = VD(srcdst) | VN(freg) | VM(freg); + else + ins = VD(freg) | VN(srcdst) | VM(srcdst); + + if (reg_size == 4) + ins |= (1 << 30); + + return push_inst(compiler, ORR_v | ins); + } + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + if (elem_size > 3) + elem_size = 3; + + ins = (type & SLJIT_SIMD_STORE) ? ST1 : LD1; + + if (reg_size == 4) + ins |= (1 << 30); + + return push_inst(compiler, ins | ((sljit_ins)elem_size << 10) | RN(srcdst) | VT(freg)); +} + +static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) +{ + sljit_ins result; + + if (elem_size > 2 && (sljit_u32)value == (value >> 32)) { + elem_size = 2; + value = (sljit_u32)value; + } + + if (elem_size == 2 && (sljit_u16)value == (value >> 16)) { + elem_size = 1; + value = (sljit_u16)value; + } + + if (elem_size == 1 && (sljit_u8)value == (value >> 8)) { + elem_size = 0; + value = (sljit_u8)value; + } + + switch (elem_size) { + case 0: + SLJIT_ASSERT(value <= 0xff); + result = 0xe000; + break; + case 1: + SLJIT_ASSERT(value <= 0xffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x8000; + break; + } + + if ((value & 0xff) == 0) { + value >>= 8; + result |= 0xa000; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value ^= (sljit_uw)0xffff; + result = (1 << 29); + } + break; + case 2: + SLJIT_ASSERT(value <= 0xffffffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x0000; + break; + } + + if ((value & ~(sljit_uw)0xff00) == 0) { + value >>= 8; + result |= 0x2000; + break; + } + + if ((value & ~(sljit_uw)0xff0000) == 0) { + value >>= 16; + result |= 0x4000; + break; + } + + if ((value & ~(sljit_uw)0xff000000) == 0) { + value >>= 24; + result |= 0x6000; + break; + } + + if ((value & (sljit_uw)0xff) == 0xff && (value >> 16) == 0) { + value >>= 8; + result |= 0xc000; + break; + } + + if ((value & (sljit_uw)0xffff) == 0xffff && (value >> 24) == 0) { + value >>= 16; + result |= 0xd000; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value ^= (sljit_uw)0xffffffff; + result = (1 << 29); + } + break; + default: + return ~(sljit_ins)0; + } + + return (((sljit_ins)value & 0x1f) << 5) | (((sljit_ins)value & 0xe0) << 11) | result; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imm; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + + ins = (sljit_ins)elem_size << 10; + + if (reg_size == 4) + ins |= (sljit_ins)1 << 30; + + return push_inst(compiler, LD1R | ins | RN(src) | VT(freg)); + } + + ins = (sljit_ins)1 << (16 + elem_size); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 30; + + if (type & SLJIT_SIMD_FLOAT) { + if (src == SLJIT_IMM) + return push_inst(compiler, MOVI | (ins & ((sljit_ins)1 << 30)) | VD(freg)); + + return push_inst(compiler, DUP_e | ins | VD(freg) | VN(src)); + } + + if (src == SLJIT_IMM) { + if (elem_size < 3) + srcw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + imm = simd_get_imm(elem_size, (sljit_uw)srcw); + + if (imm != ~(sljit_ins)0) { + imm |= ins & ((sljit_ins)1 << 30); + + return push_inst(compiler, MOVI | imm | VD(freg)); + } + + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } + + return push_inst(compiler, DUP_g | ins | VD(freg) | RN(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (type & SLJIT_SIMD_LANE_ZERO) { + ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 30); + + if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { + FAIL_IF(push_inst(compiler, ORR_v | ins | VD(TMP_FREG1) | VN(freg) | VM(freg))); + srcdst = TMP_FREG1; + srcdstw = 0; + } + + FAIL_IF(push_inst(compiler, MOVI | ins | VD(freg))); + } + + if (srcdst & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + if (elem_size == 3) + ins = 0x8400; + else if (elem_size == 0) + ins = 0; + else + ins = (sljit_ins)0x2000 << elem_size; + + lane_index = lane_index << elem_size; + ins |= (sljit_ins)(((lane_index & 0x8) << 27) | ((lane_index & 0x7) << 10)); + + return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? ST1_s : LD1_s) | ins | RN(srcdst) | VT(freg)); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (type & SLJIT_SIMD_STORE) + ins = INS_e | ((sljit_ins)1 << (16 + elem_size)) | ((sljit_ins)lane_index << (11 + elem_size)) | VD(srcdst) | VN(freg); + else + ins = INS_e | ((((sljit_ins)lane_index << 1) | 1) << (16 + elem_size)) | VD(freg) | VN(srcdst); + + return push_inst(compiler, ins); + } + + if (srcdst == SLJIT_IMM) { + if (elem_size < 3) + srcdstw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + FAIL_IF(load_immediate(compiler, TMP_REG1, srcdstw)); + srcdst = TMP_REG1; + } + + if (type & SLJIT_SIMD_STORE) { + ins = RD(srcdst) | VN(freg); + + if ((type & SLJIT_SIMD_LANE_SIGNED) && (elem_size < 2 || (elem_size == 2 && !(type & SLJIT_32)))) { + ins |= SMOV; + + if (!(type & SLJIT_32)) + ins |= (sljit_ins)1 << 30; + } else + ins |= UMOV; + } else + ins = INS | VD(freg) | RN(srcdst); + + if (elem_size == 3) + ins |= (sljit_ins)1 << 30; + + return push_inst(compiler, ins | ((((sljit_ins)lane_index << 1) | 1) << (16 + elem_size))); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + ins = (((sljit_ins)src_lane_index << 1) | 1) << (16 + elem_size); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 30; + + return push_inst(compiler, DUP_e | ins | VD(freg) | VN(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size != 2 || elem2_size != 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + + if (reg_size == 4 && elem2_size - elem_size == 1) + FAIL_IF(push_inst(compiler, LD1 | ((sljit_ins)elem_size << 10) | RN(src) | VT(freg))); + else + FAIL_IF(push_inst(compiler, LD1_s | ((sljit_ins)0x2000 << (reg_size - elem2_size + elem_size)) | RN(src) | VT(freg))); + src = freg; + } + + if (type & SLJIT_SIMD_FLOAT) { + SLJIT_ASSERT(reg_size == 4); + return push_inst(compiler, FCVTL | (1 << 22) | VD(freg) | VN(src)); + } + + do { + FAIL_IF(push_inst(compiler, ((type & SLJIT_SIMD_EXTEND_SIGNED) ? SSHLL : USHLL) + | ((sljit_ins)1 << (19 + elem_size)) | VD(freg) | VN(src))); + src = freg; + } while (++elem_size < elem2_size); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imms; + sljit_s32 dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + switch (elem_size) { + case 0: + imms = 0x643219; + ins = USHR | (0x9 << 16); + break; + case 1: + imms = (reg_size == 4) ? 0x643219 : 0x6231; + ins = USHR | (0x11 << 16); + break; + case 2: + imms = (reg_size == 4) ? 0x6231 : 0x61; + ins = USHR | (0x21 << 16); + break; + default: + imms = 0x61; + ins = USHR | (0x41 << 16); + break; + } + + if (reg_size == 4) + ins |= (1 << 30); + + FAIL_IF(push_inst(compiler, ins | VD(TMP_FREG1) | VN(freg))); + + if (reg_size == 4 && elem_size > 0) + FAIL_IF(push_inst(compiler, XTN | ((sljit_ins)(elem_size - 1) << 22) | VD(TMP_FREG1) | VN(TMP_FREG1))); + + if (imms >= 0x100) { + ins = (reg_size == 4 && elem_size == 0) ? (1 << 30) : 0; + + do { + FAIL_IF(push_inst(compiler, USRA | ins | ((imms & 0xff) << 16) | VD(TMP_FREG1) | VN(TMP_FREG1))); + imms >>= 8; + } while (imms >= 0x100); + } + + FAIL_IF(push_inst(compiler, USRA | (1 << 30) | (imms << 16) | VD(TMP_FREG1) | VN(TMP_FREG1))); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + ins = (0x1 << 16); + + if (reg_size == 4 && elem_size == 0) { + FAIL_IF(push_inst(compiler, INS_e | (0x3 << 16) | (0x8 << 11) | VD(TMP_FREG1) | VN(TMP_FREG1))); + ins = (0x2 << 16); + } + + FAIL_IF(push_inst(compiler, UMOV | ins | RD(dst_r) | VN(TMP_FREG1))); + + if (dst_r == TMP_REG1) + return emit_op_mem(compiler, STORE | ((type & SLJIT_32) ? INT_SIZE : WORD_SIZE), TMP_REG1, dst, dstw, TMP_REG2); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + switch (SLJIT_SIMD_GET_OPCODE(type)) { + case SLJIT_SIMD_OP2_AND: + ins = AND_v; + break; + case SLJIT_SIMD_OP2_OR: + ins = ORR_v; + break; + case SLJIT_SIMD_OP2_XOR: + ins = EOR_v; + break; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + ins |= (sljit_ins)1 << 30; + + return push_inst(compiler, ins | VD(dst_freg) | VN(src1_freg) | VM(src2_freg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + +#ifdef __ARM_FEATURE_ATOMICS + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + ins = LDR ^ (1 << 30); + break; + case SLJIT_MOV_U16: + ins = LDRH; + break; + case SLJIT_MOV_U8: + ins = LDRB; + break; + default: + ins = LDR; + break; + } +#else /* !__ARM_FEATURE_ATOMICS */ + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + ins = LDXR ^ (1 << 30); + break; + case SLJIT_MOV_U8: + ins = LDXRB; + break; + case SLJIT_MOV_U16: + ins = LDXRH; + break; + default: + ins = LDXR; + break; + } +#endif /* ARM_FEATURE_ATOMICS */ + return push_inst(compiler, ins | RN(mem_reg) | RT(dst_reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_ins ins; + sljit_s32 tmp = temp_reg; + sljit_ins cmp = 0; + sljit_ins inv_bits = W_OP; + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + +#ifdef __ARM_FEATURE_ATOMICS + if (op & SLJIT_SET_ATOMIC_STORED) + cmp = (SUBS ^ W_OP) | RD(TMP_ZERO); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + ins = CAS ^ (1 << 30); + break; + case SLJIT_MOV_U16: + ins = CASH; + break; + case SLJIT_MOV_U8: + ins = CASB; + break; + default: + ins = CAS; + inv_bits = 0; + if (cmp) + cmp ^= W_OP; + break; + } + + if (cmp) { + FAIL_IF(push_inst(compiler, (MOV ^ inv_bits) | RM(temp_reg) | RD(TMP_REG1))); + tmp = TMP_REG1; + } + FAIL_IF(push_inst(compiler, ins | RM(tmp) | RN(mem_reg) | RD(src_reg))); + if (!cmp) + return SLJIT_SUCCESS; + + FAIL_IF(push_inst(compiler, cmp | RM(tmp) | RN(temp_reg))); + FAIL_IF(push_inst(compiler, (CSET ^ inv_bits) | RD(tmp))); + return push_inst(compiler, cmp | RM(tmp) | RN(TMP_ZERO)); +#else /* !__ARM_FEATURE_ATOMICS */ + SLJIT_UNUSED_ARG(tmp); + SLJIT_UNUSED_ARG(inv_bits); + + if (op & SLJIT_SET_ATOMIC_STORED) + cmp = (SUBI ^ W_OP) | (1 << 29); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + ins = STXR ^ (1 << 30); + break; + case SLJIT_MOV_U8: + ins = STXRB; + break; + case SLJIT_MOV_U16: + ins = STXRH; + break; + default: + ins = STXR; + break; + } + + FAIL_IF(push_inst(compiler, ins | RM(TMP_REG1) | RN(mem_reg) | RT(src_reg))); + return cmp ? push_inst(compiler, cmp | RD(TMP_ZERO) | RN(TMP_REG1)) : SLJIT_SUCCESS; +#endif /* __ARM_FEATURE_ATOMICS */ +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset) { sljit_s32 dst_reg; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c index 7d6bac077e2..c27c50ddb3a 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c @@ -49,8 +49,20 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15 }; -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { - 0, 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, 6, 7 +static const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = { + 0, + 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6, + 0, 1, 2, 3, 4, 5, 15, 14, 13, 12, 11, 10, 9, 8, + 7, 6 +}; + +static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1) + 1] = { + 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1 }; #define COPY_BITS(src, from, to, bits) \ @@ -75,13 +87,15 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { (reg_map[reg1] <= 7 && reg_map[reg2] <= 7 && reg_map[reg3] <= 7) /* Thumb32 encodings. */ -#define RD4(rd) ((sljit_ins)reg_map[rd] << 8) -#define RN4(rn) ((sljit_ins)reg_map[rn] << 16) #define RM4(rm) ((sljit_ins)reg_map[rm]) +#define RD4(rd) ((sljit_ins)reg_map[rd] << 8) #define RT4(rt) ((sljit_ins)reg_map[rt] << 12) -#define DD4(dd) ((sljit_ins)freg_map[dd] << 12) -#define DN4(dn) ((sljit_ins)freg_map[dn] << 16) -#define DM4(dm) ((sljit_ins)freg_map[dm]) +#define RN4(rn) ((sljit_ins)reg_map[rn] << 16) + +#define VM4(vm) (((sljit_ins)freg_map[vm]) | ((sljit_ins)freg_ebit_map[vm] << 5)) +#define VD4(vd) (((sljit_ins)freg_map[vd] << 12) | ((sljit_ins)freg_ebit_map[vd] << 22)) +#define VN4(vn) (((sljit_ins)freg_map[vn] << 16) | ((sljit_ins)freg_ebit_map[vn] << 7)) + #define IMM5(imm) \ (COPY_BITS(imm, 2, 12, 3) | (((sljit_ins)imm & 0x3) << 6)) #define IMM12(imm) \ @@ -128,9 +142,12 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define EORS 0x4040 #define EOR_W 0xea800000 #define IT 0xbf00 -#define LDR_SP 0x9800 #define LDR 0xf8d00000 +#define LDR_SP 0x9800 #define LDRD 0xe9500000 +#define LDREX 0xe8500f00 +#define LDREXB 0xe8d00f4f +#define LDREXH 0xe8d00f5f #define LDRI 0xf8500800 #define LSLS 0x4080 #define LSLSI 0x0000 @@ -160,6 +177,10 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define POP_W 0xe8bd0000 #define PUSH 0xb400 #define PUSH_W 0xe92d0000 +#define REV 0xba00 +#define REV_W 0xfa90f080 +#define REV16 0xba40 +#define REV16_W 0xfa90f090 #define RBIT 0xfa90f0a0 #define RORS 0x41c0 #define ROR_W 0xfa60f000 @@ -171,8 +192,11 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define SBC_W 0xeb600000 #define SDIV 0xfb90f0f0 #define SMULL 0xfb800000 -#define STRD 0xe9400000 #define STR_SP 0x9000 +#define STRD 0xe9400000 +#define STREX 0xe8400000 +#define STREXB 0xe8c00f40 +#define STREXH 0xe8c00f50 #define SUBS 0x1a00 #define SUBSI3 0x1e00 #define SUBSI8 0x3800 @@ -195,23 +219,57 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define UXTH_W 0xfa1ff080 #define VABS_F32 0xeeb00ac0 #define VADD_F32 0xee300a00 +#define VAND 0xef000110 #define VCMP_F32 0xeeb40a40 #define VCVT_F32_S32 0xeeb80ac0 +#define VCVT_F32_U32 0xeeb80a40 #define VCVT_F64_F32 0xeeb70ac0 #define VCVT_S32_F32 0xeebd0ac0 #define VDIV_F32 0xee800a00 +#define VDUP 0xee800b10 +#define VDUP_s 0xffb00c00 +#define VEOR 0xff000110 +#define VLD1 0xf9200000 +#define VLD1_r 0xf9a00c00 +#define VLD1_s 0xf9a00000 #define VLDR_F32 0xed100a00 #define VMOV_F32 0xeeb00a40 #define VMOV 0xee000a10 #define VMOV2 0xec400a10 +#define VMOV_i 0xef800010 +#define VMOV_s 0xee000b10 +#define VMOVN 0xffb20200 #define VMRS 0xeef1fa10 #define VMUL_F32 0xee200a00 #define VNEG_F32 0xeeb10a40 +#define VORR 0xef200110 #define VPOP 0xecbd0b00 #define VPUSH 0xed2d0b00 +#define VSHLL 0xef800a10 +#define VSHR 0xef800010 +#define VSRA 0xef800110 +#define VST1 0xf9000000 +#define VST1_s 0xf9800000 #define VSTR_F32 0xed000a00 #define VSUB_F32 0xee300a40 +#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + +static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32) +{ + if (compiler->scratches == -1) + return 0; + + if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) + fr -= SLJIT_F64_SECOND(0); + + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) + || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); +} + +#endif /* SLJIT_ARGUMENT_CHECKS */ + static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_ins inst) { sljit_u16 *ptr; @@ -488,18 +546,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) { switch (feature_type) { case SLJIT_HAS_FPU: + case SLJIT_HAS_F64_AS_F32_PAIR: + case SLJIT_HAS_SIMD: #ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; + return (SLJIT_IS_FPU_AVAILABLE) != 0; #else /* Available by default. */ return 1; #endif + case SLJIT_SIMD_REGS_ARE_PAIRS: case SLJIT_HAS_CLZ: case SLJIT_HAS_CTZ: + case SLJIT_HAS_REV: case SLJIT_HAS_ROT: case SLJIT_HAS_CMOV: case SLJIT_HAS_PREFETCH: + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: + case SLJIT_HAS_ATOMIC: return 1; default: @@ -615,18 +680,17 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s switch (flags & 0xffff) { case SLJIT_CLZ: case SLJIT_CTZ: + case SLJIT_REV: + case SLJIT_REV_U16: + case SLJIT_REV_S16: + case SLJIT_REV_U32: + case SLJIT_REV_S32: case SLJIT_MUL: /* No form with immediate operand. */ break; case SLJIT_MOV: SLJIT_ASSERT(!(flags & SET_FLAGS) && (flags & ARG2_IMM) && arg1 == TMP_REG2); return load_immediate(compiler, dst, imm); - case SLJIT_NOT: - if (!(flags & SET_FLAGS)) - return load_immediate(compiler, dst, ~imm); - /* Since the flags should be set, we just fallback to the register mode. - Although some clever things could be done here, "NOT IMM" does not worth the efforts. */ - break; case SLJIT_ADD: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; imm2 = NEGATE(imm); @@ -657,9 +721,14 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s break; case SLJIT_ADDC: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; - imm = get_imm(imm); - if (imm != INVALID_IMM) - return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + imm2 = get_imm(imm); + if (imm2 != INVALID_IMM) + return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2); + if (flags & ARG2_IMM) { + imm = get_imm(~imm); + if (imm != INVALID_IMM) + return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + } break; case SLJIT_SUB: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB; @@ -712,9 +781,12 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB; if (flags & ARG1_IMM) break; - imm = get_imm(imm); + imm2 = get_imm(imm); + if (imm2 != INVALID_IMM) + return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm2); + imm = get_imm(~imm); if (imm != INVALID_IMM) - return push_inst32(compiler, SBCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); + return push_inst32(compiler, ADCI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); break; case SLJIT_AND: imm2 = get_imm(imm); @@ -733,6 +805,11 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s return push_inst32(compiler, ORNI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); break; case SLJIT_XOR: + if (imm == (sljit_uw)-1) { + if (IS_2_LO_REGS(dst, reg)) + return push_inst16(compiler, MVNS | RD3(dst) | RN3(reg)); + return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(reg)); + } imm = get_imm(imm); if (imm != INVALID_IMM) return push_inst32(compiler, EORI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | imm); @@ -788,8 +865,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s imm = arg2; arg2 = (arg1 == TMP_REG1) ? TMP_REG2 : TMP_REG1; FAIL_IF(load_immediate(compiler, (sljit_s32)arg2, imm)); - } - else { + } else { imm = arg1; arg1 = (arg2 == TMP_REG1) ? TMP_REG2 : TMP_REG1; FAIL_IF(load_immediate(compiler, (sljit_s32)arg1, imm)); @@ -829,11 +905,6 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s if (IS_2_LO_REGS(dst, arg2)) return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2)); return push_inst32(compiler, SXTH_W | RD4(dst) | RM4(arg2)); - case SLJIT_NOT: - SLJIT_ASSERT(arg1 == TMP_REG2); - if (IS_2_LO_REGS(dst, arg2)) - return push_inst16(compiler, MVNS | RD3(dst) | RN3(arg2)); - return push_inst32(compiler, MVN_W | (flags & SET_FLAGS) | RD4(dst) | RM4(arg2)); case SLJIT_CLZ: SLJIT_ASSERT(arg1 == TMP_REG2); return push_inst32(compiler, CLZ | RN4(arg2) | RD4(dst) | RM4(arg2)); @@ -841,6 +912,29 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s SLJIT_ASSERT(arg1 == TMP_REG2); FAIL_IF(push_inst32(compiler, RBIT | RN4(arg2) | RD4(dst) | RM4(arg2))); return push_inst32(compiler, CLZ | RN4(dst) | RD4(dst) | RM4(dst)); + case SLJIT_REV: + case SLJIT_REV_U32: + case SLJIT_REV_S32: + SLJIT_ASSERT(arg1 == TMP_REG2); + if (IS_2_LO_REGS(dst, arg2)) + return push_inst16(compiler, REV | RD3(dst) | RN3(arg2)); + return push_inst32(compiler, REV_W | RN4(arg2) | RD4(dst) | RM4(arg2)); + case SLJIT_REV_U16: + case SLJIT_REV_S16: + SLJIT_ASSERT(arg1 == TMP_REG2 && dst != TMP_REG2); + + flags &= 0xffff; + if (IS_2_LO_REGS(dst, arg2)) + FAIL_IF(push_inst16(compiler, REV16 | RD3(dst) | RN3(arg2))); + else + FAIL_IF(push_inst32(compiler, REV16_W | RN4(arg2) | RD4(dst) | RM4(arg2))); + + if (dst == TMP_REG1 || (arg2 == TMP_REG1 && flags == SLJIT_REV_U16)) + return SLJIT_SUCCESS; + + if (reg_map[dst] <= 7) + return push_inst16(compiler, (flags == SLJIT_REV_U16 ? UXTH : SXTH) | RD3(dst) | RN3(dst)); + return push_inst32(compiler, (flags == SLJIT_REV_U16 ? UXTH_W : SXTH_W) | RD4(dst) | RM4(dst)); case SLJIT_ADD: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; if (IS_3_LO_REGS(dst, arg1, arg2)) @@ -1176,12 +1270,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi } if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) { - FAIL_IF(push_inst32(compiler, VPUSH | DD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); + FAIL_IF(push_inst32(compiler, VPUSH | VD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); } else { if (fsaveds > 0) - FAIL_IF(push_inst32(compiler, VPUSH | DD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); + FAIL_IF(push_inst32(compiler, VPUSH | VD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) - FAIL_IF(push_inst32(compiler, VPUSH | DD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); + FAIL_IF(push_inst32(compiler, VPUSH | VD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); } } @@ -1258,17 +1352,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi switch (arg_types & SLJIT_ARG_MASK) { case SLJIT_ARG_TYPE_F64: if (offset != old_offset) - *remap_ptr++ = VMOV_F32 | SLJIT_32 | DD4(offset) | DM4(old_offset); + *remap_ptr++ = VMOV_F32 | SLJIT_32 | VD4(offset) | VM4(old_offset); old_offset++; offset++; break; case SLJIT_ARG_TYPE_F32: if (f32_offset != 0) { - *remap_ptr++ = VMOV_F32 | 0x20 | DD4(offset) | DM4(f32_offset); + *remap_ptr++ = VMOV_F32 | 0x20 | VD4(offset) | VM4(f32_offset); f32_offset = 0; } else { if (offset != old_offset) - *remap_ptr++ = VMOV_F32 | DD4(offset) | DM4(old_offset); + *remap_ptr++ = VMOV_F32 | VD4(offset) | VM4(old_offset); f32_offset = old_offset; old_offset++; } @@ -1356,6 +1450,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp size = GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 1); + /* Doubles are saved, so alignment is unaffected. */ if ((size & SSIZE_OF(sw)) != 0 && (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG)) size += SSIZE_OF(sw); @@ -1401,12 +1496,12 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit FAIL_IF(emit_add_sp(compiler, (sljit_uw)local_size)); if (fsaveds + fscratches >= SLJIT_NUMBER_OF_FLOAT_REGISTERS) { - FAIL_IF(push_inst32(compiler, VPOP | DD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); + FAIL_IF(push_inst32(compiler, VPOP | VD4(SLJIT_FS0) | ((sljit_uw)SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS << 1))); } else { if (fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) - FAIL_IF(push_inst32(compiler, VPOP | DD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); + FAIL_IF(push_inst32(compiler, VPOP | VD4(fscratches) | ((sljit_uw)(fscratches - (SLJIT_FIRST_SAVED_FLOAT_REG - 1)) << 1))); if (fsaveds > 0) - FAIL_IF(push_inst32(compiler, VPOP | DD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); + FAIL_IF(push_inst32(compiler, VPOP | VD4(SLJIT_FS0) | ((sljit_uw)fsaveds << 1))); } local_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds, 1) & 0x7; @@ -1705,22 +1800,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile break; case SLJIT_MOV_U8: flags = BYTE_SIZE; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_u8)srcw; break; case SLJIT_MOV_S8: flags = BYTE_SIZE | SIGNED; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_s8)srcw; break; case SLJIT_MOV_U16: flags = HALF_SIZE; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_u16)srcw; break; case SLJIT_MOV_S16: flags = HALF_SIZE | SIGNED; - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) srcw = (sljit_s16)srcw; break; default: @@ -1729,7 +1824,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile break; } - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG2, (sljit_uw)srcw)); else if (src & SLJIT_MEM) { FAIL_IF(emit_op_mem(compiler, flags, dst_r, src, srcw, TMP_REG1)); @@ -1745,10 +1840,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2); } + SLJIT_COMPILE_ASSERT(WORD_SIZE == 0, word_size_must_be_0); flags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0; + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) + flags |= HALF_SIZE; + if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1)); + FAIL_IF(emit_op_mem(compiler, flags, TMP_REG1, src, srcw, TMP_REG1)); src = TMP_REG1; } @@ -1778,7 +1877,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile if (dst == TMP_REG1) flags |= UNUSED_RETURN; - if (src1 & SLJIT_IMM) + if (src1 == SLJIT_IMM) flags |= ARG1_IMM; else if (src1 & SLJIT_MEM) { emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1); @@ -1787,7 +1886,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile else src1w = src1; - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) flags |= ARG2_IMM; else if (src2 & SLJIT_MEM) { src2_reg = (!(flags & ARG1_IMM) && (src1w == TMP_REG1)) ? TMP_REG2 : TMP_REG1; @@ -1816,68 +1915,60 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_left; CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); op = GET_OPCODE(op); is_left = (op == SLJIT_SHL || op == SLJIT_MSHL); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, is_left ? SLJIT_ROTL : SLJIT_ROTR, dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); - if (src2 & SLJIT_IMM) { - src2w &= 0x1f; + if (src3 == SLJIT_IMM) { + src3w &= 0x1f; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src2, src2w, TMP_REG2)); - src2 = TMP_REG2; - } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w)); - src1 = TMP_REG1; - } - - if (src2 & SLJIT_IMM) { - if (reg_map[src_dst] <= 7) - FAIL_IF(push_inst16(compiler, (is_left ? LSLSI : LSRSI) | RD3(src_dst) | RN3(src_dst) | ((sljit_ins)src2w << 6))); + if (IS_2_LO_REGS(dst_reg, src1_reg)) + FAIL_IF(push_inst16(compiler, (is_left ? LSLSI : LSRSI) | RD3(dst_reg) | RN3(src1_reg) | ((sljit_ins)src3w << 6))); else - FAIL_IF(push_inst32(compiler, (is_left ? LSL_WI : LSR_WI) | RD4(src_dst) | RM4(src_dst) | IMM5(src2w))); + FAIL_IF(push_inst32(compiler, (is_left ? LSL_WI : LSR_WI) | RD4(dst_reg) | RM4(src1_reg) | IMM5(src3w))); - src2w = (src2w ^ 0x1f) + 1; - return push_inst32(compiler, ORR_W | RD4(src_dst) | RN4(src_dst) | RM4(src1) | (is_left ? 0x10 : 0x0) | IMM5(src2w)); + src3w = (src3w ^ 0x1f) + 1; + return push_inst32(compiler, ORR_W | RD4(dst_reg) | RN4(dst_reg) | RM4(src2_reg) | (is_left ? 0x10 : 0x0) | IMM5(src3w)); } - if (op == SLJIT_MSHL || op == SLJIT_MLSHR) { - FAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(src2) | 0x1f)); - src2 = TMP_REG2; + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src3, src3w, TMP_REG2)); + src3 = TMP_REG2; } - if (IS_2_LO_REGS(src_dst, src2)) - FAIL_IF(push_inst16(compiler, (is_left ? LSLS : LSRS) | RD3(src_dst) | RN3(src2))); + if (op == SLJIT_MSHL || op == SLJIT_MLSHR || dst_reg == src3) { + FAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(src3) | 0x1f)); + src3 = TMP_REG2; + } + + if (dst_reg == src1_reg && IS_2_LO_REGS(dst_reg, src3)) + FAIL_IF(push_inst16(compiler, (is_left ? LSLS : LSRS) | RD3(dst_reg) | RN3(src3))); else - FAIL_IF(push_inst32(compiler, (is_left ? LSL_W : LSR_W) | RD4(src_dst) | RN4(src_dst) | RM4(src2))); + FAIL_IF(push_inst32(compiler, (is_left ? LSL_W : LSR_W) | RD4(dst_reg) | RN4(src1_reg) | RM4(src3))); - FAIL_IF(push_inst32(compiler, (is_left ? LSR_WI : LSL_WI) | RD4(TMP_REG1) | RM4(src1) | (1 << 6))); - FAIL_IF(push_inst32(compiler, EORI | RD4(TMP_REG2) | RN4(src2) | 0x1f)); + FAIL_IF(push_inst32(compiler, (is_left ? LSR_WI : LSL_WI) | RD4(TMP_REG1) | RM4(src2_reg) | (1 << 6))); + FAIL_IF(push_inst32(compiler, EORI | RD4(TMP_REG2) | RN4(src3) | 0x1f)); FAIL_IF(push_inst32(compiler, (is_left ? LSR_W : LSL_W) | RD4(TMP_REG1) | RN4(TMP_REG1) | RM4(TMP_REG2))); - return push_inst32(compiler, ORR_W | RD4(src_dst) | RN4(src_dst) | RM4(TMP_REG1)); + return push_inst32(compiler, ORR_W | RD4(dst_reg) | RN4(dst_reg) | RM4(TMP_REG1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, @@ -1909,16 +2000,60 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 size, dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + SLJIT_ASSERT(reg_map[TMP_REG2] == 14); + + if (FAST_IS_REG(dst)) + return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2)); + break; + case SLJIT_GET_RETURN_ADDRESS: + size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 0); + + if (compiler->fsaveds > 0 || compiler->fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { + /* The size of pc is not added above. */ + if ((size & SSIZE_OF(sw)) == 0) + size += SSIZE_OF(sw); + + size += GET_SAVED_FLOAT_REGISTERS_SIZE(compiler->fscratches, compiler->fsaveds, f64); + } + + SLJIT_ASSERT(((compiler->local_size + size + SSIZE_OF(sw)) & 0x7) == 0); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + size, TMP_REG1)); + break; + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, TMP_REG1); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return (freg_map[reg] << 1); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type == SLJIT_FLOAT_REGISTER || type == SLJIT_SIMD_REG_64) + return freg_map[reg]; + + if (type != SLJIT_SIMD_REG_128) + return freg_map[reg] & ~0x1; + + return -1; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -1954,35 +2089,35 @@ static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags, if ((arg & REG_MASK) && (argw & 0x3) == 0) { if (!(argw & ~0x3fc)) - return push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | DD4(reg) | ((sljit_uw)argw >> 2)); + return push_inst32(compiler, inst | 0x800000 | RN4(arg & REG_MASK) | VD4(reg) | ((sljit_uw)argw >> 2)); if (!(-argw & ~0x3fc)) - return push_inst32(compiler, inst | RN4(arg & REG_MASK) | DD4(reg) | ((sljit_uw)-argw >> 2)); + return push_inst32(compiler, inst | RN4(arg & REG_MASK) | VD4(reg) | ((sljit_uw)-argw >> 2)); } if (arg & REG_MASK) { if (emit_set_delta(compiler, TMP_REG1, arg & REG_MASK, argw) != SLJIT_ERR_UNSUPPORTED) { FAIL_IF(compiler->error); - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg)); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | VD4(reg)); } imm = get_imm((sljit_uw)argw & ~(sljit_uw)0x3fc); if (imm != INVALID_IMM) { FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm)); - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2)); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | VD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2)); } imm = get_imm((sljit_uw)-argw & ~(sljit_uw)0x3fc); if (imm != INVALID_IMM) { argw = -argw; FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg & REG_MASK) | imm)); - return push_inst32(compiler, inst | RN4(TMP_REG1) | DD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2)); + return push_inst32(compiler, inst | RN4(TMP_REG1) | VD4(reg) | (((sljit_uw)argw & 0x3fc) >> 2)); } } FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)argw)); if (arg & REG_MASK) FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, (arg & REG_MASK)))); - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg)); + return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | VD4(reg)); } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, @@ -1996,41 +2131,53 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp src = TMP_FREG1; } - FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_32) | DD4(TMP_FREG1) | DM4(src))); + FAIL_IF(push_inst32(compiler, VCVT_S32_F32 | (op & SLJIT_32) | VD4(TMP_FREG1) | VM4(src))); if (FAST_IS_REG(dst)) - return push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | DN4(TMP_FREG1)); + return push_inst32(compiler, VMOV | (1 << 20) | RT4(dst) | VN4(TMP_FREG1)); /* Store the integer value from a VFP register. */ return emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - op ^= SLJIT_32; - if (FAST_IS_REG(src)) - FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | DN4(TMP_FREG1))); + FAIL_IF(push_inst32(compiler, VMOV | RT4(src) | VN4(TMP_FREG1))); else if (src & SLJIT_MEM) { /* Load the integer value into a VFP register. */ FAIL_IF(emit_fop_mem(compiler, FPU_LOAD, TMP_FREG1, src, srcw)); } else { FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); - FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | DN4(TMP_FREG1))); + FAIL_IF(push_inst32(compiler, VMOV | RT4(TMP_REG1) | VN4(TMP_FREG1))); } - FAIL_IF(push_inst32(compiler, VCVT_F32_S32 | (op & SLJIT_32) | DD4(dst_r) | DM4(TMP_FREG1))); + FAIL_IF(push_inst32(compiler, ins | VD4(dst_r) | VM4(TMP_FREG1))); if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, (ins & SLJIT_32), TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + return sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_S32 | (~op & SLJIT_32), dst, dstw, src, srcw); +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + return sljit_emit_fop1_conv_f64_from_w(compiler, VCVT_F32_U32 | (~op & SLJIT_32), dst, dstw, src, srcw); +} + static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) @@ -2038,17 +2185,23 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile op ^= SLJIT_32; if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } - FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_32) | DD4(src1) | DM4(src2))); - return push_inst32(compiler, VMRS); + FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_32) | VD4(src1) | VM4(src2))); + FAIL_IF(push_inst32(compiler, VMRS)); + + if (GET_FLAG_TYPE(op) != SLJIT_UNORDERED_OR_EQUAL) + return SLJIT_SUCCESS; + + FAIL_IF(push_inst16(compiler, IT | (0x6 << 4) | 0x8)); + return push_inst16(compiler, CMP /* Rm, Rn = r0 */); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, @@ -2068,7 +2221,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil op ^= SLJIT_32; if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, dst_r, src, srcw); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, dst_r, src, srcw)); src = dst_r; } @@ -2076,19 +2229,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) - FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src))); + FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src))); else dst_r = src; } break; case SLJIT_NEG_F64: - FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src))); + FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src))); break; case SLJIT_ABS_F64: - FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src))); + FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src))); break; case SLJIT_CONV_F64_FROM_F32: - FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_32) | DD4(dst_r) | DM4(src))); + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src))); op ^= SLJIT_32; break; } @@ -2115,27 +2268,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w)); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w); + FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32) | FPU_LOAD, TMP_FREG2, src2, src2w)); src2 = TMP_FREG2; } switch (GET_OPCODE(op)) { case SLJIT_ADD_F64: - FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2))); + FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2))); break; case SLJIT_SUB_F64: - FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2))); + FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2))); break; case SLJIT_MUL_F64: - FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2))); + FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2))); break; case SLJIT_DIV_F64: - FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_32) | DD4(dst_r) | DN4(src1) | DM4(src2))); + FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_32) | VD4(dst_r) | VN4(src1) | VM4(src2))); break; + case SLJIT_COPYSIGN_F64: + FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(src2) | RT4(TMP_REG1) | ((op & SLJIT_32) ? (1 << 7) : 0))); + FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src1))); + FAIL_IF(push_inst32(compiler, CMPI_W | RN4(TMP_REG1) | 0)); + FAIL_IF(push_inst16(compiler, IT | (0xb << 4) | 0x8)); + return push_inst32(compiler, VNEG_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(dst_r)); } if (!(dst & SLJIT_MEM)) @@ -2143,23 +2302,99 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw); } -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { +#if defined(__ARM_NEON) && __ARM_NEON + sljit_u32 exp; + sljit_ins ins; +#endif /* NEON */ + union { + sljit_u32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - SLJIT_ASSERT(reg_map[TMP_REG2] == 14); + u.value = value; - if (FAST_IS_REG(dst)) - return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2)); +#if defined(__ARM_NEON) && __ARM_NEON + if ((u.imm << (32 - 19)) == 0) { + exp = (u.imm >> (23 + 2)) & 0x3f; - /* Memory. */ - return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, TMP_REG1); + if (exp == 0x20 || exp == 0x1f) { + ins = ((u.imm >> 24) & 0x80) | ((u.imm >> 19) & 0x7f); + return push_inst32(compiler, (VMOV_F32 ^ (1 << 6)) | ((ins & 0xf0) << 12) | VD4(freg) | (ins & 0xf)); + } + } +#endif /* NEON */ + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm)); + return push_inst32(compiler, VMOV | VN4(freg) | RT4(TMP_REG1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ +#if defined(__ARM_NEON) && __ARM_NEON + sljit_u32 exp; + sljit_ins ins; +#endif /* NEON */ + union { + sljit_u32 imm[2]; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + +#if defined(__ARM_NEON) && __ARM_NEON + if (u.imm[0] == 0 && (u.imm[1] << (64 - 48)) == 0) { + exp = (u.imm[1] >> ((52 - 32) + 2)) & 0x1ff; + + if (exp == 0x100 || exp == 0xff) { + ins = ((u.imm[1] >> (56 - 32)) & 0x80) | ((u.imm[1] >> (48 - 32)) & 0x7f); + return push_inst32(compiler, (VMOV_F32 ^ (1 << 6)) | (1 << 8) | ((ins & 0xf0) << 12) | VD4(freg) | (ins & 0xf)); + } + } +#endif /* NEON */ + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0])); + if (u.imm[0] == u.imm[1]) + return push_inst32(compiler, VMOV2 | RN4(TMP_REG1) | RT4(TMP_REG1) | VM4(freg)); + + FAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1])); + return push_inst32(compiler, VMOV2 | RN4(TMP_REG2) | RT4(TMP_REG1) | VM4(freg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_s32 reg2; + sljit_ins inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + + inst = VMOV2 | RN4(reg) | RT4(reg2) | VM4(freg); + } else { + inst = VMOV | VN4(freg) | RT4(reg); + + if (!(op & SLJIT_32)) + inst |= 1 << 7; + } + + if (GET_OPCODE(op) == SLJIT_COPY_FROM_F64) + inst |= 1 << 20; + + return push_inst32(compiler, inst); } /* --------------------------------------------------------------------- */ @@ -2170,15 +2405,17 @@ static sljit_uw get_cc(struct sljit_compiler *compiler, sljit_s32 type) { switch (type) { case SLJIT_EQUAL: + case SLJIT_ATOMIC_STORED: case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: - case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */ + case SLJIT_UNORDERED_OR_EQUAL: return 0x0; case SLJIT_NOT_EQUAL: + case SLJIT_ATOMIC_NOT_STORED: case SLJIT_F_NOT_EQUAL: case SLJIT_UNORDERED_OR_NOT_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */ + case SLJIT_ORDERED_NOT_EQUAL: return 0x1; case SLJIT_CARRY: @@ -2453,18 +2690,18 @@ static sljit_s32 hardfloat_call_with_args(struct sljit_compiler *compiler, sljit switch (arg_types & SLJIT_ARG_MASK) { case SLJIT_ARG_TYPE_F64: if (offset != new_offset) - FAIL_IF(push_inst32(compiler, VMOV_F32 | SLJIT_32 | DD4(new_offset) | DM4(offset))); + FAIL_IF(push_inst32(compiler, VMOV_F32 | SLJIT_32 | VD4(new_offset) | VM4(offset))); new_offset++; offset++; break; case SLJIT_ARG_TYPE_F32: if (f32_offset != 0) { - FAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | DD4(f32_offset) | DM4(offset))); + FAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | VD4(f32_offset) | VM4(offset))); f32_offset = 0; } else { if (offset != new_offset) - FAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | DD4(new_offset) | DM4(offset))); + FAIL_IF(push_inst32(compiler, VMOV_F32 | 0x400000 | VD4(new_offset) | VM4(offset))); f32_offset = new_offset; new_offset++; } @@ -2546,7 +2783,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi SLJIT_ASSERT(reg_map[TMP_REG1] != 14); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { if (FAST_IS_REG(src)) { SLJIT_ASSERT(reg_map[src] != 14); return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src)); @@ -2645,8 +2882,8 @@ static SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *com if (FAST_IS_REG(src)) { if (op & SLJIT_32) - return push_inst32(compiler, VMOV | (1 << 20) | DN4(src) | RT4(SLJIT_R0)); - return push_inst32(compiler, VMOV2 | (1 << 20) | DM4(src) | RT4(SLJIT_R0) | RN4(SLJIT_R1)); + return push_inst32(compiler, VMOV | (1 << 20) | VN4(src) | RT4(SLJIT_R0)); + return push_inst32(compiler, VMOV2 | (1 << 20) | VM4(src) | RT4(SLJIT_R0) | RN4(SLJIT_R1)); } SLJIT_SKIP_CHECKS(compiler); @@ -2711,23 +2948,47 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { sljit_uw cc, tmp; CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (src2_reg != dst_reg && src1 == dst_reg) { + src1 = src2_reg; + src1w = 0; + src2_reg = dst_reg; + type ^= 0x1; + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_SIZE, (src2_reg != dst_reg) ? dst_reg : TMP_REG1, src1, src1w, TMP_REG2)); + + if (src2_reg != dst_reg) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + src1 = TMP_REG1; + src1w = 0; + } + } else if (dst_reg != src2_reg) + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(dst_reg, src2_reg))); cc = get_cc(compiler, type & ~SLJIT_32); - if (!(src & SLJIT_IMM)) { + if (src1 != SLJIT_IMM) { FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); - return push_inst16(compiler, MOV | SET_REGS44(dst_reg, src)); + return push_inst16(compiler, MOV | SET_REGS44(dst_reg, src1)); } - tmp = (sljit_uw) srcw; + tmp = (sljit_uw)src1w; if (tmp < 0x10000) { /* set low 16 bits, set hi 16 bits to 0. */ @@ -2736,13 +2997,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil | COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff)); } - tmp = get_imm((sljit_uw)srcw); + tmp = get_imm((sljit_uw)src1w); if (tmp != INVALID_IMM) { FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); return push_inst32(compiler, MOV_WI | RD4(dst_reg) | tmp); } - tmp = get_imm(~(sljit_uw)srcw); + tmp = get_imm(~(sljit_uw)src1w); if (tmp != INVALID_IMM) { FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); return push_inst32(compiler, MVN_WI | RD4(dst_reg) | tmp); @@ -2750,13 +3011,43 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil FAIL_IF(push_inst16(compiler, IT | (cc << 4) | ((cc & 0x1) << 3) | 0x4)); - tmp = (sljit_uw) srcw; + tmp = (sljit_uw)src1w; FAIL_IF(push_inst32(compiler, MOVW | RD4(dst_reg) | COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff))); return push_inst32(compiler, MOVT | RD4(dst_reg) | COPY_BITS(tmp, 12 + 16, 16, 4) | COPY_BITS(tmp, 11 + 16, 26, 1) | COPY_BITS(tmp, 8 + 16, 12, 3) | ((tmp & 0xff0000) >> 16)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + type ^= SLJIT_32; + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst32(compiler, VMOV_F32 | (type & SLJIT_32) | VD4(dst_freg) | VM4(src2_freg))); + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w)); + src1 = TMP_FREG1; + } + + FAIL_IF(push_inst16(compiler, IT | (get_cc(compiler, type & ~SLJIT_32) << 4) | 0x8)); + return push_inst32(compiler, VMOV_F32 | (type & SLJIT_32) | VD4(dst_freg) | VM4(src1)); +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw) @@ -2770,7 +3061,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile if (!(reg & REG_PAIR_MASK)) return sljit_emit_mem_unaligned(compiler, type, reg, mem, memw); - if (type & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32)) { + if (type & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)) { if ((mem & REG_MASK) == 0) { if ((memw & 0xfff) >= (0x1000 - SSIZE_OF(sw))) { imm = get_imm((sljit_uw)((memw + 0x1000) & ~0xfff)); @@ -2781,7 +3072,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile imm = get_imm((sljit_uw)(memw & ~0xfff)); if (imm != INVALID_IMM) - memw &= 0xff; + memw &= 0xfff; } if (imm == INVALID_IMM) { @@ -3058,11 +3349,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil CHECK_ERROR(); CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw)); - if (type & SLJIT_MEM_UNALIGNED_32) + if (type & SLJIT_MEM_ALIGNED_32) return emit_fop_mem(compiler, ((type ^ SLJIT_32) & SLJIT_32) | ((type & SLJIT_MEM_STORE) ? 0 : FPU_LOAD), freg, mem, memw); if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | DN4(freg) | RT4(TMP_REG2))); + FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(freg) | RT4(TMP_REG2))); if (type & SLJIT_32) return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw, TMP_REG1); @@ -3071,13 +3362,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil mem |= SLJIT_MEM; FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw, TMP_REG1)); - FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | DN4(freg) | 0x80 | RT4(TMP_REG2))); + FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(freg) | 0x80 | RT4(TMP_REG2))); return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, mem, memw + 4, TMP_REG1); } if (type & SLJIT_32) { FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1)); - return push_inst32(compiler, VMOV | DN4(freg) | RT4(TMP_REG2)); + return push_inst32(compiler, VMOV | VN4(freg) | RT4(TMP_REG2)); } FAIL_IF(update_mem_addr(compiler, &mem, &memw, 0xfff - 4)); @@ -3085,11 +3376,715 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, mem, memw, TMP_REG1)); FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, mem, memw + 4, TMP_REG1)); - return push_inst32(compiler, VMOV2 | DM4(freg) | RT4(TMP_REG2) | RN4(TMP_REG1)); + return push_inst32(compiler, VMOV2 | VM4(freg) | RT4(TMP_REG2) | RN4(TMP_REG1)); +} + +static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, sljit_s32 *mem_ptr, sljit_sw memw) +{ + sljit_uw imm; + sljit_s32 mem = *mem_ptr; + + if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { + *mem_ptr = TMP_REG1; + return push_inst32(compiler, ADD_W | RD4(TMP_REG1) | RN4(mem & REG_MASK) | RM4(OFFS_REG(mem)) | ((sljit_uw)(memw & 0x3) << 6)); + } + + if (SLJIT_UNLIKELY(!(mem & REG_MASK))) { + *mem_ptr = TMP_REG1; + return load_immediate(compiler, TMP_REG1, (sljit_uw)memw); + } + + mem &= REG_MASK; + + if (memw == 0) { + *mem_ptr = mem; + return SLJIT_SUCCESS; + } + + *mem_ptr = TMP_REG1; + imm = get_imm((sljit_uw)(memw < 0 ? -memw : memw)); + + if (imm != INVALID_IMM) + return push_inst32(compiler, ((memw < 0) ? SUB_WI : ADD_WI) | RD4(TMP_REG1) | RN4(mem) | imm); + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)memw)); + return push_inst16(compiler, ADD | SET_REGS44(TMP_REG1, mem)); +} + +static SLJIT_INLINE sljit_s32 simd_get_quad_reg_index(sljit_s32 freg) +{ + freg += freg & 0x1; + + SLJIT_ASSERT((freg_map[freg] & 0x1) == (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS)); + + if (freg <= SLJIT_NUMBER_OF_SCRATCH_FLOAT_REGISTERS) + freg--; + + return freg; +} + +#define SLJIT_QUAD_OTHER_HALF(freg) ((((freg) & 0x1) << 1) - 1) + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (!(srcdst & SLJIT_MEM)) { + if (reg_size == 4) + srcdst = simd_get_quad_reg_index(srcdst); + + if (type & SLJIT_SIMD_STORE) + ins = VD4(srcdst) | VN4(freg) | VM4(freg); + else + ins = VD4(freg) | VN4(srcdst) | VM4(srcdst); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst32(compiler, VORR | ins); + } + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + if (elem_size > 3) + elem_size = 3; + + ins = ((type & SLJIT_SIMD_STORE) ? VST1 : VLD1) | VD4(freg) + | (sljit_ins)((reg_size == 3) ? (0x7 << 8) : (0xa << 8)); + + SLJIT_ASSERT(reg_size >= alignment); + + if (alignment == 3) + ins |= 0x10; + else if (alignment >= 4) + ins |= 0x20; + + return push_inst32(compiler, ins | RN4(srcdst) | ((sljit_ins)elem_size) << 6 | 0xf); +} + +static sljit_ins simd_get_imm(sljit_s32 elem_size, sljit_uw value) +{ + sljit_ins result; + + if (elem_size > 1 && (sljit_u16)value == (value >> 16)) { + elem_size = 1; + value = (sljit_u16)value; + } + + if (elem_size == 1 && (sljit_u8)value == (value >> 8)) { + elem_size = 0; + value = (sljit_u8)value; + } + + switch (elem_size) { + case 0: + SLJIT_ASSERT(value <= 0xff); + result = 0xe00; + break; + case 1: + SLJIT_ASSERT(value <= 0xffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x800; + break; + } + + if ((value & 0xff) == 0) { + value >>= 8; + result |= 0xa00; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value ^= (sljit_uw)0xffff; + result = (1 << 5); + } + break; + default: + SLJIT_ASSERT(value <= 0xffffffff); + result = 0; + + while (1) { + if (value <= 0xff) { + result |= 0x000; + break; + } + + if ((value & ~(sljit_uw)0xff00) == 0) { + value >>= 8; + result |= 0x200; + break; + } + + if ((value & ~(sljit_uw)0xff0000) == 0) { + value >>= 16; + result |= 0x400; + break; + } + + if ((value & ~(sljit_uw)0xff000000) == 0) { + value >>= 24; + result |= 0x600; + break; + } + + if ((value & (sljit_uw)0xff) == 0xff && (value >> 16) == 0) { + value >>= 8; + result |= 0xc00; + break; + } + + if ((value & (sljit_uw)0xffff) == 0xffff && (value >> 24) == 0) { + value >>= 16; + result |= 0xd00; + break; + } + + if (result != 0) + return ~(sljit_ins)0; + + value = ~value; + result = (1 << 5); + } + break; + } + + return ((sljit_ins)value & 0xf) | (((sljit_ins)value & 0x70) << 12) | (((sljit_ins)value & 0x80) << 21) | result; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imm; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (src == SLJIT_IMM && srcw == 0) + return push_inst32(compiler, VMOV_i | ((reg_size == 4) ? (1 << 6) : 0) | VD4(freg)); + + if (SLJIT_UNLIKELY(elem_size == 3)) { + SLJIT_ASSERT(type & SLJIT_SIMD_FLOAT); + + if (src & SLJIT_MEM) { + FAIL_IF(emit_fop_mem(compiler, FPU_LOAD | SLJIT_32, freg, src, srcw)); + src = freg; + } else if (freg != src) + FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (freg != src) + return push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src)); + return SLJIT_SUCCESS; + } + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + + ins = (sljit_ins)(elem_size << 6); + + if (reg_size == 4) + ins |= 1 << 5; + + return push_inst32(compiler, VLD1_r | ins | VD4(freg) | RN4(src) | 0xf); + } + + if (type & SLJIT_SIMD_FLOAT) { + SLJIT_ASSERT(elem_size == 2); + ins = ((sljit_ins)freg_ebit_map[src] << (16 + 2 + 1)) | ((sljit_ins)1 << (16 + 2)); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst32(compiler, VDUP_s | ins | VD4(freg) | (sljit_ins)freg_map[src]); + } + + if (src == SLJIT_IMM) { + if (elem_size < 2) + srcw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + imm = simd_get_imm(elem_size, (sljit_uw)srcw); + + if (imm != ~(sljit_ins)0) { + if (reg_size == 4) + imm |= (sljit_ins)1 << 6; + + return push_inst32(compiler, VMOV_i | imm | VD4(freg)); + } + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcw)); + src = TMP_REG1; + } + + switch (elem_size) { + case 0: + ins = 1 << 22; + break; + case 1: + ins = 1 << 5; + break; + default: + ins = 0; + break; + } + + if (reg_size == 4) + ins |= (sljit_ins)1 << 21; + + return push_inst32(compiler, VDUP | ins | VN4(freg) | RT4(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (type & SLJIT_SIMD_LANE_ZERO) { + ins = (reg_size == 3) ? 0 : ((sljit_ins)1 << 6); + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 3 && !(srcdst & SLJIT_MEM)) { + if (lane_index == 1) + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (srcdst != freg) + FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(srcdst) | VM4(srcdst))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst32(compiler, VMOV_i | VD4(freg)); + } + + if (srcdst == freg || (elem_size == 3 && srcdst == (freg + SLJIT_QUAD_OTHER_HALF(freg)))) { + FAIL_IF(push_inst32(compiler, VORR | ins | VD4(TMP_FREG2) | VN4(freg) | VM4(freg))); + srcdst = TMP_FREG2; + srcdstw = 0; + } + } + + FAIL_IF(push_inst32(compiler, VMOV_i | ins | VD4(freg))); + } + + if (reg_size == 4 && lane_index >= (0x8 >> elem_size)) { + lane_index -= (0x8 >> elem_size); + freg += SLJIT_QUAD_OTHER_HALF(freg); + } + + if (srcdst & SLJIT_MEM) { + if (elem_size == 3) + return emit_fop_mem(compiler, ((type & SLJIT_SIMD_STORE) ? 0 : FPU_LOAD) | SLJIT_32, freg, srcdst, srcdstw); + + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw)); + + lane_index = lane_index << elem_size; + ins = (sljit_ins)((elem_size << 10) | (lane_index << 5)); + return push_inst32(compiler, ((type & SLJIT_SIMD_STORE) ? VST1_s : VLD1_s) | ins | VD4(freg) | RN4(srcdst) | 0xf); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 3) { + if (type & SLJIT_SIMD_STORE) + return push_inst32(compiler, VORR | VD4(srcdst) | VN4(freg) | VM4(freg)); + return push_inst32(compiler, VMOV_F32 | SLJIT_32 | VD4(freg) | VM4(srcdst)); + } + + if (type & SLJIT_SIMD_STORE) { + if (freg_ebit_map[freg] == 0) { + if (lane_index == 1) + freg = SLJIT_F64_SECOND(freg); + + return push_inst32(compiler, VMOV_F32 | VD4(srcdst) | VM4(freg)); + } + + FAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | ((sljit_ins)lane_index << 21) | VN4(freg) | RT4(TMP_REG1))); + return push_inst32(compiler, VMOV | VN4(srcdst) | RT4(TMP_REG1)); + } + + FAIL_IF(push_inst32(compiler, VMOV | (1 << 20) | VN4(srcdst) | RT4(TMP_REG1))); + return push_inst32(compiler, VMOV_s | ((sljit_ins)lane_index << 21) | VN4(freg) | RT4(TMP_REG1)); + } + + if (srcdst == SLJIT_IMM) { + if (elem_size < 2) + srcdstw &= ((sljit_sw)1 << (((sljit_sw)1 << elem_size) << 3)) - 1; + + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)srcdstw)); + srcdst = TMP_REG1; + } + + if (elem_size == 0) + ins = 0x400000; + else if (elem_size == 1) + ins = 0x20; + else + ins = 0; + + lane_index = lane_index << elem_size; + ins |= (sljit_ins)(((lane_index & 0x4) << 19) | ((lane_index & 0x3) << 5)); + + if (type & SLJIT_SIMD_STORE) { + ins |= (1 << 20); + + if (elem_size < 2 && !(type & SLJIT_SIMD_LANE_SIGNED)) + ins |= (1 << 23); + } + + return push_inst32(compiler, VMOV_s | ins | VN4(freg) | RT4(srcdst)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) { + freg = simd_get_quad_reg_index(freg); + src = simd_get_quad_reg_index(src); + + if (src_lane_index >= (0x8 >> elem_size)) { + src_lane_index -= (0x8 >> elem_size); + src += SLJIT_QUAD_OTHER_HALF(src); + } + } + + if (elem_size == 3) { + if (freg != src) + FAIL_IF(push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src))); + + freg += SLJIT_QUAD_OTHER_HALF(freg); + + if (freg != src) + return push_inst32(compiler, VORR | VD4(freg) | VN4(src) | VM4(src)); + return SLJIT_SUCCESS; + } + + ins = ((((sljit_ins)src_lane_index << 1) | 1) << (16 + elem_size)); + + if (reg_size == 4) + ins |= (sljit_ins)1 << 6; + + return push_inst32(compiler, VDUP_s | ins | VD4(freg) | VM4(src)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_s32 dst_reg; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size != 2 || elem2_size != 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + freg = simd_get_quad_reg_index(freg); + + if (src & SLJIT_MEM) { + FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw)); + if (reg_size == 4 && elem2_size - elem_size == 1) + FAIL_IF(push_inst32(compiler, VLD1 | (0x7 << 8) | VD4(freg) | RN4(src) | 0xf)); + else + FAIL_IF(push_inst32(compiler, VLD1_s | (sljit_ins)((reg_size - elem2_size + elem_size) << 10) | VD4(freg) | RN4(src) | 0xf)); + src = freg; + } else if (reg_size == 4) + src = simd_get_quad_reg_index(src); + + if (!(type & SLJIT_SIMD_FLOAT)) { + dst_reg = (reg_size == 4) ? freg : TMP_FREG2; + + do { + FAIL_IF(push_inst32(compiler, VSHLL | ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0 : (1 << 28)) + | ((sljit_ins)1 << (19 + elem_size)) | VD4(dst_reg) | VM4(src))); + src = dst_reg; + } while (++elem_size < elem2_size); + + if (dst_reg == TMP_FREG2) + return push_inst32(compiler, VORR | VD4(freg) | VN4(TMP_FREG2) | VM4(TMP_FREG2)); + return SLJIT_SUCCESS; + } + + /* No SIMD variant, must use VFP instead. */ + SLJIT_ASSERT(reg_size == 4); + + if (freg == src) { + freg += SLJIT_QUAD_OTHER_HALF(freg); + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src) | 0x20)); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src)); + } + + FAIL_IF(push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src))); + freg += SLJIT_QUAD_OTHER_HALF(freg); + return push_inst32(compiler, VCVT_F64_F32 | VD4(freg) | VM4(src) | 0x20); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins, imms; + sljit_s32 dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + switch (elem_size) { + case 0: + imms = 0x243219; + ins = VSHR | (1 << 28) | (0x9 << 16); + break; + case 1: + imms = (reg_size == 4) ? 0x243219 : 0x2231; + ins = VSHR | (1 << 28) | (0x11 << 16); + break; + case 2: + imms = (reg_size == 4) ? 0x2231 : 0x21; + ins = VSHR | (1 << 28) | (0x21 << 16); + break; + default: + imms = 0x21; + ins = VSHR | (1 << 28) | (0x1 << 16) | (1 << 7); + break; + } + + if (reg_size == 4) { + freg = simd_get_quad_reg_index(freg); + ins |= (sljit_ins)1 << 6; + } + + SLJIT_ASSERT((freg_map[TMP_FREG2] & 0x1) == 0); + FAIL_IF(push_inst32(compiler, ins | VD4(TMP_FREG2) | VM4(freg))); + + if (reg_size == 4 && elem_size > 0) + FAIL_IF(push_inst32(compiler, VMOVN | ((sljit_ins)(elem_size - 1) << 18) | VD4(TMP_FREG2) | VM4(TMP_FREG2))); + + ins = (reg_size == 4 && elem_size == 0) ? (1 << 6) : 0; + + while (imms >= 0x100) { + FAIL_IF(push_inst32(compiler, VSRA | (1 << 28) | ins | ((imms & 0xff) << 16) | VD4(TMP_FREG2) | VM4(TMP_FREG2))); + imms >>= 8; + } + + FAIL_IF(push_inst32(compiler, VSRA | (1 << 28) | ins | (1 << 7) | (imms << 16) | VD4(TMP_FREG2) | VM4(TMP_FREG2))); + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + FAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RT4(dst_r) | VN4(TMP_FREG2))); + + if (reg_size == 4 && elem_size == 0) { + SLJIT_ASSERT(freg_map[TMP_FREG2] + 1 == freg_map[TMP_FREG1]); + FAIL_IF(push_inst32(compiler, VMOV_s | (1 << 20) | (1 << 23) | (0x2 << 21) | RT4(TMP_REG2)| VN4(TMP_FREG1))); + FAIL_IF(push_inst32(compiler, ORR_W | RD4(dst_r) | RN4(dst_r) | RM4(TMP_REG2) | (0x2 << 12))); + } + + if (dst_r == TMP_REG1) + return emit_op_mem(compiler, STORE | WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + + if (reg_size != 3 && reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + switch (SLJIT_SIMD_GET_OPCODE(type)) { + case SLJIT_SIMD_OP2_AND: + ins = VAND; + break; + case SLJIT_SIMD_OP2_OR: + ins = VORR; + break; + case SLJIT_SIMD_OP2_XOR: + ins = VEOR; + break; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) { + dst_freg = simd_get_quad_reg_index(dst_freg); + src1_freg = simd_get_quad_reg_index(src1_freg); + src2_freg = simd_get_quad_reg_index(src2_freg); + ins |= (sljit_ins)1 << 6; + } + + return push_inst32(compiler, ins | VD4(dst_freg) | VN4(src1_freg) | VM4(src2_freg)); } #undef FPU_LOAD +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV_U8: + ins = LDREXB; + break; + case SLJIT_MOV_U16: + ins = LDREXH; + break; + default: + ins = LDREX; + break; + } + + return push_inst32(compiler, ins | RN4(mem_reg) | RT4(dst_reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_ins ins; + + /* temp_reg == mem_reg is undefined so use another temp register */ + SLJIT_UNUSED_ARG(temp_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV_U8: + ins = STREXB | RM4(TMP_REG1); + break; + case SLJIT_MOV_U16: + ins = STREXH | RM4(TMP_REG1); + break; + default: + ins = STREX | RD4(TMP_REG1); + break; + } + + FAIL_IF(push_inst32(compiler, ins | RN4(mem_reg) | RT4(src_reg))); + if (op & SLJIT_SET_ATOMIC_STORED) + return push_inst32(compiler, CMPI_W | RN4(TMP_REG1)); + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value) { struct sljit_const *const_; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c index e6853c98f67..9620b945f65 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_32.c @@ -26,6 +26,49 @@ /* mips 32-bit arch dependent functions. */ +static sljit_s32 emit_copysign(struct sljit_compiler *compiler, sljit_s32 op, + sljit_sw src1, sljit_sw src2, sljit_sw dst) +{ + int is_32 = (op & SLJIT_32); + sljit_ins mfhc = MFC1, mthc = MTC1; + sljit_ins src1_r = FS(src1), src2_r = FS(src2), dst_r = FS(dst); + + if (!is_32) { + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + mfhc = MFHC1; + mthc = MTHC1; + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + src1_r |= (1 << 11); + src2_r |= (1 << 11); + dst_r |= (1 << 11); + break; + } + } + + FAIL_IF(push_inst(compiler, mfhc | T(TMP_REG1) | src1_r, DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, mfhc | T(TMP_REG2) | src2_r, DR(TMP_REG2))); + if (!is_32 && src1 != dst) + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(src1) | FD(dst), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + else + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + FAIL_IF(push_inst(compiler, XOR | T(TMP_REG1) | D(TMP_REG2) | S(TMP_REG2), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SRL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SLL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, XOR | T(TMP_REG2) | D(TMP_REG1) | S(TMP_REG1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, mthc | T(TMP_REG1) | dst_r, MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + if (mthc == MTC1) + return push_inst(compiler, NOP, UNMOVABLE_INS); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) { if (!(imm & ~0xffff)) @@ -44,6 +87,108 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + struct { +#if defined(SLJIT_LITTLE_ENDIAN) && SLJIT_LITTLE_ENDIAN + sljit_s32 lo; + sljit_s32 hi; +#else /* !SLJIT_LITTLE_ENDIAN */ + sljit_s32 hi; + sljit_s32 lo; +#endif /* SLJIT_LITTLE_ENDIAN */ + } bin; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.bin.lo != 0) + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.bin.lo)); + if (u.bin.hi != 0) + FAIL_IF(load_immediate(compiler, DR(TMP_REG2), u.bin.hi)); + + FAIL_IF(push_inst(compiler, MTC1 | (u.bin.lo != 0 ? T(TMP_REG1) : TA(0)) | FS(freg), MOVABLE_INS)); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + return push_inst(compiler, MTHC1 | (u.bin.hi != 0 ? T(TMP_REG2) : TA(0)) | FS(freg), MOVABLE_INS); +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + FAIL_IF(push_inst(compiler, MTC1 | (u.bin.hi != 0 ? T(TMP_REG2) : TA(0)) | FS(freg) | (1 << 11), MOVABLE_INS)); + break; + } +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_s32 reg2 = 0; + sljit_ins inst = FS(freg); + sljit_ins mthc = MTC1, mfhc = MFC1; + int is_32 = (op & SLJIT_32); + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + op = GET_OPCODE(op); + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + + inst |= T(reg2); + + if (op == SLJIT_COPY_TO_F64) + FAIL_IF(push_inst(compiler, MTC1 | inst, MOVABLE_INS)); + else + FAIL_IF(push_inst(compiler, MFC1 | inst, DR(reg2))); + + inst = FS(freg) | (1 << 11); +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + if (cpu_feature_list & CPU_FEATURE_FR) { + mthc = MTHC1; + mfhc = MFHC1; + inst = FS(freg); + } +#endif /* SLJIT_MIPS_REV >= 2 */ + } + + inst |= T(reg); + if (!is_32 && !reg2) { + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + mthc = MTHC1; + mfhc = MFHC1; + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + inst |= (1 << 11); + break; + } + } + + if (op == SLJIT_COPY_TO_F64) + FAIL_IF(push_inst(compiler, mthc | inst, MOVABLE_INS)); + else + FAIL_IF(push_inst(compiler, mfhc | inst, DR(reg))); + +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + if (mthc == MTC1 || mfhc == MFC1) + return push_inst(compiler, NOP, UNMOVABLE_INS); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins *)addr; @@ -74,6 +219,11 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t sljit_ins ins = NOP; sljit_u8 offsets[4]; sljit_u8 *offsets_ptr = offsets; +#if defined(SLJIT_LITTLE_ENDIAN) && SLJIT_LITTLE_ENDIAN + sljit_ins f64_hi = TA(7), f64_lo = TA(6); +#else + sljit_ins f64_hi = TA(6), f64_lo = TA(7); +#endif /* SLJIT_LITTLE_ENDIAN */ SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12); @@ -138,20 +288,28 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t switch (types & SLJIT_ARG_MASK) { case SLJIT_ARG_TYPE_F64: - if (*offsets_ptr < 4 * sizeof (sljit_sw)) { + if (*offsets_ptr < 4 * sizeof(sljit_sw)) { if (prev_ins != NOP) FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS)); /* Must be preceded by at least one other argument, * and its starting offset must be 8 because of alignment. */ SLJIT_ASSERT((*offsets_ptr >> 2) == 2); - - prev_ins = MFC1 | TA(6) | FS(float_arg_count) | (1 << 11); - ins = MFC1 | TA(7) | FS(float_arg_count); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + prev_ins = MFHC1 | f64_hi | FS(float_arg_count); + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + prev_ins = MFC1 | f64_hi | FS(float_arg_count) | (1 << 11); + break; + } + ins = MFC1 | f64_lo | FS(float_arg_count); } else if (*offsets_ptr < 254) ins = SDC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr); else if (*offsets_ptr == 254) - ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1); + ins = MOV_fmt(FMT_D) | FS(SLJIT_FR0) | FD(TMP_FREG1); float_arg_count--; break; @@ -161,7 +319,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t else if (*offsets_ptr < 254) ins = SWC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(*offsets_ptr); else if (*offsets_ptr == 254) - ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1); + ins = MOV_fmt(FMT_S) | FS(SLJIT_FR0) | FD(TMP_FREG1); float_arg_count--; break; @@ -285,7 +443,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw)); else if (src != PIC_ADDR_REG) FAIL_IF(push_inst(compiler, ADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG))); diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c index d2a5924f8e9..52a0d3fb7ad 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_64.c @@ -26,6 +26,23 @@ /* mips 64-bit arch dependent functions. */ +static sljit_s32 emit_copysign(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src1, sljit_s32 src2, sljit_s32 dst) +{ + FAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | T(TMP_REG1) | FS(src1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | T(TMP_REG2) | FS(src2), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, XOR | S(TMP_REG2) | T(TMP_REG1) | D(TMP_REG2), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, SRL) | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(31), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, XOR | S(TMP_REG1) | T(TMP_REG2) | D(TMP_REG1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, SELECT_OP(DMTC1, MTC1) | T(TMP_REG1) | FS(dst), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + if (!(op & SLJIT_32)) + return push_inst(compiler, NOP, UNMOVABLE_INS); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm) { sljit_s32 shift = 32; @@ -128,6 +145,57 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_sw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm == 0) { + FAIL_IF(push_inst(compiler, DMTC1 | TA(0) | FS(freg), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + return SLJIT_SUCCESS; + } + + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.imm)); + FAIL_IF(push_inst(compiler, DMTC1 | T(TMP_REG1) | FS(freg), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_ins inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + inst = T(reg) | FS(freg); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) + FAIL_IF(push_inst(compiler, SELECT_OP(DMTC1, MTC1) | inst, MOVABLE_INS)); + else + FAIL_IF(push_inst(compiler, SELECT_OP(DMFC1, MFC1) | inst, DR(reg))); + +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + if (!(op & SLJIT_32)) + return push_inst(compiler, NOP, UNMOVABLE_INS); +#endif /* MIPS III */ + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins *)addr; @@ -183,17 +251,17 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t switch (types & SLJIT_ARG_MASK) { case SLJIT_ARG_TYPE_F64: if (arg_count != float_arg_count) - ins = MOV_S | FMT_D | FS(float_arg_count) | FD(arg_count); + ins = MOV_fmt(FMT_D) | FS(float_arg_count) | FD(arg_count); else if (arg_count == 1) - ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1); + ins = MOV_fmt(FMT_D) | FS(SLJIT_FR0) | FD(TMP_FREG1); arg_count--; float_arg_count--; break; case SLJIT_ARG_TYPE_F32: if (arg_count != float_arg_count) - ins = MOV_S | FMT_S | FS(float_arg_count) | FD(arg_count); + ins = MOV_fmt(FMT_S) | FS(float_arg_count) | FD(arg_count); else if (arg_count == 1) - ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1); + ins = MOV_fmt(FMT_S) | FS(SLJIT_FR0) | FD(TMP_FREG1); arg_count--; float_arg_count--; break; @@ -300,7 +368,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2); - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw)); else if (src != PIC_ADDR_REG) FAIL_IF(push_inst(compiler, DADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG))); diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c index 9afe901c382..807b3474ead 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeMIPS_common.c @@ -26,9 +26,12 @@ /* Latest MIPS architecture. */ -#ifndef __mips_hard_float +#ifdef HAVE_PRCTL +#include +#endif + +#if !defined(__mips_hard_float) || defined(__mips_single_float) /* Disable automatic detection, covers both -msoft-float and -mno-float */ -#undef SLJIT_IS_FPU_AVAILABLE #define SLJIT_IS_FPU_AVAILABLE 0 #endif @@ -42,6 +45,14 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) return "MIPS64-R6" SLJIT_CPUINFO; #endif /* SLJIT_CONFIG_MIPS_32 */ +#elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 5) + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return "MIPS32-R5" SLJIT_CPUINFO; +#else /* !SLJIT_CONFIG_MIPS_32 */ + return "MIPS64-R5" SLJIT_CPUINFO; +#endif /* SLJIT_CONFIG_MIPS_32 */ + #elif (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -83,27 +94,31 @@ typedef sljit_u32 sljit_ins; #define EQUAL_FLAG 3 #define OTHER_FLAG 1 +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 7] = { + 0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31, 3, 1 +}; + #define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) #define TMP_FREG3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3) -static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { - 0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31 -}; - #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { - 0, 0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20, 12, 10, 16 +static const sljit_u8 freg_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3) << 1) + 1] = { + 0, + 0, 14, 2, 4, 6, 8, 18, 30, 28, 26, 24, 22, 20, + 12, 10, 16, + 1, 15, 3, 5, 7, 9, 19, 31, 29, 27, 25, 23, 21, + 13, 11, 17 }; -#else +#else /* !SLJIT_CONFIG_MIPS_32 */ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 1, 2, 3, 4, 5, 6, 7, 8, 9, 31, 30, 29, 28, 27, 26, 25, 24, 12, 11, 10 }; -#endif +#endif /* SLJIT_CONFIG_MIPS_32 */ /* --------------------------------------------------------------------- */ /* Instrucion forms */ @@ -200,10 +215,18 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define DMULTU (HI(0) | LO(29)) #endif /* SLJIT_MIPS_REV >= 6 */ #define DIV_S (HI(17) | FMT_S | LO(3)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 #define DINSU (HI(31) | LO(6)) +#endif /* SLJIT_MIPS_REV >= 2 */ +#define DMFC1 (HI(17) | (1 << 21)) +#define DMTC1 (HI(17) | (5 << 21)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 #define DROTR (HI(0) | (1 << 21) | LO(58)) #define DROTR32 (HI(0) | (1 << 21) | LO(62)) #define DROTRV (HI(0) | (1 << 6) | LO(22)) +#define DSBH (HI(31) | (2 << 6) | LO(36)) +#define DSHD (HI(31) | (5 << 6) | LO(36)) +#endif /* SLJIT_MIPS_REV >= 2 */ #define DSLL (HI(0) | LO(56)) #define DSLL32 (HI(0) | LO(60)) #define DSLLV (HI(0) | LO(20)) @@ -232,6 +255,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define LWR (HI(38)) #define LWC1 (HI(49)) #define MFC1 (HI(17)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 +#define MFHC1 (HI(17) | (3 << 21)) +#endif /* SLJIT_MIPS_REV >= 2 */ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define MOD (HI(0) | (3 << 6) | LO(26)) #define MODU (HI(0) | (3 << 6) | LO(27)) @@ -239,8 +265,10 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define MFHI (HI(0) | LO(16)) #define MFLO (HI(0) | LO(18)) #endif /* SLJIT_MIPS_REV >= 6 */ -#define MOV_S (HI(17) | FMT_S | LO(6)) #define MTC1 (HI(17) | (4 << 21)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 +#define MTHC1 (HI(17) | (7 << 21)) +#endif /* SLJIT_MIPS_REV >= 2 */ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 6) #define MUH (HI(0) | (3 << 6) | LO(24)) #define MUHU (HI(0) | (3 << 6) | LO(25)) @@ -256,8 +284,10 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define NOR (HI(0) | LO(39)) #define OR (HI(0) | LO(37)) #define ORI (HI(13)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 #define ROTR (HI(0) | (1 << 21) | LO(2)) #define ROTRV (HI(0) | (1 << 6) | LO(6)) +#endif /* SLJIT_MIPS_REV >= 2 */ #define SD (HI(63)) #define SDL (HI(44)) #define SDR (HI(45)) @@ -279,6 +309,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define SWR (HI(46)) #define SWC1 (HI(57)) #define TRUNC_W_S (HI(17) | FMT_S | LO(13)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 +#define WSBH (HI(31) | (2 << 6) | LO(32)) +#endif /* SLJIT_MIPS_REV >= 2 */ #define XOR (HI(0) | LO(38)) #define XORI (HI(14)) @@ -289,15 +322,21 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #else /* SLJIT_MIPS_REV < 6 */ #define DCLZ (HI(28) | LO(36)) #define MOVF (HI(0) | (0 << 16) | LO(1)) +#define MOVF_S (HI(17) | FMT_S | (0 << 16) | LO(17)) #define MOVN (HI(0) | LO(11)) +#define MOVN_S (HI(17) | FMT_S | LO(19)) #define MOVT (HI(0) | (1 << 16) | LO(1)) +#define MOVT_S (HI(17) | FMT_S | (1 << 16) | LO(17)) #define MOVZ (HI(0) | LO(10)) +#define MOVZ_S (HI(17) | FMT_S | LO(18)) #define MUL (HI(28) | LO(2)) #endif /* SLJIT_MIPS_REV >= 6 */ #define PREF (HI(51)) #define PREFX (HI(19) | LO(15)) +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 #define SEB (HI(31) | (16 << 6) | LO(32)) #define SEH (HI(31) | (24 << 6) | LO(32)) +#endif /* SLJIT_MIPS_REV >= 2 */ #endif /* SLJIT_MIPS_REV >= 1 */ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -318,10 +357,107 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { #define LOAD_W LD #endif +#define MOV_fmt(f) (HI(17) | f | LO(6)) + #define SIMM_MAX (0x7fff) #define SIMM_MIN (-0x8000) #define UIMM_MAX (0xffff) +#define CPU_FEATURE_DETECTED (1 << 0) +#define CPU_FEATURE_FPU (1 << 1) +#define CPU_FEATURE_FP64 (1 << 2) +#define CPU_FEATURE_FR (1 << 3) + +static sljit_u32 cpu_feature_list = 0; + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + && (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) + +static sljit_s32 function_check_is_freg(struct sljit_compiler *compiler, sljit_s32 fr, sljit_s32 is_32) +{ + if (compiler->scratches == -1) + return 0; + + if (is_32 && fr >= SLJIT_F64_SECOND(SLJIT_FR0)) + fr -= SLJIT_F64_SECOND(0); + + return (fr >= SLJIT_FR0 && fr < (SLJIT_FR0 + compiler->fscratches)) + || (fr > (SLJIT_FS0 - compiler->fsaveds) && fr <= SLJIT_FS0) + || (fr >= SLJIT_TMP_FREGISTER_BASE && fr < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)); +} + +#endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_ARGUMENT_CHECKS */ + +static void get_cpu_features(void) +{ +#if !defined(SLJIT_IS_FPU_AVAILABLE) && defined(__GNUC__) + sljit_u32 fir = 0; +#endif /* !SLJIT_IS_FPU_AVAILABLE && __GNUC__ */ + sljit_u32 feature_list = CPU_FEATURE_DETECTED; + +#if defined(SLJIT_IS_FPU_AVAILABLE) +#if SLJIT_IS_FPU_AVAILABLE + feature_list |= CPU_FEATURE_FPU; +#if SLJIT_IS_FPU_AVAILABLE == 64 + feature_list |= CPU_FEATURE_FP64; +#endif /* SLJIT_IS_FPU_AVAILABLE == 64 */ +#endif /* SLJIT_IS_FPU_AVAILABLE */ +#elif defined(__GNUC__) + __asm__ ("cfc1 %0, $0" : "=r"(fir)); + if ((fir & (0x3 << 16)) == (0x3 << 16)) + feature_list |= CPU_FEATURE_FPU; + +#if (defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64) \ + && (!defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV < 2) + if ((feature_list & CPU_FEATURE_FPU)) + feature_list |= CPU_FEATURE_FP64; +#else /* SLJIT_CONFIG_MIPS32 || SLJIT_MIPS_REV >= 2 */ + if ((fir & (1 << 22))) + feature_list |= CPU_FEATURE_FP64; +#endif /* SLJIT_CONFIG_MIPS_64 && SLJIT_MIPS_REV < 2 */ +#endif /* SLJIT_IS_FPU_AVAILABLE */ + + if ((feature_list & CPU_FEATURE_FPU) && (feature_list & CPU_FEATURE_FP64)) { +#if defined(SLJIT_CONFIG_MIPS_32) && SLJIT_CONFIG_MIPS_32 +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 6 + feature_list |= CPU_FEATURE_FR; +#elif defined(SLJIT_DETECT_FR) && SLJIT_DETECT_FR == 0 +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 5 + feature_list |= CPU_FEATURE_FR; +#endif /* SLJIT_MIPS_REV >= 5 */ +#else + sljit_s32 flag = -1; +#ifndef FR_GET_FP_MODE + sljit_f64 zero = 0.0; +#else /* PR_GET_FP_MODE */ + flag = prctl(PR_GET_FP_MODE); + + if (flag > 0) + feature_list |= CPU_FEATURE_FR; +#endif /* FP_GET_PR_MODE */ +#if ((defined(SLJIT_DETECT_FR) && SLJIT_DETECT_FR == 2) \ + || (!defined(PR_GET_FP_MODE) && (!defined(SLJIT_DETECT_FR) || SLJIT_DETECT_FR >= 1))) \ + && (defined(__GNUC__) && (defined(__mips) && __mips >= 2)) + if (flag < 0) { + __asm__ (".set oddspreg\n" + "lwc1 $f17, %0\n" + "ldc1 $f16, %1\n" + "swc1 $f17, %0\n" + : "+m" (flag) : "m" (zero) : "$f16", "$f17"); + if (flag) + feature_list |= CPU_FEATURE_FR; + } +#endif /* (!PR_GET_FP_MODE || (PR_GET_FP_MODE && SLJIT_DETECT_FR == 2)) && __GNUC__ */ +#endif /* SLJIT_MIPS_REV >= 6 */ +#else /* !SLJIT_CONFIG_MIPS_32 */ + /* StatusFR=1 is the only mode supported by the code in MIPS64 */ + feature_list |= CPU_FEATURE_FR; +#endif /* SLJIT_CONFIG_MIPS_32 */ + } + + cpu_feature_list = feature_list; +} + /* dest_reg is the absolute name of the register Useful for reordering instructions in the delay slot. */ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot) @@ -715,21 +851,23 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) { -#if defined(__GNUC__) && !defined(SLJIT_IS_FPU_AVAILABLE) - sljit_sw fir = 0; -#endif /* __GNUC__ && !SLJIT_IS_FPU_AVAILABLE */ - switch (feature_type) { +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ + && (!defined(SLJIT_IS_FPU_AVAILABLE) || SLJIT_IS_FPU_AVAILABLE) + case SLJIT_HAS_F64_AS_F32_PAIR: + if (!cpu_feature_list) + get_cpu_features(); + + return (cpu_feature_list & CPU_FEATURE_FR) != 0; +#endif /* SLJIT_CONFIG_MIPS_32 && SLJIT_IS_FPU_AVAILABLE */ case SLJIT_HAS_FPU: -#ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; -#elif defined(__GNUC__) - __asm__ ("cfc1 %0, $0" : "=r"(fir)); - return (fir >> 22) & 0x1; -#else -#error "FIR check is not implemented for this architecture" -#endif + if (!cpu_feature_list) + get_cpu_features(); + + return (cpu_feature_list & CPU_FEATURE_FPU) != 0; case SLJIT_HAS_ZERO_REGISTER: + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: return 1; #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) case SLJIT_HAS_CLZ: @@ -741,6 +879,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) return 2; #endif /* SLJIT_MIPS_REV >= 1 */ #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) + case SLJIT_HAS_REV: case SLJIT_HAS_ROT: return 1; #endif /* SLJIT_MIPS_REV >= 2 */ @@ -751,7 +890,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - return (type >= SLJIT_ORDERED_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL); + SLJIT_UNUSED_ARG(type); + return 0; } /* --------------------------------------------------------------------- */ @@ -791,6 +931,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw); static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr); +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#define SELECT_OP(a, b) (b) +#else +#define SELECT_OP(a, b) (!(op & SLJIT_32) ? a : b) +#endif + #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #include "sljitNativeMIPS_32.c" #else @@ -815,12 +961,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { if ((local_size & SSIZE_OF(sw)) != 0) local_size += SSIZE_OF(sw); - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; #else - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f; #endif compiler->local_size = local_size; @@ -918,10 +1064,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (word_arg_count == 0 && float_arg_count <= 2) { if (float_arg_count == 1) - FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); } else if (arg_count < 4) { FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS)); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + FAIL_IF(push_inst(compiler, MTHC1 | TA(5 + arg_count) | FS(float_arg_count), MOVABLE_INS)); + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + FAIL_IF(push_inst(compiler, MTC1 | TA(5 + arg_count) | FS(float_arg_count) | (1 << 11), MOVABLE_INS)); + break; + } } else FAIL_IF(push_inst(compiler, LDC1 | base | FT(float_arg_count) | IMM(local_size + (arg_count << 2)), MOVABLE_INS)); arg_count++; @@ -931,7 +1086,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (word_arg_count == 0 && float_arg_count <= 2) { if (float_arg_count == 1) - FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); } else if (arg_count < 4) FAIL_IF(push_inst(compiler, MTC1 | TA(4 + arg_count) | FS(float_arg_count), MOVABLE_INS)); else @@ -966,16 +1121,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi case SLJIT_ARG_TYPE_F64: float_arg_count++; if (arg_count != float_arg_count) - FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(arg_count) | FD(float_arg_count), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS)); else if (arg_count == 1) - FAIL_IF(push_inst(compiler, MOV_S | FMT_D | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_D) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); break; case SLJIT_ARG_TYPE_F32: float_arg_count++; if (arg_count != float_arg_count) - FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(arg_count) | FD(float_arg_count), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(arg_count) | FD(float_arg_count), MOVABLE_INS)); else if (arg_count == 1) - FAIL_IF(push_inst(compiler, MOV_S | FMT_S | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT_S) | FS(TMP_FREG1) | FD(SLJIT_FR0), MOVABLE_INS)); break; default: word_arg_count++; @@ -1011,12 +1166,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { if ((local_size & SSIZE_OF(sw)) != 0) local_size += SSIZE_OF(sw); - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; #else - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 31) & ~0x1f; #endif return SLJIT_SUCCESS; @@ -1042,10 +1197,10 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { if ((tmp & SSIZE_OF(sw)) != 0) tmp += SSIZE_OF(sw); - tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } #else - tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + tmp += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); #endif if (local_size <= SIMM_MAX) { @@ -1138,7 +1293,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c FAIL_IF(emit_stack_frame_release(compiler, 1, &ins)); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS)); return push_inst(compiler, ins, UNMOVABLE_INS); } @@ -1388,16 +1543,12 @@ static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, slji #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#define SELECT_OP(a, b) (b) - #define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \ op_imm = (imm); \ op_v = (v); #else /* !SLJIT_CONFIG_MIPS_32 */ -#define SELECT_OP(a, b) \ - (!(op & SLJIT_32) ? a : b) #define EMIT_SHIFT(dimm, dimm32, imm, dv, v) \ op_dimm = (dimm); \ @@ -1414,10 +1565,10 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj { sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ); #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - sljit_ins max = (op & SLJIT_32) ? 32 : 64; -#else /* !SLJIT_CONFIG_RISCV_64 */ - sljit_ins max = 32; -#endif /* SLJIT_CONFIG_RISCV_64 */ + sljit_ins word_size = (op & SLJIT_32) ? 32 : 64; +#else /* !SLJIT_CONFIG_MIPS_64 */ + sljit_ins word_size = 32; +#endif /* SLJIT_CONFIG_MIPS_64 */ /* The TMP_REG2 is the next value. */ if (src != TMP_REG2) @@ -1425,7 +1576,7 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG2) | TA(0) | IMM(is_clz ? 13 : 14), UNMOVABLE_INS)); /* The OTHER_FLAG is the counter. Delay slot. */ - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(max), OTHER_FLAG)); + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(word_size), OTHER_FLAG)); if (!is_clz) { FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG2) | T(TMP_REG1) | IMM(1), DR(TMP_REG1))); @@ -1437,7 +1588,7 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(OTHER_FLAG) | IMM(0), OTHER_FLAG)); /* The TMP_REG1 is the next shift. */ - FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(TMP_REG1) | IMM(max), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(TMP_REG1) | IMM(word_size), DR(TMP_REG1))); FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(TMP_REG2) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG)); FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1))); @@ -1459,6 +1610,104 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj #endif /* SLJIT_MIPS_REV < 1 */ +static sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src) +{ +#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64 + int is_32 = (op & SLJIT_32); +#endif /* SLJIT_CONFIG_MIPS_64 */ + + op = GET_OPCODE(op); +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 +#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64 + if (!is_32 && (op == SLJIT_REV)) { + FAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst))); + return push_inst(compiler, DSHD | T(dst) | D(dst), DR(dst)); + } + if (op != SLJIT_REV && src != TMP_REG2) { + FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG1), DR(TMP_REG1))); + src = TMP_REG1; + } +#endif /* SLJIT_CONFIG_MIPS_64 */ + FAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst))); + FAIL_IF(push_inst(compiler, ROTR | T(dst) | D(dst) | SH_IMM(16), DR(dst))); +#if defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64 + if (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3) + FAIL_IF(push_inst(compiler, DINSU | T(dst) | SA(0) | (31 << 11), DR(dst))); +#endif /* SLJIT_CONFIG_MIPS_64 */ +#else /* SLJIT_MIPS_REV < 2 */ +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (!is_32) { + FAIL_IF(push_inst(compiler, DSRL32 | T(src) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, ORI | SA(0) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG)); + FAIL_IF(push_inst(compiler, DSLL32 | T(src) | D(dst) | SH_IMM(0), DR(dst))); + FAIL_IF(push_inst(compiler, DSLL32 | TA(OTHER_FLAG) | DA(OTHER_FLAG) | SH_IMM(0), OTHER_FLAG)); + FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst))); + + FAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xffff, OTHER_FLAG)); + FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst))); + FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, DSLL | TA(OTHER_FLAG) | DA(EQUAL_FLAG) | SH_IMM(8), EQUAL_FLAG)); + FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst))); + FAIL_IF(push_inst(compiler, XOR | SA(OTHER_FLAG) | TA(EQUAL_FLAG) | DA(OTHER_FLAG), OTHER_FLAG)); + FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst))); + + FAIL_IF(push_inst(compiler, DSRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst))); + FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(8), DR(dst))); + return push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)); + } + + if (op != SLJIT_REV && src != TMP_REG2) { + FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG2) | SH_IMM(0), DR(TMP_REG2))); + src = TMP_REG2; + } +#endif /* SLJIT_CONFIG_MIPS_64 */ + + FAIL_IF(push_inst(compiler, SRL | T(src) | D(TMP_REG1) | SH_IMM(16), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, LUI | TA(OTHER_FLAG) | 0xff, OTHER_FLAG)); + FAIL_IF(push_inst(compiler, SLL | T(src) | D(dst) | SH_IMM(16), DR(dst))); + FAIL_IF(push_inst(compiler, ORI | SA(OTHER_FLAG) | TA(OTHER_FLAG) | 0xff, OTHER_FLAG)); + FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst))); + + FAIL_IF(push_inst(compiler, SRL | T(dst) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, AND | S(dst) | TA(OTHER_FLAG) | D(dst), DR(dst))); + FAIL_IF(push_inst(compiler, AND | S(TMP_REG1) | TA(OTHER_FLAG) | D(TMP_REG1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, SLL | T(dst) | D(dst) | SH_IMM(8), DR(dst))); + FAIL_IF(push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst))); + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (op == SLJIT_REV_U32 && dst != TMP_REG2 && dst != TMP_REG3) { + FAIL_IF(push_inst(compiler, DSLL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst))); + FAIL_IF(push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst))); + } +#endif /* SLJIT_CONFIG_MIPS_64 */ +#endif /* SLJIT_MIPR_REV >= 2 */ + return SLJIT_SUCCESS; +} + +static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src) +{ +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 +#if defined(SLJIT_CONFIG_MIPS_32) && SLJIT_CONFIG_MIPS_32 + FAIL_IF(push_inst(compiler, WSBH | T(src) | D(dst), DR(dst))); +#else /* !SLJIT_CONFIG_MIPS_32 */ + FAIL_IF(push_inst(compiler, DSBH | T(src) | D(dst), DR(dst))); +#endif /* SLJIT_CONFIG_MIPS_32 */ + if (GET_OPCODE(op) == SLJIT_REV_U16) + return push_inst(compiler, ANDI | S(dst) | T(dst) | 0xffff, DR(dst)); + else + return push_inst(compiler, SEH | T(dst) | D(dst), DR(dst)); +#else /* SLJIT_MIPS_REV < 2 */ + FAIL_IF(push_inst(compiler, SELECT_OP(DSRL, SRL) | T(src) | D(TMP_REG1) | SH_IMM(8), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | T(src) | D(dst) | SH_IMM(24), DR(dst))); + FAIL_IF(push_inst(compiler, ANDI | S(TMP_REG1) | T(TMP_REG1) | 0xff, DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SELECT_OP(DSRL32, SRL) : SELECT_OP(DSRA32, SRA)) | T(dst) | D(dst) | SH_IMM(16), DR(dst))); + return push_inst(compiler, OR | S(dst) | T(TMP_REG1) | D(dst), DR(dst)); +#endif /* SLJIT_MIPS_REV >= 2 */ +} + static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_s32 src1, sljit_sw src2) { @@ -1486,17 +1735,17 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); -#else /* SLJIT_MIPS_REV < 1 */ +#else /* SLJIT_MIPS_REV < 2 */ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst))); return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst)); -#endif /* SLJIT_MIPS_REV >= 1 */ +#endif /* SLJIT_MIPS_REV >= 2 */ #else /* !SLJIT_CONFIG_MIPS_32 */ -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) if (op & SLJIT_32) return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); -#endif /* SLJIT_MIPS_REV >= 1 */ +#endif /* SLJIT_MIPS_REV >= 2 */ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst))); return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst)); #endif /* SLJIT_CONFIG_MIPS_32 */ @@ -1515,17 +1764,17 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); -#else /* SLJIT_MIPS_REV < 1 */ +#else /* SLJIT_MIPS_REV < 2 */ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst))); return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst)); -#endif /* SLJIT_MIPS_REV >= 1 */ +#endif /* SLJIT_MIPS_REV >= 2 */ #else /* !SLJIT_CONFIG_MIPS_32 */ -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) if (op & SLJIT_32) return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); -#endif /* SLJIT_MIPS_REV >= 1 */ +#endif /* SLJIT_MIPS_REV >= 2 */ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst))); return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst)); #endif /* SLJIT_CONFIG_MIPS_32 */ @@ -1539,7 +1788,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) if (dst == src2) - return push_inst(compiler, DINSU | T(src2) | SA(0) | (31 << 11) | (0 << 11), DR(dst)); + return push_inst(compiler, DINSU | T(src2) | SA(0) | (31 << 11), DR(dst)); #endif /* SLJIT_MIPS_REV >= 2 */ FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst))); return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst)); @@ -1556,14 +1805,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return SLJIT_SUCCESS; #endif /* SLJIT_CONFIG_MIPS_64 */ - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (op & SLJIT_SET_Z) - FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (!(flags & UNUSED_DEST)) - FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); - return SLJIT_SUCCESS; - #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1) case SLJIT_CLZ: SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); @@ -1591,10 +1832,21 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return emit_clz_ctz(compiler, op, dst, src2); #endif /* SLJIT_MIPS_REV >= 1 */ + case SLJIT_REV: + case SLJIT_REV_U32: + case SLJIT_REV_S32: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && src2 != TMP_REG1 && dst != TMP_REG1); + return emit_rev(compiler, op, dst, src2); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + return emit_rev16(compiler, op, dst, src2); + case SLJIT_ADD: /* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */ is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW; - carry_src_ar = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + carry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_overflow) { @@ -1650,7 +1902,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return push_inst(compiler, XOR | S(TMP_REG1) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG); case SLJIT_ADDC: - carry_src_ar = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + carry_src_ar = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst))); @@ -1697,11 +1949,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl is_handled = 0; if (flags & SRC2_IMM) { - if (GET_FLAG_TYPE(op) == SLJIT_LESS || GET_FLAG_TYPE(op) == SLJIT_GREATER_EQUAL) { + if (GET_FLAG_TYPE(op) == SLJIT_LESS) { FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG)); is_handled = 1; } - else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS || GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER_EQUAL) { + else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) { FAIL_IF(push_inst(compiler, SLTI | S(src1) | TA(OTHER_FLAG) | IMM(src2), OTHER_FLAG)); is_handled = 1; } @@ -1718,19 +1970,15 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl switch (GET_FLAG_TYPE(op)) { case SLJIT_LESS: - case SLJIT_GREATER_EQUAL: FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG)); break; case SLJIT_GREATER: - case SLJIT_LESS_EQUAL: FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG)); break; case SLJIT_SIG_LESS: - case SLJIT_SIG_GREATER_EQUAL: FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(OTHER_FLAG), OTHER_FLAG)); break; case SLJIT_SIG_GREATER: - case SLJIT_SIG_LESS_EQUAL: FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(OTHER_FLAG), OTHER_FLAG)); break; } @@ -1753,7 +2001,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW; - is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_overflow) { @@ -1802,7 +2050,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl flags &= ~SRC2_IMM; } - is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_carry) @@ -1868,6 +2116,14 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return SLJIT_SUCCESS; case SLJIT_XOR: + if (!(flags & LOGICAL_OP)) { + SLJIT_ASSERT((flags & SRC2_IMM) && src2 == -1); + if (op & SLJIT_SET_Z) + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (!(flags & UNUSED_DEST)) + FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | D(dst), DR(dst))); + return SLJIT_SUCCESS; + } EMIT_LOGICAL(XORI, XOR); return SLJIT_SUCCESS; @@ -2034,9 +2290,10 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 compiler->cache_argw = 0; } - if (dst == TMP_REG2) { + if (dst == 0) { SLJIT_ASSERT(HAS_FLAGS(op)); flags |= UNUSED_DEST; + dst = TMP_REG2; } else if (FAST_IS_REG(dst)) { dst_r = dst; @@ -2048,10 +2305,10 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 flags |= SLOW_DEST; if (flags & IMM_OP) { - if ((src2 & SLJIT_IMM) && src2w != 0 && CHECK_IMM(flags, src2w)) { + if (src2 == SLJIT_IMM && src2w != 0 && CHECK_IMM(flags, src2w)) { flags |= SRC2_IMM; src2_r = src2w; - } else if ((flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w != 0 && CHECK_IMM(flags, src1w)) { + } else if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && CHECK_IMM(flags, src1w)) { flags |= SRC2_IMM; src2_r = src1w; @@ -2068,7 +2325,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 src1_r = src1; flags |= REG1_SOURCE; } - else if (src1 & SLJIT_IMM) { + else if (src1 == SLJIT_IMM) { if (src1w) { FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); src1_r = TMP_REG1; @@ -2091,7 +2348,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP) dst_r = (sljit_s32)src2_r; } - else if (src2 & SLJIT_IMM) { + else if (src2 == SLJIT_IMM) { if (!(flags & SRC2_IMM)) { if (src2w) { FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w)); @@ -2279,31 +2536,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) case SLJIT_MOV_U32: - return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u32)srcw : srcw); case SLJIT_MOV_S32: case SLJIT_MOV32: - return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw); #endif case SLJIT_MOV_U8: - return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); + return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw); case SLJIT_MOV_S8: - return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); + return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw); case SLJIT_MOV_U16: - return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); + return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw); case SLJIT_MOV_S16: - return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); - - case SLJIT_NOT: - return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_CLZ: case SLJIT_CTZ: + case SLJIT_REV: return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + return emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_REV_U32: + case SLJIT_REV_S32: + return emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); } SLJIT_UNREACHABLE(); @@ -2326,9 +2589,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) if (op & SLJIT_32) { flags |= INT_DATA | SIGNED_DATA; - if (src1 & SLJIT_IMM) + if (src1 == SLJIT_IMM) src1w = (sljit_s32)src1w; - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) src2w = (sljit_s32)src2w; } #endif @@ -2348,9 +2611,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile compiler->status_flags_state = 0; return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); + case SLJIT_XOR: + if ((src1 == SLJIT_IMM && src1w == -1) || (src2 == SLJIT_IMM && src2w == -1)) { + return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + } + /* fallthrough */ case SLJIT_AND: case SLJIT_OR: - case SLJIT_XOR: return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SHL: @@ -2362,10 +2629,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile case SLJIT_ROTL: case SLJIT_ROTR: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) src2w &= 0x1f; #else - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { if (op & SLJIT_32) src2w &= 0x1f; else @@ -2387,7 +2654,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w)); SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w); + return sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w); } #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) @@ -2399,9 +2666,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil #endif /* SLJIT_CONFIG_MIPS_64 */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_left; sljit_ins ins1, ins2, ins3; @@ -2414,50 +2682,44 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * #endif /* SLJIT_CONFIG_MIPS_64 */ CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); - if (src2 & SLJIT_IMM) { - src2w &= bit_length - 1; + if (src3 == SLJIT_IMM) { + src3w &= bit_length - 1; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src2, src2w)); - src2 = TMP_REG2; - } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); - src1 = TMP_REG1; - } - - if (src2 & SLJIT_IMM) { if (is_left) { - ins1 = SELECT_OP3(op, src2w, DSLL, DSLL32, SLL); - src2w = bit_length - src2w; - ins2 = SELECT_OP3(op, src2w, DSRL, DSRL32, SRL); + ins1 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL); + src3w = bit_length - src3w; + ins2 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL); } else { - ins1 = SELECT_OP3(op, src2w, DSRL, DSRL32, SRL); - src2w = bit_length - src2w; - ins2 = SELECT_OP3(op, src2w, DSLL, DSLL32, SLL); + ins1 = SELECT_OP3(op, src3w, DSRL, DSRL32, SRL); + src3w = bit_length - src3w; + ins2 = SELECT_OP3(op, src3w, DSLL, DSLL32, SLL); } - FAIL_IF(push_inst(compiler, ins1 | T(src_dst) | D(src_dst), DR(src_dst))); - FAIL_IF(push_inst(compiler, ins2 | T(src1) | D(TMP_REG1), DR(TMP_REG1))); - return push_inst(compiler, OR | S(src_dst) | T(TMP_REG1) | D(src_dst), DR(src_dst)); + FAIL_IF(push_inst(compiler, ins1 | T(src1_reg) | D(dst_reg), DR(dst_reg))); + FAIL_IF(push_inst(compiler, ins2 | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1))); + return push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg)); + } + + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src3, src3w)); + src3 = TMP_REG2; + } else if (dst_reg == src3) { + FAIL_IF(push_inst(compiler, SELECT_OP2(op, DADDU, ADDU) | S(src3) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); + src3 = TMP_REG2; } if (is_left) { @@ -2470,17 +2732,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * ins3 = SELECT_OP2(op, DSLLV, SLLV); } - FAIL_IF(push_inst(compiler, ins2 | S(src2) | T(src_dst) | D(src_dst), DR(src_dst))); + FAIL_IF(push_inst(compiler, ins2 | S(src3) | T(src1_reg) | D(dst_reg), DR(dst_reg))); if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) { - FAIL_IF(push_inst(compiler, ins1 | T(src1) | D(TMP_REG1) | (1 << 6), DR(TMP_REG1))); - FAIL_IF(push_inst(compiler, XORI | S(src2) | T(TMP_REG2) | ((sljit_ins)bit_length - 1), DR(TMP_REG2))); - src1 = TMP_REG1; + FAIL_IF(push_inst(compiler, ins1 | T(src2_reg) | D(TMP_REG1) | (1 << 6), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, XORI | S(src3) | T(TMP_REG2) | ((sljit_ins)bit_length - 1), DR(TMP_REG2))); + src2_reg = TMP_REG1; } else - FAIL_IF(push_inst(compiler, SELECT_OP2(op, DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG2), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SELECT_OP2(op, DSUBU, SUBU) | SA(0) | T(src3) | D(TMP_REG2), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, ins3 | S(TMP_REG2) | T(src1) | D(TMP_REG1), DR(TMP_REG1))); - return push_inst(compiler, OR | S(src_dst) | T(TMP_REG1) | D(src_dst), DR(src_dst)); + FAIL_IF(push_inst(compiler, ins3 | S(TMP_REG2) | T(src2_reg) | D(TMP_REG1), DR(TMP_REG1))); + return push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg)); } #undef SELECT_OP3 @@ -2518,21 +2780,54 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 dst_ar = RETURN_ADDR_REG; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + if (FAST_IS_REG(dst)) + return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS); + break; + case SLJIT_GET_RETURN_ADDRESS: + dst_ar = DR(FAST_IS_REG(dst) ? dst : TMP_REG2); + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_ar, SLJIT_MEM1(SLJIT_SP), compiler->local_size - SSIZE_OF(sw))); + break; + } + + if (dst & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw)); + + if (op == SLJIT_FAST_ENTER) + compiler->delay_slot = UNMOVABLE_INS; + } + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type != SLJIT_FLOAT_REGISTER) + return -1; + return FR(reg); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_u32 size) { + SLJIT_UNUSED_ARG(size); + CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -2544,14 +2839,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c /* --------------------------------------------------------------------- */ #define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 7)) -#define FMT(op) ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) << (21 - 8)) +#define FMT(op) (FMT_S | (~(sljit_ins)op & SLJIT_32) << (21 - (5 + 3))) static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define flags (sljit_u32)0 + sljit_u32 flags = 0; #else sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64)) << 21; #endif @@ -2565,18 +2860,13 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp if (FAST_IS_REG(dst)) { FAIL_IF(push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) +#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif +#endif /* MIPS III */ return SLJIT_SUCCESS; } - /* Store the integer value from a VFP register. */ return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, FR(TMP_FREG1), dst, dstw, 0, 0); - -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# undef flags -#endif } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, @@ -2584,43 +2874,158 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp sljit_s32 src, sljit_sw srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define flags (sljit_u32)0 + sljit_u32 flags = 0; #else sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)) << 21; #endif - sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - if (FAST_IS_REG(src)) { - FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif - } else if (src & SLJIT_MEM) { - /* Load the integer value into a VFP register. */ + if (src & SLJIT_MEM) FAIL_IF(emit_op_mem2(compiler, (flags ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw)); - } else { + if (src == SLJIT_IMM) { #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) - srcw = (sljit_s32)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; #endif - FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); - FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); + src = TMP_REG1; + } + + FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif +#endif /* MIPS III */ } - FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((((sljit_ins)op & SLJIT_32) ^ SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); if (dst & SLJIT_MEM) return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0); return SLJIT_SUCCESS; +} +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# undef flags + sljit_u32 flags = 0; +#else + sljit_u32 flags = 1 << 21; #endif + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem2(compiler, (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_UW ? WORD_DATA : INT_DATA) | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw)); + src = TMP_REG1; + } else if (src == SLJIT_IMM) { +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) + srcw = (sljit_u32)srcw; +#endif + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); + src = TMP_REG1; + } + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) { + if (src != TMP_REG1) { + FAIL_IF(push_inst(compiler, DSLL32 | T(src) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, DSRL32 | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(0), DR(TMP_REG1))); + } + + FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0); + return SLJIT_SUCCESS; + } +#else /* !SLJIT_CONFIG_MIPS_64 */ + if (!(op & SLJIT_32)) { + FAIL_IF(push_inst(compiler, SLL | T(src) | D(TMP_REG2) | SH_IMM(1), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, SRL | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(1), DR(TMP_REG2))); + + FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG2) | FS(TMP_FREG1), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | 1 | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + +#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1) + FAIL_IF(push_inst(compiler, BGEZ | S(src) | 5, UNMOVABLE_INS)); +#else /* SLJIT_MIPS_REV >= 1 */ + FAIL_IF(push_inst(compiler, BGEZ | S(src) | 4, UNMOVABLE_INS)); +#endif /* SLJIT_MIPS_REV < 1 */ + + FAIL_IF(push_inst(compiler, LUI | T(TMP_REG2) | IMM(0x41e0), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, MTC1 | TA(0) | FS(TMP_FREG2), UNMOVABLE_INS)); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + FAIL_IF(push_inst(compiler, MTHC1 | T(TMP_REG2) | FS(TMP_FREG2), UNMOVABLE_INS)); + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(TMP_FREG2) | (1 << 11), UNMOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + break; + } + FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(TMP_FREG2) | FS(dst_r) | FD(dst_r), UNMOVABLE_INS)); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0); + return SLJIT_SUCCESS; + } +#endif /* SLJIT_CONFIG_MIPS_64 */ + +#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1) + FAIL_IF(push_inst(compiler, BLTZ | S(src) | 5, UNMOVABLE_INS)); +#else /* SLJIT_MIPS_REV >= 1 */ + FAIL_IF(push_inst(compiler, BLTZ | S(src) | 4, UNMOVABLE_INS)); +#endif /* SLJIT_MIPS_REV < 1 */ + FAIL_IF(push_inst(compiler, ANDI | S(src) | T(TMP_REG2) | IMM(1), DR(TMP_REG2))); + + FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* !SLJIT_MIPS_REV */ + + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + +#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 1) + FAIL_IF(push_inst(compiler, BEQ | 6, UNMOVABLE_INS)); +#else /* SLJIT_MIPS_REV >= 1 */ + FAIL_IF(push_inst(compiler, BEQ | 5, UNMOVABLE_INS)); +#endif /* SLJIT_MIPS_REV < 1 */ + +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + FAIL_IF(push_inst(compiler, DSRL | T(src) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1))); +#else /* !SLJIT_CONFIG_MIPS_64 */ + FAIL_IF(push_inst(compiler, SRL | T(src) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1))); +#endif /* SLJIT_CONFIG_MIPS_64 */ + + FAIL_IF(push_inst(compiler, OR | S(TMP_REG1) | T(TMP_REG2) | D(TMP_REG1), DR(TMP_REG1))); + + FAIL_IF(push_inst(compiler, MTC1 | flags | T(TMP_REG1) | FS(TMP_FREG1), MOVABLE_INS)); +#if !defined(SLJIT_MIPS_REV) + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* !SLJIT_MIPS_REV */ + + FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | ((~(sljit_ins)op & SLJIT_32) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(dst_r) | FS(dst_r) | FD(dst_r), UNMOVABLE_INS)); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0); + return SLJIT_SUCCESS; } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, @@ -2642,36 +3047,30 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile switch (GET_FLAG_TYPE(op)) { case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: - case SLJIT_UNORDERED_OR_NOT_EQUAL: inst = C_EQ_S; break; case SLJIT_F_NOT_EQUAL: case SLJIT_UNORDERED_OR_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: inst = C_UEQ_S; break; case SLJIT_F_LESS: case SLJIT_ORDERED_LESS: - case SLJIT_UNORDERED_OR_GREATER_EQUAL: inst = C_OLT_S; break; case SLJIT_F_GREATER_EQUAL: case SLJIT_UNORDERED_OR_LESS: - case SLJIT_ORDERED_GREATER_EQUAL: inst = C_ULT_S; break; case SLJIT_F_GREATER: case SLJIT_ORDERED_GREATER: - case SLJIT_UNORDERED_OR_LESS_EQUAL: inst = C_ULE_S; break; case SLJIT_F_LESS_EQUAL: case SLJIT_UNORDERED_OR_GREATER: - case SLJIT_ORDERED_LESS_EQUAL: inst = C_OLE_S; break; default: - SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_UNORDERED || GET_FLAG_TYPE(op) == SLJIT_ORDERED); + SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_UNORDERED); inst = C_UN_S; break; } @@ -2705,7 +3104,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil case SLJIT_MOV_F64: if (src != dst_r) { if (dst_r != TMP_FREG1) - FAIL_IF(push_inst(compiler, MOV_S | FMT(op) | FS(src) | FD(dst_r), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_fmt(FMT(op)) | FS(src) | FD(dst_r), MOVABLE_INS)); else dst_r = src; } @@ -2786,18 +3185,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, ADD_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, SUB_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, MUL_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; - case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, DIV_S | FMT(op) | FT(src2) | FS(src1) | FD(dst_r), MOVABLE_INS)); break; + case SLJIT_COPYSIGN_F64: + return emit_copysign(compiler, op, src1, src2, dst_r); } if (dst_r == TMP_FREG2) @@ -2806,26 +3204,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return SLJIT_SUCCESS; } -#undef FLOAT_DATA -#undef FMT - -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { + union { + sljit_s32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - if (FAST_IS_REG(dst)) - return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS); + u.value = value; - /* Memory. */ - FAIL_IF(emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw)); - compiler->delay_slot = UNMOVABLE_INS; - return SLJIT_SUCCESS; + if (u.imm == 0) + return push_inst(compiler, MTC1 | TA(0) | FS(freg), MOVABLE_INS); + + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), u.imm)); + return push_inst(compiler, MTC1 | T(TMP_REG1) | FS(freg), MOVABLE_INS); } /* --------------------------------------------------------------------- */ @@ -2984,7 +3380,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile } #define RESOLVE_IMM1() \ - if (src1 & SLJIT_IMM) { \ + if (src1 == SLJIT_IMM) { \ if (src1w) { \ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); \ src1 = TMP_REG1; \ @@ -2994,7 +3390,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile } #define RESOLVE_IMM2() \ - if (src2 & SLJIT_IMM) { \ + if (src2 == SLJIT_IMM) { \ if (src2w) { \ PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \ src2 = TMP_REG2; \ @@ -3046,10 +3442,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler if (compiler->delay_slot == MOVABLE_INS || (compiler->delay_slot != UNMOVABLE_INS && compiler->delay_slot != DR(src1) && compiler->delay_slot != DR(src2))) jump->flags |= IS_MOVABLE; PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(src1) | T(src2) | BRANCH_LENGTH, UNMOVABLE_INS)); - } - else if (type >= SLJIT_SIG_LESS && (((src1 & SLJIT_IMM) && (src1w == 0)) || ((src2 & SLJIT_IMM) && (src2w == 0)))) { + } else if (type >= SLJIT_SIG_LESS && ((src1 == SLJIT_IMM && src1w == 0) || (src2 == SLJIT_IMM && src2w == 0))) { inst = NOP; - if ((src1 & SLJIT_IMM) && (src1w == 0)) { + if (src1 == SLJIT_IMM && src1w == 0) { RESOLVE_IMM2(); switch (type) { case SLJIT_SIG_LESS: @@ -3097,7 +3492,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler else { if (type == SLJIT_LESS || type == SLJIT_GREATER_EQUAL || type == SLJIT_SIG_LESS || type == SLJIT_SIG_GREATER_EQUAL) { RESOLVE_IMM1(); - if ((src2 & SLJIT_IMM) && src2w <= SIMM_MAX && src2w >= SIMM_MIN) + if (src2 == SLJIT_IMM && src2w <= SIMM_MAX && src2w >= SIMM_MIN) PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src1) | T(TMP_REG1) | IMM(src2w), DR(TMP_REG1))); else { RESOLVE_IMM2(); @@ -3107,7 +3502,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler } else { RESOLVE_IMM2(); - if ((src1 & SLJIT_IMM) && src1w <= SIMM_MAX && src1w >= SIMM_MIN) + if (src1 == SLJIT_IMM && src1w <= SIMM_MAX && src1w >= SIMM_MIN) PTR_FAIL_IF(push_inst(compiler, (type <= SLJIT_LESS_EQUAL ? SLTIU : SLTI) | S(src2) | T(TMP_REG1) | IMM(src1w), DR(TMP_REG1))); else { RESOLVE_IMM1(); @@ -3142,9 +3537,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler #undef BR_T #undef BR_F -#undef FLOAT_DATA -#undef FMT - SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump = NULL; @@ -3152,7 +3544,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); FAIL_IF(!jump); set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0)); @@ -3184,8 +3576,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi #endif } - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); - return SLJIT_SUCCESS; + return push_inst(compiler, NOP, UNMOVABLE_INS); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, @@ -3287,50 +3678,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, TMP_REG2, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, - sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) + +static sljit_ins get_select_cc(sljit_s32 type, sljit_s32 is_float) { -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) - sljit_ins ins; -#endif /* SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6 */ - - CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); - -#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) - - if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { -#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) - if (type & SLJIT_32) - srcw = (sljit_s32)srcw; -#endif - FAIL_IF(load_immediate(compiler, DR(TMP_REG1), srcw)); - src = TMP_REG1; - srcw = 0; - } - switch (type & ~SLJIT_32) { case SLJIT_EQUAL: - ins = MOVZ | TA(EQUAL_FLAG); - break; + return (is_float ? MOVZ_S : MOVZ) | TA(EQUAL_FLAG); case SLJIT_NOT_EQUAL: - ins = MOVN | TA(EQUAL_FLAG); - break; + return (is_float ? MOVN_S : MOVN) | TA(EQUAL_FLAG); case SLJIT_LESS: case SLJIT_GREATER: case SLJIT_SIG_LESS: case SLJIT_SIG_GREATER: case SLJIT_OVERFLOW: - ins = MOVN | TA(OTHER_FLAG); - break; + case SLJIT_CARRY: + return (is_float ? MOVN_S : MOVN) | TA(OTHER_FLAG); case SLJIT_GREATER_EQUAL: case SLJIT_LESS_EQUAL: case SLJIT_SIG_GREATER_EQUAL: case SLJIT_SIG_LESS_EQUAL: case SLJIT_NOT_OVERFLOW: - ins = MOVZ | TA(OTHER_FLAG); - break; + case SLJIT_NOT_CARRY: + return (is_float ? MOVZ_S : MOVZ) | TA(OTHER_FLAG); case SLJIT_F_EQUAL: case SLJIT_F_LESS: case SLJIT_F_LESS_EQUAL: @@ -3341,8 +3711,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil case SLJIT_UNORDERED_OR_LESS_EQUAL: case SLJIT_ORDERED_LESS_EQUAL: case SLJIT_UNORDERED: - ins = MOVT; - break; + return is_float ? MOVT_S : MOVT; case SLJIT_F_NOT_EQUAL: case SLJIT_F_GREATER_EQUAL: case SLJIT_F_GREATER: @@ -3353,21 +3722,159 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil case SLJIT_ORDERED_GREATER: case SLJIT_UNORDERED_OR_GREATER: case SLJIT_ORDERED: - ins = MOVF; - break; + return is_float ? MOVF_S : MOVF; default: - ins = MOVZ | TA(OTHER_FLAG); SLJIT_UNREACHABLE(); - break; + return (is_float ? MOVZ_S : MOVZ) | TA(OTHER_FLAG); + } +} + +#endif /* SLJIT_MIPS_REV >= 1 */ + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_reg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) +{ +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + sljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA; + sljit_ins mov_ins = (type & SLJIT_32) ? ADDU : DADDU; +#else /* !SLJIT_CONFIG_MIPS_64 */ + sljit_s32 inp_flags = WORD_DATA | LOAD_DATA; + sljit_ins mov_ins = ADDU; +#endif /* SLJIT_CONFIG_MIPS_64 */ + +#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) + struct sljit_label *label; + struct sljit_jump *jump; +#endif /* !(SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) */ + + CHECK_ERROR(); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); + ADJUST_LOCAL_OFFSET(src1, src1w); + +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG2), src1, src1w)); + src1 = TMP_REG2; + } else if (src1 == SLJIT_IMM) { +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (type & SLJIT_32) + src1w = (sljit_s32)src1w; +#endif + FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w)); + src1 = TMP_REG1; } - return push_inst(compiler, ins | S(src) | D(dst_reg), DR(dst_reg)); + if (dst_reg != src2_reg) { + if (dst_reg == src1) { + src1 = src2_reg; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, mov_ins | S(src2_reg) | TA(0) | D(dst_reg), DR(dst_reg))); + } + + return push_inst(compiler, get_select_cc(type, 0) | S(src1) | D(dst_reg), DR(dst_reg)); #else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */ - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw); + if (dst_reg != src2_reg) { + if (dst_reg == src1) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) { + FAIL_IF(push_inst(compiler, ADDU_W | S(dst_reg) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); + + if ((src1 & REG_MASK) == dst_reg) + src1 = (src1 & ~REG_MASK) | TMP_REG2; + + if (OFFS_REG(src1) == dst_reg) + src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG2); + } + + FAIL_IF(push_inst(compiler, mov_ins | S(src2_reg) | TA(0) | D(dst_reg), DR(dst_reg))); + } + } + + SLJIT_SKIP_CHECKS(compiler); + jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1); + FAIL_IF(!jump); + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, DR(dst_reg), src1, src1w)); + } else if (src1 == SLJIT_IMM) { +#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) + if (type & SLJIT_32) + src1w = (sljit_s32)src1w; +#endif /* SLJIT_CONFIG_MIPS_64 */ + FAIL_IF(load_immediate(compiler, DR(dst_reg), src1w)); + } else + FAIL_IF(push_inst(compiler, mov_ins | S(src1) | TA(0) | D(dst_reg), DR(dst_reg))); + + SLJIT_SKIP_CHECKS(compiler); + label = sljit_emit_label(compiler); + FAIL_IF(!label); + + sljit_set_label(jump, label); + return SLJIT_SUCCESS; #endif /* SLJIT_MIPS_REV >= 1 */ } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ +#if !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) + struct sljit_label *label; + struct sljit_jump *jump; +#endif /* !(SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) */ + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, MOV_fmt(FMT(type)) | FS(src2_freg) | FD(dst_freg), MOVABLE_INS)); + } + +#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6) + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, FR(TMP_FREG1), src1, src1w)); + src1 = TMP_FREG1; + } + + return push_inst(compiler, get_select_cc(type, 1) | FMT(type) | FS(src1) | FD(dst_freg), MOVABLE_INS); + +#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */ + SLJIT_SKIP_CHECKS(compiler); + jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1); + FAIL_IF(!jump); + + if (src1 & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, FR(dst_freg), src1, src1w)); + else + FAIL_IF(push_inst(compiler, MOV_fmt(FMT(type)) | FS(src1) | FD(dst_freg), MOVABLE_INS)); + + SLJIT_SKIP_CHECKS(compiler); + label = sljit_emit_label(compiler); + FAIL_IF(!label); + + sljit_set_label(jump, label); + return SLJIT_SUCCESS; +#endif /* SLJIT_MIPS_REV >= 1 */ +} + +#undef FLOAT_DATA +#undef FMT + static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem, sljit_sw *memw, sljit_s16 max_offset) { sljit_s32 arg = *mem; @@ -3410,21 +3917,33 @@ static sljit_s32 update_mem_addr(struct sljit_compiler *compiler, sljit_s32 *mem } #if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) -#define MEM16_IMM_FIRST(memw) IMM((memw) + 1) -#define MEM16_IMM_SECOND(memw) IMM(memw) -#define MEMF64_FS_FIRST(freg) FS(freg) -#define MEMF64_FS_SECOND(freg) (FS(freg) | ((sljit_ins)1 << 11)) +#define IMM_LEFT(memw) IMM((memw) + SSIZE_OF(sw) - 1) +#define IMM_RIGHT(memw) IMM(memw) +#define IMM_32_LEFT(memw) IMM((memw) + SSIZE_OF(s32) - 1) +#define IMM_32_RIGHT(memw) IMM(memw) +#define IMM_F64_FIRST_LEFT(memw) IMM((memw) + SSIZE_OF(s32) - 1) +#define IMM_F64_FIRST_RIGHT(memw) IMM(memw) +#define IMM_F64_SECOND_LEFT(memw) IMM((memw) + SSIZE_OF(f64) - 1) +#define IMM_F64_SECOND_RIGHT(memw) IMM((memw) + SSIZE_OF(s32)) +#define IMM_16_FIRST(memw) IMM((memw) + 1) +#define IMM_16_SECOND(memw) IMM(memw) #else /* !SLJIT_LITTLE_ENDIAN */ -#define MEM16_IMM_FIRST(memw) IMM(memw) -#define MEM16_IMM_SECOND(memw) IMM((memw) + 1) -#define MEMF64_FS_FIRST(freg) (FS(freg) | ((sljit_ins)1 << 11)) -#define MEMF64_FS_SECOND(freg) FS(freg) +#define IMM_LEFT(memw) IMM(memw) +#define IMM_RIGHT(memw) IMM((memw) + SSIZE_OF(sw) - 1) +#define IMM_32_LEFT(memw) IMM(memw) +#define IMM_32_RIGHT(memw) IMM((memw) + SSIZE_OF(s32) - 1) +#define IMM_F64_FIRST_LEFT(memw) IMM((memw) + SSIZE_OF(s32)) +#define IMM_F64_FIRST_RIGHT(memw) IMM((memw) + SSIZE_OF(f64) - 1) +#define IMM_F64_SECOND_LEFT(memw) IMM(memw) +#define IMM_F64_SECOND_RIGHT(memw) IMM((memw) + SSIZE_OF(s32) - 1) +#define IMM_16_FIRST(memw) IMM(memw) +#define IMM_16_SECOND(memw) IMM((memw) + 1) #endif /* SLJIT_LITTLE_ENDIAN */ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16)) +#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16)) #else /* !SLJIT_CONFIG_MIPS_32 */ -#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_UNALIGNED_16 | SLJIT_MEM_UNALIGNED_32)) +#define MEM_CHECK_UNALIGNED(type) ((type) & (SLJIT_MEM_UNALIGNED | SLJIT_MEM_ALIGNED_16 | SLJIT_MEM_ALIGNED_32)) #endif /* SLJIT_CONFIG_MIPS_32 */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, @@ -3461,10 +3980,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile ins_right = ((type & SLJIT_MEM_STORE) ? SDR : LDR) | S(mem); #endif /* SLJIT_CONFIG_MIPS_32 */ - FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM(memw), DR(REG_PAIR_FIRST(reg)))); - FAIL_IF(push_inst(compiler, ins_right | T(REG_PAIR_FIRST(reg)) | IMM(memw + (SSIZE_OF(sw) - 1)), DR(REG_PAIR_FIRST(reg)))); - FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)))); - return push_inst(compiler, ins_right | T(REG_PAIR_SECOND(reg)) | IMM((memw + 2 * SSIZE_OF(sw) - 1)), DR(REG_PAIR_SECOND(reg))); + FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_FIRST(reg)) | IMM_LEFT(memw), DR(REG_PAIR_FIRST(reg)))); + FAIL_IF(push_inst(compiler, ins_right | T(REG_PAIR_FIRST(reg)) | IMM_RIGHT(memw), DR(REG_PAIR_FIRST(reg)))); + FAIL_IF(push_inst(compiler, ins | T(REG_PAIR_SECOND(reg)) | IMM_LEFT(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg)))); + return push_inst(compiler, ins_right | T(REG_PAIR_SECOND(reg)) | IMM_RIGHT(memw + SSIZE_OF(sw)), DR(REG_PAIR_SECOND(reg))); } #endif /* !(SLJIT_MIPS_REV >= 6) */ @@ -3505,8 +4024,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile if (type & SLJIT_MEM_STORE) { FAIL_IF(push_inst(compiler, SRA_W | T(reg) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(TMP_REG2) | MEM16_IMM_FIRST(memw), MOVABLE_INS)); - return push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(reg) | MEM16_IMM_SECOND(memw), MOVABLE_INS); + FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(TMP_REG2) | IMM_16_FIRST(memw), MOVABLE_INS)); + return push_inst(compiler, data_transfer_insts[BYTE_DATA] | S(mem) | T(reg) | IMM_16_SECOND(memw), MOVABLE_INS); } flags = BYTE_DATA | LOAD_DATA; @@ -3514,15 +4033,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile if (op == SLJIT_MOV_S16) flags |= SIGNED_DATA; - FAIL_IF(push_inst(compiler, data_transfer_insts[flags] | S(mem) | T(TMP_REG2) | MEM16_IMM_FIRST(memw), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA | LOAD_DATA] | S(mem) | T(reg) | MEM16_IMM_SECOND(memw), DR(reg))); + FAIL_IF(push_inst(compiler, data_transfer_insts[flags] | S(mem) | T(TMP_REG2) | IMM_16_FIRST(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, data_transfer_insts[BYTE_DATA | LOAD_DATA] | S(mem) | T(reg) | IMM_16_SECOND(memw), DR(reg))); FAIL_IF(push_inst(compiler, SLL_W | T(TMP_REG2) | D(TMP_REG2) | SH_IMM(8), DR(TMP_REG2))); return push_inst(compiler, OR | S(reg) | T(TMP_REG2) | D(reg), DR(reg)); case SLJIT_MOV: case SLJIT_MOV_P: #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - if (type & SLJIT_MEM_UNALIGNED_32) { + if (type & SLJIT_MEM_ALIGNED_32) { flags = WORD_DATA; if (!(type & SLJIT_MEM_STORE)) flags |= LOAD_DATA; @@ -3534,8 +4053,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2); if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst(compiler, SDL | S(mem) | T(reg) | IMM(memw), MOVABLE_INS)); - return push_inst(compiler, SDR | S(mem) | T(reg) | IMM(memw + 7), MOVABLE_INS); + FAIL_IF(push_inst(compiler, SDL | S(mem) | T(reg) | IMM_LEFT(memw), MOVABLE_INS)); + return push_inst(compiler, SDR | S(mem) | T(reg) | IMM_RIGHT(memw), MOVABLE_INS); } if (mem == reg) { @@ -3543,8 +4062,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile mem = TMP_REG1; } - FAIL_IF(push_inst(compiler, LDL | S(mem) | T(reg) | IMM(memw), DR(reg))); - return push_inst(compiler, LDR | S(mem) | T(reg) | IMM(memw + 7), DR(reg)); + FAIL_IF(push_inst(compiler, LDL | S(mem) | T(reg) | IMM_LEFT(memw), DR(reg))); + return push_inst(compiler, LDR | S(mem) | T(reg) | IMM_RIGHT(memw), DR(reg)); #endif /* SLJIT_CONFIG_MIPS_32 */ } @@ -3552,8 +4071,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile SLJIT_ASSERT(FAST_IS_REG(mem) && mem != TMP_REG2); if (type & SLJIT_MEM_STORE) { - FAIL_IF(push_inst(compiler, SWL | S(mem) | T(reg) | IMM(memw), MOVABLE_INS)); - return push_inst(compiler, SWR | S(mem) | T(reg) | IMM(memw + 3), MOVABLE_INS); + FAIL_IF(push_inst(compiler, SWL | S(mem) | T(reg) | IMM_32_LEFT(memw), MOVABLE_INS)); + return push_inst(compiler, SWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), MOVABLE_INS); } if (mem == reg) { @@ -3561,18 +4080,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile mem = TMP_REG1; } - FAIL_IF(push_inst(compiler, LWL | S(mem) | T(reg) | IMM(memw), DR(reg))); + FAIL_IF(push_inst(compiler, LWL | S(mem) | T(reg) | IMM_32_LEFT(memw), DR(reg))); #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - return push_inst(compiler, LWR | S(mem) | T(reg) | IMM(memw + 3), DR(reg)); + return push_inst(compiler, LWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), DR(reg)); #else /* !SLJIT_CONFIG_MIPS_32 */ - FAIL_IF(push_inst(compiler, LWR | S(mem) | T(reg) | IMM(memw + 3), DR(reg))); + FAIL_IF(push_inst(compiler, LWR | S(mem) | T(reg) | IMM_32_RIGHT(memw), DR(reg))); if (op != SLJIT_MOV_U32) return SLJIT_SUCCESS; #if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 2) - return push_inst(compiler, DINSU | T(reg) | SA(0) | (31 << 11) | (0 << 11), DR(reg)); -#else /* SLJIT_MIPS_REV < 1 */ + return push_inst(compiler, DINSU | T(reg) | SA(0) | (31 << 11), DR(reg)); +#else /* SLJIT_MIPS_REV < 2 */ FAIL_IF(push_inst(compiler, DSLL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg))); return push_inst(compiler, DSRL32 | T(reg) | D(reg) | SH_IMM(0), DR(reg)); #endif /* SLJIT_MIPS_REV >= 2 */ @@ -3595,77 +4114,97 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil if (type & SLJIT_MEM_STORE) { if (type & SLJIT_32) { FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2))); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) +#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif - FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS)); - return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), MOVABLE_INS); +#endif /* MIPS III */ + FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_32_LEFT(memw), MOVABLE_INS)); + return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_32_RIGHT(memw), MOVABLE_INS); } #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | MEMF64_FS_FIRST(freg), DR(TMP_REG2))); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) + FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2))); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ + FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_LEFT(memw), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_RIGHT(memw), MOVABLE_INS)); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + FAIL_IF(push_inst(compiler, MFHC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2))); + break; +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | FS(freg) | (1 << 11), DR(TMP_REG2))); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); #endif - FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), MOVABLE_INS)); + break; + } - FAIL_IF(push_inst(compiler, MFC1 | T(TMP_REG2) | MEMF64_FS_SECOND(freg), DR(TMP_REG2))); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif - FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM(memw + 4), MOVABLE_INS)); - return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM(memw + 7), MOVABLE_INS); + FAIL_IF(push_inst(compiler, SWL | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_LEFT(memw), MOVABLE_INS)); + return push_inst(compiler, SWR | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_RIGHT(memw), MOVABLE_INS); #else /* !SLJIT_CONFIG_MIPS_32 */ - FAIL_IF(push_inst(compiler, MFC1 | (1 << 21) | T(TMP_REG2) | FS(freg), DR(TMP_REG2))); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) + FAIL_IF(push_inst(compiler, DMFC1 | T(TMP_REG2) | FS(freg), DR(TMP_REG2))); +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif - FAIL_IF(push_inst(compiler, SDL | S(mem) | T(TMP_REG2) | IMM(memw), MOVABLE_INS)); - return push_inst(compiler, SDR | S(mem) | T(TMP_REG2) | IMM(memw + 7), MOVABLE_INS); +#endif /* MIPS III */ + FAIL_IF(push_inst(compiler, SDL | S(mem) | T(TMP_REG2) | IMM_LEFT(memw), MOVABLE_INS)); + return push_inst(compiler, SDR | S(mem) | T(TMP_REG2) | IMM_RIGHT(memw), MOVABLE_INS); #endif /* SLJIT_CONFIG_MIPS_32 */ } if (type & SLJIT_32) { - FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_32_LEFT(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_32_RIGHT(memw), DR(TMP_REG2))); FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) +#if !defined(SLJIT_MIPS_REV) || (SLJIT_CONFIG_MIPS_32 && SLJIT_MIPS_REV <= 1) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif +#endif /* MIPS III */ return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 3), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | MEMF64_FS_FIRST(freg), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_LEFT(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_F64_FIRST_RIGHT(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM(memw + 4), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM(memw + 7), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | MEMF64_FS_SECOND(freg), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif + FAIL_IF(push_inst(compiler, LWL | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_LEFT(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LWR | S(mem) | T(TMP_REG2) | IMM_F64_SECOND_RIGHT(memw), DR(TMP_REG2))); + switch (cpu_feature_list & CPU_FEATURE_FR) { +#if defined(SLJIT_MIPS_REV) && SLJIT_MIPS_REV >= 2 + case CPU_FEATURE_FR: + return push_inst(compiler, MTHC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS); +#endif /* SLJIT_MIPS_REV >= 2 */ + default: + FAIL_IF(push_inst(compiler, MTC1 | T(TMP_REG2) | FS(freg) | (1 << 11), MOVABLE_INS)); + break; + } #else /* !SLJIT_CONFIG_MIPS_32 */ - FAIL_IF(push_inst(compiler, LDL | S(mem) | T(TMP_REG2) | IMM(memw), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, LDR | S(mem) | T(TMP_REG2) | IMM(memw + 7), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LDL | S(mem) | T(TMP_REG2) | IMM_LEFT(memw), DR(TMP_REG2))); + FAIL_IF(push_inst(compiler, LDR | S(mem) | T(TMP_REG2) | IMM_RIGHT(memw), DR(TMP_REG2))); - FAIL_IF(push_inst(compiler, MTC1 | (1 << 21) | T(TMP_REG2) | FS(freg), MOVABLE_INS)); -#if (!defined SLJIT_MIPS_REV || SLJIT_MIPS_REV <= 3) - FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif + FAIL_IF(push_inst(compiler, DMTC1 | T(TMP_REG2) | FS(freg), MOVABLE_INS)); #endif /* SLJIT_CONFIG_MIPS_32 */ +#if !defined(SLJIT_MIPS_REV) || SLJIT_MIPS_REV <= 1 + FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); +#endif /* MIPS III */ return SLJIT_SUCCESS; } #endif /* !SLJIT_MIPS_REV || SLJIT_MIPS_REV < 6 */ -#undef MEM16_IMM_FIRST -#undef MEM16_IMM_SECOND -#undef MEMF64_FS_FIRST -#undef MEMF64_FS_SECOND +#undef IMM_16_SECOND +#undef IMM_16_FIRST +#undef IMM_F64_SECOND_RIGHT +#undef IMM_F64_SECOND_LEFT +#undef IMM_F64_FIRST_RIGHT +#undef IMM_F64_FIRST_LEFT +#undef IMM_32_RIGHT +#undef IMM_32_LEFT +#undef IMM_RIGHT +#undef IMM_LEFT #undef MEM_CHECK_UNALIGNED #undef TO_ARGW_HI diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_32.c index 9449e4b9d76..2352fad5d47 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_32.c @@ -85,10 +85,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } return SLJIT_SUCCESS; - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1); - return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); - case SLJIT_CLZ: SLJIT_ASSERT(src1 == TMP_REG1); return push_inst(compiler, CNTLZW | S(src2) | A(dst)); @@ -246,6 +242,10 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(imm))); return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(imm >> 16)); } + if (flags & ALT_FORM4) { + SLJIT_ASSERT(src1 == TMP_REG1); + return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); + } return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_SHL: @@ -325,6 +325,151 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + sljit_s32 invert_sign = 1; + + if (src == SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ (sljit_sw)0x80000000)); + src = TMP_REG1; + invert_sign = 0; + } else if (!FAST_IS_REG(src)) { + FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); + src = TMP_REG1; + } + + /* First, a special double precision floating point value is constructed: + (2^53 + (src xor (2^31))) + The upper 32 bits of this number is a constant, and the lower 32 bits + is simply the value of the source argument. The xor 2^31 operation adds + 0x80000000 to the source argument, which moves it into the 0 - 0xffffffff + range. Finally we substract 2^53 + 2^31 to get the converted value. */ + FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330)); + if (invert_sign) + FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000)); + FAIL_IF(push_inst(compiler, STW | S(TMP_REG2) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI)); + FAIL_IF(push_inst(compiler, STW | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, STW | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG2) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + + FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2))); + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r))); + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src == SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } else if (!FAST_IS_REG(src)) { + FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); + src = TMP_REG1; + } + + /* First, a special double precision floating point value is constructed: + (2^53 + src) + The upper 32 bits of this number is a constant, and the lower 32 bits + is simply the value of the source argument. Finally we substract 2^53 + to get the converted value. */ + FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330)); + FAIL_IF(push_inst(compiler, STW | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + FAIL_IF(push_inst(compiler, STW | S(TMP_REG2) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI)); + + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, STW | S(TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG2) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + + FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2))); + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r))); + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_s32 imm[2]; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm[0] != 0) + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0])); + if (u.imm[1] != 0) + FAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1])); + + /* Saved in the same endianness. */ + FAIL_IF(push_inst(compiler, STW | S(u.imm[0] != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, STW | S(u.imm[1] != 0 ? TMP_REG2 : TMP_ZERO) | A(SLJIT_SP) | (TMP_MEM_OFFSET + sizeof(sljit_s32)))); + return push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_s32 reg2 = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (op & SLJIT_32) { + if (op == SLJIT_COPY32_TO_F32) { + FAIL_IF(push_inst(compiler, STW | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, LFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); + } + + FAIL_IF(push_inst(compiler, STFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, LWZ | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET); + } + + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + } + + if (op == SLJIT_COPY_TO_F64) { + FAIL_IF(push_inst(compiler, STW | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI)); + + if (reg2 != 0) + FAIL_IF(push_inst(compiler, STW | S(reg2) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + else + FAIL_IF(push_inst(compiler, STFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + + return push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); + } + + FAIL_IF(push_inst(compiler, STFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + + if (reg2 != 0) + FAIL_IF(push_inst(compiler, LWZ | S(reg2) | A(SLJIT_SP) | TMP_MEM_OFFSET_LO)); + + return push_inst(compiler, LWZ | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET_HI); +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins *)addr; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_64.c index 80549108bfb..b3cf9d074d5 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_64.c @@ -49,7 +49,7 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); - if (!(imm & ~0xffff)) + if (((sljit_uw)imm >> 16) == 0) return push_inst(compiler, ORI | S(TMP_ZERO) | A(reg) | IMM(imm)); if (imm <= 0x7fffffffl && imm >= -0x80000000l) { @@ -57,6 +57,11 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; } + if (((sljit_uw)imm >> 32) == 0) { + FAIL_IF(push_inst(compiler, ORIS | S(TMP_ZERO) | A(reg) | IMM(imm >> 16))); + return (imm & 0xffff) ? push_inst(compiler, ORI | S(reg) | A(reg) | IMM(imm)) : SLJIT_SUCCESS; + } + /* Count leading zeroes. */ tmp = (sljit_uw)((imm >= 0) ? imm : ~imm); ASM_SLJIT_CLZ(tmp, shift); @@ -198,11 +203,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } return SLJIT_SUCCESS; - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1); - UN_EXTS(); - return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); - case SLJIT_CLZ: SLJIT_ASSERT(src1 == TMP_REG1); return push_inst(compiler, ((flags & ALT_FORM1) ? CNTLZW : CNTLZD) | S(src2) | A(dst)); @@ -399,6 +399,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl FAIL_IF(push_inst(compiler, XORI | S(src1) | A(dst) | IMM(imm))); return push_inst(compiler, XORIS | S(dst) | A(dst) | IMM(imm >> 16)); } + if (flags & ALT_FORM4) { + SLJIT_ASSERT(src1 == TMP_REG1); + UN_EXTS(); + return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); + } return push_inst(compiler, XOR | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_SHL: @@ -563,6 +568,141 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_ return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (src == SLJIT_IMM) { + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; + + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) { + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1))); + else + FAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); + src = TMP_REG1; + } + + if (FAST_IS_REG(src)) { + FAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + } else + FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1)); + + FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r))); + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; + + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) { + if (src == SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_u32)srcw)); + src = TMP_REG1; + } else { + if (FAST_IS_REG(src)) + FAIL_IF(push_inst(compiler, CLRLDI(TMP_REG1, src, 32))); + else + FAIL_IF(emit_op_mem(compiler, INT_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); + src = TMP_REG1; + } + + FAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); + } else { + if (src == SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + src = TMP_REG1; + } else if (src & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); + src = TMP_REG1; + } + + FAIL_IF(push_inst(compiler, CMPI | CRD(0 | 1) | A(src) | 0)); + FAIL_IF(push_inst(compiler, BCx | (12 << 21) | (0 << 16) | 20)); + FAIL_IF(push_inst(compiler, STD | S(src) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); + FAIL_IF(push_inst(compiler, Bx | ((op & SLJIT_32) ? 36 : 32))); + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, RLWINM | S(src) | A(TMP_REG2) | RLWI_SH(10) | RLWI_MBE(10, 21))); + else + FAIL_IF(push_inst(compiler, ANDI | S(src) | A(TMP_REG2) | 0x1)); + + /* Shift right. */ + FAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(63) | RLDI_MB(1))); + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, RLDICR | S(TMP_REG1) | A(TMP_REG1) | RLDI_SH(0) | RLDI_ME(53))); + + FAIL_IF(push_inst(compiler, OR | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2))); + + FAIL_IF(push_inst(compiler, STD | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, LFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); + FAIL_IF(push_inst(compiler, FADD | FD(dst_r) | FA(dst_r) | FB(dst_r))); + } + + if (op & SLJIT_32) + FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r))); + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_sw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm != 0) + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm)); + + FAIL_IF(push_inst(compiler, STD | S(u.imm != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, LFD | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) { + FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? STW : STD) | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, ((op & SLJIT_32) ? LFS : LFD) | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); + } + + FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? STFS : STFD) | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, ((op & SLJIT_32) ? LWZ : LD) | S(reg) | A(SLJIT_SP) | TMP_MEM_OFFSET); +} + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset) { sljit_ins *inst = (sljit_ins*)addr; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_common.c b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_common.c index f387114733b..54977f02e3e 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativePPC_common.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativePPC_common.c @@ -132,7 +132,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { OE and Rc flag (see ALT_SET_FLAGS). */ #define OE(flags) ((flags) & ALT_SET_FLAGS) /* Rc flag (see ALT_SET_FLAGS). */ -#define RC(flags) (((flags) & ALT_SET_FLAGS) >> 10) +#define RC(flags) ((sljit_ins)((flags) & ALT_SET_FLAGS) >> 10) #define HI(opcode) ((sljit_ins)(opcode) << 26) #define LO(opcode) ((sljit_ins)(opcode) << 1) @@ -150,6 +150,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define BCx (HI(16)) #define BCCTR (HI(19) | LO(528) | (3 << 11)) #define BLR (HI(19) | LO(16) | (0x14 << 21)) +#if defined(_ARCH_PWR10) && _ARCH_PWR10 +#define BRD (HI(31) | LO(187)) +#endif /* POWER10 */ #define CNTLZD (HI(31) | LO(58)) #define CNTLZW (HI(31) | LO(26)) #define CMP (HI(31) | LO(0)) @@ -183,6 +186,12 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define FSUBS (HI(59) | LO(20)) #define LD (HI(58) | 0) #define LFD (HI(50)) +#define LFS (HI(48)) +#if defined(_ARCH_PWR7) && _ARCH_PWR7 +#define LDBRX (HI(31) | LO(532)) +#endif /* POWER7 */ +#define LHBRX (HI(31) | LO(790)) +#define LWBRX (HI(31) | LO(534)) #define LWZ (HI(32)) #define MFCR (HI(31) | LO(19)) #define MFLR (HI(31) | LO(339) | 0x80000) @@ -219,11 +228,17 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define SRD (HI(31) | LO(539)) #define SRW (HI(31) | LO(536)) #define STD (HI(62) | 0) +#if defined(_ARCH_PWR7) && _ARCH_PWR7 +#define STDBRX (HI(31) | LO(660)) +#endif /* POWER7 */ #define STDU (HI(62) | 1) #define STDUX (HI(31) | LO(181)) #define STFD (HI(54)) #define STFIWX (HI(31) | LO(983)) +#define STFS (HI(52)) +#define STHBRX (HI(31) | LO(918)) #define STW (HI(36)) +#define STWBRX (HI(31) | LO(662)) #define STWU (HI(37)) #define STWUX (HI(31) | LO(183)) #define SUBF (HI(31) | LO(40)) @@ -253,10 +268,24 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) #define SLWI_W(shift) SLWI(shift) +#define TMP_MEM_OFFSET (2 * sizeof(sljit_sw)) #else /* !SLJIT_CONFIG_PPC_32 */ #define SLWI_W(shift) SLDI(shift) +#define TMP_MEM_OFFSET (6 * sizeof(sljit_sw)) #endif /* SLJIT_CONFIG_PPC_32 */ +#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#define TMP_MEM_OFFSET_LO (TMP_MEM_OFFSET) +#define TMP_MEM_OFFSET_HI (TMP_MEM_OFFSET + sizeof(sljit_s32)) +#define LWBRX_FIRST_REG S(TMP_REG1) +#define LWBRX_SECOND_REG S(dst) +#else /* !SLJIT_LITTLE_ENDIAN */ +#define TMP_MEM_OFFSET_LO (TMP_MEM_OFFSET + sizeof(sljit_s32)) +#define TMP_MEM_OFFSET_HI (TMP_MEM_OFFSET) +#define LWBRX_FIRST_REG S(dst) +#define LWBRX_SECOND_REG S(TMP_REG1) +#endif /* SLJIT_LITTLE_ENDIAN */ + #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_uw addr, void* func) { @@ -423,6 +452,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil reverse_buf(compiler); #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) + /* add to compiler->size additional instruction space to hold the trampoline and padding */ #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); #else @@ -623,7 +653,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; - compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins); code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset); @@ -641,8 +670,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1); #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) + compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins) + sizeof(struct sljit_function_context); + return code_ptr; #else + compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins); + return code; #endif } @@ -652,12 +685,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) switch (feature_type) { case SLJIT_HAS_FPU: #ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; + return (SLJIT_IS_FPU_AVAILABLE) != 0; #else /* Available by default. */ return 1; #endif - + case SLJIT_HAS_REV: +#if defined(_ARCH_PWR10) && _ARCH_PWR10 + return 1; +#else /* !POWER10 */ + return 2; +#endif /* POWER10 */ /* A saved register is set to a zero value. */ case SLJIT_HAS_ZERO_REGISTER: case SLJIT_HAS_CLZ: @@ -675,7 +713,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - return (type >= SLJIT_UNORDERED && type <= SLJIT_ORDERED_LESS_EQUAL); + switch (type) { + case SLJIT_UNORDERED_OR_EQUAL: + case SLJIT_ORDERED_NOT_EQUAL: + case SLJIT_UNORDERED_OR_LESS: + case SLJIT_ORDERED_GREATER_EQUAL: + case SLJIT_UNORDERED_OR_GREATER: + case SLJIT_ORDERED_LESS_EQUAL: + return 1; + } + + return 0; } /* --------------------------------------------------------------------- */ @@ -699,6 +747,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) #define MEM_MASK 0x7f +#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 6)) + /* Other inp_flags. */ /* Integer opertion and set flags -> requires exts on 64 bit systems. */ @@ -722,6 +772,9 @@ ALT_FORM1 0x001000 ... ALT_FORM5 0x010000 */ +static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, + sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg); + #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) #include "sljitNativePPC_32.c" #else @@ -737,16 +790,13 @@ ALT_FORM5 0x010000 */ #endif #if (defined SLJIT_PPC_STACK_FRAME_V2 && SLJIT_PPC_STACK_FRAME_V2) -#define LR_SAVE_OFFSET 2 * SSIZE_OF(sw) +#define LR_SAVE_OFFSET (2 * SSIZE_OF(sw)) #else #define LR_SAVE_OFFSET SSIZE_OF(sw) #endif #define STACK_MAX_DISTANCE (0x8000 - SSIZE_OF(sw) - LR_SAVE_OFFSET) -static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg, - sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg); - SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) @@ -763,7 +813,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - saved_arg_count, 0) - + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); if (!(options & SLJIT_ENTER_REG_ARG)) local_size += SSIZE_OF(sw); @@ -873,7 +923,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size); local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds - SLJIT_KEPT_SAVEDS_COUNT(options), 0) - + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + + GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); if (!(options & SLJIT_ENTER_REG_ARG)) local_size += SSIZE_OF(sw); @@ -1222,7 +1272,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 src1_r = src1; flags |= REG1_SOURCE; } - else if (src1 & SLJIT_IMM) { + else if (src1 == SLJIT_IMM) { src1_r = TMP_ZERO; if (src1w != 0) { FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); @@ -1242,7 +1292,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P) dst_r = src2_r; } - else if (src2 & SLJIT_IMM) { + else if (src2 == SLJIT_IMM) { src2_r = TMP_ZERO; if (src2w != 0) { FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); @@ -1312,29 +1362,161 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return SLJIT_SUCCESS; } -static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, - sljit_s32 src, sljit_sw srcw) +static sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { - if (!(src & OFFS_REG_MASK)) { - if (srcw == 0 && (src & REG_MASK)) - return push_inst(compiler, DCBT | A(0) | B(src & REG_MASK)); + sljit_s32 mem, offs_reg, inp_flags; + sljit_sw memw; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_s32 is_32 = op & SLJIT_32; - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - /* Works with SLJIT_MEM0() case as well. */ - return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1)); + op = GET_OPCODE(op); +#endif /* SLJIT_CONFIG_PPC_64 */ + + if (!((dst | src) & SLJIT_MEM)) { + /* Both are registers. */ + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) { + if (src == dst) { + FAIL_IF(push_inst(compiler, RLWIMI | S(dst) | A(dst) | RLWI_SH(16) | RLWI_MBE(8, 15))); + FAIL_IF(push_inst(compiler, RLWINM | S(dst) | A(dst) | RLWI_SH(24) | RLWI_MBE(16, 31))); + } else { + FAIL_IF(push_inst(compiler, RLWINM | S(src) | A(dst) | RLWI_SH(8) | RLWI_MBE(16, 23))); + FAIL_IF(push_inst(compiler, RLWIMI | S(src) | A(dst) | RLWI_SH(24) | RLWI_MBE(24, 31))); + } + + if (op == SLJIT_REV_U16) + return SLJIT_SUCCESS; + return push_inst(compiler, EXTSH | S(dst) | A(dst)); + } + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (!is_32) { +#if defined(_ARCH_PWR10) && _ARCH_PWR10 + return push_inst(compiler, BRD | S(src) | A(dst)); +#else /* !POWER10 */ + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(0) | IMM(TMP_MEM_OFFSET_HI))); + FAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(32) | RLDI_MB(32))); + FAIL_IF(push_inst(compiler, STWBRX | S(src) | A(SLJIT_SP) | B(TMP_REG2))); + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(0) | IMM(TMP_MEM_OFFSET_LO))); + FAIL_IF(push_inst(compiler, STWBRX | S(TMP_REG1) | A(SLJIT_SP) | B(TMP_REG2))); + return push_inst(compiler, LD | D(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET); +#endif /* POWER10 */ + } +#endif /* SLJIT_CONFIG_PPC_64 */ + + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(0) | IMM(TMP_MEM_OFFSET))); + FAIL_IF(push_inst(compiler, STWBRX | S(src) | A(SLJIT_SP) | B(TMP_REG2))); + FAIL_IF(push_inst(compiler, LWZ | D(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op == SLJIT_REV_S32) + return push_inst(compiler, EXTSW | S(dst) | A(dst)); +#endif /* SLJIT_CONFIG_PPC_64 */ + return SLJIT_SUCCESS; } - srcw &= 0x3; + mem = src; + memw = srcw; - if (srcw == 0) - return push_inst(compiler, DCBT | A(src & REG_MASK) | B(OFFS_REG(src))); + if (dst & SLJIT_MEM) { + mem = dst; + memw = dstw; - FAIL_IF(push_inst(compiler, SLWI_W(srcw) | S(OFFS_REG(src)) | A(TMP_REG1))); - return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1)); + if (src & SLJIT_MEM) { + inp_flags = HALF_DATA | LOAD_DATA; + + if (op != SLJIT_REV_U16 && op != SLJIT_REV_S16) { +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + inp_flags = (is_32 ? INT_DATA : WORD_DATA) | LOAD_DATA; +#else /* !SLJIT_CONFIG_PPC_64 */ + inp_flags = WORD_DATA | LOAD_DATA; +#endif /* SLJIT_CONFIG_PPC_64 */ + } + + FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src, srcw, TMP_REG2)); + src = TMP_REG1; + } + } + + if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) { + offs_reg = OFFS_REG(mem); + mem &= REG_MASK; + memw &= 0x3; + + if (memw != 0) { + FAIL_IF(push_inst(compiler, SLWI_W(memw) | S(offs_reg) | A(TMP_REG2))); + offs_reg = TMP_REG2; + } +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + } else if (memw > 0x7fff7fffl || memw < -0x80000000l) { + FAIL_IF(load_immediate(compiler, TMP_REG2, memw)); + offs_reg = TMP_REG2; + mem &= REG_MASK; +#endif /* SLJIT_CONFIG_PPC_64 */ + } else { + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(mem & REG_MASK) | IMM(memw))); + if (memw > SIMM_MAX || memw < SIMM_MIN) + FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(TMP_REG2) | IMM((memw + 0x8000) >> 16))); + + mem = 0; + offs_reg = TMP_REG2; + } + + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) { + if (dst & SLJIT_MEM) + return push_inst(compiler, STHBRX | S(src) | A(mem) | B(offs_reg)); + + FAIL_IF(push_inst(compiler, LHBRX | S(dst) | A(mem) | B(offs_reg))); + + if (op == SLJIT_REV_U16) + return SLJIT_SUCCESS; + return push_inst(compiler, EXTSH | S(dst) | A(dst)); + } + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (!is_32) { + if (dst & SLJIT_MEM) { +#if defined(_ARCH_PWR7) && _ARCH_PWR7 + return push_inst(compiler, STDBRX | S(src) | A(mem) | B(offs_reg)); +#else /* !POWER7 */ +#if defined(SLJIT_LITTLE_ENDIAN) && SLJIT_LITTLE_ENDIAN + FAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(32) | RLDI_MB(32))); + FAIL_IF(push_inst(compiler, STWBRX | S(TMP_REG1) | A(mem) | B(offs_reg))); + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(offs_reg) | IMM(SSIZE_OF(s32)))); + return push_inst(compiler, STWBRX | S(src) | A(mem) | B(TMP_REG2)); +#else /* !SLJIT_LITTLE_ENDIAN */ + FAIL_IF(push_inst(compiler, STWBRX | S(src) | A(mem) | B(offs_reg))); + FAIL_IF(push_inst(compiler, RLDICL | S(src) | A(TMP_REG1) | RLDI_SH(32) | RLDI_MB(32))); + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(offs_reg) | IMM(SSIZE_OF(s32)))); + return push_inst(compiler, STWBRX | S(TMP_REG1) | A(mem) | B(TMP_REG2)); +#endif /* SLJIT_LITTLE_ENDIAN */ +#endif /* POWER7 */ + } +#if defined(_ARCH_PWR7) && _ARCH_PWR7 + return push_inst(compiler, LDBRX | S(dst) | A(mem) | B(offs_reg)); +#else /* !POWER7 */ + FAIL_IF(push_inst(compiler, LWBRX | LWBRX_FIRST_REG | A(mem) | B(offs_reg))); + FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(offs_reg) | IMM(SSIZE_OF(s32)))); + FAIL_IF(push_inst(compiler, LWBRX | LWBRX_SECOND_REG | A(mem) | B(TMP_REG2))); + return push_inst(compiler, RLDIMI | S(TMP_REG1) | A(dst) | RLDI_SH(32) | RLDI_MB(0)); +#endif /* POWER7 */ + } +#endif /* SLJIT_CONFIG_PPC_64 */ + + if (dst & SLJIT_MEM) + return push_inst(compiler, STWBRX | S(src) | A(mem) | B(offs_reg)); + + FAIL_IF(push_inst(compiler, LWBRX | S(dst) | A(mem) | B(offs_reg))); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op == SLJIT_REV_S32) + return push_inst(compiler, EXTSW | S(dst) | A(dst)); +#endif /* SLJIT_CONFIG_PPC_64 */ + return SLJIT_SUCCESS; } #define EMIT_MOV(type, type_flags, type_cast) \ - emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw) + emit_op(compiler, (src == SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? type_cast srcw : srcw) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, @@ -1353,19 +1535,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile if (GET_FLAG_TYPE(op_flags) == SLJIT_OVERFLOW) FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); - if (op < SLJIT_NOT && FAST_IS_REG(src) && src == dst) { + if (op <= SLJIT_MOV_P && FAST_IS_REG(src) && src == dst) { if (!TYPE_CAST_NEEDED(op)) return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op_flags & SLJIT_32) { - if (op < SLJIT_NOT) { + if (op <= SLJIT_MOV_P) { if (src & SLJIT_MEM) { if (op == SLJIT_MOV_S32) op = SLJIT_MOV_U32; } - else if (src & SLJIT_IMM) { + else if (src == SLJIT_IMM) { if (op == SLJIT_MOV_U32) op = SLJIT_MOV_S32; } @@ -1410,16 +1592,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile case SLJIT_MOV_S16: return EMIT_MOV(SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, (sljit_s16)); - case SLJIT_NOT: - return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw); - case SLJIT_CLZ: case SLJIT_CTZ: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - return emit_op(compiler, op, flags | (!(op_flags & SLJIT_32) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); -#else + if (op_flags & SLJIT_32) + flags |= ALT_FORM1; +#endif /* SLJIT_CONFIG_PPC_64 */ return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); -#endif + case SLJIT_REV_U32: + case SLJIT_REV_S32: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + op |= SLJIT_32; +#endif /* SLJIT_CONFIG_PPC_64 */ + /* fallthrough */ + case SLJIT_REV: + case SLJIT_REV_U16: + case SLJIT_REV_S16: +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + op |= (op_flags & SLJIT_32); +#endif /* SLJIT_CONFIG_PPC_64 */ + return emit_rev(compiler, op, dst, dstw, src, srcw); } return SLJIT_SUCCESS; @@ -1427,40 +1619,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile #undef EMIT_MOV +/* Macros for checking different operand types / values. */ #define TEST_SL_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN) - + ((src) == SLJIT_IMM && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN) #define TEST_UL_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & ~0xffff)) - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define TEST_SH_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l) -#else -#define TEST_SH_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & 0xffff)) -#endif - + ((src) == SLJIT_IMM && !((srcw) & ~0xffff)) #define TEST_UH_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & ~(sljit_sw)0xffff0000)) + ((src) == SLJIT_IMM && !((srcw) & ~(sljit_sw)0xffff0000)) #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define TEST_SH_IMM(src, srcw) \ + ((src) == SLJIT_IMM && !((srcw) & 0xffff) && (srcw) <= 0x7fffffffl && (srcw) >= -0x80000000l) #define TEST_ADD_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l) -#else -#define TEST_ADD_IMM(src, srcw) \ - ((src) & SLJIT_IMM) -#endif - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + ((src) == SLJIT_IMM && (srcw) <= 0x7fff7fffl && (srcw) >= -0x80000000l) #define TEST_UI_IMM(src, srcw) \ - (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff)) -#else -#define TEST_UI_IMM(src, srcw) \ - ((src) & SLJIT_IMM) -#endif + ((src) == SLJIT_IMM && !((srcw) & ~0xffffffff)) -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define TEST_ADD_FORM1(op) \ (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \ || (op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_32 | SLJIT_SET_Z | SLJIT_SET_CARRY)) @@ -1470,14 +1644,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile #define TEST_SUB_FORM3(op) \ (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW \ || (op & (SLJIT_32 | SLJIT_SET_Z)) == (SLJIT_32 | SLJIT_SET_Z)) -#else + +#else /* !SLJIT_CONFIG_PPC_64 */ +#define TEST_SH_IMM(src, srcw) \ + ((src) == SLJIT_IMM && !((srcw) & 0xffff)) +#define TEST_ADD_IMM(src, srcw) \ + ((src) == SLJIT_IMM) +#define TEST_UI_IMM(src, srcw) \ + ((src) == SLJIT_IMM) + #define TEST_ADD_FORM1(op) \ (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW) #define TEST_SUB_FORM2(op) \ (GET_FLAG_TYPE(op) >= SLJIT_SIG_LESS && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) #define TEST_SUB_FORM3(op) \ (GET_FLAG_TYPE(op) == SLJIT_OVERFLOW) -#endif +#endif /* SLJIT_CONFIG_PPC_64 */ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, @@ -1496,9 +1678,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile if (op & SLJIT_32) { /* Most operations expect sign extended arguments. */ flags |= INT_DATA | SIGNED_DATA; - if (src1 & SLJIT_IMM) + if (src1 == SLJIT_IMM) src1w = (sljit_s32)(src1w); - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) src2w = (sljit_s32)(src2w); if (HAS_FLAGS(op)) flags |= ALT_SIGN_EXT; @@ -1514,7 +1696,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile if (TEST_ADD_FORM1(op)) return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w); - if (!HAS_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { + if (!HAS_FLAGS(op) && (src1 == SLJIT_IMM || src2 == SLJIT_IMM)) { if (TEST_SL_IMM(src2, src2w)) { compiler->imm = (sljit_ins)src2w & 0xffff; return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); @@ -1565,7 +1747,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); } } - return emit_op(compiler, SLJIT_ADD, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, SLJIT_ADD, flags | ((GET_FLAG_TYPE(op) == SLJIT_CARRY) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); case SLJIT_ADDC: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD; @@ -1583,7 +1765,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src1, src1w, src2, src2w); } - if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= (SIMM_MAX + 1)) { + if (src2 == SLJIT_IMM && src2w >= 0 && src2w <= (SIMM_MAX + 1)) { compiler->imm = (sljit_ins)src2w; return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } @@ -1599,7 +1781,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile } if (TEST_SUB_FORM2(op)) { - if ((src2 & SLJIT_IMM) && src2w >= -SIMM_MAX && src2w <= SIMM_MAX) { + if (src2 == SLJIT_IMM && src2w >= -SIMM_MAX && src2w <= SIMM_MAX) { compiler->imm = (sljit_ins)src2w & 0xffff; return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3 | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); } @@ -1632,7 +1814,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile } /* We know ALT_SIGN_EXT is set if it is an SLJIT_32 on 64 bit systems. */ - return emit_op(compiler, SLJIT_SUB, flags | ((GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, SLJIT_SUB, flags | ((GET_FLAG_TYPE(op) == SLJIT_CARRY) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUBC: compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB; @@ -1657,9 +1839,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO))); return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w); + case SLJIT_XOR: + if (src2 == SLJIT_IMM && src2w == -1) { + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM4, dst, dstw, TMP_REG1, 0, src1, src1w); + } + if (src1 == SLJIT_IMM && src1w == -1) { + return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM4, dst, dstw, TMP_REG1, 0, src2, src2w); + } + /* fallthrough */ case SLJIT_AND: case SLJIT_OR: - case SLJIT_XOR: /* Commutative unsigned operations. */ if (!HAS_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) { if (TEST_UL_IMM(src2, src2w)) { @@ -1704,7 +1893,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile if (op & SLJIT_32) flags |= ALT_FORM2; #endif - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { compiler->imm = (sljit_ins)src2w; return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } @@ -1730,9 +1919,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil #undef TEST_SUB_FORM3 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_right; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) @@ -1744,85 +1934,97 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * #endif /* SLJIT_CONFIG_PPC_64 */ CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); is_right = (GET_OPCODE(op) == SLJIT_LSHR || GET_OPCODE(op) == SLJIT_MLSHR); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); - if (src2 & SLJIT_IMM) { - src2w &= bit_length - 1; + if (src3 == SLJIT_IMM) { + src3w &= bit_length - 1; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src2, src2w, TMP_REG2)); - src2 = TMP_REG2; - } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src1, src1w, TMP_REG1)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); - src1 = TMP_REG1; - } - - if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (!(op & SLJIT_32)) { if (is_right) { - FAIL_IF(push_inst(compiler, SRDI(src2w) | S(src_dst) | A(src_dst))); - return push_inst(compiler, RLDIMI | S(src1) | A(src_dst) | RLDI_SH(64 - src2w) | RLDI_MB(0)); + FAIL_IF(push_inst(compiler, SRDI(src3w) | S(src1_reg) | A(dst_reg))); + return push_inst(compiler, RLDIMI | S(src2_reg) | A(dst_reg) | RLDI_SH(64 - src3w) | RLDI_MB(0)); } - FAIL_IF(push_inst(compiler, SLDI(src2w) | S(src_dst) | A(src_dst))); + FAIL_IF(push_inst(compiler, SLDI(src3w) | S(src1_reg) | A(dst_reg))); /* Computes SRDI(64 - src2w). */ - FAIL_IF(push_inst(compiler, RLDICL | S(src1) | A(TMP_REG1) | RLDI_SH(src2w) | RLDI_MB(64 - src2w))); - return push_inst(compiler, OR | S(src_dst) | A(src_dst) | B(TMP_REG1)); + FAIL_IF(push_inst(compiler, RLDICL | S(src2_reg) | A(TMP_REG1) | RLDI_SH(src3w) | RLDI_MB(64 - src3w))); + return push_inst(compiler, OR | S(dst_reg) | A(dst_reg) | B(TMP_REG1)); } #endif /* SLJIT_CONFIG_PPC_64 */ if (is_right) { - FAIL_IF(push_inst(compiler, SRWI(src2w) | S(src_dst) | A(src_dst))); - return push_inst(compiler, RLWIMI | S(src1) | A(src_dst) | RLWI_SH(32 - src2w) | RLWI_MBE(0, src2w - 1)); + FAIL_IF(push_inst(compiler, SRWI(src3w) | S(src1_reg) | A(dst_reg))); + return push_inst(compiler, RLWIMI | S(src2_reg) | A(dst_reg) | RLWI_SH(32 - src3w) | RLWI_MBE(0, src3w - 1)); } - FAIL_IF(push_inst(compiler, SLWI(src2w) | S(src_dst) | A(src_dst))); - return push_inst(compiler, RLWIMI | S(src1) | A(src_dst) | RLWI_SH(src2w) | RLWI_MBE(32 - src2w, 31)); + FAIL_IF(push_inst(compiler, SLWI(src3w) | S(src1_reg) | A(dst_reg))); + return push_inst(compiler, RLWIMI | S(src2_reg) | A(dst_reg) | RLWI_SH(src3w) | RLWI_MBE(32 - src3w, 31)); + } + + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src3, src3w, TMP_REG2)); + src3 = TMP_REG2; } #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (!(op & SLJIT_32)) { - if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR) { - FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x3f)); - src2 = TMP_REG2; + if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR || dst_reg == src3) { + FAIL_IF(push_inst(compiler, ANDI | S(src3) | A(TMP_REG2) | 0x3f)); + src3 = TMP_REG2; } - FAIL_IF(push_inst(compiler, (is_right ? SRD : SLD) | S(src_dst) | A(src_dst) | B(src2))); - FAIL_IF(push_inst(compiler, (is_right ? SLDI(1) : SRDI(1)) | S(src1) | A(TMP_REG1))); - FAIL_IF(push_inst(compiler, XORI | S(src2) | A(TMP_REG2) | 0x3f)); + FAIL_IF(push_inst(compiler, (is_right ? SRD : SLD) | S(src1_reg) | A(dst_reg) | B(src3))); + FAIL_IF(push_inst(compiler, (is_right ? SLDI(1) : SRDI(1)) | S(src2_reg) | A(TMP_REG1))); + FAIL_IF(push_inst(compiler, XORI | S(src3) | A(TMP_REG2) | 0x3f)); FAIL_IF(push_inst(compiler, (is_right ? SLD : SRD) | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2))); - return push_inst(compiler, OR | S(src_dst) | A(src_dst) | B(TMP_REG1)); + return push_inst(compiler, OR | S(dst_reg) | A(dst_reg) | B(TMP_REG1)); } #endif /* SLJIT_CONFIG_PPC_64 */ - if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR) { - FAIL_IF(push_inst(compiler, ANDI | S(src2) | A(TMP_REG2) | 0x1f)); - src2 = TMP_REG2; + if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR || dst_reg == src3) { + FAIL_IF(push_inst(compiler, ANDI | S(src3) | A(TMP_REG2) | 0x1f)); + src3 = TMP_REG2; } - FAIL_IF(push_inst(compiler, (is_right ? SRW : SLW) | S(src_dst) | A(src_dst) | B(src2))); - FAIL_IF(push_inst(compiler, (is_right ? SLWI(1) : SRWI(1)) | S(src1) | A(TMP_REG1))); - FAIL_IF(push_inst(compiler, XORI | S(src2) | A(TMP_REG2) | 0x1f)); + FAIL_IF(push_inst(compiler, (is_right ? SRW : SLW) | S(src1_reg) | A(dst_reg) | B(src3))); + FAIL_IF(push_inst(compiler, (is_right ? SLWI(1) : SRWI(1)) | S(src2_reg) | A(TMP_REG1))); + FAIL_IF(push_inst(compiler, XORI | S(src3) | A(TMP_REG2) | 0x1f)); FAIL_IF(push_inst(compiler, (is_right ? SLW : SRW) | S(TMP_REG1) | A(TMP_REG1) | B(TMP_REG2))); - return push_inst(compiler, OR | S(src_dst) | A(src_dst) | B(TMP_REG1)); + return push_inst(compiler, OR | S(dst_reg) | A(dst_reg) | B(TMP_REG1)); +} + +static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, + sljit_s32 src, sljit_sw srcw) +{ + if (!(src & OFFS_REG_MASK)) { + if (srcw == 0 && (src & REG_MASK)) + return push_inst(compiler, DCBT | A(0) | B(src & REG_MASK)); + + FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); + /* Works with SLJIT_MEM0() case as well. */ + return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1)); + } + + srcw &= 0x3; + + if (srcw == 0) + return push_inst(compiler, DCBT | A(src & REG_MASK) | B(OFFS_REG(src))); + + FAIL_IF(push_inst(compiler, SLWI_W(srcw) | S(OFFS_REG(src)) | A(TMP_REG1))); + return push_inst(compiler, DCBT | A(src & REG_MASK) | B(TMP_REG1)); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, @@ -1854,21 +2056,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + if (FAST_IS_REG(dst)) + return push_inst(compiler, MFLR | D(dst)); + + FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG1))); + break; + case SLJIT_GET_RETURN_ADDRESS: + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + LR_SAVE_OFFSET, TMP_REG2)); + break; + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_DATA, TMP_REG1, dst, dstw, TMP_REG2); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type != SLJIT_FLOAT_REGISTER) + return -1; + return freg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_u32 size) { + SLJIT_UNUSED_ARG(size); + CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -1879,24 +2112,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c /* Floating point operators */ /* --------------------------------------------------------------------- */ -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_32) >> 6)) #define SELECT_FOP(op, single, double) ((sljit_ins)((op & SLJIT_32) ? single : double)) -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define FLOAT_TMP_MEM_OFFSET (6 * sizeof(sljit_sw)) -#else -#define FLOAT_TMP_MEM_OFFSET (2 * sizeof(sljit_sw)) - -#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) -#define FLOAT_TMP_MEM_OFFSET_LOW (2 * sizeof(sljit_sw)) -#define FLOAT_TMP_MEM_OFFSET_HI (3 * sizeof(sljit_sw)) -#else -#define FLOAT_TMP_MEM_OFFSET_LOW (3 * sizeof(sljit_sw)) -#define FLOAT_TMP_MEM_OFFSET_HI (2 * sizeof(sljit_sw)) -#endif - -#endif /* SLJIT_CONFIG_PPC_64 */ - static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) @@ -1913,19 +2130,19 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp if (op == SLJIT_CONV_SW_FROM_F64) { if (FAST_IS_REG(dst)) { - FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1)); - return emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1); + FAIL_IF(push_inst(compiler, STFD | FS(TMP_FREG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, LD | S(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET); } return emit_op_mem(compiler, DOUBLE_DATA, TMP_FREG1, dst, dstw, TMP_REG1); } -#else +#else /* !SLJIT_CONFIG_PPC_64 */ FAIL_IF(push_inst(compiler, FCTIWZ | FD(TMP_FREG1) | FB(src))); -#endif +#endif /* SLJIT_CONFIG_PPC_64 */ if (FAST_IS_REG(dst)) { - FAIL_IF(load_immediate(compiler, TMP_REG1, FLOAT_TMP_MEM_OFFSET)); + FAIL_IF(load_immediate(compiler, TMP_REG1, TMP_MEM_OFFSET)); FAIL_IF(push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(SLJIT_SP) | B(TMP_REG1))); - return emit_op_mem(compiler, INT_DATA | LOAD_DATA, dst, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1); + return push_inst(compiler, LWZ | S(dst) | A(SLJIT_SP) | TMP_MEM_OFFSET); } SLJIT_ASSERT(dst & SLJIT_MEM); @@ -1935,16 +2152,14 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp if (dstw) { FAIL_IF(push_inst(compiler, SLWI_W(dstw) | S(OFFS_REG(dst)) | A(TMP_REG1))); dstw = TMP_REG1; - } - else + } else dstw = OFFS_REG(dst); } else { if ((dst & REG_MASK) && !dstw) { dstw = dst & REG_MASK; dst = 0; - } - else { + } else { /* This works regardless we have SLJIT_MEM1 or SLJIT_MEM0. */ FAIL_IF(load_immediate(compiler, TMP_REG1, dstw)); dstw = TMP_REG1; @@ -1954,85 +2169,6 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp return push_inst(compiler, STFIWX | FS(TMP_FREG1) | A(dst & REG_MASK) | B(dstw)); } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src, sljit_sw srcw) -{ -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - - sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - - if (src & SLJIT_IMM) { - if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) - srcw = (sljit_s32)srcw; - - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - } - else if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) { - if (FAST_IS_REG(src)) - FAIL_IF(push_inst(compiler, EXTSW | S(src) | A(TMP_REG1))); - else - FAIL_IF(emit_op_mem(compiler, INT_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); - src = TMP_REG1; - } - - if (FAST_IS_REG(src)) { - FAIL_IF(emit_op_mem(compiler, WORD_DATA, src, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1)); - FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1)); - } - else - FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, TMP_REG1)); - - FAIL_IF(push_inst(compiler, FCFID | FD(dst_r) | FB(TMP_FREG1))); - - if (dst & SLJIT_MEM) - return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); - if (op & SLJIT_32) - return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); - return SLJIT_SUCCESS; - -#else - - sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_s32 invert_sign = 1; - - if (src & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw ^ (sljit_sw)0x80000000)); - src = TMP_REG1; - invert_sign = 0; - } - else if (!FAST_IS_REG(src)) { - FAIL_IF(emit_op_mem(compiler, WORD_DATA | SIGNED_DATA | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1)); - src = TMP_REG1; - } - - /* First, a special double floating point value is constructed: (2^53 + (input xor (2^31))) - The double precision format has exactly 53 bit precision, so the lower 32 bit represents - the lower 32 bit of such value. The result of xor 2^31 is the same as adding 0x80000000 - to the input, which shifts it into the 0 - 0xffffffff range. To get the converted floating - point value, we need to subtract 2^53 + 2^31 from the constructed value. */ - FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG2) | A(0) | 0x4330)); - if (invert_sign) - FAIL_IF(push_inst(compiler, XORIS | S(src) | A(TMP_REG1) | 0x8000)); - FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_HI, TMP_REG1)); - FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2)); - FAIL_IF(push_inst(compiler, ADDIS | D(TMP_REG1) | A(0) | 0x8000)); - FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1)); - FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET_LOW, TMP_REG2)); - FAIL_IF(emit_op_mem(compiler, DOUBLE_DATA | LOAD_DATA, TMP_FREG2, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, TMP_REG1)); - - FAIL_IF(push_inst(compiler, FSUB | FD(dst_r) | FA(TMP_FREG1) | FB(TMP_FREG2))); - - if (dst & SLJIT_MEM) - return emit_op_mem(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, TMP_REG1); - if (op & SLJIT_32) - return push_inst(compiler, FRSP | FD(dst_r) | FB(dst_r)); - return SLJIT_SUCCESS; - -#endif -} - static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w) @@ -2051,13 +2187,10 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile switch (GET_FLAG_TYPE(op)) { case SLJIT_UNORDERED_OR_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: return push_inst(compiler, CROR | ((4 + 2) << 21) | ((4 + 2) << 16) | ((4 + 3) << 11)); case SLJIT_UNORDERED_OR_LESS: - case SLJIT_ORDERED_GREATER_EQUAL: return push_inst(compiler, CROR | ((4 + 0) << 21) | ((4 + 0) << 16) | ((4 + 3) << 11)); case SLJIT_UNORDERED_OR_GREATER: - case SLJIT_ORDERED_LESS_EQUAL: return push_inst(compiler, CROR | ((4 + 1) << 21) | ((4 + 1) << 16) | ((4 + 3) << 11)); } @@ -2143,18 +2276,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil case SLJIT_ADD_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_r) | FA(src1) | FB(src2))); break; - case SLJIT_SUB_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_r) | FA(src1) | FB(src2))); break; - case SLJIT_MUL_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_r) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); break; - case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_r) | FA(src1) | FB(src2))); break; + case SLJIT_COPYSIGN_F64: + FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? STFS : STFD) | FS(src2) | A(SLJIT_SP) | TMP_MEM_OFFSET)); +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + FAIL_IF(push_inst(compiler, LWZ | S(TMP_REG1) | A(SLJIT_SP) | ((op & SLJIT_32) ? TMP_MEM_OFFSET : TMP_MEM_OFFSET_HI))); +#else /* !SLJIT_CONFIG_PPC_32 */ + FAIL_IF(push_inst(compiler, ((op & SLJIT_32) ? LWZ : LD) | S(TMP_REG1) | A(SLJIT_SP) | TMP_MEM_OFFSET)); +#endif /* SLJIT_CONFIG_PPC_32 */ + FAIL_IF(push_inst(compiler, FABS | FD(dst_r) | FB(src1))); +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(TMP_REG1) | 0)); +#else /* !SLJIT_CONFIG_PPC_32 */ + FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((op & SLJIT_32) ? 0 : 1)) | A(TMP_REG1) | 0)); +#endif /* SLJIT_CONFIG_PPC_32 */ + FAIL_IF(push_inst(compiler, BCx | (4 << 21) | (0 << 16) | 8)); + return push_inst(compiler, FNEG | FD(dst_r) | FB(dst_r)); } if (dst & SLJIT_MEM) @@ -2165,22 +2310,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil #undef SELECT_FOP -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { + union { + sljit_s32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - if (FAST_IS_REG(dst)) - return push_inst(compiler, MFLR | D(dst)); + u.value = value; - /* Memory. */ - FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2))); - return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); + if (u.imm != 0) + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm)); + + FAIL_IF(push_inst(compiler, STW | S(u.imm != 0 ? TMP_REG1 : TMP_ZERO) | A(SLJIT_SP) | TMP_MEM_OFFSET)); + return push_inst(compiler, LFS | FS(freg) | A(SLJIT_SP) | TMP_MEM_OFFSET); } /* --------------------------------------------------------------------- */ @@ -2303,7 +2450,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile set_jump(jump, compiler, (sljit_u32)type & SLJIT_REWRITABLE_JUMP); type &= 0xff; - if (type == SLJIT_CARRY || type == SLJIT_NOT_CARRY) + if ((type | 0x1) == SLJIT_NOT_CARRY) PTR_FAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG1) | A(TMP_ZERO) | B(TMP_ZERO))); /* In PPC, we don't need to touch the arguments. */ @@ -2324,6 +2471,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types) { + SLJIT_UNUSED_ARG(arg_types); + CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types)); @@ -2360,7 +2509,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi #else /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */ src_r = src; #endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */ - } else if (src & SLJIT_IMM) { + } else if (src == SLJIT_IMM) { /* These jumps are converted to jump/call instructions when possible. */ jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); FAIL_IF(!jump); @@ -2390,6 +2539,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi sljit_s32 arg_types, sljit_s32 src, sljit_sw srcw) { + SLJIT_UNUSED_ARG(arg_types); + CHECK_ERROR(); CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw)); @@ -2572,14 +2723,106 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return sljit_emit_op2(compiler, saved_op, dst, 0, dst, 0, TMP_REG2, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { - CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + sljit_ins *ptr; + sljit_uw size; +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + sljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA; +#else /* !SLJIT_CONFIG_PPC_64 */ + sljit_s32 inp_flags = WORD_DATA | LOAD_DATA; +#endif /* SLJIT_CONFIG_PPC_64 */ - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);; + CHECK_ERROR(); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_reg != src2_reg) { + if (dst_reg == src1) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) { + FAIL_IF(push_inst(compiler, OR | S(dst_reg) | A(TMP_REG2) | B(dst_reg))); + + if ((src1 & REG_MASK) == dst_reg) + src1 = (src1 & ~REG_MASK) | TMP_REG2; + + if (OFFS_REG(src1) == dst_reg) + src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG2); + } + + FAIL_IF(push_inst(compiler, OR | S(src2_reg) | A(dst_reg) | B(src2_reg))); + } + } + + if (((type & ~SLJIT_32) | 0x1) == SLJIT_NOT_CARRY) + FAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG1) | A(TMP_ZERO) | B(TMP_ZERO))); + + size = compiler->size; + + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + compiler->size++; + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, dst_reg, src1, src1w, TMP_REG1)); + } else if (src1 == SLJIT_IMM) { +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + if (type & SLJIT_32) + src1w = (sljit_s32)src1w; +#endif /* SLJIT_CONFIG_RISCV_64 */ + FAIL_IF(load_immediate(compiler, dst_reg, src1w)); + } else + FAIL_IF(push_inst(compiler, OR | S(src1) | A(dst_reg) | B(src1))); + + *ptr = BCx | get_bo_bi_flags(compiler, (type ^ 0x1) & ~SLJIT_32) | (sljit_ins)((compiler->size - size) << 2); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_ins *ptr; + sljit_uw size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, FMR | FD(dst_freg) | FB(src2_freg))); + } + + if (((type & ~SLJIT_32) | 0x1) == SLJIT_NOT_CARRY) + FAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG1) | A(TMP_ZERO) | B(TMP_ZERO))); + + size = compiler->size; + + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + compiler->size++; + + if (src1 & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, dst_freg, src1, src1w, TMP_REG1)); + else + FAIL_IF(push_inst(compiler, FMR | FD(dst_freg) | FB(src1))); + + *ptr = BCx | get_bo_bi_flags(compiler, (type ^ 0x1) & ~SLJIT_32) | (sljit_ins)((compiler->size - size) << 2); + return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) @@ -2813,7 +3056,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(emit_const(compiler, dst_r, init_value)); if (dst & SLJIT_MEM) - PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)); + PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, dst_r, dst, dstw, TMP_REG1)); return const_; } diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_32.c index b38e6924c80..396c956c197 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_32.c @@ -27,7 +27,6 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r) { SLJIT_UNUSED_ARG(tmp_r); - SLJIT_ASSERT(dst_r != tmp_r); if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)); @@ -43,6 +42,76 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_s32 imm[2]; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm[0] != 0) + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm[0], TMP_REG3)); + if (u.imm[1] != 0) + FAIL_IF(load_immediate(compiler, TMP_REG2, u.imm[1], TMP_REG3)); + + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-16))); + FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(u.imm[0] != 0 ? TMP_REG1 : TMP_ZERO) | (8 << 7))); + FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(u.imm[1] != 0 ? TMP_REG2 : TMP_ZERO) | (12 << 7))); + FAIL_IF(push_inst(compiler, FLD | FRD(freg) | RS1(SLJIT_SP) | IMM_I(8))); + return push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(16)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_ins inst; + sljit_s32 reg2 = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (op & SLJIT_32) { + if (op == SLJIT_COPY32_TO_F32) + inst = FMV_W_X | RS1(reg) | FRD(freg); + else + inst = FMV_X_W | FRS1(freg) | RD(reg); + + return push_inst(compiler, inst); + } + + FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-16))); + + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + } + + if (op == SLJIT_COPY_TO_F64) { + if (reg2 != 0) + FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(reg2) | (8 << 7))); + else + FAIL_IF(push_inst(compiler, FSW | RS1(SLJIT_SP) | FRS2(freg) | (8 << 7))); + + FAIL_IF(push_inst(compiler, SW | RS1(SLJIT_SP) | RS2(reg) | (12 << 7))); + FAIL_IF(push_inst(compiler, FLD | FRD(freg) | RS1(SLJIT_SP) | IMM_I(8))); + } else { + FAIL_IF(push_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(freg) | (8 << 7))); + + if (reg2 != 0) + FAIL_IF(push_inst(compiler, FMV_X_W | FRS1(freg) | RD(reg2))); + + FAIL_IF(push_inst(compiler, LW | RD(reg) | RS1(SLJIT_SP) | IMM_I(12))); + } + + return push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(16)); +} + static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins) { if ((init_value & 0x800) != 0) diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_64.c index 32cec7848d2..7fcf2c52730 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_64.c @@ -28,8 +28,6 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r { sljit_sw high; - SLJIT_ASSERT(dst_r != tmp_r); - if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)); @@ -81,6 +79,8 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r return SLJIT_SUCCESS; } + SLJIT_ASSERT(dst_r != tmp_r); + high = imm >> 32; imm = (sljit_s32)imm; @@ -126,6 +126,45 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r return push_inst(compiler, XOR | RD(dst_r) | RS1(dst_r) | RS2(tmp_r)); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_sw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm == 0) + return push_inst(compiler, FMV_W_X | (1 << 25) | RS1(TMP_ZERO) | FRD(freg)); + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm, TMP_REG3)); + return push_inst(compiler, FMV_W_X | (1 << 25) | RS1(TMP_REG1) | FRD(freg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_ins inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) + inst = FMV_W_X | RS1(reg) | FRD(freg); + else + inst = FMV_X_W | FRS1(freg) | RD(reg); + + if (!(op & SLJIT_32)) + inst |= (sljit_ins)1 << 25; + + return push_inst(compiler, inst); +} + static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value, sljit_ins last_ins) { sljit_sw high; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_common.c b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_common.c index 58a48c649c9..64bd411d9d3 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_common.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeRISCV_common.c @@ -97,16 +97,20 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define FLD (F3(0x3) | OPC(0x7)) #define FLE_S (F7(0x50) | F3(0x0) | OPC(0x53)) #define FLT_S (F7(0x50) | F3(0x1) | OPC(0x53)) -#define FSD (F3(0x3) | OPC(0x27)) /* These conversion opcodes are partly defined. */ #define FCVT_S_D (F7(0x20) | OPC(0x53)) #define FCVT_S_W (F7(0x68) | OPC(0x53)) +#define FCVT_S_WU (F7(0x68) | F12(0x1) | OPC(0x53)) #define FCVT_W_S (F7(0x60) | F3(0x1) | OPC(0x53)) #define FMUL_S (F7(0x8) | F3(0x7) | OPC(0x53)) +#define FMV_X_W (F7(0x70) | F3(0x0) | OPC(0x53)) +#define FMV_W_X (F7(0x78) | F3(0x0) | OPC(0x53)) +#define FSD (F3(0x3) | OPC(0x27)) #define FSGNJ_S (F7(0x10) | F3(0x0) | OPC(0x53)) #define FSGNJN_S (F7(0x10) | F3(0x1) | OPC(0x53)) #define FSGNJX_S (F7(0x10) | F3(0x2) | OPC(0x53)) #define FSUB_S (F7(0x4) | F3(0x7) | OPC(0x53)) +#define FSW (F3(0x2) | OPC(0x27)) #define JAL (OPC(0x6f)) #define JALR (F3(0x0) | OPC(0x67)) #define LD (F3(0x3) | OPC(0x3)) @@ -344,13 +348,12 @@ static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg) if ((addr & 0x80000000l) != 0) high = ~high; - if ((high & 0x800) != 0) - high += 0x1000; - if (flags & PATCH_ABS52) { SLJIT_ASSERT(addr <= S52_MAX); inst[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high << 12); } else { + if ((high & 0x800) != 0) + high += 0x1000; inst[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff); inst[1] = ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high); inst++; @@ -531,7 +534,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) { switch (feature_type) { case SLJIT_HAS_FPU: +#ifdef SLJIT_IS_FPU_AVAILABLE + return (SLJIT_IS_FPU_AVAILABLE) != 0; +#elif defined(__riscv_float_abi_soft) + return 0; +#else + return 1; +#endif /* SLJIT_IS_FPU_AVAILABLE */ case SLJIT_HAS_ZERO_REGISTER: + case SLJIT_HAS_COPY_F32: +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + case SLJIT_HAS_COPY_F64: +#endif /* !SLJIT_CONFIG_RISCV_64 */ return 1; default: return 0; @@ -540,7 +554,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - return (type >= SLJIT_ORDERED_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL); + switch (type) { + case SLJIT_UNORDERED_OR_EQUAL: + case SLJIT_ORDERED_NOT_EQUAL: + return 2; + + case SLJIT_UNORDERED: + case SLJIT_ORDERED: + return 1; + } + + return 0; } /* --------------------------------------------------------------------- */ @@ -610,10 +634,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { if ((local_size & SSIZE_OF(sw)) != 0) local_size += SSIZE_OF(sw); - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } #else - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); #endif local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; compiler->local_size = local_size; @@ -704,10 +728,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp if (fsaveds > 0 || fscratches >= SLJIT_FIRST_SAVED_FLOAT_REG) { if ((local_size & SSIZE_OF(sw)) != 0) local_size += SSIZE_OF(sw); - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); } #else - local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sizeof(sljit_f64)); + local_size += GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, f64); #endif compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 15) & ~0xf; @@ -915,7 +939,7 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl /* Since tmp can be the same as base or offset registers, * these might be unavailable after modifying tmp. */ - if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) + if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA) && reg == TMP_REG2) tmp_r = reg; if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) { @@ -1031,9 +1055,11 @@ static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, slji #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) #define WORD 0 +#define WORD_32 0 #define IMM_EXTEND(v) (IMM_I(v)) #else /* !SLJIT_CONFIG_RISCV_32 */ #define WORD word +#define WORD_32 0x08 #define IMM_EXTEND(v) (IMM_I((op & SLJIT_32) ? (v) : (32 + (v)))) #endif /* SLJIT_CONFIG_RISCV_32 */ @@ -1041,16 +1067,16 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj { sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ); #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - sljit_ins word = (op & SLJIT_32) >> 5; - sljit_ins max = (op & SLJIT_32) ? 32 : 64; + sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5; + sljit_ins word_size = (op & SLJIT_32) ? 32 : 64; #else /* !SLJIT_CONFIG_RISCV_64 */ - sljit_ins max = 32; + sljit_ins word_size = 32; #endif /* SLJIT_CONFIG_RISCV_64 */ SLJIT_ASSERT(WORD == 0 || WORD == 0x8); /* The OTHER_FLAG is the counter. */ - FAIL_IF(push_inst(compiler, ADDI | WORD | RD(OTHER_FLAG) | RS1(TMP_ZERO) | IMM_I(max))); + FAIL_IF(push_inst(compiler, ADDI | WORD | RD(OTHER_FLAG) | RS1(TMP_ZERO) | IMM_I(word_size))); /* The TMP_REG2 is the next value. */ if (src != TMP_REG2) @@ -1066,7 +1092,7 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj FAIL_IF(push_inst(compiler, BLT | RS1(TMP_REG2) | RS2(TMP_ZERO) | ((sljit_ins)(2 * SSIZE_OF(ins)) << 7) | ((sljit_ins)(8 * SSIZE_OF(ins)) << 20))); /* The TMP_REG1 is the next shift. */ - FAIL_IF(push_inst(compiler, ADDI | WORD | RD(TMP_REG1) | RS1(TMP_ZERO) | IMM_I(max))); + FAIL_IF(push_inst(compiler, ADDI | WORD | RD(TMP_REG1) | RS1(TMP_ZERO) | IMM_I(word_size))); FAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(TMP_REG2) | IMM_I(0))); FAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_I(1))); @@ -1081,6 +1107,65 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, slj return push_inst(compiler, ADDI | WORD | RD(dst) | RS1(OTHER_FLAG) | IMM_I(0)); } +static sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src) +{ + SLJIT_UNUSED_ARG(op); + +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + if (!(op & SLJIT_32)) { + FAIL_IF(push_inst(compiler, LUI | RD(OTHER_FLAG) | 0x10000)); + FAIL_IF(push_inst(compiler, SRLI | RD(TMP_REG1) | RS1(src) | IMM_I(32))); + FAIL_IF(push_inst(compiler, ADDI | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | IMM_I(0xfff))); + FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(src) | IMM_I(32))); + FAIL_IF(push_inst(compiler, SLLI | RD(EQUAL_FLAG) | RS1(OTHER_FLAG) | IMM_I(32))); + FAIL_IF(push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1))); + FAIL_IF(push_inst(compiler, OR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(EQUAL_FLAG))); + + FAIL_IF(push_inst(compiler, SRLI | RD(TMP_REG1) | RS1(dst) | IMM_I(16))); + FAIL_IF(push_inst(compiler, AND | RD(dst) | RS1(dst) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, SLLI | RD(EQUAL_FLAG) | RS1(OTHER_FLAG) | IMM_I(8))); + FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(16))); + FAIL_IF(push_inst(compiler, XOR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(EQUAL_FLAG))); + FAIL_IF(push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1))); + + FAIL_IF(push_inst(compiler, SRLI | RD(TMP_REG1) | RS1(dst) | IMM_I(8))); + FAIL_IF(push_inst(compiler, AND | RD(dst) | RS1(dst) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(8))); + return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)); + } +#endif /* SLJIT_CONFIG_RISCV_64 */ + + FAIL_IF(push_inst(compiler, SRLI | WORD_32 | RD(TMP_REG1) | RS1(src) | IMM_I(16))); + FAIL_IF(push_inst(compiler, LUI | RD(OTHER_FLAG) | 0xff0000)); + FAIL_IF(push_inst(compiler, SLLI | WORD_32 | RD(dst) | RS1(src) | IMM_I(16))); + FAIL_IF(push_inst(compiler, ORI | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | IMM_I(0xff))); + FAIL_IF(push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1))); + + FAIL_IF(push_inst(compiler, SRLI | WORD_32 | RD(TMP_REG1) | RS1(dst) | IMM_I(8))); + FAIL_IF(push_inst(compiler, AND | RD(dst) | RS1(dst) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(OTHER_FLAG))); + FAIL_IF(push_inst(compiler, SLLI | WORD_32 | RD(dst) | RS1(dst) | IMM_I(8))); + return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)); +} + +static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src) +{ +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5; + sljit_ins word_size = (op & SLJIT_32) ? 32 : 64; +#else /* !SLJIT_CONFIG_RISCV_64 */ + sljit_ins word_size = 32; +#endif /* SLJIT_CONFIG_RISCV_64 */ + + FAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(src) | IMM_I(8))); + FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src) | IMM_I(word_size - 8))); + FAIL_IF(push_inst(compiler, ANDI | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_I(0xff))); + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI) | WORD | RD(dst) | RS1(dst) | IMM_I(word_size - 16))); + return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1)); +} + #define EMIT_LOGICAL(op_imm, op_reg) \ if (flags & SRC2_IMM) { \ if (op & SLJIT_SET_Z) \ @@ -1105,7 +1190,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl sljit_s32 is_overflow, is_carry, carry_src_r, is_handled; sljit_ins op_imm, op_reg; #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - sljit_ins word = (op & SLJIT_32) >> 5; + sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5; #endif /* SLJIT_CONFIG_RISCV_64 */ SLJIT_ASSERT(WORD == 0 || WORD == 0x8); @@ -1174,10 +1259,33 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); return emit_clz_ctz(compiler, op, dst, src2); + case SLJIT_REV: + case SLJIT_REV_S32: +#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) + case SLJIT_REV_U32: +#endif /* SLJIT_CONFIG_RISCV_32 */ + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + return emit_rev(compiler, op, dst, src2); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + return emit_rev16(compiler, op, dst, src2); + +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + case SLJIT_REV_U32: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && dst != TMP_REG1); + FAIL_IF(emit_rev(compiler, op, dst, src2)); + if (dst == TMP_REG2) + return SLJIT_SUCCESS; + FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(32))); + return push_inst(compiler, SRLI | RD(dst) | RS1(dst) | IMM_I(32)); +#endif /* SLJIT_CONFIG_RISCV_32 */ + case SLJIT_ADD: /* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */ is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW; - carry_src_r = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + carry_src_r = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_overflow) { @@ -1233,7 +1341,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl return push_inst(compiler, XOR | RD(OTHER_FLAG) | RS1(TMP_REG1) | RS2(OTHER_FLAG)); case SLJIT_ADDC: - carry_src_r = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + carry_src_r = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2))); @@ -1280,11 +1388,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl is_handled = 0; if (flags & SRC2_IMM) { - if (GET_FLAG_TYPE(op) == SLJIT_LESS || GET_FLAG_TYPE(op) == SLJIT_GREATER_EQUAL) { + if (GET_FLAG_TYPE(op) == SLJIT_LESS) { FAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2))); is_handled = 1; } - else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS || GET_FLAG_TYPE(op) == SLJIT_SIG_GREATER_EQUAL) { + else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) { FAIL_IF(push_inst(compiler, SLTI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2))); is_handled = 1; } @@ -1301,19 +1409,15 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl switch (GET_FLAG_TYPE(op)) { case SLJIT_LESS: - case SLJIT_GREATER_EQUAL: FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src1) | RS2(src2))); break; case SLJIT_GREATER: - case SLJIT_LESS_EQUAL: FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src2) | RS2(src1))); break; case SLJIT_SIG_LESS: - case SLJIT_SIG_GREATER_EQUAL: FAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RS1(src1) | RS2(src2))); break; case SLJIT_SIG_GREATER: - case SLJIT_SIG_LESS_EQUAL: FAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RS1(src2) | RS2(src1))); break; } @@ -1336,7 +1440,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl } is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW; - is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_overflow) { @@ -1385,7 +1489,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl flags &= ~SRC2_IMM; } - is_carry = GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY); + is_carry = GET_FLAG_TYPE(op) == SLJIT_CARRY; if (flags & SRC2_IMM) { if (is_carry) @@ -1534,9 +1638,10 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 compiler->cache_argw = 0; } - if (dst == TMP_REG2) { + if (dst == 0) { SLJIT_ASSERT(HAS_FLAGS(op)); flags |= UNUSED_DEST; + dst = TMP_REG2; } else if (FAST_IS_REG(dst)) { dst_r = dst; @@ -1548,11 +1653,11 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 flags |= SLOW_DEST; if (flags & IMM_OP) { - if ((src2 & SLJIT_IMM) && src2w != 0 && src2w <= SIMM_MAX && src2w >= SIMM_MIN) { + if (src2 == SLJIT_IMM && src2w != 0 && src2w <= SIMM_MAX && src2w >= SIMM_MIN) { flags |= SRC2_IMM; src2_r = src2w; } - else if ((flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w != 0 && src1w <= SIMM_MAX && src1w >= SIMM_MIN) { + else if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && src1w <= SIMM_MAX && src1w >= SIMM_MIN) { flags |= SRC2_IMM; src2_r = src1w; @@ -1569,7 +1674,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 src1_r = src1; flags |= REG1_SOURCE; } - else if (src1 & SLJIT_IMM) { + else if (src1 == SLJIT_IMM) { if (src1w) { FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3)); src1_r = TMP_REG1; @@ -1592,7 +1697,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 if ((flags & (REG_DEST | MOVE_OP)) == MOVE_OP) dst_r = (sljit_s32)src2_r; } - else if (src2 & SLJIT_IMM) { + else if (src2 == SLJIT_IMM) { if (!(flags & SRC2_IMM)) { if (src2w) { FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w, TMP_REG3)); @@ -1649,7 +1754,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - sljit_ins word = (op & SLJIT_32) >> 5; + sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5; SLJIT_ASSERT(word == 0 || word == 0x8); #endif /* SLJIT_CONFIG_RISCV_64 */ @@ -1718,32 +1823,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) case SLJIT_MOV_U32: - return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u32)srcw : srcw); case SLJIT_MOV_S32: /* Logical operators have no W variant, so sign extended input is necessary for them. */ case SLJIT_MOV32: - return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw); #endif case SLJIT_MOV_U8: - return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw); + return emit_op(compiler, op, BYTE_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u8)srcw : srcw); case SLJIT_MOV_S8: - return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw); + return emit_op(compiler, op, BYTE_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s8)srcw : srcw); case SLJIT_MOV_U16: - return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw); + return emit_op(compiler, op, HALF_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_u16)srcw : srcw); case SLJIT_MOV_S16: - return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw); - - case SLJIT_NOT: - return emit_op(compiler, SLJIT_XOR | (op & (SLJIT_32 | SLJIT_SET_Z)), flags, dst, dstw, src, srcw, SLJIT_IMM, -1); + return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, (src == SLJIT_IMM) ? (sljit_s16)srcw : srcw); case SLJIT_CLZ: case SLJIT_CTZ: + case SLJIT_REV: return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_REV_U16: + case SLJIT_REV_S16: + return emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + + case SLJIT_REV_U32: + case SLJIT_REV_S32: + return emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); } SLJIT_UNREACHABLE(); @@ -1766,9 +1877,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) if (op & SLJIT_32) { flags |= INT_DATA | SIGNED_DATA; - if (src1 & SLJIT_IMM) + if (src1 == SLJIT_IMM) src1w = (sljit_s32)src1w; - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) src2w = (sljit_s32)src2w; } #endif @@ -1801,7 +1912,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile case SLJIT_MASHR: case SLJIT_ROTL: case SLJIT_ROTR: - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) src2w &= 0x1f; #else /* !SLJIT_CONFIG_RISCV_32 */ @@ -1827,18 +1938,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w)); SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w); + return sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_left; sljit_ins ins1, ins2, ins3; #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - sljit_ins word = (op & SLJIT_32) >> 5; + sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5; sljit_s32 inp_flags = ((op & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA; sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64; #else /* !SLJIT_CONFIG_RISCV_64 */ @@ -1849,50 +1961,44 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * SLJIT_ASSERT(WORD == 0 || WORD == 0x8); CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, (is_left ? SLJIT_ROTL : SLJIT_ROTR) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); - if (src2 & SLJIT_IMM) { - src2w &= bit_length - 1; + if (src3 == SLJIT_IMM) { + src3w &= bit_length - 1; - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (src2 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src2, src2w)); - src2 = TMP_REG2; - } - if (src1 & SLJIT_MEM) { - FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src1, src1w)); - src1 = TMP_REG1; - } else if (src1 & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3)); - src1 = TMP_REG1; - } - - if (src2 & SLJIT_IMM) { if (is_left) { - ins1 = SLLI | WORD | IMM_I(src2w); - src2w = bit_length - src2w; - ins2 = SRLI | WORD | IMM_I(src2w); + ins1 = SLLI | WORD | IMM_I(src3w); + src3w = bit_length - src3w; + ins2 = SRLI | WORD | IMM_I(src3w); } else { - ins1 = SRLI | WORD | IMM_I(src2w); - src2w = bit_length - src2w; - ins2 = SLLI | WORD | IMM_I(src2w); + ins1 = SRLI | WORD | IMM_I(src3w); + src3w = bit_length - src3w; + ins2 = SLLI | WORD | IMM_I(src3w); } - FAIL_IF(push_inst(compiler, ins1 | RD(src_dst) | RS1(src_dst))); - FAIL_IF(push_inst(compiler, ins2 | RD(TMP_REG1) | RS1(src1))); - return push_inst(compiler, OR | RD(src_dst) | RS1(src_dst) | RS2(TMP_REG1)); + FAIL_IF(push_inst(compiler, ins1 | RD(dst_reg) | RS1(src1_reg))); + FAIL_IF(push_inst(compiler, ins2 | RD(TMP_REG1) | RS1(src2_reg))); + return push_inst(compiler, OR | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1)); + } + + if (src3 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG2, src3, src3w)); + src3 = TMP_REG2; + } else if (dst_reg == src3) { + push_inst(compiler, ADDI | WORD | RD(TMP_REG2) | RS1(src3) | IMM_I(0)); + src3 = TMP_REG2; } if (is_left) { @@ -1905,21 +2011,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler * ins3 = SLL; } - FAIL_IF(push_inst(compiler, ins1 | WORD | RD(src_dst) | RS1(src_dst) | RS2(src2))); + FAIL_IF(push_inst(compiler, ins1 | WORD | RD(dst_reg) | RS1(src1_reg) | RS2(src3))); if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) { - FAIL_IF(push_inst(compiler, ins2 | WORD | RD(TMP_REG1) | RS1(src1) | IMM_I(1))); - FAIL_IF(push_inst(compiler, XORI | RD(TMP_REG2) | RS1(src2) | IMM_I((sljit_ins)bit_length - 1))); - src1 = TMP_REG1; + FAIL_IF(push_inst(compiler, ins2 | WORD | RD(TMP_REG1) | RS1(src2_reg) | IMM_I(1))); + FAIL_IF(push_inst(compiler, XORI | RD(TMP_REG2) | RS1(src3) | IMM_I((sljit_ins)bit_length - 1))); + src2_reg = TMP_REG1; } else - FAIL_IF(push_inst(compiler, SUB | WORD | RD(TMP_REG2) | RS1(TMP_ZERO) | RS2(src2))); + FAIL_IF(push_inst(compiler, SUB | WORD | RD(TMP_REG2) | RS1(TMP_ZERO) | RS2(src3))); - FAIL_IF(push_inst(compiler, ins3 | WORD | RD(TMP_REG1) | RS1(src1) | RS2(TMP_REG2))); - return push_inst(compiler, OR | RD(src_dst) | RS1(src_dst) | RS2(TMP_REG1)); + FAIL_IF(push_inst(compiler, ins3 | WORD | RD(TMP_REG1) | RS1(src2_reg) | RS2(TMP_REG2))); + return push_inst(compiler, OR | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1)); } -#undef WORD - SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw) { @@ -1947,21 +2051,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return reg_map[reg]; + sljit_s32 dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + if (FAST_IS_REG(dst)) + return push_inst(compiler, ADDI | RD(dst) | RS1(RETURN_ADDR_REG) | IMM_I(0)); + + SLJIT_ASSERT(RETURN_ADDR_REG == TMP_REG2); + break; + case SLJIT_GET_RETURN_ADDRESS: + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2; + FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size - SSIZE_OF(sw))); + break; + } + + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return reg_map[reg]; + + if (type != SLJIT_FLOAT_REGISTER) + return -1; + return freg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, void *instruction, sljit_u32 size) { + SLJIT_UNUSED_ARG(size); + CHECK_ERROR(); CHECK(check_sljit_emit_op_custom(compiler, instruction, size)); @@ -2008,51 +2143,73 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp #endif } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { - sljit_ins inst; -#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - sljit_u32 flags = ((sljit_u32)(GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW)) << 21; -#endif - sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); -#else - FAIL_IF(emit_op_mem2(compiler, (flags ? WORD_DATA : INT_DATA) | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); -#endif +#else /* SLJIT_CONFIG_RISCV_32 */ + FAIL_IF(emit_op_mem2(compiler, ((ins & (1 << 21)) ? WORD_DATA : INT_DATA) | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); +#endif /* !SLJIT_CONFIG_RISCV_32 */ src = TMP_REG1; - } else if (src & SLJIT_IMM) { -#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) - if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) - srcw = (sljit_s32)srcw; -#endif - + } else if (src == SLJIT_IMM) { FAIL_IF(load_immediate(compiler, TMP_REG1, srcw, TMP_REG3)); src = TMP_REG1; } - inst = FCVT_S_W | FMT(op) | FRD(dst_r) | RS1(src); + FAIL_IF(push_inst(compiler, ins | FRD(dst_r) | RS1(src))); + + if (dst & SLJIT_MEM) + return emit_op_mem2(compiler, DOUBLE_DATA | ((sljit_s32)(~ins >> 24) & 0x2), TMP_FREG1, dst, dstw, 0, 0); + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins ins = FCVT_S_W | FMT(op); #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) if (op & SLJIT_32) - inst |= F3(0x7); -#else - inst |= flags; + ins |= F3(0x7); +#else /* !SLJIT_CONFIG_RISCV_32 */ + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) + ins |= (1 << 21); + else if (src == SLJIT_IMM) + srcw = (sljit_s32)srcw; if (op != SLJIT_CONV_F64_FROM_S32) - inst |= F3(0x7); -#endif + ins |= F3(0x7); +#endif /* SLJIT_CONFIG_RISCV_32 */ - FAIL_IF(push_inst(compiler, inst)); + return sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw); +} - if (dst & SLJIT_MEM) - return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0); - return SLJIT_SUCCESS; +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins ins = FCVT_S_WU | FMT(op); + +#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) + if (op & SLJIT_32) + ins |= F3(0x7); +#else /* !SLJIT_CONFIG_RISCV_32 */ + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_UW) + ins |= (1 << 21); + else if (src == SLJIT_IMM) + srcw = (sljit_u32)srcw; + + if (op != SLJIT_CONV_F64_FROM_S32) + ins |= F3(0x7); +#endif /* SLJIT_CONFIG_RISCV_32 */ + + return sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw); } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, @@ -2073,40 +2230,36 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile switch (GET_FLAG_TYPE(op)) { case SLJIT_F_EQUAL: - case SLJIT_F_NOT_EQUAL: case SLJIT_ORDERED_EQUAL: - case SLJIT_UNORDERED_OR_NOT_EQUAL: inst = FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2); break; case SLJIT_F_LESS: - case SLJIT_F_GREATER_EQUAL: case SLJIT_ORDERED_LESS: - case SLJIT_UNORDERED_OR_GREATER_EQUAL: inst = FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2); break; case SLJIT_ORDERED_GREATER: - case SLJIT_UNORDERED_OR_LESS_EQUAL: inst = FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src2) | FRS2(src1); break; case SLJIT_F_GREATER: - case SLJIT_F_LESS_EQUAL: case SLJIT_UNORDERED_OR_GREATER: - case SLJIT_ORDERED_LESS_EQUAL: inst = FLE_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2); break; case SLJIT_UNORDERED_OR_LESS: - case SLJIT_ORDERED_GREATER_EQUAL: inst = FLE_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src2) | FRS2(src1); break; - case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */ - case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */ + case SLJIT_UNORDERED_OR_EQUAL: FAIL_IF(push_inst(compiler, FLT_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src2))); FAIL_IF(push_inst(compiler, FLT_S | FMT(op) | RD(TMP_REG1) | FRS1(src2) | FRS2(src1))); inst = OR | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(TMP_REG1); break; - default: /* SLJIT_UNORDERED, SLJIT_ORDERED */ - FAIL_IF(push_inst(compiler, FADD_S | FMT(op) | FRD(TMP_FREG1) | FRS1(src1) | FRS2(src2))); - inst = FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(TMP_FREG1) | FRS2(TMP_FREG1); + default: /* SLJIT_UNORDERED */ + if (src1 == src2) { + inst = FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src1); + break; + } + FAIL_IF(push_inst(compiler, FEQ_S | FMT(op) | RD(OTHER_FLAG) | FRS1(src1) | FRS2(src1))); + FAIL_IF(push_inst(compiler, FEQ_S | FMT(op) | RD(TMP_REG1) | FRS1(src2) | FRS2(src2))); + inst = AND | RD(OTHER_FLAG) | RS1(OTHER_FLAG) | RS2(TMP_REG1); break; } @@ -2233,6 +2386,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil case SLJIT_DIV_F64: FAIL_IF(push_inst(compiler, FDIV_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2))); break; + + case SLJIT_COPYSIGN_F64: + return push_inst(compiler, FSGNJ_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2)); } if (dst_r == TMP_FREG2) @@ -2241,24 +2397,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return SLJIT_SUCCESS; } -#undef FLOAT_DATA -#undef FMT - -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) { + union { + sljit_s32 imm; + sljit_f32 value; + } u; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); - if (FAST_IS_REG(dst)) - return push_inst(compiler, ADDI | RD(dst) | RS1(RETURN_ADDR_REG) | IMM_I(0)); + u.value = value; - /* Memory. */ - return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); + if (u.imm == 0) + return push_inst(compiler, FMV_W_X | RS1(TMP_ZERO) | FRD(freg)); + + FAIL_IF(load_immediate(compiler, TMP_REG1, u.imm, TMP_REG3)); + return push_inst(compiler, FMV_W_X | RS1(TMP_REG1) | FRD(freg)); } /* --------------------------------------------------------------------- */ @@ -2287,6 +2443,54 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #define BRANCH_LENGTH ((sljit_ins)(7 * sizeof(sljit_ins)) << 7) #endif +static sljit_ins get_jump_instruction(sljit_s32 type) +{ + switch (type) { + case SLJIT_EQUAL: + return BNE | RS1(EQUAL_FLAG) | RS2(TMP_ZERO); + case SLJIT_NOT_EQUAL: + return BEQ | RS1(EQUAL_FLAG) | RS2(TMP_ZERO); + case SLJIT_LESS: + case SLJIT_GREATER: + case SLJIT_SIG_LESS: + case SLJIT_SIG_GREATER: + case SLJIT_OVERFLOW: + case SLJIT_CARRY: + case SLJIT_F_EQUAL: + case SLJIT_ORDERED_EQUAL: + case SLJIT_ORDERED_NOT_EQUAL: + case SLJIT_F_LESS: + case SLJIT_ORDERED_LESS: + case SLJIT_ORDERED_GREATER: + case SLJIT_F_LESS_EQUAL: + case SLJIT_ORDERED_LESS_EQUAL: + case SLJIT_ORDERED_GREATER_EQUAL: + case SLJIT_ORDERED: + return BEQ | RS1(OTHER_FLAG) | RS2(TMP_ZERO); + break; + case SLJIT_GREATER_EQUAL: + case SLJIT_LESS_EQUAL: + case SLJIT_SIG_GREATER_EQUAL: + case SLJIT_SIG_LESS_EQUAL: + case SLJIT_NOT_OVERFLOW: + case SLJIT_NOT_CARRY: + case SLJIT_F_NOT_EQUAL: + case SLJIT_UNORDERED_OR_NOT_EQUAL: + case SLJIT_UNORDERED_OR_EQUAL: + case SLJIT_F_GREATER_EQUAL: + case SLJIT_UNORDERED_OR_GREATER_EQUAL: + case SLJIT_UNORDERED_OR_LESS_EQUAL: + case SLJIT_F_GREATER: + case SLJIT_UNORDERED_OR_GREATER: + case SLJIT_UNORDERED_OR_LESS: + case SLJIT_UNORDERED: + return BNE | RS1(OTHER_FLAG) | RS2(TMP_ZERO); + default: + /* Not conditional branch. */ + return 0; + } +} + SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; @@ -2300,57 +2504,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); type &= 0xff; - switch (type) { - case SLJIT_EQUAL: - inst = BNE | RS1(EQUAL_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH; - break; - case SLJIT_NOT_EQUAL: - inst = BEQ | RS1(EQUAL_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH; - break; - case SLJIT_LESS: - case SLJIT_GREATER: - case SLJIT_SIG_LESS: - case SLJIT_SIG_GREATER: - case SLJIT_OVERFLOW: - case SLJIT_CARRY: - case SLJIT_F_EQUAL: - case SLJIT_ORDERED_EQUAL: - case SLJIT_ORDERED_NOT_EQUAL: /* Not supported. */ - case SLJIT_F_LESS: - case SLJIT_ORDERED_LESS: - case SLJIT_ORDERED_GREATER: - case SLJIT_F_LESS_EQUAL: - case SLJIT_ORDERED_LESS_EQUAL: - case SLJIT_ORDERED_GREATER_EQUAL: - case SLJIT_ORDERED: - inst = BEQ | RS1(OTHER_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH; - break; - case SLJIT_GREATER_EQUAL: - case SLJIT_LESS_EQUAL: - case SLJIT_SIG_GREATER_EQUAL: - case SLJIT_SIG_LESS_EQUAL: - case SLJIT_NOT_OVERFLOW: - case SLJIT_NOT_CARRY: - case SLJIT_F_NOT_EQUAL: - case SLJIT_UNORDERED_OR_NOT_EQUAL: - case SLJIT_UNORDERED_OR_EQUAL: /* Not supported. */ - case SLJIT_F_GREATER_EQUAL: - case SLJIT_UNORDERED_OR_GREATER_EQUAL: - case SLJIT_UNORDERED_OR_LESS_EQUAL: - case SLJIT_F_GREATER: - case SLJIT_UNORDERED_OR_GREATER: - case SLJIT_UNORDERED_OR_LESS: - case SLJIT_UNORDERED: - inst = BNE | RS1(OTHER_FLAG) | RS2(TMP_ZERO) | BRANCH_LENGTH; - break; - default: - /* Not conditional branch. */ - inst = 0; - break; - } + inst = get_jump_instruction(type); if (inst != 0) { - PTR_FAIL_IF(push_inst(compiler, inst)); + PTR_FAIL_IF(push_inst(compiler, inst | BRANCH_LENGTH)); jump->flags |= IS_COND; } @@ -2420,7 +2577,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler src2 = TMP_REG2; } - if (src1 & SLJIT_IMM) { + if (src1 == SLJIT_IMM) { if (src1w != 0) { PTR_FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3)); src1 = TMP_REG1; @@ -2429,7 +2586,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler src1 = TMP_ZERO; } - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { if (src2w != 0) { PTR_FAIL_IF(load_immediate(compiler, TMP_REG2, src2w, TMP_REG3)); src2 = TMP_REG2; @@ -2499,7 +2656,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { if (src & SLJIT_MEM) { ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw)); @@ -2641,16 +2798,110 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return emit_op(compiler, saved_op, mem_type, dst, dstw, dst, dstw, src_r, 0); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { - CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + sljit_ins *ptr; + sljit_uw size; +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + sljit_ins word = (sljit_ins)(type & SLJIT_32) >> 5; + sljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA; +#else /* !SLJIT_CONFIG_RISCV_64 */ + sljit_s32 inp_flags = WORD_DATA | LOAD_DATA; +#endif /* SLJIT_CONFIG_RISCV_64 */ - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);; + SLJIT_ASSERT(WORD == 0 || WORD == 0x8); + + CHECK_ERROR(); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_reg != src2_reg) { + if (dst_reg == src1) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) { + FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG2) | RS1(dst_reg) | IMM_I(0))); + + if ((src1 & REG_MASK) == dst_reg) + src1 = (src1 & ~REG_MASK) | TMP_REG2; + + if (OFFS_REG(src1) == dst_reg) + src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG2); + } + + FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst_reg) | RS1(src2_reg) | IMM_I(0))); + } + } + + size = compiler->size; + + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + compiler->size++; + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_op_mem(compiler, inp_flags, dst_reg, src1, src1w)); + } else if (src1 == SLJIT_IMM) { +#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) + if (word) + src1w = (sljit_s32)src1w; +#endif /* SLJIT_CONFIG_RISCV_64 */ + FAIL_IF(load_immediate(compiler, dst_reg, src1w, TMP_REG1)); + } else + FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst_reg) | RS1(src1) | IMM_I(0))); + + *ptr = get_jump_instruction(type & ~SLJIT_32) | (sljit_ins)((compiler->size - size) << 9); + return SLJIT_SUCCESS; } +#undef WORD + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_ins *ptr; + sljit_uw size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, FSGNJ_S | FMT(type) | FRD(dst_freg) | FRS1(src2_freg) | FRS2(src2_freg))); + } + + size = compiler->size; + + ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); + FAIL_IF(!ptr); + compiler->size++; + + if (src1 & SLJIT_MEM) + FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, dst_freg, src1, src1w)); + else + FAIL_IF(push_inst(compiler, FSGNJ_S | FMT(type) | FRD(dst_freg) | FRS1(src1) | FRS2(src1))); + + *ptr = get_jump_instruction(type & ~SLJIT_32) | (sljit_ins)((compiler->size - size) << 9); + return SLJIT_SUCCESS; +} + +#undef FLOAT_DATA +#undef FMT + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw) diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeS390X.c b/src/3rdparty/pcre2/src/sljit/sljitNativeS390X.c index 8b51bad9bc3..67516f9b320 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeS390X.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeS390X.c @@ -47,8 +47,8 @@ static const sljit_ins sljit_ins_const = (sljit_ins)1 << 48; #define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) -static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = { - 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1 +static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { + 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1, 14 }; /* there are also a[2-15] available, but they are slower to access and @@ -83,7 +83,7 @@ static const sljit_gpr r10 = 10; /* reg_map[9] */ static const sljit_gpr r11 = 11; /* reg_map[10] */ static const sljit_gpr r12 = 12; /* reg_map[11]: GOT */ static const sljit_gpr r13 = 13; /* reg_map[12]: Literal Pool pointer */ -static const sljit_gpr r14 = 14; /* reg_map[0]: return address and flag register */ +static const sljit_gpr r14 = 14; /* reg_map[0]: return address */ static const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */ /* WARNING: r12 and r13 shouldn't be used as per ABI recommendation */ @@ -96,20 +96,16 @@ static const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stac #define tmp0 r0 #define tmp1 r1 -/* TODO(carenas): flags should move to a different register so that - * link register doesn't need to change - */ - /* When reg cannot be unused. */ #define IS_GPR_REG(reg) ((reg > 0) && (reg) <= SLJIT_SP) /* Link register. */ static const sljit_gpr link_r = 14; /* r14 */ -#define TMP_FREG1 (0) +#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { - 1, 0, 2, 4, 6, 3, 5, 7, 15, 14, 13, 12, 11, 10, 9, 8, +static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = { + 0, 0, 2, 4, 6, 3, 5, 7, 15, 14, 13, 12, 11, 10, 9, 8, 1 }; #define R0A(r) (r) @@ -126,7 +122,10 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { #define F0(r) ((sljit_ins)freg_map[r]) #define F4(r) (R4A((sljit_ins)freg_map[r])) +#define F12(r) (R12A((sljit_ins)freg_map[r])) #define F20(r) (R20A((sljit_ins)freg_map[r])) +#define F28(r) (R28A((sljit_ins)freg_map[r])) +#define F32(r) (R32A((sljit_ins)freg_map[r])) #define F36(r) (R36A((sljit_ins)freg_map[r])) struct sljit_s390x_const { @@ -141,12 +140,6 @@ static SLJIT_INLINE sljit_gpr gpr(sljit_s32 r) return reg_map[r]; } -static SLJIT_INLINE sljit_gpr fgpr(sljit_s32 r) -{ - SLJIT_ASSERT(r >= 0 && r < (sljit_s32)(sizeof(freg_map) / sizeof(freg_map[0]))); - return freg_map[r]; -} - /* Size of instruction in bytes. Tags must already be cleared. */ static SLJIT_INLINE sljit_uw sizeof_ins(sljit_ins ins) { @@ -217,6 +210,7 @@ static SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 t } /* fallthrough */ + case SLJIT_ATOMIC_STORED: case SLJIT_F_EQUAL: case SLJIT_ORDERED_EQUAL: return cc0; @@ -236,6 +230,7 @@ static SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 t return (cc1 | cc2 | cc3); case SLJIT_LESS: + case SLJIT_ATOMIC_NOT_STORED: return cc1; case SLJIT_GREATER_EQUAL: @@ -454,10 +449,12 @@ HAVE_FACILITY(have_misc2, MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY) static SLJIT_INLINE sljit_ins disp_s20(sljit_s32 d) { + sljit_uw dh, dl; + SLJIT_ASSERT(is_s20(d)); - sljit_uw dh = (d >> 12) & 0xff; - sljit_uw dl = (d << 8) & 0xfff00; + dh = (d >> 12) & 0xff; + dl = ((sljit_uw)d << 8) & 0xfff00; return (dh | dl) << 8; } @@ -899,23 +896,17 @@ static sljit_s32 push_load_imm_inst(struct sljit_compiler *compiler, sljit_gpr t if (((sljit_uw)v & ~(sljit_uw)0xffff000000000000) == 0) return push_inst(compiler, llihh(target, (sljit_u16)(v >> 48))); - /* 6 byte instructions (requires extended immediate facility) */ - if (have_eimm()) { - if (is_s32(v)) - return push_inst(compiler, lgfi(target, (sljit_s32)v)); + if (is_s32(v)) + return push_inst(compiler, lgfi(target, (sljit_s32)v)); - if (((sljit_uw)v >> 32) == 0) - return push_inst(compiler, llilf(target, (sljit_u32)v)); + if (((sljit_uw)v >> 32) == 0) + return push_inst(compiler, llilf(target, (sljit_u32)v)); - if (((sljit_uw)v << 32) == 0) - return push_inst(compiler, llihf(target, (sljit_u32)((sljit_uw)v >> 32))); + if (((sljit_uw)v << 32) == 0) + return push_inst(compiler, llihf(target, (sljit_u32)((sljit_uw)v >> 32))); - FAIL_IF(push_inst(compiler, llilf(target, (sljit_u32)v))); - return push_inst(compiler, iihf(target, (sljit_u32)(v >> 32))); - } - - /* TODO(mundaym): instruction sequences that don't use extended immediates */ - abort(); + FAIL_IF(push_inst(compiler, llilf(target, (sljit_u32)v))); + return push_inst(compiler, iihf(target, (sljit_u32)(v >> 32))); } struct addr { @@ -995,24 +986,47 @@ static sljit_s32 make_addr_bx(struct sljit_compiler *compiler, (cond) ? EVAL(i1, r, addr) : EVAL(i2, r, addr) /* May clobber tmp1. */ -static sljit_s32 load_word(struct sljit_compiler *compiler, sljit_gpr dst_r, +static sljit_s32 load_store_op(struct sljit_compiler *compiler, sljit_gpr reg, + sljit_s32 mem, sljit_sw memw, + sljit_s32 is_32bit, const sljit_ins* forms) +{ + struct addr addr; + + SLJIT_ASSERT(mem & SLJIT_MEM); + + if (is_32bit && ((mem & OFFS_REG_MASK) || is_u12(memw) || !is_s20(memw))) { + FAIL_IF(make_addr_bx(compiler, &addr, mem, memw, tmp1)); + return push_inst(compiler, forms[0] | R20A(reg) | R16A(addr.index) | R12A(addr.base) | (sljit_ins)addr.offset); + } + + FAIL_IF(make_addr_bxy(compiler, &addr, mem, memw, tmp1)); + return push_inst(compiler, (is_32bit ? forms[1] : forms[2]) | R36A(reg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset)); +} + +static const sljit_ins load_forms[3] = { + 0x58000000 /* l */, + 0xe30000000058 /* ly */, + 0xe30000000004 /* lg */ +}; + +static const sljit_ins store_forms[3] = { + 0x50000000 /* st */, + 0xe30000000050 /* sty */, + 0xe30000000024 /* stg */ +}; + +static const sljit_ins load_halfword_forms[3] = { + 0x48000000 /* lh */, + 0xe30000000078 /* lhy */, + 0xe30000000015 /* lgh */ +}; + +/* May clobber tmp1. */ +static SLJIT_INLINE sljit_s32 load_word(struct sljit_compiler *compiler, sljit_gpr dst_r, sljit_s32 src, sljit_sw srcw, sljit_s32 is_32bit) { - struct addr addr; - sljit_ins ins; - - SLJIT_ASSERT(src & SLJIT_MEM); - - if (is_32bit && ((src & OFFS_REG_MASK) || is_u12(srcw) || !is_s20(srcw))) { - FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1)); - return push_inst(compiler, 0x58000000 /* l */ | R20A(dst_r) | R16A(addr.index) | R12A(addr.base) | (sljit_ins)addr.offset); - } - - FAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp1)); - - ins = is_32bit ? 0xe30000000058 /* ly */ : 0xe30000000004 /* lg */; - return push_inst(compiler, ins | R36A(dst_r) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset)); + return load_store_op(compiler, dst_r, src, srcw, is_32bit, load_forms); } /* May clobber tmp1. */ @@ -1032,24 +1046,11 @@ static sljit_s32 load_unsigned_word(struct sljit_compiler *compiler, sljit_gpr d } /* May clobber tmp1. */ -static sljit_s32 store_word(struct sljit_compiler *compiler, sljit_gpr src_r, +static SLJIT_INLINE sljit_s32 store_word(struct sljit_compiler *compiler, sljit_gpr src_r, sljit_s32 dst, sljit_sw dstw, sljit_s32 is_32bit) { - struct addr addr; - sljit_ins ins; - - SLJIT_ASSERT(dst & SLJIT_MEM); - - if (is_32bit && ((dst & OFFS_REG_MASK) || is_u12(dstw) || !is_s20(dstw))) { - FAIL_IF(make_addr_bx(compiler, &addr, dst, dstw, tmp1)); - return push_inst(compiler, 0x50000000 /* st */ | R20A(src_r) | R16A(addr.index) | R12A(addr.base) | (sljit_ins)addr.offset); - } - - FAIL_IF(make_addr_bxy(compiler, &addr, dst, dstw, tmp1)); - - ins = is_32bit ? 0xe30000000050 /* sty */ : 0xe30000000024 /* stg */; - return push_inst(compiler, ins | R36A(src_r) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset)); + return load_store_op(compiler, src_r, dst, dstw, is_32bit, store_forms); } #undef WHEN @@ -1058,15 +1059,17 @@ static sljit_s32 emit_move(struct sljit_compiler *compiler, sljit_gpr dst_r, sljit_s32 src, sljit_sw srcw) { + sljit_gpr src_r; + SLJIT_ASSERT(!IS_GPR_REG(src) || dst_r != gpr(src & REG_MASK)); - if (src & SLJIT_IMM) + if (src == SLJIT_IMM) return push_load_imm_inst(compiler, dst_r, srcw); if (src & SLJIT_MEM) return load_word(compiler, dst_r, src, srcw, (compiler->mode & SLJIT_32) != 0); - sljit_gpr src_r = gpr(src & REG_MASK); + src_r = gpr(src & REG_MASK); return push_inst(compiler, (compiler->mode & SLJIT_32) ? lr(dst_r, src_r) : lgr(dst_r, src_r)); } @@ -1259,10 +1262,10 @@ static sljit_s32 emit_siy(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_sw srcw) { - SLJIT_ASSERT(dst & SLJIT_MEM); - sljit_gpr dst_r = tmp1; + SLJIT_ASSERT(dst & SLJIT_MEM); + if (dst & OFFS_REG_MASK) { sljit_gpr index = tmp1; @@ -1567,6 +1570,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (jump && jump->addr == j) { sljit_sw target = (sljit_sw)((jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target); if ((jump->flags & SLJIT_REWRITABLE_JUMP) || (jump->flags & JUMP_ADDR)) { + sljit_ins op, arg; + jump->addr = (sljit_uw)pool_ptr; /* load address into tmp1 */ @@ -1583,8 +1588,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil *(pool_ptr++) = (sljit_uw)target; /* branch to tmp1 */ - sljit_ins op = (ins >> 32) & 0xf; - sljit_ins arg = (ins >> 36) & 0xf; + op = (ins >> 32) & 0xf; + arg = (ins >> 36) & 0xf; switch (op) { case 4: /* brcl -> bcr */ ins = bcr(arg, tmp1); @@ -1638,6 +1643,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil compiler->error = SLJIT_ERR_COMPILED; compiler->executable_offset = executable_offset; compiler->executable_size = ins_size; + if (pool_size) + compiler->executable_size += (pad_size + pool_size); code = SLJIT_ADD_EXEC_OFFSET(code, executable_offset); code_ptr = SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset); SLJIT_CACHE_FLUSH(code, code_ptr); @@ -1650,12 +1657,25 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) /* TODO(mundaym): implement all */ switch (feature_type) { case SLJIT_HAS_FPU: +#ifdef SLJIT_IS_FPU_AVAILABLE + return (SLJIT_IS_FPU_AVAILABLE) != 0; +#else + return 1; +#endif /* SLJIT_IS_FPU_AVAILABLE */ + case SLJIT_HAS_CLZ: + case SLJIT_HAS_REV: case SLJIT_HAS_ROT: case SLJIT_HAS_PREFETCH: + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: + case SLJIT_HAS_SIMD: + case SLJIT_HAS_ATOMIC: return 1; + case SLJIT_HAS_CTZ: return 2; + case SLJIT_HAS_CMOV: return have_lscond1() ? 1 : 0; } @@ -1664,7 +1684,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - return (type >= SLJIT_UNORDERED && type <= SLJIT_ORDERED_LESS_EQUAL); + SLJIT_UNUSED_ARG(type); + return 0; } /* --------------------------------------------------------------------- */ @@ -1741,7 +1762,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi local_size = (local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE + 0xf) & ~0xf; compiler->local_size = local_size; - FAIL_IF(push_inst(compiler, 0xe30000000071 /* lay */ | R36A(r15) | R28A(r15) | disp_s20(-local_size))); + if (is_s20(-local_size)) + FAIL_IF(push_inst(compiler, 0xe30000000071 /* lay */ | R36A(r15) | R28A(r15) | disp_s20(-local_size))); + else + FAIL_IF(push_inst(compiler, 0xc20400000000 /* slgfi */ | R36A(r15) | (sljit_ins)local_size)); if (options & SLJIT_ENTER_REG_ARG) return SLJIT_SUCCESS; @@ -1786,8 +1810,10 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit if (is_u12(local_size)) FAIL_IF(push_inst(compiler, 0x41000000 /* ly */ | R20A(r15) | R12A(r15) | (sljit_ins)local_size)); - else + else if (is_s20(local_size)) FAIL_IF(push_inst(compiler, 0xe30000000071 /* lay */ | R36A(r15) | R28A(r15) | disp_s20(local_size))); + else + FAIL_IF(push_inst(compiler, 0xc20a00000000 /* algfi */ | R36A(r15) | (sljit_ins)local_size)); offset = 2 * SSIZE_OF(sw); if (saveds + scratches >= SLJIT_NUMBER_OF_REGISTERS) { @@ -2011,12 +2037,85 @@ static sljit_s32 sljit_emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 o return push_inst(compiler, ((op & SLJIT_32) ? 0x1800 /* lr */ : 0xb9040000 /* lgr */) | R4A(dst_r) | R0A(tmp0)); } +static sljit_s32 sljit_emit_rev(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + struct addr addr; + sljit_gpr reg; + sljit_ins ins; + sljit_s32 opcode = GET_OPCODE(op); + sljit_s32 is_16bit = (opcode == SLJIT_REV_U16 || opcode == SLJIT_REV_S16); + + if (dst & SLJIT_MEM) { + if (src & SLJIT_MEM) { + FAIL_IF(load_store_op(compiler, tmp0, src, srcw, op & SLJIT_32, is_16bit ? load_halfword_forms : load_forms)); + reg = tmp0; + } else + reg = gpr(src); + + FAIL_IF(make_addr_bxy(compiler, &addr, dst, dstw, tmp1)); + + if (is_16bit) + ins = 0xe3000000003f /* strvh */; + else + ins = (op & SLJIT_32) ? 0xe3000000003e /* strv */ : 0xe3000000002f /* strvg */; + + return push_inst(compiler, ins | R36A(reg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset)); + } + + reg = gpr(dst); + + if (src & SLJIT_MEM) { + FAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp1)); + + if (is_16bit) + ins = 0xe3000000001f /* lrvh */; + else + ins = (op & SLJIT_32) ? 0xe3000000001e /* lrv */ : 0xe3000000000f /* lrvg */; + + FAIL_IF(push_inst(compiler, ins | R36A(reg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset))); + + if (opcode == SLJIT_REV) + return SLJIT_SUCCESS; + + if (is_16bit) { + if (op & SLJIT_32) + ins = (opcode == SLJIT_REV_U16) ? 0xb9950000 /* llhr */ : 0xb9270000 /* lhr */; + else + ins = (opcode == SLJIT_REV_U16) ? 0xb9850000 /* llghr */ : 0xb9070000 /* lghr */; + } else + ins = (opcode == SLJIT_REV_U32) ? 0xb9160000 /* llgfr */ : 0xb9140000 /* lgfr */; + + return push_inst(compiler, ins | R4A(reg) | R0A(reg)); + } + + ins = (op & SLJIT_32) ? 0xb91f0000 /* lrvr */ : 0xb90f0000 /* lrvgr */; + FAIL_IF(push_inst(compiler, ins | R4A(reg) | R0A(gpr(src)))); + + if (opcode == SLJIT_REV) + return SLJIT_SUCCESS; + + if (!is_16bit) { + ins = (opcode == SLJIT_REV_U32) ? 0xb9160000 /* llgfr */ : 0xb9140000 /* lgfr */; + return push_inst(compiler, ins | R4A(reg) | R0A(reg)); + } + + if (op & SLJIT_32) { + ins = (opcode == SLJIT_REV_U16) ? 0x88000000 /* srl */ : 0x8a000000 /* sra */; + return push_inst(compiler, ins | R20A(reg) | 16); + } + + ins = (opcode == SLJIT_REV_U16) ? 0xeb000000000c /* srlg */ : 0xeb000000000a /* srag */; + return push_inst(compiler, ins | R36A(reg) | R32A(reg) | (48 << 16)); +} + /* LEVAL will be defined later with different parameters as needed */ #define WHEN2(cond, i1, i2) (cond) ? LEVAL(i1) : LEVAL(i2) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src, sljit_sw srcw) + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) { sljit_ins ins; struct addr mem; @@ -2087,7 +2186,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile return SLJIT_SUCCESS; } /* LOAD IMMEDIATE */ - if (FAST_IS_REG(dst) && (src & SLJIT_IMM)) { + if (FAST_IS_REG(dst) && src == SLJIT_IMM) { switch (opcode) { case SLJIT_MOV_U8: srcw = (sljit_sw)((sljit_u8)(srcw)); @@ -2166,14 +2265,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile return SLJIT_SUCCESS; } /* STORE and STORE IMMEDIATE */ - if ((dst & SLJIT_MEM) - && (FAST_IS_REG(src) || (src & SLJIT_IMM))) { + if ((dst & SLJIT_MEM) && (FAST_IS_REG(src) || src == SLJIT_IMM)) { + struct addr mem; sljit_gpr reg = FAST_IS_REG(src) ? gpr(src) : tmp0; - if (src & SLJIT_IMM) { + + if (src == SLJIT_IMM) { /* TODO(mundaym): MOVE IMMEDIATE? */ FAIL_IF(push_load_imm_inst(compiler, reg, srcw)); } - struct addr mem; FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1)); switch (opcode) { case SLJIT_MOV_U8: @@ -2240,39 +2339,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile SLJIT_UNREACHABLE(); } - SLJIT_ASSERT((src & SLJIT_IMM) == 0); /* no immediates */ + SLJIT_ASSERT(src != SLJIT_IMM); - dst_r = FAST_IS_REG(dst) ? gpr(REG_MASK & dst) : tmp0; - src_r = FAST_IS_REG(src) ? gpr(REG_MASK & src) : tmp0; + dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0; + src_r = FAST_IS_REG(src) ? gpr(src) : tmp0; compiler->status_flags_state = op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z); /* TODO(mundaym): optimize loads and stores */ switch (opcode) { - case SLJIT_NOT: - if (src & SLJIT_MEM) - FAIL_IF(load_word(compiler, src_r, src, srcw, op & SLJIT_32)); - - /* emulate ~x with x^-1 */ - if (!(op & SLJIT_32)) { - FAIL_IF(push_load_imm_inst(compiler, tmp1, -1)); - if (src_r != dst_r) - FAIL_IF(push_inst(compiler, lgr(dst_r, src_r))); - - FAIL_IF(push_inst(compiler, xgr(dst_r, tmp1))); - break; - } - - if (have_eimm()) - FAIL_IF(push_inst(compiler, xilf(dst_r, 0xffffffff))); - else { - FAIL_IF(push_load_imm_inst(compiler, tmp1, -1)); - if (src_r != dst_r) - FAIL_IF(push_inst(compiler, lr(dst_r, src_r))); - - FAIL_IF(push_inst(compiler, xr(dst_r, tmp1))); - } - break; case SLJIT_CLZ: case SLJIT_CTZ: if (src & SLJIT_MEM) @@ -2280,13 +2355,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile FAIL_IF(sljit_emit_clz_ctz(compiler, op, dst_r, src_r)); break; + case SLJIT_REV_U32: + case SLJIT_REV_S32: + op |= SLJIT_32; + /* fallthrough */ + case SLJIT_REV: + case SLJIT_REV_U16: + case SLJIT_REV_S16: + return sljit_emit_rev(compiler, op, dst, dstw, src, srcw); default: SLJIT_UNREACHABLE(); } - if ((op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == (SLJIT_SET_Z | SLJIT_SET_OVERFLOW)) - FAIL_IF(update_zero_overflow(compiler, op, dst_r)); - if (dst & SLJIT_MEM) return store_word(compiler, dst_r, dst, dstw, op & SLJIT_32); @@ -2337,7 +2417,7 @@ static sljit_s32 sljit_emit_add(struct sljit_compiler *compiler, sljit_s32 op, const struct ins_forms *forms; sljit_ins ins; - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { if (!sets_zero_overflow && is_s8(src2w) && (src1 & SLJIT_MEM) && (dst == src1 && dstw == src1w)) { if (sets_overflow) ins = (op & SLJIT_32) ? 0xeb000000006a /* asi */ : 0xeb000000007a /* agsi */; @@ -2422,9 +2502,8 @@ static sljit_s32 sljit_emit_sub(struct sljit_compiler *compiler, sljit_s32 op, compiler->status_flags_state |= SLJIT_CURRENT_FLAGS_COMPARE; - if (src2 & SLJIT_IMM) { - if (compare_signed || ((op & VARIABLE_FLAG_MASK) == 0 && is_s32(src2w))) - { + if (src2 == SLJIT_IMM) { + if (compare_signed || ((op & VARIABLE_FLAG_MASK) == 0 && is_s32(src2w))) { if ((op & SLJIT_32) || is_s32(src2w)) { ins = (op & SLJIT_32) ? 0xc20d00000000 /* cfi */ : 0xc20c00000000 /* cgfi */; return emit_ri(compiler, ins, src1, src1, src1w, src2w, RIL_A); @@ -2465,7 +2544,7 @@ static sljit_s32 sljit_emit_sub(struct sljit_compiler *compiler, sljit_s32 op, goto done; } - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { sljit_sw neg_src2w = -src2w; if (sets_signed || neg_src2w != 0 || (op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)) == 0) { @@ -2573,7 +2652,7 @@ static sljit_s32 sljit_emit_multiply(struct sljit_compiler *compiler, sljit_s32 return emit_commutative(compiler, &multiply_overflow_forms, dst, src1, src1w, src2, src2w); } - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { if (is_s16(src2w)) { ins = (op & SLJIT_32) ? 0xa70c0000 /* mhi */ : 0xa70d0000 /* mghi */; return emit_ri(compiler, ins, dst, src1, src1w, src2w, RI_A); @@ -2680,7 +2759,7 @@ static sljit_s32 sljit_emit_bitwise(struct sljit_compiler *compiler, sljit_s32 o sljit_s32 type = GET_OPCODE(op); const struct ins_forms *forms; - if ((src2 & SLJIT_IMM) && (!(op & SLJIT_SET_Z) || (type == SLJIT_AND && dst == (sljit_s32)tmp0))) { + if (src2 == SLJIT_IMM && (!(op & SLJIT_SET_Z) || (type == SLJIT_AND && dst == (sljit_s32)tmp0))) { sljit_s32 count16 = 0; sljit_uw imm = (sljit_uw)src2w; @@ -2705,12 +2784,12 @@ static sljit_s32 sljit_emit_bitwise(struct sljit_compiler *compiler, sljit_s32 o FAIL_IF(emit_move(compiler, tmp0, src1, src1w)); if ((imm & 0x000000000000ffffull) != 0 || imm == 0) - return push_inst(compiler, 0xa7010000 | R20A(src_r) | imm); + return push_inst(compiler, 0xa7010000 /* tmll */ | R20A(src_r) | imm); if ((imm & 0x00000000ffff0000ull) != 0) - return push_inst(compiler, 0xa7000000 | R20A(src_r) | (imm >> 16)); + return push_inst(compiler, 0xa7000000 /* tmlh */ | R20A(src_r) | (imm >> 16)); if ((imm & 0x0000ffff00000000ull) != 0) - return push_inst(compiler, 0xa7030000 | R20A(src_r) | (imm >> 32)); - return push_inst(compiler, 0xa7020000 | R20A(src_r) | (imm >> 48)); + return push_inst(compiler, 0xa7030000 /* tmhl */ | R20A(src_r) | (imm >> 32)); + return push_inst(compiler, 0xa7020000 /* tmhh */ | R20A(src_r) | (imm >> 48)); } if (!(op & SLJIT_SET_Z)) @@ -2744,7 +2823,7 @@ static sljit_s32 sljit_emit_shift(struct sljit_compiler *compiler, sljit_s32 op, else FAIL_IF(emit_move(compiler, tmp0, src1, src1w)); - if (!(src2 & SLJIT_IMM)) { + if (src2 != SLJIT_IMM) { if (FAST_IS_REG(src2)) base_r = gpr(src2); else { @@ -2804,7 +2883,7 @@ static sljit_s32 sljit_emit_rotate(struct sljit_compiler *compiler, sljit_s32 op else FAIL_IF(emit_move(compiler, tmp0, src1, src1w)); - if (!(src2 & SLJIT_IMM)) { + if (src2 != SLJIT_IMM) { if (FAST_IS_REG(src2)) base_r = gpr(src2); else { @@ -2814,7 +2893,7 @@ static sljit_s32 sljit_emit_rotate(struct sljit_compiler *compiler, sljit_s32 op } if (GET_OPCODE(op) == SLJIT_ROTR) { - if (!(src2 & SLJIT_IMM)) { + if (src2 != SLJIT_IMM) { ins = (op & SLJIT_32) ? 0x1300 /* lcr */ : 0xb9030000 /* lcgr */; FAIL_IF(push_inst(compiler, ins | R4A(tmp1) | R0A(base_r))); base_r = tmp1; @@ -2822,7 +2901,7 @@ static sljit_s32 sljit_emit_rotate(struct sljit_compiler *compiler, sljit_s32 op src2w = -src2w; } - if (src2 & SLJIT_IMM) + if (src2 == SLJIT_IMM) imm = (sljit_ins)(src2w & ((op & SLJIT_32) ? 0x1f : 0x3f)); ins = (op & SLJIT_32) ? 0xeb000000001d /* rll */ : 0xeb000000001c /* rllg */; @@ -2863,7 +2942,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile compiler->mode = op & SLJIT_32; compiler->status_flags_state = op & (VARIABLE_FLAG_MASK | SLJIT_SET_Z); - if (is_commutative(op) && (src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM)) { + if (is_commutative(op) && src1 == SLJIT_IMM && src2 != SLJIT_IMM) { src1 ^= src2; src2 ^= src1; src1 ^= src2; @@ -2931,122 +3010,125 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { sljit_s32 is_right; sljit_sw bit_length = (op & SLJIT_32) ? 32 : 64; - sljit_gpr src_dst_r = gpr(src_dst); - sljit_gpr src1_r = tmp0; - sljit_gpr src2_r = tmp1; + sljit_gpr dst_r = gpr(dst_reg); + sljit_gpr src1_r = gpr(src1_reg); + sljit_gpr src2_r = gpr(src2_reg); + sljit_gpr src3_r = tmp1; sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); is_right = (GET_OPCODE(op) == SLJIT_LSHR || GET_OPCODE(op) == SLJIT_MLSHR); - if (src_dst == src1) { + if (src1_reg == src2_reg) { SLJIT_SKIP_CHECKS(compiler); - return sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), src_dst, 0, src_dst, 0, src2, src2w); + return sljit_emit_op2(compiler, (is_right ? SLJIT_ROTR : SLJIT_ROTL) | (op & SLJIT_32), dst_reg, 0, src1_reg, 0, src3, src3w); } - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + ADJUST_LOCAL_OFFSET(src3, src3w); - if (src1 & SLJIT_MEM) - FAIL_IF(load_word(compiler, tmp0, src1, src1w, op & SLJIT_32)); - else if (src1 & SLJIT_IMM) - FAIL_IF(push_load_imm_inst(compiler, tmp0, src1w)); - else - src1_r = gpr(src1); + if (src3 == SLJIT_IMM) { + src3w &= bit_length - 1; - if (src2 & SLJIT_IMM) { - src2w &= bit_length - 1; - - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; - } else if (!(src2 & SLJIT_MEM)) - src2_r = gpr(src2); - else - FAIL_IF(load_word(compiler, tmp1, src2, src2w, op & SLJIT_32)); - if (src2 & SLJIT_IMM) { if (op & SLJIT_32) { - ins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */; - FAIL_IF(push_inst(compiler, ins | R20A(src_dst_r) | (sljit_ins)src2w)); + if (dst_r == src1_r) { + ins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */; + FAIL_IF(push_inst(compiler, ins | R20A(dst_r) | (sljit_ins)src3w)); + } else { + ins = is_right ? 0xeb00000000de /* srlk */ : 0xeb00000000df /* sllk */; + FAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | ((sljit_ins)src3w << 16))); + } } else { ins = is_right ? 0xeb000000000c /* srlg */ : 0xeb000000000d /* sllg */; - FAIL_IF(push_inst(compiler, ins | R36A(src_dst_r) | R32A(src_dst_r) | ((sljit_ins)src2w << 16))); + FAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | ((sljit_ins)src3w << 16))); } ins = 0xec0000000055 /* risbg */; if (is_right) { - src2w = bit_length - src2w; - ins |= ((sljit_ins)(64 - bit_length) << 24) | ((sljit_ins)(63 - src2w) << 16) | ((sljit_ins)src2w << 8); + src3w = bit_length - src3w; + ins |= ((sljit_ins)(64 - bit_length) << 24) | ((sljit_ins)(63 - src3w) << 16) | ((sljit_ins)src3w << 8); } else - ins |= ((sljit_ins)(64 - src2w) << 24) | ((sljit_ins)63 << 16) | ((sljit_ins)src2w << 8); + ins |= ((sljit_ins)(64 - src3w) << 24) | ((sljit_ins)63 << 16) | ((sljit_ins)(src3w + 64 - bit_length) << 8); - return push_inst(compiler, ins | R36A(src_dst_r) | R32A(src1_r)); + return push_inst(compiler, ins | R36A(dst_r) | R32A(src2_r)); } + if (!(src3 & SLJIT_MEM)) { + src3_r = gpr(src3); + + if (dst_r == src3_r) { + FAIL_IF(push_inst(compiler, 0x1800 /* lr */ | R4A(tmp1) | R0A(src3_r))); + src3_r = tmp1; + } + } else + FAIL_IF(load_word(compiler, tmp1, src3, src3w, op & SLJIT_32)); + if (op & SLJIT_32) { if (GET_OPCODE(op) == SLJIT_MSHL || GET_OPCODE(op) == SLJIT_MLSHR) { - if (src2_r != tmp1) { - FAIL_IF(push_inst(compiler, 0xec0000000055 /* risbg */ | R36A(tmp1) | R32A(src2_r) | (59 << 24) | (1 << 23) | (63 << 16))); - src2_r = tmp1; + if (src3_r != tmp1) { + FAIL_IF(push_inst(compiler, 0xec0000000055 /* risbg */ | R36A(tmp1) | R32A(src3_r) | (59 << 24) | (1 << 23) | (63 << 16))); + src3_r = tmp1; } else FAIL_IF(push_inst(compiler, 0xa5070000 /* nill */ | R20A(tmp1) | 0x1f)); } - ins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */; - FAIL_IF(push_inst(compiler, ins | R20A(src_dst_r) | R12A(src2_r))); + if (dst_r == src1_r) { + ins = is_right ? 0x88000000 /* srl */ : 0x89000000 /* sll */; + FAIL_IF(push_inst(compiler, ins | R20A(dst_r) | R12A(src3_r))); + } else { + ins = is_right ? 0xeb00000000de /* srlk */ : 0xeb00000000df /* sllk */; + FAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | R28A(src3_r))); + } - if (src2_r != tmp1) { + if (src3_r != tmp1) { FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | 0x1f)); - FAIL_IF(push_inst(compiler, 0x1700 /* xr */ | R4A(tmp1) | R0A(src2_r))); + FAIL_IF(push_inst(compiler, 0x1700 /* xr */ | R4A(tmp1) | R0A(src3_r))); } else FAIL_IF(push_inst(compiler, 0xc00700000000 /* xilf */ | R36A(tmp1) | 0x1f)); - if (src1_r == tmp0) { - ins = is_right ? 0x89000000 /* sll */ : 0x88000000 /* srl */; - FAIL_IF(push_inst(compiler, ins | R20A(tmp0) | R12A(tmp1) | 0x1)); - } else { - ins = is_right ? 0xeb00000000df /* sllk */ : 0xeb00000000de /* srlk */; - FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src1_r) | R28A(tmp1) | (0x1 << 16))); - } + ins = is_right ? 0xeb00000000df /* sllk */ : 0xeb00000000de /* srlk */; + FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src2_r) | R28A(tmp1) | (0x1 << 16))); - return push_inst(compiler, 0x1600 /* or */ | R4A(src_dst_r) | R0A(tmp0)); + return push_inst(compiler, 0x1600 /* or */ | R4A(dst_r) | R0A(tmp0)); } ins = is_right ? 0xeb000000000c /* srlg */ : 0xeb000000000d /* sllg */; - FAIL_IF(push_inst(compiler, ins | R36A(src_dst_r) | R32A(src_dst_r) | R28A(src2_r))); + FAIL_IF(push_inst(compiler, ins | R36A(dst_r) | R32A(src1_r) | R28A(src3_r))); ins = is_right ? 0xeb000000000d /* sllg */ : 0xeb000000000c /* srlg */; if (!(op & SLJIT_SHIFT_INTO_NON_ZERO)) { - if (src2_r != tmp1) + if (src3_r != tmp1) FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | 0x3f)); - FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src1_r) | (0x1 << 16))); - src1_r = tmp0; + FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src2_r) | (0x1 << 16))); + src2_r = tmp0; - if (src2_r != tmp1) - FAIL_IF(push_inst(compiler, 0xb9820000 /* xgr */ | R4A(tmp1) | R0A(src2_r))); + if (src3_r != tmp1) + FAIL_IF(push_inst(compiler, 0xb9820000 /* xgr */ | R4A(tmp1) | R0A(src3_r))); else FAIL_IF(push_inst(compiler, 0xc00700000000 /* xilf */ | R36A(tmp1) | 0x3f)); } else - FAIL_IF(push_inst(compiler, 0xb9030000 /* lcgr */ | R4A(tmp1) | R0A(src2_r))); + FAIL_IF(push_inst(compiler, 0xb9030000 /* lcgr */ | R4A(tmp1) | R0A(src3_r))); - FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src1_r) | R28A(tmp1))); - return push_inst(compiler, 0xb9810000 /* ogr */ | R4A(src_dst_r) | R0A(tmp0)); + FAIL_IF(push_inst(compiler, ins | R36A(tmp0) | R32A(src2_r) | R28A(tmp1))); + return push_inst(compiler, 0xb9810000 /* ogr */ | R4A(dst_r) | R0A(tmp0)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src( - struct sljit_compiler *compiler, - sljit_s32 op, sljit_s32 src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src, sljit_sw srcw) { sljit_gpr src_r; struct addr addr; @@ -3077,16 +3159,46 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src( return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); - return (sljit_s32)gpr(reg); + sljit_gpr dst_r = link_r; + sljit_s32 size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + switch (op) { + case SLJIT_FAST_ENTER: + if (FAST_IS_REG(dst)) + return push_inst(compiler, lgr(gpr(dst), link_r)); + break; + case SLJIT_GET_RETURN_ADDRESS: + dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0; + + size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 2); + FAIL_IF(load_word(compiler, dst_r, SLJIT_MEM1(SLJIT_SP), compiler->local_size + size, 0)); + break; + } + + if (dst & SLJIT_MEM) + return store_word(compiler, dst_r, dst, dstw, 0); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); - return (sljit_s32)fgpr(reg); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) + return (sljit_s32)gpr(reg); + + if (type != SLJIT_FLOAT_REGISTER) + return -1; + + return (sljit_s32)freg_map[reg]; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -3177,33 +3289,61 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, +static sljit_s32 sljit_emit_fop1_conv_f64_from_w(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1; - sljit_ins ins; - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { FAIL_IF(push_load_imm_inst(compiler, tmp0, srcw)); src = (sljit_s32)tmp0; } else if (src & SLJIT_MEM) { - FAIL_IF(load_word(compiler, tmp0, src, srcw, GET_OPCODE(op) >= SLJIT_CONV_F64_FROM_S32)); + FAIL_IF(load_word(compiler, tmp0, src, srcw, ins & 0x100000)); src = (sljit_s32)tmp0; } + FAIL_IF(push_inst(compiler, ins | F4(dst_r) | R0(src))); + + if (dst & SLJIT_MEM) + return float_mem(compiler, FLOAT_STORE | ((ins & 0x10000) ? 0 : SLJIT_32), TMP_FREG1, dst, dstw); + + return SLJIT_SUCCESS; +} + +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins ins; + + if (src == SLJIT_IMM && GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) + srcw = (sljit_s32)srcw; + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) ins = (op & SLJIT_32) ? 0xb3a40000 /* cegbr */ : 0xb3a50000 /* cdgbr */; else ins = (op & SLJIT_32) ? 0xb3940000 /* cefbr */ : 0xb3950000 /* cdfbr */; - FAIL_IF(push_inst(compiler, ins | F4(dst_r) | R0(src))); + return sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw); +} - if (dst & SLJIT_MEM) - return float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), TMP_FREG1, dst, dstw); +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_ins ins; - return SLJIT_SUCCESS; + if (src == SLJIT_IMM && GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) + srcw = (sljit_u32)srcw; + + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_UW) + ins = (op & SLJIT_32) ? 0xb3a00000 /* celgbr */ : 0xb3a10000 /* cdlgbr */; + else + ins = (op & SLJIT_32) ? 0xb3900000 /* celfbr */ : 0xb3910000 /* cdlfbr */; + + return sljit_emit_fop1_conv_f64_from_w(compiler, ins, dst, dstw, src, srcw); } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compiler, sljit_s32 op, @@ -3355,21 +3495,91 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return SLJIT_SUCCESS; } -/* --------------------------------------------------------------------- */ -/* Other instructions */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) { + sljit_s32 reg; + CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); + CHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); - if (FAST_IS_REG(dst)) - return push_inst(compiler, lgr(gpr(dst), link_r)); + if (src2 & SLJIT_MEM) { + FAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), TMP_FREG1, src2, src2w)); + src2 = TMP_FREG1; + } - /* memory */ - return store_word(compiler, link_r, dst, dstw, 0); + if (src1 & SLJIT_MEM) { + reg = (dst_freg == src2) ? TMP_FREG1 : dst_freg; + FAIL_IF(float_mem(compiler, FLOAT_LOAD | (op & SLJIT_32), reg, src1, src1w)); + src1 = reg; + } + + return push_inst(compiler, 0xb3720000 /* cpsdr */ | F12(src2) | F4(dst_freg) | F0(src1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) +{ + union { + sljit_s32 imm; + sljit_f32 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); + + u.value = value; + + FAIL_IF(push_load_imm_inst(compiler, tmp1, (sljit_sw)(((sljit_uw)u.imm << 32)))); + return push_inst(compiler, 0xb3c10000 /* ldgr */ | F4(freg) | R0A(tmp1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_sw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + FAIL_IF(push_load_imm_inst(compiler, tmp1, (sljit_sw)u.imm)); + return push_inst(compiler, 0xb3c10000 /* ldgr */ | F4(freg) | R0A(tmp1)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_gpr gen_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + gen_r = gpr(reg); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) { + if (op & SLJIT_32) { + FAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp0) | R32A(gen_r) | (32 << 16))); + gen_r = tmp0; + } + + return push_inst(compiler, 0xb3c10000 /* ldgr */ | F4(freg) | R0A(gen_r)); + } + + FAIL_IF(push_inst(compiler, 0xb3cd0000 /* lgdr */ | R4A(gen_r) | F0(freg))); + + if (!(op & SLJIT_32)) + return SLJIT_SUCCESS; + + return push_inst(compiler, 0xeb000000000c /* srlg */ | R36A(gen_r) | R32A(gen_r) | (32 << 16)); } /* --------------------------------------------------------------------- */ @@ -3394,14 +3604,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { + struct sljit_jump *jump; sljit_u8 mask = ((type & 0xff) < SLJIT_JUMP) ? get_cc(compiler, type & 0xff) : 0xf; CHECK_ERROR_PTR(); CHECK_PTR(check_sljit_emit_jump(compiler, type)); /* record jump */ - struct sljit_jump *jump = (struct sljit_jump *) - ensure_abuf(compiler, sizeof(struct sljit_jump)); + jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump)); PTR_FAIL_IF(!jump); set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); jump->addr = compiler->size; @@ -3439,7 +3649,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi CHECK_ERROR(); CHECK(check_sljit_emit_ijump(compiler, type, src, srcw)); - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { SLJIT_ASSERT(!(srcw & 1)); /* target address must be even */ FAIL_IF(push_load_imm_inst(compiler, src_r, srcw)); } @@ -3459,6 +3669,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi sljit_s32 arg_types, sljit_s32 src, sljit_sw srcw) { + SLJIT_UNUSED_ARG(arg_types); + CHECK_ERROR(); CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw)); @@ -3490,13 +3702,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_s32 dst, sljit_sw dstw, sljit_s32 type) { + sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0; + sljit_gpr loc_r = tmp1; sljit_u8 mask = get_cc(compiler, type); CHECK_ERROR(); CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type)); - sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0; - sljit_gpr loc_r = tmp1; switch (GET_OPCODE(op)) { case SLJIT_AND: case SLJIT_OR: @@ -3556,37 +3768,125 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { - sljit_ins mask = get_cc(compiler, type & ~SLJIT_32); + sljit_ins mask; sljit_gpr src_r; + sljit_gpr dst_r = gpr(dst_reg); sljit_ins ins; CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); - if (type & SLJIT_32) - srcw = (sljit_s32)srcw; + ADJUST_LOCAL_OFFSET(src1, src1w); - if (have_lscond2() && (src & SLJIT_IMM) && is_s16(srcw)) { - ins = (type & SLJIT_32) ? 0xec0000000042 /* lochi */ : 0xec0000000046 /* locghi */; - return push_inst(compiler, ins | R36A(gpr(dst_reg)) | (mask << 32) | (sljit_ins)(srcw & 0xffff) << 16); + if (dst_reg != src2_reg) { + if (src1 == dst_reg) { + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else { + if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) { + FAIL_IF(load_word(compiler, dst_r, src1, src1w, type & SLJIT_32)); + src1 = src2_reg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(push_inst(compiler, ((type & SLJIT_32) ? 0x1800 /* lr */ : 0xb9040000 /* lgr */) | R4A(dst_r) | R0A(gpr(src2_reg)))); + } } - if (src & SLJIT_IMM) { - FAIL_IF(push_load_imm_inst(compiler, tmp0, srcw)); + mask = get_cc(compiler, type & ~SLJIT_32); + + if (src1 & SLJIT_MEM) { + if (src1 & OFFS_REG_MASK) { + src_r = gpr(OFFS_REG(src1)); + + if (src1w != 0) { + FAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp1) | R32A(src_r) | ((sljit_ins)(src1w & 0x3) << 16))); + src_r = tmp1; + } + + FAIL_IF(push_inst(compiler, 0xb9e80000 /* agrk */ | R12A(src_r) | R4A(tmp1) | R0A(gpr(src1 & REG_MASK)))); + src_r = tmp1; + src1w = 0; + } else if (!is_s20(src1w)) { + FAIL_IF(push_load_imm_inst(compiler, tmp1, src1w)); + + if (src1 & REG_MASK) + FAIL_IF(push_inst(compiler, 0xb9e80000 /* agrk */ | R12A(tmp1) | R4A(tmp1) | R0A(gpr(src1 & REG_MASK)))); + + src_r = tmp1; + src1w = 0; + } else + src_r = gpr(src1 & REG_MASK); + + ins = (type & SLJIT_32) ? 0xeb00000000f2 /* loc */ : 0xeb00000000e2 /* locg */; + return push_inst(compiler, ins | R36A(dst_r) | (mask << 32) | R28A(src_r) | disp_s20((sljit_s32)src1w)); + } + + if (src1 == SLJIT_IMM) { + if (type & SLJIT_32) + src1w = (sljit_s32)src1w; + + if (have_lscond2() && is_s16(src1w)) { + ins = (type & SLJIT_32) ? 0xec0000000042 /* lochi */ : 0xec0000000046 /* locghi */; + return push_inst(compiler, ins | R36A(dst_r) | (mask << 32) | (sljit_ins)(src1w & 0xffff) << 16); + } + + FAIL_IF(push_load_imm_inst(compiler, tmp0, src1w)); src_r = tmp0; } else - src_r = gpr(src); + src_r = gpr(src1); - if (have_lscond1()) { - ins = (type & SLJIT_32) ? 0xb9f20000 /* locr */ : 0xb9e20000 /* locgr */; - return push_inst(compiler, ins | (mask << 12) | R4A(gpr(dst_reg)) | R0A(src_r)); + ins = (type & SLJIT_32) ? 0xb9f20000 /* locr */ : 0xb9e20000 /* locgr */; + return push_inst(compiler, ins | (mask << 12) | R4A(dst_r) | R0A(src_r)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_ins ins; + struct sljit_label *label; + struct sljit_jump *jump; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else { + ins = (type & SLJIT_32) ? 0x3800 /* ler */ : 0x2800 /* ldr */; + FAIL_IF(push_inst(compiler, ins | F4(dst_freg) | F0(src2_freg))); + } } - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw); + SLJIT_SKIP_CHECKS(compiler); + jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1); + FAIL_IF(!jump); + + if (!(src1 & SLJIT_MEM)) { + ins = (type & SLJIT_32) ? 0x3800 /* ler */ : 0x2800 /* ldr */; + FAIL_IF(push_inst(compiler, ins | F4(dst_freg) | F0(src1))); + } else + FAIL_IF(float_mem(compiler, FLOAT_LOAD | (type & SLJIT_32), dst_freg, src1, src1w)); + + SLJIT_SKIP_CHECKS(compiler); + label = sljit_emit_label(compiler); + FAIL_IF(!label); + + sljit_set_label(jump, label); + return SLJIT_SUCCESS; } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, @@ -3648,6 +3948,502 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile return push_inst(compiler, ins | R36A(reg2) | disp_s20((sljit_s32)memw + SSIZE_OF(sw))); } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); + struct addr addr; + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (!(srcdst & SLJIT_MEM)) { + if (type & SLJIT_SIMD_STORE) + ins = F36(srcdst) | F32(freg); + else + ins = F36(freg) | F32(srcdst); + + return push_inst(compiler, 0xe70000000056 /* vlr */ | ins); + } + + FAIL_IF(make_addr_bx(compiler, &addr, srcdst, srcdstw, tmp1)); + ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + + if (alignment >= 4) + ins |= 4 << 12; + else if (alignment == 3) + ins |= 3 << 12; + + return push_inst(compiler, ((type & SLJIT_SIMD_STORE) ? 0xe7000000000e /* vst */ : 0xe70000000006 /* vl */) | ins); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + struct addr addr; + sljit_gpr reg; + sljit_sw sign_ext; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && elem_size < 2) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (src & SLJIT_MEM) { + FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1)); + return push_inst(compiler, 0xe70000000005 /* vlrep */ | F36(freg) + | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset) | ((sljit_ins)elem_size << 12)); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (src == SLJIT_IMM) + return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg)); + + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(src) | ((sljit_ins)elem_size << 12)); + } + + if (src == SLJIT_IMM) { + sign_ext = 0x10000; + + switch (elem_size) { + case 0: + srcw &= 0xff; + sign_ext = (sljit_s8)srcw; + break; + case 1: + srcw &= 0xffff; + sign_ext = (sljit_s16)srcw; + break; + case 2: + if ((sljit_s32)srcw == (sljit_s16)srcw) { + srcw &= 0xffff; + sign_ext = (sljit_s16)srcw; + } else + srcw &= 0xffffffff; + break; + default: + if (srcw == (sljit_s16)srcw) { + srcw &= 0xffff; + sign_ext = (sljit_s16)srcw; + } + break; + } + + if (sign_ext != 0x10000) { + if (sign_ext == 0 || sign_ext == -1) + return push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg) + | (sign_ext == 0 ? 0 : ((sljit_ins)0xffff << 16))); + + return push_inst(compiler, 0xe70000000045 /* vrepi */ | F36(freg) + | ((sljit_ins)srcw << 16) | ((sljit_ins)elem_size << 12)); + } + + push_load_imm_inst(compiler, tmp0, srcw); + reg = tmp0; + } else + reg = gpr(src); + + FAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(reg) | ((sljit_ins)elem_size << 12))); + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(freg) | ((sljit_ins)elem_size << 12)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + struct addr addr; + sljit_gpr reg; + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && elem_size < 2) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (srcdst & SLJIT_MEM) { + FAIL_IF(make_addr_bx(compiler, &addr, srcdst, srcdstw, tmp1)); + ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + } + + if (type & SLJIT_SIMD_LANE_ZERO) { + if ((srcdst & SLJIT_MEM) && lane_index == ((1 << (3 - elem_size)) - 1)) + return push_inst(compiler, 0xe70000000004 /* vllez */ | ins | ((sljit_ins)elem_size << 12)); + + if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { + FAIL_IF(push_inst(compiler, 0xe70000000056 /* vlr */ | F36(TMP_FREG1) | F32(freg))); + srcdst = TMP_FREG1; + srcdstw = 0; + } + + FAIL_IF(push_inst(compiler, 0xe70000000044 /* vgbm */ | F36(freg))); + } + + if (srcdst & SLJIT_MEM) { + switch (elem_size) { + case 0: + ins |= 0xe70000000000 /* vleb */; + break; + case 1: + ins |= 0xe70000000001 /* vleh */; + break; + case 2: + ins |= 0xe70000000003 /* vlef */; + break; + default: + ins |= 0xe70000000002 /* vleg */; + break; + } + + /* Convert to vsteb - vsteg */ + if (type & SLJIT_SIMD_STORE) + ins |= 0x8; + + return push_inst(compiler, ins | ((sljit_ins)lane_index << 12)); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (type & SLJIT_SIMD_STORE) + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(srcdst) | F32(freg) | ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12)); + + if (elem_size == 3) { + if (lane_index == 0) + ins = F32(srcdst) | F28(freg) | (1 << 12); + else + ins = F32(freg) | F28(srcdst); + + return push_inst(compiler, 0xe70000000084 /* vpdi */ | F36(freg) | ins); + } + + FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(tmp0) | F32(srcdst) | ((sljit_ins)2 << 12))); + return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(tmp0) | ((sljit_ins)lane_index << 16) | ((sljit_ins)2 << 12)); + } + + if (srcdst == SLJIT_IMM) { + switch (elem_size) { + case 0: + ins = 0xe70000000040 /* vleib */; + srcdstw &= 0xff; + break; + case 1: + ins = 0xe70000000041 /* vleih */; + srcdstw &= 0xffff; + break; + case 2: + if ((sljit_s32)srcdstw == (sljit_s16)srcdstw) { + srcdstw &= 0xffff; + ins = 0xe70000000043 /* vleif */; + } else + srcdstw &= 0xffffffff; + break; + default: + if (srcdstw == (sljit_s16)srcdstw) { + srcdstw &= 0xffff; + ins = 0xe70000000042 /* vleig */; + } + break; + } + + if (ins != 0) + return push_inst(compiler, ins | F36(freg) | ((sljit_ins)srcdstw << 16) | ((sljit_ins)lane_index << 12)); + + push_load_imm_inst(compiler, tmp0, srcdstw); + reg = tmp0; + } else + reg = gpr(srcdst); + + ins = ((sljit_ins)lane_index << 16) | ((sljit_ins)elem_size << 12); + + if (!(type & SLJIT_SIMD_STORE)) + return push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(freg) | R32A(reg) | ins); + + FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(reg) | F32(freg) | ins)); + + if (!(type & SLJIT_SIMD_LANE_SIGNED) || elem_size >= 3) + return SLJIT_SUCCESS; + + switch (elem_size) { + case 0: + ins = 0xb9060000 /* lgbr */; + break; + case 1: + ins = 0xb9070000 /* lghr */; + break; + default: + ins = 0xb9140000 /* lgfr */; + break; + } + + return push_inst(compiler, ins | R4A(reg) | R0A(reg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && elem_size < 2) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + return push_inst(compiler, 0xe7000000004d /* vrep */ | F36(freg) | F32(src) + | ((sljit_ins)src_lane_index << 16) | ((sljit_ins)elem_size << 12)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); + struct addr addr; + sljit_ins ins; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && elem_size < 2) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (src & SLJIT_MEM) { + FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp1)); + ins = F36(freg) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset); + + switch (elem2_size - elem_size) { + case 1: + ins |= 0xe70000000002 /* vleg */; + break; + case 2: + ins |= 0xe70000000003 /* vlef */; + break; + default: + ins |= 0xe70000000001 /* vleh */; + break; + } + + FAIL_IF(push_inst(compiler, ins)); + src = freg; + } + + if (type & SLJIT_SIMD_FLOAT) { + FAIL_IF(push_inst(compiler, 0xe700000000d5 /* vuplh */ | F36(freg) | F32(src) | (2 << 12))); + FAIL_IF(push_inst(compiler, 0xe70000000030 /* vesl */ | F36(freg) | F32(freg) | (32 << 16) | (3 << 12))); + return push_inst(compiler, 0xe700000000c4 /* vfll */ | F36(freg) | F32(freg) | (2 << 12)); + } + + ins = ((type & SLJIT_SIMD_EXTEND_SIGNED) ? 0xe700000000d7 /* vuph */ : 0xe700000000d5 /* vuplh */) | F36(freg); + + do { + FAIL_IF(push_inst(compiler, ins | F32(src) | ((sljit_ins)elem_size << 12))); + src = freg; + } while (++elem_size < elem2_size); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_gpr dst_r; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + + ADJUST_LOCAL_OFFSET(dst, dstw); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && elem_size < 2) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + switch (elem_size) { + case 0: + push_load_imm_inst(compiler, tmp0, (sljit_sw)0x4048505860687078); + push_load_imm_inst(compiler, tmp1, (sljit_sw)0x0008101820283038); + FAIL_IF(push_inst(compiler, 0xe70000000062 /* vlvgp */ | F36(TMP_FREG1) | R32A(tmp1) | R28A(tmp0))); + break; + case 1: + push_load_imm_inst(compiler, tmp0, (sljit_sw)0x0010203040506070); + break; + case 2: + push_load_imm_inst(compiler, tmp0, (sljit_sw)0x8080808000204060); + break; + default: + push_load_imm_inst(compiler, tmp0, (sljit_sw)0x8080808080800040); + break; + } + + if (elem_size != 0) + FAIL_IF(push_inst(compiler, 0xe70000000022 /* vlvg */ | F36(TMP_FREG1) | R32A(tmp0) | (1 << 16) | (3 << 12))); + + FAIL_IF(push_inst(compiler, 0xe70000000085 /* vbperm */ | F36(TMP_FREG1) | F32(freg) | F28(TMP_FREG1))); + + dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0; + FAIL_IF(push_inst(compiler, 0xe70000000021 /* vlgv */ | R36A(dst_r) | F32(TMP_FREG1) + | (elem_size == 0 ? ((3 << 16) | (1 << 12)) : (7 << 16)))); + + if (dst_r == tmp0) + return store_word(compiler, tmp0, dst, dstw, type & SLJIT_32); + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_ins ins = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + + if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + switch (SLJIT_SIMD_GET_OPCODE(type)) { + case SLJIT_SIMD_OP2_AND: + ins = 0xe70000000068 /* vn */; + break; + case SLJIT_SIMD_OP2_OR: + ins = 0xe7000000006a /* vo */; + break; + case SLJIT_SIMD_OP2_XOR: + ins = 0xe7000000006d /* vx */; + break; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + return push_inst(compiler, ins | F36(dst_freg) | F32(src1_freg) | F28(src2_freg)); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + SLJIT_SKIP_CHECKS(compiler); + return sljit_emit_op1(compiler, op, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_ins mask; + sljit_gpr tmp_r = gpr(temp_reg); + sljit_gpr mem_r = gpr(mem_reg); + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + + switch (GET_OPCODE(op)) { + case SLJIT_MOV32: + case SLJIT_MOV_U32: + return push_inst(compiler, 0xba000000 /* cs */ | R20A(tmp_r) | R16A(gpr(src_reg)) | R12A(mem_r)); + case SLJIT_MOV_U8: + mask = 0xff; + break; + case SLJIT_MOV_U16: + mask = 0xffff; + break; + default: + return push_inst(compiler, 0xeb0000000030 /* csg */ | R36A(tmp_r) | R32A(gpr(src_reg)) | R28A(mem_r)); + } + + /* tmp0 = (src_reg ^ tmp_r) & mask */ + FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | mask)); + FAIL_IF(push_inst(compiler, 0xb9e70000 /* xgrk */ | R4A(tmp0) | R0A(gpr(src_reg)) | R12A(tmp_r))); + FAIL_IF(push_inst(compiler, 0xa7090000 /* lghi */ | R20A(tmp_r) | 0xfffc)); + FAIL_IF(push_inst(compiler, 0xb9800000 /* ngr */ | R4A(tmp0) | R0A(tmp1))); + + /* tmp0 = tmp0 << (((mem_r ^ 0x3) & 0x3) << 3) */ + FAIL_IF(push_inst(compiler, 0xa50f0000 /* llill */ | R20A(tmp1) | (sljit_ins)((mask == 0xff) ? 0x18 : 0x10))); + FAIL_IF(push_inst(compiler, 0xb9800000 /* ngr */ | R4A(tmp_r) | R0A(mem_r))); + FAIL_IF(push_inst(compiler, 0xec0000000057 /* rxsbg */ | R36A(tmp1) | R32A(mem_r) | (59 << 24) | (60 << 16) | (3 << 8))); + FAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp0) | R32A(tmp0) | R28A(tmp1))); + + /* Already computed: tmp_r = mem_r & ~0x3 */ + + FAIL_IF(push_inst(compiler, 0x58000000 /* l */ | R20A(tmp1) | R12A(tmp_r))); + FAIL_IF(push_inst(compiler, 0x1700 /* x */ | R4A(tmp0) | R0A(tmp1))); + return push_inst(compiler, 0xba000000 /* cs */ | R20A(tmp1) | R16A(tmp0) | R12A(tmp_r)); +} + /* --------------------------------------------------------------------- */ /* Other instructions */ /* --------------------------------------------------------------------- */ diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c index 08da03026d4..ba4a1ebbc20 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_32.c @@ -62,21 +62,19 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw /* Both size flags cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); /* SSE2 and immediate is not possible. */ - SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); - SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) - && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) - && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); + SLJIT_ASSERT(a != SLJIT_IMM || !(flags & EX86_SSE2)); + SLJIT_ASSERT(((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) + & ((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0); + SLJIT_ASSERT((flags & (EX86_VEX_EXT | EX86_REX)) != EX86_VEX_EXT); size &= 0xf; - inst_size = size; + /* The mod r/m byte is always present. */ + inst_size = size + 1; - if (flags & (EX86_PREF_F2 | EX86_PREF_F3)) - inst_size++; - if (flags & EX86_PREF_66) + if (flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) inst_size++; /* Calculate size of b. */ - inst_size += 1; /* mod r/m byte. */ if (b & SLJIT_MEM) { if (!(b & REG_MASK)) inst_size += sizeof(sljit_sw); @@ -87,8 +85,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw inst_size += sizeof(sljit_s8); else inst_size += sizeof(sljit_sw); - } - else if (reg_map[b & REG_MASK] == 5) { + } else if (reg_map[b & REG_MASK] == 5) { /* Swap registers if possible. */ if ((b & OFFS_REG_MASK) && (immb & 0x3) == 0 && reg_map[OFFS_REG(b)] != 5) b = SLJIT_MEM | OFFS_REG(b) | TO_OFFS_REG(b & REG_MASK); @@ -105,15 +102,14 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw } /* Calculate size of a. */ - if (a & SLJIT_IMM) { + if (a == SLJIT_IMM) { if (flags & EX86_BIN_INS) { if (imma <= 127 && imma >= -128) { inst_size += 1; flags |= EX86_BYTE_ARG; } else inst_size += 4; - } - else if (flags & EX86_SHIFT_INS) { + } else if (flags & EX86_SHIFT_INS) { SLJIT_ASSERT(imma <= 0x1f); if (imma != 1) { inst_size++; @@ -125,8 +121,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw inst_size += sizeof(short); else inst_size += sizeof(sljit_sw); - } - else + } else SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size); @@ -136,27 +131,26 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw INC_SIZE(inst_size); if (flags & EX86_PREF_F2) *inst++ = 0xf2; - if (flags & EX86_PREF_F3) + else if (flags & EX86_PREF_F3) *inst++ = 0xf3; - if (flags & EX86_PREF_66) + else if (flags & EX86_PREF_66) *inst++ = 0x66; buf_ptr = inst + size; /* Encode mod/rm byte. */ if (!(flags & EX86_SHIFT_INS)) { - if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) + if ((flags & EX86_BIN_INS) && a == SLJIT_IMM) *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; - if (a & SLJIT_IMM) + if (a == SLJIT_IMM) *buf_ptr = 0; else if (!(flags & EX86_SSE2_OP1)) *buf_ptr = U8(reg_map[a] << 3); else - *buf_ptr = U8(a << 3); - } - else { - if (a & SLJIT_IMM) { + *buf_ptr = U8(freg_map[a] << 3); + } else { + if (a == SLJIT_IMM) { if (imma == 1) *inst = GROUP_SHIFT_1; else @@ -167,7 +161,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw } if (!(b & SLJIT_MEM)) { - *buf_ptr = U8(*buf_ptr | MOD_REG | (!(flags & EX86_SSE2_OP2) ? reg_map[b] : b)); + *buf_ptr = U8(*buf_ptr | MOD_REG | (!(flags & EX86_SSE2_OP2) ? reg_map[b] : freg_map[b])); buf_ptr++; } else if (b & REG_MASK) { reg_map_b = reg_map[b & REG_MASK]; @@ -183,8 +177,9 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw if (!(b & OFFS_REG_MASK)) *buf_ptr++ |= reg_map_b; else { - *buf_ptr++ |= 0x04; - *buf_ptr++ = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3)); + buf_ptr[0] |= 0x04; + buf_ptr[1] = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3)); + buf_ptr += 2; } if (immb != 0 || reg_map_b == 5) { @@ -195,25 +190,24 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw buf_ptr += sizeof(sljit_sw); } } - } - else { + } else { if (reg_map_b == 5) *buf_ptr |= 0x40; - *buf_ptr++ |= 0x04; - *buf_ptr++ = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3) | (immb << 6)); + buf_ptr[0] |= 0x04; + buf_ptr[1] = U8(reg_map_b | (reg_map[OFFS_REG(b)] << 3) | (immb << 6)); + buf_ptr += 2; if (reg_map_b == 5) *buf_ptr++ = 0; } - } - else { + } else { *buf_ptr++ |= 0x05; sljit_unaligned_store_sw(buf_ptr, immb); /* 32 bit displacement. */ buf_ptr += sizeof(sljit_sw); } - if (a & SLJIT_IMM) { + if (a == SLJIT_IMM) { if (flags & EX86_BYTE_ARG) *buf_ptr = U8(imma); else if (flags & EX86_HALF_ARG) @@ -222,7 +216,67 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw sljit_unaligned_store_sw(buf_ptr, imma); } - return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); + return inst; +} + +static sljit_s32 emit_vex_instruction(struct sljit_compiler *compiler, sljit_uw op, + /* The first and second register operand. */ + sljit_s32 a, sljit_s32 v, + /* The general operand (not immediate). */ + sljit_s32 b, sljit_sw immb) +{ + sljit_u8 *inst; + sljit_u8 vex = 0; + sljit_u8 vex_m = 0; + sljit_uw size; + + SLJIT_ASSERT(((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) + & ((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0); + + if (op & VEX_OP_0F38) + vex_m = 0x2; + else if (op & VEX_OP_0F3A) + vex_m = 0x3; + + if (op & VEX_W) { + if (vex_m == 0) + vex_m = 0x1; + + vex |= 0x80; + } + + if (op & EX86_PREF_66) + vex |= 0x1; + else if (op & EX86_PREF_F2) + vex |= 0x3; + else if (op & EX86_PREF_F3) + vex |= 0x2; + + op &= ~(EX86_PREF_66 | EX86_PREF_F2 | EX86_PREF_F3); + + if (op & VEX_256) + vex |= 0x4; + + vex = U8(vex | ((((op & VEX_SSE2_OPV) ? freg_map[v] : reg_map[v]) ^ 0xf) << 3)); + + size = op & ~(sljit_uw)0xff; + size |= (vex_m == 0) ? 3 : 4; + + inst = emit_x86_instruction(compiler, size, a, 0, b, immb); + FAIL_IF(!inst); + + if (vex_m == 0) { + inst[0] = 0xc5; + inst[1] = U8(vex | 0x80); + inst[2] = U8(op); + return SLJIT_SUCCESS; + } + + inst[0] = 0xc4; + inst[1] = U8(vex_m | 0xe0); + inst[2] = vex; + inst[3] = U8(op); + return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ @@ -578,8 +632,6 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler) { - sljit_u8 *inst; - CHECK_ERROR(); CHECK(check_sljit_emit_return_void(compiler)); @@ -588,11 +640,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler FAIL_IF(emit_stack_frame_release(compiler, 0)); - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - RET(); - return SLJIT_SUCCESS; + return emit_byte(compiler, RET_near); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler, @@ -782,7 +830,7 @@ static sljit_s32 tail_call_with_args(struct sljit_compiler *compiler, offset = stack_size + compiler->local_size; - if (!(src & SLJIT_IMM) && src != SLJIT_R0) { + if (src != SLJIT_IMM && src != SLJIT_R0) { if (word_arg_count >= 1) { EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R0, 0); r2_offset = sizeof(sljit_sw); @@ -836,7 +884,7 @@ static sljit_s32 tail_call_with_args(struct sljit_compiler *compiler, stack_size = args_size + SSIZE_OF(sw); - if (word_arg_count >= 1 && !(src & SLJIT_IMM) && src != SLJIT_R0) { + if (word_arg_count >= 1 && src != SLJIT_IMM && src != SLJIT_R0) { r2_offset = SSIZE_OF(sw); stack_size += SSIZE_OF(sw); } @@ -865,7 +913,7 @@ static sljit_s32 tail_call_with_args(struct sljit_compiler *compiler, EMIT_MOV(compiler, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), word_arg4_offset); } - if (!(src & SLJIT_IMM) && src != SLJIT_R0) { + if (src != SLJIT_IMM && src != SLJIT_R0) { if (word_arg_count >= 1) { SLJIT_ASSERT(r2_offset == sizeof(sljit_sw)); EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R0, 0); @@ -952,13 +1000,7 @@ static sljit_s32 emit_tail_call_end(struct sljit_compiler *compiler, sljit_s32 e sljit_u8 *inst; BINARY_IMM32(ADD, extra_space, SLJIT_SP, 0); - - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - RET(); - - return SLJIT_SUCCESS; + return emit_byte(compiler, RET_near); } static sljit_s32 tail_call_reg_arg_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types) @@ -1075,7 +1117,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi stack_size = type; FAIL_IF(tail_call_with_args(compiler, &stack_size, arg_types, src, srcw)); - if (!(src & SLJIT_IMM)) { + if (src != SLJIT_IMM) { src = SLJIT_R0; srcw = 0; } @@ -1142,30 +1184,20 @@ static SLJIT_INLINE sljit_s32 emit_fmov_before_return(struct sljit_compiler *com return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +static sljit_s32 emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { sljit_u8 *inst; - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - CHECK_EXTRA_REGS(dst, dstw, (void)0); - if (FAST_IS_REG(dst)) { - /* Unused dest is possible here. */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - - INC_SIZE(1); - POP_REG(reg_map[dst]); - return SLJIT_SUCCESS; - } + /* Unused dest is possible here. */ + if (FAST_IS_REG(dst)) + return emit_byte(compiler, U8(POP_r + reg_map[dst])); /* Memory. */ inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!inst); - *inst++ = POP_rm; + *inst = POP_rm; return SLJIT_SUCCESS; } @@ -1185,8 +1217,8 @@ static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src else { inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst |= PUSH_rm; + inst[0] = GROUP_FF; + inst[1] |= PUSH_rm; inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); @@ -1197,6 +1229,22 @@ static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src return SLJIT_SUCCESS; } +static sljit_s32 sljit_emit_get_return_address(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 options = compiler->options; + sljit_s32 saveds = compiler->saveds; + sljit_s32 scratches = compiler->scratches; + + saveds = ((scratches > 9 ? (scratches - 9) : 0) + (saveds <= 3 ? saveds : 3) - SLJIT_KEPT_SAVEDS_COUNT(options)) * SSIZE_OF(sw); + + /* Saving ebp. */ + if (!(options & SLJIT_ENTER_REG_ARG)) + saveds += SSIZE_OF(sw); + + return emit_mov(compiler, dst, dstw, SLJIT_MEM1(SLJIT_SP), compiler->local_size + saveds); +} + /* --------------------------------------------------------------------- */ /* Other operations */ /* --------------------------------------------------------------------- */ @@ -1279,6 +1327,283 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile return SLJIT_SUCCESS; } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; + sljit_u8 *inst, *jump_inst1, *jump_inst2; + sljit_uw size1, size2; + + /* Binary representation of 0x80000000. */ + static const sljit_f64 f64_high_bit = (sljit_f64)0x80000000ul; + + CHECK_EXTRA_REGS(src, srcw, (void)0); + + if (!(op & SLJIT_32)) { + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0); + FAIL_IF(!inst); + inst[1] |= ROL; + + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0); + FAIL_IF(!inst); + inst[1] |= SHR; + + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_PREF_F2 | EX86_SSE2_OP1, dst_r, TMP_REG1, 0)); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = U8(get_jump_code(SLJIT_NOT_CARRY) - 0x10); + + size1 = compiler->size; + FAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_PREF_F2 | EX86_SSE2, dst_r, SLJIT_MEM0(), (sljit_sw)&f64_high_bit)); + + inst[1] = U8(compiler->size - size1); + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, 0, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; + } + + if (!FAST_IS_REG(src)) { + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + src = TMP_REG1; + } + + BINARY_IMM32(CMP, 0, src, 0); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = JL_i8; + jump_inst1 = inst; + + size1 = compiler->size; + + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, src, 0)); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = JMP_i8; + jump_inst2 = inst; + + size2 = compiler->size; + + jump_inst1[1] = U8(size2 - size1); + + if (src != TMP_REG1) + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); + + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0); + FAIL_IF(!inst); + inst[1] |= SHR; + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = JNC_i8; + jump_inst1 = inst; + + size1 = compiler->size; + + BINARY_IMM32(OR, 1, TMP_REG1, 0); + jump_inst1[1] = U8(compiler->size - size1); + + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, TMP_REG1, 0)); + FAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, dst_r, 0)); + + jump_inst2[1] = U8(compiler->size - size2); + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) +{ + sljit_u8 *inst; + union { + sljit_s32 imm; + sljit_f32 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); + + u.value = value; + + if (u.imm != 0) + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + + inst[0] = GROUP_66; + inst[1] = GROUP_0F; + + if (u.imm == 0) { + inst[2] = PXOR_x_xm; + inst[3] = U8(freg | (freg << 3) | MOD_REG); + } else { + inst[2] = MOVD_x_rm; + inst[3] = U8(reg_map[TMP_REG1] | (freg << 3) | MOD_REG); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + sljit_u8 *inst; + sljit_s32 tmp_freg = freg; + union { + sljit_s32 imm[2]; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm[0] == 0) { + if (u.imm[1] == 0) + return emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, freg, freg, 0); + + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm[1]); + } else + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm[0]); + + FAIL_IF(emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, freg, TMP_REG1, 0)); + + if (u.imm[1] == 0) + return SLJIT_SUCCESS; + + if (u.imm[0] == 0) { + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!inst); + INC_SIZE(4); + + inst[0] = GROUP_0F; + inst[1] = SHUFPS_x_xm; + inst[2] = U8(MOD_REG | (freg << 3) | freg); + inst[3] = 0x51; + return SLJIT_SUCCESS; + } + + if (u.imm[0] != u.imm[1]) { + SLJIT_ASSERT(u.imm[1] != 0 && cpu_feature_list != 0); + + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm[1]); + + if (cpu_feature_list & CPU_FEATURE_SSE41) { + FAIL_IF(emit_groupf_ext(compiler, PINSRD_x_rm_i8 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2_OP1, freg, TMP_REG1, 0)); + return emit_byte(compiler, 1); + } + + FAIL_IF(emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, TMP_FREG, TMP_REG1, 0)); + tmp_freg = TMP_FREG; + } + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); + FAIL_IF(!inst); + INC_SIZE(3); + + inst[0] = GROUP_0F; + inst[1] = UNPCKLPS_x_xm; + inst[2] = U8(MOD_REG | (freg << 3) | tmp_freg); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_u8 *inst; + sljit_s32 reg2; + sljit_sw regw, reg2w; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + regw = 0; + reg2 = 0; + reg2w = 0; + + SLJIT_ASSERT(cpu_feature_list != 0); + + if (!(op & SLJIT_32) && (cpu_feature_list & CPU_FEATURE_SSE41)) { + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_FIRST(reg); + reg = REG_PAIR_SECOND(reg); + + CHECK_EXTRA_REGS(reg, regw, (void)0); + + FAIL_IF(emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x) + | EX86_PREF_66 | EX86_SSE2_OP1, freg, reg, regw)); + } else + reg2 = reg; + + CHECK_EXTRA_REGS(reg2, reg2w, (void)0); + + FAIL_IF(emit_groupf_ext(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? PINSRD_x_rm_i8 : PEXTRD_rm_x_i8) + | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2_OP1, freg, reg2, reg2w)); + return emit_byte(compiler, 1); + } + + if (reg & REG_PAIR_MASK) { + reg2 = REG_PAIR_SECOND(reg); + reg = REG_PAIR_FIRST(reg); + + if (reg == reg2) + reg = 0; + + CHECK_EXTRA_REGS(reg2, reg2w, (void)0); + } + + CHECK_EXTRA_REGS(reg, regw, (void)0); + + if (op & SLJIT_32) + return emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x) + | EX86_PREF_66 | EX86_SSE2_OP1, freg, reg, regw); + + if (op == SLJIT_COPY_FROM_F64) { + inst = (sljit_u8*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!inst); + INC_SIZE(5); + + inst[0] = GROUP_66; + inst[1] = GROUP_0F; + inst[2] = PSHUFD_x_xm; + inst[3] = U8(MOD_REG | (TMP_FREG << 3) | freg); + inst[4] = 1; + } else if (reg != 0) + FAIL_IF(emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, TMP_FREG, reg, regw)); + + if (reg2 != 0) + FAIL_IF(emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x) + | EX86_PREF_66 | EX86_SSE2_OP1, freg, reg2, reg2w)); + + if (GET_OPCODE(op) == SLJIT_COPY_TO_F64) { + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); + FAIL_IF(!inst); + INC_SIZE(3); + + inst[0] = GROUP_0F; + inst[1] = UNPCKLPS_x_xm; + inst[2] = U8(MOD_REG | (freg << 3) | (reg == 0 ? freg : TMP_FREG)); + } else + FAIL_IF(emit_groupf(compiler, MOVD_rm_x | EX86_PREF_66 | EX86_SSE2_OP1, TMP_FREG, reg, regw)); + + return SLJIT_SUCCESS; +} + static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler) { sljit_sw size; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c index 4e938ffcf31..f313f3f038f 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_64.c @@ -37,9 +37,9 @@ static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg, inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw)); FAIL_IF(!inst); INC_SIZE(2 + sizeof(sljit_sw)); - *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); - *inst++ = U8(MOV_r_i32 | (reg_map[reg] & 0x7)); - sljit_unaligned_store_sw(inst, imm); + inst[0] = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); + inst[1] = U8(MOV_r_i32 | reg_lmap[reg]); + sljit_unaligned_store_sw(inst + 2, imm); return SLJIT_SUCCESS; } @@ -72,7 +72,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw sljit_uw inst_size; /* The immediate operand must be 32 bit. */ - SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma)); + SLJIT_ASSERT(a != SLJIT_IMM || compiler->mode32 || IS_HALFWORD(imma)); /* Both cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); /* Size flags not allowed for typed instructions. */ @@ -80,26 +80,24 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw /* Both size flags cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BYTE_ARG | EX86_HALF_ARG)) != (EX86_BYTE_ARG | EX86_HALF_ARG)); /* SSE2 and immediate is not possible. */ - SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); - SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) - && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) - && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); + SLJIT_ASSERT(a != SLJIT_IMM || !(flags & EX86_SSE2)); + SLJIT_ASSERT(((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) + & ((flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0); + SLJIT_ASSERT((flags & (EX86_VEX_EXT | EX86_REX)) != EX86_VEX_EXT); size &= 0xf; - inst_size = size; + /* The mod r/m byte is always present. */ + inst_size = size + 1; if (!compiler->mode32 && !(flags & EX86_NO_REXW)) rex |= REX_W; else if (flags & EX86_REX) rex |= REX; - if (flags & (EX86_PREF_F2 | EX86_PREF_F3)) - inst_size++; - if (flags & EX86_PREF_66) + if (flags & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) inst_size++; /* Calculate size of b. */ - inst_size += 1; /* mod r/m byte. */ if (b & SLJIT_MEM) { if (!(b & OFFS_REG_MASK) && NOT_HALFWORD(immb)) { PTR_FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immb)); @@ -119,8 +117,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw inst_size += sizeof(sljit_s8); else inst_size += sizeof(sljit_s32); - } - else if (reg_lmap[b & REG_MASK] == 5) { + } else if (reg_lmap[b & REG_MASK] == 5) { /* Swap registers if possible. */ if ((b & OFFS_REG_MASK) && (immb & 0x3) == 0 && reg_lmap[OFFS_REG(b)] != 5) b = SLJIT_MEM | OFFS_REG(b) | TO_OFFS_REG(b & REG_MASK); @@ -140,23 +137,26 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw rex |= REX_X; } } - } - else if (!(flags & EX86_SSE2_OP2)) { + } else if (!(flags & EX86_SSE2_OP2)) { if (reg_map[b] >= 8) rex |= REX_B; - } - else if (freg_map[b] >= 8) + } else if (freg_map[b] >= 8) rex |= REX_B; - if (a & SLJIT_IMM) { + if ((flags & EX86_VEX_EXT) && (rex & 0x3)) { + SLJIT_ASSERT(size == 2); + size++; + inst_size++; + } + + if (a == SLJIT_IMM) { if (flags & EX86_BIN_INS) { if (imma <= 127 && imma >= -128) { inst_size += 1; flags |= EX86_BYTE_ARG; } else inst_size += 4; - } - else if (flags & EX86_SHIFT_INS) { + } else if (flags & EX86_SHIFT_INS) { SLJIT_ASSERT(imma <= (compiler->mode32 ? 0x1f : 0x3f)); if (imma != 1) { inst_size++; @@ -168,8 +168,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw inst_size += sizeof(short); else inst_size += sizeof(sljit_s32); - } - else { + } else { SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); /* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */ if (!(flags & EX86_SSE2_OP1)) { @@ -186,32 +185,34 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw inst = (sljit_u8*)ensure_buf(compiler, 1 + inst_size); PTR_FAIL_IF(!inst); - /* Encoding the byte. */ + /* Encoding prefixes. */ INC_SIZE(inst_size); if (flags & EX86_PREF_F2) *inst++ = 0xf2; - if (flags & EX86_PREF_F3) + else if (flags & EX86_PREF_F3) *inst++ = 0xf3; - if (flags & EX86_PREF_66) + else if (flags & EX86_PREF_66) *inst++ = 0x66; + + /* Rex is always the last prefix. */ if (rex) *inst++ = rex; + buf_ptr = inst + size; /* Encode mod/rm byte. */ if (!(flags & EX86_SHIFT_INS)) { - if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) + if ((flags & EX86_BIN_INS) && a == SLJIT_IMM) *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; - if (a & SLJIT_IMM) + if (a == SLJIT_IMM) *buf_ptr = 0; else if (!(flags & EX86_SSE2_OP1)) *buf_ptr = U8(reg_lmap[a] << 3); else *buf_ptr = U8(freg_lmap[a] << 3); - } - else { - if (a & SLJIT_IMM) { + } else { + if (a == SLJIT_IMM) { if (imma == 1) *inst = GROUP_SHIFT_1; else @@ -238,8 +239,9 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw if (!(b & OFFS_REG_MASK)) *buf_ptr++ |= reg_lmap_b; else { - *buf_ptr++ |= 0x04; - *buf_ptr++ = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3)); + buf_ptr[0] |= 0x04; + buf_ptr[1] = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3)); + buf_ptr += 2; } if (immb != 0 || reg_lmap_b == 5) { @@ -250,26 +252,26 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw buf_ptr += sizeof(sljit_s32); } } - } - else { + } else { if (reg_lmap_b == 5) *buf_ptr |= 0x40; - *buf_ptr++ |= 0x04; - *buf_ptr++ = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6)); + buf_ptr[0] |= 0x04; + buf_ptr[1] = U8(reg_lmap_b | (reg_lmap[OFFS_REG(b)] << 3) | (immb << 6)); + buf_ptr += 2; if (reg_lmap_b == 5) *buf_ptr++ = 0; } - } - else { - *buf_ptr++ |= 0x04; - *buf_ptr++ = 0x25; + } else { + buf_ptr[0] |= 0x04; + buf_ptr[1] = 0x25; + buf_ptr += 2; sljit_unaligned_store_s32(buf_ptr, (sljit_s32)immb); /* 32 bit displacement. */ buf_ptr += sizeof(sljit_s32); } - if (a & SLJIT_IMM) { + if (a == SLJIT_IMM) { if (flags & EX86_BYTE_ARG) *buf_ptr = U8(imma); else if (flags & EX86_HALF_ARG) @@ -278,7 +280,78 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw sljit_unaligned_store_s32(buf_ptr, (sljit_s32)imma); } - return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); + return inst; +} + +static sljit_s32 emit_vex_instruction(struct sljit_compiler *compiler, sljit_uw op, + /* The first and second register operand. */ + sljit_s32 a, sljit_s32 v, + /* The general operand (not immediate). */ + sljit_s32 b, sljit_sw immb) +{ + sljit_u8 *inst; + sljit_u8 vex = 0; + sljit_u8 vex_m = 0; + sljit_uw size; + + SLJIT_ASSERT(((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) + & ((op & (EX86_PREF_F2 | EX86_PREF_F3 | EX86_PREF_66)) - 1)) == 0); + + op |= EX86_REX; + + if (op & VEX_OP_0F38) + vex_m = 0x2; + else if (op & VEX_OP_0F3A) + vex_m = 0x3; + + if ((op & VEX_W) || ((op & VEX_AUTO_W) && !compiler->mode32)) { + if (vex_m == 0) + vex_m = 0x1; + + vex |= 0x80; + } + + if (op & EX86_PREF_66) + vex |= 0x1; + else if (op & EX86_PREF_F2) + vex |= 0x3; + else if (op & EX86_PREF_F3) + vex |= 0x2; + + op &= ~(EX86_PREF_66 | EX86_PREF_F2 | EX86_PREF_F3); + + if (op & VEX_256) + vex |= 0x4; + + vex = U8(vex | ((((op & VEX_SSE2_OPV) ? freg_map[v] : reg_map[v]) ^ 0xf) << 3)); + + size = op & ~(sljit_uw)0xff; + size |= (vex_m == 0) ? (EX86_VEX_EXT | 2) : 3; + + inst = emit_x86_instruction(compiler, size, a, 0, b, immb); + FAIL_IF(!inst); + + SLJIT_ASSERT((inst[-1] & 0xf0) == REX); + + /* If X or B is present in REX prefix. */ + if (vex_m == 0 && inst[-1] & 0x3) + vex_m = 0x1; + + if (vex_m == 0) { + vex |= U8(((inst[-1] >> 2) ^ 0x1) << 7); + + inst[-1] = 0xc5; + inst[0] = vex; + inst[1] = U8(op); + return SLJIT_SUCCESS; + } + + vex_m |= U8((inst[-1] ^ 0x7) << 5); + inst[-1] = 0xc4; + inst[0] = vex_m; + inst[1] = vex; + inst[2] = U8(op); + return SLJIT_SUCCESS; } /* --------------------------------------------------------------------- */ @@ -370,6 +443,12 @@ static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, slji return code_ptr; } +#ifdef _WIN64 +typedef struct { + sljit_sw regs[2]; +} sljit_sse2_reg; +#endif /* _WIN64 */ + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler, sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds, sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size) @@ -423,7 +502,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi #ifdef _WIN64 local_size += SLJIT_LOCALS_OFFSET; - saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, 16); + saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg); if (saved_float_regs_size > 0) { saved_float_regs_offset = ((local_size + 0xf) & ~0xf); @@ -532,16 +611,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi tmp = SLJIT_FS0 - fsaveds; for (i = SLJIT_FS0; i > tmp; i--) { - inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset); - *inst++ = GROUP_0F; - *inst = MOVAPS_xm_x; + FAIL_IF(emit_groupf(compiler, MOVAPS_xm_x | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset)); saved_float_regs_offset += 16; } for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) { - inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset); - *inst++ = GROUP_0F; - *inst = MOVAPS_xm_x; + FAIL_IF(emit_groupf(compiler, MOVAPS_xm_x | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset)); saved_float_regs_offset += 16; } } @@ -565,7 +640,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp #ifdef _WIN64 local_size += SLJIT_LOCALS_OFFSET; - saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, 16); + saved_float_regs_size = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg); if (saved_float_regs_size > 0) local_size = ((local_size + 0xf) & ~0xf) + saved_float_regs_size; @@ -591,7 +666,7 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit #endif /* _WIN64 */ #ifdef _WIN64 - saved_float_regs_offset = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, 16); + saved_float_regs_offset = GET_SAVED_FLOAT_REGISTERS_SIZE(fscratches, fsaveds, sse2_reg); if (saved_float_regs_offset > 0) { compiler->mode32 = 1; @@ -599,16 +674,12 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit tmp = SLJIT_FS0 - fsaveds; for (i = SLJIT_FS0; i > tmp; i--) { - inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset); - *inst++ = GROUP_0F; - *inst = MOVAPS_x_xm; + FAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset)); saved_float_regs_offset += 16; } for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) { - inst = emit_x86_instruction(compiler, 2 | EX86_SSE2, i, 0, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset); - *inst++ = GROUP_0F; - *inst = MOVAPS_x_xm; + FAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | EX86_SSE2, i, SLJIT_MEM1(SLJIT_SP), saved_float_regs_offset)); saved_float_regs_offset += 16; } @@ -656,20 +727,13 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler) { - sljit_u8 *inst; - CHECK_ERROR(); CHECK(check_sljit_emit_return_void(compiler)); compiler->mode32 = 0; FAIL_IF(emit_stack_frame_release(compiler, 0)); - - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - RET(); - return SLJIT_SUCCESS; + return emit_byte(compiler, RET_near); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler, @@ -863,22 +927,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi return sljit_emit_ijump(compiler, type, src, srcw); } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) +static sljit_s32 emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw) { sljit_u8 *inst; - CHECK_ERROR(); - CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw)); - ADJUST_LOCAL_OFFSET(dst, dstw); - if (FAST_IS_REG(dst)) { - if (reg_map[dst] < 8) { - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - POP_REG(reg_lmap[dst]); - return SLJIT_SUCCESS; - } + if (reg_map[dst] < 8) + return emit_byte(compiler, U8(POP_r + reg_lmap[dst])); inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); @@ -892,7 +947,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler * compiler->mode32 = 1; inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!inst); - *inst++ = POP_rm; + *inst = POP_rm; return SLJIT_SUCCESS; } @@ -922,8 +977,8 @@ static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src compiler->mode32 = 1; inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst |= PUSH_rm; + inst[0] = GROUP_FF; + inst[1] |= PUSH_rm; inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); FAIL_IF(!inst); @@ -934,6 +989,16 @@ static sljit_s32 emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src return SLJIT_SUCCESS; } +static sljit_s32 sljit_emit_get_return_address(struct sljit_compiler *compiler, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 saved_regs_size; + + compiler->mode32 = 0; + saved_regs_size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 0); + return emit_mov(compiler, dst, dstw, SLJIT_MEM1(SLJIT_SP), compiler->local_size + saved_regs_size); +} + /* --------------------------------------------------------------------- */ /* Other operations */ /* --------------------------------------------------------------------- */ @@ -1027,15 +1092,15 @@ static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign, compiler->mode32 = 0; - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { if (FAST_IS_REG(dst)) { - if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_i32; - return SLJIT_SUCCESS; - } - return emit_load_imm64(compiler, dst, srcw); + if (!sign || ((sljit_u32)srcw <= 0x7fffffff)) + return emit_do_imm32(compiler, reg_map[dst] <= 7 ? 0 : REX_B, U8(MOV_r_i32 | reg_lmap[dst]), srcw); + + inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw); + FAIL_IF(!inst); + *inst = MOV_rm_i32; + return SLJIT_SUCCESS; } compiler->mode32 = 1; inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw); @@ -1053,10 +1118,10 @@ static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign, if (sign) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw); FAIL_IF(!inst); - *inst++ = MOVSXD_r_rm; + *inst = MOVSXD_r_rm; } else { compiler->mode32 = 1; - FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw)); + EMIT_MOV(compiler, dst_r, 0, src, srcw); compiler->mode32 = 0; } } @@ -1072,6 +1137,203 @@ static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign, return SLJIT_SUCCESS; } +static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_uw(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; + sljit_u8 *inst, *jump_inst1, *jump_inst2; + sljit_uw size1, size2; + + compiler->mode32 = 0; + + if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_U32) { + if (src != SLJIT_IMM) { + compiler->mode32 = 1; + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + compiler->mode32 = 0; + } else + FAIL_IF(emit_do_imm32(compiler, reg_map[TMP_REG1] <= 7 ? 0 : REX_B, U8(MOV_r_i32 | reg_lmap[TMP_REG1]), srcw)); + + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, TMP_REG1, 0)); + + compiler->mode32 = 1; + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; + } + + if (!FAST_IS_REG(src)) { + EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); + src = TMP_REG1; + } + + BINARY_IMM32(CMP, 0, src, 0); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = JL_i8; + jump_inst1 = inst; + + size1 = compiler->size; + + compiler->mode32 = 0; + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, src, 0)); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = JMP_i8; + jump_inst2 = inst; + + size2 = compiler->size; + + jump_inst1[1] = U8(size2 - size1); + + if (src != TMP_REG1) + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); + + EMIT_MOV(compiler, TMP_REG2, 0, src, 0); + + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 1, TMP_REG1, 0); + FAIL_IF(!inst); + inst[1] |= SHR; + + compiler->mode32 = 1; + BINARY_IMM32(AND, 1, TMP_REG2, 0); + + compiler->mode32 = 0; + inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG2, 0); + FAIL_IF(!inst); + inst[0] = OR_r_rm; + + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, TMP_REG1, 0)); + compiler->mode32 = 1; + FAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, dst_r, 0)); + + jump_inst2[1] = U8(compiler->size - size2); + + if (dst_r == TMP_FREG) + return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); + return SLJIT_SUCCESS; +} + +static sljit_s32 sljit_emit_fset(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_u8 rex, sljit_s32 is_zero) +{ + sljit_u8 *inst; + sljit_u32 size; + + if (is_zero) { + rex = freg_map[freg] >= 8 ? (REX_R | REX_B) : 0; + } else { + if (freg_map[freg] >= 8) + rex |= REX_R; + if (reg_map[TMP_REG1] >= 8) + rex |= REX_B; + } + + size = (rex != 0) ? 5 : 4; + + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + + *inst++ = GROUP_66; + if (rex != 0) + *inst++ = rex; + inst[0] = GROUP_0F; + + if (is_zero) { + inst[1] = PXOR_x_xm; + inst[2] = U8(freg_lmap[freg] | (freg_lmap[freg] << 3) | MOD_REG); + } else { + inst[1] = MOVD_x_rm; + inst[2] = U8(reg_lmap[TMP_REG1] | (freg_lmap[freg] << 3) | MOD_REG); + } + + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f32 value) +{ + union { + sljit_s32 imm; + sljit_f32 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset32(compiler, freg, value)); + + u.value = value; + + if (u.imm != 0) { + compiler->mode32 = 1; + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm); + } + + return sljit_emit_fset(compiler, freg, 0, u.imm == 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *compiler, + sljit_s32 freg, sljit_f64 value) +{ + union { + sljit_sw imm; + sljit_f64 value; + } u; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fset64(compiler, freg, value)); + + u.value = value; + + if (u.imm != 0) { + compiler->mode32 = 0; + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, u.imm); + } + + return sljit_emit_fset(compiler, freg, REX_W, u.imm == 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 freg, sljit_s32 reg) +{ + sljit_u8 *inst; + sljit_u32 size; + sljit_u8 rex = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fcopy(compiler, op, freg, reg)); + + if (!(op & SLJIT_32)) + rex = REX_W; + + if (freg_map[freg] >= 8) + rex |= REX_R; + + if (reg_map[reg] >= 8) + rex |= REX_B; + + size = (rex != 0) ? 5 : 4; + + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + + *inst++ = GROUP_66; + if (rex != 0) + *inst++ = rex; + inst[0] = GROUP_0F; + inst[1] = GET_OPCODE(op) == SLJIT_COPY_TO_F64 ? MOVD_x_rm : MOVD_rm_x; + inst[2] = U8(reg_lmap[reg] | (freg_lmap[freg] << 3) | MOD_REG); + + return SLJIT_SUCCESS; +} + static sljit_s32 skip_frames_before_return(struct sljit_compiler *compiler) { sljit_s32 tmp, size; diff --git a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c index 651942be80a..c2c0421349b 100644 --- a/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c +++ b/src/3rdparty/pcre2/src/sljit/sljitNativeX86_common.c @@ -24,6 +24,12 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +#include +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ + SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { return "x86" SLJIT_CPUINFO; @@ -61,15 +67,18 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) 15 - R15 */ -#define TMP_FREG (0) +#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) +#define TMP_FREG (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -/* Last register + 1. */ -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { - 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 7, 6, 3, 4, 5 + 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 5, 7, 6, 4, 3 +}; + +static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = { + 0, 1, 2, 3, 4, 5, 6, 7, 0 }; #define CHECK_EXTRA_REGS(p, w, do) \ @@ -81,12 +90,10 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = { #else /* SLJIT_CONFIG_X86_32 */ -/* Last register + 1. */ -#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2) #define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3) /* Note: r12 & 0x7 == 0b100, which decoded as SIB byte present - Note: avoid to use r12 and r13 for memory addessing + Note: avoid to use r12 and r13 for memory addressing therefore r12 is better to be a higher saved register. */ #ifndef _WIN64 /* Args: rdi(=7), rsi(=6), rdx(=2), rcx(=1), r8, r9. Scratches: rax(=0), r10, r11 */ @@ -95,7 +102,7 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = { }; /* low-map. reg_map & 0x7. */ static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = { - 0, 0, 6, 7, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 1 + 0, 0, 6, 7, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 1 }; #else /* Args: rcx(=1), rdx(=2), r8, r9. Scratches: rax(=0), r10, r11 */ @@ -109,12 +116,12 @@ static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = { #endif /* Args: xmm0-xmm3 */ -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { - 4, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = { + 0, 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 4 }; /* low-map. freg_map & 0x7. */ -static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { - 4, 0, 1, 2, 3, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7 +static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = { + 0, 0, 1, 2, 3, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 4 }; #define REX_W 0x48 @@ -140,155 +147,237 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { #define U8(v) ((sljit_u8)(v)) - /* Size flags for emit_x86_instruction: */ -#define EX86_BIN_INS 0x0010 -#define EX86_SHIFT_INS 0x0020 -#define EX86_REX 0x0040 -#define EX86_NO_REXW 0x0080 -#define EX86_BYTE_ARG 0x0100 -#define EX86_HALF_ARG 0x0200 -#define EX86_PREF_66 0x0400 -#define EX86_PREF_F2 0x0800 -#define EX86_PREF_F3 0x1000 -#define EX86_SSE2_OP1 0x2000 -#define EX86_SSE2_OP2 0x4000 +#define EX86_BIN_INS ((sljit_uw)0x000010) +#define EX86_SHIFT_INS ((sljit_uw)0x000020) +#define EX86_BYTE_ARG ((sljit_uw)0x000040) +#define EX86_HALF_ARG ((sljit_uw)0x000080) +/* Size flags for both emit_x86_instruction and emit_vex_instruction: */ +#define EX86_REX ((sljit_uw)0x000100) +#define EX86_NO_REXW ((sljit_uw)0x000200) +#define EX86_PREF_66 ((sljit_uw)0x000400) +#define EX86_PREF_F2 ((sljit_uw)0x000800) +#define EX86_PREF_F3 ((sljit_uw)0x001000) +#define EX86_SSE2_OP1 ((sljit_uw)0x002000) +#define EX86_SSE2_OP2 ((sljit_uw)0x004000) #define EX86_SSE2 (EX86_SSE2_OP1 | EX86_SSE2_OP2) +#define EX86_VEX_EXT ((sljit_uw)0x008000) +/* Op flags for emit_vex_instruction: */ +#define VEX_OP_0F38 ((sljit_uw)0x010000) +#define VEX_OP_0F3A ((sljit_uw)0x020000) +#define VEX_SSE2_OPV ((sljit_uw)0x040000) +#define VEX_AUTO_W ((sljit_uw)0x080000) +#define VEX_W ((sljit_uw)0x100000) +#define VEX_256 ((sljit_uw)0x200000) + +#define EX86_SELECT_66(op) (((op) & SLJIT_32) ? 0 : EX86_PREF_66) +#define EX86_SELECT_F2_F3(op) (((op) & SLJIT_32) ? EX86_PREF_F3 : EX86_PREF_F2) /* --------------------------------------------------------------------- */ -/* Instrucion forms */ +/* Instruction forms */ /* --------------------------------------------------------------------- */ -#define ADD (/* BINARY */ 0 << 3) -#define ADD_EAX_i32 0x05 -#define ADD_r_rm 0x03 -#define ADD_rm_r 0x01 -#define ADDSD_x_xm 0x58 -#define ADC (/* BINARY */ 2 << 3) -#define ADC_EAX_i32 0x15 -#define ADC_r_rm 0x13 -#define ADC_rm_r 0x11 -#define AND (/* BINARY */ 4 << 3) -#define AND_EAX_i32 0x25 -#define AND_r_rm 0x23 -#define AND_rm_r 0x21 -#define ANDPD_x_xm 0x54 -#define BSR_r_rm (/* GROUP_0F */ 0xbd) -#define BSF_r_rm (/* GROUP_0F */ 0xbc) -#define CALL_i32 0xe8 -#define CALL_rm (/* GROUP_FF */ 2 << 3) -#define CDQ 0x99 -#define CMOVE_r_rm (/* GROUP_0F */ 0x44) -#define CMP (/* BINARY */ 7 << 3) -#define CMP_EAX_i32 0x3d -#define CMP_r_rm 0x3b -#define CMP_rm_r 0x39 -#define CVTPD2PS_x_xm 0x5a -#define CVTSI2SD_x_rm 0x2a -#define CVTTSD2SI_r_xm 0x2c -#define DIV (/* GROUP_F7 */ 6 << 3) -#define DIVSD_x_xm 0x5e -#define FLDS 0xd9 -#define FLDL 0xdd -#define FSTPS 0xd9 -#define FSTPD 0xdd -#define INT3 0xcc -#define IDIV (/* GROUP_F7 */ 7 << 3) -#define IMUL (/* GROUP_F7 */ 5 << 3) -#define IMUL_r_rm (/* GROUP_0F */ 0xaf) -#define IMUL_r_rm_i8 0x6b -#define IMUL_r_rm_i32 0x69 -#define JE_i8 0x74 -#define JNE_i8 0x75 -#define JMP_i8 0xeb -#define JMP_i32 0xe9 -#define JMP_rm (/* GROUP_FF */ 4 << 3) -#define LEA_r_m 0x8d -#define LOOP_i8 0xe2 -#define LZCNT_r_rm (/* GROUP_F3 */ /* GROUP_0F */ 0xbd) -#define MOV_r_rm 0x8b -#define MOV_r_i32 0xb8 -#define MOV_rm_r 0x89 -#define MOV_rm_i32 0xc7 -#define MOV_rm8_i8 0xc6 -#define MOV_rm8_r8 0x88 -#define MOVAPS_x_xm 0x28 -#define MOVAPS_xm_x 0x29 -#define MOVSD_x_xm 0x10 -#define MOVSD_xm_x 0x11 -#define MOVSXD_r_rm 0x63 -#define MOVSX_r_rm8 (/* GROUP_0F */ 0xbe) -#define MOVSX_r_rm16 (/* GROUP_0F */ 0xbf) -#define MOVZX_r_rm8 (/* GROUP_0F */ 0xb6) -#define MOVZX_r_rm16 (/* GROUP_0F */ 0xb7) -#define MUL (/* GROUP_F7 */ 4 << 3) -#define MULSD_x_xm 0x59 -#define NEG_rm (/* GROUP_F7 */ 3 << 3) -#define NOP 0x90 -#define NOT_rm (/* GROUP_F7 */ 2 << 3) -#define OR (/* BINARY */ 1 << 3) -#define OR_r_rm 0x0b -#define OR_EAX_i32 0x0d -#define OR_rm_r 0x09 -#define OR_rm8_r8 0x08 -#define POP_r 0x58 -#define POP_rm 0x8f -#define POPF 0x9d -#define PREFETCH 0x18 -#define PUSH_i32 0x68 -#define PUSH_r 0x50 -#define PUSH_rm (/* GROUP_FF */ 6 << 3) -#define PUSHF 0x9c -#define ROL (/* SHIFT */ 0 << 3) -#define ROR (/* SHIFT */ 1 << 3) -#define RET_near 0xc3 -#define RET_i16 0xc2 -#define SBB (/* BINARY */ 3 << 3) -#define SBB_EAX_i32 0x1d -#define SBB_r_rm 0x1b -#define SBB_rm_r 0x19 -#define SAR (/* SHIFT */ 7 << 3) -#define SHL (/* SHIFT */ 4 << 3) -#define SHLD (/* GROUP_0F */ 0xa5) -#define SHRD (/* GROUP_0F */ 0xad) -#define SHR (/* SHIFT */ 5 << 3) -#define SUB (/* BINARY */ 5 << 3) -#define SUB_EAX_i32 0x2d -#define SUB_r_rm 0x2b -#define SUB_rm_r 0x29 -#define SUBSD_x_xm 0x5c -#define TEST_EAX_i32 0xa9 -#define TEST_rm_r 0x85 -#define TZCNT_r_rm (/* GROUP_F3 */ /* GROUP_0F */ 0xbc) -#define UCOMISD_x_xm 0x2e -#define UNPCKLPD_x_xm 0x14 -#define XCHG_EAX_r 0x90 -#define XCHG_r_rm 0x87 -#define XOR (/* BINARY */ 6 << 3) -#define XOR_EAX_i32 0x35 -#define XOR_r_rm 0x33 -#define XOR_rm_r 0x31 -#define XORPD_x_xm 0x57 +#define ADD (/* BINARY */ 0 << 3) +#define ADD_EAX_i32 0x05 +#define ADD_r_rm 0x03 +#define ADD_rm_r 0x01 +#define ADDSD_x_xm 0x58 +#define ADC (/* BINARY */ 2 << 3) +#define ADC_EAX_i32 0x15 +#define ADC_r_rm 0x13 +#define ADC_rm_r 0x11 +#define AND (/* BINARY */ 4 << 3) +#define AND_EAX_i32 0x25 +#define AND_r_rm 0x23 +#define AND_rm_r 0x21 +#define ANDPD_x_xm 0x54 +#define BSR_r_rm (/* GROUP_0F */ 0xbd) +#define BSF_r_rm (/* GROUP_0F */ 0xbc) +#define BSWAP_r (/* GROUP_0F */ 0xc8) +#define CALL_i32 0xe8 +#define CALL_rm (/* GROUP_FF */ 2 << 3) +#define CDQ 0x99 +#define CMOVE_r_rm (/* GROUP_0F */ 0x44) +#define CMP (/* BINARY */ 7 << 3) +#define CMP_EAX_i32 0x3d +#define CMP_r_rm 0x3b +#define CMP_rm_r 0x39 +#define CMPS_x_xm 0xc2 +#define CMPXCHG_rm_r 0xb1 +#define CMPXCHG_rm8_r 0xb0 +#define CVTPD2PS_x_xm 0x5a +#define CVTPS2PD_x_xm 0x5a +#define CVTSI2SD_x_rm 0x2a +#define CVTTSD2SI_r_xm 0x2c +#define DIV (/* GROUP_F7 */ 6 << 3) +#define DIVSD_x_xm 0x5e +#define EXTRACTPS_x_xm 0x17 +#define FLDS 0xd9 +#define FLDL 0xdd +#define FSTPS 0xd9 +#define FSTPD 0xdd +#define INSERTPS_x_xm 0x21 +#define INT3 0xcc +#define IDIV (/* GROUP_F7 */ 7 << 3) +#define IMUL (/* GROUP_F7 */ 5 << 3) +#define IMUL_r_rm (/* GROUP_0F */ 0xaf) +#define IMUL_r_rm_i8 0x6b +#define IMUL_r_rm_i32 0x69 +#define JL_i8 0x7c +#define JE_i8 0x74 +#define JNC_i8 0x73 +#define JNE_i8 0x75 +#define JMP_i8 0xeb +#define JMP_i32 0xe9 +#define JMP_rm (/* GROUP_FF */ 4 << 3) +#define LEA_r_m 0x8d +#define LOOP_i8 0xe2 +#define LZCNT_r_rm (/* GROUP_F3 */ /* GROUP_0F */ 0xbd) +#define MOV_r_rm 0x8b +#define MOV_r_i32 0xb8 +#define MOV_rm_r 0x89 +#define MOV_rm_i32 0xc7 +#define MOV_rm8_i8 0xc6 +#define MOV_rm8_r8 0x88 +#define MOVAPS_x_xm 0x28 +#define MOVAPS_xm_x 0x29 +#define MOVD_x_rm 0x6e +#define MOVD_rm_x 0x7e +#define MOVDDUP_x_xm 0x12 +#define MOVDQA_x_xm 0x6f +#define MOVDQA_xm_x 0x7f +#define MOVHLPS_x_x 0x12 +#define MOVHPD_m_x 0x17 +#define MOVHPD_x_m 0x16 +#define MOVLHPS_x_x 0x16 +#define MOVLPD_m_x 0x13 +#define MOVLPD_x_m 0x12 +#define MOVMSKPS_r_x (/* GROUP_0F */ 0x50) +#define MOVQ_x_xm (/* GROUP_0F */ 0x7e) +#define MOVSD_x_xm 0x10 +#define MOVSD_xm_x 0x11 +#define MOVSHDUP_x_xm 0x16 +#define MOVSXD_r_rm 0x63 +#define MOVSX_r_rm8 (/* GROUP_0F */ 0xbe) +#define MOVSX_r_rm16 (/* GROUP_0F */ 0xbf) +#define MOVUPS_x_xm 0x10 +#define MOVZX_r_rm8 (/* GROUP_0F */ 0xb6) +#define MOVZX_r_rm16 (/* GROUP_0F */ 0xb7) +#define MUL (/* GROUP_F7 */ 4 << 3) +#define MULSD_x_xm 0x59 +#define NEG_rm (/* GROUP_F7 */ 3 << 3) +#define NOP 0x90 +#define NOT_rm (/* GROUP_F7 */ 2 << 3) +#define OR (/* BINARY */ 1 << 3) +#define OR_r_rm 0x0b +#define OR_EAX_i32 0x0d +#define OR_rm_r 0x09 +#define OR_rm8_r8 0x08 +#define ORPD_x_xm 0x56 +#define PACKSSWB_x_xm (/* GROUP_0F */ 0x63) +#define PAND_x_xm 0xdb +#define PCMPEQD_x_xm 0x76 +#define PINSRB_x_rm_i8 0x20 +#define PINSRW_x_rm_i8 0xc4 +#define PINSRD_x_rm_i8 0x22 +#define PEXTRB_rm_x_i8 0x14 +#define PEXTRW_rm_x_i8 0x15 +#define PEXTRD_rm_x_i8 0x16 +#define PMOVMSKB_r_x (/* GROUP_0F */ 0xd7) +#define PMOVSXBD_x_xm 0x21 +#define PMOVSXBQ_x_xm 0x22 +#define PMOVSXBW_x_xm 0x20 +#define PMOVSXDQ_x_xm 0x25 +#define PMOVSXWD_x_xm 0x23 +#define PMOVSXWQ_x_xm 0x24 +#define PMOVZXBD_x_xm 0x31 +#define PMOVZXBQ_x_xm 0x32 +#define PMOVZXBW_x_xm 0x30 +#define PMOVZXDQ_x_xm 0x35 +#define PMOVZXWD_x_xm 0x33 +#define PMOVZXWQ_x_xm 0x34 +#define POP_r 0x58 +#define POP_rm 0x8f +#define POPF 0x9d +#define POR_x_xm 0xeb +#define PREFETCH 0x18 +#define PSHUFB_x_xm 0x00 +#define PSHUFD_x_xm 0x70 +#define PSHUFLW_x_xm 0x70 +#define PSRLDQ_x 0x73 +#define PSLLD_x_i8 0x72 +#define PSLLQ_x_i8 0x73 +#define PUSH_i32 0x68 +#define PUSH_r 0x50 +#define PUSH_rm (/* GROUP_FF */ 6 << 3) +#define PUSHF 0x9c +#define PXOR_x_xm 0xef +#define ROL (/* SHIFT */ 0 << 3) +#define ROR (/* SHIFT */ 1 << 3) +#define RET_near 0xc3 +#define RET_i16 0xc2 +#define SBB (/* BINARY */ 3 << 3) +#define SBB_EAX_i32 0x1d +#define SBB_r_rm 0x1b +#define SBB_rm_r 0x19 +#define SAR (/* SHIFT */ 7 << 3) +#define SHL (/* SHIFT */ 4 << 3) +#define SHLD (/* GROUP_0F */ 0xa5) +#define SHRD (/* GROUP_0F */ 0xad) +#define SHR (/* SHIFT */ 5 << 3) +#define SHUFPS_x_xm 0xc6 +#define SUB (/* BINARY */ 5 << 3) +#define SUB_EAX_i32 0x2d +#define SUB_r_rm 0x2b +#define SUB_rm_r 0x29 +#define SUBSD_x_xm 0x5c +#define TEST_EAX_i32 0xa9 +#define TEST_rm_r 0x85 +#define TZCNT_r_rm (/* GROUP_F3 */ /* GROUP_0F */ 0xbc) +#define UCOMISD_x_xm 0x2e +#define UNPCKLPD_x_xm 0x14 +#define UNPCKLPS_x_xm 0x14 +#define VBROADCASTSD_x_xm 0x19 +#define VBROADCASTSS_x_xm 0x18 +#define VEXTRACTF128_x_ym 0x19 +#define VEXTRACTI128_x_ym 0x39 +#define VINSERTF128_y_y_xm 0x18 +#define VINSERTI128_y_y_xm 0x38 +#define VPBROADCASTB_x_xm 0x78 +#define VPBROADCASTD_x_xm 0x58 +#define VPBROADCASTQ_x_xm 0x59 +#define VPBROADCASTW_x_xm 0x79 +#define VPERMPD_y_ym 0x01 +#define VPERMQ_y_ym 0x00 +#define XCHG_EAX_r 0x90 +#define XCHG_r_rm 0x87 +#define XOR (/* BINARY */ 6 << 3) +#define XOR_EAX_i32 0x35 +#define XOR_r_rm 0x33 +#define XOR_rm_r 0x31 +#define XORPD_x_xm 0x57 -#define GROUP_0F 0x0f -#define GROUP_F3 0xf3 -#define GROUP_F7 0xf7 -#define GROUP_FF 0xff -#define GROUP_BINARY_81 0x81 -#define GROUP_BINARY_83 0x83 -#define GROUP_SHIFT_1 0xd1 -#define GROUP_SHIFT_N 0xc1 -#define GROUP_SHIFT_CL 0xd3 +#define GROUP_0F 0x0f +#define GROUP_66 0x66 +#define GROUP_F3 0xf3 +#define GROUP_F7 0xf7 +#define GROUP_FF 0xff +#define GROUP_BINARY_81 0x81 +#define GROUP_BINARY_83 0x83 +#define GROUP_SHIFT_1 0xd1 +#define GROUP_SHIFT_N 0xc1 +#define GROUP_SHIFT_CL 0xd3 +#define GROUP_LOCK 0xf0 -#define MOD_REG 0xc0 -#define MOD_DISP8 0x40 +#define MOD_REG 0xc0 +#define MOD_DISP8 0x40 -#define INC_SIZE(s) (*inst++ = U8(s), compiler->size += (s)) +#define INC_SIZE(s) (*inst++ = U8(s), compiler->size += (s)) -#define PUSH_REG(r) (*inst++ = U8(PUSH_r + (r))) -#define POP_REG(r) (*inst++ = U8(POP_r + (r))) -#define RET() (*inst++ = RET_near) -#define RET_I16(n) (*inst++ = RET_i16, *inst++ = U8(n), *inst++ = 0) +#define PUSH_REG(r) (*inst++ = U8(PUSH_r + (r))) +#define POP_REG(r) (*inst++ = U8(POP_r + (r))) +#define RET() (*inst++ = RET_near) +#define RET_I16(n) (*inst++ = RET_i16, *inst++ = U8(n), *inst++ = 0) /* Multithreading does not affect these static variables, since they store built-in CPU features. Therefore they can be overwritten by different threads @@ -297,9 +386,12 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = { #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) #define CPU_FEATURE_SSE2 0x002 #endif -#define CPU_FEATURE_LZCNT 0x004 -#define CPU_FEATURE_TZCNT 0x008 -#define CPU_FEATURE_CMOV 0x010 +#define CPU_FEATURE_SSE41 0x004 +#define CPU_FEATURE_LZCNT 0x008 +#define CPU_FEATURE_TZCNT 0x010 +#define CPU_FEATURE_CMOV 0x020 +#define CPU_FEATURE_AVX 0x040 +#define CPU_FEATURE_AVX2 0x080 static sljit_u32 cpu_feature_list = 0; @@ -332,124 +424,124 @@ static SLJIT_INLINE void sljit_unaligned_store_sw(void *addr, sljit_sw value) /* Utility functions */ /******************************************************/ -static void get_cpu_features(void) +static void execute_cpu_id(sljit_u32 info[4]) { - sljit_u32 feature_list = CPU_FEATURE_DETECTED; - sljit_u32 value; - #if defined(_MSC_VER) && _MSC_VER >= 1400 - int CPUInfo[4]; + __cpuidex((int*)info, (int)info[0], (int)info[2]); - __cpuid(CPUInfo, 0); - if (CPUInfo[0] >= 7) { - __cpuidex(CPUInfo, 7, 0); - if (CPUInfo[1] & 0x8) - feature_list |= CPU_FEATURE_TZCNT; - } - - __cpuid(CPUInfo, (int)0x80000001); - if (CPUInfo[2] & 0x20) - feature_list |= CPU_FEATURE_LZCNT; - - __cpuid(CPUInfo, 1); - value = (sljit_u32)CPUInfo[3]; - -#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) +#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__TINYC__) /* AT&T syntax. */ __asm__ ( - "movl $0x0, %%eax\n" - "lzcnt %%eax, %%eax\n" - "setnz %%al\n" - "movl %%eax, %0\n" - : "=g" (value) - : #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - : "eax" -#else - : "rax" -#endif - ); - - if (value & 0x1) - feature_list |= CPU_FEATURE_LZCNT; - - __asm__ ( - "movl $0x0, %%eax\n" - "tzcnt %%eax, %%eax\n" - "setnz %%al\n" - "movl %%eax, %0\n" - : "=g" (value) - : -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - : "eax" -#else - : "rax" -#endif - ); - - if (value & 0x1) - feature_list |= CPU_FEATURE_TZCNT; - - __asm__ ( - "movl $0x1, %%eax\n" -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - /* On x86-32, there is no red zone, so this - should work (no need for a local variable). */ - "push %%ebx\n" -#endif + "movl %0, %%esi\n" + "movl (%%esi), %%eax\n" + "movl 8(%%esi), %%ecx\n" + "pushl %%ebx\n" "cpuid\n" -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - "pop %%ebx\n" -#endif - "movl %%edx, %0\n" - : "=g" (value) + "movl %%eax, (%%esi)\n" + "movl %%ebx, 4(%%esi)\n" + "popl %%ebx\n" + "movl %%ecx, 8(%%esi)\n" + "movl %%edx, 12(%%esi)\n" +#else /* !SLJIT_CONFIG_X86_32 */ + "movq %0, %%rsi\n" + "movl (%%rsi), %%eax\n" + "movl 8(%%rsi), %%ecx\n" + "cpuid\n" + "movl %%eax, (%%rsi)\n" + "movl %%ebx, 4(%%rsi)\n" + "movl %%ecx, 8(%%rsi)\n" + "movl %%edx, 12(%%rsi)\n" +#endif /* SLJIT_CONFIG_X86_32 */ : + : "r" (info) #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - : "%eax", "%ecx", "%edx" -#else - : "%rax", "%rbx", "%rcx", "%rdx" -#endif + : "memory", "eax", "ecx", "edx", "esi" +#else /* !SLJIT_CONFIG_X86_32 */ + : "memory", "rax", "rbx", "rcx", "rdx", "rsi" +#endif /* SLJIT_CONFIG_X86_32 */ ); -#else /* _MSC_VER && _MSC_VER >= 1400 */ +#else /* _MSC_VER < 1400 */ /* Intel syntax. */ __asm { - mov eax, 0 - lzcnt eax, eax - setnz al - mov value, eax - } - - if (value & 0x1) - feature_list |= CPU_FEATURE_LZCNT; - - __asm { - mov eax, 0 - tzcnt eax, eax - setnz al - mov value, eax - } - - if (value & 0x1) - feature_list |= CPU_FEATURE_TZCNT; - - __asm { - mov eax, 1 +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + mov esi, info + mov eax, [esi] + mov ecx, [esi + 8] cpuid - mov value, edx + mov [esi], eax + mov [esi + 4], ebx + mov [esi + 8], ecx + mov [esi + 12], edx +#else /* !SLJIT_CONFIG_X86_32 */ + mov rsi, info + mov eax, [rsi] + mov ecx, [rsi + 8] + cpuid + mov [rsi], eax + mov [rsi + 4], ebx + mov [rsi + 8], ecx + mov [rsi + 12], edx +#endif /* SLJIT_CONFIG_X86_32 */ } #endif /* _MSC_VER && _MSC_VER >= 1400 */ +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) +__msan_unpoison(info, 4 * sizeof(sljit_u32)); +#endif /* __has_feature(memory_sanitizer) */ +#endif /* defined(__has_feature) */ + +} + +static void get_cpu_features(void) +{ + sljit_u32 feature_list = CPU_FEATURE_DETECTED; + sljit_u32 info[4]; + sljit_u32 max_id; + + info[0] = 0; + execute_cpu_id(info); + max_id = info[0]; + + if (max_id >= 7) { + info[0] = 7; + info[2] = 0; + execute_cpu_id(info); + + if (info[1] & 0x8) + feature_list |= CPU_FEATURE_TZCNT; + if (info[1] & 0x20) + feature_list |= CPU_FEATURE_AVX2; + } + + if (max_id >= 1) { + info[0] = 1; + execute_cpu_id(info); + + if (info[2] & 0x80000) + feature_list |= CPU_FEATURE_SSE41; + if (info[2] & 0x10000000) + feature_list |= CPU_FEATURE_AVX; #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) - if (value & 0x4000000) - feature_list |= CPU_FEATURE_SSE2; + if (info[3] & 0x4000000) + feature_list |= CPU_FEATURE_SSE2; #endif - if (value & 0x8000) - feature_list |= CPU_FEATURE_CMOV; + if (info[3] & 0x8000) + feature_list |= CPU_FEATURE_CMOV; + } + + info[0] = 0x80000001; + info[2] = 0; /* Silences an incorrect compiler warning. */ + execute_cpu_id(info); + + if (info[2] & 0x20) + feature_list |= CPU_FEATURE_LZCNT; cpu_feature_list = feature_list; } @@ -458,15 +550,15 @@ static sljit_u8 get_jump_code(sljit_uw type) { switch (type) { case SLJIT_EQUAL: + case SLJIT_ATOMIC_STORED: case SLJIT_F_EQUAL: case SLJIT_UNORDERED_OR_EQUAL: - case SLJIT_ORDERED_EQUAL: /* Not supported. */ return 0x84 /* je */; case SLJIT_NOT_EQUAL: + case SLJIT_ATOMIC_NOT_STORED: case SLJIT_F_NOT_EQUAL: case SLJIT_ORDERED_NOT_EQUAL: - case SLJIT_UNORDERED_OR_NOT_EQUAL: /* Not supported. */ return 0x85 /* jne */; case SLJIT_LESS: @@ -514,9 +606,11 @@ static sljit_u8 get_jump_code(sljit_uw type) return 0x81 /* jno */; case SLJIT_UNORDERED: + case SLJIT_ORDERED_EQUAL: /* NaN. */ return 0x8a /* jp */; case SLJIT_ORDERED: + case SLJIT_UNORDERED_OR_NOT_EQUAL: /* Not NaN. */ return 0x8b /* jpo */; } return 0; @@ -541,7 +635,7 @@ static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code label_addr = jump->u.target - (sljit_uw)executable_offset; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN) + if ((sljit_sw)(label_addr - (jump->addr + 2)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 6)) < HALFWORD_MIN) return generate_far_jump_code(jump, code_ptr); #endif @@ -737,7 +831,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) switch (feature_type) { case SLJIT_HAS_FPU: #ifdef SLJIT_IS_FPU_AVAILABLE - return SLJIT_IS_FPU_AVAILABLE; + return (SLJIT_IS_FPU_AVAILABLE) != 0; #elif (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) if (cpu_feature_list == 0) get_cpu_features(); @@ -768,19 +862,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) get_cpu_features(); return (cpu_feature_list & CPU_FEATURE_CMOV) != 0; + case SLJIT_HAS_REV: case SLJIT_HAS_ROT: case SLJIT_HAS_PREFETCH: + case SLJIT_HAS_COPY_F32: + case SLJIT_HAS_COPY_F64: + case SLJIT_HAS_ATOMIC: return 1; - case SLJIT_HAS_SSE2: -#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) +#if !(defined SLJIT_IS_FPU_AVAILABLE) || SLJIT_IS_FPU_AVAILABLE + case SLJIT_HAS_AVX: if (cpu_feature_list == 0) get_cpu_features(); - return (cpu_feature_list & CPU_FEATURE_SSE2) != 0; -#else /* !SLJIT_DETECT_SSE2 */ - return 1; -#endif /* SLJIT_DETECT_SSE2 */ - + return (cpu_feature_list & CPU_FEATURE_AVX) != 0; + case SLJIT_HAS_AVX2: + if (cpu_feature_list == 0) + get_cpu_features(); + return (cpu_feature_list & CPU_FEATURE_AVX2) != 0; + case SLJIT_HAS_SIMD: + if (cpu_feature_list == 0) + get_cpu_features(); + return (cpu_feature_list & CPU_FEATURE_SSE41) != 0; +#endif /* SLJIT_IS_FPU_AVAILABLE */ default: return 0; } @@ -788,16 +891,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type) SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) { - if (type < SLJIT_UNORDERED || type > SLJIT_ORDERED_LESS_EQUAL) - return 0; - switch (type) { case SLJIT_ORDERED_EQUAL: case SLJIT_UNORDERED_OR_NOT_EQUAL: - return 0; + return 2; } - return 1; + return 0; } /* --------------------------------------------------------------------- */ @@ -841,6 +941,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type) #endif /* SLJIT_CONFIG_X86_64 */ +static sljit_s32 emit_byte(struct sljit_compiler *compiler, sljit_u8 byte) +{ + sljit_u8 *inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!inst); + INC_SIZE(1); + *inst = byte; + return SLJIT_SUCCESS; +} + static sljit_s32 emit_mov(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw); @@ -848,6 +957,14 @@ static sljit_s32 emit_mov(struct sljit_compiler *compiler, #define EMIT_MOV(compiler, dst, dstw, src, srcw) \ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); +static sljit_s32 emit_groupf(struct sljit_compiler *compiler, + sljit_uw op, + sljit_s32 dst, sljit_s32 src, sljit_sw srcw); + +static sljit_s32 emit_groupf_ext(struct sljit_compiler *compiler, + sljit_uw op, + sljit_s32 dst, sljit_s32 src, sljit_sw srcw); + static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler, sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src); @@ -858,6 +975,10 @@ static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w); +static sljit_s32 emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_reg, + sljit_s32 src, sljit_sw srcw); + static SLJIT_INLINE sljit_s32 emit_endbranch(struct sljit_compiler *compiler) { #if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) @@ -866,14 +987,14 @@ static SLJIT_INLINE sljit_s32 emit_endbranch(struct sljit_compiler *compiler) inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); - *inst++ = 0xf3; - *inst++ = 0x0f; - *inst++ = 0x1e; + inst[0] = GROUP_F3; + inst[1] = GROUP_0F; + inst[2] = 0x1e; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *inst = 0xfb; -#else - *inst = 0xfa; -#endif + inst[3] = 0xfb; +#else /* !SLJIT_CONFIG_X86_32 */ + inst[3] = 0xfa; +#endif /* SLJIT_CONFIG_X86_32 */ #else /* !SLJIT_CONFIG_X86_CET */ SLJIT_UNUSED_ARG(compiler); #endif /* SLJIT_CONFIG_X86_CET */ @@ -896,13 +1017,17 @@ static SLJIT_INLINE sljit_s32 emit_rdssp(struct sljit_compiler *compiler, sljit_ inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); - *inst++ = 0xf3; + *inst++ = GROUP_F3; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B); #endif - *inst++ = 0x0f; - *inst++ = 0x1e; - *inst = (0x3 << 6) | (0x1 << 3) | (reg_map[reg] & 0x7); + inst[0] = GROUP_0F; + inst[1] = 0x1e; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + inst[2] = U8(MOD_REG | (0x1 << 3) | reg_lmap[reg]); +#else + inst[2] = U8(MOD_REG | (0x1 << 3) | reg_map[reg]); +#endif return SLJIT_SUCCESS; } @@ -920,13 +1045,13 @@ static SLJIT_INLINE sljit_s32 emit_incssp(struct sljit_compiler *compiler, sljit inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); - *inst++ = 0xf3; + *inst++ = GROUP_F3; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : REX_B); #endif - *inst++ = 0x0f; - *inst++ = 0xae; - *inst = (0x3 << 6) | (0x5 << 3) | (reg_map[reg] & 0x7); + inst[0] = GROUP_0F; + inst[1] = 0xae; + inst[2] = (0x3 << 6) | (0x5 << 3) | (reg_map[reg] & 0x7); return SLJIT_SUCCESS; } @@ -954,19 +1079,7 @@ static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compile FAIL_IF(emit_rdssp(compiler, TMP_REG1)); /* Load return address on shadow stack into TMP_REG1. */ -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - SLJIT_ASSERT(reg_map[TMP_REG1] == 5); - - /* Hand code unsupported "mov 0x0(%ebp),%ebp". */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); - FAIL_IF(!inst); - INC_SIZE(3); - *inst++ = 0x8b; - *inst++ = 0x6d; - *inst = 0; -#else /* !SLJIT_CONFIG_X86_32 */ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(TMP_REG1), 0); -#endif /* SLJIT_CONFIG_X86_32 */ /* Compare return address against TMP_REG1. */ FAIL_IF(emit_cmp_binary (compiler, TMP_REG1, 0, src, srcw)); @@ -994,8 +1107,8 @@ static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compile inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); - *inst++ = JMP_i8; - *inst = size_before_rdssp_inst - compiler->size; + inst[0] = JMP_i8; + inst[1] = size_before_rdssp_inst - compiler->size; *jz_after_cmp_inst = compiler->size - size_jz_after_cmp_inst; #else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */ @@ -1024,7 +1137,8 @@ static sljit_s32 emit_mov(struct sljit_compiler *compiler, *inst = MOV_rm_r; return SLJIT_SUCCESS; } - if (src & SLJIT_IMM) { + + if (src == SLJIT_IMM) { if (FAST_IS_REG(dst)) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw); @@ -1071,6 +1185,27 @@ static sljit_s32 emit_mov(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } +static sljit_s32 emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_reg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_u8* inst; + sljit_uw size; + + SLJIT_ASSERT(type >= SLJIT_EQUAL && type <= SLJIT_ORDERED_LESS_EQUAL); + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = U8(get_jump_code((sljit_uw)type ^ 0x1) - 0x10); + + size = compiler->size; + EMIT_MOV(compiler, dst_reg, 0, src, srcw); + + inst[1] = U8(compiler->size - size); + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { sljit_u8 *inst; @@ -1083,17 +1218,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile switch (GET_OPCODE(op)) { case SLJIT_BREAKPOINT: - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = INT3; - break; + return emit_byte(compiler, INT3); case SLJIT_NOP: - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = NOP; - break; + return emit_byte(compiler, NOP); case SLJIT_LMUL_UW: case SLJIT_LMUL_SW: case SLJIT_DIVMOD_UW: @@ -1134,23 +1261,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = CDQ; + FAIL_IF(emit_byte(compiler, CDQ)); #else - if (compiler->mode32) { - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = CDQ; - } else { + if (!compiler->mode32) { inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); - *inst++ = REX_W; - *inst = CDQ; - } + inst[0] = REX_W; + inst[1] = CDQ; + } else + FAIL_IF(emit_byte(compiler, CDQ)); #endif } @@ -1158,14 +1278,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); FAIL_IF(!inst); INC_SIZE(2); - *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); -#else + inst[0] = GROUP_F7; + inst[1] = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_map[TMP_REG1] : reg_map[SLJIT_R1]); +#else /* !SLJIT_CONFIG_X86_32 */ #ifdef _WIN64 size = (!compiler->mode32 || op >= SLJIT_DIVMOD_UW) ? 3 : 2; -#else +#else /* !_WIN64 */ size = (!compiler->mode32) ? 3 : 2; -#endif +#endif /* _WIN64 */ inst = (sljit_u8*)ensure_buf(compiler, 1 + size); FAIL_IF(!inst); INC_SIZE(size); @@ -1174,29 +1294,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile *inst++ = REX_W | ((op >= SLJIT_DIVMOD_UW) ? REX_B : 0); else if (op >= SLJIT_DIVMOD_UW) *inst++ = REX_B; - *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); -#else + inst[0] = GROUP_F7; + inst[1] = MOD_REG | ((op >= SLJIT_DIVMOD_UW) ? reg_lmap[TMP_REG1] : reg_lmap[SLJIT_R1]); +#else /* !_WIN64 */ if (!compiler->mode32) *inst++ = REX_W; - *inst++ = GROUP_F7; - *inst = MOD_REG | reg_map[SLJIT_R1]; -#endif -#endif + inst[0] = GROUP_F7; + inst[1] = MOD_REG | reg_map[SLJIT_R1]; +#endif /* _WIN64 */ +#endif /* SLJIT_CONFIG_X86_32 */ switch (op) { case SLJIT_LMUL_UW: - *inst |= MUL; + inst[1] |= MUL; break; case SLJIT_LMUL_SW: - *inst |= IMUL; + inst[1] |= IMUL; break; case SLJIT_DIVMOD_UW: case SLJIT_DIV_UW: - *inst |= DIV; + inst[1] |= DIV; break; case SLJIT_DIVMOD_SW: case SLJIT_DIV_SW: - *inst |= IDIV; + inst[1] |= IDIV; break; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) @@ -1216,29 +1336,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile return SLJIT_SUCCESS; } -#define ENCODE_PREFIX(prefix) \ - do { \ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); \ - FAIL_IF(!inst); \ - INC_SIZE(1); \ - *inst = U8(prefix); \ - } while (0) - static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { sljit_u8* inst; sljit_s32 dst_r; -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_s32 work_r; -#endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; #endif - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { if (FAST_IS_REG(dst)) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw); @@ -1267,100 +1376,33 @@ static sljit_s32 emit_mov_byte(struct sljit_compiler *compiler, sljit_s32 sign, #else dst_r = src; #endif - } + } else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - else if (FAST_IS_REG(src) && reg_map[src] >= 4) { - /* src, dst are registers. */ - SLJIT_ASSERT(FAST_IS_REG(dst)); - if (reg_map[dst] < 4) { - if (dst != src) - EMIT_MOV(compiler, dst, 0, src, 0); - inst = emit_x86_instruction(compiler, 2, dst, 0, dst, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; - } - else { - if (dst != src) - EMIT_MOV(compiler, dst, 0, src, 0); - if (sign) { - /* shl reg, 24 */ - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); - FAIL_IF(!inst); - *inst |= SHL; - /* sar reg, 24 */ - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); - FAIL_IF(!inst); - *inst |= SAR; - } - else { + if (FAST_IS_REG(src) && reg_map[src] >= 4) { + /* Both src and dst are registers. */ + SLJIT_ASSERT(FAST_IS_REG(dst)); + + if (src == dst && !sign) { inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0xff, dst, 0); FAIL_IF(!inst); *(inst + 1) |= AND; + return SLJIT_SUCCESS; } + + EMIT_MOV(compiler, TMP_REG1, 0, src, 0); + src = TMP_REG1; + srcw = 0; } - return SLJIT_SUCCESS; - } -#endif - else { +#endif /* !SLJIT_CONFIG_X86_32 */ + /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */ - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; + FAIL_IF(emit_groupf(compiler, sign ? MOVSX_r_rm8 : MOVZX_r_rm8, dst_r, src, srcw)); } if (dst & SLJIT_MEM) { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (dst_r == TMP_REG1) { - /* Find a non-used register, whose reg_map[src] < 4. */ - if ((dst & REG_MASK) == SLJIT_R0) { - if ((dst & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_R1)) - work_r = SLJIT_R2; - else - work_r = SLJIT_R1; - } - else { - if ((dst & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_R0)) - work_r = SLJIT_R0; - else if ((dst & REG_MASK) == SLJIT_R1) - work_r = SLJIT_R2; - else - work_r = SLJIT_R1; - } - - if (work_r == SLJIT_R0) { - ENCODE_PREFIX(XCHG_EAX_r | reg_map[TMP_REG1]); - } - else { - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); - FAIL_IF(!inst); - *inst = XCHG_r_rm; - } - - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_r8; - - if (work_r == SLJIT_R0) { - ENCODE_PREFIX(XCHG_EAX_r | reg_map[TMP_REG1]); - } - else { - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); - FAIL_IF(!inst); - *inst = XCHG_r_rm; - } - } - else { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_r8; - } -#else inst = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw); FAIL_IF(!inst); *inst = MOV_rm8_r8; -#endif } return SLJIT_SUCCESS; @@ -1377,15 +1419,15 @@ static sljit_s32 emit_prefetch(struct sljit_compiler *compiler, sljit_s32 op, inst = emit_x86_instruction(compiler, 2, 0, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst++ = PREFETCH; + inst[0] = GROUP_0F; + inst[1] = PREFETCH; if (op == SLJIT_PREFETCH_L1) - *inst |= (1 << 3); + inst[2] |= (1 << 3); else if (op == SLJIT_PREFETCH_L2) - *inst |= (2 << 3); + inst[2] |= (2 << 3); else if (op == SLJIT_PREFETCH_L3) - *inst |= (3 << 3); + inst[2] |= (3 << 3); return SLJIT_SUCCESS; } @@ -1401,7 +1443,7 @@ static sljit_s32 emit_mov_half(struct sljit_compiler *compiler, sljit_s32 sign, compiler->mode32 = 0; #endif - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { if (FAST_IS_REG(dst)) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) return emit_do_imm(compiler, MOV_r_i32 | reg_map[dst], srcw); @@ -1422,12 +1464,8 @@ static sljit_s32 emit_mov_half(struct sljit_compiler *compiler, sljit_s32 sign, if ((dst & SLJIT_MEM) && FAST_IS_REG(src)) dst_r = src; - else { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm16 : MOVZX_r_rm16; - } + else + FAIL_IF(emit_groupf(compiler, sign ? MOVSX_r_rm16 : MOVZX_r_rm16, dst_r, src, srcw)); if (dst & SLJIT_MEM) { inst = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw); @@ -1448,8 +1486,8 @@ static sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode, /* Same input and output */ inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; + inst[0] = GROUP_F7; + inst[1] |= opcode; return SLJIT_SUCCESS; } @@ -1457,46 +1495,16 @@ static sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode, EMIT_MOV(compiler, dst, 0, src, srcw); inst = emit_x86_instruction(compiler, 1, 0, 0, dst, 0); FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; + inst[0] = GROUP_F7; + inst[1] |= opcode; return SLJIT_SUCCESS; } EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; - EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); - return SLJIT_SUCCESS; -} - -static sljit_s32 emit_not_with_flags(struct sljit_compiler *compiler, - sljit_s32 dst, sljit_sw dstw, - sljit_s32 src, sljit_sw srcw) -{ - sljit_u8* inst; - - if (FAST_IS_REG(dst)) { - EMIT_MOV(compiler, dst, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0); - FAIL_IF(!inst); - *inst = OR_r_rm; - return SLJIT_SUCCESS; - } - - EMIT_MOV(compiler, TMP_REG1, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, TMP_REG1, 0); - FAIL_IF(!inst); - *inst = OR_r_rm; + inst[0] = GROUP_F7; + inst[1] |= opcode; EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); return SLJIT_SUCCESS; } @@ -1514,32 +1522,19 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 is_clz, sljit_s32 dst_r; sljit_sw max; - if (cpu_feature_list == 0) - get_cpu_features(); + SLJIT_ASSERT(cpu_feature_list != 0); dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; if (is_clz ? (cpu_feature_list & CPU_FEATURE_LZCNT) : (cpu_feature_list & CPU_FEATURE_TZCNT)) { - /* Group prefix added separately. */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst++ = GROUP_F3; - - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = is_clz ? LZCNT_r_rm : TZCNT_r_rm; + FAIL_IF(emit_groupf(compiler, (is_clz ? LZCNT_r_rm : TZCNT_r_rm) | EX86_PREF_F3, dst_r, src, srcw)); if (dst & SLJIT_MEM) EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); return SLJIT_SUCCESS; } - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = is_clz ? BSR_r_rm : BSF_r_rm; + FAIL_IF(emit_groupf(compiler, is_clz ? BSR_r_rm : BSF_r_rm, dst_r, src, srcw)); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) max = is_clz ? (32 + 31) : 32; @@ -1553,11 +1548,11 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 is_clz, inst = emit_x86_instruction(compiler, 2, dst_r, 0, SLJIT_MEM0(), is_clz ? (sljit_sw)&emit_clz_arg : (sljit_sw)&emit_ctz_arg); FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CMOVE_r_rm; + inst[0] = GROUP_0F; + inst[1] = CMOVE_r_rm; } else - FAIL_IF(sljit_emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max)); + FAIL_IF(emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max)); if (is_clz) { inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0); @@ -1572,14 +1567,9 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 is_clz, if (cpu_feature_list & CPU_FEATURE_CMOV) { EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, max); - - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CMOVE_r_rm; - } - else - FAIL_IF(sljit_emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max)); + FAIL_IF(emit_groupf(compiler, CMOVE_r_rm, dst_r, TMP_REG2, 0)); + } else + FAIL_IF(emit_cmov_generic(compiler, SLJIT_EQUAL, dst_r, SLJIT_IMM, max)); if (is_clz) { inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, max >> 1, dst_r, 0); @@ -1593,14 +1583,109 @@ static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 is_clz, return SLJIT_SUCCESS; } +static sljit_s32 emit_bswap(struct sljit_compiler *compiler, + sljit_s32 op, + sljit_s32 dst, sljit_sw dstw, + sljit_s32 src, sljit_sw srcw) +{ + sljit_u8 *inst; + sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + sljit_uw size; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + sljit_u8 rex = 0; +#else /* !SLJIT_CONFIG_X86_64 */ + sljit_s32 dst_is_ereg = op & SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (op == SLJIT_REV_U32 || op == SLJIT_REV_S32) + compiler->mode32 = 1; +#else /* !SLJIT_CONFIG_X86_64 */ + op &= ~SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (src != dst_r) { + /* Only the lower 16 bit is read for eregs. */ + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) + FAIL_IF(emit_mov_half(compiler, 0, dst_r, 0, src, srcw)); + else + EMIT_MOV(compiler, dst_r, 0, src, srcw); + } + + size = 2; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (!compiler->mode32) + rex = REX_W; + + if (reg_map[dst_r] >= 8) + rex |= REX_B; + + if (rex != 0) + size++; +#endif /* SLJIT_CONFIG_X86_64 */ + + inst = (sljit_u8*)ensure_buf(compiler, 1 + size); + FAIL_IF(!inst); + INC_SIZE(size); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (rex != 0) + *inst++ = rex; + + inst[0] = GROUP_0F; + inst[1] = BSWAP_r | reg_lmap[dst_r]; +#else /* !SLJIT_CONFIG_X86_64 */ + inst[0] = GROUP_0F; + inst[1] = BSWAP_r | reg_map[dst_r]; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + size = compiler->mode32 ? 16 : 48; +#else /* !SLJIT_CONFIG_X86_64 */ + size = 16; +#endif /* SLJIT_CONFIG_X86_64 */ + + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, (sljit_sw)size, dst_r, 0); + FAIL_IF(!inst); + if (op == SLJIT_REV_U16) + inst[1] |= SHR; + else + inst[1] |= SAR; + } + + if (dst & SLJIT_MEM) { +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst_is_ereg) + op = SLJIT_REV; +#endif /* SLJIT_CONFIG_X86_32 */ + if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) + return emit_mov_half(compiler, 0, dst, dstw, TMP_REG1, 0); + + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (op == SLJIT_REV_S32) { + compiler->mode32 = 0; + inst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0); + FAIL_IF(!inst); + *inst = MOVSXD_r_rm; + } +#endif /* SLJIT_CONFIG_X86_64 */ + + return SLJIT_SUCCESS; +} + SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { - sljit_s32 op_flags = GET_ALL_FLAGS(op); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) sljit_s32 dst_is_ereg = 0; -#endif +#else /* !SLJIT_CONFIG_X86_32 */ + sljit_s32 op_flags = GET_ALL_FLAGS(op); +#endif /* SLJIT_CONFIG_X86_32 */ CHECK_ERROR(); CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw)); @@ -1611,14 +1696,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile CHECK_EXTRA_REGS(src, srcw, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = op_flags & SLJIT_32; -#endif +#endif /* SLJIT_CONFIG_X86_64 */ op = GET_OPCODE(op); if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; -#endif +#endif /* SLJIT_CONFIG_X86_64 */ if (FAST_IS_REG(src) && src == dst) { if (!TYPE_CAST_NEEDED(op)) @@ -1631,14 +1716,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile if (op == SLJIT_MOV_S32) op = SLJIT_MOV_U32; } - else if (src & SLJIT_IMM) { + else if (src == SLJIT_IMM) { if (op == SLJIT_MOV_U32) op = SLJIT_MOV_S32; } } -#endif +#endif /* SLJIT_CONFIG_X86_64 */ - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { switch (op) { case SLJIT_MOV_U8: srcw = (sljit_u8)srcw; @@ -1659,12 +1744,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile case SLJIT_MOV_S32: srcw = (sljit_s32)srcw; break; -#endif +#endif /* SLJIT_CONFIG_X86_64 */ } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (SLJIT_UNLIKELY(dst_is_ereg)) return emit_mov(compiler, dst, dstw, src, srcw); -#endif +#endif /* SLJIT_CONFIG_X86_32 */ } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -1672,7 +1757,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_SP)); dst = TMP_REG1; } -#endif +#endif /* SLJIT_CONFIG_X86_32 */ switch (op) { case SLJIT_MOV: @@ -1681,7 +1766,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile case SLJIT_MOV_U32: case SLJIT_MOV_S32: case SLJIT_MOV32: -#endif +#endif /* SLJIT_CONFIG_X86_32 */ EMIT_MOV(compiler, dst, dstw, src, srcw); break; case SLJIT_MOV_U8: @@ -1708,25 +1793,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile EMIT_MOV(compiler, dst, dstw, src, srcw); compiler->mode32 = 0; break; -#endif +#endif /* SLJIT_CONFIG_X86_64 */ } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1) return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), dstw, TMP_REG1, 0); -#endif +#endif /* SLJIT_CONFIG_X86_32 */ return SLJIT_SUCCESS; } switch (op) { - case SLJIT_NOT: - if (SLJIT_UNLIKELY(op_flags & SLJIT_SET_Z)) - return emit_not_with_flags(compiler, dst, dstw, src, srcw); - return emit_unary(compiler, NOT_rm, dst, dstw, src, srcw); - case SLJIT_CLZ: case SLJIT_CTZ: return emit_clz_ctz(compiler, (op == SLJIT_CLZ), dst, dstw, src, srcw); + case SLJIT_REV: + case SLJIT_REV_U16: + case SLJIT_REV_S16: + case SLJIT_REV_U32: + case SLJIT_REV_S32: +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst_is_ereg) + op |= SLJIT_32; +#endif /* SLJIT_CONFIG_X86_32 */ + return emit_bswap(compiler, op, dst, dstw, src, srcw); } return SLJIT_SUCCESS; @@ -1745,7 +1835,7 @@ static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, sljit_u8 op_imm = U8(op_types & 0xff); if (dst == src1 && dstw == src1w) { - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else @@ -1779,7 +1869,7 @@ static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, /* Only for cumulative operations. */ if (dst == src2 && dstw == src2w) { - if (src1 & SLJIT_IMM) { + if (src1 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((dst == SLJIT_R0) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { #else @@ -1813,7 +1903,7 @@ static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, /* General version. */ if (FAST_IS_REG(dst)) { EMIT_MOV(compiler, dst, 0, src1, src1w); - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); } else { @@ -1825,7 +1915,7 @@ static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler, else { /* This version requires less memory writing. */ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); } else { @@ -1852,7 +1942,7 @@ static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler, sljit_u8 op_imm = U8(op_types & 0xff); if (dst == src1 && dstw == src1w) { - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((dst == SLJIT_R0) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else @@ -1886,7 +1976,7 @@ static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler, /* General version. */ if (FAST_IS_REG(dst) && dst != src2) { EMIT_MOV(compiler, dst, 0, src1, src1w); - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); } else { @@ -1898,7 +1988,7 @@ static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler, else { /* This version requires less memory writing. */ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, TMP_REG1, 0); } else { @@ -1921,20 +2011,12 @@ static sljit_s32 emit_mul(struct sljit_compiler *compiler, sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; /* Register destination. */ - if (dst_r == src1 && !(src2 & SLJIT_IMM)) { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; - } - else if (dst_r == src2 && !(src1 & SLJIT_IMM)) { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; - } - else if (src1 & SLJIT_IMM) { - if (src2 & SLJIT_IMM) { + if (dst_r == src1 && src2 != SLJIT_IMM) { + FAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, src2, src2w)); + } else if (dst_r == src2 && src1 != SLJIT_IMM) { + FAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, src1, src1w)); + } else if (src1 == SLJIT_IMM) { + if (src2 == SLJIT_IMM) { EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, src2w); src2 = dst_r; src2w = 0; @@ -1944,10 +2026,8 @@ static sljit_s32 emit_mul(struct sljit_compiler *compiler, inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); FAIL_IF(!inst); *inst = IMUL_r_rm_i8; - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = U8(src1w); + + FAIL_IF(emit_byte(compiler, U8(src1w))); } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { @@ -1973,30 +2053,26 @@ static sljit_s32 emit_mul(struct sljit_compiler *compiler, if (dst_r != src2) EMIT_MOV(compiler, dst_r, 0, src2, src2w); FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w)); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; + FAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, TMP_REG2, 0)); } #endif } - else if (src2 & SLJIT_IMM) { + else if (src2 == SLJIT_IMM) { /* Note: src1 is NOT immediate. */ if (src2w <= 127 && src2w >= -128) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i8; - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = U8(src2w); + + FAIL_IF(emit_byte(compiler, U8(src2w))); } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); @@ -2007,31 +2083,24 @@ static sljit_s32 emit_mul(struct sljit_compiler *compiler, inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); FAIL_IF(!inst); *inst = IMUL_r_rm_i32; + inst = (sljit_u8*)ensure_buf(compiler, 1 + 4); FAIL_IF(!inst); INC_SIZE(4); sljit_unaligned_store_s32(inst, (sljit_s32)src2w); - } - else { + } else { if (dst_r != src1) EMIT_MOV(compiler, dst_r, 0, src1, src1w); FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; + FAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, TMP_REG2, 0)); } #endif - } - else { + } else { /* Neither argument is immediate. */ if (ADDRESSING_DEPENDS_ON(src2, dst_r)) dst_r = TMP_REG1; EMIT_MOV(compiler, dst_r, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; + FAIL_IF(emit_groupf(compiler, IMUL_r_rm, dst_r, src2, src2w)); } if (dst & SLJIT_MEM) @@ -2064,10 +2133,10 @@ static sljit_s32 emit_lea_binary(struct sljit_compiler *compiler, done = 1; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if (src2 == SLJIT_IMM && (compiler->mode32 || IS_HALFWORD(src2w))) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_s32)src2w); #else - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w); #endif FAIL_IF(!inst); @@ -2077,10 +2146,10 @@ static sljit_s32 emit_lea_binary(struct sljit_compiler *compiler, } else if (FAST_IS_REG(src2)) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { + if (src1 == SLJIT_IMM && (compiler->mode32 || IS_HALFWORD(src1w))) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_s32)src1w); #else - if (src1 & SLJIT_IMM) { + if (src1 == SLJIT_IMM) { inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w); #endif FAIL_IF(!inst); @@ -2104,16 +2173,16 @@ static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler, sljit_u8* inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { + if (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(CMP_EAX_i32, src2w); return SLJIT_SUCCESS; } if (FAST_IS_REG(src1)) { - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { BINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0); } else { @@ -2124,15 +2193,15 @@ static sljit_s32 emit_cmp_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } - if (FAST_IS_REG(src2) && !(src1 & SLJIT_IMM)) { + if (FAST_IS_REG(src2) && src1 != SLJIT_IMM) { inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); FAIL_IF(!inst); *inst = CMP_rm_r; return SLJIT_SUCCESS; } - if (src2 & SLJIT_IMM) { - if (src1 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { + if (src1 == SLJIT_IMM) { EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); src1 = TMP_REG1; src1w = 0; @@ -2155,25 +2224,25 @@ static sljit_s32 emit_test_binary(struct sljit_compiler *compiler, sljit_u8* inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if (src1 == SLJIT_R0 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { + if (src1 == SLJIT_R0 && src2 == SLJIT_IMM && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(TEST_EAX_i32, src2w); return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { + if (src2 == SLJIT_R0 && src1 == SLJIT_IMM && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { #else - if (src2 == SLJIT_R0 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) { + if (src2 == SLJIT_R0 && src1 == SLJIT_IMM && (src1w > 127 || src1w < -128)) { #endif BINARY_EAX_IMM(TEST_EAX_i32, src1w); return SLJIT_SUCCESS; } - if (!(src1 & SLJIT_IMM)) { - if (src2 & SLJIT_IMM) { + if (src1 != SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src2w) || compiler->mode32) { inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w); @@ -2201,8 +2270,8 @@ static sljit_s32 emit_test_binary(struct sljit_compiler *compiler, } } - if (!(src2 & SLJIT_IMM)) { - if (src1 & SLJIT_IMM) { + if (src2 != SLJIT_IMM) { + if (src1 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src1w) || compiler->mode32) { inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, src2w); @@ -2231,7 +2300,7 @@ static sljit_s32 emit_test_binary(struct sljit_compiler *compiler, } EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src2w) || compiler->mode32) { inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REG1, 0); @@ -2269,18 +2338,18 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler, #endif sljit_u8* inst; - if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) { + if (src2 == SLJIT_IMM || src2 == SLJIT_PREF_SHIFT_REG) { if (dst == src1 && dstw == src1w) { inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; return SLJIT_SUCCESS; } if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) { EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); return SLJIT_SUCCESS; } @@ -2288,14 +2357,14 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler, EMIT_MOV(compiler, dst, 0, src1, src1w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; return SLJIT_SUCCESS; } EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REG1, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0); return SLJIT_SUCCESS; } @@ -2305,7 +2374,7 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler, EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; return emit_mov(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); } @@ -2323,7 +2392,7 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler, EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; #endif @@ -2349,7 +2418,7 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler, EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); FAIL_IF(!inst); - *inst |= mode; + inst[1] |= mode; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), 0); @@ -2372,7 +2441,7 @@ static sljit_s32 emit_shift_with_flags(struct sljit_compiler *compiler, sljit_s32 src2, sljit_sw src2w) { /* The CPU does not set flags if the shift count is 0. */ - if (src2 & SLJIT_IMM) { + if (src2 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) src2w &= compiler->mode32 ? 0x1f : 0x3f; #else /* !SLJIT_CONFIG_X86_64 */ @@ -2437,7 +2506,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return emit_unary(compiler, NEG_rm, dst, dstw, src2, src2w); if (!HAS_FLAGS(op)) { - if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED) + if (src2 == SLJIT_IMM && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED) return compiler->error; if (FAST_IS_REG(dst) && src2 == dst) { FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB), dst, 0, dst, 0, src1, src1w)); @@ -2459,6 +2528,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile return emit_cum_binary(compiler, BINARY_OPCODE(OR), dst, dstw, src1, src1w, src2, src2w); case SLJIT_XOR: + if (!HAS_FLAGS(op)) { + if (src2 == SLJIT_IMM && src2w == -1) + return emit_unary(compiler, NOT_rm, dst, dstw, src1, src1w); + if (src1 == SLJIT_IMM && src1w == -1) + return emit_unary(compiler, NOT_rm, dst, dstw, src2, src2w); + } + return emit_cum_binary(compiler, BINARY_OPCODE(XOR), dst, dstw, src1, src1w, src2, src2w); case SLJIT_SHL: @@ -2514,117 +2590,192 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op, - sljit_s32 src_dst, - sljit_s32 src1, sljit_sw src1w, - sljit_s32 src2, sljit_sw src2w) + sljit_s32 dst_reg, + sljit_s32 src1_reg, + sljit_s32 src2_reg, + sljit_s32 src3, sljit_sw src3w) { - sljit_s32 restore_ecx = 0; - sljit_s32 is_rotate, is_left; + sljit_s32 is_rotate, is_left, move_src1; sljit_u8* inst; + sljit_sw src1w = 0; sljit_sw dstw = 0; + /* The whole register must be saved even for 32 bit operations. */ + sljit_u8 restore_ecx = 0; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_s32 tmp2 = SLJIT_MEM1(SLJIT_SP); -#else /* !SLJIT_CONFIG_X86_32 */ - sljit_s32 tmp2 = TMP_REG2; + sljit_sw src2w = 0; + sljit_s32 restore_sp4 = 0; #endif /* SLJIT_CONFIG_X86_32 */ CHECK_ERROR(); - CHECK(check_sljit_emit_shift_into(compiler, op, src_dst, src1, src1w, src2, src2w)); - ADJUST_LOCAL_OFFSET(src1, src1w); - ADJUST_LOCAL_OFFSET(src2, src2w); + CHECK(check_sljit_emit_shift_into(compiler, op, dst_reg, src1_reg, src2_reg, src3, src3w)); + ADJUST_LOCAL_OFFSET(src3, src3w); - CHECK_EXTRA_REGS(src1, src1w, (void)0); - CHECK_EXTRA_REGS(src2, src2w, (void)0); + CHECK_EXTRA_REGS(dst_reg, dstw, (void)0); + CHECK_EXTRA_REGS(src3, src3w, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = op & SLJIT_32; -#endif +#endif /* SLJIT_CONFIG_X86_64 */ - if (src2 & SLJIT_IMM) { + if (src3 == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - src2w &= 0x1f; + src3w &= 0x1f; #else /* !SLJIT_CONFIG_X86_32 */ - src2w &= (op & SLJIT_32) ? 0x1f : 0x3f; + src3w &= (op & SLJIT_32) ? 0x1f : 0x3f; #endif /* SLJIT_CONFIG_X86_32 */ - if (src2w == 0) + if (src3w == 0) return SLJIT_SUCCESS; } is_left = (GET_OPCODE(op) == SLJIT_SHL || GET_OPCODE(op) == SLJIT_MSHL); - is_rotate = (src_dst == src1); - CHECK_EXTRA_REGS(src_dst, dstw, (void)0); + is_rotate = (src1_reg == src2_reg); + CHECK_EXTRA_REGS(src1_reg, src1w, (void)0); + CHECK_EXTRA_REGS(src2_reg, src2w, (void)0); if (is_rotate) - return emit_shift(compiler, is_left ? ROL : ROR, src_dst, dstw, src1, src1w, src2, src2w); + return emit_shift(compiler, is_left ? ROL : ROR, dst_reg, dstw, src1_reg, src1w, src3, src3w); - if ((src2 & SLJIT_IMM) || src2 == SLJIT_PREF_SHIFT_REG) { - if (!FAST_IS_REG(src1)) { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); - src1 = TMP_REG1; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (src2_reg & SLJIT_MEM) { + EMIT_MOV(compiler, TMP_REG1, 0, src2_reg, src2w); + src2_reg = TMP_REG1; + } +#endif /* SLJIT_CONFIG_X86_32 */ + + if (dst_reg == SLJIT_PREF_SHIFT_REG && src3 != SLJIT_IMM && (src3 != SLJIT_PREF_SHIFT_REG || src1_reg != SLJIT_PREF_SHIFT_REG)) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + EMIT_MOV(compiler, TMP_REG1, 0, src1_reg, src1w); + src1_reg = TMP_REG1; + src1w = 0; +#else /* !SLJIT_CONFIG_X86_64 */ + if (src2_reg != TMP_REG1) { + EMIT_MOV(compiler, TMP_REG1, 0, src1_reg, src1w); + src1_reg = TMP_REG1; + src1w = 0; + } else if ((src1_reg & SLJIT_MEM) || src1_reg == SLJIT_PREF_SHIFT_REG) { + restore_sp4 = (src3 == SLJIT_R0) ? SLJIT_R1 : SLJIT_R0; + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), restore_sp4, 0); + EMIT_MOV(compiler, restore_sp4, 0, src1_reg, src1w); + src1_reg = restore_sp4; + src1w = 0; + } else { + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), src1_reg, 0); + restore_sp4 = src1_reg; } - } else if (FAST_IS_REG(src1)) { -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 0; -#endif - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0); -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = op & SLJIT_32; -#endif - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); +#endif /* SLJIT_CONFIG_X86_64 */ - if (src1 == SLJIT_PREF_SHIFT_REG) - src1 = TMP_REG1; - - if (src_dst == SLJIT_PREF_SHIFT_REG) - src_dst = TMP_REG1; - - restore_ecx = 1; + if (src3 != SLJIT_PREF_SHIFT_REG) + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src3, src3w); } else { - EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + if (src2_reg == SLJIT_PREF_SHIFT_REG && src3 != SLJIT_IMM && src3 != SLJIT_PREF_SHIFT_REG) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 0; -#endif - EMIT_MOV(compiler, tmp2, 0, SLJIT_PREF_SHIFT_REG, 0); + compiler->mode32 = 0; +#endif /* SLJIT_CONFIG_X86_64 */ + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = op & SLJIT_32; -#endif - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w); - - src1 = TMP_REG1; - - if (src_dst == SLJIT_PREF_SHIFT_REG) { - src_dst = tmp2; - SLJIT_ASSERT(dstw == 0); + compiler->mode32 = op & SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ + src2_reg = TMP_REG1; + restore_ecx = 1; } - restore_ecx = 2; + move_src1 = 0; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (dst_reg != src1_reg) { + if (dst_reg != src3) { + EMIT_MOV(compiler, dst_reg, 0, src1_reg, src1w); + src1_reg = dst_reg; + src1w = 0; + } else + move_src1 = 1; + } +#else /* !SLJIT_CONFIG_X86_64 */ + if (dst_reg & SLJIT_MEM) { + if (src2_reg != TMP_REG1) { + EMIT_MOV(compiler, TMP_REG1, 0, src1_reg, src1w); + src1_reg = TMP_REG1; + src1w = 0; + } else if ((src1_reg & SLJIT_MEM) || src1_reg == SLJIT_PREF_SHIFT_REG) { + restore_sp4 = (src3 == SLJIT_R0) ? SLJIT_R1 : SLJIT_R0; + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), restore_sp4, 0); + EMIT_MOV(compiler, restore_sp4, 0, src1_reg, src1w); + src1_reg = restore_sp4; + src1w = 0; + } else { + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32), src1_reg, 0); + restore_sp4 = src1_reg; + } + } else if (dst_reg != src1_reg) { + if (dst_reg != src3) { + EMIT_MOV(compiler, dst_reg, 0, src1_reg, src1w); + src1_reg = dst_reg; + src1w = 0; + } else + move_src1 = 1; + } +#endif /* SLJIT_CONFIG_X86_64 */ + + if (src3 != SLJIT_IMM && src3 != SLJIT_PREF_SHIFT_REG) { + if (!restore_ecx) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0); + compiler->mode32 = op & SLJIT_32; + restore_ecx = 1; +#else /* !SLJIT_CONFIG_X86_64 */ + if (src1_reg != TMP_REG1 && src2_reg != TMP_REG1) { + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0); + restore_ecx = 1; + } else { + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_PREF_SHIFT_REG, 0); + restore_ecx = 2; + } +#endif /* SLJIT_CONFIG_X86_64 */ + } + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src3, src3w); + } + + if (move_src1) { + EMIT_MOV(compiler, dst_reg, 0, src1_reg, src1w); + src1_reg = dst_reg; + src1w = 0; + } } - inst = emit_x86_instruction(compiler, 2, src1, 0, src_dst, dstw); + inst = emit_x86_instruction(compiler, 2, src2_reg, 0, src1_reg, src1w); FAIL_IF(!inst); inst[0] = GROUP_0F; - if (src2 & SLJIT_IMM) { + if (src3 == SLJIT_IMM) { inst[1] = U8((is_left ? SHLD : SHRD) - 1); - /* Immedate argument is added separately. */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = U8(src2w); + /* Immediate argument is added separately. */ + FAIL_IF(emit_byte(compiler, U8(src3w))); } else inst[1] = U8(is_left ? SHLD : SHRD); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = 0; -#endif + if (restore_ecx) { + compiler->mode32 = 0; + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); + } - if (restore_ecx == 1) - return emit_mov(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0); - if (restore_ecx == 2) - return emit_mov(compiler, SLJIT_PREF_SHIFT_REG, 0, tmp2, 0); + if (src1_reg != dst_reg) { + compiler->mode32 = op & SLJIT_32; + return emit_mov(compiler, dst_reg, dstw, src1_reg, 0); + } +#else /* !SLJIT_CONFIG_X86_64 */ + if (restore_ecx) + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, restore_ecx == 1 ? TMP_REG1 : SLJIT_MEM1(SLJIT_SP), 0); + + if (src1_reg != dst_reg) + EMIT_MOV(compiler, dst_reg, dstw, src1_reg, 0); + + if (restore_sp4) + return emit_mov(compiler, restore_sp4, 0, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_s32)); +#endif /* SLJIT_CONFIG_X86_32 */ return SLJIT_SUCCESS; } @@ -2656,24 +2807,41 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst, sljit_sw dstw) { - CHECK_REG_INDEX(check_sljit_get_register_index(reg)); -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (reg >= SLJIT_R3 && reg <= SLJIT_R8) - return -1; -#endif - return reg_map[reg]; + CHECK_ERROR(); + CHECK(check_sljit_emit_op_dst(compiler, op, dst, dstw)); + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + + switch (op) { + case SLJIT_FAST_ENTER: + return emit_fast_enter(compiler, dst, dstw); + case SLJIT_GET_RETURN_ADDRESS: + return sljit_emit_get_return_address(compiler, dst, dstw); + } + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg) +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, sljit_s32 reg) { - CHECK_REG_INDEX(check_sljit_get_float_register_index(reg)); + CHECK_REG_INDEX(check_sljit_get_register_index(type, reg)); + + if (type == SLJIT_GP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - return reg; -#else + if (reg >= SLJIT_R3 && reg <= SLJIT_R8) + return -1; +#endif /* SLJIT_CONFIG_X86_32 */ + return reg_map[reg]; + } + + if (type != SLJIT_FLOAT_REGISTER && type != SLJIT_SIMD_REG_128 && type != SLJIT_SIMD_REG_256 && type != SLJIT_SIMD_REG_512) + return -1; + return freg_map[reg]; -#endif } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler, @@ -2701,6 +2869,8 @@ static sljit_u32 *sse2_buffer; static void init_compiler(void) { + get_cpu_features(); + /* Align to 16 bytes. */ sse2_buffer = (sljit_u32*)(((sljit_uw)sse2_data + 15) & ~(sljit_uw)0xf); @@ -2714,58 +2884,60 @@ static void init_compiler(void) sse2_buffer[13] = 0x7fffffff; } -static sljit_s32 emit_sse2(struct sljit_compiler *compiler, sljit_u8 opcode, - sljit_s32 single, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w) +static sljit_s32 emit_groupf(struct sljit_compiler *compiler, + sljit_uw op, + sljit_s32 dst, sljit_s32 src, sljit_sw srcw) { - sljit_u8 *inst; - - inst = emit_x86_instruction(compiler, 2 | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + sljit_u8 *inst = emit_x86_instruction(compiler, 2 | (op & ~(sljit_uw)0xff), dst, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = opcode; + inst[0] = GROUP_0F; + inst[1] = op & 0xff; return SLJIT_SUCCESS; } -static sljit_s32 emit_sse2_logic(struct sljit_compiler *compiler, sljit_u8 opcode, - sljit_s32 pref66, sljit_s32 xmm1, sljit_s32 xmm2, sljit_sw xmm2w) +static sljit_s32 emit_groupf_ext(struct sljit_compiler *compiler, + sljit_uw op, + sljit_s32 dst, sljit_s32 src, sljit_sw srcw) { sljit_u8 *inst; - inst = emit_x86_instruction(compiler, 2 | (pref66 ? EX86_PREF_66 : 0) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + SLJIT_ASSERT((op & EX86_SSE2) && ((op & VEX_OP_0F38) || (op & VEX_OP_0F3A))); + + inst = emit_x86_instruction(compiler, 3 | (op & ~((sljit_uw)0xff | VEX_OP_0F38 | VEX_OP_0F3A)), dst, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = opcode; + inst[0] = GROUP_0F; + inst[1] = U8((op & VEX_OP_0F38) ? 0x38 : 0x3A); + inst[2] = op & 0xff; return SLJIT_SUCCESS; } static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler, sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw) { - return emit_sse2(compiler, MOVSD_x_xm, single, dst, src, srcw); + return emit_groupf(compiler, MOVSD_x_xm | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, dst, src, srcw); } static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler, sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src) { - return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw); + return emit_groupf(compiler, MOVSD_xm_x | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, src, dst, dstw); } static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw) { - sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; - sljit_u8 *inst; + sljit_s32 dst_r; + + CHECK_EXTRA_REGS(dst, dstw, (void)0); + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (GET_OPCODE(op) == SLJIT_CONV_SW_FROM_F64) compiler->mode32 = 0; #endif - inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_32) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CVTTSD2SI_r_xm; + FAIL_IF(emit_groupf(compiler, CVTTSD2SI_r_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP2, dst_r, src, srcw)); if (dst & SLJIT_MEM) return emit_mov(compiler, dst, dstw, TMP_REG1, 0); @@ -2777,14 +2949,15 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG; - sljit_u8 *inst; + + CHECK_EXTRA_REGS(src, srcw, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) compiler->mode32 = 0; #endif - if (src & SLJIT_IMM) { + if (src == SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) srcw = (sljit_s32)srcw; @@ -2794,10 +2967,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp srcw = 0; } - inst = emit_x86_instruction(compiler, 2 | ((op & SLJIT_32) ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2_OP1, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CVTSI2SD_x_rm; + FAIL_IF(emit_groupf(compiler, CVTSI2SD_x_rm | EX86_SELECT_F2_F3(op) | EX86_SSE2_OP1, dst_r, src, srcw)); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; @@ -2812,16 +2982,28 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile sljit_s32 src2, sljit_sw src2w) { switch (GET_FLAG_TYPE(op)) { + case SLJIT_ORDERED_EQUAL: + /* Also: SLJIT_UNORDERED_OR_NOT_EQUAL */ + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w)); + FAIL_IF(emit_groupf(compiler, CMPS_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, TMP_FREG, src2, src2w)); + + /* EQ */ + FAIL_IF(emit_byte(compiler, 0)); + + src1 = TMP_FREG; + src2 = TMP_FREG; + src2w = 0; + break; + case SLJIT_ORDERED_LESS: - case SLJIT_UNORDERED_OR_GREATER_EQUAL: case SLJIT_UNORDERED_OR_GREATER: - case SLJIT_ORDERED_LESS_EQUAL: + /* Also: SLJIT_UNORDERED_OR_GREATER_EQUAL, SLJIT_ORDERED_LESS_EQUAL */ if (!FAST_IS_REG(src2)) { FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src2, src2w)); src2 = TMP_FREG; } - return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_32), src2, src1, src1w); + return emit_groupf(compiler, UCOMISD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, src2, src1, src1w); } if (!FAST_IS_REG(src1)) { @@ -2829,7 +3011,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile src1 = TMP_FREG; } - return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_32), src1, src2, src2w); + return emit_groupf(compiler, UCOMISD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, src1, src2, src2w); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, @@ -2837,6 +3019,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil sljit_s32 src, sljit_sw srcw) { sljit_s32 dst_r; + sljit_u8 *inst; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 1; @@ -2860,42 +3043,57 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil /* We overwrite the high bits of source. From SLJIT point of view, this is not an issue. Note: In SSE3, we could also use MOVDDUP and MOVSLDUP. */ - FAIL_IF(emit_sse2_logic(compiler, UNPCKLPD_x_xm, op & SLJIT_32, src, src, 0)); - } - else { + FAIL_IF(emit_groupf(compiler, UNPCKLPD_x_xm | ((op & SLJIT_32) ? EX86_PREF_66 : 0) | EX86_SSE2, src, src, 0)); + } else { FAIL_IF(emit_sse2_load(compiler, !(op & SLJIT_32), TMP_FREG, src, srcw)); src = TMP_FREG; } - FAIL_IF(emit_sse2_logic(compiler, CVTPD2PS_x_xm, op & SLJIT_32, dst_r, src, 0)); + FAIL_IF(emit_groupf(compiler, CVTPD2PS_x_xm | ((op & SLJIT_32) ? EX86_PREF_66 : 0) | EX86_SSE2, dst_r, src, 0)); if (dst_r == TMP_FREG) return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } if (FAST_IS_REG(dst)) { - dst_r = dst; - if (dst != src) - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src, srcw)); - } - else { - dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src, srcw)); + dst_r = (dst == src) ? TMP_FREG : dst; + + if (src & SLJIT_MEM) + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src, srcw)); + + FAIL_IF(emit_groupf(compiler, PCMPEQD_x_xm | EX86_PREF_66 | EX86_SSE2, dst_r, dst_r, 0)); + + inst = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2_OP2, 0, 0, dst_r, 0); + inst[0] = GROUP_0F; + /* Same as PSRLD_x / PSRLQ_x */ + inst[1] = (op & SLJIT_32) ? PSLLD_x_i8 : PSLLQ_x_i8; + + if (GET_OPCODE(op) == SLJIT_ABS_F64) { + inst[2] |= 2 << 3; + FAIL_IF(emit_byte(compiler, 1)); + } else { + inst[2] |= 6 << 3; + FAIL_IF(emit_byte(compiler, ((op & SLJIT_32) ? 31 : 63))); + } + + if (dst_r != TMP_FREG) + dst_r = (src & SLJIT_MEM) ? TMP_FREG : src; + return emit_groupf(compiler, (GET_OPCODE(op) == SLJIT_NEG_F64 ? XORPD_x_xm : ANDPD_x_xm) | EX86_SSE2, dst, dst_r, 0); } + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src, srcw)); + switch (GET_OPCODE(op)) { case SLJIT_NEG_F64: - FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_32 ? sse2_buffer : sse2_buffer + 8))); + FAIL_IF(emit_groupf(compiler, XORPD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, TMP_FREG, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer : sse2_buffer + 8))); break; case SLJIT_ABS_F64: - FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_32 ? sse2_buffer + 4 : sse2_buffer + 12))); + FAIL_IF(emit_groupf(compiler, ANDPD_x_xm | EX86_SELECT_66(op) | EX86_SSE2, TMP_FREG, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer + 4 : sse2_buffer + 12))); break; } - if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); - return SLJIT_SUCCESS; + return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, @@ -2938,19 +3136,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil switch (GET_OPCODE(op)) { case SLJIT_ADD_F64: - FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_32, dst_r, src2, src2w)); + FAIL_IF(emit_groupf(compiler, ADDSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w)); break; case SLJIT_SUB_F64: - FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_32, dst_r, src2, src2w)); + FAIL_IF(emit_groupf(compiler, SUBSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w)); break; case SLJIT_MUL_F64: - FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_32, dst_r, src2, src2w)); + FAIL_IF(emit_groupf(compiler, MULSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w)); break; case SLJIT_DIV_F64: - FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_32, dst_r, src2, src2w)); + FAIL_IF(emit_groupf(compiler, DIVSD_x_xm | EX86_SELECT_F2_F3(op) | EX86_SSE2, dst_r, src2, src2w)); break; } @@ -2959,6 +3157,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil return SLJIT_SUCCESS; } +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2r(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2, sljit_sw src2w) +{ + sljit_uw pref; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fop2r(compiler, op, dst_freg, src1, src1w, src2, src2w)); + ADJUST_LOCAL_OFFSET(src1, src1w); + ADJUST_LOCAL_OFFSET(src2, src2w); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif + + if (dst_freg == src1) { + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src2, src2w)); + pref = EX86_SELECT_66(op) | EX86_SSE2; + FAIL_IF(emit_groupf(compiler, XORPD_x_xm | pref, TMP_FREG, src1, src1w)); + FAIL_IF(emit_groupf(compiler, ANDPD_x_xm | pref, TMP_FREG, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer : sse2_buffer + 8))); + return emit_groupf(compiler, XORPD_x_xm | pref, dst_freg, TMP_FREG, 0); + } + + if (src1 & SLJIT_MEM) { + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w)); + src1 = TMP_FREG; + src1w = 0; + } + + if (dst_freg != src2) + FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_freg, src2, src2w)); + + pref = EX86_SELECT_66(op) | EX86_SSE2; + FAIL_IF(emit_groupf(compiler, XORPD_x_xm | pref, dst_freg, src1, src1w)); + FAIL_IF(emit_groupf(compiler, ANDPD_x_xm | pref, dst_freg, SLJIT_MEM0(), (sljit_sw)((op & SLJIT_32) ? sse2_buffer : sse2_buffer + 8))); + return emit_groupf(compiler, XORPD_x_xm | pref, dst_freg, src1, src1w); +} + /* --------------------------------------------------------------------- */ /* Conditional instructions */ /* --------------------------------------------------------------------- */ @@ -2980,9 +3217,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF(!inst); - - *inst++ = 0; - *inst++ = 0; + inst[0] = 0; + inst[1] = 0; return label; } @@ -3010,8 +3246,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF_NULL(inst); - *inst++ = 0; - *inst++ = 1; + inst[0] = 0; + inst[1] = 1; return jump; } @@ -3042,8 +3278,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi inst = (sljit_u8*)ensure_buf(compiler, 2); FAIL_IF_NULL(inst); - *inst++ = 0; - *inst++ = 1; + inst[0] = 0; + inst[1] = 1; } else { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -3052,8 +3288,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi #endif inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst = U8(*inst | ((type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm)); + inst[0] = GROUP_FF; + inst[1] = U8(inst[1] | ((type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm)); } return SLJIT_SUCCESS; } @@ -3063,10 +3299,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co sljit_s32 type) { sljit_u8 *inst; - sljit_u8 cond_set = 0; + sljit_u8 cond_set; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) sljit_s32 reg; -#endif +#endif /* !SLJIT_CONFIG_X86_64 */ /* ADJUST_LOCAL_OFFSET and CHECK_EXTRA_REGS might overwrite these values. */ sljit_s32 dst_save = dst; sljit_sw dstw_save = dstw; @@ -3086,13 +3322,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co FAIL_IF(!inst); INC_SIZE(4 + 3); /* Set low register to conditional flag. */ - *inst++ = (reg_map[TMP_REG1] <= 7) ? REX : REX_B; - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | reg_lmap[TMP_REG1]; - *inst++ = U8(REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B)); - *inst++ = OR_rm8_r8; - *inst++ = U8(MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]); + inst[0] = (reg_map[TMP_REG1] <= 7) ? REX : REX_B; + inst[1] = GROUP_0F; + inst[2] = cond_set; + inst[3] = MOD_REG | reg_lmap[TMP_REG1]; + inst[4] = U8(REX | (reg_map[TMP_REG1] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B)); + inst[5] = OR_rm8_r8; + inst[6] = U8(MOD_REG | (reg_lmap[TMP_REG1] << 3) | reg_lmap[dst]); return SLJIT_SUCCESS; } @@ -3102,15 +3338,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co FAIL_IF(!inst); INC_SIZE(4 + 4); /* Set low register to conditional flag. */ - *inst++ = (reg_map[reg] <= 7) ? REX : REX_B; - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | reg_lmap[reg]; - *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); + inst[0] = (reg_map[reg] <= 7) ? REX : REX_B; + inst[1] = GROUP_0F; + inst[2] = cond_set; + inst[3] = MOD_REG | reg_lmap[reg]; + inst[4] = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); /* The movzx instruction does not affect flags. */ - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst = U8(MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]); + inst[5] = GROUP_0F; + inst[6] = MOVZX_r_rm8; + inst[7] = U8(MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]); if (reg != TMP_REG1) return SLJIT_SUCCESS; @@ -3123,110 +3359,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co SLJIT_SKIP_CHECKS(compiler); return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REG1, 0); -#else +#else /* !SLJIT_CONFIG_X86_64 */ + SLJIT_ASSERT(reg_map[TMP_REG1] < 4); + /* The SLJIT_CONFIG_X86_32 code path starts here. */ - if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst)) { - if (reg_map[dst] <= 4) { - /* Low byte is accessible. */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3); - FAIL_IF(!inst); - INC_SIZE(3 + 3); - /* Set low byte to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = U8(MOD_REG | reg_map[dst]); - - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst = U8(MOD_REG | (reg_map[dst] << 3) | reg_map[dst]); - return SLJIT_SUCCESS; - } - - /* Low byte is not accessible. */ - if (cpu_feature_list == 0) - get_cpu_features(); - - if (cpu_feature_list & CPU_FEATURE_CMOV) { - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, 1); - /* a xor reg, reg operation would overwrite the flags. */ - EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0); - - inst = (sljit_u8*)ensure_buf(compiler, 1 + 3); - FAIL_IF(!inst); - INC_SIZE(3); - - *inst++ = GROUP_0F; - /* cmovcc = setcc - 0x50. */ - *inst++ = U8(cond_set - 0x50); - *inst++ = U8(MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REG1]); - return SLJIT_SUCCESS; - } - - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + if (GET_OPCODE(op) < SLJIT_ADD && FAST_IS_REG(dst) && reg_map[dst] <= 4) { + /* Low byte is accessible. */ + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3); FAIL_IF(!inst); - INC_SIZE(1 + 3 + 3 + 1); - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); - /* Set al to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 0 /* eax */; + INC_SIZE(3 + 3); + /* Set low byte to conditional flag. */ + inst[0] = GROUP_0F; + inst[1] = cond_set; + inst[2] = U8(MOD_REG | reg_map[dst]); - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst++ = U8(MOD_REG | (reg_map[dst] << 3) | 0 /* eax */); - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); + inst[3] = GROUP_0F; + inst[4] = MOVZX_r_rm8; + inst[5] = U8(MOD_REG | (reg_map[dst] << 3) | reg_map[dst]); return SLJIT_SUCCESS; } if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && FAST_IS_REG(dst) && reg_map[dst] <= 4) { - SLJIT_ASSERT(reg_map[SLJIT_R0] == 0); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 2); + FAIL_IF(!inst); + INC_SIZE(3 + 2); - if (dst != SLJIT_R0) { - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1); - FAIL_IF(!inst); - INC_SIZE(1 + 3 + 2 + 1); - /* Set low register to conditional flag. */ - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 0 /* eax */; - *inst++ = OR_rm8_r8; - *inst++ = MOD_REG | (0 /* eax */ << 3) | reg_map[dst]; - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); - } - else { - inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2); - FAIL_IF(!inst); - INC_SIZE(2 + 3 + 2 + 2); - /* Set low register to conditional flag. */ - *inst++ = XCHG_r_rm; - *inst++ = U8(MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]); - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 1 /* ecx */; - *inst++ = OR_rm8_r8; - *inst++ = MOD_REG | (1 /* ecx */ << 3) | 0 /* eax */; - *inst++ = XCHG_r_rm; - *inst++ = U8(MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REG1]); - } + /* Set low byte to conditional flag. */ + inst[0] = GROUP_0F; + inst[1] = cond_set; + inst[2] = U8(MOD_REG | reg_map[TMP_REG1]); + + inst[3] = OR_rm8_r8; + inst[4] = U8(MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[dst]); return SLJIT_SUCCESS; } - /* Set TMP_REG1 to the bit. */ - inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); + inst = (sljit_u8*)ensure_buf(compiler, 1 + 3 + 3); FAIL_IF(!inst); - INC_SIZE(1 + 3 + 3 + 1); - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); - /* Set al to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 0 /* eax */; + INC_SIZE(3 + 3); + /* Set low byte to conditional flag. */ + inst[0] = GROUP_0F; + inst[1] = cond_set; + inst[2] = U8(MOD_REG | reg_map[TMP_REG1]); - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst++ = MOD_REG | (0 << 3) /* eax */ | 0 /* eax */; - - *inst++ = U8(XCHG_EAX_r | reg_map[TMP_REG1]); + inst[3] = GROUP_0F; + inst[4] = MOVZX_r_rm8; + inst[5] = U8(MOD_REG | (reg_map[TMP_REG1] << 3) | reg_map[TMP_REG1]); if (GET_OPCODE(op) < SLJIT_ADD) return emit_mov(compiler, dst, dstw, TMP_REG1, 0); @@ -3236,43 +3414,1256 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co #endif /* SLJIT_CONFIG_X86_64 */ } -SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type, +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 dst_reg, - sljit_s32 src, sljit_sw srcw) + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_reg) { - sljit_u8* inst; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_s32 dst = dst_reg; + sljit_sw dstw = 0; +#endif /* SLJIT_CONFIG_X86_32 */ + sljit_sw src2w = 0; CHECK_ERROR(); - CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw)); + CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg)); -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - type &= ~SLJIT_32; + ADJUST_LOCAL_OFFSET(src1, src1w); - if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV) || (dst_reg >= SLJIT_R3 && dst_reg <= SLJIT_S3)) - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw); -#else - if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV)) - return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw); -#endif - - /* ADJUST_LOCAL_OFFSET is not needed. */ - CHECK_EXTRA_REGS(src, srcw, (void)0); + CHECK_EXTRA_REGS(dst, dstw, (void)0); + CHECK_EXTRA_REGS(src1, src1w, (void)0); + CHECK_EXTRA_REGS(src2_reg, src2w, (void)0); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = type & SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ type &= ~SLJIT_32; -#endif - if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { - EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst & SLJIT_MEM) { + if (src1 == SLJIT_IMM || (!(src1 & SLJIT_MEM) && (src2_reg & SLJIT_MEM))) { + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + src1 = src2_reg; + src1w = src2w; + type ^= 0x1; + } else + EMIT_MOV(compiler, TMP_REG1, 0, src2_reg, src2w); + + dst_reg = TMP_REG1; + } else { +#endif /* SLJIT_CONFIG_X86_32 */ + if (dst_reg != src2_reg) { + if (dst_reg == src1) { + src1 = src2_reg; + src1w = src2w; + type ^= 0x1; + } else { + if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) { + EMIT_MOV(compiler, dst_reg, 0, src1, src1w); + src1 = src2_reg; + src1w = src2w; + type ^= 0x1; + } else + EMIT_MOV(compiler, dst_reg, 0, src2_reg, src2w); + } + } + + if (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) { + SLJIT_ASSERT(dst_reg != TMP_REG1); + EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w); + src1 = TMP_REG1; + src1w = 0; + } +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + } +#endif /* SLJIT_CONFIG_X86_32 */ + + if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) + FAIL_IF(emit_groupf(compiler, U8(get_jump_code((sljit_uw)type) - 0x40), dst_reg, src1, src1w)); + else + FAIL_IF(emit_cmov_generic(compiler, type, dst_reg, src1, src1w)); + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (dst_reg == TMP_REG1) + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); +#endif /* SLJIT_CONFIG_X86_32 */ + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, + sljit_s32 src1, sljit_sw src1w, + sljit_s32 src2_freg) +{ + sljit_u8* inst; + sljit_uw size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_fselect(compiler, type, dst_freg, src1, src1w, src2_freg)); + + ADJUST_LOCAL_OFFSET(src1, src1w); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (dst_freg != src2_freg) { + if (dst_freg == src1) { + src1 = src2_freg; + src1w = 0; + type ^= 0x1; + } else + FAIL_IF(emit_sse2_load(compiler, type & SLJIT_32, dst_freg, src2_freg, 0)); + } + + inst = (sljit_u8*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!inst); + INC_SIZE(2); + inst[0] = U8(get_jump_code((sljit_uw)(type & ~SLJIT_32) ^ 0x1) - 0x10); + + size = compiler->size; + FAIL_IF(emit_sse2_load(compiler, type & SLJIT_32, dst_freg, src1, src1w)); + + inst[1] = U8(compiler->size - size); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 alignment = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_uw op; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + + switch (reg_size) { + case 4: + op = EX86_SSE2; + break; + case 5: + if (!(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + op = EX86_SSE2 | VEX_256; + break; + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (!(srcdst & SLJIT_MEM)) + alignment = reg_size; + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 2 || elem_size == 3) { + op |= alignment >= reg_size ? MOVAPS_x_xm : MOVUPS_x_xm; + + if (elem_size == 3) + op |= EX86_PREF_66; + + if (type & SLJIT_SIMD_STORE) + op += 1; + } else + return SLJIT_ERR_UNSUPPORTED; + } else { + op |= ((type & SLJIT_SIMD_STORE) ? MOVDQA_xm_x : MOVDQA_x_xm) + | (alignment >= reg_size ? EX86_PREF_66 : EX86_PREF_F3); + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (op & VEX_256) + return emit_vex_instruction(compiler, op, freg, 0, srcdst, srcdstw); + + return emit_groupf(compiler, op, freg, srcdst, srcdstw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_u8 *inst; + sljit_u8 opcode = 0; + sljit_uw size; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + + if (!(type & SLJIT_SIMD_FLOAT)) { + CHECK_EXTRA_REGS(src, srcw, (void)0); + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : (elem_size > 2)) + return SLJIT_ERR_UNSUPPORTED; +#else /* !SLJIT_CONFIG_X86_32 */ + compiler->mode32 = 1; + + if (elem_size > 3 || ((type & SLJIT_SIMD_FLOAT) && elem_size < 2)) + return SLJIT_ERR_UNSUPPORTED; +#endif /* SLJIT_CONFIG_X86_32 */ + + if (cpu_feature_list & CPU_FEATURE_AVX2) { + if (reg_size < 4 || reg_size > 5) + return SLJIT_ERR_UNSUPPORTED; + + if (src != SLJIT_IMM && (reg_size == 5 || elem_size < 3 || !(type & SLJIT_SIMD_FLOAT))) { + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (!(src & SLJIT_MEM) && !(type & SLJIT_SIMD_FLOAT)) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (elem_size >= 3) + compiler->mode32 = 0; +#endif /* SLJIT_CONFIG_X86_64 */ + FAIL_IF(emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, freg, src, srcw)); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + src = freg; + srcw = 0; + } + + switch (elem_size) { + case 0: + size = VPBROADCASTB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + case 1: + size = VPBROADCASTW_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + case 2: + size = ((type & SLJIT_SIMD_FLOAT) ? VBROADCASTSS_x_xm : VPBROADCASTD_x_xm) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + default: +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + size = VBROADCASTSD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; +#else /* !SLJIT_CONFIG_X86_32 */ + size = ((type & SLJIT_SIMD_FLOAT) ? VBROADCASTSD_x_xm : VPBROADCASTQ_x_xm) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; +#endif /* SLJIT_CONFIG_X86_32 */ + break; + } + + if (reg_size == 5) + size |= VEX_256; + + return emit_vex_instruction(compiler, size, freg, 0, src, srcw); + } + } else if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (type & SLJIT_SIMD_FLOAT) { + if (src == SLJIT_IMM) { + if (reg_size == 5) + return emit_vex_instruction(compiler, XORPD_x_xm | VEX_256 | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0); + + return emit_groupf(compiler, XORPD_x_xm | (elem_size == 3 ? EX86_PREF_66 : 0) | EX86_SSE2, freg, freg, 0); + } + + if (elem_size == 2 && freg != src) { + FAIL_IF(emit_sse2_load(compiler, 1, freg, src, srcw)); + src = freg; + srcw = 0; + } + + FAIL_IF(emit_groupf(compiler, (elem_size == 2 ? SHUFPS_x_xm : MOVDDUP_x_xm) | (elem_size == 2 ? 0 : EX86_PREF_F2) | EX86_SSE2, freg, src, srcw)); + + if (elem_size == 2) + return emit_byte(compiler, 0); + return SLJIT_SUCCESS; + } + + if (src == SLJIT_IMM) { + if (elem_size == 0) { + srcw = (sljit_u8)srcw; + srcw |= srcw << 8; + srcw |= srcw << 16; + elem_size = 2; + } else if (elem_size == 1) { + srcw = (sljit_u16)srcw; + srcw |= srcw << 16; + elem_size = 2; + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (elem_size == 2 && (sljit_s32)srcw == -1) + srcw = -1; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (srcw == 0 || srcw == -1) { + if (reg_size == 5) + return emit_vex_instruction(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | VEX_256 | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0); + + return emit_groupf(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | EX86_PREF_66 | EX86_SSE2, freg, freg, 0); + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (elem_size == 3) + FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw)); + else +#endif /* SLJIT_CONFIG_X86_64 */ + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw); + src = TMP_REG1; srcw = 0; } - inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw); + size = 2; + opcode = MOVD_x_rm; + + switch (elem_size) { + case 0: + if (!FAST_IS_REG(src)) { + opcode = 0x3a /* Prefix of PINSRB_x_rm_i8. */; + size = 3; + } + break; + case 1: + if (!FAST_IS_REG(src)) + opcode = PINSRW_x_rm_i8; + break; + case 2: + break; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + case 3: + /* MOVQ */ + compiler->mode32 = 0; + break; +#endif /* SLJIT_CONFIG_X86_64 */ + } + + inst = emit_x86_instruction(compiler, size | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, src, srcw); FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = U8(get_jump_code((sljit_uw)type) - 0x40); + inst[0] = GROUP_0F; + inst[1] = opcode; + + if (reg_size == 5) { + SLJIT_ASSERT(opcode == MOVD_x_rm); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + size = VPBROADCASTD_x_xm; +#else /* !SLJIT_CONFIG_X86_32 */ + size = (elem_size == 3) ? VPBROADCASTQ_x_xm : VPBROADCASTD_x_xm; +#endif /* SLJIT_CONFIG_X86_32 */ + return emit_vex_instruction(compiler, size | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); + } + + if (size == 3) { + SLJIT_ASSERT(opcode == 0x3a); + inst[2] = PINSRB_x_rm_i8; + } + + if (opcode != MOVD_x_rm) + FAIL_IF(emit_byte(compiler, 0)); + + switch (elem_size) { + case 0: + FAIL_IF(emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, TMP_FREG, 0)); + return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, TMP_FREG, 0); + case 1: + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, freg, 0)); + FAIL_IF(emit_byte(compiler, 0)); + /* fallthrough */ + default: + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, freg, 0)); + return emit_byte(compiler, 0); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + case 3: + compiler->mode32 = 1; + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, freg, 0)); + return emit_byte(compiler, 0x44); +#endif /* SLJIT_CONFIG_X86_64 */ + } +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, sljit_s32 lane_index, + sljit_s32 srcdst, sljit_sw srcdstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_u8 *inst; + sljit_u8 opcode = 0; + sljit_uw size; + sljit_s32 freg_orig = freg; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_s32 srcdst_is_ereg = 0; + sljit_s32 srcdst_orig = 0; + sljit_sw srcdstw_orig = 0; +#endif /* SLJIT_CONFIG_X86_32 */ + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_mov(compiler, type, freg, lane_index, srcdst, srcdstw)); + + ADJUST_LOCAL_OFFSET(srcdst, srcdstw); + + if (reg_size == 5) { + if (!(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + } else if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if ((type & SLJIT_SIMD_FLOAT) ? (elem_size < 2 || elem_size > 3) : elem_size > 2) + return SLJIT_ERR_UNSUPPORTED; +#else /* SLJIT_CONFIG_X86_32 */ + if (elem_size > 3 || ((type & SLJIT_SIMD_FLOAT) && elem_size < 2)) + return SLJIT_ERR_UNSUPPORTED; +#endif /* SLJIT_CONFIG_X86_32 */ + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#else /* !SLJIT_CONFIG_X86_64 */ + if (!(type & SLJIT_SIMD_FLOAT)) { + CHECK_EXTRA_REGS(srcdst, srcdstw, srcdst_is_ereg = 1); + + if ((type & SLJIT_SIMD_STORE) && ((srcdst_is_ereg && elem_size < 2) || (elem_size == 0 && (type & SLJIT_SIMD_LANE_SIGNED) && FAST_IS_REG(srcdst) && reg_map[srcdst] >= 4))) { + srcdst_orig = srcdst; + srcdstw_orig = srcdstw; + srcdst = TMP_REG1; + srcdstw = 0; + } + } +#endif /* SLJIT_CONFIG_X86_64 */ + + if (type & SLJIT_SIMD_LANE_ZERO) { + if (lane_index == 0) { + if (!(type & SLJIT_SIMD_FLOAT)) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (elem_size == 3) { + compiler->mode32 = 0; + elem_size = 2; + } +#endif /* SLJIT_CONFIG_X86_64 */ + if (srcdst == SLJIT_IMM) { + if (elem_size == 0) + srcdstw = (sljit_u8)srcdstw; + else if (elem_size == 1) + srcdstw = (sljit_u16)srcdstw; + + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcdstw); + srcdst = TMP_REG1; + srcdstw = 0; + elem_size = 2; + } + + if (elem_size == 2) { + if (reg_size == 4) + return emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, freg, srcdst, srcdstw); + return emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, srcdst, srcdstw); + } + } else if (srcdst & SLJIT_MEM) { + SLJIT_ASSERT(elem_size == 2 || elem_size == 3); + + if (reg_size == 4) + return emit_groupf(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, freg, srcdst, srcdstw); + return emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, freg, 0, srcdst, srcdstw); + } else if (elem_size == 3) { + if (reg_size == 4) + return emit_groupf(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, freg, srcdst, 0); + return emit_vex_instruction(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, freg, 0, srcdst, 0); + } + } + + if (reg_size == 5 && lane_index >= (1 << (4 - elem_size))) { + freg = TMP_FREG; + lane_index -= (1 << (4 - elem_size)); + } else if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) { + FAIL_IF(emit_sse2_load(compiler, elem_size == 2, TMP_FREG, srcdst, srcdstw)); + srcdst = TMP_FREG; + srcdstw = 0; + } + + size = ((!(type & SLJIT_SIMD_FLOAT) || elem_size != 2) ? EX86_PREF_66 : 0) + | ((type & SLJIT_SIMD_FLOAT) ? XORPD_x_xm : PXOR_x_xm) | EX86_SSE2; + + if (reg_size == 5) + FAIL_IF(emit_vex_instruction(compiler, size | VEX_256 | VEX_SSE2_OPV, freg, freg, freg, 0)); + else + FAIL_IF(emit_groupf(compiler, size, freg, freg, 0)); + } else if (reg_size == 5 && lane_index >= (1 << (4 - elem_size))) { + FAIL_IF(emit_vex_instruction(compiler, ((type & SLJIT_SIMD_FLOAT) ? VEXTRACTF128_x_ym : VEXTRACTI128_x_ym) | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, 0, TMP_FREG, 0)); + FAIL_IF(emit_byte(compiler, 1)); + + freg = TMP_FREG; + lane_index -= (1 << (4 - elem_size)); + } + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size == 3) { + if (srcdst & SLJIT_MEM) { + if (type & SLJIT_SIMD_STORE) + size = lane_index == 0 ? MOVLPD_m_x : MOVHPD_m_x; + else + size = lane_index == 0 ? MOVLPD_x_m : MOVHPD_x_m; + + FAIL_IF(emit_groupf(compiler, size | EX86_PREF_66 | EX86_SSE2, freg, srcdst, srcdstw)); + + /* In case of store, freg is not TMP_FREG. */ + } else if (type & SLJIT_SIMD_STORE) { + if (lane_index == 1) + return emit_groupf(compiler, MOVHLPS_x_x | EX86_SSE2, srcdst, freg, 0); + return emit_sse2_load(compiler, 0, srcdst, freg, 0); + } else { + if (lane_index == 1) + FAIL_IF(emit_groupf(compiler, MOVLHPS_x_x | EX86_SSE2, freg, srcdst, 0)); + else + FAIL_IF(emit_sse2_store(compiler, 0, freg, 0, srcdst)); + } + } else if (type & SLJIT_SIMD_STORE) { + if (lane_index == 0) + return emit_sse2_store(compiler, 1, srcdst, srcdstw, freg); + + if (srcdst & SLJIT_MEM) { + FAIL_IF(emit_groupf_ext(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, srcdst, srcdstw)); + return emit_byte(compiler, U8(lane_index)); + } + + if (srcdst == freg) + size = SHUFPS_x_xm | EX86_SSE2; + else { + if (cpu_feature_list & CPU_FEATURE_AVX) { + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, srcdst, freg, freg, 0)); + return emit_byte(compiler, U8(lane_index)); + } + + switch (lane_index) { + case 1: + size = MOVSHDUP_x_xm | EX86_PREF_F3 | EX86_SSE2; + break; + case 2: + size = MOVHLPS_x_x | EX86_SSE2; + break; + default: + SLJIT_ASSERT(lane_index == 3); + size = PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2; + break; + } + } + + FAIL_IF(emit_groupf(compiler, size, srcdst, freg, 0)); + + size &= 0xff; + if (size == SHUFPS_x_xm || size == PSHUFD_x_xm) + return emit_byte(compiler, U8(lane_index)); + + return SLJIT_SUCCESS; + } else { + if (lane_index != 0 || (srcdst & SLJIT_MEM)) { + FAIL_IF(emit_groupf_ext(compiler, INSERTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, srcdst, srcdstw)); + FAIL_IF(emit_byte(compiler, U8(lane_index << 4))); + } else + FAIL_IF(emit_sse2_store(compiler, 1, freg, 0, srcdst)); + } + + if (freg != TMP_FREG || (type & SLJIT_SIMD_STORE)) + return SLJIT_SUCCESS; + + SLJIT_ASSERT(reg_size == 5); + + if (type & SLJIT_SIMD_LANE_ZERO) { + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg_orig, 0, TMP_FREG, 0)); + return emit_byte(compiler, 0x4e); + } + + FAIL_IF(emit_vex_instruction(compiler, VINSERTF128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, freg_orig, freg_orig, TMP_FREG, 0)); + return emit_byte(compiler, 1); + } + + if (srcdst == SLJIT_IMM) { + EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcdstw); + srcdst = TMP_REG1; + srcdstw = 0; + } + + size = 3; + + switch (elem_size) { + case 0: + opcode = (type & SLJIT_SIMD_STORE) ? PEXTRB_rm_x_i8 : PINSRB_x_rm_i8; + break; + case 1: + if (!(type & SLJIT_SIMD_STORE)) { + size = 2; + opcode = PINSRW_x_rm_i8; + } else + opcode = PEXTRW_rm_x_i8; + break; + case 2: + opcode = (type & SLJIT_SIMD_STORE) ? PEXTRD_rm_x_i8 : PINSRD_x_rm_i8; + break; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + case 3: + /* PINSRQ / PEXTRQ */ + opcode = (type & SLJIT_SIMD_STORE) ? PEXTRD_rm_x_i8 : PINSRD_x_rm_i8; + compiler->mode32 = 0; + break; +#endif /* SLJIT_CONFIG_X86_64 */ + } + + inst = emit_x86_instruction(compiler, size | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, srcdst, srcdstw); + FAIL_IF(!inst); + inst[0] = GROUP_0F; + + if (size == 3) { + inst[1] = 0x3a; + inst[2] = opcode; + } else + inst[1] = opcode; + + FAIL_IF(emit_byte(compiler, U8(lane_index))); + + if (!(type & SLJIT_SIMD_LANE_SIGNED) || (srcdst & SLJIT_MEM)) { + if (freg == TMP_FREG && !(type & SLJIT_SIMD_STORE)) { + SLJIT_ASSERT(reg_size == 5); + + if (type & SLJIT_SIMD_LANE_ZERO) { + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg_orig, 0, TMP_FREG, 0)); + return emit_byte(compiler, 0x4e); + } + + FAIL_IF(emit_vex_instruction(compiler, VINSERTI128_y_y_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2 | VEX_SSE2_OPV, freg_orig, freg_orig, TMP_FREG, 0)); + return emit_byte(compiler, 1); + } + +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if (srcdst_orig & SLJIT_MEM) + return emit_mov(compiler, srcdst_orig, srcdstw_orig, TMP_REG1, 0); +#endif /* SLJIT_CONFIG_X86_32 */ + return SLJIT_SUCCESS; + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (elem_size >= 3) + return SLJIT_SUCCESS; + + compiler->mode32 = (type & SLJIT_32); + + size = 2; + + if (elem_size == 0) + size |= EX86_REX; + + if (elem_size == 2) { + if (type & SLJIT_32) + return SLJIT_SUCCESS; + + SLJIT_ASSERT(!(compiler->mode32)); + size = 1; + } + + inst = emit_x86_instruction(compiler, size, srcdst, 0, srcdst, 0); + FAIL_IF(!inst); + + if (size != 1) { + inst[0] = GROUP_0F; + inst[1] = U8((elem_size == 0) ? MOVSX_r_rm8 : MOVSX_r_rm16); + } else + inst[0] = MOVSXD_r_rm; +#else /* !SLJIT_CONFIG_X86_64 */ + if (elem_size >= 2) + return SLJIT_SUCCESS; + + FAIL_IF(emit_groupf(compiler, (elem_size == 0) ? MOVSX_r_rm8 : MOVSX_r_rm16, + (srcdst_orig != 0 && FAST_IS_REG(srcdst_orig)) ? srcdst_orig : srcdst, srcdst, 0)); + + if (srcdst_orig & SLJIT_MEM) + return emit_mov(compiler, srcdst_orig, srcdstw_orig, TMP_REG1, 0); +#endif /* SLJIT_CONFIG_X86_64 */ + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_s32 src_lane_index) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_uw pref; + sljit_u8 byte; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_s32 opcode3 = TMP_REG1; +#else /* !SLJIT_CONFIG_X86_32 */ + sljit_s32 opcode3 = SLJIT_S0; +#endif /* SLJIT_CONFIG_X86_32 */ + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, freg, src, src_lane_index)); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + SLJIT_ASSERT(reg_map[opcode3] == 3); + + if (reg_size == 5) { + if (!(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + } else if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_FLOAT) { + pref = 0; + byte = U8(src_lane_index); + + if (elem_size == 3) { + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 5) { + if (src_lane_index == 0) + return emit_vex_instruction(compiler, VBROADCASTSD_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); + + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + + byte = U8(byte | (byte << 2)); + return emit_byte(compiler, U8(byte | (byte << 4))); + } + + if (src_lane_index == 0) + return emit_groupf(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, src, 0); + + /* Changes it to SHUFPD_x_xm. */ + pref = EX86_PREF_66; + } else if (elem_size != 2) + return SLJIT_ERR_UNSUPPORTED; + else if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 5) { + SLJIT_ASSERT(elem_size == 2); + + if (src_lane_index == 0) + return emit_vex_instruction(compiler, VBROADCASTSS_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); + + FAIL_IF(emit_vex_instruction(compiler, VPERMPD_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + + byte = 0x44; + if (src_lane_index >= 4) { + byte = 0xee; + src_lane_index -= 4; + } + + FAIL_IF(emit_byte(compiler, byte)); + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | VEX_256 | pref | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, freg, 0)); + byte = U8(src_lane_index); + } else if (freg != src && (cpu_feature_list & CPU_FEATURE_AVX)) { + FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | pref | EX86_SSE2 | VEX_SSE2_OPV, freg, src, src, 0)); + } else { + if (freg != src) + FAIL_IF(emit_groupf(compiler, MOVAPS_x_xm | pref | EX86_SSE2, freg, src, 0)); + + FAIL_IF(emit_groupf(compiler, SHUFPS_x_xm | pref | EX86_SSE2, freg, freg, 0)); + } + + if (elem_size == 2) { + byte = U8(byte | (byte << 2)); + byte = U8(byte | (byte << 4)); + } else + byte = U8(byte | (byte << 1)); + + return emit_byte(compiler, U8(byte)); + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (elem_size == 0) { + if (reg_size == 5 && src_lane_index >= 16) { + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + FAIL_IF(emit_byte(compiler, src_lane_index >= 24 ? 0xff : 0xaa)); + src_lane_index &= 0x7; + src = freg; + } + + if ((freg != src && !(cpu_feature_list & CPU_FEATURE_AVX2)) || src_lane_index != 0) { + pref = 0; + + if ((src_lane_index & 0x3) == 0) { + pref = EX86_PREF_66; + byte = U8(src_lane_index >> 2); + } else if (src_lane_index < 8 && (src_lane_index & 0x1) == 0) { + pref = EX86_PREF_F2; + byte = U8(src_lane_index >> 1); + } else { + if (freg == src || !(cpu_feature_list & CPU_FEATURE_AVX2)) { + if (freg != src) + FAIL_IF(emit_groupf(compiler, MOVDQA_x_xm | EX86_PREF_66 | EX86_SSE2, freg, src, 0)); + + FAIL_IF(emit_groupf(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2, opcode3, freg, 0)); + } else + FAIL_IF(emit_vex_instruction(compiler, PSRLDQ_x | EX86_PREF_66 | EX86_SSE2_OP2 | VEX_SSE2_OPV, opcode3, freg, src, 0)); + + FAIL_IF(emit_byte(compiler, U8(src_lane_index))); + } + + if (pref != 0) { + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, src, 0)); + FAIL_IF(emit_byte(compiler, byte)); + } + + src = freg; + } + + if (cpu_feature_list & CPU_FEATURE_AVX2) + return emit_vex_instruction(compiler, VPBROADCASTB_x_xm | (reg_size == 5 ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, 0); + + SLJIT_ASSERT(reg_size == 4); + FAIL_IF(emit_groupf(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, TMP_FREG, 0)); + return emit_groupf_ext(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, TMP_FREG, 0); + } + + if ((cpu_feature_list & CPU_FEATURE_AVX2) && src_lane_index == 0 && elem_size <= 3) { + switch (elem_size) { + case 1: + pref = VPBROADCASTW_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + case 2: + pref = VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + default: + pref = VPBROADCASTQ_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2; + break; + } + + if (reg_size == 5) + pref |= VEX_256; + + return emit_vex_instruction(compiler, pref, freg, 0, src, 0); + } + + if (reg_size == 5) { + switch (elem_size) { + case 1: + byte = U8(src_lane_index & 0x3); + src_lane_index >>= 2; + pref = PSHUFLW_x_xm | VEX_256 | ((src_lane_index & 1) == 0 ? EX86_PREF_F2 : EX86_PREF_F3) | EX86_SSE2; + break; + case 2: + byte = U8(src_lane_index & 0x3); + src_lane_index >>= 1; + pref = PSHUFD_x_xm | VEX_256 | EX86_PREF_66 | EX86_SSE2; + break; + case 3: + pref = 0; + break; + default: + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + return emit_byte(compiler, U8(src_lane_index == 0 ? 0x44 : 0xee)); + } + + if (pref != 0) { + FAIL_IF(emit_vex_instruction(compiler, pref, freg, 0, src, 0)); + byte = U8(byte | (byte << 2)); + FAIL_IF(emit_byte(compiler, U8(byte | (byte << 4)))); + + if (src_lane_index == 0) + return emit_vex_instruction(compiler, VPBROADCASTQ_x_xm | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); + + src = freg; + } + + FAIL_IF(emit_vex_instruction(compiler, VPERMQ_y_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | VEX_W | EX86_SSE2, freg, 0, src, 0)); + byte = U8(src_lane_index); + byte = U8(byte | (byte << 2)); + return emit_byte(compiler, U8(byte | (byte << 4))); + } + + switch (elem_size) { + case 1: + byte = U8(src_lane_index & 0x3); + src_lane_index >>= 1; + pref = (src_lane_index & 2) == 0 ? EX86_PREF_F2 : EX86_PREF_F3; + + FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, src, 0)); + byte = U8(byte | (byte << 2)); + FAIL_IF(emit_byte(compiler, U8(byte | (byte << 4)))); + + if ((cpu_feature_list & CPU_FEATURE_AVX2) && pref == EX86_PREF_F2) + return emit_vex_instruction(compiler, VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, freg, 0); + + src = freg; + /* fallthrough */ + case 2: + byte = U8(src_lane_index); + byte = U8(byte | (byte << 2)); + break; + default: + byte = U8(src_lane_index << 1); + byte = U8(byte | (byte << 2) | 0x4); + break; + } + + FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, src, 0)); + return emit_byte(compiler, U8(byte | (byte << 4))); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 src, sljit_sw srcw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 elem2_size = SLJIT_SIMD_GET_ELEM2_SIZE(type); + sljit_u8 opcode; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw)); + + ADJUST_LOCAL_OFFSET(src, srcw); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (reg_size == 5) { + if (!(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + } else if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_FLOAT) { + if (elem_size != 2 || elem2_size != 3) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + return emit_groupf(compiler, CVTPS2PD_x_xm | EX86_SSE2, freg, src, srcw); + return emit_vex_instruction(compiler, CVTPS2PD_x_xm | VEX_256 | EX86_SSE2, freg, 0, src, srcw); + } + + switch (elem_size) { + case 0: + if (elem2_size == 1) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXBW_x_xm : PMOVZXBW_x_xm; + else if (elem2_size == 2) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXBD_x_xm : PMOVZXBD_x_xm; + else if (elem2_size == 3) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXBQ_x_xm : PMOVZXBQ_x_xm; + else + return SLJIT_ERR_UNSUPPORTED; + break; + case 1: + if (elem2_size == 2) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXWD_x_xm : PMOVZXWD_x_xm; + else if (elem2_size == 3) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXWQ_x_xm : PMOVZXWQ_x_xm; + else + return SLJIT_ERR_UNSUPPORTED; + break; + case 2: + if (elem2_size == 3) + opcode = (type & SLJIT_SIMD_EXTEND_SIGNED) ? PMOVSXDQ_x_xm : PMOVZXDQ_x_xm; + else + return SLJIT_ERR_UNSUPPORTED; + break; + default: + return SLJIT_ERR_UNSUPPORTED; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + if (reg_size == 4) + return emit_groupf_ext(compiler, opcode | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, src, srcw); + return emit_vex_instruction(compiler, opcode | VEX_256 | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, srcw); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 freg, + sljit_s32 dst, sljit_sw dstw) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 dst_r; + sljit_uw pref; + sljit_u8 *inst; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_sign(compiler, type, freg, dst, dstw)); + + ADJUST_LOCAL_OFFSET(dst, dstw); + + CHECK_EXTRA_REGS(dst, dstw, (void)0); +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (elem_size > 3 || ((type & SLJIT_SIMD_FLOAT) && elem_size < 2)) + return SLJIT_ERR_UNSUPPORTED; + + if (reg_size == 4) { + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + pref = EX86_PREF_66 | EX86_SSE2_OP2; + + switch (elem_size) { + case 1: + FAIL_IF(emit_groupf(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2, TMP_FREG, freg, 0)); + freg = TMP_FREG; + break; + case 2: + pref = EX86_SSE2_OP2; + break; + } + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + FAIL_IF(emit_groupf(compiler, (elem_size < 2 ? PMOVMSKB_r_x : MOVMSKPS_r_x) | pref, dst_r, freg, 0)); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = type & SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (elem_size == 1) { + inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 8, dst_r, 0); + FAIL_IF(!inst); + inst[1] |= SHR; + } + + if (dst_r == TMP_REG1) + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); + + return SLJIT_SUCCESS; + } + + if (reg_size != 5 || !(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1; + + if (elem_size == 1) { + FAIL_IF(emit_vex_instruction(compiler, VEXTRACTI128_x_ym | VEX_256 | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, 0, TMP_FREG, 0)); + FAIL_IF(emit_byte(compiler, 1)); + FAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | VEX_256 | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, freg, TMP_FREG, 0)); + FAIL_IF(emit_groupf(compiler, PMOVMSKB_r_x | EX86_PREF_66 | EX86_SSE2_OP2, dst_r, TMP_FREG, 0)); + } else { + pref = MOVMSKPS_r_x | VEX_256 | EX86_SSE2_OP2; + + if (elem_size == 0) + pref = PMOVMSKB_r_x | VEX_256 | EX86_PREF_66 | EX86_SSE2_OP2; + else if (elem_size == 3) + pref |= EX86_PREF_66; + + FAIL_IF(emit_vex_instruction(compiler, pref, dst_r, 0, freg, 0)); + } + + if (dst_r == TMP_REG1) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = type & SLJIT_32; +#endif /* SLJIT_CONFIG_X86_64 */ + return emit_mov(compiler, dst, dstw, TMP_REG1, 0); + } + + return SLJIT_SUCCESS; +} + +static sljit_s32 emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src_freg) +{ + sljit_uw op = ((type & SLJIT_SIMD_FLOAT) ? MOVAPS_x_xm : MOVDQA_x_xm) | EX86_SSE2; + + SLJIT_ASSERT(SLJIT_SIMD_GET_REG_SIZE(type) == 4); + + if (!(type & SLJIT_SIMD_FLOAT) || SLJIT_SIMD_GET_ELEM_SIZE(type) == 3) + op |= EX86_PREF_66; + + return emit_groupf(compiler, op, dst_freg, src_freg, 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *compiler, sljit_s32 type, + sljit_s32 dst_freg, sljit_s32 src1_freg, sljit_s32 src2_freg) +{ + sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type); + sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type); + sljit_s32 needs_move = 0; + sljit_uw op = 0; + + CHECK_ERROR(); + CHECK(check_sljit_emit_simd_op2(compiler, type, dst_freg, src1_freg, src2_freg)); + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 1; +#endif /* SLJIT_CONFIG_X86_64 */ + + if (reg_size == 5) { + if (!(cpu_feature_list & CPU_FEATURE_AVX2)) + return SLJIT_ERR_UNSUPPORTED; + } else if (reg_size != 4) + return SLJIT_ERR_UNSUPPORTED; + + if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3)) + return SLJIT_ERR_UNSUPPORTED; + + switch (SLJIT_SIMD_GET_OPCODE(type)) { + case SLJIT_SIMD_OP2_AND: + op = (type & SLJIT_SIMD_FLOAT) ? ANDPD_x_xm : PAND_x_xm; + + if (!(type & SLJIT_SIMD_FLOAT) || elem_size == 3) + op |= EX86_PREF_66; + break; + case SLJIT_SIMD_OP2_OR: + op = (type & SLJIT_SIMD_FLOAT) ? ORPD_x_xm : POR_x_xm; + + if (!(type & SLJIT_SIMD_FLOAT) || elem_size == 3) + op |= EX86_PREF_66; + break; + case SLJIT_SIMD_OP2_XOR: + op = (type & SLJIT_SIMD_FLOAT) ? XORPD_x_xm : PXOR_x_xm; + + if (!(type & SLJIT_SIMD_FLOAT) || elem_size == 3) + op |= EX86_PREF_66; + break; + } + + if (type & SLJIT_SIMD_TEST) + return SLJIT_SUCCESS; + + needs_move = dst_freg != src1_freg && dst_freg != src2_freg; + + if (reg_size == 5 || (needs_move && (cpu_feature_list & CPU_FEATURE_AVX2))) { + if (reg_size == 5) + op |= VEX_256; + + return emit_vex_instruction(compiler, op | EX86_SSE2 | VEX_SSE2_OPV, dst_freg, src1_freg, src2_freg, 0); + } + + if (needs_move) { + FAIL_IF(emit_simd_mov(compiler, type, dst_freg, src1_freg)); + } else if (dst_freg != src1_freg) { + SLJIT_ASSERT(dst_freg == src2_freg); + src2_freg = src1_freg; + } + + FAIL_IF(emit_groupf(compiler, op | EX86_SSE2, dst_freg, src2_freg, 0)); + return SLJIT_SUCCESS; +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 dst_reg, + sljit_s32 mem_reg) +{ + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg)); + + SLJIT_SKIP_CHECKS(compiler); + return sljit_emit_op1(compiler, op, dst_reg, 0, SLJIT_MEM1(mem_reg), 0); +} + +SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler *compiler, sljit_s32 op, + sljit_s32 src_reg, + sljit_s32 mem_reg, + sljit_s32 temp_reg) +{ + sljit_uw pref; + sljit_s32 free_reg = TMP_REG1; +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + sljit_sw srcw = 0; + sljit_sw tempw = 0; +#endif /* SLJIT_CONFIG_X86_32 */ + + CHECK_ERROR(); + CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg)); + CHECK_EXTRA_REGS(src_reg, srcw, (void)0); + CHECK_EXTRA_REGS(temp_reg, tempw, (void)0); + + SLJIT_ASSERT(FAST_IS_REG(src_reg) || src_reg == SLJIT_MEM1(SLJIT_SP)); + SLJIT_ASSERT(FAST_IS_REG(temp_reg) || temp_reg == SLJIT_MEM1(SLJIT_SP)); + + op = GET_OPCODE(op); +#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) + if ((src_reg & SLJIT_MEM) || (op == SLJIT_MOV_U8 && reg_map[src_reg] >= 4)) { + /* Src is virtual register or its low byte is not accessible. */ + SLJIT_ASSERT(src_reg != SLJIT_R1); + free_reg = src_reg; + + EMIT_MOV(compiler, TMP_REG1, 0, src_reg, srcw); + src_reg = TMP_REG1; + + if (mem_reg == src_reg) + mem_reg = TMP_REG1; + } +#endif /* SLJIT_CONFIG_X86_32 */ + + if (temp_reg != SLJIT_R0) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; + + EMIT_MOV(compiler, free_reg, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, 0); + + if (src_reg == SLJIT_R0) + src_reg = free_reg; + if (mem_reg == SLJIT_R0) + mem_reg = free_reg; +#else /* !SLJIT_CONFIG_X86_64 */ + if (src_reg == TMP_REG1 && mem_reg == SLJIT_R0 && (free_reg & SLJIT_MEM)) { + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_R1, 0); + EMIT_MOV(compiler, SLJIT_R1, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); + + mem_reg = SLJIT_R1; + free_reg = SLJIT_R1; + } else { + EMIT_MOV(compiler, free_reg, 0, SLJIT_R0, 0); + EMIT_MOV(compiler, SLJIT_R0, 0, temp_reg, tempw); + + if (src_reg == SLJIT_R0) + src_reg = free_reg; + if (mem_reg == SLJIT_R0) + mem_reg = free_reg; + } +#endif /* SLJIT_CONFIG_X86_64 */ + } + +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = op != SLJIT_MOV && op != SLJIT_MOV_P; +#endif /* SLJIT_CONFIG_X86_64 */ + + /* Lock prefix. */ + FAIL_IF(emit_byte(compiler, GROUP_LOCK)); + + pref = 0; + if (op == SLJIT_MOV_U16) + pref = EX86_HALF_ARG | EX86_PREF_66; +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + if (op == SLJIT_MOV_U8) + pref = EX86_REX; +#endif /* SLJIT_CONFIG_X86_64 */ + + FAIL_IF(emit_groupf(compiler, (op == SLJIT_MOV_U8 ? CMPXCHG_rm8_r : CMPXCHG_rm_r) | pref, src_reg, SLJIT_MEM1(mem_reg), 0)); + + if (temp_reg != SLJIT_R0) { +#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) + compiler->mode32 = 0; + return emit_mov(compiler, SLJIT_R0, 0, TMP_REG1, 0); +#else /* !SLJIT_CONFIG_X86_64 */ + EMIT_MOV(compiler, SLJIT_R0, 0, free_reg, 0); + if (free_reg != TMP_REG1) + return emit_mov(compiler, free_reg, 0, (free_reg == SLJIT_R1) ? SLJIT_MEM1(SLJIT_SP) : TMP_REG1, 0); +#endif /* SLJIT_CONFIG_X86_64 */ + } return SLJIT_SUCCESS; } @@ -3339,8 +4730,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF(!inst); - *inst++ = 0; - *inst++ = 2; + inst[0] = 0; + inst[1] = 2; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (dst & SLJIT_MEM) @@ -3393,8 +4784,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj inst = (sljit_u8*)ensure_buf(compiler, 2); PTR_FAIL_IF(!inst); - *inst++ = 0; - *inst++ = 3; + inst[0] = 0; + inst[1] = 3; return put_label; } diff --git a/src/3rdparty/sqlite/qt_attribution.json b/src/3rdparty/sqlite/qt_attribution.json index 2dea4e71c07..640a926fca0 100644 --- a/src/3rdparty/sqlite/qt_attribution.json +++ b/src/3rdparty/sqlite/qt_attribution.json @@ -6,8 +6,8 @@ "Description": "SQLite is a small C library that implements a self-contained, embeddable, zero-configuration SQL database engine.", "Homepage": "https://www.sqlite.org/", - "Version": "3.44.1", - "DownloadLocation": "https://sqlite.org/2023/sqlite-amalgamation-3440100.zip", + "Version": "3.45.1", + "DownloadLocation": "https://www.sqlite.org/2024/sqlite-amalgamation-3450100.zip", "License": "Public Domain", "Copyright": "The authors disclaim copyright to the source code. However, a license can be obtained if needed." } diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c index 7d61daa8062..139ee46a6a9 100644 --- a/src/3rdparty/sqlite/sqlite3.c +++ b/src/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.44.1. By combining all the individual C code files into this +** version 3.45.1. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** d295f48e8f367b066b881780c98bdf980a1d. +** e876e51a0ed5c5b3126f52e532044363a014. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -459,9 +459,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.1" -#define SQLITE_VERSION_NUMBER 3044001 -#define SQLITE_SOURCE_ID "2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4" +#define SQLITE_VERSION "3.45.1" +#define SQLITE_VERSION_NUMBER 3045001 +#define SQLITE_SOURCE_ID "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257cc467a" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -4267,15 +4267,17 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); ** ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language -** text that describes the error, as either UTF-8 or UTF-16 respectively. +** text that describes the error, as either UTF-8 or UTF-16 respectively, +** or NULL if no error message is available. ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** -** ^The sqlite3_errstr() interface returns the English-language text -** that describes the [result code], as UTF-8. +** ^The sqlite3_errstr(E) interface returns the English-language text +** that describes the [result code] E, as UTF-8, or NULL if E is not an +** result code for which a text error message is available. ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** @@ -8350,9 +8352,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** ^(Some systems (for example, Windows 95) do not support the operation ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() -** will always return SQLITE_BUSY. The SQLite core only ever uses -** sqlite3_mutex_try() as an optimization so this is acceptable -** behavior.)^ +** will always return SQLITE_BUSY. In most cases the SQLite core only uses +** sqlite3_mutex_try() as an optimization, so this is acceptable +** behavior. The exceptions are unix builds that set the +** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working +** sqlite3_mutex_try() is required.)^ ** ** ^The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior @@ -8611,6 +8615,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ +#define SQLITE_TESTCTRL_JSON_SELFCHECK 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ @@ -13124,8 +13129,11 @@ struct Fts5PhraseIter { ** created with the "columnsize=0" option. ** ** xColumnText: -** This function attempts to retrieve the text of column iCol of the -** current document. If successful, (*pz) is set to point to a buffer +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the text of column iCol of +** the current document. If successful, (*pz) is set to point to a buffer ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, ** if an error occurs, an SQLite error code is returned and the final values @@ -13135,8 +13143,10 @@ struct Fts5PhraseIter { ** Returns the number of phrases in the current query expression. ** ** xPhraseSize: -** Returns the number of tokens in phrase iPhrase of the query. Phrases -** are numbered starting from zero. +** If parameter iCol is less than zero, or greater than or equal to the +** number of phrases in the current query, as returned by xPhraseCount, +** 0 is returned. Otherwise, this function returns the number of tokens in +** phrase iPhrase of the query. Phrases are numbered starting from zero. ** ** xInstCount: ** Set *pnInst to the total number of occurrences of all phrases within @@ -13152,12 +13162,13 @@ struct Fts5PhraseIter { ** Query for the details of phrase match iIdx within the current row. ** Phrase matches are numbered starting from zero, so the iIdx argument ** should be greater than or equal to zero and smaller than the value -** output by xInstCount(). +** output by xInstCount(). If iIdx is less than zero or greater than +** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. ** -** Usually, output parameter *piPhrase is set to the phrase number, *piCol +** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. Returns SQLITE_OK if successful, or an error -** code (i.e. SQLITE_NOMEM) if an error occurs. +** first token of the phrase. SQLITE_OK is returned if successful, or an +** error code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -13183,6 +13194,10 @@ struct Fts5PhraseIter { ** Invoking Api.xUserData() returns a copy of the pointer passed as ** the third argument to pUserData. ** +** If parameter iPhrase is less than zero, or greater than or equal to +** the number of phrases in the query, as returned by xPhraseCount(), +** this function returns SQLITE_RANGE. +** ** If the callback function returns any value other than SQLITE_OK, the ** query is abandoned and the xQueryPhrase function returns immediately. ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. @@ -13297,9 +13312,42 @@ struct Fts5PhraseIter { ** ** xPhraseNextColumn() ** See xPhraseFirstColumn above. +** +** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase iPhrase of the current +** query. Before returning, output parameter *ppToken is set to point +** to a buffer containing the requested token, and *pnToken to the +** size of this buffer in bytes. +** +** If iPhrase or iToken are less than zero, or if iPhrase is greater than +** or equal to the number of phrases in the query as reported by +** xPhraseCount(), or if iToken is equal to or greater than the number of +** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken + are both zeroed. +** +** The output text is not a copy of the query text that specified the +** token. It is the output of the tokenizer module. For tokendata=1 +** tables, this includes any embedded 0x00 and trailing data. +** +** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase hit iIdx within the +** current row. If iIdx is less than zero or greater than or equal to the +** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, +** output variable (*ppToken) is set to point to a buffer containing the +** matching document token, and (*pnToken) to the size of that buffer in +** bytes. This API is not available if the specified token matches a +** prefix query term. In that case both output variables are always set +** to 0. +** +** The output text is not a copy of the document text that was tokenized. +** It is the output of the tokenizer module. For tokendata=1 tables, this +** includes any embedded 0x00 and trailing data. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ void *(*xUserData)(Fts5Context*); @@ -13334,6 +13382,13 @@ struct Fts5ExtensionApi { int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); + + /* Below this point are iVersion>=3 only */ + int (*xQueryToken)(Fts5Context*, + int iPhrase, int iToken, + const char **ppToken, int *pnToken + ); + int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); }; /* @@ -13820,7 +13875,7 @@ struct fts5_api { ** max_page_count macro. */ #ifndef SQLITE_MAX_PAGE_COUNT -# define SQLITE_MAX_PAGE_COUNT 1073741823 +# define SQLITE_MAX_PAGE_COUNT 0xfffffffe /* 4294967294 */ #endif /* @@ -13959,6 +14014,19 @@ struct fts5_api { # undef SQLITE_USE_SEH #endif +/* +** Enable SQLITE_DIRECT_OVERFLOW_READ, unless the build explicitly +** disables it using -DSQLITE_DIRECT_OVERFLOW_READ=0 +*/ +#if defined(SQLITE_DIRECT_OVERFLOW_READ) && SQLITE_DIRECT_OVERFLOW_READ+1==1 + /* Disable if -DSQLITE_DIRECT_OVERFLOW_READ=0 */ +# undef SQLITE_DIRECT_OVERFLOW_READ +#else + /* In all other cases, enable */ +# define SQLITE_DIRECT_OVERFLOW_READ 1 +#endif + + /* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never @@ -15841,7 +15909,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*); SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); -SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, u64*); SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*); SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); @@ -16428,6 +16496,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ #define P4_INTARRAY (-14) /* P4 is a vector of 32-bit integers */ #define P4_FUNCCTX (-15) /* P4 is a pointer to an sqlite3_context object */ +#define P4_TABLEREF (-16) /* Like P4_TABLE, but reference counted */ /* Error message codes for OP_Halt */ #define P5_ConstraintNotNull 1 @@ -16650,13 +16719,15 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Pagecount 178 #define OP_MaxPgcnt 179 #define OP_ClrSubtype 180 /* synopsis: r[P1].subtype = 0 */ -#define OP_FilterAdd 181 /* synopsis: filter(P1) += key(P3@P4) */ -#define OP_Trace 182 -#define OP_CursorHint 183 -#define OP_ReleaseReg 184 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 185 -#define OP_Explain 186 -#define OP_Abortable 187 +#define OP_GetSubtype 181 /* synopsis: r[P2] = r[P1].subtype */ +#define OP_SetSubtype 182 /* synopsis: r[P2].subtype = r[P1] */ +#define OP_FilterAdd 183 /* synopsis: filter(P1) += key(P3@P4) */ +#define OP_Trace 184 +#define OP_CursorHint 185 +#define OP_ReleaseReg 186 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 187 +#define OP_Explain 188 +#define OP_Abortable 189 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -16692,8 +16763,8 @@ typedef struct VdbeOpList VdbeOpList; /* 152 */ 0x00, 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04,\ /* 160 */ 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x50,\ -/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x00, 0x00, 0x00,\ -/* 184 */ 0x00, 0x00, 0x00, 0x00,} +/* 176 */ 0x40, 0x00, 0x10, 0x10, 0x02, 0x12, 0x12, 0x00,\ +/* 184 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,} /* The resolve3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -17954,11 +18025,11 @@ struct FuncDestructor { #define MFUNCTION(zName, nArg, xPtr, xFunc) \ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } -#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, iArg, xFunc) \ +#define JFUNCTION(zName, nArg, bUseCache, bWS, bRS, bJsonB, iArg, xFunc) \ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_FUNC_CONSTANT|\ SQLITE_UTF8|((bUseCache)*SQLITE_FUNC_RUNONLY)|\ ((bRS)*SQLITE_SUBTYPE)|((bWS)*SQLITE_RESULT_SUBTYPE), \ - SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } + SQLITE_INT_TO_PTR(iArg|((bJsonB)*JSON_BLOB)),0,xFunc,0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_FUNC_BUILTIN|\ SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ @@ -18593,6 +18664,7 @@ struct Index { unsigned isCovering:1; /* True if this is a covering index */ unsigned noSkipScan:1; /* Do not try to use skip-scan if true */ unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */ + unsigned bLowQual:1; /* sqlite_stat1 says this is a low-quality index */ unsigned bNoQuery:1; /* Do not use this index to optimize queries */ unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */ unsigned bHasVCol:1; /* Index references one or more VIRTUAL columns */ @@ -18706,6 +18778,7 @@ struct AggInfo { int iOBTab; /* Ephemeral table to implement ORDER BY */ u8 bOBPayload; /* iOBTab has payload columns separate from key */ u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */ + u8 bUseSubtype; /* Transfer subtype info through sorter */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ @@ -19239,6 +19312,7 @@ struct NameContext { int nRef; /* Number of names resolved by this context */ int nNcErr; /* Number of errors encountered while resolving names */ int ncFlags; /* Zero or more NC_* flags defined below */ + u32 nNestedSelect; /* Number of nested selects using this NC */ Select *pWinSelect; /* SELECT statement for any window functions */ }; @@ -19955,6 +20029,9 @@ struct sqlite3_str { ** ** 3. Make a (read-only) copy of a read-only RCStr string using ** sqlite3RCStrRef(). +** +** "String" is in the name, but an RCStr object can also be used to hold +** binary data. */ struct RCStr { u64 nRCRef; /* Number of references */ @@ -20013,6 +20090,9 @@ struct Sqlite3Config { u8 bSmallMalloc; /* Avoid large memory allocations if true */ u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ u8 bUseLongDouble; /* Make use of long double */ +#ifdef SQLITE_DEBUG + u8 bJsonSelfcheck; /* Double-check JSON parsing */ +#endif int mxStrlen; /* Maximum string length */ int neverCorrupt; /* Database is always well-formed */ int szLookaside; /* Default lookaside buffer size */ @@ -20639,6 +20719,7 @@ SQLITE_PRIVATE void sqlite3ExprOrderByAggregateError(Parse*,Expr*); SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); +SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3*,void*); SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*); SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*); SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); @@ -20648,6 +20729,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int); SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int); SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); +SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3*,void*); SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*); SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); @@ -20738,6 +20820,7 @@ SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); +SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3*, void*); SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*); #ifndef SQLITE_OMIT_AUTOINCREMENT SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); @@ -20774,6 +20857,7 @@ SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,u32,Expr*); SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); +SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3*,void*); SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, Trigger*); SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); @@ -21000,6 +21084,7 @@ SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); #endif SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); +SQLITE_PRIVATE int sqlite3Utf8ReadLimited(const u8*, int, u32*); SQLITE_PRIVATE LogEst sqlite3LogEst(u64); SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); @@ -21346,6 +21431,7 @@ SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8); SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*); SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*); SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); +SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3*,void*); SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); #else # define sqlite3CteNew(P,T,E,S) ((void*)0) @@ -22723,6 +22809,9 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* bSmallMalloc */ 1, /* bExtraSchemaChecks */ sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */ +#ifdef SQLITE_DEBUG + 0, /* bJsonSelfcheck */ +#endif 0x7ffffffe, /* mxStrlen */ 0, /* neverCorrupt */ SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ @@ -23975,7 +24064,7 @@ SQLITE_API int sqlite3_db_status( case SQLITE_DBSTATUS_CACHE_MISS: case SQLITE_DBSTATUS_CACHE_WRITE:{ int i; - int nRet = 0; + u64 nRet = 0; assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 ); assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 ); @@ -23988,7 +24077,7 @@ SQLITE_API int sqlite3_db_status( *pHighwater = 0; /* IMP: R-42420-56072 */ /* IMP: R-54100-20147 */ /* IMP: R-29431-39229 */ - *pCurrent = nRet; + *pCurrent = (int)nRet & 0x7fffffff; break; } @@ -25057,6 +25146,12 @@ static int isDate( } computeJD(p); if( p->isError || !validJulianDay(p->iJD) ) return 1; + if( argc==1 && p->validYMD && p->D>28 ){ + /* Make sure a YYYY-MM-DD is normalized. + ** Example: 2023-02-31 -> 2023-03-03 */ + assert( p->validJD ); + p->validYMD = 0; + } return 0; } @@ -32085,7 +32180,7 @@ SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ /***************************************************************************** -** Reference counted string storage +** Reference counted string/blob storage *****************************************************************************/ /* @@ -32937,7 +33032,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m assert( pExpr->x.pList->nExpr==2 ); pY = pExpr->x.pList->a[0].pExpr; pZ = pExpr->x.pList->a[1].pExpr; - sqlite3TreeViewLine(pView, "BETWEEN"); + sqlite3TreeViewLine(pView, "BETWEEN%s", zFlgs); sqlite3TreeViewExpr(pView, pX, 1); sqlite3TreeViewExpr(pView, pY, 1); sqlite3TreeViewExpr(pView, pZ, 0); @@ -34072,7 +34167,38 @@ SQLITE_PRIVATE u32 sqlite3Utf8Read( return c; } - +/* +** Read a single UTF8 character out of buffer z[], but reading no +** more than n characters from the buffer. z[] is not zero-terminated. +** +** Return the number of bytes used to construct the character. +** +** Invalid UTF8 might generate a strange result. No effort is made +** to detect invalid UTF8. +** +** At most 4 bytes will be read out of z[]. The return value will always +** be between 1 and 4. +*/ +SQLITE_PRIVATE int sqlite3Utf8ReadLimited( + const u8 *z, + int n, + u32 *piOut +){ + u32 c; + int i = 1; + assert( n>0 ); + c = z[0]; + if( c>=0xc0 ){ + c = sqlite3Utf8Trans1[c-0xc0]; + if( n>4 ) n = 4; + while( iiBusyTimeout; +#if SQLITE_ENABLE_SETLK_TIMEOUT==1 pFile->iBusyTimeout = *(int*)pArg; +#elif SQLITE_ENABLE_SETLK_TIMEOUT==2 + pFile->iBusyTimeout = !!(*(int*)pArg); +#else +# error "SQLITE_ENABLE_SETLK_TIMEOUT must be set to 1 or 2" +#endif *(int*)pArg = iOld; return SQLITE_OK; } @@ -42146,6 +42280,25 @@ static int unixGetpagesize(void){ ** Either unixShmNode.pShmMutex must be held or unixShmNode.nRef==0 and ** unixMutexHeld() is true when reading or writing any other field ** in this structure. +** +** aLock[SQLITE_SHM_NLOCK]: +** This array records the various locks held by clients on each of the +** SQLITE_SHM_NLOCK slots. If the aLock[] entry is set to 0, then no +** locks are held by the process on this slot. If it is set to -1, then +** some client holds an EXCLUSIVE lock on the locking slot. If the aLock[] +** value is set to a positive value, then it is the number of shared +** locks currently held on the slot. +** +** aMutex[SQLITE_SHM_NLOCK]: +** Normally, when SQLITE_ENABLE_SETLK_TIMEOUT is not defined, mutex +** pShmMutex is used to protect the aLock[] array and the right to +** call fcntl() on unixShmNode.hShm to obtain or release locks. +** +** If SQLITE_ENABLE_SETLK_TIMEOUT is defined though, we use an array +** of mutexes - one for each locking slot. To read or write locking +** slot aLock[iSlot], the caller must hold the corresponding mutex +** aMutex[iSlot]. Similarly, to call fcntl() to obtain or release a +** lock corresponding to slot iSlot, mutex aMutex[iSlot] must be held. */ struct unixShmNode { unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ @@ -42159,10 +42312,11 @@ struct unixShmNode { char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + sqlite3_mutex *aMutex[SQLITE_SHM_NLOCK]; +#endif int aLock[SQLITE_SHM_NLOCK]; /* # shared locks on slot, -1==excl lock */ #ifdef SQLITE_DEBUG - u8 exclMask; /* Mask of exclusive locks held */ - u8 sharedMask; /* Mask of shared locks held */ u8 nextShmId; /* Next available unixShm.id value */ #endif }; @@ -42245,16 +42399,35 @@ static int unixShmSystemLock( struct flock f; /* The posix advisory locking structure */ int rc = SQLITE_OK; /* Result code form fcntl() */ - /* Access to the unixShmNode object is serialized by the caller */ pShmNode = pFile->pInode->pShmNode; - assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); - assert( pShmNode->nRef>0 || unixMutexHeld() ); + + /* Assert that the parameters are within expected range and that the + ** correct mutex or mutexes are held. */ + assert( pShmNode->nRef>=0 ); + assert( (ofst==UNIX_SHM_DMS && n==1) + || (ofst>=UNIX_SHM_BASE && ofst+n<=(UNIX_SHM_BASE+SQLITE_SHM_NLOCK)) + ); + if( ofst==UNIX_SHM_DMS ){ + assert( pShmNode->nRef>0 || unixMutexHeld() ); + assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); + }else{ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int ii; + for(ii=ofst-UNIX_SHM_BASE; iiaMutex[ii]) ); + } +#else + assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); + assert( pShmNode->nRef>0 ); +#endif + } /* Shared locks never span more than one byte */ assert( n==1 || lockType!=F_RDLCK ); /* Locks are within range */ assert( n>=1 && n<=SQLITE_SHM_NLOCK ); + assert( ofst>=UNIX_SHM_BASE && ofst<=(UNIX_SHM_DMS+SQLITE_SHM_NLOCK) ); if( pShmNode->hShm>=0 ){ int res; @@ -42265,7 +42438,7 @@ static int unixShmSystemLock( f.l_len = n; res = osSetPosixAdvisoryLock(pShmNode->hShm, &f, pFile); if( res==-1 ){ -#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +#if defined(SQLITE_ENABLE_SETLK_TIMEOUT) && SQLITE_ENABLE_SETLK_TIMEOUT==1 rc = (pFile->iBusyTimeout ? SQLITE_BUSY_TIMEOUT : SQLITE_BUSY); #else rc = SQLITE_BUSY; @@ -42273,39 +42446,28 @@ static int unixShmSystemLock( } } - /* Update the global lock state and do debug tracing */ + /* Do debug tracing */ #ifdef SQLITE_DEBUG - { u16 mask; OSTRACE(("SHM-LOCK ")); - mask = ofst>31 ? 0xffff : (1<<(ofst+n)) - (1<exclMask &= ~mask; - pShmNode->sharedMask &= ~mask; + OSTRACE(("unlock %d..%d ok\n", ofst, ofst+n-1)); }else if( lockType==F_RDLCK ){ - OSTRACE(("read-lock %d ok", ofst)); - pShmNode->exclMask &= ~mask; - pShmNode->sharedMask |= mask; + OSTRACE(("read-lock %d..%d ok\n", ofst, ofst+n-1)); }else{ assert( lockType==F_WRLCK ); - OSTRACE(("write-lock %d ok", ofst)); - pShmNode->exclMask |= mask; - pShmNode->sharedMask &= ~mask; + OSTRACE(("write-lock %d..%d ok\n", ofst, ofst+n-1)); } }else{ if( lockType==F_UNLCK ){ - OSTRACE(("unlock %d failed", ofst)); + OSTRACE(("unlock %d..%d failed\n", ofst, ofst+n-1)); }else if( lockType==F_RDLCK ){ - OSTRACE(("read-lock failed")); + OSTRACE(("read-lock %d..%d failed\n", ofst, ofst+n-1)); }else{ assert( lockType==F_WRLCK ); - OSTRACE(("write-lock %d failed", ofst)); + OSTRACE(("write-lock %d..%d failed\n", ofst, ofst+n-1)); } } - OSTRACE((" - afterwards %03x,%03x\n", - pShmNode->sharedMask, pShmNode->exclMask)); - } #endif return rc; @@ -42342,6 +42504,11 @@ static void unixShmPurge(unixFile *pFd){ int i; assert( p->pInode==pFd->pInode ); sqlite3_mutex_free(p->pShmMutex); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + for(i=0; iaMutex[i]); + } +#endif for(i=0; inRegion; i+=nShmPerMap){ if( p->hShm>=0 ){ osMunmap(p->apRegion[i], p->szRegion); @@ -42401,7 +42568,20 @@ static int unixLockSharedMemory(unixFile *pDbFd, unixShmNode *pShmNode){ pShmNode->isUnlocked = 1; rc = SQLITE_READONLY_CANTINIT; }else{ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* Do not use a blocking lock here. If the lock cannot be obtained + ** immediately, it means some other connection is truncating the + ** *-shm file. And after it has done so, it will not release its + ** lock, but only downgrade it to a shared lock. So no point in + ** blocking here. The call below to obtain the shared DMS lock may + ** use a blocking lock. */ + int iSaveTimeout = pDbFd->iBusyTimeout; + pDbFd->iBusyTimeout = 0; +#endif rc = unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + pDbFd->iBusyTimeout = iSaveTimeout; +#endif /* The first connection to attach must truncate the -shm file. We ** truncate to 3 bytes (an arbitrary small number, less than the ** -shm header size) rather than 0 as a system debugging aid, to @@ -42522,6 +42702,18 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ rc = SQLITE_NOMEM_BKPT; goto shm_open_err; } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + { + int ii; + for(ii=0; iiaMutex[ii] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( pShmNode->aMutex[ii]==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto shm_open_err; + } + } + } +#endif } if( pInode->bProcessLock==0 ){ @@ -42743,9 +42935,11 @@ shmpage_out: */ #ifdef SQLITE_DEBUG static int assertLockingArrayOk(unixShmNode *pShmNode){ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + return 1; +#else unixShm *pX; int aLock[SQLITE_SHM_NLOCK]; - assert( sqlite3_mutex_held(pShmNode->pShmMutex) ); memset(aLock, 0, sizeof(aLock)); for(pX=pShmNode->pFirst; pX; pX=pX->pNext){ @@ -42763,13 +42957,14 @@ static int assertLockingArrayOk(unixShmNode *pShmNode){ assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) ); return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0); +#endif } #endif /* ** Change the lock state for a shared-memory segment. ** -** Note that the relationship between SHAREd and EXCLUSIVE locks is a little +** Note that the relationship between SHARED and EXCLUSIVE locks is a little ** different here than in posix. In xShmLock(), one can go from unlocked ** to shared and back or from unlocked to exclusive and back. But one may ** not go from shared to exclusive or from exclusive to shared. @@ -42784,7 +42979,7 @@ static int unixShmLock( unixShm *p; /* The shared memory being locked */ unixShmNode *pShmNode; /* The underlying file iNode */ int rc = SQLITE_OK; /* Result code */ - u16 mask; /* Mask of locks to take or release */ + u16 mask = (1<<(ofst+n)) - (1<pShm; @@ -42819,88 +43014,151 @@ static int unixShmLock( ** It is not permitted to block on the RECOVER lock. */ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT - assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( - (ofst!=2) /* not RECOVER */ - && (ofst!=1 || (p->exclMask|p->sharedMask)==0) - && (ofst!=0 || (p->exclMask|p->sharedMask)<3) - && (ofst<3 || (p->exclMask|p->sharedMask)<(1<exclMask|p->sharedMask); + assert( (flags & SQLITE_SHM_UNLOCK) || pDbFd->iBusyTimeout==0 || ( + (ofst!=2) /* not RECOVER */ + && (ofst!=1 || lockMask==0 || lockMask==2) + && (ofst!=0 || lockMask<3) + && (ofst<3 || lockMask<(1<1 || mask==(1<pShmMutex); - assert( assertLockingArrayOk(pShmNode) ); - if( flags & SQLITE_SHM_UNLOCK ){ - if( (p->exclMask|p->sharedMask) & mask ){ - int ii; - int bUnlock = 1; + /* Check if there is any work to do. There are three cases: + ** + ** a) An unlock operation where there are locks to unlock, + ** b) An shared lock where the requested lock is not already held + ** c) An exclusive lock where the requested lock is not already held + ** + ** The SQLite core never requests an exclusive lock that it already holds. + ** This is assert()ed below. + */ + assert( flags!=(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK) + || 0==(p->exclMask & mask) + ); + if( ((flags & SQLITE_SHM_UNLOCK) && ((p->exclMask|p->sharedMask) & mask)) + || (flags==(SQLITE_SHM_SHARED|SQLITE_SHM_LOCK) && 0==(p->sharedMask & mask)) + || (flags==(SQLITE_SHM_EXCLUSIVE|SQLITE_SHM_LOCK)) + ){ - for(ii=ofst; ii((p->sharedMask & (1<aMutex[iMutex]); + if( rc!=SQLITE_OK ) goto leave_shmnode_mutexes; + }else{ + sqlite3_mutex_enter(pShmNode->aMutex[iMutex]); } + } +#else + sqlite3_mutex_enter(pShmNode->pShmMutex); +#endif - if( bUnlock ){ - rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); + if( ALWAYS(rc==SQLITE_OK) ){ + if( flags & SQLITE_SHM_UNLOCK ){ + /* Case (a) - unlock. */ + int bUnlock = 1; + assert( (p->exclMask & p->sharedMask)==0 ); + assert( !(flags & SQLITE_SHM_EXCLUSIVE) || (p->exclMask & mask)==mask ); + assert( !(flags & SQLITE_SHM_SHARED) || (p->sharedMask & mask)==mask ); + + /* If this is a SHARED lock being unlocked, it is possible that other + ** clients within this process are holding the same SHARED lock. In + ** this case, set bUnlock to 0 so that the posix lock is not removed + ** from the file-descriptor below. */ + if( flags & SQLITE_SHM_SHARED ){ + assert( n==1 ); + assert( aLock[ofst]>=1 ); + if( aLock[ofst]>1 ){ + bUnlock = 0; + aLock[ofst]--; + p->sharedMask &= ~mask; + } + } + + if( bUnlock ){ + rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n); + if( rc==SQLITE_OK ){ + memset(&aLock[ofst], 0, sizeof(int)*n); + p->sharedMask &= ~mask; + p->exclMask &= ~mask; + } + } + }else if( flags & SQLITE_SHM_SHARED ){ + /* Case (b) - a shared lock. */ + + if( aLock[ofst]<0 ){ + /* An exclusive lock is held by some other connection. BUSY. */ + rc = SQLITE_BUSY; + }else if( aLock[ofst]==0 ){ + rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); + } + + /* Get the local shared locks */ if( rc==SQLITE_OK ){ - memset(&aLock[ofst], 0, sizeof(int)*n); + p->sharedMask |= mask; + aLock[ofst]++; } - }else if( ALWAYS(p->sharedMask & (1<1 ); - aLock[ofst]--; - } + }else{ + /* Case (c) - an exclusive lock. */ + int ii; - /* Undo the local locks */ - if( rc==SQLITE_OK ){ - p->exclMask &= ~mask; - p->sharedMask &= ~mask; - } - } - }else if( flags & SQLITE_SHM_SHARED ){ - assert( n==1 ); - assert( (p->exclMask & (1<sharedMask & mask)==0 ){ - if( aLock[ofst]<0 ){ - rc = SQLITE_BUSY; - }else if( aLock[ofst]==0 ){ - rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n); - } - - /* Get the local shared locks */ - if( rc==SQLITE_OK ){ - p->sharedMask |= mask; - aLock[ofst]++; - } - } - }else{ - /* Make sure no sibling connections hold locks that will block this - ** lock. If any do, return SQLITE_BUSY right away. */ - int ii; - for(ii=ofst; iisharedMask & mask)==0 ); - if( ALWAYS((p->exclMask & (1<sharedMask & mask)==0 ); - p->exclMask |= mask; + assert( (p->exclMask & mask)==0 ); + + /* Make sure no sibling connections hold locks that will block this + ** lock. If any do, return SQLITE_BUSY right away. */ for(ii=ofst; iiexclMask |= mask; + for(ii=ofst; ii=ofst; iMutex--){ + sqlite3_mutex_leave(pShmNode->aMutex[iMutex]); + } +#else + sqlite3_mutex_leave(pShmNode->pShmMutex); +#endif } - assert( assertLockingArrayOk(pShmNode) ); - sqlite3_mutex_leave(pShmNode->pShmMutex); + OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", p->id, osGetpid(0), p->sharedMask, p->exclMask)); return rc; @@ -43150,11 +43408,16 @@ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ #if SQLITE_MAX_MMAP_SIZE>0 if( pFd->mmapSizeMax>0 ){ + /* Ensure that there is always at least a 256 byte buffer of addressable + ** memory following the returned page. If the database is corrupt, + ** SQLite may overread the page slightly (in practice only a few bytes, + ** but 256 is safe, round, number). */ + const int nEofBuffer = 256; if( pFd->pMapRegion==0 ){ int rc = unixMapfile(pFd, -1); if( rc!=SQLITE_OK ) return rc; } - if( pFd->mmapSize >= iOff+nAmt ){ + if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ *pp = &((u8 *)pFd->pMapRegion)[iOff]; pFd->nFetchOut++; } @@ -50507,6 +50770,11 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ #if SQLITE_MAX_MMAP_SIZE>0 if( pFd->mmapSizeMax>0 ){ + /* Ensure that there is always at least a 256 byte buffer of addressable + ** memory following the returned page. If the database is corrupt, + ** SQLite may overread the page slightly (in practice only a few bytes, + ** but 256 is safe, round, number). */ + const int nEofBuffer = 256; if( pFd->pMapRegion==0 ){ int rc = winMapfile(pFd, -1); if( rc!=SQLITE_OK ){ @@ -50515,7 +50783,7 @@ static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ return rc; } } - if( pFd->mmapSize >= iOff+nAmt ){ + if( pFd->mmapSize >= (iOff+nAmt+nEofBuffer) ){ assert( pFd->pMapRegion!=0 ); *pp = &((u8 *)pFd->pMapRegion)[iOff]; pFd->nFetchOut++; @@ -57118,7 +57386,7 @@ struct Pager { char *zJournal; /* Name of the journal file */ int (*xBusyHandler)(void*); /* Function to call when busy */ void *pBusyHandlerArg; /* Context argument for xBusyHandler */ - int aStat[4]; /* Total cache hits, misses, writes, spills */ + u32 aStat[4]; /* Total cache hits, misses, writes, spills */ #ifdef SQLITE_TEST int nRead; /* Database pages read */ #endif @@ -57248,9 +57516,8 @@ SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ #ifndef SQLITE_OMIT_WAL if( pPager->pWal ){ u32 iRead = 0; - int rc; - rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); - return (rc==SQLITE_OK && iRead==0); + (void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); + return iRead==0; } #endif return 1; @@ -63262,11 +63529,11 @@ SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; a[4] = pPager->eState; a[5] = pPager->errCode; - a[6] = pPager->aStat[PAGER_STAT_HIT]; - a[7] = pPager->aStat[PAGER_STAT_MISS]; + a[6] = (int)pPager->aStat[PAGER_STAT_HIT] & 0x7fffffff; + a[7] = (int)pPager->aStat[PAGER_STAT_MISS] & 0x7fffffff; a[8] = 0; /* Used to be pPager->nOvfl */ a[9] = pPager->nRead; - a[10] = pPager->aStat[PAGER_STAT_WRITE]; + a[10] = (int)pPager->aStat[PAGER_STAT_WRITE] & 0x7fffffff; return a; } #endif @@ -63282,7 +63549,7 @@ SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ ** reset parameter is non-zero, the cache hit or miss count is zeroed before ** returning. */ -SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, u64 *pnVal){ assert( eStat==SQLITE_DBSTATUS_CACHE_HIT || eStat==SQLITE_DBSTATUS_CACHE_MISS @@ -64222,7 +64489,7 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ } #endif -#ifdef SQLITE_USE_SEH +#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) SQLITE_PRIVATE int sqlite3PagerWalSystemErrno(Pager *pPager){ return sqlite3WalSystemErrno(pPager->pWal); } @@ -66238,6 +66505,19 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ } #ifdef SQLITE_ENABLE_SETLK_TIMEOUT + + +/* +** Attempt to enable blocking locks that block for nMs ms. Return 1 if +** blocking locks are successfully enabled, or 0 otherwise. +*/ +static int walEnableBlockingMs(Wal *pWal, int nMs){ + int rc = sqlite3OsFileControl( + pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&nMs + ); + return (rc==SQLITE_OK); +} + /* ** Attempt to enable blocking locks. Blocking locks are enabled only if (a) ** they are supported by the VFS, and (b) the database handle is configured @@ -66249,11 +66529,7 @@ static int walEnableBlocking(Wal *pWal){ if( pWal->db ){ int tmout = pWal->db->busyTimeout; if( tmout ){ - int rc; - rc = sqlite3OsFileControl( - pWal->pDbFd, SQLITE_FCNTL_LOCK_TIMEOUT, (void*)&tmout - ); - res = (rc==SQLITE_OK); + res = walEnableBlockingMs(pWal, tmout); } } return res; @@ -66302,20 +66578,10 @@ SQLITE_PRIVATE void sqlite3WalDb(Wal *pWal, sqlite3 *db){ pWal->db = db; } -/* -** Take an exclusive WRITE lock. Blocking if so configured. -*/ -static int walLockWriter(Wal *pWal){ - int rc; - walEnableBlocking(pWal); - rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1); - walDisableBlocking(pWal); - return rc; -} #else # define walEnableBlocking(x) 0 # define walDisableBlocking(x) -# define walLockWriter(pWal) walLockExclusive((pWal), WAL_WRITE_LOCK, 1) +# define walEnableBlockingMs(pWal, ms) 0 # define sqlite3WalDb(pWal, db) #endif /* ifdef SQLITE_ENABLE_SETLK_TIMEOUT */ @@ -66916,7 +67182,9 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ } }else{ int bWriteLock = pWal->writeLock; - if( bWriteLock || SQLITE_OK==(rc = walLockWriter(pWal)) ){ + if( bWriteLock + || SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) + ){ pWal->writeLock = 1; if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ badHdr = walIndexTryHdr(pWal, pChanged); @@ -66924,7 +67192,8 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){ /* If the wal-index header is still malformed even while holding ** a WRITE lock, it can only mean that the header is corrupted and ** needs to be reconstructed. So run recovery to do exactly that. - */ + ** Disable blocking locks first. */ + walDisableBlocking(pWal); rc = walIndexRecover(pWal); *pChanged = 1; } @@ -67134,6 +67403,37 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ return rc; } +/* +** The final argument passed to walTryBeginRead() is of type (int*). The +** caller should invoke walTryBeginRead as follows: +** +** int cnt = 0; +** do { +** rc = walTryBeginRead(..., &cnt); +** }while( rc==WAL_RETRY ); +** +** The final value of "cnt" is of no use to the caller. It is used by +** the implementation of walTryBeginRead() as follows: +** +** + Each time walTryBeginRead() is called, it is incremented. Once +** it reaches WAL_RETRY_PROTOCOL_LIMIT - indicating that walTryBeginRead() +** has many times been invoked and failed with WAL_RETRY - walTryBeginRead() +** returns SQLITE_PROTOCOL. +** +** + If SQLITE_ENABLE_SETLK_TIMEOUT is defined and walTryBeginRead() failed +** because a blocking lock timed out (SQLITE_BUSY_TIMEOUT from the OS +** layer), the WAL_RETRY_BLOCKED_MASK bit is set in "cnt". In this case +** the next invocation of walTryBeginRead() may omit an expected call to +** sqlite3OsSleep(). There has already been a delay when the previous call +** waited on a lock. +*/ +#define WAL_RETRY_PROTOCOL_LIMIT 100 +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +# define WAL_RETRY_BLOCKED_MASK 0x10000000 +#else +# define WAL_RETRY_BLOCKED_MASK 0 +#endif + /* ** Attempt to start a read transaction. This might fail due to a race or ** other transient condition. When that happens, it returns WAL_RETRY to @@ -67184,13 +67484,16 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ ** so it takes care to hold an exclusive lock on the corresponding ** WAL_READ_LOCK() while changing values. */ -static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ +static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int *pCnt){ volatile WalCkptInfo *pInfo; /* Checkpoint information in wal-index */ u32 mxReadMark; /* Largest aReadMark[] value */ int mxI; /* Index of largest aReadMark[] value */ int i; /* Loop counter */ int rc = SQLITE_OK; /* Return code */ u32 mxFrame; /* Wal frame to lock to */ +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + int nBlockTmout = 0; +#endif assert( pWal->readLock<0 ); /* Not currently locked */ @@ -67214,14 +67517,34 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ ** so that on the 100th (and last) RETRY we delay for 323 milliseconds. ** The total delay time before giving up is less than 10 seconds. */ - if( cnt>5 ){ + (*pCnt)++; + if( *pCnt>5 ){ int nDelay = 1; /* Pause time in microseconds */ - if( cnt>100 ){ + int cnt = (*pCnt & ~WAL_RETRY_BLOCKED_MASK); + if( cnt>WAL_RETRY_PROTOCOL_LIMIT ){ VVA_ONLY( pWal->lockError = 1; ) return SQLITE_PROTOCOL; } - if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; + if( *pCnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + /* In SQLITE_ENABLE_SETLK_TIMEOUT builds, configure the file-descriptor + ** to block for locks for approximately nDelay us. This affects three + ** locks: (a) the shared lock taken on the DMS slot in os_unix.c (if + ** using os_unix.c), (b) the WRITER lock taken in walIndexReadHdr() if the + ** first attempted read fails, and (c) the shared lock taken on the + ** read-mark. + ** + ** If the previous call failed due to an SQLITE_BUSY_TIMEOUT error, + ** then sleep for the minimum of 1us. The previous call already provided + ** an extra delay while it was blocking on the lock. + */ + nBlockTmout = (nDelay+998) / 1000; + if( !useWal && walEnableBlockingMs(pWal, nBlockTmout) ){ + if( *pCnt & WAL_RETRY_BLOCKED_MASK ) nDelay = 1; + } +#endif sqlite3OsSleep(pWal->pVfs, nDelay); + *pCnt &= ~WAL_RETRY_BLOCKED_MASK; } if( !useWal ){ @@ -67229,6 +67552,13 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ if( pWal->bShmUnreliable==0 ){ rc = walIndexReadHdr(pWal, pChanged); } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + walDisableBlocking(pWal); + if( rc==SQLITE_BUSY_TIMEOUT ){ + rc = SQLITE_BUSY; + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } +#endif if( rc==SQLITE_BUSY ){ /* If there is not a recovery running in another thread or process ** then convert BUSY errors to WAL_RETRY. If recovery is known to @@ -67343,9 +67673,19 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTINIT; } + (void)walEnableBlockingMs(pWal, nBlockTmout); rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); + walDisableBlocking(pWal); if( rc ){ - return rc==SQLITE_BUSY ? WAL_RETRY : rc; +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT + if( rc==SQLITE_BUSY_TIMEOUT ){ + *pCnt |= WAL_RETRY_BLOCKED_MASK; + } +#else + assert( rc!=SQLITE_BUSY_TIMEOUT ); +#endif + assert( (rc&0xFF)!=SQLITE_BUSY||rc==SQLITE_BUSY||rc==SQLITE_BUSY_TIMEOUT ); + return (rc&0xFF)==SQLITE_BUSY ? WAL_RETRY : rc; } /* Now that the read-lock has been obtained, check that neither the ** value in the aReadMark[] array or the contents of the wal-index @@ -67533,7 +67873,7 @@ static int walBeginReadTransaction(Wal *pWal, int *pChanged){ #endif do{ - rc = walTryBeginRead(pWal, pChanged, 0, ++cnt); + rc = walTryBeginRead(pWal, pChanged, 0, &cnt); }while( rc==WAL_RETRY ); testcase( (rc&0xff)==SQLITE_BUSY ); testcase( (rc&0xff)==SQLITE_IOERR ); @@ -67714,6 +68054,7 @@ static int walFindFrame( iRead = iFrame; } if( (nCollide--)==0 ){ + *piRead = 0; return SQLITE_CORRUPT_BKPT; } iKey = walNextHash(iKey); @@ -68017,7 +68358,7 @@ static int walRestartLog(Wal *pWal){ cnt = 0; do{ int notUsed; - rc = walTryBeginRead(pWal, ¬Used, 1, ++cnt); + rc = walTryBeginRead(pWal, ¬Used, 1, &cnt); }while( rc==WAL_RETRY ); assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */ testcase( (rc&0xff)==SQLITE_IOERR ); @@ -68438,10 +68779,9 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( if( pWal->readOnly ) return SQLITE_READONLY; WALTRACE(("WAL%p: checkpoint begins\n", pWal)); - /* Enable blocking locks, if possible. If blocking locks are successfully - ** enabled, set xBusy2=0 so that the busy-handler is never invoked. */ + /* Enable blocking locks, if possible. */ sqlite3WalDb(pWal, db); - (void)walEnableBlocking(pWal); + if( xBusy2 ) (void)walEnableBlocking(pWal); /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive ** "checkpoint" lock on the database file. @@ -68482,9 +68822,14 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint( /* Read the wal-index header. */ SEH_TRY { if( rc==SQLITE_OK ){ + /* For a passive checkpoint, do not re-enable blocking locks after + ** reading the wal-index header. A passive checkpoint should not block + ** or invoke the busy handler. The only lock such a checkpoint may + ** attempt to obtain is a lock on a read-slot, and it should give up + ** immediately and do a partial checkpoint if it cannot obtain it. */ walDisableBlocking(pWal); rc = walIndexReadHdr(pWal, &isChanged); - (void)walEnableBlocking(pWal); + if( eMode2!=SQLITE_CHECKPOINT_PASSIVE ) (void)walEnableBlocking(pWal); if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ sqlite3OsUnfetch(pWal->pDbFd, 0, 0); } @@ -68821,7 +69166,7 @@ SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ ** 22 1 Min embedded payload fraction (must be 32) ** 23 1 Min leaf payload fraction (must be 32) ** 24 4 File change counter -** 28 4 Reserved for future use +** 28 4 The size of the database in pages ** 32 4 First freelist page ** 36 4 Number of freelist pages in the file ** 40 60 15 4-byte meta values passed to higher layers @@ -74948,7 +75293,6 @@ static int accessPayload( assert( aWrite>=pBufStart ); /* due to (6) */ memcpy(aSave, aWrite, 4); rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); - if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT; nextPage = get4byte(aWrite); memcpy(aWrite, aSave, 4); }else @@ -76068,7 +76412,10 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ } pPage = pCur->pPage; - assert( pPage->isInit ); + if( sqlite3FaultSim(412) ) pPage->isInit = 0; + if( !pPage->isInit ){ + return SQLITE_CORRUPT_BKPT; + } if( !pPage->leaf ){ int idx = pCur->ix; rc = moveToChild(pCur, get4byte(findCell(pPage, idx))); @@ -84183,10 +84530,11 @@ static int growOpArray(Vdbe *v, int nOp){ ** sqlite3CantopenError(lineno) */ static void test_addop_breakpoint(int pc, Op *pOp){ - static int n = 0; + static u64 n = 0; (void)pc; (void)pOp; n++; + if( n==LARGEST_UINT64 ) abort(); /* so that n is used, preventing a warning */ } #endif @@ -85371,6 +85719,10 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); break; } + case P4_TABLEREF: { + if( db->pnBytesFreed==0 ) sqlite3DeleteTable(db, (Table*)p4); + break; + } } } @@ -85498,7 +85850,7 @@ static void SQLITE_NOINLINE vdbeChangeP4Full( int n ){ if( pOp->p4type ){ - freeP4(p->db, pOp->p4type, pOp->p4.p); + assert( pOp->p4type > P4_FREE_IF_LE ); pOp->p4type = 0; pOp->p4.p = 0; } @@ -89621,7 +89973,15 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ int rc = SQLITE_OK; Vdbe *p = (Vdbe*)pStmt; #if SQLITE_THREADSAFE - sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex; + sqlite3_mutex *mutex; +#endif +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif +#if SQLITE_THREADSAFE + mutex = p->db->mutex; #endif sqlite3_mutex_enter(mutex); for(i=0; inVar; i++){ @@ -90411,9 +90771,8 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ #ifdef SQLITE_ENABLE_API_ARMOR if( p==0 ) return 0; -#else - assert( p && p->pFunc ); #endif + assert( p && p->pFunc ); return p->pFunc->pUserData; } @@ -92330,11 +92689,12 @@ SQLITE_API int sqlite3_found_count = 0; ** sqlite3CantopenError(lineno) */ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ - static int n = 0; + static u64 n = 0; (void)pc; (void)pOp; (void)v; n++; + if( n==LARGEST_UINT64 ) abort(); /* So that n is used, preventing a warning */ } #endif @@ -94231,7 +94591,7 @@ case OP_AddImm: { /* in1 */ pIn1 = &aMem[pOp->p1]; memAboutToChange(p, pIn1); sqlite3VdbeMemIntegerify(pIn1); - pIn1->u.i += pOp->p2; + *(u64*)&pIn1->u.i += (u64)pOp->p2; break; } @@ -100377,9 +100737,10 @@ case OP_VCheck: { /* out2 */ pOut = &aMem[pOp->p2]; sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ - assert( pOp->p4type==P4_TABLE ); + assert( pOp->p4type==P4_TABLEREF ); pTab = pOp->p4.pTab; assert( pTab!=0 ); + assert( pTab->nTabRef>0 ); assert( IsVirtual(pTab) ); if( pTab->u.vtab.p==0 ) break; pVtab = pTab->u.vtab.p->pVtab; @@ -100388,13 +100749,11 @@ case OP_VCheck: { /* out2 */ assert( pModule!=0 ); assert( pModule->iVersion>=4 ); assert( pModule->xIntegrity!=0 ); - pTab->nTabRef++; sqlite3VtabLock(pTab->u.vtab.p); assert( pOp->p1>=0 && pOp->p1nDb ); rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName, pOp->p3, &zErr); sqlite3VtabUnlock(pTab->u.vtab.p); - sqlite3DeleteTable(db, pTab); if( rc ){ sqlite3_free(zErr); goto abort_due_to_error; @@ -100519,6 +100878,7 @@ case OP_VColumn: { /* ncycle */ const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; + FuncDef nullFunc; VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur!=0 ); @@ -100536,6 +100896,9 @@ case OP_VColumn: { /* ncycle */ memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; sContext.enc = encoding; + nullFunc.pUserData = 0; + nullFunc.funcFlags = SQLITE_RESULT_SUBTYPE; + sContext.pFunc = &nullFunc; assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 ); if( pOp->p5 & OPFLAG_NOCHNG ){ sqlite3VdbeMemSetNull(pDest); @@ -100868,6 +101231,42 @@ case OP_ClrSubtype: { /* in1 */ break; } +/* Opcode: GetSubtype P1 P2 * * * +** Synopsis: r[P2] = r[P1].subtype +** +** Extract the subtype value from register P1 and write that subtype +** into register P2. If P1 has no subtype, then P1 gets a NULL. +*/ +case OP_GetSubtype: { /* in1 out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( pIn1->flags & MEM_Subtype ){ + sqlite3VdbeMemSetInt64(pOut, pIn1->eSubtype); + }else{ + sqlite3VdbeMemSetNull(pOut); + } + break; +} + +/* Opcode: SetSubtype P1 P2 * * * +** Synopsis: r[P2].subtype = r[P1] +** +** Set the subtype value of register P2 to the integer from register P1. +** If P1 is NULL, clear the subtype from p2. +*/ +case OP_SetSubtype: { /* in1 out2 */ + pIn1 = &aMem[pOp->p1]; + pOut = &aMem[pOp->p2]; + if( pIn1->flags & MEM_Null ){ + pOut->flags &= ~MEM_Subtype; + }else{ + assert( pIn1->flags & MEM_Int ); + pOut->flags |= MEM_Subtype; + pOut->eSubtype = (u8)(pIn1->u.i & 0xff); + } + break; +} + /* Opcode: FilterAdd P1 * P3 P4 * ** Synopsis: filter(P1) += key(P3@P4) ** @@ -105916,6 +106315,7 @@ SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){ assert( ExprUseYTab(pExpr) ); pExTab = pExpr->y.pTab; assert( pExTab!=0 ); + assert( n < pExTab->nCol ); if( (pExTab->tabFlags & TF_HasGenerated)!=0 && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 ){ @@ -106492,6 +106892,7 @@ static int lookupName( sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); pParse->checkSchema = 1; pTopNC->nNcErr++; + eNewExprOp = TK_NULL; } assert( pFJMatch==0 ); @@ -106518,7 +106919,7 @@ static int lookupName( ** If a generated column is referenced, set bits for every column ** of the table. */ - if( pExpr->iColumn>=0 && pMatch!=0 ){ + if( pExpr->iColumn>=0 && cnt==1 && pMatch!=0 ){ pMatch->colUsed |= sqlite3ExprColUsed(pExpr); } @@ -106983,11 +107384,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ while( pNC2 && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0 ){ - pExpr->op2++; + pExpr->op2 += (1 + pNC2->nNestedSelect); pNC2 = pNC2->pNext; } assert( pDef!=0 || IN_RENAME_OBJECT ); if( pNC2 && pDef ){ + pExpr->op2 += pNC2->nNestedSelect; assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg ); testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); @@ -107546,6 +107948,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Recursively resolve names in all subqueries in the FROM clause */ + if( pOuterNC ) pOuterNC->nNestedSelect++; for(i=0; ipSrc->nSrc; i++){ SrcItem *pItem = &p->pSrc->a[i]; if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ @@ -107570,6 +107973,9 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } } } + if( pOuterNC && ALWAYS(pOuterNC->nNestedSelect>0) ){ + pOuterNC->nNestedSelect--; + } /* Set up the local name-context to pass to sqlite3ResolveExprNames() to ** resolve the result-set expression list. @@ -109157,9 +109563,7 @@ SQLITE_PRIVATE void sqlite3ExprAddFunctionOrderBy( assert( ExprUseXList(pExpr) ); if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){ /* Ignore ORDER BY on zero-argument aggregates */ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - pOrderBy); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pOrderBy); return; } if( IsWindowFunc(pExpr) ){ @@ -109340,6 +109744,9 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ if( p ) sqlite3ExprDeleteNN(db, p); } +SQLITE_PRIVATE void sqlite3ExprDeleteGeneric(sqlite3 *db, void *p){ + if( ALWAYS(p) ) sqlite3ExprDeleteNN(db, (Expr*)p); +} /* ** Clear both elements of an OnOrUsing object @@ -109365,9 +109772,7 @@ SQLITE_PRIVATE void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ ** pExpr to the pParse->pConstExpr list with a register number of 0. */ SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprDelete, - pExpr); + sqlite3ParserAddCleanup(pParse, sqlite3ExprDeleteGeneric, pExpr); } /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the @@ -110173,6 +110578,9 @@ static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ if( pList ) exprListDeleteNN(db, pList); } +SQLITE_PRIVATE void sqlite3ExprListDeleteGeneric(sqlite3 *db, void *pList){ + if( ALWAYS(pList) ) exprListDeleteNN(db, (ExprList*)pList); +} /* ** Return the bitwise-OR of all Expr.flags fields in the given @@ -110672,9 +111080,10 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ case TK_COLUMN: assert( ExprUseYTab(p) ); return ExprHasProperty(p, EP_CanBeNull) || - p->y.pTab==0 || /* Reference to column of index on expression */ + NEVER(p->y.pTab==0) || /* Reference to column of index on expr */ (p->iColumn>=0 && p->y.pTab->aCol!=0 /* Possible due to prior error */ + && ALWAYS(p->iColumny.pTab->nCol) && p->y.pTab->aCol[p->iColumn].notNull==0); default: return 1; @@ -113256,8 +113665,10 @@ SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); if( inReg!=target ){ u8 op; - if( ALWAYS(pExpr) - && (ExprHasProperty(pExpr,EP_Subquery) || pExpr->op==TK_REGISTER) + Expr *pX = sqlite3ExprSkipCollateAndLikely(pExpr); + testcase( pX!=pExpr ); + if( ALWAYS(pX) + && (ExprHasProperty(pX,EP_Subquery) || pX->op==TK_REGISTER) ){ op = OP_Copy; }else{ @@ -114703,13 +115114,14 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ case TK_AGG_FUNCTION: { if( (pNC->ncFlags & NC_InAggFunc)==0 && pWalker->walkerDepth==pExpr->op2 + && pExpr->pAggInfo==0 ){ /* Check to see if pExpr is a duplicate of another aggregate ** function that is already in the pAggInfo structure */ struct AggInfo_func *pItem = pAggInfo->aFunc; for(i=0; inFunc; i++, pItem++){ - if( pItem->pFExpr==pExpr ) break; + if( NEVER(pItem->pFExpr==pExpr) ) break; if( sqlite3ExprCompare(0, pItem->pFExpr, pExpr, -1)==0 ){ break; } @@ -114752,6 +115164,8 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ }else{ pItem->bOBPayload = 1; } + pItem->bUseSubtype = + (pItem->pFunc->funcFlags & SQLITE_SUBTYPE)!=0; }else{ pItem->iOBTab = -1; } @@ -117518,9 +117932,9 @@ static void openStatTable( typedef struct StatAccum StatAccum; typedef struct StatSample StatSample; struct StatSample { - tRowcnt *anEq; /* sqlite_stat4.nEq */ tRowcnt *anDLt; /* sqlite_stat4.nDLt */ #ifdef SQLITE_ENABLE_STAT4 + tRowcnt *anEq; /* sqlite_stat4.nEq */ tRowcnt *anLt; /* sqlite_stat4.nLt */ union { i64 iRowid; /* Rowid in main table of the key */ @@ -117678,9 +118092,9 @@ static void statInit( /* Allocate the space required for the StatAccum object */ n = sizeof(*p) - + sizeof(tRowcnt)*nColUp /* StatAccum.anEq */ - + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ + + sizeof(tRowcnt)*nColUp; /* StatAccum.anDLt */ #ifdef SQLITE_ENABLE_STAT4 + n += sizeof(tRowcnt)*nColUp; /* StatAccum.anEq */ if( mxSample ){ n += sizeof(tRowcnt)*nColUp /* StatAccum.anLt */ + sizeof(StatSample)*(nCol+mxSample) /* StatAccum.aBest[], a[] */ @@ -117701,9 +118115,9 @@ static void statInit( p->nKeyCol = nKeyCol; p->nSkipAhead = 0; p->current.anDLt = (tRowcnt*)&p[1]; - p->current.anEq = &p->current.anDLt[nColUp]; #ifdef SQLITE_ENABLE_STAT4 + p->current.anEq = &p->current.anDLt[nColUp]; p->mxSample = p->nLimit==0 ? mxSample : 0; if( mxSample ){ u8 *pSpace; /* Allocated space not yet assigned */ @@ -117970,7 +118384,9 @@ static void statPush( if( p->nRow==0 ){ /* This is the first call to this function. Do initialization. */ +#ifdef SQLITE_ENABLE_STAT4 for(i=0; inCol; i++) p->current.anEq[i] = 1; +#endif }else{ /* Second and subsequent calls get processed here */ #ifdef SQLITE_ENABLE_STAT4 @@ -117979,15 +118395,17 @@ static void statPush( /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply ** to the current row of the index. */ +#ifdef SQLITE_ENABLE_STAT4 for(i=0; icurrent.anEq[i]++; } +#endif for(i=iChng; inCol; i++){ p->current.anDLt[i]++; #ifdef SQLITE_ENABLE_STAT4 if( p->mxSample ) p->current.anLt[i] += p->current.anEq[i]; -#endif p->current.anEq[i] = 1; +#endif } } @@ -118121,7 +118539,9 @@ static void statGet( u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; sqlite3_str_appendf(&sStat, " %llu", iVal); +#ifdef SQLITE_ENABLE_STAT4 assert( p->current.anEq[i] ); +#endif } sqlite3ResultStrAccum(context, &sStat); } @@ -118810,6 +119230,16 @@ static void decodeIntArray( while( z[0]!=0 && z[0]!=' ' ) z++; while( z[0]==' ' ) z++; } + + /* Set the bLowQual flag if the peak number of rows obtained + ** from a full equality match is so large that a full table scan + ** seems likely to be faster than using the index. + */ + if( aLog[0] > 66 /* Index has more than 100 rows */ + && aLog[0] <= aLog[nOut-1] /* And only a single value seen */ + ){ + pIndex->bLowQual = 1; + } } } @@ -120856,7 +121286,7 @@ SQLITE_PRIVATE void sqlite3ColumnSetExpr( */ SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ if( pCol->iDflt==0 ) return 0; - if( NEVER(!IsOrdinaryTable(pTab)) ) return 0; + if( !IsOrdinaryTable(pTab) ) return 0; if( NEVER(pTab->u.tab.pDfltList==0) ) return 0; if( NEVER(pTab->u.tab.pDfltList->nExpriDflt) ) return 0; return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; @@ -121009,6 +121439,9 @@ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ if( db->pnBytesFreed==0 && (--pTable->nTabRef)>0 ) return; deleteTable(db, pTable); } +SQLITE_PRIVATE void sqlite3DeleteTableGeneric(sqlite3 *db, void *pTable){ + sqlite3DeleteTable(db, (Table*)pTable); +} /* @@ -121546,7 +121979,8 @@ SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ /* ** Clean up the data structures associated with the RETURNING clause. */ -static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ +static void sqlite3DeleteReturning(sqlite3 *db, void *pArg){ + Returning *pRet = (Returning*)pArg; Hash *pHash; pHash = &(db->aDb[1].pSchema->trigHash); sqlite3HashInsert(pHash, pRet->zName, 0); @@ -121588,8 +122022,7 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ pParse->u1.pReturning = pRet; pRet->pParse = pParse; pRet->pReturnEL = pList; - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); + sqlite3ParserAddCleanup(pParse, sqlite3DeleteReturning, pRet); testcase( pParse->earlyCleanup ); if( db->mallocFailed ) return; sqlite3_snprintf(sizeof(pRet->zName), pRet->zName, @@ -121788,7 +122221,8 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){ assert( zIn!=0 ); while( zIn[0] ){ - h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff]; + u8 x = *(u8*)zIn; + h = (h<<8) + sqlite3UpperToLower[x]; zIn++; if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ aff = SQLITE_AFF_TEXT; @@ -125653,7 +126087,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ if( iDb<0 ) return; z = sqlite3NameFromToken(db, pObjName); if( z==0 ) return; - zDb = db->aDb[iDb].zDbSName; + zDb = pName2->n ? db->aDb[iDb].zDbSName : 0; pTab = sqlite3FindTable(db, z, zDb); if( pTab ){ reindexTable(pParse, pTab, 0); @@ -125663,6 +126097,7 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ pIndex = sqlite3FindIndex(db, z, zDb); sqlite3DbFree(db, z); if( pIndex ){ + iDb = sqlite3SchemaToIndex(db, pIndex->pTable->pSchema); sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3RefillIndex(pParse, pIndex, -1); return; @@ -125828,6 +126263,9 @@ SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ sqlite3DbFree(db, pWith); } } +SQLITE_PRIVATE void sqlite3WithDeleteGeneric(sqlite3 *db, void *pWith){ + sqlite3WithDelete(db, (With*)pWith); +} #endif /* !defined(SQLITE_OMIT_CTE) */ /************** End of build.c ***********************************************/ @@ -139053,7 +139491,8 @@ SQLITE_PRIVATE void sqlite3Pragma( if( pVTab->pModule->iVersion<4 ) continue; if( pVTab->pModule->xIntegrity==0 ) continue; sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); - sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + pTab->nTabRef++; + sqlite3VdbeAppendP4(v, pTab, P4_TABLEREF); a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); integrityCheckResultRow(v); sqlite3VdbeJumpHere(v, a1); @@ -141080,6 +141519,7 @@ static int sqlite3LockAndPrepare( assert( (rc&db->errMask)==rc ); db->busyHandler.nBusy = 0; sqlite3_mutex_leave(db->mutex); + assert( rc==SQLITE_OK || (*ppStmt)==0 ); return rc; } @@ -141477,6 +141917,9 @@ SQLITE_PRIVATE Select *sqlite3SelectNew( SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); } +SQLITE_PRIVATE void sqlite3SelectDeleteGeneric(sqlite3 *db, void *p){ + if( ALWAYS(p) ) clearSelect(db, (Select*)p, 1); +} /* ** Return a pointer to the right-most SELECT statement in a compound. @@ -143612,7 +144055,8 @@ SQLITE_PRIVATE void sqlite3SubqueryColumnTypes( NameContext sNC; assert( pSelect!=0 ); - assert( (pSelect->selFlags & SF_Resolved)!=0 ); + testcase( (pSelect->selFlags & SF_Resolved)==0 ); + assert( (pSelect->selFlags & SF_Resolved)!=0 || IN_RENAME_OBJECT ); assert( pTab->nCol==pSelect->pEList->nExpr || pParse->nErr>0 ); assert( aff==SQLITE_AFF_NONE || aff==SQLITE_AFF_BLOB ); if( db->mallocFailed || IN_RENAME_OBJECT ) return; @@ -144496,9 +144940,7 @@ multi_select_end: pDest->iSdst = dest.iSdst; pDest->nSdst = dest.nSdst; if( pDelete ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3SelectDelete, - pDelete); + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pDelete); } return rc; } @@ -145049,8 +145491,7 @@ static int multiSelectOrderBy( /* Make arrangements to free the 2nd and subsequent arms of the compound ** after the parse has finished */ if( pSplit->pPrior ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior); + sqlite3ParserAddCleanup(pParse, sqlite3SelectDeleteGeneric, pSplit->pPrior); } pSplit->pPrior = pPrior; pPrior->pNext = pSplit; @@ -145871,9 +146312,7 @@ static int flattenSubquery( Table *pTabToDel = pSubitem->pTab; if( pTabToDel->nTabRef==1 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); - sqlite3ParserAddCleanup(pToplevel, - (void(*)(sqlite3*,void*))sqlite3DeleteTable, - pTabToDel); + sqlite3ParserAddCleanup(pToplevel, sqlite3DeleteTableGeneric, pTabToDel); testcase( pToplevel->earlyCleanup ); }else{ pTabToDel->nTabRef--; @@ -146920,8 +147359,7 @@ static struct Cte *searchWith( SQLITE_PRIVATE With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ if( pWith ){ if( bFree ){ - pWith = (With*)sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3WithDelete, + pWith = (With*)sqlite3ParserAddCleanup(pParse, sqlite3WithDeleteGeneric, pWith); if( pWith==0 ) return 0; } @@ -147954,6 +148392,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ assert( pFunc->pFExpr->pLeft!=0 ); assert( pFunc->pFExpr->pLeft->op==TK_ORDER ); assert( ExprUseXList(pFunc->pFExpr->pLeft) ); + assert( pFunc->pFunc!=0 ); pOBList = pFunc->pFExpr->pLeft->x.pList; if( !pFunc->bOBUnique ){ nExtra++; /* One extra column for the OP_Sequence */ @@ -147963,6 +148402,9 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ assert( ExprUseXList(pFunc->pFExpr) ); nExtra += pFunc->pFExpr->x.pList->nExpr; } + if( pFunc->bUseSubtype ){ + nExtra += pFunc->pFExpr->x.pList->nExpr; + } pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra); if( !pFunc->bOBUnique && pParse->nErr==0 ){ pKeyInfo->nKeyField++; @@ -147989,9 +148431,9 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ assert( ExprUseXList(pF->pFExpr) ); pList = pF->pFExpr->x.pList; if( pF->iOBTab>=0 ){ - /* For an ORDER BY aggregate, calls to OP_AggStep where deferred and - ** all content was stored in emphermal table pF->iOBTab. Extract that - ** content now (in ORDER BY order) and make all calls to OP_AggStep + /* For an ORDER BY aggregate, calls to OP_AggStep were deferred. Inputs + ** were stored in emphermal table pF->iOBTab. Here, we extract those + ** inputs (in ORDER BY order) and make all calls to OP_AggStep ** before doing the OP_AggFinal call. */ int iTop; /* Start of loop for extracting columns */ int nArg; /* Number of columns to extract */ @@ -147999,6 +148441,7 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ int regAgg; /* Extract into this array */ int j; /* Loop counter */ + assert( pF->pFunc!=0 ); nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); @@ -148015,6 +148458,15 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ for(j=nArg-1; j>=0; j--){ sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j); } + if( pF->bUseSubtype ){ + int regSubtype = sqlite3GetTempReg(pParse); + int iBaseCol = nKey + nArg + (pF->bOBPayload==0 && pF->bOBUnique==0); + for(j=nArg-1; j>=0; j--){ + sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, iBaseCol+j, regSubtype); + sqlite3VdbeAddOp2(v, OP_SetSubtype, regSubtype, regAgg+j); + } + sqlite3ReleaseTempReg(pParse, regSubtype); + } sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); @@ -148069,6 +148521,7 @@ static void updateAccumulator( ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); assert( !IsWindowFunc(pF->pFExpr) ); + assert( pF->pFunc!=0 ); pList = pF->pFExpr->x.pList; if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){ Expr *pFilter = pF->pFExpr->y.pWin->pFilter; @@ -148113,6 +148566,9 @@ static void updateAccumulator( if( pF->bOBPayload ){ regAggSz += nArg; } + if( pF->bUseSubtype ){ + regAggSz += nArg; + } regAggSz++; /* One extra register to hold result of MakeRecord */ regAgg = sqlite3GetTempRange(pParse, regAggSz); regDistinct = regAgg; @@ -148125,6 +148581,14 @@ static void updateAccumulator( if( pF->bOBPayload ){ regDistinct = regAgg+jj; sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP); + jj += nArg; + } + if( pF->bUseSubtype ){ + int kk; + int regBase = pF->bOBPayload ? regDistinct : regAgg; + for(kk=0; kknExpr; @@ -148329,7 +148793,8 @@ static SrcItem *isSelfJoinView( /* ** Deallocate a single AggInfo object */ -static void agginfoFree(sqlite3 *db, AggInfo *p){ +static void agginfoFree(sqlite3 *db, void *pArg){ + AggInfo *p = (AggInfo*)pArg; sqlite3DbFree(db, p->aCol); sqlite3DbFree(db, p->aFunc); sqlite3DbFreeNN(db, p); @@ -148403,7 +148868,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ pSub->selFlags |= SF_Aggregate; pSub->selFlags &= ~SF_Compound; pSub->nSelectRow = 0; - sqlite3ExprListDelete(db, pSub->pEList); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, pSub->pEList); pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm); pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0); @@ -148583,9 +149048,8 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); } #endif - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - p->pOrderBy); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, + p->pOrderBy); testcase( pParse->earlyCleanup ); p->pOrderBy = 0; } @@ -148777,9 +149241,8 @@ SQLITE_PRIVATE int sqlite3Select( ){ TREETRACE(0x800,pParse,p, ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))sqlite3ExprListDelete, - pSub->pOrderBy); + sqlite3ParserAddCleanup(pParse, sqlite3ExprListDeleteGeneric, + pSub->pOrderBy); pSub->pOrderBy = 0; } @@ -149308,8 +149771,7 @@ SQLITE_PRIVATE int sqlite3Select( */ pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) ); if( pAggInfo ){ - sqlite3ParserAddCleanup(pParse, - (void(*)(sqlite3*,void*))agginfoFree, pAggInfo); + sqlite3ParserAddCleanup(pParse, agginfoFree, pAggInfo); testcase( pParse->earlyCleanup ); } if( db->mallocFailed ){ @@ -153958,7 +154420,6 @@ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ if( p ){ db->pDisconnect = 0; - sqlite3ExpirePreparedStatements(db, 0); do { VTable *pNext = p->pNext; sqlite3VtabUnlock(p); @@ -155524,7 +155985,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int); #ifdef WHERETRACE_ENABLED SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC); SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm); -SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC); +SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC); #endif SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( WhereClause *pWC, /* The WHERE clause to be searched */ @@ -160986,12 +161447,22 @@ static void translateColumnToCopy( for(; iStartp1!=iTabCur ) continue; if( pOp->opcode==OP_Column ){ +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE OP_Column to OP_Copy at %d\n", iStart); + } +#endif pOp->opcode = OP_Copy; pOp->p1 = pOp->p2 + iRegister; pOp->p2 = pOp->p3; pOp->p3 = 0; pOp->p5 = 2; /* Cause the MEM_Subtype flag to be cleared */ }else if( pOp->opcode==OP_Rowid ){ +#ifdef SQLITE_DEBUG + if( pParse->db->flags & SQLITE_VdbeAddopTrace ){ + printf("TRANSLATE OP_Rowid to OP_Sequence at %d\n", iStart); + } +#endif pOp->opcode = OP_Sequence; pOp->p1 = iAutoidxCur; #ifdef SQLITE_ALLOW_ROWID_IN_VIEW @@ -162318,7 +162789,8 @@ static int whereRangeScanEst( ** sample, then assume they are 4x more selective. This brings ** the estimated selectivity more in line with what it would be ** if estimated without the use of STAT4 tables. */ - if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) ); + if( iLwrIdx==iUprIdx ){ nNew -= 20; } + assert( 20==sqlite3LogEst(4) ); }else{ nNew = 10; assert( 10==sqlite3LogEst(2) ); } @@ -162542,17 +163014,34 @@ SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ #ifdef WHERETRACE_ENABLED /* ** Print a WhereLoop object for debugging purposes +** +** Format example: +** +** .--- Position in WHERE clause rSetup, rRun, nOut ---. +** | | +** | .--- selfMask nTerm ------. | +** | | | | +** | | .-- prereq Idx wsFlags----. | | +** | | | Name | | | +** | | | __|__ nEq ---. ___|__ | __|__ +** | / \ / \ / \ | / \ / \ / \ +** 1.002.001 t2.t2xy 2 f 010241 N 2 cost 0,56,31 */ -SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ - WhereInfo *pWInfo = pWC->pWInfo; - int nb = 1+(pWInfo->pTabList->nSrc+3)/4; - SrcItem *pItem = pWInfo->pTabList->a + p->iTab; - Table *pTab = pItem->pTab; - Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; - sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, - p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); - sqlite3DebugPrintf(" %12s", - pItem->zAlias ? pItem->zAlias : pTab->zName); +SQLITE_PRIVATE void sqlite3WhereLoopPrint(const WhereLoop *p, const WhereClause *pWC){ + if( pWC ){ + WhereInfo *pWInfo = pWC->pWInfo; + int nb = 1+(pWInfo->pTabList->nSrc+3)/4; + SrcItem *pItem = pWInfo->pTabList->a + p->iTab; + Table *pTab = pItem->pTab; + Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; + sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, + p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); + sqlite3DebugPrintf(" %12s", + pItem->zAlias ? pItem->zAlias : pTab->zName); + }else{ + sqlite3DebugPrintf("%c%2d.%03llx.%03llx %c%d", + p->cId, p->iTab, p->maskSelf, p->prereq & 0xfff, p->cId, p->iTab); + } if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ const char *zName; if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ @@ -162589,6 +163078,15 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ } } } +SQLITE_PRIVATE void sqlite3ShowWhereLoop(const WhereLoop *p){ + if( p ) sqlite3WhereLoopPrint(p, 0); +} +SQLITE_PRIVATE void sqlite3ShowWhereLoopList(const WhereLoop *p){ + while( p ){ + sqlite3ShowWhereLoop(p); + p = p->pNextLoop; + } +} #endif /* @@ -162701,46 +163199,60 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ } /* -** Return TRUE if all of the following are true: +** Return TRUE if X is a proper subset of Y but is of equal or less cost. +** In other words, return true if all constraints of X are also part of Y +** and Y has additional constraints that might speed the search that X lacks +** but the cost of running X is not more than the cost of running Y. ** -** (1) X has the same or lower cost, or returns the same or fewer rows, -** than Y. -** (2) X uses fewer WHERE clause terms than Y -** (3) Every WHERE clause term used by X is also used by Y -** (4) X skips at least as many columns as Y -** (5) If X is a covering index, than Y is too +** In other words, return true if the cost relationwship between X and Y +** is inverted and needs to be adjusted. ** -** Conditions (2) and (3) mean that X is a "proper subset" of Y. -** If X is a proper subset of Y then Y is a better choice and ought -** to have a lower cost. This routine returns TRUE when that cost -** relationship is inverted and needs to be adjusted. Constraint (4) -** was added because if X uses skip-scan less than Y it still might -** deserve a lower cost even if it is a proper subset of Y. Constraint (5) -** was added because a covering index probably deserves to have a lower cost -** than a non-covering index even if it is a proper subset. +** Case 1: +** +** (1a) X and Y use the same index. +** (1b) X has fewer == terms than Y +** (1c) Neither X nor Y use skip-scan +** (1d) X does not have a a greater cost than Y +** +** Case 2: +** +** (2a) X has the same or lower cost, or returns the same or fewer rows, +** than Y. +** (2b) X uses fewer WHERE clause terms than Y +** (2c) Every WHERE clause term used by X is also used by Y +** (2d) X skips at least as many columns as Y +** (2e) If X is a covering index, than Y is too */ static int whereLoopCheaperProperSubset( const WhereLoop *pX, /* First WhereLoop to compare */ const WhereLoop *pY /* Compare against this WhereLoop */ ){ int i, j; - if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ - return 0; /* X is not a subset of Y */ + if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; /* (1d) and (2a) */ + assert( (pX->wsFlags & WHERE_VIRTUALTABLE)==0 ); + assert( (pY->wsFlags & WHERE_VIRTUALTABLE)==0 ); + if( pX->u.btree.nEq < pY->u.btree.nEq /* (1b) */ + && pX->u.btree.pIndex==pY->u.btree.pIndex /* (1a) */ + && pX->nSkip==0 && pY->nSkip==0 /* (1c) */ + ){ + return 1; /* Case 1 is true */ } - if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; - if( pY->nSkip > pX->nSkip ) return 0; + if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ + return 0; /* (2b) */ + } + if( pY->nSkip > pX->nSkip ) return 0; /* (2d) */ for(i=pX->nLTerm-1; i>=0; i--){ if( pX->aLTerm[i]==0 ) continue; for(j=pY->nLTerm-1; j>=0; j--){ if( pY->aLTerm[j]==pX->aLTerm[i] ) break; } - if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ + if( j<0 ) return 0; /* (2c) */ } if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){ - return 0; /* Constraint (5) */ + return 0; /* (2e) */ } - return 1; /* All conditions meet */ + return 1; /* Case 2 is true */ } /* @@ -163230,7 +163742,10 @@ static int whereLoopAddBtreeIndex( assert( pNew->u.btree.nBtm==0 ); opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS; } - if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); + if( pProbe->bUnordered || pProbe->bLowQual ){ + if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE); + if( pProbe->bLowQual ) opMask &= ~(WO_EQ|WO_IN|WO_IS); + } assert( pNew->u.btree.nEqnColumn ); assert( pNew->u.btree.nEqnKeyCol @@ -166310,7 +166825,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); - if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0; + if( pOrderBy && pOrderBy->nExpr>=BMS ){ + pOrderBy = 0; + wctrlFlags &= ~WHERE_WANT_DISTINCT; + } /* The number of tables in the FROM clause is limited by the number of ** bits in a Bitmask @@ -166335,7 +166853,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** field (type Bitmask) it must be aligned on an 8-byte boundary on ** some architectures. Hence the ROUND8() below. */ - nByteWInfo = ROUND8P(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); + nByteWInfo = ROUND8P(sizeof(WhereInfo)); + if( nTabList>1 ){ + nByteWInfo = ROUND8P(nByteWInfo + (nTabList-1)*sizeof(WhereLevel)); + } pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); if( db->mallocFailed ){ sqlite3DbFree(db, pWInfo); @@ -166897,6 +167418,11 @@ whereBeginError: pParse->nQueryLoop = pWInfo->savedNQueryLoop; whereInfoFree(db, pWInfo); } +#ifdef WHERETRACE_ENABLED + /* Prevent harmless compiler warnings about debugging routines + ** being declared but never used */ + sqlite3ShowWhereLoopList(0); +#endif /* WHERETRACE_ENABLED */ return 0; } @@ -182233,6 +182759,28 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } #endif + + /* sqlite3_test_control(SQLITE_TESTCTRL_JSON_SELFCHECK, &onOff); + ** + ** Activate or deactivate validation of JSONB that is generated from + ** text. Off by default, as the validation is slow. Validation is + ** only available if compiled using SQLITE_DEBUG. + ** + ** If onOff is initially 1, then turn it on. If onOff is initially + ** off, turn it off. If onOff is initially -1, then change onOff + ** to be the current setting. + */ + case SQLITE_TESTCTRL_JSON_SELFCHECK: { +#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) + int *pOnOff = va_arg(ap, int*); + if( *pOnOff<0 ){ + *pOnOff = sqlite3Config.bJsonSelfcheck; + }else{ + sqlite3Config.bJsonSelfcheck = (u8)((*pOnOff)&0xff); + } +#endif + break; + } } va_end(ap); #endif /* SQLITE_UNTESTABLE */ @@ -184217,6 +184765,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); SQLITE_PRIVATE int sqlite3Fts3ExprIterate(Fts3Expr*, int (*x)(Fts3Expr*,int,void*), void*); +SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk); + #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ #endif /* _FTSINT_H */ @@ -187939,7 +188489,7 @@ static int fts3ShadowName(const char *zName){ ** Implementation of the xIntegrity() method on the FTS3/FTS4 virtual ** table. */ -static int fts3Integrity( +static int fts3IntegrityMethod( sqlite3_vtab *pVtab, /* The virtual table to be checked */ const char *zSchema, /* Name of schema in which pVtab lives */ const char *zTabname, /* Name of the pVTab table */ @@ -187947,30 +188497,21 @@ static int fts3Integrity( char **pzErr /* Write error message here */ ){ Fts3Table *p = (Fts3Table*)pVtab; - char *zSql; int rc; - char *zErr = 0; + int bOk = 0; - assert( pzErr!=0 ); - assert( *pzErr==0 ); UNUSED_PARAMETER(isQuick); - zSql = sqlite3_mprintf( - "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", - zSchema, zTabname, zTabname); - if( zSql==0 ){ - return SQLITE_NOMEM; - } - rc = sqlite3_exec(p->db, zSql, 0, 0, &zErr); - sqlite3_free(zSql); - if( (rc&0xff)==SQLITE_CORRUPT ){ - *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", - p->bFts4 ? 4 : 3, zSchema, zTabname); - }else if( rc!=SQLITE_OK ){ + rc = sqlite3Fts3IntegrityCheck(p, &bOk); + assert( rc!=SQLITE_CORRUPT_VTAB || bOk==0 ); + if( rc!=SQLITE_OK && rc!=SQLITE_CORRUPT_VTAB ){ *pzErr = sqlite3_mprintf("unable to validate the inverted index for" " FTS%d table %s.%s: %s", - p->bFts4 ? 4 : 3, zSchema, zTabname, zErr); + p->bFts4 ? 4 : 3, zSchema, zTabname, sqlite3_errstr(rc)); + }else if( bOk==0 ){ + *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", + p->bFts4 ? 4 : 3, zSchema, zTabname); } - sqlite3_free(zErr); + sqlite3Fts3SegmentsClose(p); return SQLITE_OK; } @@ -188001,7 +188542,7 @@ static const sqlite3_module fts3Module = { /* xRelease */ fts3ReleaseMethod, /* xRollbackTo */ fts3RollbackToMethod, /* xShadowName */ fts3ShadowName, - /* xIntegrity */ fts3Integrity, + /* xIntegrity */ fts3IntegrityMethod, }; /* @@ -199555,7 +200096,7 @@ static u64 fts3ChecksumIndex( ** If an error occurs (e.g. an OOM or IO error), return an SQLite error ** code. The final value of *pbOk is undefined in this case. */ -static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ +SQLITE_PRIVATE int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){ int rc = SQLITE_OK; /* Return code */ u64 cksum1 = 0; /* Checksum based on FTS index contents */ u64 cksum2 = 0; /* Checksum based on %_content contents */ @@ -199633,7 +200174,7 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ sqlite3_finalize(pStmt); } - *pbOk = (cksum1==cksum2); + *pbOk = (rc==SQLITE_OK && cksum1==cksum2); return rc; } @@ -199673,7 +200214,7 @@ static int fts3DoIntegrityCheck( ){ int rc; int bOk = 0; - rc = fts3IntegrityCheck(p, &bOk); + rc = sqlite3Fts3IntegrityCheck(p, &bOk); if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB; return rc; } @@ -202647,24 +203188,145 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ ** ****************************************************************************** ** -** This SQLite JSON functions. +** SQLite JSON functions. ** ** This file began as an extension in ext/misc/json1.c in 2015. That ** extension proved so useful that it has now been moved into the core. ** -** For the time being, all JSON is stored as pure text. (We might add -** a JSONB type in the future which stores a binary encoding of JSON in -** a BLOB, but there is no support for JSONB in the current implementation. -** This implementation parses JSON text at 250 MB/s, so it is hard to see -** how JSONB might improve on that.) +** The original design stored all JSON as pure text, canonical RFC-8259. +** Support for JSON-5 extensions was added with version 3.42.0 (2023-05-16). +** All generated JSON text still conforms strictly to RFC-8259, but text +** with JSON-5 extensions is accepted as input. +** +** Beginning with version 3.45.0 (circa 2024-01-01), these routines also +** accept BLOB values that have JSON encoded using a binary representation +** called "JSONB". The name JSONB comes from PostgreSQL, however the on-disk +** format SQLite JSONB is completely different and incompatible with +** PostgreSQL JSONB. +** +** Decoding and interpreting JSONB is still O(N) where N is the size of +** the input, the same as text JSON. However, the constant of proportionality +** for JSONB is much smaller due to faster parsing. The size of each +** element in JSONB is encoded in its header, so there is no need to search +** for delimiters using persnickety syntax rules. JSONB seems to be about +** 3x faster than text JSON as a result. JSONB is also tends to be slightly +** smaller than text JSON, by 5% or 10%, but there are corner cases where +** JSONB can be slightly larger. So you are not far mistaken to say that +** a JSONB blob is the same size as the equivalent RFC-8259 text. +** +** +** THE JSONB ENCODING: +** +** Every JSON element is encoded in JSONB as a header and a payload. +** The header is between 1 and 9 bytes in size. The payload is zero +** or more bytes. +** +** The lower 4 bits of the first byte of the header determines the +** element type: +** +** 0: NULL +** 1: TRUE +** 2: FALSE +** 3: INT -- RFC-8259 integer literal +** 4: INT5 -- JSON5 integer literal +** 5: FLOAT -- RFC-8259 floating point literal +** 6: FLOAT5 -- JSON5 floating point literal +** 7: TEXT -- Text literal acceptable to both SQL and JSON +** 8: TEXTJ -- Text containing RFC-8259 escapes +** 9: TEXT5 -- Text containing JSON5 and/or RFC-8259 escapes +** 10: TEXTRAW -- Text containing unescaped syntax characters +** 11: ARRAY +** 12: OBJECT +** +** The other three possible values (13-15) are reserved for future +** enhancements. +** +** The upper 4 bits of the first byte determine the size of the header +** and sometimes also the size of the payload. If X is the first byte +** of the element and if X>>4 is between 0 and 11, then the payload +** will be that many bytes in size and the header is exactly one byte +** in size. Other four values for X>>4 (12-15) indicate that the header +** is more than one byte in size and that the payload size is determined +** by the remainder of the header, interpreted as a unsigned big-endian +** integer. +** +** Value of X>>4 Size integer Total header size +** ------------- -------------------- ----------------- +** 12 1 byte (0-255) 2 +** 13 2 byte (0-65535) 3 +** 14 4 byte (0-4294967295) 5 +** 15 8 byte (0-1.8e19) 9 +** +** The payload size need not be expressed in its minimal form. For example, +** if the payload size is 10, the size can be expressed in any of 5 different +** ways: (1) (X>>4)==10, (2) (X>>4)==12 following by on 0x0a byte, +** (3) (X>>4)==13 followed by 0x00 and 0x0a, (4) (X>>4)==14 followed by +** 0x00 0x00 0x00 0x0a, or (5) (X>>4)==15 followed by 7 bytes of 0x00 and +** a single byte of 0x0a. The shorter forms are preferred, of course, but +** sometimes when generating JSONB, the payload size is not known in advance +** and it is convenient to reserve sufficient header space to cover the +** largest possible payload size and then come back later and patch up +** the size when it becomes known, resulting in a non-minimal encoding. +** +** The value (X>>4)==15 is not actually used in the current implementation +** (as SQLite is currently unable handle BLOBs larger than about 2GB) +** but is included in the design to allow for future enhancements. +** +** The payload follows the header. NULL, TRUE, and FALSE have no payload and +** their payload size must always be zero. The payload for INT, INT5, +** FLOAT, FLOAT5, TEXT, TEXTJ, TEXT5, and TEXTROW is text. Note that the +** "..." or '...' delimiters are omitted from the various text encodings. +** The payload for ARRAY and OBJECT is a list of additional elements that +** are the content for the array or object. The payload for an OBJECT +** must be an even number of elements. The first element of each pair is +** the label and must be of type TEXT, TEXTJ, TEXT5, or TEXTRAW. +** +** A valid JSONB blob consists of a single element, as described above. +** Usually this will be an ARRAY or OBJECT element which has many more +** elements as its content. But the overall blob is just a single element. +** +** Input validation for JSONB blobs simply checks that the element type +** code is between 0 and 12 and that the total size of the element +** (header plus payload) is the same as the size of the BLOB. If those +** checks are true, the BLOB is assumed to be JSONB and processing continues. +** Errors are only raised if some other miscoding is discovered during +** processing. +** +** Additional information can be found in the doc/jsonb.md file of the +** canonical SQLite source tree. */ #ifndef SQLITE_OMIT_JSON /* #include "sqliteInt.h" */ +/* JSONB element types +*/ +#define JSONB_NULL 0 /* "null" */ +#define JSONB_TRUE 1 /* "true" */ +#define JSONB_FALSE 2 /* "false" */ +#define JSONB_INT 3 /* integer acceptable to JSON and SQL */ +#define JSONB_INT5 4 /* integer in 0x000 notation */ +#define JSONB_FLOAT 5 /* float acceptable to JSON and SQL */ +#define JSONB_FLOAT5 6 /* float with JSON5 extensions */ +#define JSONB_TEXT 7 /* Text compatible with both JSON and SQL */ +#define JSONB_TEXTJ 8 /* Text with JSON escapes */ +#define JSONB_TEXT5 9 /* Text with JSON-5 escape */ +#define JSONB_TEXTRAW 10 /* SQL text that needs escaping for JSON */ +#define JSONB_ARRAY 11 /* An array */ +#define JSONB_OBJECT 12 /* An object */ + +/* Human-readable names for the JSONB values. The index for each +** string must correspond to the JSONB_* integer above. +*/ +static const char * const jsonbType[] = { + "null", "true", "false", "integer", "integer", + "real", "real", "text", "text", "text", + "text", "array", "object", "", "", "", "" +}; + /* ** Growing our own isspace() routine this way is twice as fast as ** the library isspace() function, resulting in a 7% overall performance -** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). +** increase for the text-JSON parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). */ static const char jsonIsSpace[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, @@ -202685,11 +203347,19 @@ static const char jsonIsSpace[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -#define fast_isspace(x) (jsonIsSpace[(unsigned char)x]) +#define jsonIsspace(x) (jsonIsSpace[(unsigned char)x]) /* -** Characters that are special to JSON. Control charaters, -** '"' and '\\'. +** The set of all space characters recognized by jsonIsspace(). +** Useful as the second argument to strspn(). +*/ +static const char jsonSpaces[] = "\011\012\015\040"; + +/* +** Characters that are special to JSON. Control characters, +** '"' and '\\' and '\''. Actually, '\'' is not special to +** canonical JSON, but it is special in JSON-5, so we include +** it in the set of special characters. */ static const char jsonIsOk[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -202711,22 +203381,49 @@ static const char jsonIsOk[256] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; - -#if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) -# define VVA(X) -#else -# define VVA(X) X -#endif - /* Objects */ +typedef struct JsonCache JsonCache; typedef struct JsonString JsonString; -typedef struct JsonNode JsonNode; typedef struct JsonParse JsonParse; -typedef struct JsonCleanup JsonCleanup; + +/* +** Magic number used for the JSON parse cache in sqlite3_get_auxdata() +*/ +#define JSON_CACHE_ID (-429938) /* Cache entry */ +#define JSON_CACHE_SIZE 4 /* Max number of cache entries */ + +/* +** jsonUnescapeOneChar() returns this invalid code point if it encounters +** a syntax error. +*/ +#define JSON_INVALID_CHAR 0x99999 + +/* A cache mapping JSON text into JSONB blobs. +** +** Each cache entry is a JsonParse object with the following restrictions: +** +** * The bReadOnly flag must be set +** +** * The aBlob[] array must be owned by the JsonParse object. In other +** words, nBlobAlloc must be non-zero. +** +** * eEdit and delta must be zero. +** +** * zJson must be an RCStr. In other words bJsonIsRCStr must be true. +*/ +struct JsonCache { + sqlite3 *db; /* Database connection */ + int nUsed; /* Number of active entries in the cache */ + JsonParse *a[JSON_CACHE_SIZE]; /* One line for each cache entry */ +}; /* An instance of this object represents a JSON string ** under construction. Really, this is a generic string accumulator ** that can be and is used to create strings other than JSON. +** +** If the generated string is longer than will fit into the zSpace[] buffer, +** then it will be an RCStr string. This aids with caching of large +** JSON strings. */ struct JsonString { sqlite3_context *pCtx; /* Function context - put error messages here */ @@ -202734,121 +203431,75 @@ struct JsonString { u64 nAlloc; /* Bytes of storage available in zBuf[] */ u64 nUsed; /* Bytes of zBuf[] currently used */ u8 bStatic; /* True if zBuf is static space */ - u8 bErr; /* True if an error has been encountered */ + u8 eErr; /* True if an error has been encountered */ char zSpace[100]; /* Initial static space */ }; -/* A deferred cleanup task. A list of JsonCleanup objects might be -** run when the JsonParse object is destroyed. -*/ -struct JsonCleanup { - JsonCleanup *pJCNext; /* Next in a list */ - void (*xOp)(void*); /* Routine to run */ - void *pArg; /* Argument to xOp() */ -}; +/* Allowed values for JsonString.eErr */ +#define JSTRING_OOM 0x01 /* Out of memory */ +#define JSTRING_MALFORMED 0x02 /* Malformed JSONB */ +#define JSTRING_ERR 0x04 /* Error already sent to sqlite3_result */ -/* JSON type values +/* The "subtype" set for text JSON values passed through using +** sqlite3_result_subtype() and sqlite3_value_subtype(). */ -#define JSON_SUBST 0 /* Special edit node. Uses u.iPrev */ -#define JSON_NULL 1 -#define JSON_TRUE 2 -#define JSON_FALSE 3 -#define JSON_INT 4 -#define JSON_REAL 5 -#define JSON_STRING 6 -#define JSON_ARRAY 7 -#define JSON_OBJECT 8 - -/* The "subtype" set for JSON values */ #define JSON_SUBTYPE 74 /* Ascii for "J" */ /* -** Names of the various JSON types: +** Bit values for the flags passed into various SQL function implementations +** via the sqlite3_user_data() value. */ -static const char * const jsonType[] = { - "subst", - "null", "true", "false", "integer", "real", "text", "array", "object" -}; - -/* Bit values for the JsonNode.jnFlag field -*/ -#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ -#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ -#define JNODE_REMOVE 0x04 /* Do not output */ -#define JNODE_REPLACE 0x08 /* Target of a JSON_SUBST node */ -#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */ -#define JNODE_LABEL 0x20 /* Is a label of an object */ -#define JNODE_JSON5 0x40 /* Node contains JSON5 enhancements */ +#define JSON_JSON 0x01 /* Result is always JSON */ +#define JSON_SQL 0x02 /* Result is always SQL */ +#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ +#define JSON_ISSET 0x04 /* json_set(), not json_insert() */ +#define JSON_BLOB 0x08 /* Use the BLOB output format */ -/* A single node of parsed JSON. An array of these nodes describes -** a parse of JSON + edits. +/* A parsed JSON value. Lifecycle: ** -** Use the json_parse() SQL function (available when compiled with -** -DSQLITE_DEBUG) to see a dump of complete JsonParse objects, including -** a complete listing and decoding of the array of JsonNodes. -*/ -struct JsonNode { - u8 eType; /* One of the JSON_ type values */ - u8 jnFlags; /* JNODE flags */ - u8 eU; /* Which union element to use */ - u32 n; /* Bytes of content for INT, REAL or STRING - ** Number of sub-nodes for ARRAY and OBJECT - ** Node that SUBST applies to */ - union { - const char *zJContent; /* 1: Content for INT, REAL, and STRING */ - u32 iAppend; /* 2: More terms for ARRAY and OBJECT */ - u32 iKey; /* 3: Key for ARRAY objects in json_tree() */ - u32 iPrev; /* 4: Previous SUBST node, or 0 */ - } u; -}; - - -/* A parsed and possibly edited JSON string. Lifecycle: +** 1. JSON comes in and is parsed into a JSONB value in aBlob. The +** original text is stored in zJson. This step is skipped if the +** input is JSONB instead of text JSON. ** -** 1. JSON comes in and is parsed into an array aNode[]. The original -** JSON text is stored in zJson. +** 2. The aBlob[] array is searched using the JSON path notation, if needed. ** -** 2. Zero or more changes are made (via json_remove() or json_replace() -** or similar) to the aNode[] array. +** 3. Zero or more changes are made to aBlob[] (via json_remove() or +** json_replace() or json_patch() or similar). ** -** 3. A new, edited and mimified JSON string is generated from aNode -** and stored in zAlt. The JsonParse object always owns zAlt. -** -** Step 1 always happens. Step 2 and 3 may or may not happen, depending -** on the operation. -** -** aNode[].u.zJContent entries typically point into zJson. Hence zJson -** must remain valid for the lifespan of the parse. For edits, -** aNode[].u.zJContent might point to malloced space other than zJson. -** Entries in pClup are responsible for freeing that extra malloced space. -** -** When walking the parse tree in aNode[], edits are ignored if useMod is -** false. +** 4. New JSON text is generated from the aBlob[] for output. This step +** is skipped if the function is one of the jsonb_* functions that +** returns JSONB instead of text JSON. */ struct JsonParse { - u32 nNode; /* Number of slots of aNode[] used */ - u32 nAlloc; /* Number of slots of aNode[] allocated */ - JsonNode *aNode; /* Array of nodes containing the parse */ - char *zJson; /* Original JSON string (before edits) */ - char *zAlt; /* Revised and/or mimified JSON */ - u32 *aUp; /* Index of parent of each node */ - JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */ + u8 *aBlob; /* JSONB representation of JSON value */ + u32 nBlob; /* Bytes of aBlob[] actually used */ + u32 nBlobAlloc; /* Bytes allocated to aBlob[]. 0 if aBlob is external */ + char *zJson; /* Json text used for parsing */ + sqlite3 *db; /* The database connection to which this object belongs */ + int nJson; /* Length of the zJson string in bytes */ + u32 nJPRef; /* Number of references to this object */ + u32 iErr; /* Error location in zJson[] */ u16 iDepth; /* Nesting depth */ u8 nErr; /* Number of errors seen */ u8 oom; /* Set to true if out of memory */ u8 bJsonIsRCStr; /* True if zJson is an RCStr */ u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ - u8 useMod; /* Actually use the edits contain inside aNode */ - u8 hasMod; /* aNode contains edits from the original zJson */ - u32 nJPRef; /* Number of references to this object */ - int nJson; /* Length of the zJson string in bytes */ - int nAlt; /* Length of alternative JSON string zAlt, in bytes */ - u32 iErr; /* Error location in zJson[] */ - u32 iSubst; /* Last JSON_SUBST entry in aNode[] */ - u32 iHold; /* Age of this entry in the cache for LRU replacement */ + u8 bReadOnly; /* Do not modify. */ + /* Search and edit information. See jsonLookupStep() */ + u8 eEdit; /* Edit operation to apply */ + int delta; /* Size change due to the edit */ + u32 nIns; /* Number of bytes to insert */ + u32 iLabel; /* Location of label if search landed on an object value */ + u8 *aIns; /* Content to be inserted */ }; +/* Allowed values for JsonParse.eEdit */ +#define JEDIT_DEL 1 /* Delete if exists */ +#define JEDIT_REPL 2 /* Overwrite if exists */ +#define JEDIT_INS 3 /* Insert if not exists */ +#define JEDIT_SET 4 /* Insert or overwrite */ + /* ** Maximum nesting depth of JSON for this implementation. ** @@ -202856,15 +203507,151 @@ struct JsonParse { ** descent parser. A depth of 1000 is far deeper than any sane JSON ** should go. Historical note: This limit was 2000 prior to version 3.42.0 */ -#define JSON_MAX_DEPTH 1000 +#ifndef SQLITE_JSON_MAX_DEPTH +# define JSON_MAX_DEPTH 1000 +#else +# define JSON_MAX_DEPTH SQLITE_JSON_MAX_DEPTH +#endif + +/* +** Allowed values for the flgs argument to jsonParseFuncArg(); +*/ +#define JSON_EDITABLE 0x01 /* Generate a writable JsonParse object */ +#define JSON_KEEPERROR 0x02 /* Return non-NULL even if there is an error */ + +/************************************************************************** +** Forward references +**************************************************************************/ +static void jsonReturnStringAsBlob(JsonString*); +static int jsonFuncArgMightBeBinary(sqlite3_value *pJson); +static u32 jsonTranslateBlobToText(const JsonParse*,u32,JsonString*); +static void jsonReturnParse(sqlite3_context*,JsonParse*); +static JsonParse *jsonParseFuncArg(sqlite3_context*,sqlite3_value*,u32); +static void jsonParseFree(JsonParse*); +static u32 jsonbPayloadSize(const JsonParse*, u32, u32*); +static u32 jsonUnescapeOneChar(const char*, u32, u32*); + +/************************************************************************** +** Utility routines for dealing with JsonCache objects +**************************************************************************/ + +/* +** Free a JsonCache object. +*/ +static void jsonCacheDelete(JsonCache *p){ + int i; + for(i=0; inUsed; i++){ + jsonParseFree(p->a[i]); + } + sqlite3DbFree(p->db, p); +} +static void jsonCacheDeleteGeneric(void *p){ + jsonCacheDelete((JsonCache*)p); +} + +/* +** Insert a new entry into the cache. If the cache is full, expel +** the least recently used entry. Return SQLITE_OK on success or a +** result code otherwise. +** +** Cache entries are stored in age order, oldest first. +*/ +static int jsonCacheInsert( + sqlite3_context *ctx, /* The SQL statement context holding the cache */ + JsonParse *pParse /* The parse object to be added to the cache */ +){ + JsonCache *p; + + assert( pParse->zJson!=0 ); + assert( pParse->bJsonIsRCStr ); + assert( pParse->delta==0 ); + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ){ + sqlite3 *db = sqlite3_context_db_handle(ctx); + p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p==0 ) return SQLITE_NOMEM; + p->db = db; + sqlite3_set_auxdata(ctx, JSON_CACHE_ID, p, jsonCacheDeleteGeneric); + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ) return SQLITE_NOMEM; + } + if( p->nUsed >= JSON_CACHE_SIZE ){ + jsonParseFree(p->a[0]); + memmove(p->a, &p->a[1], (JSON_CACHE_SIZE-1)*sizeof(p->a[0])); + p->nUsed = JSON_CACHE_SIZE-1; + } + assert( pParse->nBlobAlloc>0 ); + pParse->eEdit = 0; + pParse->nJPRef++; + pParse->bReadOnly = 1; + p->a[p->nUsed] = pParse; + p->nUsed++; + return SQLITE_OK; +} + +/* +** Search for a cached translation the json text supplied by pArg. Return +** the JsonParse object if found. Return NULL if not found. +** +** When a match if found, the matching entry is moved to become the +** most-recently used entry if it isn't so already. +** +** The JsonParse object returned still belongs to the Cache and might +** be deleted at any moment. If the caller whants the JsonParse to +** linger, it needs to increment the nPJRef reference counter. +*/ +static JsonParse *jsonCacheSearch( + sqlite3_context *ctx, /* The SQL statement context holding the cache */ + sqlite3_value *pArg /* Function argument containing SQL text */ +){ + JsonCache *p; + int i; + const char *zJson; + int nJson; + + if( sqlite3_value_type(pArg)!=SQLITE_TEXT ){ + return 0; + } + zJson = (const char*)sqlite3_value_text(pArg); + if( zJson==0 ) return 0; + nJson = sqlite3_value_bytes(pArg); + + p = sqlite3_get_auxdata(ctx, JSON_CACHE_ID); + if( p==0 ){ + return 0; + } + for(i=0; inUsed; i++){ + if( p->a[i]->zJson==zJson ) break; + } + if( i>=p->nUsed ){ + for(i=0; inUsed; i++){ + if( p->a[i]->nJson!=nJson ) continue; + if( memcmp(p->a[i]->zJson, zJson, nJson)==0 ) break; + } + } + if( inUsed ){ + if( inUsed-1 ){ + /* Make the matching entry the most recently used entry */ + JsonParse *tmp = p->a[i]; + memmove(&p->a[i], &p->a[i+1], (p->nUsed-i-1)*sizeof(tmp)); + p->a[p->nUsed-1] = tmp; + i = p->nUsed - 1; + } + assert( p->a[i]->delta==0 ); + return p->a[i]; + }else{ + return 0; + } +} /************************************************************************** ** Utility routines for dealing with JsonString objects **************************************************************************/ -/* Set the JsonString object to an empty string +/* Turn uninitialized bulk memory into a valid JsonString object +** holding a zero-length string. */ -static void jsonZero(JsonString *p){ +static void jsonStringZero(JsonString *p){ p->zBuf = p->zSpace; p->nAlloc = sizeof(p->zSpace); p->nUsed = 0; @@ -202873,39 +203660,39 @@ static void jsonZero(JsonString *p){ /* Initialize the JsonString object */ -static void jsonInit(JsonString *p, sqlite3_context *pCtx){ +static void jsonStringInit(JsonString *p, sqlite3_context *pCtx){ p->pCtx = pCtx; - p->bErr = 0; - jsonZero(p); + p->eErr = 0; + jsonStringZero(p); } /* Free all allocated memory and reset the JsonString object back to its ** initial state. */ -static void jsonReset(JsonString *p){ +static void jsonStringReset(JsonString *p){ if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf); - jsonZero(p); + jsonStringZero(p); } /* Report an out-of-memory (OOM) condition */ -static void jsonOom(JsonString *p){ - p->bErr = 1; - sqlite3_result_error_nomem(p->pCtx); - jsonReset(p); +static void jsonStringOom(JsonString *p){ + p->eErr |= JSTRING_OOM; + if( p->pCtx ) sqlite3_result_error_nomem(p->pCtx); + jsonStringReset(p); } /* Enlarge pJson->zBuf so that it can hold at least N more bytes. ** Return zero on success. Return non-zero on an OOM error */ -static int jsonGrow(JsonString *p, u32 N){ +static int jsonStringGrow(JsonString *p, u32 N){ u64 nTotal = NnAlloc ? p->nAlloc*2 : p->nAlloc+N+10; char *zNew; if( p->bStatic ){ - if( p->bErr ) return 1; + if( p->eErr ) return 1; zNew = sqlite3RCStrNew(nTotal); if( zNew==0 ){ - jsonOom(p); + jsonStringOom(p); return SQLITE_NOMEM; } memcpy(zNew, p->zBuf, (size_t)p->nUsed); @@ -202914,8 +203701,8 @@ static int jsonGrow(JsonString *p, u32 N){ }else{ p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal); if( p->zBuf==0 ){ - p->bErr = 1; - jsonZero(p); + p->eErr |= JSTRING_OOM; + jsonStringZero(p); return SQLITE_NOMEM; } } @@ -202925,20 +203712,20 @@ static int jsonGrow(JsonString *p, u32 N){ /* Append N bytes from zIn onto the end of the JsonString string. */ -static SQLITE_NOINLINE void jsonAppendExpand( +static SQLITE_NOINLINE void jsonStringExpandAndAppend( JsonString *p, const char *zIn, u32 N ){ assert( N>0 ); - if( jsonGrow(p,N) ) return; + if( jsonStringGrow(p,N) ) return; memcpy(p->zBuf+p->nUsed, zIn, N); p->nUsed += N; } static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ if( N==0 ) return; if( N+p->nUsed >= p->nAlloc ){ - jsonAppendExpand(p,zIn,N); + jsonStringExpandAndAppend(p,zIn,N); }else{ memcpy(p->zBuf+p->nUsed, zIn, N); p->nUsed += N; @@ -202947,7 +203734,7 @@ static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ assert( N>0 ); if( N+p->nUsed >= p->nAlloc ){ - jsonAppendExpand(p,zIn,N); + jsonStringExpandAndAppend(p,zIn,N); }else{ memcpy(p->zBuf+p->nUsed, zIn, N); p->nUsed += N; @@ -202959,7 +203746,7 @@ static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ */ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ va_list ap; - if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return; + if( (p->nUsed + N >= p->nAlloc) && jsonStringGrow(p, N) ) return; va_start(ap, zFormat); sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); va_end(ap); @@ -202969,7 +203756,7 @@ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ /* Append a single character */ static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){ - if( jsonGrow(p,1) ) return; + if( jsonStringGrow(p,1) ) return; p->zBuf[p->nUsed++] = c; } static void jsonAppendChar(JsonString *p, char c){ @@ -202980,24 +203767,27 @@ static void jsonAppendChar(JsonString *p, char c){ } } -/* Try to force the string to be a zero-terminated RCStr string. +/* Remove a single character from the end of the string +*/ +static void jsonStringTrimOneChar(JsonString *p){ + if( p->eErr==0 ){ + assert( p->nUsed>0 ); + p->nUsed--; + } +} + + +/* Make sure there is a zero terminator on p->zBuf[] ** ** Return true on success. Return false if an OOM prevents this ** from happening. */ -static int jsonForceRCStr(JsonString *p){ +static int jsonStringTerminate(JsonString *p){ jsonAppendChar(p, 0); - if( p->bErr ) return 0; - p->nUsed--; - if( p->bStatic==0 ) return 1; - p->nAlloc = 0; - p->nUsed++; - jsonGrow(p, p->nUsed); - p->nUsed--; - return p->bStatic==0; + jsonStringTrimOneChar(p); + return p->eErr==0; } - /* Append a comma separator to the output buffer, if the previous ** character is not '[' or '{'. */ @@ -203010,21 +203800,66 @@ static void jsonAppendSeparator(JsonString *p){ } /* Append the N-byte string in zIn to the end of the JsonString string -** under construction. Enclose the string in "..." and escape -** any double-quotes or backslash characters contained within the +** under construction. Enclose the string in double-quotes ("...") and +** escape any double-quotes or backslash characters contained within the ** string. +** +** This routine is a high-runner. There is a measurable performance +** increase associated with unwinding the jsonIsOk[] loop. */ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ - u32 i; - if( zIn==0 || ((N+p->nUsed+2 >= p->nAlloc) && jsonGrow(p,N+2)!=0) ) return; + u32 k; + u8 c; + const u8 *z = (const u8*)zIn; + if( z==0 ) return; + if( (N+p->nUsed+2 >= p->nAlloc) && jsonStringGrow(p,N+2)!=0 ) return; p->zBuf[p->nUsed++] = '"'; - for(i=0; izBuf[p->nUsed++] = c; - }else if( c=='"' || c=='\\' ){ + while( 1 /*exit-by-break*/ ){ + k = 0; + /* The following while() is the 4-way unwound equivalent of + ** + ** while( k=N ){ + while( k=N ){ + if( k>0 ){ + memcpy(&p->zBuf[p->nUsed], z, k); + p->nUsed += k; + } + break; + } + if( k>0 ){ + memcpy(&p->zBuf[p->nUsed], z, k); + p->nUsed += k; + z += k; + N -= k; + } + c = z[0]; + if( c=='"' || c=='\\' ){ json_simple_escape: - if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; + if( (p->nUsed+N+3 > p->nAlloc) && jsonStringGrow(p,N+3)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; p->zBuf[p->nUsed++] = c; }else if( c=='\'' ){ @@ -203045,7 +203880,7 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ c = aSpecial[c]; goto json_simple_escape; } - if( (p->nUsed+N+7+i > p->nAlloc) && jsonGrow(p,N+7-i)!=0 ) return; + if( (p->nUsed+N+7 > p->nAlloc) && jsonStringGrow(p,N+7)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; p->zBuf[p->nUsed++] = 'u'; p->zBuf[p->nUsed++] = '0'; @@ -203053,146 +203888,18 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4]; p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf]; } + z++; + N--; } p->zBuf[p->nUsed++] = '"'; assert( p->nUsednAlloc ); } /* -** The zIn[0..N] string is a JSON5 string literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. +** Append an sqlite3_value (such as a function parameter) to the JSON +** string under construction in p. */ -static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){ - u32 i; - jsonAppendChar(p, '"'); - zIn++; - N -= 2; - while( N>0 ){ - for(i=0; i0 ){ - jsonAppendRawNZ(p, zIn, i); - zIn += i; - N -= i; - if( N==0 ) break; - } - if( zIn[0]=='"' ){ - jsonAppendRawNZ(p, "\\\"", 2); - zIn++; - N--; - continue; - } - assert( zIn[0]=='\\' ); - switch( (u8)zIn[1] ){ - case '\'': - jsonAppendChar(p, '\''); - break; - case 'v': - jsonAppendRawNZ(p, "\\u0009", 6); - break; - case 'x': - jsonAppendRawNZ(p, "\\u00", 4); - jsonAppendRawNZ(p, &zIn[2], 2); - zIn += 2; - N -= 2; - break; - case '0': - jsonAppendRawNZ(p, "\\u0000", 6); - break; - case '\r': - if( zIn[2]=='\n' ){ - zIn++; - N--; - } - break; - case '\n': - break; - case 0xe2: - assert( N>=4 ); - assert( 0x80==(u8)zIn[2] ); - assert( 0xa8==(u8)zIn[3] || 0xa9==(u8)zIn[3] ); - zIn += 2; - N -= 2; - break; - default: - jsonAppendRawNZ(p, zIn, 2); - break; - } - zIn += 2; - N -= 2; - } - jsonAppendChar(p, '"'); -} - -/* -** The zIn[0..N] string is a JSON5 integer literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. -*/ -static void jsonAppendNormalizedInt(JsonString *p, const char *zIn, u32 N){ - if( zIn[0]=='+' ){ - zIn++; - N--; - }else if( zIn[0]=='-' ){ - jsonAppendChar(p, '-'); - zIn++; - N--; - } - if( zIn[0]=='0' && (zIn[1]=='x' || zIn[1]=='X') ){ - sqlite3_int64 i = 0; - int rc = sqlite3DecOrHexToI64(zIn, &i); - if( rc<=1 ){ - jsonPrintf(100,p,"%lld",i); - }else{ - assert( rc==2 ); - jsonAppendRawNZ(p, "9.0e999", 7); - } - return; - } - assert( N>0 ); - jsonAppendRawNZ(p, zIn, N); -} - -/* -** The zIn[0..N] string is a JSON5 real literal. Append to p a translation -** of the string literal that standard JSON and that omits all JSON5 -** features. -*/ -static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){ - u32 i; - if( zIn[0]=='+' ){ - zIn++; - N--; - }else if( zIn[0]=='-' ){ - jsonAppendChar(p, '-'); - zIn++; - N--; - } - if( zIn[0]=='.' ){ - jsonAppendChar(p, '0'); - } - for(i=0; i0 ){ - jsonAppendRawNZ(p, zIn, N); - } -} - - - -/* -** Append a function parameter value to the JSON string under -** construction. -*/ -static void jsonAppendValue( +static void jsonAppendSqlValue( JsonString *p, /* Append to this JSON string */ sqlite3_value *pValue /* Value to append */ ){ @@ -203222,291 +203929,127 @@ static void jsonAppendValue( break; } default: { - if( p->bErr==0 ){ + if( jsonFuncArgMightBeBinary(pValue) ){ + JsonParse px; + memset(&px, 0, sizeof(px)); + px.aBlob = (u8*)sqlite3_value_blob(pValue); + px.nBlob = sqlite3_value_bytes(pValue); + jsonTranslateBlobToText(&px, 0, p); + }else if( p->eErr==0 ){ sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); - p->bErr = 2; - jsonReset(p); + p->eErr = JSTRING_ERR; + jsonStringReset(p); } break; } } } - -/* Make the JSON in p the result of the SQL function. +/* Make the text in p (which is probably a generated JSON text string) +** the result of the SQL function. ** -** The JSON string is reset. +** The JsonString is reset. +** +** If pParse and ctx are both non-NULL, then the SQL string in p is +** loaded into the zJson field of the pParse object as a RCStr and the +** pParse is added to the cache. */ -static void jsonResult(JsonString *p){ - if( p->bErr==0 ){ - if( p->bStatic ){ +static void jsonReturnString( + JsonString *p, /* String to return */ + JsonParse *pParse, /* JSONB source or NULL */ + sqlite3_context *ctx /* Where to cache */ +){ + assert( (pParse!=0)==(ctx!=0) ); + assert( ctx==0 || ctx==p->pCtx ); + if( p->eErr==0 ){ + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(p->pCtx)); + if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(p); + }else if( p->bStatic ){ sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, SQLITE_TRANSIENT, SQLITE_UTF8); - }else if( jsonForceRCStr(p) ){ - sqlite3RCStrRef(p->zBuf); - sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + }else if( jsonStringTerminate(p) ){ + if( pParse && pParse->bJsonIsRCStr==0 && pParse->nBlobAlloc>0 ){ + int rc; + pParse->zJson = sqlite3RCStrRef(p->zBuf); + pParse->nJson = p->nUsed; + pParse->bJsonIsRCStr = 1; + rc = jsonCacheInsert(ctx, pParse); + if( rc==SQLITE_NOMEM ){ + sqlite3_result_error_nomem(ctx); + jsonStringReset(p); + return; + } + } + sqlite3_result_text64(p->pCtx, sqlite3RCStrRef(p->zBuf), p->nUsed, sqlite3RCStrUnref, SQLITE_UTF8); + }else{ + sqlite3_result_error_nomem(p->pCtx); } - } - if( p->bErr==1 ){ + }else if( p->eErr & JSTRING_OOM ){ sqlite3_result_error_nomem(p->pCtx); + }else if( p->eErr & JSTRING_MALFORMED ){ + sqlite3_result_error(p->pCtx, "malformed JSON", -1); } - jsonReset(p); + jsonStringReset(p); } /************************************************************************** -** Utility routines for dealing with JsonNode and JsonParse objects +** Utility routines for dealing with JsonParse objects **************************************************************************/ -/* -** Return the number of consecutive JsonNode slots need to represent -** the parsed JSON at pNode. The minimum answer is 1. For ARRAY and -** OBJECT types, the number might be larger. -** -** Appended elements are not counted. The value returned is the number -** by which the JsonNode counter should increment in order to go to the -** next peer value. -*/ -static u32 jsonNodeSize(JsonNode *pNode){ - return pNode->eType>=JSON_ARRAY ? pNode->n+1 : 1; -} - /* ** Reclaim all memory allocated by a JsonParse object. But do not ** delete the JsonParse object itself. */ static void jsonParseReset(JsonParse *pParse){ - while( pParse->pClup ){ - JsonCleanup *pTask = pParse->pClup; - pParse->pClup = pTask->pJCNext; - pTask->xOp(pTask->pArg); - sqlite3_free(pTask); - } assert( pParse->nJPRef<=1 ); - if( pParse->aNode ){ - sqlite3_free(pParse->aNode); - pParse->aNode = 0; - } - pParse->nNode = 0; - pParse->nAlloc = 0; - if( pParse->aUp ){ - sqlite3_free(pParse->aUp); - pParse->aUp = 0; - } if( pParse->bJsonIsRCStr ){ sqlite3RCStrUnref(pParse->zJson); pParse->zJson = 0; + pParse->nJson = 0; pParse->bJsonIsRCStr = 0; } - if( pParse->zAlt ){ - sqlite3RCStrUnref(pParse->zAlt); - pParse->zAlt = 0; + if( pParse->nBlobAlloc ){ + sqlite3DbFree(pParse->db, pParse->aBlob); + pParse->aBlob = 0; + pParse->nBlob = 0; + pParse->nBlobAlloc = 0; } } /* -** Free a JsonParse object that was obtained from sqlite3_malloc(). -** -** Note that destroying JsonParse might call sqlite3RCStrUnref() to -** destroy the zJson value. The RCStr object might recursively invoke -** JsonParse to destroy this pParse object again. Take care to ensure -** that this recursive destructor sequence terminates harmlessly. +** Decrement the reference count on the JsonParse object. When the +** count reaches zero, free the object. */ static void jsonParseFree(JsonParse *pParse){ - if( pParse->nJPRef>1 ){ - pParse->nJPRef--; - }else{ - jsonParseReset(pParse); - sqlite3_free(pParse); - } -} - -/* -** Add a cleanup task to the JsonParse object. -** -** If an OOM occurs, the cleanup operation happens immediately -** and this function returns SQLITE_NOMEM. -*/ -static int jsonParseAddCleanup( - JsonParse *pParse, /* Add the cleanup task to this parser */ - void(*xOp)(void*), /* The cleanup task */ - void *pArg /* Argument to the cleanup */ -){ - JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) ); - if( pTask==0 ){ - pParse->oom = 1; - xOp(pArg); - return SQLITE_ERROR; - } - pTask->pJCNext = pParse->pClup; - pParse->pClup = pTask; - pTask->xOp = xOp; - pTask->pArg = pArg; - return SQLITE_OK; -} - -/* -** Convert the JsonNode pNode into a pure JSON string and -** append to pOut. Subsubstructure is also included. Return -** the number of JsonNode objects that are encoded. -*/ -static void jsonRenderNode( - JsonParse *pParse, /* the complete parse of the JSON */ - JsonNode *pNode, /* The node to render */ - JsonString *pOut /* Write JSON here */ -){ - assert( pNode!=0 ); - while( (pNode->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){ - u32 idx = (u32)(pNode - pParse->aNode); - u32 i = pParse->iSubst; - while( 1 /*exit-by-break*/ ){ - assert( inNode ); - assert( pParse->aNode[i].eType==JSON_SUBST ); - assert( pParse->aNode[i].eU==4 ); - assert( pParse->aNode[i].u.iPrevaNode[i].n==idx ){ - pNode = &pParse->aNode[i+1]; - break; - } - i = pParse->aNode[i].u.iPrev; - } - } - switch( pNode->eType ){ - default: { - assert( pNode->eType==JSON_NULL ); - jsonAppendRawNZ(pOut, "null", 4); - break; - } - case JSON_TRUE: { - jsonAppendRawNZ(pOut, "true", 4); - break; - } - case JSON_FALSE: { - jsonAppendRawNZ(pOut, "false", 5); - break; - } - case JSON_STRING: { - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_RAW ){ - if( pNode->jnFlags & JNODE_LABEL ){ - jsonAppendChar(pOut, '"'); - jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); - jsonAppendChar(pOut, '"'); - }else{ - jsonAppendString(pOut, pNode->u.zJContent, pNode->n); - } - }else if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); - } - break; - } - case JSON_REAL: { - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); - } - break; - } - case JSON_INT: { - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_JSON5 ){ - jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n); - }else{ - assert( pNode->n>0 ); - jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); - } - break; - } - case JSON_ARRAY: { - u32 j = 1; - jsonAppendChar(pOut, '['); - for(;;){ - while( j<=pNode->n ){ - if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ - jsonAppendSeparator(pOut); - jsonRenderNode(pParse, &pNode[j], pOut); - } - j += jsonNodeSize(&pNode[j]); - } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pNode->eU==2 ); - pNode = &pParse->aNode[pNode->u.iAppend]; - j = 1; - } - jsonAppendChar(pOut, ']'); - break; - } - case JSON_OBJECT: { - u32 j = 1; - jsonAppendChar(pOut, '{'); - for(;;){ - while( j<=pNode->n ){ - if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ - jsonAppendSeparator(pOut); - jsonRenderNode(pParse, &pNode[j], pOut); - jsonAppendChar(pOut, ':'); - jsonRenderNode(pParse, &pNode[j+1], pOut); - } - j += 1 + jsonNodeSize(&pNode[j+1]); - } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pNode->eU==2 ); - pNode = &pParse->aNode[pNode->u.iAppend]; - j = 1; - } - jsonAppendChar(pOut, '}'); - break; + if( pParse ){ + if( pParse->nJPRef>1 ){ + pParse->nJPRef--; + }else{ + jsonParseReset(pParse); + sqlite3DbFree(pParse->db, pParse); } } } -/* -** Return a JsonNode and all its descendants as a JSON string. -*/ -static void jsonReturnJson( - JsonParse *pParse, /* The complete JSON */ - JsonNode *pNode, /* Node to return */ - sqlite3_context *pCtx, /* Return value for this function */ - int bGenerateAlt, /* Also store the rendered text in zAlt */ - int omitSubtype /* Do not call sqlite3_result_subtype() */ -){ - JsonString s; - if( pParse->oom ){ - sqlite3_result_error_nomem(pCtx); - return; - } - if( pParse->nErr==0 ){ - jsonInit(&s, pCtx); - jsonRenderNode(pParse, pNode, &s); - if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){ - pParse->zAlt = sqlite3RCStrRef(s.zBuf); - pParse->nAlt = s.nUsed; - } - jsonResult(&s); - if( !omitSubtype ) sqlite3_result_subtype(pCtx, JSON_SUBTYPE); - } -} +/************************************************************************** +** Utility routines for the JSON text parser +**************************************************************************/ /* ** Translate a single byte of Hex into an integer. -** This routine only works if h really is a valid hexadecimal -** character: 0..9a..fA..F +** This routine only gives a correct answer if h really is a valid hexadecimal +** character: 0..9a..fA..F. But unlike sqlite3HexToInt(), it does not +** assert() if the digit is not hex. */ static u8 jsonHexToInt(int h){ - assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif #ifdef SQLITE_EBCDIC h += 9*(1&~(h>>4)); -#else - h += 9*(1&(h>>6)); #endif return (u8)(h & 0xf); } @@ -203516,10 +204059,6 @@ static u8 jsonHexToInt(int h){ */ static u32 jsonHexToInt4(const char *z){ u32 v; - assert( sqlite3Isxdigit(z[0]) ); - assert( sqlite3Isxdigit(z[1]) ); - assert( sqlite3Isxdigit(z[2]) ); - assert( sqlite3Isxdigit(z[3]) ); v = (jsonHexToInt(z[0])<<12) + (jsonHexToInt(z[1])<<8) + (jsonHexToInt(z[2])<<4) @@ -203527,282 +204066,6 @@ static u32 jsonHexToInt4(const char *z){ return v; } -/* -** Make the JsonNode the return value of the function. -*/ -static void jsonReturn( - JsonParse *pParse, /* Complete JSON parse tree */ - JsonNode *pNode, /* Node to return */ - sqlite3_context *pCtx, /* Return value for this function */ - int omitSubtype /* Do not call sqlite3_result_subtype() */ -){ - switch( pNode->eType ){ - default: { - assert( pNode->eType==JSON_NULL ); - sqlite3_result_null(pCtx); - break; - } - case JSON_TRUE: { - sqlite3_result_int(pCtx, 1); - break; - } - case JSON_FALSE: { - sqlite3_result_int(pCtx, 0); - break; - } - case JSON_INT: { - sqlite3_int64 i = 0; - int rc; - int bNeg = 0; - const char *z; - - assert( pNode->eU==1 ); - z = pNode->u.zJContent; - if( z[0]=='-' ){ z++; bNeg = 1; } - else if( z[0]=='+' ){ z++; } - rc = sqlite3DecOrHexToI64(z, &i); - if( rc<=1 ){ - sqlite3_result_int64(pCtx, bNeg ? -i : i); - }else if( rc==3 && bNeg ){ - sqlite3_result_int64(pCtx, SMALLEST_INT64); - }else{ - goto to_double; - } - break; - } - case JSON_REAL: { - double r; - const char *z; - assert( pNode->eU==1 ); - to_double: - z = pNode->u.zJContent; - sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); - sqlite3_result_double(pCtx, r); - break; - } - case JSON_STRING: { - if( pNode->jnFlags & JNODE_RAW ){ - assert( pNode->eU==1 ); - sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, - SQLITE_TRANSIENT); - }else if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ - /* JSON formatted without any backslash-escapes */ - assert( pNode->eU==1 ); - sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, - SQLITE_TRANSIENT); - }else{ - /* Translate JSON formatted string into raw text */ - u32 i; - u32 n = pNode->n; - const char *z; - char *zOut; - u32 j; - u32 nOut = n; - assert( pNode->eU==1 ); - z = pNode->u.zJContent; - zOut = sqlite3_malloc( nOut+1 ); - if( zOut==0 ){ - sqlite3_result_error_nomem(pCtx); - break; - } - for(i=1, j=0; i>6)); - zOut[j++] = 0x80 | (v&0x3f); - }else{ - u32 vlo; - if( (v&0xfc00)==0xd800 - && i>18); - zOut[j++] = 0x80 | ((v>>12)&0x3f); - zOut[j++] = 0x80 | ((v>>6)&0x3f); - zOut[j++] = 0x80 | (v&0x3f); - }else{ - zOut[j++] = 0xe0 | (v>>12); - zOut[j++] = 0x80 | ((v>>6)&0x3f); - zOut[j++] = 0x80 | (v&0x3f); - } - } - continue; - }else if( c=='b' ){ - c = '\b'; - }else if( c=='f' ){ - c = '\f'; - }else if( c=='n' ){ - c = '\n'; - }else if( c=='r' ){ - c = '\r'; - }else if( c=='t' ){ - c = '\t'; - }else if( c=='v' ){ - c = '\v'; - }else if( c=='\'' || c=='"' || c=='/' || c=='\\' ){ - /* pass through unchanged */ - }else if( c=='0' ){ - c = 0; - }else if( c=='x' ){ - c = (jsonHexToInt(z[i+1])<<4) | jsonHexToInt(z[i+2]); - i += 2; - }else if( c=='\r' && z[i+1]=='\n' ){ - i++; - continue; - }else if( 0xe2==(u8)c ){ - assert( 0x80==(u8)z[i+1] ); - assert( 0xa8==(u8)z[i+2] || 0xa9==(u8)z[i+2] ); - i += 2; - continue; - }else{ - continue; - } - } /* end if( c=='\\' ) */ - zOut[j++] = c; - } /* end for() */ - zOut[j] = 0; - sqlite3_result_text(pCtx, zOut, j, sqlite3_free); - } - break; - } - case JSON_ARRAY: - case JSON_OBJECT: { - jsonReturnJson(pParse, pNode, pCtx, 0, omitSubtype); - break; - } - } -} - -/* Forward reference */ -static int jsonParseAddNode(JsonParse*,u32,u32,const char*); - -/* -** A macro to hint to the compiler that a function should not be -** inlined. -*/ -#if defined(__GNUC__) -# define JSON_NOINLINE __attribute__((noinline)) -#elif defined(_MSC_VER) && _MSC_VER>=1310 -# define JSON_NOINLINE __declspec(noinline) -#else -# define JSON_NOINLINE -#endif - - -/* -** Add a single node to pParse->aNode after first expanding the -** size of the aNode array. Return the index of the new node. -** -** If an OOM error occurs, set pParse->oom and return -1. -*/ -static JSON_NOINLINE int jsonParseAddNodeExpand( - JsonParse *pParse, /* Append the node to this object */ - u32 eType, /* Node type */ - u32 n, /* Content size or sub-node count */ - const char *zContent /* Content */ -){ - u32 nNew; - JsonNode *pNew; - assert( pParse->nNode>=pParse->nAlloc ); - if( pParse->oom ) return -1; - nNew = pParse->nAlloc*2 + 10; - pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew); - if( pNew==0 ){ - pParse->oom = 1; - return -1; - } - pParse->nAlloc = sqlite3_msize(pNew)/sizeof(JsonNode); - pParse->aNode = pNew; - assert( pParse->nNodenAlloc ); - return jsonParseAddNode(pParse, eType, n, zContent); -} - -/* -** Create a new JsonNode instance based on the arguments and append that -** instance to the JsonParse. Return the index in pParse->aNode[] of the -** new node, or -1 if a memory allocation fails. -*/ -static int jsonParseAddNode( - JsonParse *pParse, /* Append the node to this object */ - u32 eType, /* Node type */ - u32 n, /* Content size or sub-node count */ - const char *zContent /* Content */ -){ - JsonNode *p; - assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc ); - if( pParse->nNode>=pParse->nAlloc ){ - return jsonParseAddNodeExpand(pParse, eType, n, zContent); - } - assert( pParse->aNode!=0 ); - p = &pParse->aNode[pParse->nNode]; - assert( p!=0 ); - p->eType = (u8)(eType & 0xff); - p->jnFlags = (u8)(eType >> 8); - VVA( p->eU = zContent ? 1 : 0 ); - p->n = n; - p->u.zJContent = zContent; - return pParse->nNode++; -} - -/* -** Add an array of new nodes to the current pParse->aNode array. -** Return the index of the first node added. -** -** If an OOM error occurs, set pParse->oom. -*/ -static void jsonParseAddNodeArray( - JsonParse *pParse, /* Append the node to this object */ - JsonNode *aNode, /* Array of nodes to add */ - u32 nNode /* Number of elements in aNew */ -){ - assert( aNode!=0 ); - assert( nNode>=1 ); - if( pParse->nNode + nNode > pParse->nAlloc ){ - u32 nNew = pParse->nNode + nNode; - JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode)); - if( aNew==0 ){ - pParse->oom = 1; - return; - } - pParse->nAlloc = sqlite3_msize(aNew)/sizeof(JsonNode); - pParse->aNode = aNew; - } - memcpy(&pParse->aNode[pParse->nNode], aNode, nNode*sizeof(JsonNode)); - pParse->nNode += nNode; -} - -/* -** Add a new JSON_SUBST node. The node immediately following -** this new node will be the substitute content for iNode. -*/ -static int jsonParseAddSubstNode( - JsonParse *pParse, /* Add the JSON_SUBST here */ - u32 iNode /* References this node */ -){ - int idx = jsonParseAddNode(pParse, JSON_SUBST, iNode, 0); - if( pParse->oom ) return -1; - pParse->aNode[iNode].jnFlags |= JNODE_REPLACE; - pParse->aNode[idx].eU = 4; - pParse->aNode[idx].u.iPrev = pParse->iSubst; - pParse->iSubst = idx; - pParse->hasMod = 1; - pParse->useMod = 1; - return idx; -} - /* ** Return true if z[] begins with 2 (or more) hexadecimal digits */ @@ -203956,63 +204219,500 @@ static const struct NanInfName { char *zMatch; char *zRepl; } aNanInfName[] = { - { 'i', 'I', 3, JSON_REAL, 7, "inf", "9.0e999" }, - { 'i', 'I', 8, JSON_REAL, 7, "infinity", "9.0e999" }, - { 'n', 'N', 3, JSON_NULL, 4, "NaN", "null" }, - { 'q', 'Q', 4, JSON_NULL, 4, "QNaN", "null" }, - { 's', 'S', 4, JSON_NULL, 4, "SNaN", "null" }, + { 'i', 'I', 3, JSONB_FLOAT, 7, "inf", "9.0e999" }, + { 'i', 'I', 8, JSONB_FLOAT, 7, "infinity", "9.0e999" }, + { 'n', 'N', 3, JSONB_NULL, 4, "NaN", "null" }, + { 'q', 'Q', 4, JSONB_NULL, 4, "QNaN", "null" }, + { 's', 'S', 4, JSONB_NULL, 4, "SNaN", "null" }, }; + /* -** Parse a single JSON value which begins at pParse->zJson[i]. Return the -** index of the first character past the end of the value parsed. +** Report the wrong number of arguments for json_insert(), json_replace() +** or json_set(). +*/ +static void jsonWrongNumArgs( + sqlite3_context *pCtx, + const char *zFuncName +){ + char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", + zFuncName); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); +} + +/**************************************************************************** +** Utility routines for dealing with the binary BLOB representation of JSON +****************************************************************************/ + +/* +** Expand pParse->aBlob so that it holds at least N bytes. ** -** Special return values: +** Return the number of errors. +*/ +static int jsonBlobExpand(JsonParse *pParse, u32 N){ + u8 *aNew; + u32 t; + assert( N>pParse->nBlobAlloc ); + if( pParse->nBlobAlloc==0 ){ + t = 100; + }else{ + t = pParse->nBlobAlloc*2; + } + if( tdb, pParse->aBlob, t); + if( aNew==0 ){ pParse->oom = 1; return 1; } + pParse->aBlob = aNew; + pParse->nBlobAlloc = t; + return 0; +} + +/* +** If pParse->aBlob is not previously editable (because it is taken +** from sqlite3_value_blob(), as indicated by the fact that +** pParse->nBlobAlloc==0 and pParse->nBlob>0) then make it editable +** by making a copy into space obtained from malloc. +** +** Return true on success. Return false on OOM. +*/ +static int jsonBlobMakeEditable(JsonParse *pParse, u32 nExtra){ + u8 *aOld; + u32 nSize; + assert( !pParse->bReadOnly ); + if( pParse->oom ) return 0; + if( pParse->nBlobAlloc>0 ) return 1; + aOld = pParse->aBlob; + nSize = pParse->nBlob + nExtra; + pParse->aBlob = 0; + if( jsonBlobExpand(pParse, nSize) ){ + return 0; + } + assert( pParse->nBlobAlloc >= pParse->nBlob + nExtra ); + memcpy(pParse->aBlob, aOld, pParse->nBlob); + return 1; +} + +/* Expand pParse->aBlob and append one bytes. +*/ +static SQLITE_NOINLINE void jsonBlobExpandAndAppendOneByte( + JsonParse *pParse, + u8 c +){ + jsonBlobExpand(pParse, pParse->nBlob+1); + if( pParse->oom==0 ){ + assert( pParse->nBlob+1<=pParse->nBlobAlloc ); + pParse->aBlob[pParse->nBlob++] = c; + } +} + +/* Append a single character. +*/ +static void jsonBlobAppendOneByte(JsonParse *pParse, u8 c){ + if( pParse->nBlob >= pParse->nBlobAlloc ){ + jsonBlobExpandAndAppendOneByte(pParse, c); + }else{ + pParse->aBlob[pParse->nBlob++] = c; + } +} + +/* Slow version of jsonBlobAppendNode() that first resizes the +** pParse->aBlob structure. +*/ +static void jsonBlobAppendNode(JsonParse*,u8,u32,const void*); +static SQLITE_NOINLINE void jsonBlobExpandAndAppendNode( + JsonParse *pParse, + u8 eType, + u32 szPayload, + const void *aPayload +){ + if( jsonBlobExpand(pParse, pParse->nBlob+szPayload+9) ) return; + jsonBlobAppendNode(pParse, eType, szPayload, aPayload); +} + + +/* Append an node type byte together with the payload size and +** possibly also the payload. +** +** If aPayload is not NULL, then it is a pointer to the payload which +** is also appended. If aPayload is NULL, the pParse->aBlob[] array +** is resized (if necessary) so that it is big enough to hold the +** payload, but the payload is not appended and pParse->nBlob is left +** pointing to where the first byte of payload will eventually be. +*/ +static void jsonBlobAppendNode( + JsonParse *pParse, /* The JsonParse object under construction */ + u8 eType, /* Node type. One of JSONB_* */ + u32 szPayload, /* Number of bytes of payload */ + const void *aPayload /* The payload. Might be NULL */ +){ + u8 *a; + if( pParse->nBlob+szPayload+9 > pParse->nBlobAlloc ){ + jsonBlobExpandAndAppendNode(pParse,eType,szPayload,aPayload); + return; + } + assert( pParse->aBlob!=0 ); + a = &pParse->aBlob[pParse->nBlob]; + if( szPayload<=11 ){ + a[0] = eType | (szPayload<<4); + pParse->nBlob += 1; + }else if( szPayload<=0xff ){ + a[0] = eType | 0xc0; + a[1] = szPayload & 0xff; + pParse->nBlob += 2; + }else if( szPayload<=0xffff ){ + a[0] = eType | 0xd0; + a[1] = (szPayload >> 8) & 0xff; + a[2] = szPayload & 0xff; + pParse->nBlob += 3; + }else{ + a[0] = eType | 0xe0; + a[1] = (szPayload >> 24) & 0xff; + a[2] = (szPayload >> 16) & 0xff; + a[3] = (szPayload >> 8) & 0xff; + a[4] = szPayload & 0xff; + pParse->nBlob += 5; + } + if( aPayload ){ + pParse->nBlob += szPayload; + memcpy(&pParse->aBlob[pParse->nBlob-szPayload], aPayload, szPayload); + } +} + +/* Change the payload size for the node at index i to be szPayload. +*/ +static int jsonBlobChangePayloadSize( + JsonParse *pParse, + u32 i, + u32 szPayload +){ + u8 *a; + u8 szType; + u8 nExtra; + u8 nNeeded; + int delta; + if( pParse->oom ) return 0; + a = &pParse->aBlob[i]; + szType = a[0]>>4; + if( szType<=11 ){ + nExtra = 0; + }else if( szType==12 ){ + nExtra = 1; + }else if( szType==13 ){ + nExtra = 2; + }else{ + nExtra = 4; + } + if( szPayload<=11 ){ + nNeeded = 0; + }else if( szPayload<=0xff ){ + nNeeded = 1; + }else if( szPayload<=0xffff ){ + nNeeded = 2; + }else{ + nNeeded = 4; + } + delta = nNeeded - nExtra; + if( delta ){ + u32 newSize = pParse->nBlob + delta; + if( delta>0 ){ + if( newSize>pParse->nBlobAlloc && jsonBlobExpand(pParse, newSize) ){ + return 0; /* OOM error. Error state recorded in pParse->oom. */ + } + a = &pParse->aBlob[i]; + memmove(&a[1+delta], &a[1], pParse->nBlob - (i+1)); + }else{ + memmove(&a[1], &a[1-delta], pParse->nBlob - (i+1-delta)); + } + pParse->nBlob = newSize; + } + if( nNeeded==0 ){ + a[0] = (a[0] & 0x0f) | (szPayload<<4); + }else if( nNeeded==1 ){ + a[0] = (a[0] & 0x0f) | 0xc0; + a[1] = szPayload & 0xff; + }else if( nNeeded==2 ){ + a[0] = (a[0] & 0x0f) | 0xd0; + a[1] = (szPayload >> 8) & 0xff; + a[2] = szPayload & 0xff; + }else{ + a[0] = (a[0] & 0x0f) | 0xe0; + a[1] = (szPayload >> 24) & 0xff; + a[2] = (szPayload >> 16) & 0xff; + a[3] = (szPayload >> 8) & 0xff; + a[4] = szPayload & 0xff; + } + return delta; +} + +/* +** If z[0] is 'u' and is followed by exactly 4 hexadecimal character, +** then set *pOp to JSONB_TEXTJ and return true. If not, do not make +** any changes to *pOp and return false. +*/ +static int jsonIs4HexB(const char *z, int *pOp){ + if( z[0]!='u' ) return 0; + if( !jsonIs4Hex(&z[1]) ) return 0; + *pOp = JSONB_TEXTJ; + return 1; +} + +/* +** Check a single element of the JSONB in pParse for validity. +** +** The element to be checked starts at offset i and must end at on the +** last byte before iEnd. +** +** Return 0 if everything is correct. Return the 1-based byte offset of the +** error if a problem is detected. (In other words, if the error is at offset +** 0, return 1). +*/ +static u32 jsonbValidityCheck( + const JsonParse *pParse, /* Input JSONB. Only aBlob and nBlob are used */ + u32 i, /* Start of element as pParse->aBlob[i] */ + u32 iEnd, /* One more than the last byte of the element */ + u32 iDepth /* Current nesting depth */ +){ + u32 n, sz, j, k; + const u8 *z; + u8 x; + if( iDepth>JSON_MAX_DEPTH ) return i+1; + sz = 0; + n = jsonbPayloadSize(pParse, i, &sz); + if( NEVER(n==0) ) return i+1; /* Checked by caller */ + if( NEVER(i+n+sz!=iEnd) ) return i+1; /* Checked by caller */ + z = pParse->aBlob; + x = z[i] & 0x0f; + switch( x ){ + case JSONB_NULL: + case JSONB_TRUE: + case JSONB_FALSE: { + return n+sz==1 ? 0 : i+1; + } + case JSONB_INT: { + if( sz<1 ) return i+1; + j = i+n; + if( z[j]=='-' ){ + j++; + if( sz<2 ) return i+1; + } + k = i+n+sz; + while( jk ) return j+1; + if( z[j+1]!='.' && z[j+1]!='e' && z[j+1]!='E' ) return j+1; + j++; + } + for(; j0 ) return j+1; + if( x==JSONB_FLOAT && (j==k-1 || !sqlite3Isdigit(z[j+1])) ){ + return j+1; + } + seen = 1; + continue; + } + if( z[j]=='e' || z[j]=='E' ){ + if( seen==2 ) return j+1; + if( j==k-1 ) return j+1; + if( z[j+1]=='+' || z[j+1]=='-' ){ + j++; + if( j==k-1 ) return j+1; + } + seen = 2; + continue; + } + return j+1; + } + if( seen==0 ) return i+1; + return 0; + } + case JSONB_TEXT: { + j = i+n; + k = j+sz; + while( j=k ){ + return j+1; + }else if( strchr("\"\\/bfnrt",z[j+1])!=0 ){ + j++; + }else if( z[j+1]=='u' ){ + if( j+5>=k ) return j+1; + if( !jsonIs4Hex((const char*)&z[j+2]) ) return j+1; + j++; + }else if( x!=JSONB_TEXT5 ){ + return j+1; + }else{ + u32 c = 0; + u32 szC = jsonUnescapeOneChar((const char*)&z[j], k-j, &c); + if( c==JSON_INVALID_CHAR ) return j+1; + j += szC - 1; + } + } + j++; + } + return 0; + } + case JSONB_TEXTRAW: { + return 0; + } + case JSONB_ARRAY: { + u32 sub; + j = i+n; + k = j+sz; + while( jk ) return j+1; + sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); + if( sub ) return sub; + j += n + sz; + } + assert( j==k ); + return 0; + } + case JSONB_OBJECT: { + u32 cnt = 0; + u32 sub; + j = i+n; + k = j+sz; + while( jk ) return j+1; + if( (cnt & 1)==0 ){ + x = z[j] & 0x0f; + if( xJSONB_TEXTRAW ) return j+1; + } + sub = jsonbValidityCheck(pParse, j, j+n+sz, iDepth+1); + if( sub ) return sub; + cnt++; + j += n + sz; + } + assert( j==k ); + if( (cnt & 1)!=0 ) return j+1; + return 0; + } + default: { + return i+1; + } + } +} + +/* +** Translate a single element of JSON text at pParse->zJson[i] into +** its equivalent binary JSONB representation. Append the translation into +** pParse->aBlob[] beginning at pParse->nBlob. The size of +** pParse->aBlob[] is increased as necessary. +** +** Return the index of the first character past the end of the element parsed, +** or one of the following special result codes: ** ** 0 End of input -** -1 Syntax error -** -2 '}' seen -** -3 ']' seen -** -4 ',' seen -** -5 ':' seen +** -1 Syntax error or OOM +** -2 '}' seen \ +** -3 ']' seen \___ For these returns, pParse->iErr is set to +** -4 ',' seen / the index in zJson[] of the seen character +** -5 ':' seen / */ -static int jsonParseValue(JsonParse *pParse, u32 i){ +static int jsonTranslateTextToBlob(JsonParse *pParse, u32 i){ char c; u32 j; - int iThis; + u32 iThis, iStart; int x; - JsonNode *pNode; + u8 t; const char *z = pParse->zJson; json_parse_restart: switch( (u8)z[i] ){ case '{': { /* Parse object */ - iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); - if( iThis<0 ) return -1; + iThis = pParse->nBlob; + jsonBlobAppendNode(pParse, JSONB_OBJECT, pParse->nJson-i, 0); if( ++pParse->iDepth > JSON_MAX_DEPTH ){ pParse->iErr = i; return -1; } + iStart = pParse->nBlob; for(j=i+1;;j++){ - u32 nNode = pParse->nNode; - x = jsonParseValue(pParse, j); + u32 iBlob = pParse->nBlob; + x = jsonTranslateTextToBlob(pParse, j); if( x<=0 ){ + int op; if( x==(-2) ){ j = pParse->iErr; - if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; + if( pParse->nBlob!=(u32)iStart ) pParse->hasNonstd = 1; break; } j += json5Whitespace(&z[j]); + op = JSONB_TEXT; if( sqlite3JsonId1(z[j]) - || (z[j]=='\\' && z[j+1]=='u' && jsonIs4Hex(&z[j+2])) + || (z[j]=='\\' && jsonIs4HexB(&z[j+1], &op)) ){ int k = j+1; while( (sqlite3JsonId2(z[k]) && json5Whitespace(&z[k])==0) - || (z[k]=='\\' && z[k+1]=='u' && jsonIs4Hex(&z[k+2])) + || (z[k]=='\\' && jsonIs4HexB(&z[k+1], &op)) ){ k++; } - jsonParseAddNode(pParse, JSON_STRING | (JNODE_RAW<<8), k-j, &z[j]); + assert( iBlob==pParse->nBlob ); + jsonBlobAppendNode(pParse, op, k-j, &z[j]); pParse->hasNonstd = 1; x = k; }else{ @@ -204021,24 +204721,24 @@ json_parse_restart: } } if( pParse->oom ) return -1; - pNode = &pParse->aNode[nNode]; - if( pNode->eType!=JSON_STRING ){ + t = pParse->aBlob[iBlob] & 0x0f; + if( tJSONB_TEXTRAW ){ pParse->iErr = j; return -1; } - pNode->jnFlags |= JNODE_LABEL; j = x; if( z[j]==':' ){ j++; }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); + if( jsonIsspace(z[j]) ){ + /* strspn() is not helpful here */ + do{ j++; }while( jsonIsspace(z[j]) ); if( z[j]==':' ){ j++; goto parse_object_value; } } - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x!=(-5) ){ if( x!=(-1) ) pParse->iErr = j; return -1; @@ -204046,7 +204746,7 @@ json_parse_restart: j = pParse->iErr+1; } parse_object_value: - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x<=0 ){ if( x!=(-1) ) pParse->iErr = j; return -1; @@ -204057,15 +204757,15 @@ json_parse_restart: }else if( z[j]=='}' ){ break; }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); + if( jsonIsspace(z[j]) ){ + j += 1 + (u32)strspn(&z[j+1], jsonSpaces); if( z[j]==',' ){ continue; }else if( z[j]=='}' ){ break; } } - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x==(-4) ){ j = pParse->iErr; continue; @@ -204078,25 +204778,26 @@ json_parse_restart: pParse->iErr = j; return -1; } - pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; + jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); pParse->iDepth--; return j+1; } case '[': { /* Parse array */ - iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); - if( iThis<0 ) return -1; + iThis = pParse->nBlob; + jsonBlobAppendNode(pParse, JSONB_ARRAY, pParse->nJson - i, 0); + iStart = pParse->nBlob; + if( pParse->oom ) return -1; if( ++pParse->iDepth > JSON_MAX_DEPTH ){ pParse->iErr = i; return -1; } - memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u)); for(j=i+1;;j++){ - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x<=0 ){ if( x==(-3) ){ j = pParse->iErr; - if( pParse->nNode!=(u32)iThis+1 ) pParse->hasNonstd = 1; + if( pParse->nBlob!=iStart ) pParse->hasNonstd = 1; break; } if( x!=(-1) ) pParse->iErr = j; @@ -204108,15 +204809,15 @@ json_parse_restart: }else if( z[j]==']' ){ break; }else{ - if( fast_isspace(z[j]) ){ - do{ j++; }while( fast_isspace(z[j]) ); + if( jsonIsspace(z[j]) ){ + j += 1 + (u32)strspn(&z[j+1], jsonSpaces); if( z[j]==',' ){ continue; }else if( z[j]==']' ){ break; } } - x = jsonParseValue(pParse, j); + x = jsonTranslateTextToBlob(pParse, j); if( x==(-4) ){ j = pParse->iErr; continue; @@ -204129,23 +204830,33 @@ json_parse_restart: pParse->iErr = j; return -1; } - pParse->aNode[iThis].n = pParse->nNode - (u32)iThis - 1; + jsonBlobChangePayloadSize(pParse, iThis, pParse->nBlob - iStart); pParse->iDepth--; return j+1; } case '\'': { - u8 jnFlags; + u8 opcode; char cDelim; pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; + opcode = JSONB_TEXT; goto parse_string; case '"': /* Parse string */ - jnFlags = 0; + opcode = JSONB_TEXT; parse_string: cDelim = z[i]; - for(j=i+1; 1; j++){ - if( jsonIsOk[(unsigned char)z[j]] ) continue; + j = i+1; + while( 1 /*exit-by-break*/ ){ + if( jsonIsOk[(u8)z[j]] ){ + if( !jsonIsOk[(u8)z[j+1]] ){ + j += 1; + }else if( !jsonIsOk[(u8)z[j+2]] ){ + j += 2; + }else{ + j += 3; + continue; + } + } c = z[j]; if( c==cDelim ){ break; @@ -204154,16 +204865,16 @@ json_parse_restart: if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' || c=='n' || c=='r' || c=='t' || (c=='u' && jsonIs4Hex(&z[j+1])) ){ - jnFlags |= JNODE_ESCAPE; + if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ; }else if( c=='\'' || c=='0' || c=='v' || c=='\n' || (0xe2==(u8)c && 0x80==(u8)z[j+1] && (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2])) || (c=='x' && jsonIs2Hex(&z[j+1])) ){ - jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); + opcode = JSONB_TEXT5; pParse->hasNonstd = 1; }else if( c=='\r' ){ if( z[j+1]=='\n' ) j++; - jnFlags |= (JNODE_ESCAPE|JNODE_JSON5); + opcode = JSONB_TEXT5; pParse->hasNonstd = 1; }else{ pParse->iErr = j; @@ -204173,14 +204884,17 @@ json_parse_restart: /* Control characters are not allowed in strings */ pParse->iErr = j; return -1; + }else if( c=='"' ){ + opcode = JSONB_TEXT5; } + j++; } - jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]); + jsonBlobAppendNode(pParse, opcode, j-1-i, &z[i+1]); return j+1; } case 't': { if( strncmp(z+i,"true",4)==0 && !sqlite3Isalnum(z[i+4]) ){ - jsonParseAddNode(pParse, JSON_TRUE, 0, 0); + jsonBlobAppendOneByte(pParse, JSONB_TRUE); return i+4; } pParse->iErr = i; @@ -204188,23 +204902,22 @@ json_parse_restart: } case 'f': { if( strncmp(z+i,"false",5)==0 && !sqlite3Isalnum(z[i+5]) ){ - jsonParseAddNode(pParse, JSON_FALSE, 0, 0); + jsonBlobAppendOneByte(pParse, JSONB_FALSE); return i+5; } pParse->iErr = i; return -1; } case '+': { - u8 seenDP, seenE, jnFlags; + u8 seenE; pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; + t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ goto parse_number; case '.': if( sqlite3Isdigit(z[i+1]) ){ pParse->hasNonstd = 1; - jnFlags = JNODE_JSON5; + t = 0x03; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ seenE = 0; - seenDP = JSON_REAL; goto parse_number_2; } pParse->iErr = i; @@ -204221,9 +204934,8 @@ json_parse_restart: case '8': case '9': /* Parse number */ - jnFlags = 0; + t = 0x00; /* Bit 0x01: JSON5. Bit 0x02: FLOAT */ parse_number: - seenDP = JSON_INT; seenE = 0; assert( '-' < '0' ); assert( '+' < '0' ); @@ -204233,9 +204945,9 @@ json_parse_restart: if( c<='0' ){ if( c=='0' ){ if( (z[i+1]=='x' || z[i+1]=='X') && sqlite3Isxdigit(z[i+2]) ){ - assert( seenDP==JSON_INT ); + assert( t==0x00 ); pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t = 0x01; for(j=i+3; sqlite3Isxdigit(z[j]); j++){} goto parse_number_finish; }else if( sqlite3Isdigit(z[i+1]) ){ @@ -204252,15 +204964,15 @@ json_parse_restart: ){ pParse->hasNonstd = 1; if( z[i]=='-' ){ - jsonParseAddNode(pParse, JSON_REAL, 8, "-9.0e999"); + jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); }else{ - jsonParseAddNode(pParse, JSON_REAL, 7, "9.0e999"); + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); } return i + (sqlite3StrNICmp(&z[i+4],"inity",5)==0 ? 9 : 4); } if( z[i+1]=='.' ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; goto parse_number_2; } pParse->iErr = i; @@ -204272,30 +204984,31 @@ json_parse_restart: return -1; }else if( (z[i+2]=='x' || z[i+2]=='X') && sqlite3Isxdigit(z[i+3]) ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; for(j=i+4; sqlite3Isxdigit(z[j]); j++){} goto parse_number_finish; } } } } + parse_number_2: for(j=i+1;; j++){ c = z[j]; if( sqlite3Isdigit(c) ) continue; if( c=='.' ){ - if( seenDP==JSON_REAL ){ + if( (t & 0x02)!=0 ){ pParse->iErr = j; return -1; } - seenDP = JSON_REAL; + t |= 0x02; continue; } if( c=='e' || c=='E' ){ if( z[j-1]<'0' ){ if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; }else{ pParse->iErr = j; return -1; @@ -204305,7 +205018,7 @@ json_parse_restart: pParse->iErr = j; return -1; } - seenDP = JSON_REAL; + t |= 0x02; seenE = 1; c = z[j+1]; if( c=='+' || c=='-' ){ @@ -204323,14 +205036,18 @@ json_parse_restart: if( z[j-1]<'0' ){ if( ALWAYS(z[j-1]=='.') && ALWAYS(j-2>=i) && sqlite3Isdigit(z[j-2]) ){ pParse->hasNonstd = 1; - jnFlags |= JNODE_JSON5; + t |= 0x01; }else{ pParse->iErr = j; return -1; } } parse_number_finish: - jsonParseAddNode(pParse, seenDP | (jnFlags<<8), j - i, &z[i]); + assert( JSONB_INT+0x01==JSONB_INT5 ); + assert( JSONB_FLOAT+0x01==JSONB_FLOAT5 ); + assert( JSONB_INT+0x02==JSONB_FLOAT ); + if( z[i]=='+' ) i++; + jsonBlobAppendNode(pParse, JSONB_INT+t, j-i, &z[i]); return j; } case '}': { @@ -204356,9 +205073,7 @@ json_parse_restart: case 0x0a: case 0x0d: case 0x20: { - do{ - i++; - }while( fast_isspace(z[i]) ); + i += 1 + (u32)strspn(&z[i+1], jsonSpaces); goto json_parse_restart; } case 0x0b: @@ -204380,7 +205095,7 @@ json_parse_restart: } case 'n': { if( strncmp(z+i,"null",4)==0 && !sqlite3Isalnum(z[i+4]) ){ - jsonParseAddNode(pParse, JSON_NULL, 0, 0); + jsonBlobAppendOneByte(pParse, JSONB_NULL); return i+4; } /* fall-through into the default case that checks for NaN */ @@ -204396,8 +205111,11 @@ json_parse_restart: continue; } if( sqlite3Isalnum(z[i+nn]) ) continue; - jsonParseAddNode(pParse, aNanInfName[k].eType, - aNanInfName[k].nRepl, aNanInfName[k].zRepl); + if( aNanInfName[k].eType==JSONB_FLOAT ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); + }else{ + jsonBlobAppendOneByte(pParse, JSONB_NULL); + } pParse->hasNonstd = 1; return i + nn; } @@ -204407,6 +205125,7 @@ json_parse_restart: } /* End switch(z[i]) */ } + /* ** Parse a complete JSON string. Return 0 on success or non-zero if there ** are any errors. If an error occurs, free all memory held by pParse, @@ -204415,20 +205134,26 @@ json_parse_restart: ** pParse must be initialized to an empty parse object prior to calling ** this routine. */ -static int jsonParse( +static int jsonConvertTextToBlob( JsonParse *pParse, /* Initialize and fill this JsonParse object */ sqlite3_context *pCtx /* Report errors here */ ){ int i; const char *zJson = pParse->zJson; - i = jsonParseValue(pParse, 0); + i = jsonTranslateTextToBlob(pParse, 0); if( pParse->oom ) i = -1; if( i>0 ){ +#ifdef SQLITE_DEBUG assert( pParse->iDepth==0 ); - while( fast_isspace(zJson[i]) ) i++; + if( sqlite3Config.bJsonSelfcheck ){ + assert( jsonbValidityCheck(pParse, 0, pParse->nBlob, 0)==0 ); + } +#endif + while( jsonIsspace(zJson[i]) ) i++; if( zJson[i] ){ i += json5Whitespace(&zJson[i]); if( zJson[i] ){ + if( pCtx ) sqlite3_result_error(pCtx, "malformed JSON", -1); jsonParseReset(pParse); return 1; } @@ -204449,248 +205174,715 @@ static int jsonParse( return 0; } - -/* Mark node i of pParse as being a child of iParent. Call recursively -** to fill in all the descendants of node i. +/* +** The input string pStr is a well-formed JSON text string. Convert +** this into the JSONB format and make it the return value of the +** SQL function. */ -static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ - JsonNode *pNode = &pParse->aNode[i]; - u32 j; - pParse->aUp[i] = iParent; - switch( pNode->eType ){ - case JSON_ARRAY: { - for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j)){ - jsonParseFillInParentage(pParse, i+j, i); - } - break; - } - case JSON_OBJECT: { - for(j=1; j<=pNode->n; j += jsonNodeSize(pNode+j+1)+1){ - pParse->aUp[i+j] = i; - jsonParseFillInParentage(pParse, i+j+1, i); - } - break; - } - default: { - break; - } +static void jsonReturnStringAsBlob(JsonString *pStr){ + JsonParse px; + memset(&px, 0, sizeof(px)); + jsonStringTerminate(pStr); + px.zJson = pStr->zBuf; + px.nJson = pStr->nUsed; + px.db = sqlite3_context_db_handle(pStr->pCtx); + (void)jsonTranslateTextToBlob(&px, 0); + if( px.oom ){ + sqlite3DbFree(px.db, px.aBlob); + sqlite3_result_error_nomem(pStr->pCtx); + }else{ + assert( px.nBlobAlloc>0 ); + assert( !px.bReadOnly ); + sqlite3_result_blob(pStr->pCtx, px.aBlob, px.nBlob, SQLITE_DYNAMIC); } } -/* -** Compute the parentage of all nodes in a completed parse. +/* The byte at index i is a node type-code. This routine +** determines the payload size for that node and writes that +** payload size in to *pSz. It returns the offset from i to the +** beginning of the payload. Return 0 on error. */ -static int jsonParseFindParents(JsonParse *pParse){ - u32 *aUp; - assert( pParse->aUp==0 ); - aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode ); - if( aUp==0 ){ - pParse->oom = 1; - return SQLITE_NOMEM; - } - jsonParseFillInParentage(pParse, 0, 0); - return SQLITE_OK; -} - -/* -** Magic number used for the JSON parse cache in sqlite3_get_auxdata() -*/ -#define JSON_CACHE_ID (-429938) /* First cache entry */ -#define JSON_CACHE_SZ 4 /* Max number of cache entries */ - -/* -** Obtain a complete parse of the JSON found in the pJson argument -** -** Use the sqlite3_get_auxdata() cache to find a preexisting parse -** if it is available. If the cache is not available or if it -** is no longer valid, parse the JSON again and return the new parse. -** Also register the new parse so that it will be available for -** future sqlite3_get_auxdata() calls. -** -** If an error occurs and pErrCtx!=0 then report the error on pErrCtx -** and return NULL. -** -** The returned pointer (if it is not NULL) is owned by the cache in -** most cases, not the caller. The caller does NOT need to invoke -** jsonParseFree(), in most cases. -** -** Except, if an error occurs and pErrCtx==0 then return the JsonParse -** object with JsonParse.nErr non-zero and the caller will own the JsonParse -** object. In that case, it will be the responsibility of the caller to -** invoke jsonParseFree(). To summarize: -** -** pErrCtx!=0 || p->nErr==0 ==> Return value p is owned by the -** cache. Call does not need to -** free it. -** -** pErrCtx==0 && p->nErr!=0 ==> Return value is owned by the caller -** and so the caller must free it. -*/ -static JsonParse *jsonParseCached( - sqlite3_context *pCtx, /* Context to use for cache search */ - sqlite3_value *pJson, /* Function param containing JSON text */ - sqlite3_context *pErrCtx, /* Write parse errors here if not NULL */ - int bUnedited /* No prior edits allowed */ -){ - char *zJson = (char*)sqlite3_value_text(pJson); - int nJson = sqlite3_value_bytes(pJson); - JsonParse *p; - JsonParse *pMatch = 0; - int iKey; - int iMinKey = 0; - u32 iMinHold = 0xffffffff; - u32 iMaxHold = 0; - int bJsonRCStr; - - if( zJson==0 ) return 0; - for(iKey=0; iKeynJson==nJson - && (p->hasMod==0 || bUnedited==0) - && (p->zJson==zJson || memcmp(p->zJson,zJson,nJson)==0) - ){ - p->nErr = 0; - p->useMod = 0; - pMatch = p; - }else - if( pMatch==0 - && p->zAlt!=0 - && bUnedited==0 - && p->nAlt==nJson - && memcmp(p->zAlt, zJson, nJson)==0 - ){ - p->nErr = 0; - p->useMod = 1; - pMatch = p; - }else if( p->iHoldiHold; - iMinKey = iKey; - } - if( p->iHold>iMaxHold ){ - iMaxHold = p->iHold; - } - } - if( pMatch ){ - /* The input JSON text was found in the cache. Use the preexisting - ** parse of this JSON */ - pMatch->nErr = 0; - pMatch->iHold = iMaxHold+1; - assert( pMatch->nJPRef>0 ); /* pMatch is owned by the cache */ - return pMatch; - } - - /* The input JSON was not found anywhere in the cache. We will need - ** to parse it ourselves and generate a new JsonParse object. - */ - bJsonRCStr = sqlite3ValueIsOfClass(pJson,sqlite3RCStrUnref); - p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) ); - if( p==0 ){ - sqlite3_result_error_nomem(pCtx); +static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){ + u8 x; + u32 sz; + u32 n; + if( NEVER(i>pParse->nBlob) ){ + *pSz = 0; return 0; } - memset(p, 0, sizeof(*p)); - if( bJsonRCStr ){ - p->zJson = sqlite3RCStrRef(zJson); - p->bJsonIsRCStr = 1; - }else{ - p->zJson = (char*)&p[1]; - memcpy(p->zJson, zJson, nJson+1); - } - p->nJPRef = 1; - if( jsonParse(p, pErrCtx) ){ - if( pErrCtx==0 ){ - p->nErr = 1; - assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */ - return p; - } - jsonParseFree(p); - return 0; - } - p->nJson = nJson; - p->iHold = iMaxHold+1; - /* Transfer ownership of the new JsonParse to the cache */ - sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, - (void(*)(void*))jsonParseFree); - return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); -} - -/* -** Compare the OBJECT label at pNode against zKey,nKey. Return true on -** a match. -*/ -static int jsonLabelCompare(const JsonNode *pNode, const char *zKey, u32 nKey){ - assert( pNode->eU==1 ); - if( pNode->jnFlags & JNODE_RAW ){ - if( pNode->n!=nKey ) return 0; - return strncmp(pNode->u.zJContent, zKey, nKey)==0; - }else{ - if( pNode->n!=nKey+2 ) return 0; - return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; - } -} -static int jsonSameLabel(const JsonNode *p1, const JsonNode *p2){ - if( p1->jnFlags & JNODE_RAW ){ - return jsonLabelCompare(p2, p1->u.zJContent, p1->n); - }else if( p2->jnFlags & JNODE_RAW ){ - return jsonLabelCompare(p1, p2->u.zJContent, p2->n); - }else{ - return p1->n==p2->n && strncmp(p1->u.zJContent,p2->u.zJContent,p1->n)==0; - } -} - -/* forward declaration */ -static JsonNode *jsonLookupAppend(JsonParse*,const char*,int*,const char**); - -/* -** Search along zPath to find the node specified. Return a pointer -** to that node, or NULL if zPath is malformed or if there is no such -** node. -** -** If pApnd!=0, then try to append new nodes to complete zPath if it is -** possible to do so and if no existing node corresponds to zPath. If -** new nodes are appended *pApnd is set to 1. -*/ -static JsonNode *jsonLookupStep( - JsonParse *pParse, /* The JSON to search */ - u32 iRoot, /* Begin the search at this node */ - const char *zPath, /* The path to search */ - int *pApnd, /* Append nodes to complete path if not NULL */ - const char **pzErr /* Make *pzErr point to any syntax error in zPath */ -){ - u32 i, j, nKey; - const char *zKey; - JsonNode *pRoot; - if( pParse->oom ) return 0; - pRoot = &pParse->aNode[iRoot]; - if( pRoot->jnFlags & (JNODE_REPLACE|JNODE_REMOVE) && pParse->useMod ){ - while( (pRoot->jnFlags & JNODE_REPLACE)!=0 ){ - u32 idx = (u32)(pRoot - pParse->aNode); - i = pParse->iSubst; - while( 1 /*exit-by-break*/ ){ - assert( inNode ); - assert( pParse->aNode[i].eType==JSON_SUBST ); - assert( pParse->aNode[i].eU==4 ); - assert( pParse->aNode[i].u.iPrevaNode[i].n==idx ){ - pRoot = &pParse->aNode[i+1]; - iRoot = i+1; - break; - } - i = pParse->aNode[i].u.iPrev; - } - } - if( pRoot->jnFlags & JNODE_REMOVE ){ + x = pParse->aBlob[i]>>4; + if( x<=11 ){ + sz = x; + n = 1; + }else if( x==12 ){ + if( i+1>=pParse->nBlob ){ + *pSz = 0; return 0; } + sz = pParse->aBlob[i+1]; + n = 2; + }else if( x==13 ){ + if( i+2>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = (pParse->aBlob[i+1]<<8) + pParse->aBlob[i+2]; + n = 3; + }else if( x==14 ){ + if( i+4>=pParse->nBlob ){ + *pSz = 0; + return 0; + } + sz = ((u32)pParse->aBlob[i+1]<<24) + (pParse->aBlob[i+2]<<16) + + (pParse->aBlob[i+3]<<8) + pParse->aBlob[i+4]; + n = 5; + }else{ + if( i+8>=pParse->nBlob + || pParse->aBlob[i+1]!=0 + || pParse->aBlob[i+2]!=0 + || pParse->aBlob[i+3]!=0 + || pParse->aBlob[i+4]!=0 + ){ + *pSz = 0; + return 0; + } + sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) + + (pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8]; + n = 9; + } + if( (i64)i+sz+n > pParse->nBlob + && (i64)i+sz+n > pParse->nBlob-pParse->delta + ){ + sz = 0; + n = 0; + } + *pSz = sz; + return n; +} + + +/* +** Translate the binary JSONB representation of JSON beginning at +** pParse->aBlob[i] into a JSON text string. Append the JSON +** text onto the end of pOut. Return the index in pParse->aBlob[] +** of the first byte past the end of the element that is translated. +** +** If an error is detected in the BLOB input, the pOut->eErr flag +** might get set to JSTRING_MALFORMED. But not all BLOB input errors +** are detected. So a malformed JSONB input might either result +** in an error, or in incorrect JSON. +** +** The pOut->eErr JSTRING_OOM flag is set on a OOM. +*/ +static u32 jsonTranslateBlobToText( + const JsonParse *pParse, /* the complete parse of the JSON */ + u32 i, /* Start rendering at this index */ + JsonString *pOut /* Write JSON here */ +){ + u32 sz, n, j, iEnd; + + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + pOut->eErr |= JSTRING_MALFORMED; + return pParse->nBlob+1; + } + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_NULL: { + jsonAppendRawNZ(pOut, "null", 4); + return i+1; + } + case JSONB_TRUE: { + jsonAppendRawNZ(pOut, "true", 4); + return i+1; + } + case JSONB_FALSE: { + jsonAppendRawNZ(pOut, "false", 5); + return i+1; + } + case JSONB_INT: + case JSONB_FLOAT: { + if( sz==0 ) goto malformed_jsonb; + jsonAppendRaw(pOut, (const char*)&pParse->aBlob[i+n], sz); + break; + } + case JSONB_INT5: { /* Integer literal in hexadecimal notation */ + u32 k = 2; + sqlite3_uint64 u = 0; + const char *zIn = (const char*)&pParse->aBlob[i+n]; + int bOverflow = 0; + if( sz==0 ) goto malformed_jsonb; + if( zIn[0]=='-' ){ + jsonAppendChar(pOut, '-'); + k++; + }else if( zIn[0]=='+' ){ + k++; + } + for(; keErr |= JSTRING_MALFORMED; + break; + }else if( (u>>60)!=0 ){ + bOverflow = 1; + }else{ + u = u*16 + sqlite3HexToInt(zIn[k]); + } + } + jsonPrintf(100,pOut,bOverflow?"9.0e999":"%llu", u); + break; + } + case JSONB_FLOAT5: { /* Float literal missing digits beside "." */ + u32 k = 0; + const char *zIn = (const char*)&pParse->aBlob[i+n]; + if( sz==0 ) goto malformed_jsonb; + if( zIn[0]=='-' ){ + jsonAppendChar(pOut, '-'); + k++; + } + if( zIn[k]=='.' ){ + jsonAppendChar(pOut, '0'); + } + for(; kaBlob[i+n], sz); + jsonAppendChar(pOut, '"'); + break; + } + case JSONB_TEXT5: { + const char *zIn; + u32 k; + u32 sz2 = sz; + zIn = (const char*)&pParse->aBlob[i+n]; + jsonAppendChar(pOut, '"'); + while( sz2>0 ){ + for(k=0; k0 ){ + jsonAppendRawNZ(pOut, zIn, k); + if( k>=sz2 ){ + break; + } + zIn += k; + sz2 -= k; + } + if( zIn[0]=='"' ){ + jsonAppendRawNZ(pOut, "\\\"", 2); + zIn++; + sz2--; + continue; + } + assert( zIn[0]=='\\' ); + assert( sz2>=1 ); + if( sz2<2 ){ + pOut->eErr |= JSTRING_MALFORMED; + break; + } + switch( (u8)zIn[1] ){ + case '\'': + jsonAppendChar(pOut, '\''); + break; + case 'v': + jsonAppendRawNZ(pOut, "\\u0009", 6); + break; + case 'x': + if( sz2<4 ){ + pOut->eErr |= JSTRING_MALFORMED; + sz2 = 2; + break; + } + jsonAppendRawNZ(pOut, "\\u00", 4); + jsonAppendRawNZ(pOut, &zIn[2], 2); + zIn += 2; + sz2 -= 2; + break; + case '0': + jsonAppendRawNZ(pOut, "\\u0000", 6); + break; + case '\r': + if( sz2>2 && zIn[2]=='\n' ){ + zIn++; + sz2--; + } + break; + case '\n': + break; + case 0xe2: + /* '\' followed by either U+2028 or U+2029 is ignored as + ** whitespace. Not that in UTF8, U+2028 is 0xe2 0x80 0x29. + ** U+2029 is the same except for the last byte */ + if( sz2<4 + || 0x80!=(u8)zIn[2] + || (0xa8!=(u8)zIn[3] && 0xa9!=(u8)zIn[3]) + ){ + pOut->eErr |= JSTRING_MALFORMED; + sz2 = 2; + break; + } + zIn += 2; + sz2 -= 2; + break; + default: + jsonAppendRawNZ(pOut, zIn, 2); + break; + } + assert( sz2>=2 ); + zIn += 2; + sz2 -= 2; + } + jsonAppendChar(pOut, '"'); + break; + } + case JSONB_TEXTRAW: { + jsonAppendString(pOut, (const char*)&pParse->aBlob[i+n], sz); + break; + } + case JSONB_ARRAY: { + jsonAppendChar(pOut, '['); + j = i+n; + iEnd = j+sz; + while( jeErr==0 ){ + j = jsonTranslateBlobToText(pParse, j, pOut); + jsonAppendChar(pOut, ','); + } + if( j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); + jsonAppendChar(pOut, ']'); + break; + } + case JSONB_OBJECT: { + int x = 0; + jsonAppendChar(pOut, '{'); + j = i+n; + iEnd = j+sz; + while( jeErr==0 ){ + j = jsonTranslateBlobToText(pParse, j, pOut); + jsonAppendChar(pOut, (x++ & 1) ? ',' : ':'); + } + if( (x & 1)!=0 || j>iEnd ) pOut->eErr |= JSTRING_MALFORMED; + if( sz>0 ) jsonStringTrimOneChar(pOut); + jsonAppendChar(pOut, '}'); + break; + } + + default: { + malformed_jsonb: + pOut->eErr |= JSTRING_MALFORMED; + break; + } + } + return i+n+sz; +} + +/* Return true if the input pJson +** +** For performance reasons, this routine does not do a detailed check of the +** input BLOB to ensure that it is well-formed. Hence, false positives are +** possible. False negatives should never occur, however. +*/ +static int jsonFuncArgMightBeBinary(sqlite3_value *pJson){ + u32 sz, n; + const u8 *aBlob; + int nBlob; + JsonParse s; + if( sqlite3_value_type(pJson)!=SQLITE_BLOB ) return 0; + aBlob = sqlite3_value_blob(pJson); + nBlob = sqlite3_value_bytes(pJson); + if( nBlob<1 ) return 0; + if( NEVER(aBlob==0) || (aBlob[0] & 0x0f)>JSONB_OBJECT ) return 0; + memset(&s, 0, sizeof(s)); + s.aBlob = (u8*)aBlob; + s.nBlob = nBlob; + n = jsonbPayloadSize(&s, 0, &sz); + if( n==0 ) return 0; + if( sz+n!=(u32)nBlob ) return 0; + if( (aBlob[0] & 0x0f)<=JSONB_FALSE && sz>0 ) return 0; + return sz+n==(u32)nBlob; +} + +/* +** Given that a JSONB_ARRAY object starts at offset i, return +** the number of entries in that array. +*/ +static u32 jsonbArrayCount(JsonParse *pParse, u32 iRoot){ + u32 n, sz, i, iEnd; + u32 k = 0; + n = jsonbPayloadSize(pParse, iRoot, &sz); + iEnd = iRoot+n+sz; + for(i=iRoot+n; n>0 && idelta. +*/ +static void jsonAfterEditSizeAdjust(JsonParse *pParse, u32 iRoot){ + u32 sz = 0; + u32 nBlob; + assert( pParse->delta!=0 ); + assert( pParse->nBlobAlloc >= pParse->nBlob ); + nBlob = pParse->nBlob; + pParse->nBlob = pParse->nBlobAlloc; + (void)jsonbPayloadSize(pParse, iRoot, &sz); + pParse->nBlob = nBlob; + sz += pParse->delta; + pParse->delta += jsonBlobChangePayloadSize(pParse, iRoot, sz); +} + +/* +** Modify the JSONB blob at pParse->aBlob by removing nDel bytes of +** content beginning at iDel, and replacing them with nIns bytes of +** content given by aIns. +** +** nDel may be zero, in which case no bytes are removed. But iDel is +** still important as new bytes will be insert beginning at iDel. +** +** aIns may be zero, in which case space is created to hold nIns bytes +** beginning at iDel, but that space is uninitialized. +** +** Set pParse->oom if an OOM occurs. +*/ +static void jsonBlobEdit( + JsonParse *pParse, /* The JSONB to be modified is in pParse->aBlob */ + u32 iDel, /* First byte to be removed */ + u32 nDel, /* Number of bytes to remove */ + const u8 *aIns, /* Content to insert */ + u32 nIns /* Bytes of content to insert */ +){ + i64 d = (i64)nIns - (i64)nDel; + if( d!=0 ){ + if( pParse->nBlob + d > pParse->nBlobAlloc ){ + jsonBlobExpand(pParse, pParse->nBlob+d); + if( pParse->oom ) return; + } + memmove(&pParse->aBlob[iDel+nIns], + &pParse->aBlob[iDel+nDel], + pParse->nBlob - (iDel+nDel)); + pParse->nBlob += d; + pParse->delta += d; + } + if( nIns && aIns ) memcpy(&pParse->aBlob[iDel], aIns, nIns); +} + +/* +** Return the number of escaped newlines to be ignored. +** An escaped newline is a one of the following byte sequences: +** +** 0x5c 0x0a +** 0x5c 0x0d +** 0x5c 0x0d 0x0a +** 0x5c 0xe2 0x80 0xa8 +** 0x5c 0xe2 0x80 0xa9 +*/ +static u32 jsonBytesToBypass(const char *z, u32 n){ + u32 i = 0; + while( i+10 ); + assert( z[0]=='\\' ); + if( n<2 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + switch( (u8)z[1] ){ + case 'u': { + u32 v, vlo; + if( n<6 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + v = jsonHexToInt4(&z[2]); + if( (v & 0xfc00)==0xd800 + && n>=12 + && z[6]=='\\' + && z[7]=='u' + && ((vlo = jsonHexToInt4(&z[8]))&0xfc00)==0xdc00 + ){ + *piOut = ((v&0x3ff)<<10) + (vlo&0x3ff) + 0x10000; + return 12; + }else{ + *piOut = v; + return 6; + } + } + case 'b': { *piOut = '\b'; return 2; } + case 'f': { *piOut = '\f'; return 2; } + case 'n': { *piOut = '\n'; return 2; } + case 'r': { *piOut = '\r'; return 2; } + case 't': { *piOut = '\t'; return 2; } + case 'v': { *piOut = '\v'; return 2; } + case '0': { *piOut = 0; return 2; } + case '\'': + case '"': + case '/': + case '\\':{ *piOut = z[1]; return 2; } + case 'x': { + if( n<4 ){ + *piOut = JSON_INVALID_CHAR; + return n; + } + *piOut = (jsonHexToInt(z[2])<<4) | jsonHexToInt(z[3]); + return 4; + } + case 0xe2: + case '\r': + case '\n': { + u32 nSkip = jsonBytesToBypass(z, n); + if( nSkip==0 ){ + *piOut = JSON_INVALID_CHAR; + return n; + }else if( nSkip==n ){ + *piOut = 0; + return n; + }else if( z[nSkip]=='\\' ){ + return nSkip + jsonUnescapeOneChar(&z[nSkip], n-nSkip, piOut); + }else{ + int sz = sqlite3Utf8ReadLimited((u8*)&z[nSkip], n-nSkip, piOut); + return nSkip + sz; + } + } + default: { + *piOut = JSON_INVALID_CHAR; + return 2; + } + } +} + + +/* +** Compare two object labels. Return 1 if they are equal and +** 0 if they differ. +** +** In this version, we know that one or the other or both of the +** two comparands contains an escape sequence. +*/ +static SQLITE_NOINLINE int jsonLabelCompareEscaped( + const char *zLeft, /* The left label */ + u32 nLeft, /* Size of the left label in bytes */ + int rawLeft, /* True if zLeft contains no escapes */ + const char *zRight, /* The right label */ + u32 nRight, /* Size of the right label in bytes */ + int rawRight /* True if zRight is escape-free */ +){ + u32 cLeft, cRight; + assert( rawLeft==0 || rawRight==0 ); + while( 1 /*exit-by-return*/ ){ + if( nLeft==0 ){ + cLeft = 0; + }else if( rawLeft || zLeft[0]!='\\' ){ + cLeft = ((u8*)zLeft)[0]; + if( cLeft>=0xc0 ){ + int sz = sqlite3Utf8ReadLimited((u8*)zLeft, nLeft, &cLeft); + zLeft += sz; + nLeft -= sz; + }else{ + zLeft++; + nLeft--; + } + }else{ + u32 n = jsonUnescapeOneChar(zLeft, nLeft, &cLeft); + zLeft += n; + assert( n<=nLeft ); + nLeft -= n; + } + if( nRight==0 ){ + cRight = 0; + }else if( rawRight || zRight[0]!='\\' ){ + cRight = ((u8*)zRight)[0]; + if( cRight>=0xc0 ){ + int sz = sqlite3Utf8ReadLimited((u8*)zRight, nRight, &cRight); + zRight += sz; + nRight -= sz; + }else{ + zRight++; + nRight--; + } + }else{ + u32 n = jsonUnescapeOneChar(zRight, nRight, &cRight); + zRight += n; + assert( n<=nRight ); + nRight -= n; + } + if( cLeft!=cRight ) return 0; + if( cLeft==0 ) return 1; + } +} + +/* +** Compare two object labels. Return 1 if they are equal and +** 0 if they differ. Return -1 if an OOM occurs. +*/ +static int jsonLabelCompare( + const char *zLeft, /* The left label */ + u32 nLeft, /* Size of the left label in bytes */ + int rawLeft, /* True if zLeft contains no escapes */ + const char *zRight, /* The right label */ + u32 nRight, /* Size of the right label in bytes */ + int rawRight /* True if zRight is escape-free */ +){ + if( rawLeft && rawRight ){ + /* Simpliest case: Neither label contains escapes. A simple + ** memcmp() is sufficient. */ + if( nLeft!=nRight ) return 0; + return memcmp(zLeft, zRight, nLeft)==0; + }else{ + return jsonLabelCompareEscaped(zLeft, nLeft, rawLeft, + zRight, nRight, rawRight); + } +} + +/* +** Error returns from jsonLookupStep() +*/ +#define JSON_LOOKUP_ERROR 0xffffffff +#define JSON_LOOKUP_NOTFOUND 0xfffffffe +#define JSON_LOOKUP_PATHERROR 0xfffffffd +#define JSON_LOOKUP_ISERROR(x) ((x)>=JSON_LOOKUP_PATHERROR) + +/* Forward declaration */ +static u32 jsonLookupStep(JsonParse*,u32,const char*,u32); + + +/* This helper routine for jsonLookupStep() populates pIns with +** binary data that is to be inserted into pParse. +** +** In the common case, pIns just points to pParse->aIns and pParse->nIns. +** But if the zPath of the original edit operation includes path elements +** that go deeper, additional substructure must be created. +** +** For example: +** +** json_insert('{}', '$.a.b.c', 123); +** +** The search stops at '$.a' But additional substructure must be +** created for the ".b.c" part of the patch so that the final result +** is: {"a":{"b":{"c"::123}}}. This routine populates pIns with +** the binary equivalent of {"b":{"c":123}} so that it can be inserted. +** +** The caller is responsible for resetting pIns when it has finished +** using the substructure. +*/ +static u32 jsonCreateEditSubstructure( + JsonParse *pParse, /* The original JSONB that is being edited */ + JsonParse *pIns, /* Populate this with the blob data to insert */ + const char *zTail /* Tail of the path that determins substructure */ +){ + static const u8 emptyObject[] = { JSONB_ARRAY, JSONB_OBJECT }; + int rc; + memset(pIns, 0, sizeof(*pIns)); + pIns->db = pParse->db; + if( zTail[0]==0 ){ + /* No substructure. Just insert what is given in pParse. */ + pIns->aBlob = pParse->aIns; + pIns->nBlob = pParse->nIns; + rc = 0; + }else{ + /* Construct the binary substructure */ + pIns->nBlob = 1; + pIns->aBlob = (u8*)&emptyObject[zTail[0]=='.']; + pIns->eEdit = pParse->eEdit; + pIns->nIns = pParse->nIns; + pIns->aIns = pParse->aIns; + rc = jsonLookupStep(pIns, 0, zTail, 0); + pParse->oom |= pIns->oom; + } + return rc; /* Error code only */ +} + +/* +** Search along zPath to find the Json element specified. Return an +** index into pParse->aBlob[] for the start of that element's value. +** +** If the value found by this routine is the value half of label/value pair +** within an object, then set pPath->iLabel to the start of the corresponding +** label, before returning. +** +** Return one of the JSON_LOOKUP error codes if problems are seen. +** +** This routine will also modify the blob. If pParse->eEdit is one of +** JEDIT_DEL, JEDIT_REPL, JEDIT_INS, or JEDIT_SET, then changes might be +** made to the selected value. If an edit is performed, then the return +** value does not necessarily point to the select element. If an edit +** is performed, the return value is only useful for detecting error +** conditions. +*/ +static u32 jsonLookupStep( + JsonParse *pParse, /* The JSON to search */ + u32 iRoot, /* Begin the search at this element of aBlob[] */ + const char *zPath, /* The path to search */ + u32 iLabel /* Label if iRoot is a value of in an object */ +){ + u32 i, j, k, nKey, sz, n, iEnd, rc; + const char *zKey; + u8 x; + + if( zPath[0]==0 ){ + if( pParse->eEdit && jsonBlobMakeEditable(pParse, pParse->nIns) ){ + n = jsonbPayloadSize(pParse, iRoot, &sz); + sz += n; + if( pParse->eEdit==JEDIT_DEL ){ + if( iLabel>0 ){ + sz += iRoot - iLabel; + iRoot = iLabel; + } + jsonBlobEdit(pParse, iRoot, sz, 0, 0); + }else if( pParse->eEdit==JEDIT_INS ){ + /* Already exists, so json_insert() is a no-op */ + }else{ + /* json_set() or json_replace() */ + jsonBlobEdit(pParse, iRoot, sz, pParse->aIns, pParse->nIns); + } + } + pParse->iLabel = iLabel; + return iRoot; } - if( zPath[0]==0 ) return pRoot; if( zPath[0]=='.' ){ - if( pRoot->eType!=JSON_OBJECT ) return 0; + int rawKey = 1; + x = pParse->aBlob[iRoot]; zPath++; if( zPath[0]=='"' ){ zKey = zPath + 1; @@ -204699,251 +205891,704 @@ static JsonNode *jsonLookupStep( if( zPath[i] ){ i++; }else{ - *pzErr = zPath; - return 0; + return JSON_LOOKUP_PATHERROR; } testcase( nKey==0 ); + rawKey = memchr(zKey, '\\', nKey)==0; }else{ zKey = zPath; for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} nKey = i; if( nKey==0 ){ - *pzErr = zPath; - return 0; + return JSON_LOOKUP_PATHERROR; } } - j = 1; - for(;;){ - while( j<=pRoot->n ){ - if( jsonLabelCompare(pRoot+j, zKey, nKey) ){ - return jsonLookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); + if( (x & 0x0f)!=JSONB_OBJECT ) return JSON_LOOKUP_NOTFOUND; + n = jsonbPayloadSize(pParse, iRoot, &sz); + j = iRoot + n; /* j is the index of a label */ + iEnd = j+sz; + while( jaBlob[j] & 0x0f; + if( xJSONB_TEXTRAW ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + k = j+n; /* k is the index of the label text */ + if( k+sz>=iEnd ) return JSON_LOOKUP_ERROR; + zLabel = (const char*)&pParse->aBlob[k]; + rawLabel = x==JSONB_TEXT || x==JSONB_TEXTRAW; + if( jsonLabelCompare(zKey, nKey, rawKey, zLabel, sz, rawLabel) ){ + u32 v = k+sz; /* v is the index of the value */ + if( ((pParse->aBlob[v])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, v, &sz); + if( n==0 || v+n+sz>iEnd ) return JSON_LOOKUP_ERROR; + assert( j>0 ); + rc = jsonLookupStep(pParse, v, &zPath[i], j); + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } + j = k+sz; + if( ((pParse->aBlob[j])&0x0f)>JSONB_OBJECT ) return JSON_LOOKUP_ERROR; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + j += n+sz; + } + if( j>iEnd ) return JSON_LOOKUP_ERROR; + if( pParse->eEdit>=JEDIT_INS ){ + u32 nIns; /* Total bytes to insert (label+value) */ + JsonParse v; /* BLOB encoding of the value to be inserted */ + JsonParse ix; /* Header of the label to be inserted */ + testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_SET ); + memset(&ix, 0, sizeof(ix)); + ix.db = pParse->db; + jsonBlobAppendNode(&ix, rawKey?JSONB_TEXTRAW:JSONB_TEXT5, nKey, 0); + pParse->oom |= ix.oom; + rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i]); + if( !JSON_LOOKUP_ISERROR(rc) + && jsonBlobMakeEditable(pParse, ix.nBlob+nKey+v.nBlob) + ){ + assert( !pParse->oom ); + nIns = ix.nBlob + nKey + v.nBlob; + jsonBlobEdit(pParse, j, 0, 0, nIns); + if( !pParse->oom ){ + assert( pParse->aBlob!=0 ); /* Because pParse->oom!=0 */ + assert( ix.aBlob!=0 ); /* Because pPasre->oom!=0 */ + memcpy(&pParse->aBlob[j], ix.aBlob, ix.nBlob); + k = j + ix.nBlob; + memcpy(&pParse->aBlob[k], zKey, nKey); + k += nKey; + memcpy(&pParse->aBlob[k], v.aBlob, v.nBlob); + if( ALWAYS(pParse->delta) ) jsonAfterEditSizeAdjust(pParse, iRoot); } - j++; - j += jsonNodeSize(&pRoot[j]); } - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pRoot->eU==2 ); - iRoot = pRoot->u.iAppend; - pRoot = &pParse->aNode[iRoot]; - j = 1; - } - if( pApnd ){ - u32 iStart, iLabel; - JsonNode *pNode; - assert( pParse->useMod ); - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); - iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); - zPath += i; - pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); - if( pParse->oom ) return 0; - if( pNode ){ - pRoot = &pParse->aNode[iRoot]; - assert( pRoot->eU==0 ); - pRoot->u.iAppend = iStart; - pRoot->jnFlags |= JNODE_APPEND; - VVA( pRoot->eU = 2 ); - pParse->aNode[iLabel].jnFlags |= JNODE_RAW; - } - return pNode; + jsonParseReset(&v); + jsonParseReset(&ix); + return rc; } }else if( zPath[0]=='[' ){ - i = 0; - j = 1; - while( sqlite3Isdigit(zPath[j]) ){ - i = i*10 + zPath[j] - '0'; - j++; + x = pParse->aBlob[iRoot] & 0x0f; + if( x!=JSONB_ARRAY ) return JSON_LOOKUP_NOTFOUND; + n = jsonbPayloadSize(pParse, iRoot, &sz); + k = 0; + i = 1; + while( sqlite3Isdigit(zPath[i]) ){ + k = k*10 + zPath[i] - '0'; + i++; } - if( j<2 || zPath[j]!=']' ){ + if( i<2 || zPath[i]!=']' ){ if( zPath[1]=='#' ){ - JsonNode *pBase = pRoot; - int iBase = iRoot; - if( pRoot->eType!=JSON_ARRAY ) return 0; - for(;;){ - while( j<=pBase->n ){ - if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i++; - j += jsonNodeSize(&pBase[j]); - } - if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pBase->eU==2 ); - iBase = pBase->u.iAppend; - pBase = &pParse->aNode[iBase]; - j = 1; - } - j = 2; + k = jsonbArrayCount(pParse, iRoot); + i = 2; if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ - unsigned int x = 0; - j = 3; + unsigned int nn = 0; + i = 3; do{ - x = x*10 + zPath[j] - '0'; - j++; - }while( sqlite3Isdigit(zPath[j]) ); - if( x>i ) return 0; - i -= x; + nn = nn*10 + zPath[i] - '0'; + i++; + }while( sqlite3Isdigit(zPath[i]) ); + if( nn>k ) return JSON_LOOKUP_NOTFOUND; + k -= nn; } - if( zPath[j]!=']' ){ - *pzErr = zPath; - return 0; + if( zPath[i]!=']' ){ + return JSON_LOOKUP_PATHERROR; } }else{ - *pzErr = zPath; - return 0; + return JSON_LOOKUP_PATHERROR; } } - if( pRoot->eType!=JSON_ARRAY ) return 0; - zPath += j + 1; - j = 1; - for(;;){ - while( j<=pRoot->n - && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod)) + j = iRoot+n; + iEnd = j+sz; + while( jdelta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; + } + k--; + n = jsonbPayloadSize(pParse, j, &sz); + if( n==0 ) return JSON_LOOKUP_ERROR; + j += n+sz; + } + if( j>iEnd ) return JSON_LOOKUP_ERROR; + if( k>0 ) return JSON_LOOKUP_NOTFOUND; + if( pParse->eEdit>=JEDIT_INS ){ + JsonParse v; + testcase( pParse->eEdit==JEDIT_INS ); + testcase( pParse->eEdit==JEDIT_SET ); + rc = jsonCreateEditSubstructure(pParse, &v, &zPath[i+1]); + if( !JSON_LOOKUP_ISERROR(rc) + && jsonBlobMakeEditable(pParse, v.nBlob) ){ - if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--; - j += jsonNodeSize(&pRoot[j]); + assert( !pParse->oom ); + jsonBlobEdit(pParse, j, 0, v.aBlob, v.nBlob); } - if( i==0 && j<=pRoot->n ) break; - if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; - if( pParse->useMod==0 ) break; - assert( pRoot->eU==2 ); - iRoot = pRoot->u.iAppend; - pRoot = &pParse->aNode[iRoot]; - j = 1; - } - if( j<=pRoot->n ){ - return jsonLookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); - } - if( i==0 && pApnd ){ - u32 iStart; - JsonNode *pNode; - assert( pParse->useMod ); - iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); - pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); - if( pParse->oom ) return 0; - if( pNode ){ - pRoot = &pParse->aNode[iRoot]; - assert( pRoot->eU==0 ); - pRoot->u.iAppend = iStart; - pRoot->jnFlags |= JNODE_APPEND; - VVA( pRoot->eU = 2 ); - } - return pNode; + jsonParseReset(&v); + if( pParse->delta ) jsonAfterEditSizeAdjust(pParse, iRoot); + return rc; } }else{ - *pzErr = zPath; + return JSON_LOOKUP_PATHERROR; } - return 0; + return JSON_LOOKUP_NOTFOUND; } /* -** Append content to pParse that will complete zPath. Return a pointer -** to the inserted node, or return NULL if the append fails. +** Convert a JSON BLOB into text and make that text the return value +** of an SQL function. */ -static JsonNode *jsonLookupAppend( - JsonParse *pParse, /* Append content to the JSON parse */ - const char *zPath, /* Description of content to append */ - int *pApnd, /* Set this flag to 1 */ - const char **pzErr /* Make this point to any syntax error */ +static void jsonReturnTextJsonFromBlob( + sqlite3_context *ctx, + const u8 *aBlob, + u32 nBlob ){ - *pApnd = 1; - if( zPath[0]==0 ){ - jsonParseAddNode(pParse, JSON_NULL, 0, 0); - return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; + JsonParse x; + JsonString s; + + if( NEVER(aBlob==0) ) return; + memset(&x, 0, sizeof(x)); + x.aBlob = (u8*)aBlob; + x.nBlob = nBlob; + jsonStringInit(&s, ctx); + jsonTranslateBlobToText(&x, 0, &s); + jsonReturnString(&s, 0, 0); +} + + +/* +** Return the value of the BLOB node at index i. +** +** If the value is a primitive, return it as an SQL value. +** If the value is an array or object, return it as either +** JSON text or the BLOB encoding, depending on the JSON_B flag +** on the userdata. +*/ +static void jsonReturnFromBlob( + JsonParse *pParse, /* Complete JSON parse tree */ + u32 i, /* Index of the node */ + sqlite3_context *pCtx, /* Return value for this function */ + int textOnly /* return text JSON. Disregard user-data */ +){ + u32 n, sz; + int rc; + sqlite3 *db = sqlite3_context_db_handle(pCtx); + + n = jsonbPayloadSize(pParse, i, &sz); + if( n==0 ){ + sqlite3_result_error(pCtx, "malformed JSON", -1); + return; } - if( zPath[0]=='.' ){ - jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); - }else if( strncmp(zPath,"[0]",3)==0 ){ - jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); + switch( pParse->aBlob[i] & 0x0f ){ + case JSONB_NULL: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_null(pCtx); + break; + } + case JSONB_TRUE: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_int(pCtx, 1); + break; + } + case JSONB_FALSE: { + if( sz ) goto returnfromblob_malformed; + sqlite3_result_int(pCtx, 0); + break; + } + case JSONB_INT5: + case JSONB_INT: { + sqlite3_int64 iRes = 0; + char *z; + int bNeg = 0; + char x; + if( sz==0 ) goto returnfromblob_malformed; + x = (char)pParse->aBlob[i+n]; + if( x=='-' ){ + if( sz<2 ) goto returnfromblob_malformed; + n++; + sz--; + bNeg = 1; + } + z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); + if( z==0 ) goto returnfromblob_oom; + rc = sqlite3DecOrHexToI64(z, &iRes); + sqlite3DbFree(db, z); + if( rc==0 ){ + sqlite3_result_int64(pCtx, bNeg ? -iRes : iRes); + }else if( rc==3 && bNeg ){ + sqlite3_result_int64(pCtx, SMALLEST_INT64); + }else if( rc==1 ){ + goto returnfromblob_malformed; + }else{ + if( bNeg ){ n--; sz++; } + goto to_double; + } + break; + } + case JSONB_FLOAT5: + case JSONB_FLOAT: { + double r; + char *z; + if( sz==0 ) goto returnfromblob_malformed; + to_double: + z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz); + if( z==0 ) goto returnfromblob_oom; + rc = sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); + sqlite3DbFree(db, z); + if( rc<=0 ) goto returnfromblob_malformed; + sqlite3_result_double(pCtx, r); + break; + } + case JSONB_TEXTRAW: + case JSONB_TEXT: { + sqlite3_result_text(pCtx, (char*)&pParse->aBlob[i+n], sz, + SQLITE_TRANSIENT); + break; + } + case JSONB_TEXT5: + case JSONB_TEXTJ: { + /* Translate JSON formatted string into raw text */ + u32 iIn, iOut; + const char *z; + char *zOut; + u32 nOut = sz; + z = (const char*)&pParse->aBlob[i+n]; + zOut = sqlite3DbMallocRaw(db, nOut+1); + if( zOut==0 ) goto returnfromblob_oom; + for(iIn=iOut=0; iIn=2 ); + zOut[iOut++] = (char)(0xc0 | (v>>6)); + zOut[iOut++] = 0x80 | (v&0x3f); + }else if( v<0x10000 ){ + assert( szEscape>=3 ); + zOut[iOut++] = 0xe0 | (v>>12); + zOut[iOut++] = 0x80 | ((v>>6)&0x3f); + zOut[iOut++] = 0x80 | (v&0x3f); + }else if( v==JSON_INVALID_CHAR ){ + /* Silently ignore illegal unicode */ + }else{ + assert( szEscape>=4 ); + zOut[iOut++] = 0xf0 | (v>>18); + zOut[iOut++] = 0x80 | ((v>>12)&0x3f); + zOut[iOut++] = 0x80 | ((v>>6)&0x3f); + zOut[iOut++] = 0x80 | (v&0x3f); + } + iIn += szEscape - 1; + }else{ + zOut[iOut++] = c; + } + } /* end for() */ + assert( iOut<=nOut ); + zOut[iOut] = 0; + sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC); + break; + } + case JSONB_ARRAY: + case JSONB_OBJECT: { + int flags = textOnly ? 0 : SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx)); + if( flags & JSON_BLOB ){ + sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT); + }else{ + jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n); + } + break; + } + default: { + goto returnfromblob_malformed; + } + } + return; + +returnfromblob_oom: + sqlite3_result_error_nomem(pCtx); + return; + +returnfromblob_malformed: + sqlite3_result_error(pCtx, "malformed JSON", -1); + return; +} + +/* +** pArg is a function argument that might be an SQL value or a JSON +** value. Figure out what it is and encode it as a JSONB blob. +** Return the results in pParse. +** +** pParse is uninitialized upon entry. This routine will handle the +** initialization of pParse. The result will be contained in +** pParse->aBlob and pParse->nBlob. pParse->aBlob might be dynamically +** allocated (if pParse->nBlobAlloc is greater than zero) in which case +** the caller is responsible for freeing the space allocated to pParse->aBlob +** when it has finished with it. Or pParse->aBlob might be a static string +** or a value obtained from sqlite3_value_blob(pArg). +** +** If the argument is a BLOB that is clearly not a JSONB, then this +** function might set an error message in ctx and return non-zero. +** It might also set an error message and return non-zero on an OOM error. +*/ +static int jsonFunctionArgToBlob( + sqlite3_context *ctx, + sqlite3_value *pArg, + JsonParse *pParse +){ + int eType = sqlite3_value_type(pArg); + static u8 aNull[] = { 0x00 }; + memset(pParse, 0, sizeof(pParse[0])); + pParse->db = sqlite3_context_db_handle(ctx); + switch( eType ){ + default: { + pParse->aBlob = aNull; + pParse->nBlob = 1; + return 0; + } + case SQLITE_BLOB: { + if( jsonFuncArgMightBeBinary(pArg) ){ + pParse->aBlob = (u8*)sqlite3_value_blob(pArg); + pParse->nBlob = sqlite3_value_bytes(pArg); + }else{ + sqlite3_result_error(ctx, "JSON cannot hold BLOB values", -1); + return 1; + } + break; + } + case SQLITE_TEXT: { + const char *zJson = (const char*)sqlite3_value_text(pArg); + int nJson = sqlite3_value_bytes(pArg); + if( zJson==0 ) return 1; + if( sqlite3_value_subtype(pArg)==JSON_SUBTYPE ){ + pParse->zJson = (char*)zJson; + pParse->nJson = nJson; + if( jsonConvertTextToBlob(pParse, ctx) ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + sqlite3DbFree(pParse->db, pParse->aBlob); + memset(pParse, 0, sizeof(pParse[0])); + return 1; + } + }else{ + jsonBlobAppendNode(pParse, JSONB_TEXTRAW, nJson, zJson); + } + break; + } + case SQLITE_FLOAT: { + double r = sqlite3_value_double(pArg); + if( NEVER(sqlite3IsNaN(r)) ){ + jsonBlobAppendNode(pParse, JSONB_NULL, 0, 0); + }else{ + int n = sqlite3_value_bytes(pArg); + const char *z = (const char*)sqlite3_value_text(pArg); + if( z==0 ) return 1; + if( z[0]=='I' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 5, "9e999"); + }else if( z[0]=='-' && z[1]=='I' ){ + jsonBlobAppendNode(pParse, JSONB_FLOAT, 6, "-9e999"); + }else{ + jsonBlobAppendNode(pParse, JSONB_FLOAT, n, z); + } + } + break; + } + case SQLITE_INTEGER: { + int n = sqlite3_value_bytes(pArg); + const char *z = (const char*)sqlite3_value_text(pArg); + if( z==0 ) return 1; + jsonBlobAppendNode(pParse, JSONB_INT, n, z); + break; + } + } + if( pParse->oom ){ + sqlite3_result_error_nomem(ctx); + return 1; }else{ return 0; } - if( pParse->oom ) return 0; - return jsonLookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); } /* -** Return the text of a syntax error message on a JSON path. Space is -** obtained from sqlite3_malloc(). -*/ -static char *jsonPathSyntaxError(const char *zErr){ - return sqlite3_mprintf("JSON path error near '%q'", zErr); -} - -/* -** Do a node lookup using zPath. Return a pointer to the node on success. -** Return NULL if not found or if there is an error. +** Generate a bad path error. ** -** On an error, write an error message into pCtx and increment the -** pParse->nErr counter. -** -** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if -** nodes are appended. +** If ctx is not NULL then push the error message into ctx and return NULL. +** If ctx is NULL, then return the text of the error message. */ -static JsonNode *jsonLookup( - JsonParse *pParse, /* The JSON to search */ - const char *zPath, /* The path to search */ - int *pApnd, /* Append nodes to complete path if not NULL */ - sqlite3_context *pCtx /* Report errors here, if not NULL */ +static char *jsonBadPathError( + sqlite3_context *ctx, /* The function call containing the error */ + const char *zPath /* The path with the problem */ ){ - const char *zErr = 0; - JsonNode *pNode = 0; - char *zMsg; - - if( zPath==0 ) return 0; - if( zPath[0]!='$' ){ - zErr = zPath; - goto lookup_err; - } - zPath++; - pNode = jsonLookupStep(pParse, 0, zPath, pApnd, &zErr); - if( zErr==0 ) return pNode; - -lookup_err: - pParse->nErr++; - assert( zErr!=0 && pCtx!=0 ); - zMsg = jsonPathSyntaxError(zErr); + char *zMsg = sqlite3_mprintf("bad JSON path: %Q", zPath); + if( ctx==0 ) return zMsg; if( zMsg ){ - sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_result_error(ctx, zMsg, -1); sqlite3_free(zMsg); }else{ - sqlite3_result_error_nomem(pCtx); + sqlite3_result_error_nomem(ctx); } return 0; } - -/* -** Report the wrong number of arguments for json_insert(), json_replace() -** or json_set(). +/* argv[0] is a BLOB that seems likely to be a JSONB. Subsequent +** arguments come in parse where each pair contains a JSON path and +** content to insert or set at that patch. Do the updates +** and return the result. +** +** The specific operation is determined by eEdit, which can be one +** of JEDIT_INS, JEDIT_REPL, or JEDIT_SET. */ -static void jsonWrongNumArgs( - sqlite3_context *pCtx, - const char *zFuncName +static void jsonInsertIntoBlob( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv, + int eEdit /* JEDIT_INS, JEDIT_REPL, or JEDIT_SET */ ){ - char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", - zFuncName); - sqlite3_result_error(pCtx, zMsg, -1); - sqlite3_free(zMsg); + int i; + u32 rc = 0; + const char *zPath = 0; + int flgs; + JsonParse *p; + JsonParse ax; + + assert( (argc&1)==1 ); + flgs = argc==1 ? 0 : JSON_EDITABLE; + p = jsonParseFuncArg(ctx, argv[0], flgs); + if( p==0 ) return; + for(i=1; inBlob, ax.aBlob, ax.nBlob); + } + rc = 0; + }else{ + p->eEdit = eEdit; + p->nIns = ax.nBlob; + p->aIns = ax.aBlob; + p->delta = 0; + rc = jsonLookupStep(p, 0, zPath+1, 0); + } + jsonParseReset(&ax); + if( rc==JSON_LOOKUP_NOTFOUND ) continue; + if( JSON_LOOKUP_ISERROR(rc) ) goto jsonInsertIntoBlob_patherror; + } + jsonReturnParse(ctx, p); + jsonParseFree(p); + return; + +jsonInsertIntoBlob_patherror: + jsonParseFree(p); + if( rc==JSON_LOOKUP_ERROR ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + }else{ + jsonBadPathError(ctx, zPath); + } + return; } /* -** Mark all NULL entries in the Object passed in as JNODE_REMOVE. +** If pArg is a blob that seems like a JSONB blob, then initialize +** p to point to that JSONB and return TRUE. If pArg does not seem like +** a JSONB blob, then return FALSE; +** +** This routine is only called if it is already known that pArg is a +** blob. The only open question is whether or not the blob appears +** to be a JSONB blob. */ -static void jsonRemoveAllNulls(JsonNode *pNode){ - int i, n; - assert( pNode->eType==JSON_OBJECT ); - n = pNode->n; - for(i=2; i<=n; i += jsonNodeSize(&pNode[i])+1){ - switch( pNode[i].eType ){ - case JSON_NULL: - pNode[i].jnFlags |= JNODE_REMOVE; - break; - case JSON_OBJECT: - jsonRemoveAllNulls(&pNode[i]); - break; +static int jsonArgIsJsonb(sqlite3_value *pArg, JsonParse *p){ + u32 n, sz = 0; + p->aBlob = (u8*)sqlite3_value_blob(pArg); + p->nBlob = (u32)sqlite3_value_bytes(pArg); + if( p->nBlob==0 ){ + p->aBlob = 0; + return 0; + } + if( NEVER(p->aBlob==0) ){ + return 0; + } + if( (p->aBlob[0] & 0x0f)<=JSONB_OBJECT + && (n = jsonbPayloadSize(p, 0, &sz))>0 + && sz+n==p->nBlob + && ((p->aBlob[0] & 0x0f)>JSONB_FALSE || sz==0) + ){ + return 1; + } + p->aBlob = 0; + p->nBlob = 0; + return 0; +} + +/* +** Generate a JsonParse object, containing valid JSONB in aBlob and nBlob, +** from the SQL function argument pArg. Return a pointer to the new +** JsonParse object. +** +** Ownership of the new JsonParse object is passed to the caller. The +** caller should invoke jsonParseFree() on the return value when it +** has finished using it. +** +** If any errors are detected, an appropriate error messages is set +** using sqlite3_result_error() or the equivalent and this routine +** returns NULL. This routine also returns NULL if the pArg argument +** is an SQL NULL value, but no error message is set in that case. This +** is so that SQL functions that are given NULL arguments will return +** a NULL value. +*/ +static JsonParse *jsonParseFuncArg( + sqlite3_context *ctx, + sqlite3_value *pArg, + u32 flgs +){ + int eType; /* Datatype of pArg */ + JsonParse *p = 0; /* Value to be returned */ + JsonParse *pFromCache = 0; /* Value taken from cache */ + sqlite3 *db; /* The database connection */ + + assert( ctx!=0 ); + eType = sqlite3_value_type(pArg); + if( eType==SQLITE_NULL ){ + return 0; + } + pFromCache = jsonCacheSearch(ctx, pArg); + if( pFromCache ){ + pFromCache->nJPRef++; + if( (flgs & JSON_EDITABLE)==0 ){ + return pFromCache; } } + db = sqlite3_context_db_handle(ctx); +rebuild_from_cache: + p = sqlite3DbMallocZero(db, sizeof(*p)); + if( p==0 ) goto json_pfa_oom; + memset(p, 0, sizeof(*p)); + p->db = db; + p->nJPRef = 1; + if( pFromCache!=0 ){ + u32 nBlob = pFromCache->nBlob; + p->aBlob = sqlite3DbMallocRaw(db, nBlob); + if( p->aBlob==0 ) goto json_pfa_oom; + memcpy(p->aBlob, pFromCache->aBlob, nBlob); + p->nBlobAlloc = p->nBlob = nBlob; + p->hasNonstd = pFromCache->hasNonstd; + jsonParseFree(pFromCache); + return p; + } + if( eType==SQLITE_BLOB ){ + if( jsonArgIsJsonb(pArg,p) ){ + if( (flgs & JSON_EDITABLE)!=0 && jsonBlobMakeEditable(p, 0)==0 ){ + goto json_pfa_oom; + } + return p; + } + /* If the blob is not valid JSONB, fall through into trying to cast + ** the blob into text which is then interpreted as JSON. (tag-20240123-a) + ** + ** This goes against all historical documentation about how the SQLite + ** JSON functions were suppose to work. From the beginning, blob was + ** reserved for expansion and a blob value should have raised an error. + ** But it did not, due to a bug. And many applications came to depend + ** upon this buggy behavior, espeically when using the CLI and reading + ** JSON text using readfile(), which returns a blob. For this reason + ** we will continue to support the bug moving forward. + ** See for example https://sqlite.org/forum/forumpost/012136abd5292b8d + */ + } + p->zJson = (char*)sqlite3_value_text(pArg); + p->nJson = sqlite3_value_bytes(pArg); + if( p->nJson==0 ) goto json_pfa_malformed; + if( NEVER(p->zJson==0) ) goto json_pfa_oom; + if( jsonConvertTextToBlob(p, (flgs & JSON_KEEPERROR) ? 0 : ctx) ){ + if( flgs & JSON_KEEPERROR ){ + p->nErr = 1; + return p; + }else{ + jsonParseFree(p); + return 0; + } + }else{ + int isRCStr = sqlite3ValueIsOfClass(pArg, sqlite3RCStrUnref); + int rc; + if( !isRCStr ){ + char *zNew = sqlite3RCStrNew( p->nJson ); + if( zNew==0 ) goto json_pfa_oom; + memcpy(zNew, p->zJson, p->nJson); + p->zJson = zNew; + p->zJson[p->nJson] = 0; + }else{ + sqlite3RCStrRef(p->zJson); + } + p->bJsonIsRCStr = 1; + rc = jsonCacheInsert(ctx, p); + if( rc==SQLITE_NOMEM ) goto json_pfa_oom; + if( flgs & JSON_EDITABLE ){ + pFromCache = p; + p = 0; + goto rebuild_from_cache; + } + } + return p; + +json_pfa_malformed: + if( flgs & JSON_KEEPERROR ){ + p->nErr = 1; + return p; + }else{ + jsonParseFree(p); + sqlite3_result_error(ctx, "malformed JSON", -1); + return 0; + } + +json_pfa_oom: + jsonParseFree(pFromCache); + jsonParseFree(p); + sqlite3_result_error_nomem(ctx); + return 0; } +/* +** Make the return value of a JSON function either the raw JSONB blob +** or make it JSON text, depending on whether the JSON_BLOB flag is +** set on the function. +*/ +static void jsonReturnParse( + sqlite3_context *ctx, + JsonParse *p +){ + int flgs; + if( p->oom ){ + sqlite3_result_error_nomem(ctx); + return; + } + flgs = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( flgs & JSON_BLOB ){ + if( p->nBlobAlloc>0 && !p->bReadOnly ){ + sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_DYNAMIC); + p->nBlobAlloc = 0; + }else{ + sqlite3_result_blob(ctx, p->aBlob, p->nBlob, SQLITE_TRANSIENT); + } + }else{ + JsonString s; + jsonStringInit(&s, ctx); + p->delta = 0; + jsonTranslateBlobToText(p, 0, &s); + jsonReturnString(&s, p, ctx); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } +} /**************************************************************************** ** SQL functions used for testing and debugging @@ -204951,63 +206596,124 @@ static void jsonRemoveAllNulls(JsonNode *pNode){ #if SQLITE_DEBUG /* -** Print N node entries. +** Decode JSONB bytes in aBlob[] starting at iStart through but not +** including iEnd. Indent the +** content by nIndent spaces. */ -static void jsonDebugPrintNodeEntries( - JsonNode *aNode, /* First node entry to print */ - int N /* Number of node entries to print */ +static void jsonDebugPrintBlob( + JsonParse *pParse, /* JSON content */ + u32 iStart, /* Start rendering here */ + u32 iEnd, /* Do not render this byte or any byte after this one */ + int nIndent, /* Indent by this many spaces */ + sqlite3_str *pOut /* Generate output into this sqlite3_str object */ ){ - int i; - for(i=0; iaBlob[iStart] & 0x0f; + u32 savedNBlob = pParse->nBlob; + sqlite3_str_appendf(pOut, "%5d:%*s", iStart, nIndent, ""); + if( pParse->nBlobAlloc>pParse->nBlob ){ + pParse->nBlob = pParse->nBlobAlloc; } - printf("node %4u: %-7s n=%-5d", i, zType, aNode[i].n); - if( (aNode[i].jnFlags & ~JNODE_LABEL)!=0 ){ - u8 f = aNode[i].jnFlags; - if( f & JNODE_RAW ) printf(" RAW"); - if( f & JNODE_ESCAPE ) printf(" ESCAPE"); - if( f & JNODE_REMOVE ) printf(" REMOVE"); - if( f & JNODE_REPLACE ) printf(" REPLACE"); - if( f & JNODE_APPEND ) printf(" APPEND"); - if( f & JNODE_JSON5 ) printf(" JSON5"); + nn = n = jsonbPayloadSize(pParse, iStart, &sz); + if( nn==0 ) nn = 1; + if( sz>0 && xaBlob[iStart+i]); } + if( n==0 ){ + sqlite3_str_appendf(pOut, " ERROR invalid node size\n"); + iStart = n==0 ? iStart+1 : iEnd; + continue; + } + pParse->nBlob = savedNBlob; + if( iStart+n+sz>iEnd ){ + iEnd = iStart+n+sz; + if( iEnd>pParse->nBlob ){ + if( pParse->nBlobAlloc>0 && iEnd>pParse->nBlobAlloc ){ + iEnd = pParse->nBlobAlloc; + }else{ + iEnd = pParse->nBlob; + } + } + } + sqlite3_str_appendall(pOut," <-- "); + switch( x ){ + case JSONB_NULL: sqlite3_str_appendall(pOut,"null"); break; + case JSONB_TRUE: sqlite3_str_appendall(pOut,"true"); break; + case JSONB_FALSE: sqlite3_str_appendall(pOut,"false"); break; + case JSONB_INT: sqlite3_str_appendall(pOut,"int"); break; + case JSONB_INT5: sqlite3_str_appendall(pOut,"int5"); break; + case JSONB_FLOAT: sqlite3_str_appendall(pOut,"float"); break; + case JSONB_FLOAT5: sqlite3_str_appendall(pOut,"float5"); break; + case JSONB_TEXT: sqlite3_str_appendall(pOut,"text"); break; + case JSONB_TEXTJ: sqlite3_str_appendall(pOut,"textj"); break; + case JSONB_TEXT5: sqlite3_str_appendall(pOut,"text5"); break; + case JSONB_TEXTRAW: sqlite3_str_appendall(pOut,"textraw"); break; + case JSONB_ARRAY: { + sqlite3_str_appendf(pOut,"array, %u bytes\n", sz); + jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); + showContent = 0; + break; + } + case JSONB_OBJECT: { + sqlite3_str_appendf(pOut, "object, %u bytes\n", sz); + jsonDebugPrintBlob(pParse, iStart+n, iStart+n+sz, nIndent+2, pOut); + showContent = 0; + break; + } + default: { + sqlite3_str_appendall(pOut, "ERROR: unknown node type\n"); + showContent = 0; + break; + } + } + if( showContent ){ + if( sz==0 && x<=JSONB_FALSE ){ + sqlite3_str_append(pOut, "\n", 1); + }else{ + u32 i; + sqlite3_str_appendall(pOut, ": \""); + for(i=iStart+n; iaBlob[i]; + if( c<0x20 || c>=0x7f ) c = '.'; + sqlite3_str_append(pOut, (char*)&c, 1); + } + sqlite3_str_append(pOut, "\"\n", 2); + } + } + iStart += n + sz; } } +static void jsonShowParse(JsonParse *pParse){ + sqlite3_str out; + char zBuf[1000]; + if( pParse==0 ){ + printf("NULL pointer\n"); + return; + }else{ + printf("nBlobAlloc = %u\n", pParse->nBlobAlloc); + printf("nBlob = %u\n", pParse->nBlob); + printf("delta = %d\n", pParse->delta); + if( pParse->nBlob==0 ) return; + printf("content (bytes 0..%u):\n", pParse->nBlob-1); + } + sqlite3StrAccumInit(&out, 0, zBuf, sizeof(zBuf), 1000000); + jsonDebugPrintBlob(pParse, 0, pParse->nBlob, 0, &out); + printf("%s", sqlite3_str_value(&out)); + sqlite3_str_reset(&out); +} #endif /* SQLITE_DEBUG */ - -#if 0 /* 1 for debugging. 0 normally. Requires -DSQLITE_DEBUG too */ -static void jsonDebugPrintParse(JsonParse *p){ - jsonDebugPrintNodeEntries(p->aNode, p->nNode); -} -static void jsonDebugPrintNode(JsonNode *pNode){ - jsonDebugPrintNodeEntries(pNode, jsonNodeSize(pNode)); -} -#else - /* The usual case */ -# define jsonDebugPrintNode(X) -# define jsonDebugPrintParse(X) -#endif - #ifdef SQLITE_DEBUG /* ** SQL function: json_parse(JSON) ** -** Parse JSON using jsonParseCached(). Then print a dump of that -** parse on standard output. Return the mimified JSON result, just -** like the json() function. +** Parse JSON using jsonParseFuncArg(). Return text that is a +** human-readable dump of the binary JSONB for the input parameter. */ static void jsonParseFunc( sqlite3_context *ctx, @@ -205015,38 +206721,19 @@ static void jsonParseFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ + sqlite3_str out; - assert( argc==1 ); - p = jsonParseCached(ctx, argv[0], ctx, 0); + assert( argc>=1 ); + sqlite3StrAccumInit(&out, 0, 0, 0, 1000000); + p = jsonParseFuncArg(ctx, argv[0], 0); if( p==0 ) return; - printf("nNode = %u\n", p->nNode); - printf("nAlloc = %u\n", p->nAlloc); - printf("nJson = %d\n", p->nJson); - printf("nAlt = %d\n", p->nAlt); - printf("nErr = %u\n", p->nErr); - printf("oom = %u\n", p->oom); - printf("hasNonstd = %u\n", p->hasNonstd); - printf("useMod = %u\n", p->useMod); - printf("hasMod = %u\n", p->hasMod); - printf("nJPRef = %u\n", p->nJPRef); - printf("iSubst = %u\n", p->iSubst); - printf("iHold = %u\n", p->iHold); - jsonDebugPrintNodeEntries(p->aNode, p->nNode); - jsonReturnJson(p, p->aNode, ctx, 1, 0); -} - -/* -** The json_test1(JSON) function return true (1) if the input is JSON -** text generated by another json function. It returns (0) if the input -** is not known to be JSON. -*/ -static void jsonTest1Func( - sqlite3_context *ctx, - int argc, - sqlite3_value **argv -){ - UNUSED_PARAMETER(argc); - sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); + if( argc==1 ){ + jsonDebugPrintBlob(p, 0, p->nBlob, 0, &out); + sqlite3_result_text64(ctx, out.zText, out.nChar, SQLITE_DYNAMIC, SQLITE_UTF8); + }else{ + jsonShowParse(p); + } + jsonParseFree(p); } #endif /* SQLITE_DEBUG */ @@ -205055,7 +206742,7 @@ static void jsonTest1Func( ****************************************************************************/ /* -** Implementation of the json_QUOTE(VALUE) function. Return a JSON value +** Implementation of the json_quote(VALUE) function. Return a JSON value ** corresponding to the SQL value input. Mostly this means putting ** double-quotes around strings and returning the unquoted string "null" ** when given a NULL input. @@ -205068,9 +206755,9 @@ static void jsonQuoteFunc( JsonString jx; UNUSED_PARAMETER(argc); - jsonInit(&jx, ctx); - jsonAppendValue(&jx, argv[0]); - jsonResult(&jx); + jsonStringInit(&jx, ctx); + jsonAppendSqlValue(&jx, argv[0]); + jsonReturnString(&jx, 0, 0); sqlite3_result_subtype(ctx, JSON_SUBTYPE); } @@ -205087,18 +206774,17 @@ static void jsonArrayFunc( int i; JsonString jx; - jsonInit(&jx, ctx); + jsonStringInit(&jx, ctx); jsonAppendChar(&jx, '['); for(i=0; inNode ); if( argc==2 ){ const char *zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(p, zPath, 0, ctx); - }else{ - pNode = p->aNode; - } - if( pNode==0 ){ - return; - } - if( pNode->eType==JSON_ARRAY ){ - while( 1 /*exit-by-break*/ ){ - i = 1; - while( i<=pNode->n ){ - if( (pNode[i].jnFlags & JNODE_REMOVE)==0 ) n++; - i += jsonNodeSize(&pNode[i]); - } - if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; - if( p->useMod==0 ) break; - assert( pNode->eU==2 ); - pNode = &p->aNode[pNode->u.iAppend]; + if( zPath==0 ){ + jsonParseFree(p); + return; } + i = jsonLookupStep(p, 0, zPath[0]=='$' ? zPath+1 : "@", 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + /* no-op */ + }else if( i==JSON_LOOKUP_PATHERROR ){ + jsonBadPathError(ctx, zPath); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + eErr = 1; + i = 0; + } + }else{ + i = 0; } - sqlite3_result_int64(ctx, n); + if( (p->aBlob[i] & 0x0f)==JSONB_ARRAY ){ + cnt = jsonbArrayCount(p, i); + } + if( !eErr ) sqlite3_result_int64(ctx, cnt); + jsonParseFree(p); } -/* -** Bit values for the flags passed into jsonExtractFunc() or -** jsonSetFunc() via the user-data value. -*/ -#define JSON_JSON 0x01 /* Result is always JSON */ -#define JSON_SQL 0x02 /* Result is always SQL */ -#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ -#define JSON_ISSET 0x04 /* json_set(), not json_insert() */ +/* True if the string is all digits */ +static int jsonAllDigits(const char *z, int n){ + int i; + for(i=0; i and ->> operators accept abbreviated PATH arguments. This - ** is mostly for compatibility with PostgreSQL, but also for - ** convenience. - ** - ** NUMBER ==> $[NUMBER] // PG compatible - ** LABEL ==> $.LABEL // PG compatible - ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience - */ - jsonInit(&jx, ctx); - if( sqlite3Isdigit(zPath[0]) ){ - jsonAppendRawNZ(&jx, "$[", 2); - jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); - jsonAppendRawNZ(&jx, "]", 2); - }else{ - jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='[')); - jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); - jsonAppendChar(&jx, 0); - } - pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx); - jsonReset(&jx); - }else{ - pNode = jsonLookup(p, zPath, 0, ctx); - } - if( pNode ){ - if( flags & JSON_JSON ){ - jsonReturnJson(p, pNode, ctx, 0, 0); - }else{ - jsonReturn(p, pNode, ctx, 1); - } - } - }else{ - pNode = jsonLookup(p, zPath, 0, ctx); - if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx, 0); - } - }else{ - /* Two or more PATH arguments results in a JSON array with each - ** element of the array being the value selected by one of the PATHs */ - int i; - jsonInit(&jx, ctx); + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + jsonStringInit(&jx, ctx); + if( argc>2 ){ jsonAppendChar(&jx, '['); - for(i=1; inErr ) break; - jsonAppendSeparator(&jx); - if( pNode ){ - jsonRenderNode(p, pNode, &jx); + } + for(i=1; i and ->> operators accept abbreviated PATH arguments. This + ** is mostly for compatibility with PostgreSQL, but also for + ** convenience. + ** + ** NUMBER ==> $[NUMBER] // PG compatible + ** LABEL ==> $.LABEL // PG compatible + ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience + */ + jsonStringInit(&jx, ctx); + if( jsonAllDigits(zPath, nPath) ){ + jsonAppendRawNZ(&jx, "[", 1); + jsonAppendRaw(&jx, zPath, nPath); + jsonAppendRawNZ(&jx, "]", 2); + }else if( jsonAllAlphanum(zPath, nPath) ){ + jsonAppendRawNZ(&jx, ".", 1); + jsonAppendRaw(&jx, zPath, nPath); + }else if( zPath[0]=='[' && nPath>=3 && zPath[nPath-1]==']' ){ + jsonAppendRaw(&jx, zPath, nPath); }else{ + jsonAppendRawNZ(&jx, ".\"", 2); + jsonAppendRaw(&jx, zPath, nPath); + jsonAppendRawNZ(&jx, "\"", 1); + } + jsonStringTerminate(&jx); + j = jsonLookupStep(p, 0, jx.zBuf, 0); + jsonStringReset(&jx); + }else{ + jsonBadPathError(ctx, zPath); + goto json_extract_error; + } + if( jnBlob ){ + if( argc==2 ){ + if( flags & JSON_JSON ){ + jsonStringInit(&jx, ctx); + jsonTranslateBlobToText(p, j, &jx); + jsonReturnString(&jx, 0, 0); + jsonStringReset(&jx); + assert( (flags & JSON_BLOB)==0 ); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + }else{ + jsonReturnFromBlob(p, j, ctx, 0); + if( (flags & (JSON_SQL|JSON_BLOB))==0 + && (p->aBlob[j]&0x0f)>=JSONB_ARRAY + ){ + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } + } + }else{ + jsonAppendSeparator(&jx); + jsonTranslateBlobToText(p, j, &jx); + } + }else if( j==JSON_LOOKUP_NOTFOUND ){ + if( argc==2 ){ + goto json_extract_error; /* Return NULL if not found */ + }else{ + jsonAppendSeparator(&jx); jsonAppendRawNZ(&jx, "null", 4); } + }else if( j==JSON_LOOKUP_ERROR ){ + sqlite3_result_error(ctx, "malformed JSON", -1); + goto json_extract_error; + }else{ + jsonBadPathError(ctx, zPath); + goto json_extract_error; } - if( i==argc ){ - jsonAppendChar(&jx, ']'); - jsonResult(&jx); + } + if( argc>2 ){ + jsonAppendChar(&jx, ']'); + jsonReturnString(&jx, 0, 0); + if( (flags & JSON_BLOB)==0 ){ sqlite3_result_subtype(ctx, JSON_SUBTYPE); } - jsonReset(&jx); } +json_extract_error: + jsonStringReset(&jx); + jsonParseFree(p); + return; } -/* This is the RFC 7396 MergePatch algorithm. +/* +** Return codes for jsonMergePatch() */ -static JsonNode *jsonMergePatch( - JsonParse *pParse, /* The JSON parser that contains the TARGET */ - u32 iTarget, /* Node of the TARGET in pParse */ - JsonNode *pPatch /* The PATCH */ +#define JSON_MERGE_OK 0 /* Success */ +#define JSON_MERGE_BADTARGET 1 /* Malformed TARGET blob */ +#define JSON_MERGE_BADPATCH 2 /* Malformed PATCH blob */ +#define JSON_MERGE_OOM 3 /* Out-of-memory condition */ + +/* +** RFC-7396 MergePatch for two JSONB blobs. +** +** pTarget is the target. pPatch is the patch. The target is updated +** in place. The patch is read-only. +** +** The original RFC-7396 algorithm is this: +** +** define MergePatch(Target, Patch): +** if Patch is an Object: +** if Target is not an Object: +** Target = {} # Ignore the contents and set it to an empty Object +** for each Name/Value pair in Patch: +** if Value is null: +** if Name exists in Target: +** remove the Name/Value pair from Target +** else: +** Target[Name] = MergePatch(Target[Name], Value) +** return Target +** else: +** return Patch +** +** Here is an equivalent algorithm restructured to show the actual +** implementation: +** +** 01 define MergePatch(Target, Patch): +** 02 if Patch is not an Object: +** 03 return Patch +** 04 else: // if Patch is an Object +** 05 if Target is not an Object: +** 06 Target = {} +** 07 for each Name/Value pair in Patch: +** 08 if Name exists in Target: +** 09 if Value is null: +** 10 remove the Name/Value pair from Target +** 11 else +** 12 Target[name] = MergePatch(Target[Name], Value) +** 13 else if Value is not NULL: +** 14 if Value is not an Object: +** 15 Target[name] = Value +** 16 else: +** 17 Target[name] = MergePatch('{}',value) +** 18 return Target +** | +** ^---- Line numbers referenced in comments in the implementation +*/ +static int jsonMergePatch( + JsonParse *pTarget, /* The JSON parser that contains the TARGET */ + u32 iTarget, /* Index of TARGET in pTarget->aBlob[] */ + const JsonParse *pPatch, /* The PATCH */ + u32 iPatch /* Index of PATCH in pPatch->aBlob[] */ ){ - u32 i, j; - u32 iRoot; - JsonNode *pTarget; - if( pPatch->eType!=JSON_OBJECT ){ - return pPatch; + u8 x; /* Type of a single node */ + u32 n, sz=0; /* Return values from jsonbPayloadSize() */ + u32 iTCursor; /* Cursor position while scanning the target object */ + u32 iTStart; /* First label in the target object */ + u32 iTEndBE; /* Original first byte past end of target, before edit */ + u32 iTEnd; /* Current first byte past end of target */ + u8 eTLabel; /* Node type of the target label */ + u32 iTLabel = 0; /* Index of the label */ + u32 nTLabel = 0; /* Header size in bytes for the target label */ + u32 szTLabel = 0; /* Size of the target label payload */ + u32 iTValue = 0; /* Index of the target value */ + u32 nTValue = 0; /* Header size of the target value */ + u32 szTValue = 0; /* Payload size for the target value */ + + u32 iPCursor; /* Cursor position while scanning the patch */ + u32 iPEnd; /* First byte past the end of the patch */ + u8 ePLabel; /* Node type of the patch label */ + u32 iPLabel; /* Start of patch label */ + u32 nPLabel; /* Size of header on the patch label */ + u32 szPLabel; /* Payload size of the patch label */ + u32 iPValue; /* Start of patch value */ + u32 nPValue; /* Header size for the patch value */ + u32 szPValue; /* Payload size of the patch value */ + + assert( iTarget>=0 && iTargetnBlob ); + assert( iPatch>=0 && iPatchnBlob ); + x = pPatch->aBlob[iPatch] & 0x0f; + if( x!=JSONB_OBJECT ){ /* Algorithm line 02 */ + u32 szPatch; /* Total size of the patch, header+payload */ + u32 szTarget; /* Total size of the target, header+payload */ + n = jsonbPayloadSize(pPatch, iPatch, &sz); + szPatch = n+sz; + sz = 0; + n = jsonbPayloadSize(pTarget, iTarget, &sz); + szTarget = n+sz; + jsonBlobEdit(pTarget, iTarget, szTarget, pPatch->aBlob+iPatch, szPatch); + return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; /* Line 03 */ } - assert( iTargetnNode ); - pTarget = &pParse->aNode[iTarget]; - assert( (pPatch->jnFlags & JNODE_APPEND)==0 ); - if( pTarget->eType!=JSON_OBJECT ){ - jsonRemoveAllNulls(pPatch); - return pPatch; + x = pTarget->aBlob[iTarget] & 0x0f; + if( x!=JSONB_OBJECT ){ /* Algorithm line 05 */ + n = jsonbPayloadSize(pTarget, iTarget, &sz); + jsonBlobEdit(pTarget, iTarget+n, sz, 0, 0); + x = pTarget->aBlob[iTarget]; + pTarget->aBlob[iTarget] = (x & 0xf0) | JSONB_OBJECT; } - iRoot = iTarget; - for(i=1; in; i += jsonNodeSize(&pPatch[i+1])+1){ - u32 nKey; - const char *zKey; - assert( pPatch[i].eType==JSON_STRING ); - assert( pPatch[i].jnFlags & JNODE_LABEL ); - assert( pPatch[i].eU==1 ); - nKey = pPatch[i].n; - zKey = pPatch[i].u.zJContent; - for(j=1; jn; j += jsonNodeSize(&pTarget[j+1])+1 ){ - assert( pTarget[j].eType==JSON_STRING ); - assert( pTarget[j].jnFlags & JNODE_LABEL ); - if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){ - if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ) break; - if( pPatch[i+1].eType==JSON_NULL ){ - pTarget[j+1].jnFlags |= JNODE_REMOVE; - }else{ - JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); - if( pNew==0 ) return 0; - if( pNew!=&pParse->aNode[iTarget+j+1] ){ - jsonParseAddSubstNode(pParse, iTarget+j+1); - jsonParseAddNodeArray(pParse, pNew, jsonNodeSize(pNew)); - } - pTarget = &pParse->aNode[iTarget]; - } - break; + n = jsonbPayloadSize(pPatch, iPatch, &sz); + if( NEVER(n==0) ) return JSON_MERGE_BADPATCH; + iPCursor = iPatch+n; + iPEnd = iPCursor+sz; + n = jsonbPayloadSize(pTarget, iTarget, &sz); + if( NEVER(n==0) ) return JSON_MERGE_BADTARGET; + iTStart = iTarget+n; + iTEndBE = iTStart+sz; + + while( iPCursoraBlob[iPCursor] & 0x0f; + if( ePLabelJSONB_TEXTRAW ){ + return JSON_MERGE_BADPATCH; + } + nPLabel = jsonbPayloadSize(pPatch, iPCursor, &szPLabel); + if( nPLabel==0 ) return JSON_MERGE_BADPATCH; + iPValue = iPCursor + nPLabel + szPLabel; + if( iPValue>=iPEnd ) return JSON_MERGE_BADPATCH; + nPValue = jsonbPayloadSize(pPatch, iPValue, &szPValue); + if( nPValue==0 ) return JSON_MERGE_BADPATCH; + iPCursor = iPValue + nPValue + szPValue; + if( iPCursor>iPEnd ) return JSON_MERGE_BADPATCH; + + iTCursor = iTStart; + iTEnd = iTEndBE + pTarget->delta; + while( iTCursoraBlob[iTCursor] & 0x0f; + if( eTLabelJSONB_TEXTRAW ){ + return JSON_MERGE_BADTARGET; + } + nTLabel = jsonbPayloadSize(pTarget, iTCursor, &szTLabel); + if( nTLabel==0 ) return JSON_MERGE_BADTARGET; + iTValue = iTLabel + nTLabel + szTLabel; + if( iTValue>=iTEnd ) return JSON_MERGE_BADTARGET; + nTValue = jsonbPayloadSize(pTarget, iTValue, &szTValue); + if( nTValue==0 ) return JSON_MERGE_BADTARGET; + if( iTValue + nTValue + szTValue > iTEnd ) return JSON_MERGE_BADTARGET; + isEqual = jsonLabelCompare( + (const char*)&pPatch->aBlob[iPLabel+nPLabel], + szPLabel, + (ePLabel==JSONB_TEXT || ePLabel==JSONB_TEXTRAW), + (const char*)&pTarget->aBlob[iTLabel+nTLabel], + szTLabel, + (eTLabel==JSONB_TEXT || eTLabel==JSONB_TEXTRAW)); + if( isEqual ) break; + iTCursor = iTValue + nTValue + szTValue; + } + x = pPatch->aBlob[iPValue] & 0x0f; + if( iTCursoroom) ) return JSON_MERGE_OOM; + }else{ + /* Algorithm line 12 */ + int rc, savedDelta = pTarget->delta; + pTarget->delta = 0; + rc = jsonMergePatch(pTarget, iTValue, pPatch, iPValue); + if( rc ) return rc; + pTarget->delta += savedDelta; + } + }else if( x>0 ){ /* Algorithm line 13 */ + /* No match and patch value is not NULL */ + u32 szNew = szPLabel+nPLabel; + if( (pPatch->aBlob[iPValue] & 0x0f)!=JSONB_OBJECT ){ /* Line 14 */ + jsonBlobEdit(pTarget, iTEnd, 0, 0, szPValue+nPValue+szNew); + if( pTarget->oom ) return JSON_MERGE_OOM; + memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); + memcpy(&pTarget->aBlob[iTEnd+szNew], + &pPatch->aBlob[iPValue], szPValue+nPValue); + }else{ + int rc, savedDelta; + jsonBlobEdit(pTarget, iTEnd, 0, 0, szNew+1); + if( pTarget->oom ) return JSON_MERGE_OOM; + memcpy(&pTarget->aBlob[iTEnd], &pPatch->aBlob[iPLabel], szNew); + pTarget->aBlob[iTEnd+szNew] = 0x00; + savedDelta = pTarget->delta; + pTarget->delta = 0; + rc = jsonMergePatch(pTarget, iTEnd+szNew,pPatch,iPValue); + if( rc ) return rc; + pTarget->delta += savedDelta; } } - if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ - int iStart; - JsonNode *pApnd; - u32 nApnd; - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); - jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); - pApnd = &pPatch[i+1]; - if( pApnd->eType==JSON_OBJECT ) jsonRemoveAllNulls(pApnd); - nApnd = jsonNodeSize(pApnd); - jsonParseAddNodeArray(pParse, pApnd, jsonNodeSize(pApnd)); - if( pParse->oom ) return 0; - pParse->aNode[iStart].n = 1+nApnd; - pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; - pParse->aNode[iRoot].u.iAppend = iStart; - VVA( pParse->aNode[iRoot].eU = 2 ); - iRoot = iStart; - pTarget = &pParse->aNode[iTarget]; - } } - return pTarget; + if( pTarget->delta ) jsonAfterEditSizeAdjust(pTarget, iTarget); + return pTarget->oom ? JSON_MERGE_OOM : JSON_MERGE_OK; } + /* ** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a JSON ** object that is the result of running the RFC 7396 MergePatch() algorithm @@ -205333,28 +207182,27 @@ static void jsonPatchFunc( int argc, sqlite3_value **argv ){ - JsonParse *pX; /* The JSON that is being patched */ - JsonParse *pY; /* The patch */ - JsonNode *pResult; /* The result of the merge */ + JsonParse *pTarget; /* The TARGET */ + JsonParse *pPatch; /* The PATCH */ + int rc; /* Result code */ UNUSED_PARAMETER(argc); - pX = jsonParseCached(ctx, argv[0], ctx, 1); - if( pX==0 ) return; - assert( pX->hasMod==0 ); - pX->hasMod = 1; - pY = jsonParseCached(ctx, argv[1], ctx, 1); - if( pY==0 ) return; - pX->useMod = 1; - pY->useMod = 1; - pResult = jsonMergePatch(pX, 0, pY->aNode); - assert( pResult!=0 || pX->oom ); - if( pResult && pX->oom==0 ){ - jsonDebugPrintParse(pX); - jsonDebugPrintNode(pResult); - jsonReturnJson(pX, pResult, ctx, 0, 0); - }else{ - sqlite3_result_error_nomem(ctx); + assert( argc==2 ); + pTarget = jsonParseFuncArg(ctx, argv[0], JSON_EDITABLE); + if( pTarget==0 ) return; + pPatch = jsonParseFuncArg(ctx, argv[1], 0); + if( pPatch ){ + rc = jsonMergePatch(pTarget, 0, pPatch, 0); + if( rc==JSON_MERGE_OK ){ + jsonReturnParse(ctx, pTarget); + }else if( rc==JSON_MERGE_OOM ){ + sqlite3_result_error_nomem(ctx); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + jsonParseFree(pPatch); } + jsonParseFree(pTarget); } @@ -205378,23 +207226,23 @@ static void jsonObjectFunc( "of arguments", -1); return; } - jsonInit(&jx, ctx); + jsonStringInit(&jx, ctx); jsonAppendChar(&jx, '{'); for(i=0; i1); - if( pParse==0 ) return; - for(i=1; i<(u32)argc; i++){ + p = jsonParseFuncArg(ctx, argv[0], argc>1 ? JSON_EDITABLE : 0); + if( p==0 ) return; + for(i=1; inErr ) goto remove_done; - if( pNode ){ - pNode->jnFlags |= JNODE_REMOVE; - pParse->hasMod = 1; - pParse->useMod = 1; + if( zPath==0 ){ + goto json_remove_done; } - } - if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){ - jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); - } -remove_done: - jsonDebugPrintParse(p); -} - -/* -** Substitute the value at iNode with the pValue parameter. -*/ -static void jsonReplaceNode( - sqlite3_context *pCtx, - JsonParse *p, - int iNode, - sqlite3_value *pValue -){ - int idx = jsonParseAddSubstNode(p, iNode); - if( idx<=0 ){ - assert( p->oom ); - return; - } - switch( sqlite3_value_type(pValue) ){ - case SQLITE_NULL: { - jsonParseAddNode(p, JSON_NULL, 0, 0); - break; + if( zPath[0]!='$' ){ + goto json_remove_patherror; } - case SQLITE_FLOAT: { - char *z = sqlite3_mprintf("%!0.15g", sqlite3_value_double(pValue)); - int n; - if( z==0 ){ - p->oom = 1; - break; - } - n = sqlite3Strlen30(z); - jsonParseAddNode(p, JSON_REAL, n, z); - jsonParseAddCleanup(p, sqlite3_free, z); - break; + if( zPath[1]==0 ){ + /* json_remove(j,'$') returns NULL */ + goto json_remove_done; } - case SQLITE_INTEGER: { - char *z = sqlite3_mprintf("%lld", sqlite3_value_int64(pValue)); - int n; - if( z==0 ){ - p->oom = 1; - break; - } - n = sqlite3Strlen30(z); - jsonParseAddNode(p, JSON_INT, n, z); - jsonParseAddCleanup(p, sqlite3_free, z); - - break; - } - case SQLITE_TEXT: { - const char *z = (const char*)sqlite3_value_text(pValue); - u32 n = (u32)sqlite3_value_bytes(pValue); - if( z==0 ){ - p->oom = 1; - break; - } - if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){ - char *zCopy = sqlite3_malloc64( n+1 ); - int k; - if( zCopy ){ - memcpy(zCopy, z, n); - zCopy[n] = 0; - jsonParseAddCleanup(p, sqlite3_free, zCopy); - }else{ - p->oom = 1; - sqlite3_result_error_nomem(pCtx); - } - k = jsonParseAddNode(p, JSON_STRING, n, zCopy); - assert( k>0 || p->oom ); - if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW; + p->eEdit = JEDIT_DEL; + p->delta = 0; + rc = jsonLookupStep(p, 0, zPath+1, 0); + if( JSON_LOOKUP_ISERROR(rc) ){ + if( rc==JSON_LOOKUP_NOTFOUND ){ + continue; /* No-op */ + }else if( rc==JSON_LOOKUP_PATHERROR ){ + jsonBadPathError(ctx, zPath); }else{ - JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1); - if( pPatch==0 ){ - p->oom = 1; - break; - } - jsonParseAddNodeArray(p, pPatch->aNode, pPatch->nNode); - /* The nodes copied out of pPatch and into p likely contain - ** u.zJContent pointers into pPatch->zJson. So preserve the - ** content of pPatch until p is destroyed. */ - assert( pPatch->nJPRef>=1 ); - pPatch->nJPRef++; - jsonParseAddCleanup(p, (void(*)(void*))jsonParseFree, pPatch); + sqlite3_result_error(ctx, "malformed JSON", -1); } - break; - } - default: { - jsonParseAddNode(p, JSON_NULL, 0, 0); - sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1); - p->nErr++; - break; + goto json_remove_done; } } + jsonReturnParse(ctx, p); + jsonParseFree(p); + return; + +json_remove_patherror: + jsonBadPathError(ctx, zPath); + +json_remove_done: + jsonParseFree(p); + return; } /* @@ -205537,32 +207315,12 @@ static void jsonReplaceFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ - JsonNode *pNode; - const char *zPath; - u32 i; - if( argc<1 ) return; if( (argc&1)==0 ) { jsonWrongNumArgs(ctx, "replace"); return; } - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; - pParse->nJPRef++; - for(i=1; i<(u32)argc; i+=2){ - zPath = (const char*)sqlite3_value_text(argv[i]); - pParse->useMod = 1; - pNode = jsonLookup(pParse, zPath, 0, ctx); - if( pParse->nErr ) goto replace_err; - if( pNode ){ - jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); - } - } - jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); -replace_err: - jsonDebugPrintParse(pParse); - jsonParseFree(pParse); + jsonInsertIntoBlob(ctx, argc, argv, JEDIT_REPL); } @@ -205583,39 +207341,16 @@ static void jsonSetFunc( int argc, sqlite3_value **argv ){ - JsonParse *pParse; /* The parse */ - JsonNode *pNode; - const char *zPath; - u32 i; - int bApnd; - int bIsSet = sqlite3_user_data(ctx)!=0; + + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + int bIsSet = (flags&JSON_ISSET)!=0; if( argc<1 ) return; if( (argc&1)==0 ) { jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); return; } - pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); - if( pParse==0 ) return; - pParse->nJPRef++; - for(i=1; i<(u32)argc; i+=2){ - zPath = (const char*)sqlite3_value_text(argv[i]); - bApnd = 0; - pParse->useMod = 1; - pNode = jsonLookup(pParse, zPath, &bApnd, ctx); - if( pParse->oom ){ - sqlite3_result_error_nomem(ctx); - goto jsonSetDone; - }else if( pParse->nErr ){ - goto jsonSetDone; - }else if( pNode && (bApnd || bIsSet) ){ - jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); - } - } - jsonDebugPrintParse(pParse); - jsonReturnJson(pParse, pParse->aNode, ctx, 1, 0); -jsonSetDone: - jsonParseFree(pParse); + jsonInsertIntoBlob(ctx, argc, argv, bIsSet ? JEDIT_SET : JEDIT_INS); } /* @@ -205631,27 +207366,93 @@ static void jsonTypeFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ - const char *zPath; - JsonNode *pNode; + const char *zPath = 0; + u32 i; - p = jsonParseCached(ctx, argv[0], ctx, 0); + p = jsonParseFuncArg(ctx, argv[0], 0); if( p==0 ) return; if( argc==2 ){ zPath = (const char*)sqlite3_value_text(argv[1]); - pNode = jsonLookup(p, zPath, 0, ctx); + if( zPath==0 ) goto json_type_done; + if( zPath[0]!='$' ){ + jsonBadPathError(ctx, zPath); + goto json_type_done; + } + i = jsonLookupStep(p, 0, zPath+1, 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + /* no-op */ + }else if( i==JSON_LOOKUP_PATHERROR ){ + jsonBadPathError(ctx, zPath); + }else{ + sqlite3_result_error(ctx, "malformed JSON", -1); + } + goto json_type_done; + } }else{ - pNode = p->aNode; - } - if( pNode ){ - sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); + i = 0; } + sqlite3_result_text(ctx, jsonbType[p->aBlob[i]&0x0f], -1, SQLITE_STATIC); +json_type_done: + jsonParseFree(p); } /* ** json_valid(JSON) +** json_valid(JSON, FLAGS) ** -** Return 1 if JSON is a well-formed canonical JSON string according -** to RFC-7159. Return 0 otherwise. +** Check the JSON argument to see if it is well-formed. The FLAGS argument +** encodes the various constraints on what is meant by "well-formed": +** +** 0x01 Canonical RFC-8259 JSON text +** 0x02 JSON text with optional JSON-5 extensions +** 0x04 Superficially appears to be JSONB +** 0x08 Strictly well-formed JSONB +** +** If the FLAGS argument is omitted, it defaults to 1. Useful values for +** FLAGS include: +** +** 1 Strict canonical JSON text +** 2 JSON text perhaps with JSON-5 extensions +** 4 Superficially appears to be JSONB +** 5 Canonical JSON text or superficial JSONB +** 6 JSON-5 text or superficial JSONB +** 8 Strict JSONB +** 9 Canonical JSON text or strict JSONB +** 10 JSON-5 text or strict JSONB +** +** Other flag combinations are redundant. For example, every canonical +** JSON text is also well-formed JSON-5 text, so FLAG values 2 and 3 +** are the same. Similarly, any input that passes a strict JSONB validation +** will also pass the superficial validation so 12 through 15 are the same +** as 8 through 11 respectively. +** +** This routine runs in linear time to validate text and when doing strict +** JSONB validation. Superficial JSONB validation is constant time, +** assuming the BLOB is already in memory. The performance advantage +** of superficial JSONB validation is why that option is provided. +** Application developers can choose to do fast superficial validation or +** slower strict validation, according to their specific needs. +** +** Only the lower four bits of the FLAGS argument are currently used. +** Higher bits are reserved for future expansion. To facilitate +** compatibility, the current implementation raises an error if any bit +** in FLAGS is set other than the lower four bits. +** +** The original circa 2015 implementation of the JSON routines in +** SQLite only supported canonical RFC-8259 JSON text and the json_valid() +** function only accepted one argument. That is why the default value +** for the FLAGS argument is 1, since FLAGS=1 causes this routine to only +** recognize canonical RFC-8259 JSON text as valid. The extra FLAGS +** argument was added when the JSON routines were extended to support +** JSON5-like extensions and binary JSONB stored in BLOBs. +** +** Return Values: +** +** * Raise an error if FLAGS is outside the range of 1 to 15. +** * Return NULL if the input is NULL +** * Return 1 if the input is well-formed. +** * Return 0 if the input is not well-formed. */ static void jsonValidFunc( sqlite3_context *ctx, @@ -205659,79 +207460,128 @@ static void jsonValidFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ - UNUSED_PARAMETER(argc); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ + u8 flags = 1; + u8 res = 0; + if( argc==2 ){ + i64 f = sqlite3_value_int64(argv[1]); + if( f<1 || f>15 ){ + sqlite3_result_error(ctx, "FLAGS parameter to json_valid() must be" + " between 1 and 15", -1); + return; + } + flags = f & 0x0f; + } + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_NULL: { #ifdef SQLITE_LEGACY_JSON_VALID - /* Incorrect legacy behavior was to return FALSE for a NULL input */ - sqlite3_result_int(ctx, 0); + /* Incorrect legacy behavior was to return FALSE for a NULL input */ + sqlite3_result_int(ctx, 0); #endif - return; - } - p = jsonParseCached(ctx, argv[0], 0, 0); - if( p==0 || p->oom ){ - sqlite3_result_error_nomem(ctx); - sqlite3_free(p); - }else{ - sqlite3_result_int(ctx, p->nErr==0 && (p->hasNonstd==0 || p->useMod)); - if( p->nErr ) jsonParseFree(p); + return; + } + case SQLITE_BLOB: { + if( jsonFuncArgMightBeBinary(argv[0]) ){ + if( flags & 0x04 ){ + /* Superficial checking only - accomplished by the + ** jsonFuncArgMightBeBinary() call above. */ + res = 1; + }else if( flags & 0x08 ){ + /* Strict checking. Check by translating BLOB->TEXT->BLOB. If + ** no errors occur, call that a "strict check". */ + JsonParse px; + u32 iErr; + memset(&px, 0, sizeof(px)); + px.aBlob = (u8*)sqlite3_value_blob(argv[0]); + px.nBlob = sqlite3_value_bytes(argv[0]); + iErr = jsonbValidityCheck(&px, 0, px.nBlob, 1); + res = iErr==0; + } + break; + } + /* Fall through into interpreting the input as text. See note + ** above at tag-20240123-a. */ + /* no break */ deliberate_fall_through + } + default: { + JsonParse px; + if( (flags & 0x3)==0 ) break; + memset(&px, 0, sizeof(px)); + + p = jsonParseFuncArg(ctx, argv[0], JSON_KEEPERROR); + if( p ){ + if( p->oom ){ + sqlite3_result_error_nomem(ctx); + }else if( p->nErr ){ + /* no-op */ + }else if( (flags & 0x02)!=0 || p->hasNonstd==0 ){ + res = 1; + } + jsonParseFree(p); + }else{ + sqlite3_result_error_nomem(ctx); + } + break; + } } + sqlite3_result_int(ctx, res); } /* ** json_error_position(JSON) ** -** If the argument is not an interpretable JSON string, then return the 1-based -** character position at which the parser first recognized that the input -** was in error. The left-most character is 1. If the string is valid -** JSON, then return 0. +** If the argument is NULL, return NULL ** -** Note that json_valid() is only true for strictly conforming canonical JSON. -** But this routine returns zero if the input contains extension. Thus: +** If the argument is BLOB, do a full validity check and return non-zero +** if the check fails. The return value is the approximate 1-based offset +** to the byte of the element that contains the first error. ** -** (1) If the input X is strictly conforming canonical JSON: -** -** json_valid(X) returns true -** json_error_position(X) returns 0 -** -** (2) If the input X is JSON but it includes extension (such as JSON5) that -** are not part of RFC-8259: -** -** json_valid(X) returns false -** json_error_position(X) return 0 -** -** (3) If the input X cannot be interpreted as JSON even taking extensions -** into account: -** -** json_valid(X) return false -** json_error_position(X) returns 1 or more +** Otherwise interpret the argument is TEXT (even if it is numeric) and +** return the 1-based character position for where the parser first recognized +** that the input was not valid JSON, or return 0 if the input text looks +** ok. JSON-5 extensions are accepted. */ static void jsonErrorFunc( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ - JsonParse *p; /* The parse */ + i64 iErrPos = 0; /* Error position to be returned */ + JsonParse s; + + assert( argc==1 ); UNUSED_PARAMETER(argc); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - p = jsonParseCached(ctx, argv[0], 0, 0); - if( p==0 || p->oom ){ - sqlite3_result_error_nomem(ctx); - sqlite3_free(p); - }else if( p->nErr==0 ){ - sqlite3_result_int(ctx, 0); + memset(&s, 0, sizeof(s)); + s.db = sqlite3_context_db_handle(ctx); + if( jsonFuncArgMightBeBinary(argv[0]) ){ + s.aBlob = (u8*)sqlite3_value_blob(argv[0]); + s.nBlob = sqlite3_value_bytes(argv[0]); + iErrPos = (i64)jsonbValidityCheck(&s, 0, s.nBlob, 1); }else{ - int n = 1; - u32 i; - const char *z = (const char*)sqlite3_value_text(argv[0]); - for(i=0; iiErr && ALWAYS(z[i]); i++){ - if( (z[i]&0xc0)!=0x80 ) n++; + s.zJson = (char*)sqlite3_value_text(argv[0]); + if( s.zJson==0 ) return; /* NULL input or OOM */ + s.nJson = sqlite3_value_bytes(argv[0]); + if( jsonConvertTextToBlob(&s,0) ){ + if( s.oom ){ + iErrPos = -1; + }else{ + /* Convert byte-offset s.iErr into a character offset */ + u32 k; + assert( s.zJson!=0 ); /* Because s.oom is false */ + for(k=0; kzBuf==0 ){ - jsonInit(pStr, ctx); + jsonStringInit(pStr, ctx); jsonAppendChar(pStr, '['); }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); } pStr->pCtx = ctx; - jsonAppendValue(pStr, argv[0]); + jsonAppendSqlValue(pStr, argv[0]); } } static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ + int flags; pStr->pCtx = ctx; jsonAppendChar(pStr, ']'); - if( pStr->bErr ){ - if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); - assert( pStr->bStatic ); + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + }else if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(pStr); + if( isFinal ){ + if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); + }else{ + jsonStringTrimOneChar(pStr); + } + return; }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : @@ -205775,7 +207635,7 @@ static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); - pStr->nUsed--; + jsonStringTrimOneChar(pStr); } }else{ sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); @@ -205856,27 +207716,38 @@ static void jsonObjectStep( pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ - jsonInit(pStr, ctx); + jsonStringInit(pStr, ctx); jsonAppendChar(pStr, '{'); }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); } pStr->pCtx = ctx; z = (const char*)sqlite3_value_text(argv[0]); - n = (u32)sqlite3_value_bytes(argv[0]); + n = sqlite3Strlen30(z); jsonAppendString(pStr, z, n); jsonAppendChar(pStr, ':'); - jsonAppendValue(pStr, argv[1]); + jsonAppendSqlValue(pStr, argv[1]); } } static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ + int flags; jsonAppendChar(pStr, '}'); - if( pStr->bErr ){ - if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); - assert( pStr->bStatic ); + pStr->pCtx = ctx; + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); + if( pStr->eErr ){ + jsonReturnString(pStr, 0, 0); + return; + }else if( flags & JSON_BLOB ){ + jsonReturnStringAsBlob(pStr); + if( isFinal ){ + if( !pStr->bStatic ) sqlite3RCStrUnref(pStr->zBuf); + }else{ + jsonStringTrimOneChar(pStr); + } + return; }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, pStr->bStatic ? SQLITE_TRANSIENT : @@ -205884,7 +207755,7 @@ static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); - pStr->nUsed--; + jsonStringTrimOneChar(pStr); } }else{ sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); @@ -205904,19 +207775,37 @@ static void jsonObjectFinal(sqlite3_context *ctx){ /**************************************************************************** ** The json_each virtual table ****************************************************************************/ +typedef struct JsonParent JsonParent; +struct JsonParent { + u32 iHead; /* Start of object or array */ + u32 iValue; /* Start of the value */ + u32 iEnd; /* First byte past the end */ + u32 nPath; /* Length of path */ + i64 iKey; /* Key for JSONB_ARRAY */ +}; + typedef struct JsonEachCursor JsonEachCursor; struct JsonEachCursor { sqlite3_vtab_cursor base; /* Base class - must be first */ u32 iRowid; /* The rowid */ - u32 iBegin; /* The first node of the scan */ - u32 i; /* Index in sParse.aNode[] of current row */ + u32 i; /* Index in sParse.aBlob[] of current row */ u32 iEnd; /* EOF when i equals or exceeds this value */ - u8 eType; /* Type of top-level element */ + u32 nRoot; /* Size of the root path in bytes */ + u8 eType; /* Type of the container for element i */ u8 bRecursive; /* True for json_tree(). False for json_each() */ - char *zJson; /* Input JSON */ - char *zRoot; /* Path by which to filter zJson */ + u32 nParent; /* Current nesting depth */ + u32 nParentAlloc; /* Space allocated for aParent[] */ + JsonParent *aParent; /* Parent elements of i */ + sqlite3 *db; /* Database connection */ + JsonString path; /* Current path */ JsonParse sParse; /* Parse of the input JSON */ }; +typedef struct JsonEachConnection JsonEachConnection; +struct JsonEachConnection { + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection */ +}; + /* Constructor for the json_each virtual table */ static int jsonEachConnect( @@ -205926,7 +207815,7 @@ static int jsonEachConnect( sqlite3_vtab **ppVtab, char **pzErr ){ - sqlite3_vtab *pNew; + JsonEachConnection *pNew; int rc; /* Column numbers */ @@ -205952,28 +207841,32 @@ static int jsonEachConnect( "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," "json HIDDEN,root HIDDEN)"); if( rc==SQLITE_OK ){ - pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew)); + *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) return SQLITE_NOMEM; - memset(pNew, 0, sizeof(*pNew)); sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + pNew->db = db; } return rc; } /* destructor for json_each virtual table */ static int jsonEachDisconnect(sqlite3_vtab *pVtab){ - sqlite3_free(pVtab); + JsonEachConnection *p = (JsonEachConnection*)pVtab; + sqlite3DbFree(p->db, pVtab); return SQLITE_OK; } /* constructor for a JsonEachCursor object for json_each(). */ static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + JsonEachConnection *pVtab = (JsonEachConnection*)p; JsonEachCursor *pCur; UNUSED_PARAMETER(p); - pCur = sqlite3_malloc( sizeof(*pCur) ); + pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur)); if( pCur==0 ) return SQLITE_NOMEM; - memset(pCur, 0, sizeof(*pCur)); + pCur->db = pVtab->db; + jsonStringZero(&pCur->path); *ppCursor = &pCur->base; return SQLITE_OK; } @@ -205991,21 +207884,24 @@ static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ /* Reset a JsonEachCursor back to its original state. Free any memory ** held. */ static void jsonEachCursorReset(JsonEachCursor *p){ - sqlite3_free(p->zRoot); jsonParseReset(&p->sParse); + jsonStringReset(&p->path); + sqlite3DbFree(p->db, p->aParent); p->iRowid = 0; p->i = 0; + p->aParent = 0; + p->nParent = 0; + p->nParentAlloc = 0; p->iEnd = 0; p->eType = 0; - p->zJson = 0; - p->zRoot = 0; } /* Destructor for a jsonEachCursor object */ static int jsonEachClose(sqlite3_vtab_cursor *cur){ JsonEachCursor *p = (JsonEachCursor*)cur; jsonEachCursorReset(p); - sqlite3_free(cur); + + sqlite3DbFree(p->db, cur); return SQLITE_OK; } @@ -206016,200 +207912,230 @@ static int jsonEachEof(sqlite3_vtab_cursor *cur){ return p->i >= p->iEnd; } -/* Advance the cursor to the next element for json_tree() */ -static int jsonEachNext(sqlite3_vtab_cursor *cur){ - JsonEachCursor *p = (JsonEachCursor*)cur; - if( p->bRecursive ){ - if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++; - p->i++; - p->iRowid++; - if( p->iiEnd ){ - u32 iUp = p->sParse.aUp[p->i]; - JsonNode *pUp = &p->sParse.aNode[iUp]; - p->eType = pUp->eType; - if( pUp->eType==JSON_ARRAY ){ - assert( pUp->eU==0 || pUp->eU==3 ); - testcase( pUp->eU==3 ); - VVA( pUp->eU = 3 ); - if( iUp==p->i-1 ){ - pUp->u.iKey = 0; - }else{ - pUp->u.iKey++; +/* +** If the cursor is currently pointing at the label of a object entry, +** then return the index of the value. For all other cases, return the +** current pointer position, which is the value. +*/ +static int jsonSkipLabel(JsonEachCursor *p){ + if( p->eType==JSONB_OBJECT ){ + u32 sz = 0; + u32 n = jsonbPayloadSize(&p->sParse, p->i, &sz); + return p->i + n + sz; + }else{ + return p->i; + } +} + +/* +** Append the path name for the current element. +*/ +static void jsonAppendPathName(JsonEachCursor *p){ + assert( p->nParent>0 ); + assert( p->eType==JSONB_ARRAY || p->eType==JSONB_OBJECT ); + if( p->eType==JSONB_ARRAY ){ + jsonPrintf(30, &p->path, "[%lld]", p->aParent[p->nParent-1].iKey); + }else{ + u32 n, sz = 0, k, i; + const char *z; + int needQuote = 0; + n = jsonbPayloadSize(&p->sParse, p->i, &sz); + k = p->i + n; + z = (const char*)&p->sParse.aBlob[k]; + if( sz==0 || !sqlite3Isalpha(z[0]) ){ + needQuote = 1; + }else{ + for(i=0; ipath,".\"%.*s\"", sz, z); + }else{ + jsonPrintf(sz+2,&p->path,".%.*s", sz, z); + } + } +} + +/* Advance the cursor to the next element for json_tree() */ +static int jsonEachNext(sqlite3_vtab_cursor *cur){ + JsonEachCursor *p = (JsonEachCursor*)cur; + int rc = SQLITE_OK; + if( p->bRecursive ){ + u8 x; + u8 levelChange = 0; + u32 n, sz = 0; + u32 i = jsonSkipLabel(p); + x = p->sParse.aBlob[i] & 0x0f; + n = jsonbPayloadSize(&p->sParse, i, &sz); + if( x==JSONB_OBJECT || x==JSONB_ARRAY ){ + JsonParent *pParent; + if( p->nParent>=p->nParentAlloc ){ + JsonParent *pNew; + u64 nNew; + nNew = p->nParentAlloc*2 + 3; + pNew = sqlite3DbRealloc(p->db, p->aParent, sizeof(JsonParent)*nNew); + if( pNew==0 ) return SQLITE_NOMEM; + p->nParentAlloc = (u32)nNew; + p->aParent = pNew; + } + levelChange = 1; + pParent = &p->aParent[p->nParent]; + pParent->iHead = p->i; + pParent->iValue = i; + pParent->iEnd = i + n + sz; + pParent->iKey = -1; + pParent->nPath = (u32)p->path.nUsed; + if( p->eType && p->nParent ){ + jsonAppendPathName(p); + if( p->path.eErr ) rc = SQLITE_NOMEM; + } + p->nParent++; + p->i = i + n; + }else{ + p->i = i + n + sz; + } + while( p->nParent>0 && p->i >= p->aParent[p->nParent-1].iEnd ){ + p->nParent--; + p->path.nUsed = p->aParent[p->nParent].nPath; + levelChange = 1; + } + if( levelChange ){ + if( p->nParent>0 ){ + JsonParent *pParent = &p->aParent[p->nParent-1]; + u32 iVal = pParent->iValue; + p->eType = p->sParse.aBlob[iVal] & 0x0f; + }else{ + p->eType = 0; + } + } }else{ - switch( p->eType ){ - case JSON_ARRAY: { - p->i += jsonNodeSize(&p->sParse.aNode[p->i]); - p->iRowid++; - break; - } - case JSON_OBJECT: { - p->i += 1 + jsonNodeSize(&p->sParse.aNode[p->i+1]); - p->iRowid++; - break; - } - default: { - p->i = p->iEnd; - break; + u32 n, sz = 0; + u32 i = jsonSkipLabel(p); + n = jsonbPayloadSize(&p->sParse, i, &sz); + p->i = i + n + sz; + } + if( p->eType==JSONB_ARRAY && p->nParent ){ + p->aParent[p->nParent-1].iKey++; + } + p->iRowid++; + return rc; +} + +/* Length of the path for rowid==0 in bRecursive mode. +*/ +static int jsonEachPathLength(JsonEachCursor *p){ + u32 n = p->path.nUsed; + char *z = p->path.zBuf; + if( p->iRowid==0 && p->bRecursive && n>=2 ){ + while( n>1 ){ + n--; + if( z[n]=='[' || z[n]=='.' ){ + u32 x, sz = 0; + char cSaved = z[n]; + z[n] = 0; + assert( p->sParse.eEdit==0 ); + x = jsonLookupStep(&p->sParse, 0, z+1, 0); + z[n] = cSaved; + if( JSON_LOOKUP_ISERROR(x) ) continue; + if( x + jsonbPayloadSize(&p->sParse, x, &sz) == p->i ) break; } } } - return SQLITE_OK; -} - -/* Append an object label to the JSON Path being constructed -** in pStr. -*/ -static void jsonAppendObjectPathElement( - JsonString *pStr, - JsonNode *pNode -){ - int jj, nn; - const char *z; - assert( pNode->eType==JSON_STRING ); - assert( pNode->jnFlags & JNODE_LABEL ); - assert( pNode->eU==1 ); - z = pNode->u.zJContent; - nn = pNode->n; - if( (pNode->jnFlags & JNODE_RAW)==0 ){ - assert( nn>=2 ); - assert( z[0]=='"' || z[0]=='\'' ); - assert( z[nn-1]=='"' || z[0]=='\'' ); - if( nn>2 && sqlite3Isalpha(z[1]) ){ - for(jj=2; jjsParse.aUp[i]; - jsonEachComputePath(p, pStr, iUp); - pNode = &p->sParse.aNode[i]; - pUp = &p->sParse.aNode[iUp]; - if( pUp->eType==JSON_ARRAY ){ - assert( pUp->eU==3 || (pUp->eU==0 && pUp->u.iKey==0) ); - testcase( pUp->eU==0 ); - jsonPrintf(30, pStr, "[%d]", pUp->u.iKey); - }else{ - assert( pUp->eType==JSON_OBJECT ); - if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; - jsonAppendObjectPathElement(pStr, pNode); - } + return n; } /* Return the value of a column */ static int jsonEachColumn( sqlite3_vtab_cursor *cur, /* The cursor */ sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ - int i /* Which column to return */ + int iColumn /* Which column to return */ ){ JsonEachCursor *p = (JsonEachCursor*)cur; - JsonNode *pThis = &p->sParse.aNode[p->i]; - switch( i ){ + switch( iColumn ){ case JEACH_KEY: { - if( p->i==0 ) break; - if( p->eType==JSON_OBJECT ){ - jsonReturn(&p->sParse, pThis, ctx, 0); - }else if( p->eType==JSON_ARRAY ){ - u32 iKey; - if( p->bRecursive ){ - if( p->iRowid==0 ) break; - assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 ); - iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey; + if( p->nParent==0 ){ + u32 n, j; + if( p->nRoot==1 ) break; + j = jsonEachPathLength(p); + n = p->nRoot - j; + if( n==0 ){ + break; + }else if( p->path.zBuf[j]=='[' ){ + i64 x; + sqlite3Atoi64(&p->path.zBuf[j+1], &x, n-1, SQLITE_UTF8); + sqlite3_result_int64(ctx, x); + }else if( p->path.zBuf[j+1]=='"' ){ + sqlite3_result_text(ctx, &p->path.zBuf[j+2], n-3, SQLITE_TRANSIENT); }else{ - iKey = p->iRowid; + sqlite3_result_text(ctx, &p->path.zBuf[j+1], n-1, SQLITE_TRANSIENT); } - sqlite3_result_int64(ctx, (sqlite3_int64)iKey); + break; + } + if( p->eType==JSONB_OBJECT ){ + jsonReturnFromBlob(&p->sParse, p->i, ctx, 1); + }else{ + assert( p->eType==JSONB_ARRAY ); + sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey); } break; } case JEACH_VALUE: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - jsonReturn(&p->sParse, pThis, ctx, 0); + u32 i = jsonSkipLabel(p); + jsonReturnFromBlob(&p->sParse, i, ctx, 1); break; } case JEACH_TYPE: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); + u32 i = jsonSkipLabel(p); + u8 eType = p->sParse.aBlob[i] & 0x0f; + sqlite3_result_text(ctx, jsonbType[eType], -1, SQLITE_STATIC); break; } case JEACH_ATOM: { - if( pThis->jnFlags & JNODE_LABEL ) pThis++; - if( pThis->eType>=JSON_ARRAY ) break; - jsonReturn(&p->sParse, pThis, ctx, 0); + u32 i = jsonSkipLabel(p); + if( (p->sParse.aBlob[i] & 0x0f)sParse, i, ctx, 1); + } break; } case JEACH_ID: { - sqlite3_result_int64(ctx, - (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); + sqlite3_result_int64(ctx, (sqlite3_int64)p->i); break; } case JEACH_PARENT: { - if( p->i>p->iBegin && p->bRecursive ){ - sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]); + if( p->nParent>0 && p->bRecursive ){ + sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iHead); } break; } case JEACH_FULLKEY: { - JsonString x; - jsonInit(&x, ctx); - if( p->bRecursive ){ - jsonEachComputePath(p, &x, p->i); - }else{ - if( p->zRoot ){ - jsonAppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); - }else{ - jsonAppendChar(&x, '$'); - } - if( p->eType==JSON_ARRAY ){ - jsonPrintf(30, &x, "[%d]", p->iRowid); - }else if( p->eType==JSON_OBJECT ){ - jsonAppendObjectPathElement(&x, pThis); - } - } - jsonResult(&x); + u64 nBase = p->path.nUsed; + if( p->nParent ) jsonAppendPathName(p); + sqlite3_result_text64(ctx, p->path.zBuf, p->path.nUsed, + SQLITE_TRANSIENT, SQLITE_UTF8); + p->path.nUsed = nBase; break; } case JEACH_PATH: { - if( p->bRecursive ){ - JsonString x; - jsonInit(&x, ctx); - jsonEachComputePath(p, &x, p->sParse.aUp[p->i]); - jsonResult(&x); - break; - } - /* For json_each() path and root are the same so fall through - ** into the root case */ - /* no break */ deliberate_fall_through + u32 n = jsonEachPathLength(p); + sqlite3_result_text64(ctx, p->path.zBuf, n, + SQLITE_TRANSIENT, SQLITE_UTF8); + break; } default: { - const char *zRoot = p->zRoot; - if( zRoot==0 ) zRoot = "$"; - sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); + sqlite3_result_text(ctx, p->path.zBuf, p->nRoot, SQLITE_STATIC); break; } case JEACH_JSON: { - assert( i==JEACH_JSON ); - sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); + if( p->sParse.zJson==0 ){ + sqlite3_result_blob(ctx, p->sParse.aBlob, p->sParse.nBlob, + SQLITE_STATIC); + }else{ + sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); + } break; } } @@ -206300,86 +208226,97 @@ static int jsonEachFilter( int argc, sqlite3_value **argv ){ JsonEachCursor *p = (JsonEachCursor*)cur; - const char *z; const char *zRoot = 0; - sqlite3_int64 n; + u32 i, n, sz; UNUSED_PARAMETER(idxStr); UNUSED_PARAMETER(argc); jsonEachCursorReset(p); if( idxNum==0 ) return SQLITE_OK; - z = (const char*)sqlite3_value_text(argv[0]); - if( z==0 ) return SQLITE_OK; memset(&p->sParse, 0, sizeof(p->sParse)); p->sParse.nJPRef = 1; - if( sqlite3ValueIsOfClass(argv[0], sqlite3RCStrUnref) ){ - p->sParse.zJson = sqlite3RCStrRef((char*)z); + p->sParse.db = p->db; + if( jsonFuncArgMightBeBinary(argv[0]) ){ + p->sParse.nBlob = sqlite3_value_bytes(argv[0]); + p->sParse.aBlob = (u8*)sqlite3_value_blob(argv[0]); }else{ - n = sqlite3_value_bytes(argv[0]); - p->sParse.zJson = sqlite3RCStrNew( n+1 ); - if( p->sParse.zJson==0 ) return SQLITE_NOMEM; - memcpy(p->sParse.zJson, z, (size_t)n+1); - } - p->sParse.bJsonIsRCStr = 1; - p->zJson = p->sParse.zJson; - if( jsonParse(&p->sParse, 0) ){ - int rc = SQLITE_NOMEM; - if( p->sParse.oom==0 ){ - sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); - if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; + p->sParse.zJson = (char*)sqlite3_value_text(argv[0]); + p->sParse.nJson = sqlite3_value_bytes(argv[0]); + if( p->sParse.zJson==0 ){ + p->i = p->iEnd = 0; + return SQLITE_OK; } - jsonEachCursorReset(p); - return rc; - }else if( p->bRecursive && jsonParseFindParents(&p->sParse) ){ - jsonEachCursorReset(p); - return SQLITE_NOMEM; - }else{ - JsonNode *pNode = 0; - if( idxNum==3 ){ - const char *zErr = 0; - zRoot = (const char*)sqlite3_value_text(argv[1]); - if( zRoot==0 ) return SQLITE_OK; - n = sqlite3_value_bytes(argv[1]); - p->zRoot = sqlite3_malloc64( n+1 ); - if( p->zRoot==0 ) return SQLITE_NOMEM; - memcpy(p->zRoot, zRoot, (size_t)n+1); - if( zRoot[0]!='$' ){ - zErr = zRoot; - }else{ - pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); + if( jsonConvertTextToBlob(&p->sParse, 0) ){ + if( p->sParse.oom ){ + return SQLITE_NOMEM; } - if( zErr ){ + goto json_each_malformed_input; + } + } + if( idxNum==3 ){ + zRoot = (const char*)sqlite3_value_text(argv[1]); + if( zRoot==0 ) return SQLITE_OK; + if( zRoot[0]!='$' ){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + } + p->nRoot = sqlite3Strlen30(zRoot); + if( zRoot[1]==0 ){ + i = p->i = 0; + p->eType = 0; + }else{ + i = jsonLookupStep(&p->sParse, 0, zRoot+1, 0); + if( JSON_LOOKUP_ISERROR(i) ){ + if( i==JSON_LOOKUP_NOTFOUND ){ + p->i = 0; + p->eType = 0; + p->iEnd = 0; + return SQLITE_OK; + } sqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr); + cur->pVtab->zErrMsg = jsonBadPathError(0, zRoot); jsonEachCursorReset(p); return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; - }else if( pNode==0 ){ - return SQLITE_OK; } - }else{ - pNode = p->sParse.aNode; - } - p->iBegin = p->i = (int)(pNode - p->sParse.aNode); - p->eType = pNode->eType; - if( p->eType>=JSON_ARRAY ){ - assert( pNode->eU==0 ); - VVA( pNode->eU = 3 ); - pNode->u.iKey = 0; - p->iEnd = p->i + pNode->n + 1; - if( p->bRecursive ){ - p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType; - if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){ - p->i--; - } + if( p->sParse.iLabel ){ + p->i = p->sParse.iLabel; + p->eType = JSONB_OBJECT; }else{ - p->i++; + p->i = i; + p->eType = JSONB_ARRAY; } - }else{ - p->iEnd = p->i+1; } + jsonAppendRaw(&p->path, zRoot, p->nRoot); + }else{ + i = p->i = 0; + p->eType = 0; + p->nRoot = 1; + jsonAppendRaw(&p->path, "$", 1); + } + p->nParent = 0; + n = jsonbPayloadSize(&p->sParse, i, &sz); + p->iEnd = i+n+sz; + if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY && !p->bRecursive ){ + p->i = i + n; + p->eType = p->sParse.aBlob[i] & 0x0f; + p->aParent = sqlite3DbMallocZero(p->db, sizeof(JsonParent)); + if( p->aParent==0 ) return SQLITE_NOMEM; + p->nParent = 1; + p->nParentAlloc = 1; + p->aParent[0].iKey = 0; + p->aParent[0].iEnd = p->iEnd; + p->aParent[0].iHead = p->i; + p->aParent[0].iValue = i; } return SQLITE_OK; + +json_each_malformed_input: + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); + jsonEachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; } /* The methods of the json_each virtual table */ @@ -206448,40 +208385,54 @@ static sqlite3_module jsonTreeModule = { SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ #ifndef SQLITE_OMIT_JSON static FuncDef aJsonFunc[] = { - /* calls sqlite3_result_subtype() */ - /* | */ - /* Uses cache ______ | __ calls sqlite3_value_subtype() */ - /* | | | */ - /* Num args _________ | | | ___ Flags */ - /* | | | | | */ - /* | | | | | */ - JFUNCTION(json, 1, 1, 1, 0, 0, jsonRemoveFunc), - JFUNCTION(json_array, -1, 0, 1, 1, 0, jsonArrayFunc), - JFUNCTION(json_array_length, 1, 1, 0, 0, 0, jsonArrayLengthFunc), - JFUNCTION(json_array_length, 2, 1, 0, 0, 0, jsonArrayLengthFunc), - JFUNCTION(json_error_position,1, 1, 0, 0, 0, jsonErrorFunc), - JFUNCTION(json_extract, -1, 1, 1, 0, 0, jsonExtractFunc), - JFUNCTION(->, 2, 1, 1, 0, JSON_JSON, jsonExtractFunc), - JFUNCTION(->>, 2, 1, 0, 0, JSON_SQL, jsonExtractFunc), - JFUNCTION(json_insert, -1, 1, 1, 1, 0, jsonSetFunc), - JFUNCTION(json_object, -1, 0, 1, 1, 0, jsonObjectFunc), - JFUNCTION(json_patch, 2, 1, 1, 0, 0, jsonPatchFunc), - JFUNCTION(json_quote, 1, 0, 1, 1, 0, jsonQuoteFunc), - JFUNCTION(json_remove, -1, 1, 1, 0, 0, jsonRemoveFunc), - JFUNCTION(json_replace, -1, 1, 1, 1, 0, jsonReplaceFunc), - JFUNCTION(json_set, -1, 1, 1, 1, JSON_ISSET, jsonSetFunc), - JFUNCTION(json_type, 1, 1, 0, 0, 0, jsonTypeFunc), - JFUNCTION(json_type, 2, 1, 0, 0, 0, jsonTypeFunc), - JFUNCTION(json_valid, 1, 1, 0, 0, 0, jsonValidFunc), -#ifdef SQLITE_DEBUG - JFUNCTION(json_parse, 1, 1, 1, 0, 0, jsonParseFunc), - JFUNCTION(json_test1, 1, 1, 0, 1, 0, jsonTest1Func), + /* sqlite3_result_subtype() ----, ,--- sqlite3_value_subtype() */ + /* | | */ + /* Uses cache ------, | | ,---- Returns JSONB */ + /* | | | | */ + /* Number of arguments ---, | | | | ,--- Flags */ + /* | | | | | | */ + JFUNCTION(json, 1,1,1, 0,0,0, jsonRemoveFunc), + JFUNCTION(jsonb, 1,1,0, 0,1,0, jsonRemoveFunc), + JFUNCTION(json_array, -1,0,1, 1,0,0, jsonArrayFunc), + JFUNCTION(jsonb_array, -1,0,1, 1,1,0, jsonArrayFunc), + JFUNCTION(json_array_length, 1,1,0, 0,0,0, jsonArrayLengthFunc), + JFUNCTION(json_array_length, 2,1,0, 0,0,0, jsonArrayLengthFunc), + JFUNCTION(json_error_position,1,1,0, 0,0,0, jsonErrorFunc), + JFUNCTION(json_extract, -1,1,1, 0,0,0, jsonExtractFunc), + JFUNCTION(jsonb_extract, -1,1,0, 0,1,0, jsonExtractFunc), + JFUNCTION(->, 2,1,1, 0,0,JSON_JSON, jsonExtractFunc), + JFUNCTION(->>, 2,1,0, 0,0,JSON_SQL, jsonExtractFunc), + JFUNCTION(json_insert, -1,1,1, 1,0,0, jsonSetFunc), + JFUNCTION(jsonb_insert, -1,1,0, 1,1,0, jsonSetFunc), + JFUNCTION(json_object, -1,0,1, 1,0,0, jsonObjectFunc), + JFUNCTION(jsonb_object, -1,0,1, 1,1,0, jsonObjectFunc), + JFUNCTION(json_patch, 2,1,1, 0,0,0, jsonPatchFunc), + JFUNCTION(jsonb_patch, 2,1,0, 0,1,0, jsonPatchFunc), + JFUNCTION(json_quote, 1,0,1, 1,0,0, jsonQuoteFunc), + JFUNCTION(json_remove, -1,1,1, 0,0,0, jsonRemoveFunc), + JFUNCTION(jsonb_remove, -1,1,0, 0,1,0, jsonRemoveFunc), + JFUNCTION(json_replace, -1,1,1, 1,0,0, jsonReplaceFunc), + JFUNCTION(jsonb_replace, -1,1,0, 1,1,0, jsonReplaceFunc), + JFUNCTION(json_set, -1,1,1, 1,0,JSON_ISSET, jsonSetFunc), + JFUNCTION(jsonb_set, -1,1,0, 1,1,JSON_ISSET, jsonSetFunc), + JFUNCTION(json_type, 1,1,0, 0,0,0, jsonTypeFunc), + JFUNCTION(json_type, 2,1,0, 0,0,0, jsonTypeFunc), + JFUNCTION(json_valid, 1,1,0, 0,0,0, jsonValidFunc), + JFUNCTION(json_valid, 2,1,0, 0,0,0, jsonValidFunc), +#if SQLITE_DEBUG + JFUNCTION(json_parse, 1,1,0, 0,0,0, jsonParseFunc), #endif WAGGREGATE(json_group_array, 1, 0, 0, jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| SQLITE_DETERMINISTIC), + WAGGREGATE(jsonb_group_array, 1, JSON_BLOB, 0, + jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), WAGGREGATE(json_group_object, 2, 0, 0, + jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), + WAGGREGATE(jsonb_group_object,2, JSON_BLOB, 0, jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, SQLITE_SUBTYPE|SQLITE_RESULT_SUBTYPE|SQLITE_UTF8| SQLITE_DETERMINISTIC) @@ -207232,7 +209183,7 @@ static int nodeAcquire( ** increase its reference count and return it. */ if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ - if( pParent && pParent!=pNode->pParent ){ + if( pParent && ALWAYS(pParent!=pNode->pParent) ){ RTREE_IS_CORRUPT(pRtree); return SQLITE_CORRUPT_VTAB; } @@ -209967,7 +211918,7 @@ static int rtreeSqlInit( } sqlite3_free(zSql); } - if( pRtree->nAux ){ + if( pRtree->nAux && rc!=SQLITE_NOMEM ){ pRtree->zReadAuxSql = sqlite3_mprintf( "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1", zDb, zPrefix); @@ -210656,15 +212607,13 @@ static int rtreeCheckTable( check.zTab = zTab; /* Find the number of auxiliary columns */ - if( check.rc==SQLITE_OK ){ - pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); - if( pStmt ){ - nAux = sqlite3_column_count(pStmt) - 2; - sqlite3_finalize(pStmt); - }else - if( check.rc!=SQLITE_NOMEM ){ - check.rc = SQLITE_OK; - } + pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); + if( pStmt ){ + nAux = sqlite3_column_count(pStmt) - 2; + sqlite3_finalize(pStmt); + }else + if( check.rc!=SQLITE_NOMEM ){ + check.rc = SQLITE_OK; } /* Find number of dimensions in the rtree table. */ @@ -210719,6 +212668,7 @@ static int rtreeIntegrity( if( rc==SQLITE_OK && *pzErr ){ *pzErr = sqlite3_mprintf("In RTree %s.%s:\n%z", pRtree->zDb, pRtree->zName, *pzErr); + if( (*pzErr)==0 ) rc = SQLITE_NOMEM; } return rc; } @@ -223389,9 +225339,7 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){ ** associated hash-tables. */ sessionDeleteTable(pSession, pSession->pTable); - /* Assert that all allocations have been freed and then free the - ** session object itself. */ - // assert( pSession->nMalloc==0 ); + /* Free the session object. */ sqlite3_free(pSession); } @@ -227604,8 +229552,11 @@ struct Fts5PhraseIter { ** created with the "columnsize=0" option. ** ** xColumnText: -** This function attempts to retrieve the text of column iCol of the -** current document. If successful, (*pz) is set to point to a buffer +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the text of column iCol of +** the current document. If successful, (*pz) is set to point to a buffer ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, ** if an error occurs, an SQLite error code is returned and the final values @@ -227615,8 +229566,10 @@ struct Fts5PhraseIter { ** Returns the number of phrases in the current query expression. ** ** xPhraseSize: -** Returns the number of tokens in phrase iPhrase of the query. Phrases -** are numbered starting from zero. +** If parameter iCol is less than zero, or greater than or equal to the +** number of phrases in the current query, as returned by xPhraseCount, +** 0 is returned. Otherwise, this function returns the number of tokens in +** phrase iPhrase of the query. Phrases are numbered starting from zero. ** ** xInstCount: ** Set *pnInst to the total number of occurrences of all phrases within @@ -227632,12 +229585,13 @@ struct Fts5PhraseIter { ** Query for the details of phrase match iIdx within the current row. ** Phrase matches are numbered starting from zero, so the iIdx argument ** should be greater than or equal to zero and smaller than the value -** output by xInstCount(). +** output by xInstCount(). If iIdx is less than zero or greater than +** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. ** -** Usually, output parameter *piPhrase is set to the phrase number, *piCol +** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. Returns SQLITE_OK if successful, or an error -** code (i.e. SQLITE_NOMEM) if an error occurs. +** first token of the phrase. SQLITE_OK is returned if successful, or an +** error code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -227663,6 +229617,10 @@ struct Fts5PhraseIter { ** Invoking Api.xUserData() returns a copy of the pointer passed as ** the third argument to pUserData. ** +** If parameter iPhrase is less than zero, or greater than or equal to +** the number of phrases in the query, as returned by xPhraseCount(), +** this function returns SQLITE_RANGE. +** ** If the callback function returns any value other than SQLITE_OK, the ** query is abandoned and the xQueryPhrase function returns immediately. ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. @@ -227777,9 +229735,42 @@ struct Fts5PhraseIter { ** ** xPhraseNextColumn() ** See xPhraseFirstColumn above. +** +** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase iPhrase of the current +** query. Before returning, output parameter *ppToken is set to point +** to a buffer containing the requested token, and *pnToken to the +** size of this buffer in bytes. +** +** If iPhrase or iToken are less than zero, or if iPhrase is greater than +** or equal to the number of phrases in the query as reported by +** xPhraseCount(), or if iToken is equal to or greater than the number of +** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken + are both zeroed. +** +** The output text is not a copy of the query text that specified the +** token. It is the output of the tokenizer module. For tokendata=1 +** tables, this includes any embedded 0x00 and trailing data. +** +** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase hit iIdx within the +** current row. If iIdx is less than zero or greater than or equal to the +** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, +** output variable (*ppToken) is set to point to a buffer containing the +** matching document token, and (*pnToken) to the size of that buffer in +** bytes. This API is not available if the specified token matches a +** prefix query term. In that case both output variables are always set +** to 0. +** +** The output text is not a copy of the document text that was tokenized. +** It is the output of the tokenizer module. For tokendata=1 tables, this +** includes any embedded 0x00 and trailing data. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ void *(*xUserData)(Fts5Context*); @@ -227814,6 +229805,13 @@ struct Fts5ExtensionApi { int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); + + /* Below this point are iVersion>=3 only */ + int (*xQueryToken)(Fts5Context*, + int iPhrase, int iToken, + const char **ppToken, int *pnToken + ); + int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); }; /* @@ -228288,6 +230286,7 @@ struct Fts5Config { char *zContent; /* content table */ char *zContentRowid; /* "content_rowid=" option value */ int bColumnsize; /* "columnsize=" option value (dflt==1) */ + int bTokendata; /* "tokendata=" option value (dflt==0) */ int eDetail; /* FTS5_DETAIL_XXX value */ char *zContentExprlist; Fts5Tokenizer *pTok; @@ -228476,17 +230475,19 @@ struct Fts5IndexIter { /* ** Values used as part of the flags argument passed to IndexQuery(). */ -#define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */ -#define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */ -#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */ -#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */ +#define FTS5INDEX_QUERY_PREFIX 0x0001 /* Prefix query */ +#define FTS5INDEX_QUERY_DESC 0x0002 /* Docs in descending rowid order */ +#define FTS5INDEX_QUERY_TEST_NOIDX 0x0004 /* Do not use prefix index */ +#define FTS5INDEX_QUERY_SCAN 0x0008 /* Scan query (fts5vocab) */ /* The following are used internally by the fts5_index.c module. They are ** defined here only to make it easier to avoid clashes with the flags ** above. */ -#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 -#define FTS5INDEX_QUERY_NOOUTPUT 0x0020 -#define FTS5INDEX_QUERY_SKIPHASH 0x0040 +#define FTS5INDEX_QUERY_SKIPEMPTY 0x0010 +#define FTS5INDEX_QUERY_NOOUTPUT 0x0020 +#define FTS5INDEX_QUERY_SKIPHASH 0x0040 +#define FTS5INDEX_QUERY_NOTOKENDATA 0x0080 +#define FTS5INDEX_QUERY_SCANONETERM 0x0100 /* ** Create/destroy an Fts5Index object. @@ -228555,6 +230556,10 @@ static void *sqlite3Fts5StructureRef(Fts5Index*); static void sqlite3Fts5StructureRelease(void*); static int sqlite3Fts5StructureTest(Fts5Index*, void*); +/* +** Used by xInstToken(): +*/ +static int sqlite3Fts5IterToken(Fts5IndexIter*, i64, int, int, const char**, int*); /* ** Insert or remove data to or from the index. Each time a document is @@ -228632,6 +230637,13 @@ static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); static int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin); static int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid); +static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter*); + +/* Used to populate hash tables for xInstToken in detail=none/column mode. */ +static int sqlite3Fts5IndexIterWriteTokendata( + Fts5IndexIter*, const char*, int, i64 iRowid, int iCol, int iOff +); + /* ** End of interface to code in fts5_index.c. **************************************************************************/ @@ -228737,6 +230749,7 @@ static void sqlite3Fts5HashScanNext(Fts5Hash*); static int sqlite3Fts5HashScanEof(Fts5Hash*); static void sqlite3Fts5HashScanEntry(Fts5Hash *, const char **pzTerm, /* OUT: term (nul-terminated) */ + int *pnTerm, /* OUT: Size of term in bytes */ const u8 **ppDoclist, /* OUT: pointer to doclist */ int *pnDoclist /* OUT: size of doclist in bytes */ ); @@ -228863,6 +230876,10 @@ static int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**); static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *); +static int sqlite3Fts5ExprQueryToken(Fts5Expr*, int, int, const char**, int*); +static int sqlite3Fts5ExprInstToken(Fts5Expr*, i64, int, int, int, int, const char**, int*); +static void sqlite3Fts5ExprClearTokens(Fts5Expr*); + /******************************************* ** The fts5_expr.c API above this point is used by the other hand-written ** C code in this module. The interfaces below this point are called by @@ -230678,6 +232695,14 @@ static int fts5HighlightCb( } if( iPos==p->iRangeEnd ){ + if( p->bOpen ){ + if( p->iter.iStart>=0 && iPos>=p->iter.iStart ){ + fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); + p->iOff = iEndOff; + } + fts5HighlightAppend(&rc, p, p->zClose, -1); + p->bOpen = 0; + } fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); p->iOff = iEndOff; } @@ -230711,8 +232736,10 @@ static void fts5HighlightFunction( ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); ctx.iRangeEnd = -1; rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); - - if( ctx.zIn ){ + if( rc==SQLITE_RANGE ){ + sqlite3_result_text(pCtx, "", -1, SQLITE_STATIC); + rc = SQLITE_OK; + }else if( ctx.zIn ){ if( rc==SQLITE_OK ){ rc = fts5CInstIterInit(pApi, pFts, iCol, &ctx.iter); } @@ -231279,6 +233306,7 @@ static void sqlite3Fts5BufferAppendBlob( ){ if( nData ){ if( fts5BufferGrow(pRc, pBuf, nData) ) return; + assert( pBuf->p!=0 ); memcpy(&pBuf->p[pBuf->n], pData, nData); pBuf->n += nData; } @@ -231380,6 +233408,7 @@ static int sqlite3Fts5PoslistNext64( i64 *piOff /* IN/OUT: Current offset */ ){ int i = *pi; + assert( a!=0 || i==0 ); if( i>=n ){ /* EOF */ *piOff = -1; @@ -231387,6 +233416,7 @@ static int sqlite3Fts5PoslistNext64( }else{ i64 iOff = *piOff; u32 iVal; + assert( a!=0 ); fts5FastGetVarint32(a, i, iVal); if( iVal<=1 ){ if( iVal==0 ){ @@ -232018,6 +234048,16 @@ static int fts5ConfigParseSpecial( return rc; } + if( sqlite3_strnicmp("tokendata", zCmd, nCmd)==0 ){ + if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ + *pzErr = sqlite3_mprintf("malformed tokendata=... directive"); + rc = SQLITE_ERROR; + }else{ + pConfig->bTokendata = (zArg[0]=='1'); + } + return rc; + } + *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd); return SQLITE_ERROR; } @@ -232751,7 +234791,9 @@ struct Fts5ExprNode { struct Fts5ExprTerm { u8 bPrefix; /* True for a prefix term */ u8 bFirst; /* True if token must be first in column */ - char *zTerm; /* nul-terminated term */ + char *pTerm; /* Term data */ + int nQueryTerm; /* Effective size of term in bytes */ + int nFullTerm; /* Size of term in bytes incl. tokendata */ Fts5IndexIter *pIter; /* Iterator for this term */ Fts5ExprTerm *pSynonym; /* Pointer to first in list of synonyms */ }; @@ -233618,7 +235660,7 @@ static int fts5ExprNearInitAll( p->pIter = 0; } rc = sqlite3Fts5IndexQuery( - pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm), + pExpr->pIndex, p->pTerm, p->nQueryTerm, (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) | (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0), pNear->pColset, @@ -234255,7 +236297,7 @@ static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){ Fts5ExprTerm *pSyn; Fts5ExprTerm *pNext; Fts5ExprTerm *pTerm = &pPhrase->aTerm[i]; - sqlite3_free(pTerm->zTerm); + sqlite3_free(pTerm->pTerm); sqlite3Fts5IterClose(pTerm->pIter); for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){ pNext = pSyn->pSynonym; @@ -234353,6 +236395,7 @@ static Fts5ExprNearset *sqlite3Fts5ParseNearset( typedef struct TokenCtx TokenCtx; struct TokenCtx { Fts5ExprPhrase *pPhrase; + Fts5Config *pConfig; int rc; }; @@ -234386,8 +236429,12 @@ static int fts5ParseTokenize( rc = SQLITE_NOMEM; }else{ memset(pSyn, 0, (size_t)nByte); - pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); - memcpy(pSyn->zTerm, pToken, nToken); + pSyn->pTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer); + pSyn->nFullTerm = pSyn->nQueryTerm = nToken; + if( pCtx->pConfig->bTokendata ){ + pSyn->nQueryTerm = (int)strlen(pSyn->pTerm); + } + memcpy(pSyn->pTerm, pToken, nToken); pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym; pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn; } @@ -234412,7 +236459,11 @@ static int fts5ParseTokenize( if( rc==SQLITE_OK ){ pTerm = &pPhrase->aTerm[pPhrase->nTerm++]; memset(pTerm, 0, sizeof(Fts5ExprTerm)); - pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken); + pTerm->pTerm = sqlite3Fts5Strndup(&rc, pToken, nToken); + pTerm->nFullTerm = pTerm->nQueryTerm = nToken; + if( pCtx->pConfig->bTokendata && rc==SQLITE_OK ){ + pTerm->nQueryTerm = (int)strlen(pTerm->pTerm); + } } } @@ -234479,6 +236530,7 @@ static Fts5ExprPhrase *sqlite3Fts5ParseTerm( memset(&sCtx, 0, sizeof(TokenCtx)); sCtx.pPhrase = pAppend; + sCtx.pConfig = pConfig; rc = fts5ParseStringFromToken(pToken, &z); if( rc==SQLITE_OK ){ @@ -234526,12 +236578,15 @@ static int sqlite3Fts5ExprClonePhrase( Fts5Expr **ppNew ){ int rc = SQLITE_OK; /* Return code */ - Fts5ExprPhrase *pOrig; /* The phrase extracted from pExpr */ + Fts5ExprPhrase *pOrig = 0; /* The phrase extracted from pExpr */ Fts5Expr *pNew = 0; /* Expression to return via *ppNew */ - TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */ - - pOrig = pExpr->apExprPhrase[iPhrase]; - pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); + TokenCtx sCtx = {0,0,0}; /* Context object for fts5ParseTokenize */ + if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ + rc = SQLITE_RANGE; + }else{ + pOrig = pExpr->apExprPhrase[iPhrase]; + pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); + } if( rc==SQLITE_OK ){ pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase*)); @@ -234544,7 +236599,7 @@ static int sqlite3Fts5ExprClonePhrase( pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*)); } - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){ Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; if( pColsetOrig ){ sqlite3_int64 nByte; @@ -234558,26 +236613,27 @@ static int sqlite3Fts5ExprClonePhrase( } } - if( pOrig->nTerm ){ - int i; /* Used to iterate through phrase terms */ - for(i=0; rc==SQLITE_OK && inTerm; i++){ - int tflags = 0; - Fts5ExprTerm *p; - for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ - const char *zTerm = p->zTerm; - rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm), - 0, 0); - tflags = FTS5_TOKEN_COLOCATED; - } - if( rc==SQLITE_OK ){ - sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; - sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; + if( rc==SQLITE_OK ){ + if( pOrig->nTerm ){ + int i; /* Used to iterate through phrase terms */ + sCtx.pConfig = pExpr->pConfig; + for(i=0; rc==SQLITE_OK && inTerm; i++){ + int tflags = 0; + Fts5ExprTerm *p; + for(p=&pOrig->aTerm[i]; p && rc==SQLITE_OK; p=p->pSynonym){ + rc = fts5ParseTokenize((void*)&sCtx,tflags,p->pTerm,p->nFullTerm,0,0); + tflags = FTS5_TOKEN_COLOCATED; + } + if( rc==SQLITE_OK ){ + sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix; + sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst; + } } + }else{ + /* This happens when parsing a token or quoted phrase that contains + ** no token characters at all. (e.g ... MATCH '""'). */ + sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); } - }else{ - /* This happens when parsing a token or quoted phrase that contains - ** no token characters at all. (e.g ... MATCH '""'). */ - sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); } if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){ @@ -234947,11 +237003,13 @@ static Fts5ExprNode *fts5ParsePhraseToAnd( if( parseGrowPhraseArray(pParse) ){ fts5ExprPhraseFree(pPhrase); }else{ + Fts5ExprTerm *p = &pNear->apPhrase[0]->aTerm[ii]; + Fts5ExprTerm *pTo = &pPhrase->aTerm[0]; pParse->apPhrase[pParse->nPhrase++] = pPhrase; pPhrase->nTerm = 1; - pPhrase->aTerm[0].zTerm = sqlite3Fts5Strndup( - &pParse->rc, pNear->apPhrase[0]->aTerm[ii].zTerm, -1 - ); + pTo->pTerm = sqlite3Fts5Strndup(&pParse->rc, p->pTerm, p->nFullTerm); + pTo->nQueryTerm = p->nQueryTerm; + pTo->nFullTerm = p->nFullTerm; pRet->apChild[ii] = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, sqlite3Fts5ParseNearset(pParse, 0, pPhrase) ); @@ -235136,16 +237194,17 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ /* Determine the maximum amount of space required. */ for(p=pTerm; p; p=p->pSynonym){ - nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2; + nByte += pTerm->nQueryTerm * 2 + 3 + 2; } zQuoted = sqlite3_malloc64(nByte); if( zQuoted ){ int i = 0; for(p=pTerm; p; p=p->pSynonym){ - char *zIn = p->zTerm; + char *zIn = p->pTerm; + char *zEnd = &zIn[p->nQueryTerm]; zQuoted[i++] = '"'; - while( *zIn ){ + while( zInnTerm; iTerm++){ - char *zTerm = pPhrase->aTerm[iTerm].zTerm; - zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" ", zTerm); + Fts5ExprTerm *p = &pPhrase->aTerm[iTerm]; + zRet = fts5PrintfAppend(zRet, "%s%.*s", iTerm==0?"":" ", + p->nQueryTerm, p->pTerm + ); if( pPhrase->aTerm[iTerm].bPrefix ){ zRet = fts5PrintfAppend(zRet, "*"); } @@ -235625,6 +237686,17 @@ static int fts5ExprColsetTest(Fts5Colset *pColset, int iCol){ return 0; } +/* +** pToken is a buffer nToken bytes in size that may or may not contain +** an embedded 0x00 byte. If it does, return the number of bytes in +** the buffer before the 0x00. If it does not, return nToken. +*/ +static int fts5QueryTerm(const char *pToken, int nToken){ + int ii; + for(ii=0; iipExpr; int i; + int nQuery = nToken; + i64 iRowid = pExpr->pRoot->iRowid; UNUSED_PARAM2(iUnused1, iUnused2); - if( nToken>FTS5_MAX_TOKEN_SIZE ) nToken = FTS5_MAX_TOKEN_SIZE; + if( nQuery>FTS5_MAX_TOKEN_SIZE ) nQuery = FTS5_MAX_TOKEN_SIZE; + if( pExpr->pConfig->bTokendata ){ + nQuery = fts5QueryTerm(pToken, nQuery); + } if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++; for(i=0; inPhrase; i++){ - Fts5ExprTerm *pTerm; + Fts5ExprTerm *pT; if( p->aPopulator[i].bOk==0 ) continue; - for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ - int nTerm = (int)strlen(pTerm->zTerm); - if( (nTerm==nToken || (nTermbPrefix)) - && memcmp(pTerm->zTerm, pToken, nTerm)==0 + for(pT=&pExpr->apExprPhrase[i]->aTerm[0]; pT; pT=pT->pSynonym){ + if( (pT->nQueryTerm==nQuery || (pT->nQueryTermbPrefix)) + && memcmp(pT->pTerm, pToken, pT->nQueryTerm)==0 ){ int rc = sqlite3Fts5PoslistWriterAppend( &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff ); + if( rc==SQLITE_OK && pExpr->pConfig->bTokendata && !pT->bPrefix ){ + int iCol = p->iOff>>32; + int iTokOff = p->iOff & 0x7FFFFFFF; + rc = sqlite3Fts5IndexIterWriteTokendata( + pT->pIter, pToken, nToken, iRowid, iCol, iTokOff + ); + } if( rc ) return rc; break; } @@ -235787,6 +237870,83 @@ static int sqlite3Fts5ExprPhraseCollist( return rc; } +/* +** Does the work of the fts5_api.xQueryToken() API method. +*/ +static int sqlite3Fts5ExprQueryToken( + Fts5Expr *pExpr, + int iPhrase, + int iToken, + const char **ppOut, + int *pnOut +){ + Fts5ExprPhrase *pPhrase = 0; + + if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ + return SQLITE_RANGE; + } + pPhrase = pExpr->apExprPhrase[iPhrase]; + if( iToken<0 || iToken>=pPhrase->nTerm ){ + return SQLITE_RANGE; + } + + *ppOut = pPhrase->aTerm[iToken].pTerm; + *pnOut = pPhrase->aTerm[iToken].nFullTerm; + return SQLITE_OK; +} + +/* +** Does the work of the fts5_api.xInstToken() API method. +*/ +static int sqlite3Fts5ExprInstToken( + Fts5Expr *pExpr, + i64 iRowid, + int iPhrase, + int iCol, + int iOff, + int iToken, + const char **ppOut, + int *pnOut +){ + Fts5ExprPhrase *pPhrase = 0; + Fts5ExprTerm *pTerm = 0; + int rc = SQLITE_OK; + + if( iPhrase<0 || iPhrase>=pExpr->nPhrase ){ + return SQLITE_RANGE; + } + pPhrase = pExpr->apExprPhrase[iPhrase]; + if( iToken<0 || iToken>=pPhrase->nTerm ){ + return SQLITE_RANGE; + } + pTerm = &pPhrase->aTerm[iToken]; + if( pTerm->bPrefix==0 ){ + if( pExpr->pConfig->bTokendata ){ + rc = sqlite3Fts5IterToken( + pTerm->pIter, iRowid, iCol, iOff+iToken, ppOut, pnOut + ); + }else{ + *ppOut = pTerm->pTerm; + *pnOut = pTerm->nFullTerm; + } + } + return rc; +} + +/* +** Clear the token mappings for all Fts5IndexIter objects mannaged by +** the expression passed as the only argument. +*/ +static void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){ + int ii; + for(ii=0; iinPhrase; ii++){ + Fts5ExprTerm *pT; + for(pT=&pExpr->apExprPhrase[ii]->aTerm[0]; pT; pT=pT->pSynonym){ + sqlite3Fts5IndexIterClearTokendata(pT->pIter); + } + } +} + /* ** 2014 August 11 ** @@ -235825,10 +237985,15 @@ struct Fts5Hash { /* ** Each entry in the hash table is represented by an object of the -** following type. Each object, its key (a nul-terminated string) and -** its current data are stored in a single memory allocation. The -** key immediately follows the object in memory. The position list -** data immediately follows the key data in memory. +** following type. Each object, its key, and its current data are stored +** in a single memory allocation. The key immediately follows the object +** in memory. The position list data immediately follows the key data +** in memory. +** +** The key is Fts5HashEntry.nKey bytes in size. It consists of a single +** byte identifying the index (either the main term index or a prefix-index), +** followed by the term data. For example: "0token". There is no +** nul-terminator - in this case nKey=6. ** ** The data that follows the key is in a similar, but not identical format ** to the doclist data stored in the database. It is: @@ -235963,8 +238128,7 @@ static int fts5HashResize(Fts5Hash *pHash){ unsigned int iHash; Fts5HashEntry *p = apOld[i]; apOld[i] = p->pHashNext; - iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), - (int)strlen(fts5EntryKey(p))); + iHash = fts5HashKey(nNew, (u8*)fts5EntryKey(p), p->nKey); p->pHashNext = apNew[iHash]; apNew[iHash] = p; } @@ -236048,7 +238212,7 @@ static int sqlite3Fts5HashWrite( for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ char *zKey = fts5EntryKey(p); if( zKey[0]==bByte - && p->nKey==nToken + && p->nKey==nToken+1 && memcmp(&zKey[1], pToken, nToken)==0 ){ break; @@ -236078,9 +238242,9 @@ static int sqlite3Fts5HashWrite( zKey[0] = bByte; memcpy(&zKey[1], pToken, nToken); assert( iHash==fts5HashKey(pHash->nSlot, (u8*)zKey, nToken+1) ); - p->nKey = nToken; + p->nKey = nToken+1; zKey[nToken+1] = '\0'; - p->nData = nToken+1 + 1 + sizeof(Fts5HashEntry); + p->nData = nToken+1 + sizeof(Fts5HashEntry); p->pHashNext = pHash->aSlot[iHash]; pHash->aSlot[iHash] = p; pHash->nEntry++; @@ -236197,12 +238361,17 @@ static Fts5HashEntry *fts5HashEntryMerge( *ppOut = p1; p1 = 0; }else{ - int i = 0; char *zKey1 = fts5EntryKey(p1); char *zKey2 = fts5EntryKey(p2); - while( zKey1[i]==zKey2[i] ) i++; + int nMin = MIN(p1->nKey, p2->nKey); - if( ((u8)zKey1[i])>((u8)zKey2[i]) ){ + int cmp = memcmp(zKey1, zKey2, nMin); + if( cmp==0 ){ + cmp = p1->nKey - p2->nKey; + } + assert( cmp!=0 ); + + if( cmp>0 ){ /* p2 is smaller */ *ppOut = p2; ppOut = &p2->pScanNext; @@ -236244,7 +238413,7 @@ static int fts5HashEntrySort( Fts5HashEntry *pIter; for(pIter=pHash->aSlot[iSlot]; pIter; pIter=pIter->pHashNext){ if( pTerm==0 - || (pIter->nKey+1>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm)) + || (pIter->nKey>=nTerm && 0==memcmp(fts5EntryKey(pIter), pTerm, nTerm)) ){ Fts5HashEntry *pEntry = pIter; pEntry->pScanNext = 0; @@ -236283,12 +238452,11 @@ static int sqlite3Fts5HashQuery( for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){ zKey = fts5EntryKey(p); - assert( p->nKey+1==(int)strlen(zKey) ); - if( nTerm==p->nKey+1 && memcmp(zKey, pTerm, nTerm)==0 ) break; + if( nTerm==p->nKey && memcmp(zKey, pTerm, nTerm)==0 ) break; } if( p ){ - int nHashPre = sizeof(Fts5HashEntry) + nTerm + 1; + int nHashPre = sizeof(Fts5HashEntry) + nTerm; int nList = p->nData - nHashPre; u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10)); if( pRet ){ @@ -236349,19 +238517,22 @@ static int sqlite3Fts5HashScanEof(Fts5Hash *p){ static void sqlite3Fts5HashScanEntry( Fts5Hash *pHash, const char **pzTerm, /* OUT: term (nul-terminated) */ + int *pnTerm, /* OUT: Size of term in bytes */ const u8 **ppDoclist, /* OUT: pointer to doclist */ int *pnDoclist /* OUT: size of doclist in bytes */ ){ Fts5HashEntry *p; if( (p = pHash->pScan) ){ char *zKey = fts5EntryKey(p); - int nTerm = (int)strlen(zKey); + int nTerm = p->nKey; fts5HashAddPoslistSize(pHash, p, 0); *pzTerm = zKey; - *ppDoclist = (const u8*)&zKey[nTerm+1]; - *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm + 1); + *pnTerm = nTerm; + *ppDoclist = (const u8*)&zKey[nTerm]; + *pnDoclist = p->nData - (sizeof(Fts5HashEntry) + nTerm); }else{ *pzTerm = 0; + *pnTerm = 0; *ppDoclist = 0; *pnDoclist = 0; } @@ -236692,6 +238863,9 @@ typedef struct Fts5SegWriter Fts5SegWriter; typedef struct Fts5Structure Fts5Structure; typedef struct Fts5StructureLevel Fts5StructureLevel; typedef struct Fts5StructureSegment Fts5StructureSegment; +typedef struct Fts5TokenDataIter Fts5TokenDataIter; +typedef struct Fts5TokenDataMap Fts5TokenDataMap; +typedef struct Fts5TombstoneArray Fts5TombstoneArray; struct Fts5Data { u8 *p; /* Pointer to buffer containing record */ @@ -236726,6 +238900,7 @@ struct Fts5Index { /* Error state. */ int rc; /* Current error code */ + int flushRc; /* State used by the fts5DataXXX() functions. */ sqlite3_blob *pReader; /* RO incr-blob open on %_data table */ @@ -236734,6 +238909,7 @@ struct Fts5Index { sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */ sqlite3_stmt *pIdxSelect; + sqlite3_stmt *pIdxNextSelect; int nRead; /* Total number of blocks read */ sqlite3_stmt *pDeleteFromIdx; @@ -236887,8 +239063,7 @@ struct Fts5SegIter { Fts5Data *pLeaf; /* Current leaf data */ Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */ i64 iLeafOffset; /* Byte offset within current leaf */ - Fts5Data **apTombstone; /* Array of tombstone pages */ - int nTombstone; + Fts5TombstoneArray *pTombArray; /* Array of tombstone pages */ /* Next method */ void (*xNext)(Fts5Index*, Fts5SegIter*, int*); @@ -236915,6 +239090,15 @@ struct Fts5SegIter { u8 bDel; /* True if the delete flag is set */ }; +/* +** Array of tombstone pages. Reference counted. +*/ +struct Fts5TombstoneArray { + int nRef; /* Number of pointers to this object */ + int nTombstone; + Fts5Data *apTombstone[1]; /* Array of tombstone pages */ +}; + /* ** Argument is a pointer to an Fts5Data structure that contains a ** leaf page. @@ -236959,9 +239143,16 @@ struct Fts5SegIter { ** poslist: ** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered. ** There is no way to tell if this is populated or not. +** +** pColset: +** If not NULL, points to an object containing a set of column indices. +** Only matches that occur in one of these columns will be returned. +** The Fts5Iter does not own the Fts5Colset object, and so it is not +** freed when the iterator is closed - it is owned by the upper layer. */ struct Fts5Iter { Fts5IndexIter base; /* Base class containing output vars */ + Fts5TokenDataIter *pTokenDataIter; Fts5Index *pIndex; /* Index that owns this iterator */ Fts5Buffer poslist; /* Buffer containing current poslist */ @@ -236979,7 +239170,6 @@ struct Fts5Iter { Fts5SegIter aSeg[1]; /* Array of segment iterators */ }; - /* ** An instance of the following type is used to iterate through the contents ** of a doclist-index record. @@ -237897,9 +240087,9 @@ static int fts5DlidxLvlNext(Fts5DlidxLvl *pLvl){ } if( iOffnn ){ - i64 iVal; + u64 iVal; pLvl->iLeafPgno += (iOff - pLvl->iOff) + 1; - iOff += fts5GetVarint(&pData->p[iOff], (u64*)&iVal); + iOff += fts5GetVarint(&pData->p[iOff], &iVal); pLvl->iRowid += iVal; pLvl->iOff = iOff; }else{ @@ -238278,18 +240468,20 @@ static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){ } /* -** Allocate a tombstone hash page array (pIter->apTombstone) for the -** iterator passed as the second argument. If an OOM error occurs, leave -** an error in the Fts5Index object. +** Allocate a tombstone hash page array object (pIter->pTombArray) for +** the iterator passed as the second argument. If an OOM error occurs, +** leave an error in the Fts5Index object. */ static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ const int nTomb = pIter->pSeg->nPgTombstone; if( nTomb>0 ){ - Fts5Data **apTomb = 0; - apTomb = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data)*nTomb); - if( apTomb ){ - pIter->apTombstone = apTomb; - pIter->nTombstone = nTomb; + int nByte = nTomb * sizeof(Fts5Data*) + sizeof(Fts5TombstoneArray); + Fts5TombstoneArray *pNew; + pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte); + if( pNew ){ + pNew->nTombstone = nTomb; + pNew->nRef = 1; + pIter->pTombArray = pNew; } } } @@ -238546,15 +240738,16 @@ static void fts5SegIterNext_None( }else{ const u8 *pList = 0; const char *zTerm = 0; + int nTerm = 0; int nList; sqlite3Fts5HashScanNext(p->pHash); - sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); + sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList); if( pList==0 ) goto next_none_eof; pIter->pLeaf->p = (u8*)pList; pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList; - sqlite3Fts5BufferSet(&p->rc,&pIter->term, (int)strlen(zTerm), (u8*)zTerm); + sqlite3Fts5BufferSet(&p->rc,&pIter->term, nTerm, (u8*)zTerm); pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); } @@ -238620,11 +240813,12 @@ static void fts5SegIterNext( }else if( pIter->pSeg==0 ){ const u8 *pList = 0; const char *zTerm = 0; + int nTerm = 0; int nList = 0; assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm ); if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){ sqlite3Fts5HashScanNext(p->pHash); - sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); + sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &nTerm, &pList, &nList); } if( pList==0 ){ fts5DataRelease(pIter->pLeaf); @@ -238634,8 +240828,7 @@ static void fts5SegIterNext( pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList+1; - sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm), - (u8*)zTerm); + sqlite3Fts5BufferSet(&p->rc, &pIter->term, nTerm, (u8*)zTerm); pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); *pbNewTerm = 1; } @@ -239021,7 +241214,7 @@ static void fts5SegIterSeekInit( fts5LeafSeek(p, bGe, pIter, pTerm, nTerm); } - if( p->rc==SQLITE_OK && bGe==0 ){ + if( p->rc==SQLITE_OK && (bGe==0 || (flags & FTS5INDEX_QUERY_SCANONETERM)) ){ pIter->flags |= FTS5_SEGITER_ONETERM; if( pIter->pLeaf ){ if( flags & FTS5INDEX_QUERY_DESC ){ @@ -239037,7 +241230,9 @@ static void fts5SegIterSeekInit( } fts5SegIterSetNext(p, pIter); - fts5SegIterAllocTombstone(p, pIter); + if( 0==(flags & FTS5INDEX_QUERY_SCANONETERM) ){ + fts5SegIterAllocTombstone(p, pIter); + } /* Either: ** @@ -239054,6 +241249,79 @@ static void fts5SegIterSeekInit( ); } + +/* +** SQL used by fts5SegIterNextInit() to find the page to open. +*/ +static sqlite3_stmt *fts5IdxNextStmt(Fts5Index *p){ + if( p->pIdxNextSelect==0 ){ + Fts5Config *pConfig = p->pConfig; + fts5IndexPrepareStmt(p, &p->pIdxNextSelect, sqlite3_mprintf( + "SELECT pgno FROM '%q'.'%q_idx' WHERE " + "segid=? AND term>? ORDER BY term ASC LIMIT 1", + pConfig->zDb, pConfig->zName + )); + + } + return p->pIdxNextSelect; +} + +/* +** This is similar to fts5SegIterSeekInit(), except that it initializes +** the segment iterator to point to the first term following the page +** with pToken/nToken on it. +*/ +static void fts5SegIterNextInit( + Fts5Index *p, + const char *pTerm, int nTerm, + Fts5StructureSegment *pSeg, /* Description of segment */ + Fts5SegIter *pIter /* Object to populate */ +){ + int iPg = -1; /* Page of segment to open */ + int bDlidx = 0; + sqlite3_stmt *pSel = 0; /* SELECT to find iPg */ + + pSel = fts5IdxNextStmt(p); + if( pSel ){ + assert( p->rc==SQLITE_OK ); + sqlite3_bind_int(pSel, 1, pSeg->iSegid); + sqlite3_bind_blob(pSel, 2, pTerm, nTerm, SQLITE_STATIC); + + if( sqlite3_step(pSel)==SQLITE_ROW ){ + i64 val = sqlite3_column_int64(pSel, 0); + iPg = (int)(val>>1); + bDlidx = (val & 0x0001); + } + p->rc = sqlite3_reset(pSel); + sqlite3_bind_null(pSel, 2); + if( p->rc ) return; + } + + memset(pIter, 0, sizeof(*pIter)); + pIter->pSeg = pSeg; + pIter->flags |= FTS5_SEGITER_ONETERM; + if( iPg>=0 ){ + pIter->iLeafPgno = iPg - 1; + fts5SegIterNextPage(p, pIter); + fts5SegIterSetNext(p, pIter); + } + if( pIter->pLeaf ){ + const u8 *a = pIter->pLeaf->p; + int iTermOff = 0; + + pIter->iPgidxOff = pIter->pLeaf->szLeaf; + pIter->iPgidxOff += fts5GetVarint32(&a[pIter->iPgidxOff], iTermOff); + pIter->iLeafOffset = iTermOff; + fts5SegIterLoadTerm(p, pIter, 0); + fts5SegIterLoadNPos(p, pIter); + if( bDlidx ) fts5SegIterLoadDlidx(p, pIter); + + assert( p->rc!=SQLITE_OK || + fts5BufferCompareBlob(&pIter->term, (const u8*)pTerm, nTerm)>0 + ); + } +} + /* ** Initialize the object pIter to point to term pTerm/nTerm within the ** in-memory hash table. If there is no such term in the hash-table, the @@ -239080,8 +241348,7 @@ static void fts5SegIterHashInit( const u8 *pList = 0; p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm); - sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList); - n = (z ? (int)strlen((const char*)z) : 0); + sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &n, &pList, &nList); if( pList ){ pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data)); if( pLeaf ){ @@ -239140,6 +241407,23 @@ static void fts5IndexFreeArray(Fts5Data **ap, int n){ } } +/* +** Decrement the ref-count of the object passed as the only argument. If it +** reaches 0, free it and its contents. +*/ +static void fts5TombstoneArrayDelete(Fts5TombstoneArray *p){ + if( p ){ + p->nRef--; + if( p->nRef<=0 ){ + int ii; + for(ii=0; iinTombstone; ii++){ + fts5DataRelease(p->apTombstone[ii]); + } + sqlite3_free(p); + } + } +} + /* ** Zero the iterator passed as the only argument. */ @@ -239147,7 +241431,7 @@ static void fts5SegIterClear(Fts5SegIter *pIter){ fts5BufferFree(&pIter->term); fts5DataRelease(pIter->pLeaf); fts5DataRelease(pIter->pNextLeaf); - fts5IndexFreeArray(pIter->apTombstone, pIter->nTombstone); + fts5TombstoneArrayDelete(pIter->pTombArray); fts5DlidxIterFree(pIter->pDlidx); sqlite3_free(pIter->aRowidOffset); memset(pIter, 0, sizeof(Fts5SegIter)); @@ -239392,7 +241676,6 @@ static void fts5SegIterNextFrom( }while( p->rc==SQLITE_OK ); } - /* ** Free the iterator object passed as the second argument. */ @@ -239537,24 +241820,25 @@ static int fts5IndexTombstoneQuery( static int fts5MultiIterIsDeleted(Fts5Iter *pIter){ int iFirst = pIter->aFirst[1].iFirst; Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; + Fts5TombstoneArray *pArray = pSeg->pTombArray; - if( pSeg->pLeaf && pSeg->nTombstone ){ + if( pSeg->pLeaf && pArray ){ /* Figure out which page the rowid might be present on. */ - int iPg = ((u64)pSeg->iRowid) % pSeg->nTombstone; + int iPg = ((u64)pSeg->iRowid) % pArray->nTombstone; assert( iPg>=0 ); /* If tombstone hash page iPg has not yet been loaded from the ** database, load it now. */ - if( pSeg->apTombstone[iPg]==0 ){ - pSeg->apTombstone[iPg] = fts5DataRead(pIter->pIndex, + if( pArray->apTombstone[iPg]==0 ){ + pArray->apTombstone[iPg] = fts5DataRead(pIter->pIndex, FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg) ); - if( pSeg->apTombstone[iPg]==0 ) return 0; + if( pArray->apTombstone[iPg]==0 ) return 0; } return fts5IndexTombstoneQuery( - pSeg->apTombstone[iPg], - pSeg->nTombstone, + pArray->apTombstone[iPg], + pArray->nTombstone, pSeg->iRowid ); } @@ -240093,6 +242377,32 @@ static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ } } +/* +** All the component segment-iterators of pIter have been set up. This +** functions finishes setup for iterator pIter itself. +*/ +static void fts5MultiIterFinishSetup(Fts5Index *p, Fts5Iter *pIter){ + int iIter; + for(iIter=pIter->nSeg-1; iIter>0; iIter--){ + int iEq; + if( (iEq = fts5MultiIterDoCompare(pIter, iIter)) ){ + Fts5SegIter *pSeg = &pIter->aSeg[iEq]; + if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0); + fts5MultiIterAdvanced(p, pIter, iEq, iIter); + } + } + fts5MultiIterSetEof(pIter); + fts5AssertMultiIterSetup(p, pIter); + + if( (pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter)) + || fts5MultiIterIsDeleted(pIter) + ){ + fts5MultiIterNext(p, pIter, 0, 0); + }else if( pIter->base.bEof==0 ){ + Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst]; + pIter->xSetOutputs(pIter, pSeg); + } +} /* ** Allocate a new Fts5Iter object. @@ -240174,31 +242484,12 @@ static void fts5MultiIterNew( assert( iIter==nSeg ); } - /* If the above was successful, each component iterators now points + /* If the above was successful, each component iterator now points ** to the first entry in its segment. In this case initialize the ** aFirst[] array. Or, if an error has occurred, free the iterator ** object and set the output variable to NULL. */ if( p->rc==SQLITE_OK ){ - for(iIter=pNew->nSeg-1; iIter>0; iIter--){ - int iEq; - if( (iEq = fts5MultiIterDoCompare(pNew, iIter)) ){ - Fts5SegIter *pSeg = &pNew->aSeg[iEq]; - if( p->rc==SQLITE_OK ) pSeg->xNext(p, pSeg, 0); - fts5MultiIterAdvanced(p, pNew, iEq, iIter); - } - } - fts5MultiIterSetEof(pNew); - fts5AssertMultiIterSetup(p, pNew); - - if( (pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew)) - || fts5MultiIterIsDeleted(pNew) - ){ - fts5MultiIterNext(p, pNew, 0, 0); - }else if( pNew->base.bEof==0 ){ - Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst]; - pNew->xSetOutputs(pNew, pSeg); - } - + fts5MultiIterFinishSetup(p, pNew); }else{ fts5MultiIterFree(pNew); *ppOut = 0; @@ -240223,7 +242514,6 @@ static void fts5MultiIterNew2( pNew = fts5MultiIterAlloc(p, 2); if( pNew ){ Fts5SegIter *pIter = &pNew->aSeg[1]; - pIter->flags = FTS5_SEGITER_ONETERM; if( pData->szLeaf>0 ){ pIter->pLeaf = pData; @@ -240371,6 +242661,7 @@ static void fts5IndexDiscardData(Fts5Index *p){ sqlite3Fts5HashClear(p->pHash); p->nPendingData = 0; p->nPendingRow = 0; + p->flushRc = SQLITE_OK; } p->nContentlessDelete = 0; } @@ -240586,7 +242877,7 @@ static void fts5WriteDlidxAppend( } if( pDlidx->bPrevValid ){ - iVal = iRowid - pDlidx->iPrev; + iVal = (u64)iRowid - (u64)pDlidx->iPrev; }else{ i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno); assert( pDlidx->buf.n==0 ); @@ -241506,18 +243797,24 @@ static void fts5DoSecureDelete( iOff = iStart; - /* Set variable bLastInDoclist to true if this entry happens to be - ** the last rowid in the doclist for its term. */ + /* If the position-list for the entry being removed flows over past + ** the end of this page, delete the portion of the position-list on the + ** next page and beyond. + ** + ** Set variable bLastInDoclist to true if this entry happens + ** to be the last rowid in the doclist for its term. */ + if( iNextOff>=iPgIdx ){ + int pgno = pSeg->iLeafPgno+1; + fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); + iNextOff = iPgIdx; + } + if( pSeg->bDel==0 ){ - if( iNextOff>=iPgIdx ){ - int pgno = pSeg->iLeafPgno+1; - fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); - iNextOff = iPgIdx; - }else{ + if( iNextOff!=iPgIdx ){ /* Loop through the page-footer. If iNextOff (offset of the ** entry following the one we are removing) is equal to the ** offset of a key on this page, then the entry is the last - ** in its doclist. */ + ** in its doclist. */ int iKeyOff = 0; for(iIdx=0; iIdxrc!=SQLITE_OK ) break; @@ -241811,7 +244107,7 @@ static void fts5FlushOneHash(Fts5Index *p){ if( bSecureDelete ){ if( eDetail==FTS5_DETAIL_NONE ){ if( iOffrc!=SQLITE_OK || pDoclist[iOff]==0x01 ){ iOff++; continue; @@ -241947,6 +244243,10 @@ static void fts5FlushOneHash(Fts5Index *p){ */ static void fts5IndexFlush(Fts5Index *p){ /* Unless it is empty, flush the hash table to disk */ + if( p->flushRc ){ + p->rc = p->flushRc; + return; + } if( p->nPendingData || p->nContentlessDelete ){ assert( p->pHash ); fts5FlushOneHash(p); @@ -241955,6 +244255,8 @@ static void fts5IndexFlush(Fts5Index *p){ p->nPendingData = 0; p->nPendingRow = 0; p->nContentlessDelete = 0; + }else if( p->nPendingData || p->nContentlessDelete ){ + p->flushRc = p->rc; } } } @@ -242441,7 +244743,7 @@ static void fts5SetupPrefixIter( u8 *pToken, /* Buffer containing prefix to match */ int nToken, /* Size of buffer pToken in bytes */ Fts5Colset *pColset, /* Restrict matches to these columns */ - Fts5Iter **ppIter /* OUT: New iterator */ + Fts5Iter **ppIter /* OUT: New iterator */ ){ Fts5Structure *pStruct; Fts5Buffer *aBuf; @@ -242462,8 +244764,9 @@ static void fts5SetupPrefixIter( aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf); pStruct = fts5StructureRead(p); + assert( p->rc!=SQLITE_OK || (aBuf && pStruct) ); - if( aBuf && pStruct ){ + if( p->rc==SQLITE_OK ){ const int flags = FTS5INDEX_QUERY_SCAN | FTS5INDEX_QUERY_SKIPEMPTY | FTS5INDEX_QUERY_NOOUTPUT; @@ -242475,6 +244778,12 @@ static void fts5SetupPrefixIter( int bNewTerm = 1; memset(&doclist, 0, sizeof(doclist)); + + /* If iIdx is non-zero, then it is the number of a prefix-index for + ** prefixes 1 character longer than the prefix being queried for. That + ** index contains all the doclists required, except for the one + ** corresponding to the prefix itself. That one is extracted from the + ** main term index here. */ if( iIdx!=0 ){ int dummy = 0; const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; @@ -242498,6 +244807,7 @@ static void fts5SetupPrefixIter( pToken[0] = FTS5_MAIN_PREFIX + iIdx; fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); fts5IterSetOutputCb(&p->rc, p1); + for( /* no-op */ ; fts5MultiIterEof(p, p1)==0; fts5MultiIterNext2(p, p1, &bNewTerm) @@ -242513,7 +244823,6 @@ static void fts5SetupPrefixIter( } if( p1->base.nData==0 ) continue; - if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ int i1 = i*nMerge; @@ -242552,7 +244861,7 @@ static void fts5SetupPrefixIter( } fts5MultiIterFree(p1); - pData = fts5IdxMalloc(p, sizeof(Fts5Data)+doclist.n+FTS5_DATA_ZERO_PADDING); + pData = fts5IdxMalloc(p, sizeof(*pData)+doclist.n+FTS5_DATA_ZERO_PADDING); if( pData ){ pData->p = (u8*)&pData[1]; pData->nn = pData->szLeaf = doclist.n; @@ -242695,6 +245004,7 @@ static int sqlite3Fts5IndexClose(Fts5Index *p){ sqlite3_finalize(p->pIdxWriter); sqlite3_finalize(p->pIdxDeleter); sqlite3_finalize(p->pIdxSelect); + sqlite3_finalize(p->pIdxNextSelect); sqlite3_finalize(p->pDataVersion); sqlite3_finalize(p->pDeleteFromIdx); sqlite3Fts5HashFree(p->pHash); @@ -242790,6 +245100,454 @@ static int sqlite3Fts5IndexWrite( return rc; } +/* +** pToken points to a buffer of size nToken bytes containing a search +** term, including the index number at the start, used on a tokendata=1 +** table. This function returns true if the term in buffer pBuf matches +** token pToken/nToken. +*/ +static int fts5IsTokendataPrefix( + Fts5Buffer *pBuf, + const u8 *pToken, + int nToken +){ + return ( + pBuf->n>=nToken + && 0==memcmp(pBuf->p, pToken, nToken) + && (pBuf->n==nToken || pBuf->p[nToken]==0x00) + ); +} + +/* +** Ensure the segment-iterator passed as the only argument points to EOF. +*/ +static void fts5SegIterSetEOF(Fts5SegIter *pSeg){ + fts5DataRelease(pSeg->pLeaf); + pSeg->pLeaf = 0; +} + +/* +** Usually, a tokendata=1 iterator (struct Fts5TokenDataIter) accumulates an +** array of these for each row it visits. Or, for an iterator used by an +** "ORDER BY rank" query, it accumulates an array of these for the entire +** query. +** +** Each instance in the array indicates the iterator (and therefore term) +** associated with position iPos of rowid iRowid. This is used by the +** xInstToken() API. +*/ +struct Fts5TokenDataMap { + i64 iRowid; /* Row this token is located in */ + i64 iPos; /* Position of token */ + int iIter; /* Iterator token was read from */ +}; + +/* +** An object used to supplement Fts5Iter for tokendata=1 iterators. +*/ +struct Fts5TokenDataIter { + int nIter; + int nIterAlloc; + + int nMap; + int nMapAlloc; + Fts5TokenDataMap *aMap; + + Fts5PoslistReader *aPoslistReader; + int *aPoslistToIter; + Fts5Iter *apIter[1]; +}; + +/* +** This function appends iterator pAppend to Fts5TokenDataIter pIn and +** returns the result. +*/ +static Fts5TokenDataIter *fts5AppendTokendataIter( + Fts5Index *p, /* Index object (for error code) */ + Fts5TokenDataIter *pIn, /* Current Fts5TokenDataIter struct */ + Fts5Iter *pAppend /* Append this iterator */ +){ + Fts5TokenDataIter *pRet = pIn; + + if( p->rc==SQLITE_OK ){ + if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){ + int nAlloc = pIn ? pIn->nIterAlloc*2 : 16; + int nByte = nAlloc * sizeof(Fts5Iter*) + sizeof(Fts5TokenDataIter); + Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte); + + if( pNew==0 ){ + p->rc = SQLITE_NOMEM; + }else{ + if( pIn==0 ) memset(pNew, 0, nByte); + pRet = pNew; + pNew->nIterAlloc = nAlloc; + } + } + } + if( p->rc ){ + sqlite3Fts5IterClose((Fts5IndexIter*)pAppend); + }else{ + pRet->apIter[pRet->nIter++] = pAppend; + } + assert( pRet==0 || pRet->nIter<=pRet->nIterAlloc ); + + return pRet; +} + +/* +** Delete an Fts5TokenDataIter structure and its contents. +*/ +static void fts5TokendataIterDelete(Fts5TokenDataIter *pSet){ + if( pSet ){ + int ii; + for(ii=0; iinIter; ii++){ + fts5MultiIterFree(pSet->apIter[ii]); + } + sqlite3_free(pSet->aPoslistReader); + sqlite3_free(pSet->aMap); + sqlite3_free(pSet); + } +} + +/* +** Append a mapping to the token-map belonging to object pT. +*/ +static void fts5TokendataIterAppendMap( + Fts5Index *p, + Fts5TokenDataIter *pT, + int iIter, + i64 iRowid, + i64 iPos +){ + if( p->rc==SQLITE_OK ){ + if( pT->nMap==pT->nMapAlloc ){ + int nNew = pT->nMapAlloc ? pT->nMapAlloc*2 : 64; + int nByte = nNew * sizeof(Fts5TokenDataMap); + Fts5TokenDataMap *aNew; + + aNew = (Fts5TokenDataMap*)sqlite3_realloc(pT->aMap, nByte); + if( aNew==0 ){ + p->rc = SQLITE_NOMEM; + return; + } + + pT->aMap = aNew; + pT->nMapAlloc = nNew; + } + + pT->aMap[pT->nMap].iRowid = iRowid; + pT->aMap[pT->nMap].iPos = iPos; + pT->aMap[pT->nMap].iIter = iIter; + pT->nMap++; + } +} + +/* +** The iterator passed as the only argument must be a tokendata=1 iterator +** (pIter->pTokenDataIter!=0). This function sets the iterator output +** variables (pIter->base.*) according to the contents of the current +** row. +*/ +static void fts5IterSetOutputsTokendata(Fts5Iter *pIter){ + int ii; + int nHit = 0; + i64 iRowid = SMALLEST_INT64; + int iMin = 0; + + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + + pIter->base.nData = 0; + pIter->base.pData = 0; + + for(ii=0; iinIter; ii++){ + Fts5Iter *p = pT->apIter[ii]; + if( p->base.bEof==0 ){ + if( nHit==0 || p->base.iRowidbase.iRowid; + nHit = 1; + pIter->base.pData = p->base.pData; + pIter->base.nData = p->base.nData; + iMin = ii; + }else if( p->base.iRowid==iRowid ){ + nHit++; + } + } + } + + if( nHit==0 ){ + pIter->base.bEof = 1; + }else{ + int eDetail = pIter->pIndex->pConfig->eDetail; + pIter->base.bEof = 0; + pIter->base.iRowid = iRowid; + + if( nHit==1 && eDetail==FTS5_DETAIL_FULL ){ + fts5TokendataIterAppendMap(pIter->pIndex, pT, iMin, iRowid, -1); + }else + if( nHit>1 && eDetail!=FTS5_DETAIL_NONE ){ + int nReader = 0; + int nByte = 0; + i64 iPrev = 0; + + /* Allocate array of iterators if they are not already allocated. */ + if( pT->aPoslistReader==0 ){ + pT->aPoslistReader = (Fts5PoslistReader*)sqlite3Fts5MallocZero( + &pIter->pIndex->rc, + pT->nIter * (sizeof(Fts5PoslistReader) + sizeof(int)) + ); + if( pT->aPoslistReader==0 ) return; + pT->aPoslistToIter = (int*)&pT->aPoslistReader[pT->nIter]; + } + + /* Populate an iterator for each poslist that will be merged */ + for(ii=0; iinIter; ii++){ + Fts5Iter *p = pT->apIter[ii]; + if( iRowid==p->base.iRowid ){ + pT->aPoslistToIter[nReader] = ii; + sqlite3Fts5PoslistReaderInit( + p->base.pData, p->base.nData, &pT->aPoslistReader[nReader++] + ); + nByte += p->base.nData; + } + } + + /* Ensure the output buffer is large enough */ + if( fts5BufferGrow(&pIter->pIndex->rc, &pIter->poslist, nByte+nHit*10) ){ + return; + } + + /* Ensure the token-mapping is large enough */ + if( eDetail==FTS5_DETAIL_FULL && pT->nMapAlloc<(pT->nMap + nByte) ){ + int nNew = (pT->nMapAlloc + nByte) * 2; + Fts5TokenDataMap *aNew = (Fts5TokenDataMap*)sqlite3_realloc( + pT->aMap, nNew*sizeof(Fts5TokenDataMap) + ); + if( aNew==0 ){ + pIter->pIndex->rc = SQLITE_NOMEM; + return; + } + pT->aMap = aNew; + pT->nMapAlloc = nNew; + } + + pIter->poslist.n = 0; + + while( 1 ){ + i64 iMinPos = LARGEST_INT64; + + /* Find smallest position */ + iMin = 0; + for(ii=0; iiaPoslistReader[ii]; + if( pReader->bEof==0 ){ + if( pReader->iPosiPos; + iMin = ii; + } + } + } + + /* If all readers were at EOF, break out of the loop. */ + if( iMinPos==LARGEST_INT64 ) break; + + sqlite3Fts5PoslistSafeAppend(&pIter->poslist, &iPrev, iMinPos); + sqlite3Fts5PoslistReaderNext(&pT->aPoslistReader[iMin]); + + if( eDetail==FTS5_DETAIL_FULL ){ + pT->aMap[pT->nMap].iPos = iMinPos; + pT->aMap[pT->nMap].iIter = pT->aPoslistToIter[iMin]; + pT->aMap[pT->nMap].iRowid = iRowid; + pT->nMap++; + } + } + + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + } + } +} + +/* +** The iterator passed as the only argument must be a tokendata=1 iterator +** (pIter->pTokenDataIter!=0). This function advances the iterator. If +** argument bFrom is false, then the iterator is advanced to the next +** entry. Or, if bFrom is true, it is advanced to the first entry with +** a rowid of iFrom or greater. +*/ +static void fts5TokendataIterNext(Fts5Iter *pIter, int bFrom, i64 iFrom){ + int ii; + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + + for(ii=0; iinIter; ii++){ + Fts5Iter *p = pT->apIter[ii]; + if( p->base.bEof==0 + && (p->base.iRowid==pIter->base.iRowid || (bFrom && p->base.iRowidpIndex, p, bFrom, iFrom); + while( bFrom && p->base.bEof==0 + && p->base.iRowidpIndex->rc==SQLITE_OK + ){ + fts5MultiIterNext(p->pIndex, p, 0, 0); + } + } + } + + fts5IterSetOutputsTokendata(pIter); +} + +/* +** If the segment-iterator passed as the first argument is at EOF, then +** set pIter->term to a copy of buffer pTerm. +*/ +static void fts5TokendataSetTermIfEof(Fts5Iter *pIter, Fts5Buffer *pTerm){ + if( pIter && pIter->aSeg[0].pLeaf==0 ){ + fts5BufferSet(&pIter->pIndex->rc, &pIter->aSeg[0].term, pTerm->n, pTerm->p); + } +} + +/* +** This function sets up an iterator to use for a non-prefix query on a +** tokendata=1 table. +*/ +static Fts5Iter *fts5SetupTokendataIter( + Fts5Index *p, /* FTS index to query */ + const u8 *pToken, /* Buffer containing query term */ + int nToken, /* Size of buffer pToken in bytes */ + Fts5Colset *pColset /* Colset to filter on */ +){ + Fts5Iter *pRet = 0; + Fts5TokenDataIter *pSet = 0; + Fts5Structure *pStruct = 0; + const int flags = FTS5INDEX_QUERY_SCANONETERM | FTS5INDEX_QUERY_SCAN; + + Fts5Buffer bSeek = {0, 0, 0}; + Fts5Buffer *pSmall = 0; + + fts5IndexFlush(p); + pStruct = fts5StructureRead(p); + + while( p->rc==SQLITE_OK ){ + Fts5Iter *pPrev = pSet ? pSet->apIter[pSet->nIter-1] : 0; + Fts5Iter *pNew = 0; + Fts5SegIter *pNewIter = 0; + Fts5SegIter *pPrevIter = 0; + + int iLvl, iSeg, ii; + + pNew = fts5MultiIterAlloc(p, pStruct->nSegment); + if( pSmall ){ + fts5BufferSet(&p->rc, &bSeek, pSmall->n, pSmall->p); + fts5BufferAppendBlob(&p->rc, &bSeek, 1, (const u8*)"\0"); + }else{ + fts5BufferSet(&p->rc, &bSeek, nToken, pToken); + } + if( p->rc ){ + sqlite3Fts5IterClose((Fts5IndexIter*)pNew); + break; + } + + pNewIter = &pNew->aSeg[0]; + pPrevIter = (pPrev ? &pPrev->aSeg[0] : 0); + for(iLvl=0; iLvlnLevel; iLvl++){ + for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){ + Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg]; + int bDone = 0; + + if( pPrevIter ){ + if( fts5BufferCompare(pSmall, &pPrevIter->term) ){ + memcpy(pNewIter, pPrevIter, sizeof(Fts5SegIter)); + memset(pPrevIter, 0, sizeof(Fts5SegIter)); + bDone = 1; + }else if( pPrevIter->iEndofDoclist>pPrevIter->pLeaf->szLeaf ){ + fts5SegIterNextInit(p,(const char*)bSeek.p,bSeek.n-1,pSeg,pNewIter); + bDone = 1; + } + } + + if( bDone==0 ){ + fts5SegIterSeekInit(p, bSeek.p, bSeek.n, flags, pSeg, pNewIter); + } + + if( pPrevIter ){ + if( pPrevIter->pTombArray ){ + pNewIter->pTombArray = pPrevIter->pTombArray; + pNewIter->pTombArray->nRef++; + } + }else{ + fts5SegIterAllocTombstone(p, pNewIter); + } + + pNewIter++; + if( pPrevIter ) pPrevIter++; + if( p->rc ) break; + } + } + fts5TokendataSetTermIfEof(pPrev, pSmall); + + pNew->bSkipEmpty = 1; + pNew->pColset = pColset; + fts5IterSetOutputCb(&p->rc, pNew); + + /* Loop through all segments in the new iterator. Find the smallest + ** term that any segment-iterator points to. Iterator pNew will be + ** used for this term. Also, set any iterator that points to a term that + ** does not match pToken/nToken to point to EOF */ + pSmall = 0; + for(ii=0; iinSeg; ii++){ + Fts5SegIter *pII = &pNew->aSeg[ii]; + if( 0==fts5IsTokendataPrefix(&pII->term, pToken, nToken) ){ + fts5SegIterSetEOF(pII); + } + if( pII->pLeaf && (!pSmall || fts5BufferCompare(pSmall, &pII->term)>0) ){ + pSmall = &pII->term; + } + } + + /* If pSmall is still NULL at this point, then the new iterator does + ** not point to any terms that match the query. So delete it and break + ** out of the loop - all required iterators have been collected. */ + if( pSmall==0 ){ + sqlite3Fts5IterClose((Fts5IndexIter*)pNew); + break; + } + + /* Append this iterator to the set and continue. */ + pSet = fts5AppendTokendataIter(p, pSet, pNew); + } + + if( p->rc==SQLITE_OK && pSet ){ + int ii; + for(ii=0; iinIter; ii++){ + Fts5Iter *pIter = pSet->apIter[ii]; + int iSeg; + for(iSeg=0; iSegnSeg; iSeg++){ + pIter->aSeg[iSeg].flags |= FTS5_SEGITER_ONETERM; + } + fts5MultiIterFinishSetup(p, pIter); + } + } + + if( p->rc==SQLITE_OK ){ + pRet = fts5MultiIterAlloc(p, 0); + } + if( pRet ){ + pRet->pTokenDataIter = pSet; + if( pSet ){ + fts5IterSetOutputsTokendata(pRet); + }else{ + pRet->base.bEof = 1; + } + }else{ + fts5TokendataIterDelete(pSet); + } + + fts5StructureRelease(pStruct); + fts5BufferFree(&bSeek); + return pRet; +} + + /* ** Open a new iterator to iterate though all rowid that match the ** specified token or token prefix. @@ -242811,8 +245569,13 @@ static int sqlite3Fts5IndexQuery( if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ int iPrefixIdx = 0; /* +1 prefix index */ + int bTokendata = pConfig->bTokendata; if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); + if( flags & (FTS5INDEX_QUERY_NOTOKENDATA|FTS5INDEX_QUERY_SCAN) ){ + bTokendata = 0; + } + /* Figure out which index to search and set iIdx accordingly. If this ** is a prefix query for which there is no prefix index, set iIdx to ** greater than pConfig->nPrefix to indicate that the query will be @@ -242838,7 +245601,10 @@ static int sqlite3Fts5IndexQuery( } } - if( iIdx<=pConfig->nPrefix ){ + if( bTokendata && iIdx==0 ){ + buf.p[0] = '0'; + pRet = fts5SetupTokendataIter(p, buf.p, nToken+1, pColset); + }else if( iIdx<=pConfig->nPrefix ){ /* Straight index lookup */ Fts5Structure *pStruct = fts5StructureRead(p); buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx); @@ -242885,7 +245651,11 @@ static int sqlite3Fts5IndexQuery( static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; assert( pIter->pIndex->rc==SQLITE_OK ); - fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); + if( pIter->pTokenDataIter ){ + fts5TokendataIterNext(pIter, 0, 0); + }else{ + fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); + } return fts5IndexReturn(pIter->pIndex); } @@ -242918,7 +245688,11 @@ static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ */ static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; - fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); + if( pIter->pTokenDataIter ){ + fts5TokendataIterNext(pIter, 1, iMatch); + }else{ + fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); + } return fts5IndexReturn(pIter->pIndex); } @@ -242933,6 +245707,99 @@ static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ return (z ? &z[1] : 0); } +/* +** This is used by xInstToken() to access the token at offset iOff, column +** iCol of row iRowid. The token is returned via output variables *ppOut +** and *pnOut. The iterator passed as the first argument must be a tokendata=1 +** iterator (pIter->pTokenDataIter!=0). +*/ +static int sqlite3Fts5IterToken( + Fts5IndexIter *pIndexIter, + i64 iRowid, + int iCol, + int iOff, + const char **ppOut, int *pnOut +){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + Fts5TokenDataMap *aMap = pT->aMap; + i64 iPos = (((i64)iCol)<<32) + iOff; + + int i1 = 0; + int i2 = pT->nMap; + int iTest = 0; + + while( i2>i1 ){ + iTest = (i1 + i2) / 2; + + if( aMap[iTest].iRowidiRowid ){ + i2 = iTest; + }else{ + if( aMap[iTest].iPosiPos ){ + i2 = iTest; + }else{ + break; + } + } + } + + if( i2>i1 ){ + Fts5Iter *pMap = pT->apIter[aMap[iTest].iIter]; + *ppOut = (const char*)pMap->aSeg[0].term.p+1; + *pnOut = pMap->aSeg[0].term.n-1; + } + + return SQLITE_OK; +} + +/* +** Clear any existing entries from the token-map associated with the +** iterator passed as the only argument. +*/ +static void sqlite3Fts5IndexIterClearTokendata(Fts5IndexIter *pIndexIter){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; + if( pIter && pIter->pTokenDataIter ){ + pIter->pTokenDataIter->nMap = 0; + } +} + +/* +** Set a token-mapping for the iterator passed as the first argument. This +** is used in detail=column or detail=none mode when a token is requested +** using the xInstToken() API. In this case the caller tokenizers the +** current row and configures the token-mapping via multiple calls to this +** function. +*/ +static int sqlite3Fts5IndexIterWriteTokendata( + Fts5IndexIter *pIndexIter, + const char *pToken, int nToken, + i64 iRowid, int iCol, int iOff +){ + Fts5Iter *pIter = (Fts5Iter*)pIndexIter; + Fts5TokenDataIter *pT = pIter->pTokenDataIter; + Fts5Index *p = pIter->pIndex; + int ii; + + assert( p->pConfig->eDetail!=FTS5_DETAIL_FULL ); + assert( pIter->pTokenDataIter ); + + for(ii=0; iinIter; ii++){ + Fts5Buffer *pTerm = &pT->apIter[ii]->aSeg[0].term; + if( nToken==pTerm->n-1 && memcmp(pToken, pTerm->p+1, nToken)==0 ) break; + } + if( iinIter ){ + fts5TokendataIterAppendMap(p, pT, ii, iRowid, (((i64)iCol)<<32) + iOff); + } + return fts5IndexReturn(p); +} + /* ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery(). */ @@ -242940,6 +245807,7 @@ static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ if( pIndexIter ){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *pIndex = pIter->pIndex; + fts5TokendataIterDelete(pIter->pTokenDataIter); fts5MultiIterFree(pIter); sqlite3Fts5IndexCloseReader(pIndex); } @@ -243447,7 +246315,9 @@ static int fts5QueryCksum( int eDetail = p->pConfig->eDetail; u64 cksum = *pCksum; Fts5IndexIter *pIter = 0; - int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter); + int rc = sqlite3Fts5IndexQuery( + p, z, n, (flags | FTS5INDEX_QUERY_NOTOKENDATA), 0, &pIter + ); while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){ i64 rowid = pIter->iRowid; @@ -243614,7 +246484,7 @@ static void fts5IndexIntegrityCheckEmpty( } static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){ - int iTermOff = 0; + i64 iTermOff = 0; int ii; Fts5Buffer buf1 = {0,0,0}; @@ -243623,7 +246493,7 @@ static void fts5IntegrityCheckPgidx(Fts5Index *p, Fts5Data *pLeaf){ ii = pLeaf->szLeaf; while( iinn && p->rc==SQLITE_OK ){ int res; - int iOff; + i64 iOff; int nIncr; ii += fts5GetVarint32(&pLeaf->p[ii], nIncr); @@ -244145,6 +247015,24 @@ static void fts5DecodeRowidList( } #endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) +static void fts5BufferAppendTerm(int *pRc, Fts5Buffer *pBuf, Fts5Buffer *pTerm){ + int ii; + fts5BufferGrow(pRc, pBuf, pTerm->n*2 + 1); + if( *pRc==SQLITE_OK ){ + for(ii=0; iin; ii++){ + if( pTerm->p[ii]==0x00 ){ + pBuf->p[pBuf->n++] = '\\'; + pBuf->p[pBuf->n++] = '0'; + }else{ + pBuf->p[pBuf->n++] = pTerm->p[ii]; + } + } + pBuf->p[pBuf->n] = 0x00; + } +} +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ + #if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) /* ** The implementation of user-defined scalar function fts5_decode(). @@ -244252,9 +247140,8 @@ static void fts5DecodeFunction( iOff += fts5GetVarint32(&a[iOff], nAppend); term.n = nKeep; fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]); - sqlite3Fts5BufferAppendPrintf( - &rc, &s, " term=%.*s", term.n, (const char*)term.p - ); + sqlite3Fts5BufferAppendPrintf(&rc, &s, " term="); + fts5BufferAppendTerm(&rc, &s, &term); iOff += nAppend; /* Figure out where the doclist for this term ends */ @@ -244362,9 +247249,8 @@ static void fts5DecodeFunction( fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]); iOff += nByte; - sqlite3Fts5BufferAppendPrintf( - &rc, &s, " term=%.*s", term.n, (const char*)term.p - ); + sqlite3Fts5BufferAppendPrintf(&rc, &s, " term="); + fts5BufferAppendTerm(&rc, &s, &term); iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff); } @@ -244839,7 +247725,7 @@ struct Fts5FullTable { Fts5Global *pGlobal; /* Global (connection wide) data */ Fts5Cursor *pSortCsr; /* Sort data from this cursor */ int iSavepoint; /* Successful xSavepoint()+1 */ - int bInSavepoint; + #ifdef SQLITE_DEBUG struct Fts5TransactionState ts; #endif @@ -245377,12 +248263,15 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ } idxStr[iIdxStr] = '\0'; - /* Set idxFlags flags for the ORDER BY clause */ + /* Set idxFlags flags for the ORDER BY clause + ** + ** Note that tokendata=1 tables cannot currently handle "ORDER BY rowid DESC". + */ if( pInfo->nOrderBy==1 ){ int iSort = pInfo->aOrderBy[0].iColumn; if( iSort==(pConfig->nCol+1) && bSeenMatch ){ idxFlags |= FTS5_BI_ORDER_RANK; - }else if( iSort==-1 ){ + }else if( iSort==-1 && (!pInfo->aOrderBy[0].desc || !pConfig->bTokendata) ){ idxFlags |= FTS5_BI_ORDER_ROWID; } if( BitFlagTest(idxFlags, FTS5_BI_ORDER_RANK|FTS5_BI_ORDER_ROWID) ){ @@ -245634,6 +248523,16 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ ); assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) ); + /* If this cursor uses FTS5_PLAN_MATCH and this is a tokendata=1 table, + ** clear any token mappings accumulated at the fts5_index.c level. In + ** other cases, specifically FTS5_PLAN_SOURCE and FTS5_PLAN_SORTED_MATCH, + ** we need to retain the mappings for the entire query. */ + if( pCsr->ePlan==FTS5_PLAN_MATCH + && ((Fts5Table*)pCursor->pVtab)->pConfig->bTokendata + ){ + sqlite3Fts5ExprClearTokens(pCsr->pExpr); + } + if( pCsr->ePlan<3 ){ int bSkip = 0; if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc; @@ -246294,7 +249193,10 @@ static int fts5SpecialInsert( }else if( 0==sqlite3_stricmp("flush", zCmd) ){ rc = sqlite3Fts5FlushToDisk(&pTab->p); }else{ - rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + rc = sqlite3Fts5FlushToDisk(&pTab->p); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + } if( rc==SQLITE_OK ){ rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError); } @@ -246619,7 +249521,10 @@ static int fts5ApiColumnText( ){ int rc = SQLITE_OK; Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; - if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) + Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); + if( iCol<0 || iCol>=pTab->pConfig->nCol ){ + rc = SQLITE_RANGE; + }else if( fts5IsContentless((Fts5FullTable*)(pCsr->base.pVtab)) || pCsr->ePlan==FTS5_PLAN_SPECIAL ){ *pz = 0; @@ -246644,8 +249549,9 @@ static int fts5CsrPoslist( int rc = SQLITE_OK; int bLive = (pCsr->pSorter==0); - if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ - + if( iPhrase<0 || iPhrase>=sqlite3Fts5ExprPhraseCount(pCsr->pExpr) ){ + rc = SQLITE_RANGE; + }else if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_POSLIST) ){ if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ Fts5PoslistPopulator *aPopulator; int i; @@ -246669,15 +249575,21 @@ static int fts5CsrPoslist( CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST); } - if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){ - Fts5Sorter *pSorter = pCsr->pSorter; - int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); - *pn = pSorter->aIdx[iPhrase] - i1; - *pa = &pSorter->aPoslist[i1]; + if( rc==SQLITE_OK ){ + if( pCsr->pSorter && pConfig->eDetail==FTS5_DETAIL_FULL ){ + Fts5Sorter *pSorter = pCsr->pSorter; + int i1 = (iPhrase==0 ? 0 : pSorter->aIdx[iPhrase-1]); + *pn = pSorter->aIdx[iPhrase] - i1; + *pa = &pSorter->aPoslist[i1]; + }else{ + *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); + } }else{ - *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); + *pa = 0; + *pn = 0; } + return rc; } @@ -246784,12 +249696,6 @@ static int fts5ApiInst( ){ if( iIdx<0 || iIdx>=pCsr->nInstCount ){ rc = SQLITE_RANGE; -#if 0 - }else if( fts5IsOffsetless((Fts5Table*)pCsr->base.pVtab) ){ - *piPhrase = pCsr->aInst[iIdx*3]; - *piCol = pCsr->aInst[iIdx*3 + 2]; - *piOff = -1; -#endif }else{ *piPhrase = pCsr->aInst[iIdx*3]; *piCol = pCsr->aInst[iIdx*3 + 1]; @@ -247044,13 +249950,56 @@ static int fts5ApiPhraseFirstColumn( return rc; } +/* +** xQueryToken() API implemenetation. +*/ +static int fts5ApiQueryToken( + Fts5Context* pCtx, + int iPhrase, + int iToken, + const char **ppOut, + int *pnOut +){ + Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; + return sqlite3Fts5ExprQueryToken(pCsr->pExpr, iPhrase, iToken, ppOut, pnOut); +} + +/* +** xInstToken() API implemenetation. +*/ +static int fts5ApiInstToken( + Fts5Context *pCtx, + int iIdx, + int iToken, + const char **ppOut, int *pnOut +){ + Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; + int rc = SQLITE_OK; + if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_INST)==0 + || SQLITE_OK==(rc = fts5CacheInstArray(pCsr)) + ){ + if( iIdx<0 || iIdx>=pCsr->nInstCount ){ + rc = SQLITE_RANGE; + }else{ + int iPhrase = pCsr->aInst[iIdx*3]; + int iCol = pCsr->aInst[iIdx*3 + 1]; + int iOff = pCsr->aInst[iIdx*3 + 2]; + i64 iRowid = fts5CursorRowid(pCsr); + rc = sqlite3Fts5ExprInstToken( + pCsr->pExpr, iRowid, iPhrase, iCol, iOff, iToken, ppOut, pnOut + ); + } + } + return rc; +} + static int fts5ApiQueryPhrase(Fts5Context*, int, void*, int(*)(const Fts5ExtensionApi*, Fts5Context*, void*) ); static const Fts5ExtensionApi sFts5Api = { - 2, /* iVersion */ + 3, /* iVersion */ fts5ApiUserData, fts5ApiColumnCount, fts5ApiRowCount, @@ -247070,6 +250019,8 @@ static const Fts5ExtensionApi sFts5Api = { fts5ApiPhraseNext, fts5ApiPhraseFirstColumn, fts5ApiPhraseNextColumn, + fts5ApiQueryToken, + fts5ApiInstToken }; /* @@ -247336,9 +250287,7 @@ static int fts5RenameMethod( ){ int rc; Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - pTab->bInSavepoint = 1; rc = sqlite3Fts5StorageRename(pTab->pStorage, zName); - pTab->bInSavepoint = 0; return rc; } @@ -247355,26 +250304,12 @@ static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; int rc = SQLITE_OK; - char *zSql = 0; + fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); - - if( pTab->bInSavepoint==0 ){ - zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", - pTab->p.pConfig->zDb, pTab->p.pConfig->zName, pTab->p.pConfig->zName - ); - if( zSql ){ - pTab->bInSavepoint = 1; - rc = sqlite3_exec(pTab->p.pConfig->db, zSql, 0, 0, 0); - pTab->bInSavepoint = 0; - sqlite3_free(zSql); - }else{ - rc = SQLITE_NOMEM; - } - if( rc==SQLITE_OK ){ - pTab->iSavepoint = iSavepoint+1; - } + rc = sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint+1; } - return rc; } @@ -247406,8 +250341,8 @@ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ int rc = SQLITE_OK; fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); fts5TripCursors(pTab); - pTab->p.pConfig->pgsz = 0; if( (iSavepoint+1)<=pTab->iSavepoint ){ + pTab->p.pConfig->pgsz = 0; rc = sqlite3Fts5StorageRollback(pTab->pStorage); } return rc; @@ -247612,7 +250547,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257cc467a", -1, SQLITE_TRANSIENT); } /* @@ -247635,7 +250570,7 @@ static int fts5ShadowName(const char *zName){ ** if anything is found amiss. Return a NULL pointer if everything is ** OK. */ -static int fts5Integrity( +static int fts5IntegrityMethod( sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */ const char *zSchema, /* Name of schema in which this table lives */ const char *zTabname, /* Name of the table itself */ @@ -247643,27 +250578,21 @@ static int fts5Integrity( char **pzErr /* Write error message here */ ){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - Fts5Config *pConfig = pTab->p.pConfig; - char *zSql; - char *zErr = 0; int rc; + assert( pzErr!=0 && *pzErr==0 ); UNUSED_PARAM(isQuick); - zSql = sqlite3_mprintf( - "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", - zSchema, zTabname, pConfig->zName); - if( zSql==0 ) return SQLITE_NOMEM; - rc = sqlite3_exec(pConfig->db, zSql, 0, 0, &zErr); - sqlite3_free(zSql); + rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0); if( (rc&0xff)==SQLITE_CORRUPT ){ *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", zSchema, zTabname); }else if( rc!=SQLITE_OK ){ *pzErr = sqlite3_mprintf("unable to validate the inverted index for" " FTS5 table %s.%s: %s", - zSchema, zTabname, zErr); + zSchema, zTabname, sqlite3_errstr(rc)); } - sqlite3_free(zErr); + sqlite3Fts5IndexCloseReader(pTab->p.pIndex); + return SQLITE_OK; } @@ -247693,7 +250622,7 @@ static int fts5Init(sqlite3 *db){ /* xRelease */ fts5ReleaseMethod, /* xRollbackTo */ fts5RollbackToMethod, /* xShadowName */ fts5ShadowName, - /* xIntegrity */ fts5Integrity + /* xIntegrity */ fts5IntegrityMethod }; int rc; @@ -248459,7 +251388,7 @@ static int sqlite3Fts5StorageRebuild(Fts5Storage *p){ } if( rc==SQLITE_OK ){ - rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0); + rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, pConfig->pzErrmsg); } while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){ @@ -249246,6 +252175,12 @@ static const unsigned char sqlite3Utf8Trans1[] = { #endif /* ifndef SQLITE_AMALGAMATION */ +#define FTS5_SKIP_UTF8(zIn) { \ + if( ((unsigned char)(*(zIn++)))>=0xc0 ){ \ + while( (((unsigned char)*zIn) & 0xc0)==0x80 ){ zIn++; } \ + } \ +} + typedef struct Unicode61Tokenizer Unicode61Tokenizer; struct Unicode61Tokenizer { unsigned char aTokenChar[128]; /* ASCII range token characters */ @@ -250281,6 +253216,7 @@ static int fts5PorterTokenize( typedef struct TrigramTokenizer TrigramTokenizer; struct TrigramTokenizer { int bFold; /* True to fold to lower-case */ + int iFoldParam; /* Parameter to pass to Fts5UnicodeFold() */ }; /* @@ -250307,6 +253243,7 @@ static int fts5TriCreate( }else{ int i; pNew->bFold = 1; + pNew->iFoldParam = 0; for(i=0; rc==SQLITE_OK && ibFold = (zArg[0]=='0'); } + }else if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){ + if( (zArg[0]!='0' && zArg[0]!='1' && zArg[0]!='2') || zArg[1] ){ + rc = SQLITE_ERROR; + }else{ + pNew->iFoldParam = (zArg[0]!='0') ? 2 : 0; + } }else{ rc = SQLITE_ERROR; } } + + if( pNew->iFoldParam!=0 && pNew->bFold==0 ){ + rc = SQLITE_ERROR; + } + if( rc!=SQLITE_OK ){ fts5TriDelete((Fts5Tokenizer*)pNew); pNew = 0; @@ -250341,40 +253289,62 @@ static int fts5TriTokenize( TrigramTokenizer *p = (TrigramTokenizer*)pTok; int rc = SQLITE_OK; char aBuf[32]; + char *zOut = aBuf; + int ii; const unsigned char *zIn = (const unsigned char*)pText; const unsigned char *zEof = &zIn[nText]; u32 iCode; + int aStart[3]; /* Input offset of each character in aBuf[] */ UNUSED_PARAM(unusedFlags); - while( 1 ){ - char *zOut = aBuf; - int iStart = zIn - (const unsigned char*)pText; - const unsigned char *zNext; - READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) break; - zNext = zIn; - if( zInbFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); - WRITE_UTF8(zOut, iCode); + /* Populate aBuf[] with the characters for the first trigram. */ + for(ii=0; ii<3; ii++){ + do { + aStart[ii] = zIn - (const unsigned char*)pText; + READ_UTF8(zIn, zEof, iCode); + if( iCode==0 ) return SQLITE_OK; + if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); + }while( iCode==0 ); + WRITE_UTF8(zOut, iCode); + } + + /* At the start of each iteration of this loop: + ** + ** aBuf: Contains 3 characters. The 3 characters of the next trigram. + ** zOut: Points to the byte following the last character in aBuf. + ** aStart[3]: Contains the byte offset in the input text corresponding + ** to the start of each of the three characters in the buffer. + */ + assert( zIn<=zEof ); + while( 1 ){ + int iNext; /* Start of character following current tri */ + const char *z1; + + /* Read characters from the input up until the first non-diacritic */ + do { + iNext = zIn - (const unsigned char*)pText; READ_UTF8(zIn, zEof, iCode); if( iCode==0 ) break; - }else{ - break; - } - if( zInbFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); - WRITE_UTF8(zOut, iCode); - READ_UTF8(zIn, zEof, iCode); - if( iCode==0 ) break; - if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, 0); - WRITE_UTF8(zOut, iCode); - }else{ - break; - } - rc = xToken(pCtx, 0, aBuf, zOut-aBuf, iStart, iStart + zOut-aBuf); - if( rc!=SQLITE_OK ) break; - zIn = zNext; + if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam); + }while( iCode==0 ); + + /* Pass the current trigram back to fts5 */ + rc = xToken(pCtx, 0, aBuf, zOut-aBuf, aStart[0], iNext); + if( iCode==0 || rc!=SQLITE_OK ) break; + + /* Remove the first character from buffer aBuf[]. Append the character + ** with codepoint iCode. */ + z1 = aBuf; + FTS5_SKIP_UTF8(z1); + memmove(aBuf, z1, zOut - z1); + zOut -= (z1 - aBuf); + WRITE_UTF8(zOut, iCode); + + /* Update the aStart[] array */ + aStart[0] = aStart[1]; + aStart[1] = aStart[2]; + aStart[2] = iNext; } return rc; @@ -250397,7 +253367,9 @@ static int sqlite3Fts5TokenizerPattern( ){ if( xCreate==fts5TriCreate ){ TrigramTokenizer *p = (TrigramTokenizer*)pTok; - return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; + if( p->iFoldParam==0 ){ + return p->bFold ? FTS5_PATTERN_LIKE : FTS5_PATTERN_GLOB; + } } return FTS5_PATTERN_NONE; } @@ -252186,7 +255158,7 @@ static int fts5VocabFilterMethod( if( pEq ){ zTerm = (const char *)sqlite3_value_text(pEq); nTerm = sqlite3_value_bytes(pEq); - f = 0; + f = FTS5INDEX_QUERY_NOTOKENDATA; }else{ if( pGe ){ zTerm = (const char *)sqlite3_value_text(pGe); diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h index fce162d697a..4fdfde004eb 100644 --- a/src/3rdparty/sqlite/sqlite3.h +++ b/src/3rdparty/sqlite/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.44.1" -#define SQLITE_VERSION_NUMBER 3044001 -#define SQLITE_SOURCE_ID "2023-11-22 14:18:12 d295f48e8f367b066b881780c98bdf980a1d550397d5ba0b0e49842c95b3e8b4" +#define SQLITE_VERSION "3.45.1" +#define SQLITE_VERSION_NUMBER 3045001 +#define SQLITE_SOURCE_ID "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257cc467a" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -3954,15 +3954,17 @@ SQLITE_API void sqlite3_free_filename(sqlite3_filename); ** ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language -** text that describes the error, as either UTF-8 or UTF-16 respectively. +** text that describes the error, as either UTF-8 or UTF-16 respectively, +** or NULL if no error message is available. ** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** -** ^The sqlite3_errstr() interface returns the English-language text -** that describes the [result code], as UTF-8. +** ^The sqlite3_errstr(E) interface returns the English-language text +** that describes the [result code] E, as UTF-8, or NULL if E is not an +** result code for which a text error message is available. ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** @@ -8037,9 +8039,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** ^(Some systems (for example, Windows 95) do not support the operation ** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() -** will always return SQLITE_BUSY. The SQLite core only ever uses -** sqlite3_mutex_try() as an optimization so this is acceptable -** behavior.)^ +** will always return SQLITE_BUSY. In most cases the SQLite core only uses +** sqlite3_mutex_try() as an optimization, so this is acceptable +** behavior. The exceptions are unix builds that set the +** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working +** sqlite3_mutex_try() is required.)^ ** ** ^The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior @@ -8298,6 +8302,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */ +#define SQLITE_TESTCTRL_JSON_SELFCHECK 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15 #define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ @@ -12811,8 +12816,11 @@ struct Fts5PhraseIter { ** created with the "columnsize=0" option. ** ** xColumnText: -** This function attempts to retrieve the text of column iCol of the -** current document. If successful, (*pz) is set to point to a buffer +** If parameter iCol is less than zero, or greater than or equal to the +** number of columns in the table, SQLITE_RANGE is returned. +** +** Otherwise, this function attempts to retrieve the text of column iCol of +** the current document. If successful, (*pz) is set to point to a buffer ** containing the text in utf-8 encoding, (*pn) is set to the size in bytes ** (not characters) of the buffer and SQLITE_OK is returned. Otherwise, ** if an error occurs, an SQLite error code is returned and the final values @@ -12822,8 +12830,10 @@ struct Fts5PhraseIter { ** Returns the number of phrases in the current query expression. ** ** xPhraseSize: -** Returns the number of tokens in phrase iPhrase of the query. Phrases -** are numbered starting from zero. +** If parameter iCol is less than zero, or greater than or equal to the +** number of phrases in the current query, as returned by xPhraseCount, +** 0 is returned. Otherwise, this function returns the number of tokens in +** phrase iPhrase of the query. Phrases are numbered starting from zero. ** ** xInstCount: ** Set *pnInst to the total number of occurrences of all phrases within @@ -12839,12 +12849,13 @@ struct Fts5PhraseIter { ** Query for the details of phrase match iIdx within the current row. ** Phrase matches are numbered starting from zero, so the iIdx argument ** should be greater than or equal to zero and smaller than the value -** output by xInstCount(). +** output by xInstCount(). If iIdx is less than zero or greater than +** or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. ** -** Usually, output parameter *piPhrase is set to the phrase number, *piCol +** Otherwise, output parameter *piPhrase is set to the phrase number, *piCol ** to the column in which it occurs and *piOff the token offset of the -** first token of the phrase. Returns SQLITE_OK if successful, or an error -** code (i.e. SQLITE_NOMEM) if an error occurs. +** first token of the phrase. SQLITE_OK is returned if successful, or an +** error code (i.e. SQLITE_NOMEM) if an error occurs. ** ** This API can be quite slow if used with an FTS5 table created with the ** "detail=none" or "detail=column" option. @@ -12870,6 +12881,10 @@ struct Fts5PhraseIter { ** Invoking Api.xUserData() returns a copy of the pointer passed as ** the third argument to pUserData. ** +** If parameter iPhrase is less than zero, or greater than or equal to +** the number of phrases in the query, as returned by xPhraseCount(), +** this function returns SQLITE_RANGE. +** ** If the callback function returns any value other than SQLITE_OK, the ** query is abandoned and the xQueryPhrase function returns immediately. ** If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK. @@ -12984,9 +12999,42 @@ struct Fts5PhraseIter { ** ** xPhraseNextColumn() ** See xPhraseFirstColumn above. +** +** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase iPhrase of the current +** query. Before returning, output parameter *ppToken is set to point +** to a buffer containing the requested token, and *pnToken to the +** size of this buffer in bytes. +** +** If iPhrase or iToken are less than zero, or if iPhrase is greater than +** or equal to the number of phrases in the query as reported by +** xPhraseCount(), or if iToken is equal to or greater than the number of +** tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken + are both zeroed. +** +** The output text is not a copy of the query text that specified the +** token. It is the output of the tokenizer module. For tokendata=1 +** tables, this includes any embedded 0x00 and trailing data. +** +** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken) +** This is used to access token iToken of phrase hit iIdx within the +** current row. If iIdx is less than zero or greater than or equal to the +** value returned by xInstCount(), SQLITE_RANGE is returned. Otherwise, +** output variable (*ppToken) is set to point to a buffer containing the +** matching document token, and (*pnToken) to the size of that buffer in +** bytes. This API is not available if the specified token matches a +** prefix query term. In that case both output variables are always set +** to 0. +** +** The output text is not a copy of the document text that was tokenized. +** It is the output of the tokenizer module. For tokendata=1 tables, this +** includes any embedded 0x00 and trailing data. +** +** This API can be quite slow if used with an FTS5 table created with the +** "detail=none" or "detail=column" option. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 2 */ + int iVersion; /* Currently always set to 3 */ void *(*xUserData)(Fts5Context*); @@ -13021,6 +13069,13 @@ struct Fts5ExtensionApi { int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*); void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol); + + /* Below this point are iVersion>=3 only */ + int (*xQueryToken)(Fts5Context*, + int iPhrase, int iToken, + const char **ppToken, int *pnToken + ); + int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); }; /* diff --git a/src/3rdparty/zlib/qt_attribution.json b/src/3rdparty/zlib/qt_attribution.json index 4106ab3cb73..7806aef31c7 100644 --- a/src/3rdparty/zlib/qt_attribution.json +++ b/src/3rdparty/zlib/qt_attribution.json @@ -6,11 +6,11 @@ "Description": "zlib is a general purpose data compression library.", "Homepage": "https://zlib.net/", - "Version": "1.3", - "DownloadLocation": "https://www.zlib.net/zlib-1.3.tar.gz", + "Version": "1.3.1", + "DownloadLocation": "https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz", "License": "zlib License", "LicenseId": "Zlib", "LicenseFile": "LICENSE", - "Copyright": "(C) 1995-2023 Jean-loup Gailly and Mark Adler" + "Copyright": "(C) 1995-2024 Jean-loup Gailly and Mark Adler" } diff --git a/src/3rdparty/zlib/qtpatches.diff b/src/3rdparty/zlib/qtpatches.diff index 20e2b10aa7f..b8efa5199e8 100644 --- a/src/3rdparty/zlib/qtpatches.diff +++ b/src/3rdparty/zlib/qtpatches.diff @@ -1,20 +1,20 @@ diff --git a/src/ChangeLog b/src/ChangeLog -index 8707988ac1..c107a78b5d 100644 +index b801a1031ec..686283a2aec 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,6 +1,10 @@ ChangeLog file for zlib -+Changes in 1.3 (Qt) (23 Aug 2023) ++Changes in 1.3.1 (Qt) (23 Jan 2024) +- This is a stripped down copy of zlib that contains patches to + make it compile as part of Qt. See also "qtpatches.diff". + - Changes in 1.3 (18 Aug 2023) - - Remove K&R function definitions and zlib2ansi - - Fix bug in deflateBound() for level 0 and memLevel 9 + Changes in 1.3.1 (22 Jan 2024) + - Reject overflows of zip header fields in minizip + - Fix bug in inflateSync() for data held in bit buffer diff --git a/src/README b/src/README -index e02fc5aa20..f9c16220b2 100644 +index c5f917540b6..af6b4f32bf5 100644 --- a/src/README +++ b/src/README @@ -6,6 +6,9 @@ thread safe. The data format used by the zlib library is described by RFCs @@ -28,7 +28,7 @@ index e02fc5aa20..f9c16220b2 100644 (volunteer to write man pages welcome, contact zlib@gzip.org). A usage example of the library is given in the file test/example.c which also tests that diff --git a/src/gzguts.h b/src/gzguts.h -index f9375047e8..4c7c9f1225 100644 +index eba72085bb7..5bf6b7d4813 100644 --- a/src/gzguts.h +++ b/src/gzguts.h @@ -3,6 +3,12 @@ @@ -45,7 +45,7 @@ index f9375047e8..4c7c9f1225 100644 # ifndef _LARGEFILE_SOURCE # define _LARGEFILE_SOURCE 1 diff --git a/src/zconf.h b/src/zconf.h -index fb76ffe312..18be576f50 100644 +index 62adc8d8431..4e14507a22d 100644 --- a/src/zconf.h +++ b/src/zconf.h @@ -8,6 +8,9 @@ @@ -66,7 +66,7 @@ index fb76ffe312..18be576f50 100644 /* all zlib typedefs in zlib.h and zconf.h */ # define Byte z_Byte -@@ -441,7 +445,7 @@ typedef uLong FAR uLongf; +@@ -433,7 +437,7 @@ typedef uLong FAR uLongf; typedef unsigned long z_crc_t; #endif @@ -76,7 +76,7 @@ index fb76ffe312..18be576f50 100644 #endif diff --git a/src/zlib.h b/src/zlib.h -index 6b7244f994..ffe3b177e2 100644 +index 8d4b932eaf6..2cff72ee865 100644 --- a/src/zlib.h +++ b/src/zlib.h @@ -33,11 +33,15 @@ @@ -91,13 +91,13 @@ index 6b7244f994..ffe3b177e2 100644 extern "C" { #endif --#define ZLIB_VERSION "1.3" -+#define ZLIB_VERSION "1.3 (Qt)" - #define ZLIB_VERNUM 0x1300 +-#define ZLIB_VERSION "1.3.1" ++#define ZLIB_VERSION "1.3.1 (Qt)" + #define ZLIB_VERNUM 0x1310 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 3 diff --git a/src/zutil.h b/src/zutil.h -index 902a304cc2..3ea777b0f4 100644 +index 48dd7febae6..71dd616ab8d 100644 --- a/src/zutil.h +++ b/src/zutil.h @@ -13,6 +13,12 @@ @@ -113,19 +113,7 @@ index 902a304cc2..3ea777b0f4 100644 #ifdef HAVE_HIDDEN # define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) #else -@@ -143,6 +149,11 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ - # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os - # include /* for fdopen */ - # else -+// We need to include stdio.h here because zlib.h will include TargetConditionals.h -+// This will define TARGET_OS_MAC that leads to this check. -+// Since zutil.h will include gzguts.h and gzguts.h includes stdio.h -+// AFTER check for fdopen we need to include stdio.h directly -+# include - # ifndef fdopen - # define fdopen(fd,mode) NULL /* No fdopen() */ - # endif -@@ -166,7 +177,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +@@ -157,7 +163,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 18 #endif diff --git a/src/3rdparty/zlib/src/ChangeLog b/src/3rdparty/zlib/src/ChangeLog index c107a78b5da..26541ea7928 100644 --- a/src/3rdparty/zlib/src/ChangeLog +++ b/src/3rdparty/zlib/src/ChangeLog @@ -1,10 +1,20 @@ ChangeLog file for zlib -Changes in 1.3 (Qt) (23 Aug 2023) +Changes in 1.3.1 (Qt) (23 Jan 2024) - This is a stripped down copy of zlib that contains patches to make it compile as part of Qt. See also "qtpatches.diff". +Changes in 1.3.1 (22 Jan 2024) +- Reject overflows of zip header fields in minizip +- Fix bug in inflateSync() for data held in bit buffer +- Add LIT_MEM define to use more memory for a small deflate speedup +- Fix decision on the emission of Zip64 end records in minizip +- Add bounds checking to ERR_MSG() macro, used by zError() +- Neutralize zip file traversal attacks in miniunz +- Fix a bug in ZLIB_DEBUG compiles in check_match() +- Various portability and appearance improvements + Changes in 1.3 (18 Aug 2023) - Remove K&R function definitions and zlib2ansi - Fix bug in deflateBound() for level 0 and memLevel 9 diff --git a/src/3rdparty/zlib/src/README b/src/3rdparty/zlib/src/README index f9c16220b20..af6b4f32bf5 100644 --- a/src/3rdparty/zlib/src/README +++ b/src/3rdparty/zlib/src/README @@ -1,6 +1,6 @@ ZLIB DATA COMPRESSION LIBRARY -zlib 1.3 is a general purpose data compression library. All the code is +zlib 1.3.1 is a general purpose data compression library. All the code is thread safe. The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and @@ -34,7 +34,7 @@ Mark Nelson wrote an article about zlib for the Jan. 1997 issue of Dr. Dobb's Journal; a copy of the article is available at https://marknelson.us/posts/1997/01/01/zlib-engine.html . -The changes made in version 1.3 are documented in the file ChangeLog. +The changes made in version 1.3.1 are documented in the file ChangeLog. Unsupported third party contributions are provided in directory contrib/ . @@ -86,7 +86,7 @@ Acknowledgments: Copyright notice: - (C) 1995-2023 Jean-loup Gailly and Mark Adler + (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages diff --git a/src/3rdparty/zlib/src/deflate.c b/src/3rdparty/zlib/src/deflate.c index bd011751920..012ea8148e8 100644 --- a/src/3rdparty/zlib/src/deflate.c +++ b/src/3rdparty/zlib/src/deflate.c @@ -1,5 +1,5 @@ /* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.3 Copyright 1995-2023 Jean-loup Gailly and Mark Adler "; + " deflate 1.3.1 Copyright 1995-2024 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -493,7 +493,7 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, * symbols from which it is being constructed. */ - s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, 4); + s->pending_buf = (uchf *) ZALLOC(strm, s->lit_bufsize, LIT_BUFS); s->pending_buf_size = (ulg)s->lit_bufsize * 4; if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || @@ -503,8 +503,14 @@ int ZEXPORT deflateInit2_(z_streamp strm, int level, int method, deflateEnd (strm); return Z_MEM_ERROR; } +#ifdef LIT_MEM + s->d_buf = (ushf *)(s->pending_buf + (s->lit_bufsize << 1)); + s->l_buf = s->pending_buf + (s->lit_bufsize << 2); + s->sym_end = s->lit_bufsize - 1; +#else s->sym_buf = s->pending_buf + s->lit_bufsize; s->sym_end = (s->lit_bufsize - 1) * 3; +#endif /* We avoid equality with lit_bufsize*3 because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. @@ -720,9 +726,15 @@ int ZEXPORT deflatePrime(z_streamp strm, int bits, int value) { if (deflateStateCheck(strm)) return Z_STREAM_ERROR; s = strm->state; +#ifdef LIT_MEM + if (bits < 0 || bits > 16 || + (uchf *)s->d_buf < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; +#else if (bits < 0 || bits > 16 || s->sym_buf < s->pending_out + ((Buf_size + 7) >> 3)) return Z_BUF_ERROR; +#endif do { put = Buf_size - s->bi_valid; if (put > bits) @@ -1294,7 +1306,7 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, 4); + ds->pending_buf = (uchf *) ZALLOC(dest, ds->lit_bufsize, LIT_BUFS); if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || ds->pending_buf == Z_NULL) { @@ -1305,10 +1317,15 @@ int ZEXPORT deflateCopy(z_streamp dest, z_streamp source) { zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + zmemcpy(ds->pending_buf, ss->pending_buf, ds->lit_bufsize * LIT_BUFS); ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); +#ifdef LIT_MEM + ds->d_buf = (ushf *)(ds->pending_buf + (ds->lit_bufsize << 1)); + ds->l_buf = ds->pending_buf + (ds->lit_bufsize << 2); +#else ds->sym_buf = ds->pending_buf + ds->lit_bufsize; +#endif ds->l_desc.dyn_tree = ds->dyn_ltree; ds->d_desc.dyn_tree = ds->dyn_dtree; @@ -1539,13 +1556,21 @@ local uInt longest_match(deflate_state *s, IPos cur_match) { */ local void check_match(deflate_state *s, IPos start, IPos match, int length) { /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); + Bytef *back = s->window + (int)match, *here = s->window + start; + IPos len = length; + if (match == (IPos)-1) { + /* match starts one byte before the current window -- just compare the + subsequent length-1 bytes */ + back++; + here++; + len--; + } + if (zmemcmp(back, here, len) != EQUAL) { + fprintf(stderr, " start %u, match %d, length %d\n", + start, (int)match, length); do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); + fprintf(stderr, "(%02x %02x)", *back++, *here++); + } while (--len != 0); z_error("invalid match"); } if (z_verbose > 1) { diff --git a/src/3rdparty/zlib/src/deflate.h b/src/3rdparty/zlib/src/deflate.h index 8696791429f..300c6ada62b 100644 --- a/src/3rdparty/zlib/src/deflate.h +++ b/src/3rdparty/zlib/src/deflate.h @@ -1,5 +1,5 @@ /* deflate.h -- internal compression state - * Copyright (C) 1995-2018 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -23,6 +23,10 @@ # define GZIP #endif +/* define LIT_MEM to slightly increase the speed of deflate (order 1% to 2%) at + the cost of a larger memory footprint */ +/* #define LIT_MEM */ + /* =========================================================================== * Internal compression state. */ @@ -217,7 +221,14 @@ typedef struct internal_state { /* Depth of each subtree used as tie breaker for trees of equal frequency */ +#ifdef LIT_MEM +# define LIT_BUFS 5 + ushf *d_buf; /* buffer for distances */ + uchf *l_buf; /* buffer for literals/lengths */ +#else +# define LIT_BUFS 4 uchf *sym_buf; /* buffer for distances and literals/lengths */ +#endif uInt lit_bufsize; /* Size of match buffer for literals/lengths. There are 4 reasons for @@ -239,7 +250,7 @@ typedef struct internal_state { * - I can't count above 4 */ - uInt sym_next; /* running index in sym_buf */ + uInt sym_next; /* running index in symbol buffer */ uInt sym_end; /* symbol table full when sym_next reaches this */ ulg opt_len; /* bit length of current block with optimal trees */ @@ -318,6 +329,25 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, extern const uch ZLIB_INTERNAL _dist_code[]; #endif +#ifdef LIT_MEM +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->sym_next] = 0; \ + s->l_buf[s->sym_next++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (uch)(length); \ + ush dist = (ush)(distance); \ + s->d_buf[s->sym_next] = dist; \ + s->l_buf[s->sym_next++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->sym_next == s->sym_end); \ + } +#else # define _tr_tally_lit(s, c, flush) \ { uch cc = (c); \ s->sym_buf[s->sym_next++] = 0; \ @@ -337,6 +367,7 @@ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf, s->dyn_dtree[d_code(dist)].Freq++; \ flush = (s->sym_next == s->sym_end); \ } +#endif #else # define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) # define _tr_tally_dist(s, distance, length, flush) \ diff --git a/src/3rdparty/zlib/src/gzguts.h b/src/3rdparty/zlib/src/gzguts.h index cadba0b24e4..d5512b5406a 100644 --- a/src/3rdparty/zlib/src/gzguts.h +++ b/src/3rdparty/zlib/src/gzguts.h @@ -1,5 +1,5 @@ /* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -229,9 +229,5 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error); /* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t value -- needed when comparing unsigned to z_off64_t, which is signed (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else unsigned ZLIB_INTERNAL gz_intmax(void); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) diff --git a/src/3rdparty/zlib/src/gzlib.c b/src/3rdparty/zlib/src/gzlib.c index 29fc4486fba..983153cc8e4 100644 --- a/src/3rdparty/zlib/src/gzlib.c +++ b/src/3rdparty/zlib/src/gzlib.c @@ -1,5 +1,5 @@ /* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004-2019 Mark Adler + * Copyright (C) 2004-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -563,20 +563,20 @@ void ZLIB_INTERNAL gz_error(gz_statep state, int err, const char *msg) { #endif } -#ifndef INT_MAX /* portably return maximum value for an int (when limits.h presumed not available) -- we need to do this to cover cases where 2's complement not used, since C standard permits 1's complement and sign-bit representations, otherwise we could just use ((unsigned)-1) >> 1 */ unsigned ZLIB_INTERNAL gz_intmax(void) { - unsigned p, q; - - p = 1; +#ifdef INT_MAX + return INT_MAX; +#else + unsigned p = 1, q; do { q = p; p <<= 1; p++; } while (p > q); return q >> 1; -} #endif +} diff --git a/src/3rdparty/zlib/src/inflate.c b/src/3rdparty/zlib/src/inflate.c index b0757a9b249..94ecff015a9 100644 --- a/src/3rdparty/zlib/src/inflate.c +++ b/src/3rdparty/zlib/src/inflate.c @@ -1387,7 +1387,7 @@ int ZEXPORT inflateSync(z_streamp strm) { /* if first time, start search in bit buffer */ if (state->mode != SYNC) { state->mode = SYNC; - state->hold <<= state->bits & 7; + state->hold >>= state->bits & 7; state->bits -= state->bits & 7; len = 0; while (state->bits >= 8) { diff --git a/src/3rdparty/zlib/src/inftrees.c b/src/3rdparty/zlib/src/inftrees.c index 8a208c2daa8..98cfe164458 100644 --- a/src/3rdparty/zlib/src/inftrees.c +++ b/src/3rdparty/zlib/src/inftrees.c @@ -1,5 +1,5 @@ /* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2023 Mark Adler + * Copyright (C) 1995-2024 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.3 Copyright 1995-2023 Mark Adler "; + " inflate 1.3.1 Copyright 1995-2024 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -57,7 +57,7 @@ int ZLIB_INTERNAL inflate_table(codetype type, unsigned short FAR *lens, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; static const unsigned short lext[31] = { /* Length codes 257..285 extra */ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 198, 203}; + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 77}; static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, diff --git a/src/3rdparty/zlib/src/inftrees.h b/src/3rdparty/zlib/src/inftrees.h index a10712d8cb5..396f74b5da7 100644 --- a/src/3rdparty/zlib/src/inftrees.h +++ b/src/3rdparty/zlib/src/inftrees.h @@ -41,8 +41,8 @@ typedef struct { examples/enough.c found in the zlib distribution. The arguments to that program are the number of symbols, the initial root table size, and the maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the + returns 852, and "enough 30 6 15" for distance codes returns 592. The + initial root table size (9 or 6) is found in the fifth argument of the inflate_table() calls in inflate.c and infback.c. If the root table size is changed, then these maximum sizes would be need to be recalculated and updated. */ diff --git a/src/3rdparty/zlib/src/trees.c b/src/3rdparty/zlib/src/trees.c index 8dbdc40bacc..6a523ef34e3 100644 --- a/src/3rdparty/zlib/src/trees.c +++ b/src/3rdparty/zlib/src/trees.c @@ -1,5 +1,5 @@ /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2021 Jean-loup Gailly + * Copyright (C) 1995-2024 Jean-loup Gailly * detect_data_type() function provided freely by Cosmin Truta, 2006 * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -899,14 +899,19 @@ local void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { unsigned dist; /* distance of matched string */ int lc; /* match length or unmatched char (if dist == 0) */ - unsigned sx = 0; /* running index in sym_buf */ + unsigned sx = 0; /* running index in symbol buffers */ unsigned code; /* the code to send */ int extra; /* number of extra bits to send */ if (s->sym_next != 0) do { +#ifdef LIT_MEM + dist = s->d_buf[sx]; + lc = s->l_buf[sx++]; +#else dist = s->sym_buf[sx++] & 0xff; dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; lc = s->sym_buf[sx++]; +#endif if (dist == 0) { send_code(s, lc, ltree); /* send a literal byte */ Tracecv(isgraph(lc), (stderr," '%c' ", lc)); @@ -931,8 +936,12 @@ local void compress_block(deflate_state *s, const ct_data *ltree, } } /* literal or match pair ? */ - /* Check that the overlay between pending_buf and sym_buf is ok: */ + /* Check for no overlay of pending_buf on needed symbols */ +#ifdef LIT_MEM + Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow"); +#else Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow"); +#endif } while (sx < s->sym_next); @@ -1082,9 +1091,14 @@ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf, * the current block must be flushed. */ int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) { +#ifdef LIT_MEM + s->d_buf[s->sym_next] = (ush)dist; + s->l_buf[s->sym_next++] = (uch)lc; +#else s->sym_buf[s->sym_next++] = (uch)dist; s->sym_buf[s->sym_next++] = (uch)(dist >> 8); s->sym_buf[s->sym_next++] = (uch)lc; +#endif if (dist == 0) { /* lc is the unmatched char */ s->dyn_ltree[lc].Freq++; diff --git a/src/3rdparty/zlib/src/zconf.h b/src/3rdparty/zlib/src/zconf.h index 18be576f50d..4e14507a22d 100644 --- a/src/3rdparty/zlib/src/zconf.h +++ b/src/3rdparty/zlib/src/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -304,14 +304,6 @@ # endif #endif -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - /* The following definitions for FAR are needed only for MSDOS mixed * model programming (small or medium model with some far allocations). * This was tested only with MSC; for other MSDOS compilers you may have diff --git a/src/3rdparty/zlib/src/zlib.h b/src/3rdparty/zlib/src/zlib.h index ffe3b177e29..2cff72ee865 100644 --- a/src/3rdparty/zlib/src/zlib.h +++ b/src/3rdparty/zlib/src/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.3, August 18th, 2023 + version 1.3.1, January 22nd, 2024 - Copyright (C) 1995-2023 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -41,11 +41,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.3 (Qt)" -#define ZLIB_VERNUM 0x1300 +#define ZLIB_VERSION "1.3.1 (Qt)" +#define ZLIB_VERNUM 0x1310 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 3 -#define ZLIB_VER_REVISION 0 +#define ZLIB_VER_REVISION 1 #define ZLIB_VER_SUBREVISION 0 /* @@ -940,10 +940,10 @@ ZEXTERN int ZEXPORT inflateSync(z_streamp strm); inflateSync returns Z_OK if a possible full flush point has been found, Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. + In the success case, the application may save the current value of total_in + which indicates where valid compressed data was found. In the error case, + the application may repeatedly call inflateSync, providing more input each + time, until success or end of the input data. */ ZEXTERN int ZEXPORT inflateCopy(z_streamp dest, @@ -1762,14 +1762,14 @@ ZEXTERN uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2); seq1 and seq2 with lengths len1 and len2, CRC-32 check values were calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. + len2. len2 must be non-negative. */ /* ZEXTERN uLong ZEXPORT crc32_combine_gen(z_off_t len2); Return the operator corresponding to length len2, to be used with - crc32_combine_op(). + crc32_combine_op(). len2 must be non-negative. */ ZEXTERN uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op); diff --git a/src/3rdparty/zlib/src/zutil.h b/src/3rdparty/zlib/src/zutil.h index 9253060f74d..8608a05a107 100644 --- a/src/3rdparty/zlib/src/zutil.h +++ b/src/3rdparty/zlib/src/zutil.h @@ -1,5 +1,5 @@ /* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler + * Copyright (C) 1995-2024 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -64,7 +64,7 @@ typedef unsigned long ulg; extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] +#define ERR_MSG(err) z_errmsg[(err) < -6 || (err) > 2 ? 9 : 2 - (err)] #define ERR_RETURN(strm,err) \ return (strm->msg = ERR_MSG(err), (err)) @@ -145,22 +145,8 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # endif #endif -#if defined(MACOS) || defined(TARGET_OS_MAC) +#if defined(MACOS) # define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -// We need to include stdio.h here because zlib.h will include TargetConditionals.h -// This will define TARGET_OS_MAC that leads to this check. -// Since zutil.h will include gzguts.h and gzguts.h includes stdio.h -// AFTER check for fdopen we need to include stdio.h directly -# include -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif #endif #ifdef __acorn @@ -183,18 +169,6 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # define OS_CODE 19 #endif -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - #if defined(__BORLANDC__) && !defined(MSDOS) #pragma warn -8004 #pragma warn -8008 diff --git a/src/concurrent/qtconcurrentiteratekernel.cpp b/src/concurrent/qtconcurrentiteratekernel.cpp index 268db562465..60c8da49908 100644 --- a/src/concurrent/qtconcurrentiteratekernel.cpp +++ b/src/concurrent/qtconcurrentiteratekernel.cpp @@ -103,7 +103,7 @@ namespace QtConcurrent { */ BlockSizeManager::BlockSizeManager(QThreadPool *pool, int iterationCount) - : maxBlockSize(iterationCount / (pool->maxThreadCount() * 2)), + : maxBlockSize(iterationCount / (std::max(pool->maxThreadCount(), 1) * 2)), beforeUser(0), afterUser(0), m_blockSize(1) { } diff --git a/src/concurrent/qtconcurrentreducekernel.h b/src/concurrent/qtconcurrentreducekernel.h index 16842091da1..9ab2a72c7d0 100644 --- a/src/concurrent/qtconcurrentreducekernel.h +++ b/src/concurrent/qtconcurrentreducekernel.h @@ -153,7 +153,7 @@ class ReduceKernel public: ReduceKernel(QThreadPool *pool, ReduceOptions _reduceOptions) : reduceOptions(_reduceOptions), progress(0), resultsMapSize(0), - threadCount(pool->maxThreadCount()) + threadCount(std::max(pool->maxThreadCount(), 1)) { } void runReduce(ReduceFunctor &reduce, diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake index 5e96369df02..5b1d9c37689 100644 --- a/src/corelib/Qt6CoreMacros.cmake +++ b/src/corelib/Qt6CoreMacros.cmake @@ -2008,6 +2008,11 @@ function(__qt_propagate_generated_resource target resource_name generated_source set(resource_target "${target}_resources_${resource_count}") add_library("${resource_target}" OBJECT "${generated_source_code}") + set_target_properties(${resource_target} PROPERTIES + AUTOMOC FALSE + AUTOUIC FALSE + AUTORCC FALSE + ) target_compile_definitions("${resource_target}" PRIVATE "$" ) diff --git a/src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp b/src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp index cb6928b1296..3f5a573fa78 100644 --- a/src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_serialization_qcborstream.cpp @@ -316,12 +316,12 @@ { QString result; auto r = reader.readString(); - while (r.code == QCborStreamReader::Ok) { + while (r.status == QCborStreamReader::Ok) { result += r.data; r = reader.readString(); } - if (r.code == QCborStreamReader::Error) { + if (r.status == QCborStreamReader::Error) { // handle error condition result.clear(); } @@ -334,12 +334,12 @@ { QBytearray result; auto r = reader.readBytearray(); - while (r.code == QCborStreamReader::Ok) { + while (r.status == QCborStreamReader::Ok) { result += r.data; r = reader.readByteArray(); } - if (r.code == QCborStreamReader::Error) { + if (r.status == QCborStreamReader::Error) { // handle error condition result.clear(); } diff --git a/src/corelib/global/qendian.cpp b/src/corelib/global/qendian.cpp index cc9158e34da..f12f358adc3 100644 --- a/src/corelib/global/qendian.cpp +++ b/src/corelib/global/qendian.cpp @@ -480,8 +480,8 @@ QT_BEGIN_NAMESPACE The template parameter \c T must be a C++ integer type: \list \li 8-bit: char, signed char, unsigned char, qint8, quint8 - \li 16-bit: short, unsigned short, qint16, quint16, char16_t (C++11) - \li 32-bit: int, unsigned int, qint32, quint32, char32_t (C++11) + \li 16-bit: short, unsigned short, qint16, quint16, char16_t + \li 32-bit: int, unsigned int, qint32, quint32, char32_t \li 64-bit: long long, unsigned long long, qint64, quint64 \li platform-specific size: long, unsigned long \li pointer size: qintptr, quintptr, qptrdiff diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 26f3a0178d5..04e8c7734db 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -889,6 +889,7 @@ static const struct { const char * typeName; int typeNameLength; int type; } typ {nullptr, 0, QMetaType::UnknownType} }; +// NOLINTNEXTLINE(cppcoreguidelines-virtual-class-destructor): this is not a base class static const struct : QMetaTypeModuleHelper { template()) { v_construct(&d, val); } +#ifndef QT_BOOTSTRAPPED QVariant::QVariant(const QBitArray &val) : d(QMetaType::fromType()) { v_construct(&d, val); } +#endif QVariant::QVariant(const QString &val) : d(QMetaType::fromType()) { v_construct(&d, val); } @@ -1792,6 +1794,7 @@ QChar QVariant::toChar() const return qvariant_cast(*this); } +#ifndef QT_BOOTSTRAPPED /*! Returns the variant as a QBitArray if the variant has userType() \l QMetaType::QBitArray; otherwise returns an empty bit array. @@ -1802,6 +1805,7 @@ QBitArray QVariant::toBitArray() const { return qvariant_cast(*this); } +#endif // QT_BOOTSTRAPPED template inline T qNumVariantToHelper(const QVariant::Private &d, bool *ok, const T& val) diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index 5e776707ce2..fde6a2a8189 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -194,7 +194,9 @@ class Q_CORE_EXPORT QVariant #endif QVariant(const QByteArray &bytearray); +#ifndef QT_BOOTSTRAPPED QVariant(const QBitArray &bitarray); +#endif QVariant(const QString &string); QVariant(QLatin1String string); QVariant(const QStringList &stringlist); @@ -281,7 +283,9 @@ class Q_CORE_EXPORT QVariant float toFloat(bool *ok = nullptr) const; qreal toReal(bool *ok = nullptr) const; QByteArray toByteArray() const; +#ifndef QT_BOOTSTRAPPED QBitArray toBitArray() const; +#endif QString toString() const; QStringList toStringList() const; QChar toChar() const; diff --git a/src/corelib/serialization/qdatastream.h b/src/corelib/serialization/qdatastream.h index dc4e7da51bd..a192b43d928 100644 --- a/src/corelib/serialization/qdatastream.h +++ b/src/corelib/serialization/qdatastream.h @@ -45,6 +45,8 @@ #include #include +#include // std::distance(), std::next() + #ifdef Status #error qdatastream.h must be included before any header file that defines Status #endif diff --git a/src/corelib/text/qregularexpression.cpp b/src/corelib/text/qregularexpression.cpp index 55ad29c7448..23cf86e2903 100644 --- a/src/corelib/text/qregularexpression.cpp +++ b/src/corelib/text/qregularexpression.cpp @@ -3012,7 +3012,8 @@ static const char *pcreCompileErrorCodes[] = QT_TRANSLATE_NOOP("QRegularExpression", "heap limit exceeded"), QT_TRANSLATE_NOOP("QRegularExpression", "invalid syntax"), QT_TRANSLATE_NOOP("QRegularExpression", "internal error - duplicate substitution match"), - QT_TRANSLATE_NOOP("QRegularExpression", "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching") + QT_TRANSLATE_NOOP("QRegularExpression", "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching"), + QT_TRANSLATE_NOOP("QRegularExpression", "INTERNAL ERROR: invalid substring offset") }; #endif // #if 0 diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp index 15d540fa394..a8613a77bd0 100644 --- a/src/corelib/text/qstring.cpp +++ b/src/corelib/text/qstring.cpp @@ -2394,15 +2394,17 @@ QString::QString(QChar ch) /*! \fn QString::QString(const QByteArray &ba) Constructs a string initialized with the byte array \a ba. The - given byte array is converted to Unicode using fromUtf8(). Stops - copying at the first 0 character, otherwise copies the entire byte - array. + given byte array is converted to Unicode using fromUtf8(). You can disable this constructor by defining \l QT_NO_CAST_FROM_ASCII when you compile your applications. This can be useful if you want to ensure that all user-visible strings go through QObject::tr(), for example. + \note: any null ('\\0') bytes in the byte array will be included in this + string, converted to Unicode null characters (U+0000). This behavior is + different from Qt 5.x. + \sa fromLatin1(), fromLocal8Bit(), fromUtf8() */ @@ -2668,8 +2670,7 @@ QString &QString::operator=(QLatin1String other) \overload operator=() Assigns \a ba to this string. The byte array is converted to Unicode - using the fromUtf8() function. This function stops conversion at the - first NUL character found, or the end of the \a ba byte array. + using the fromUtf8() function. You can disable this operator by defining \l QT_NO_CAST_FROM_ASCII when you compile your applications. This @@ -3660,8 +3661,7 @@ QString &QString::replace(QChar c, QLatin1String after, Qt::CaseSensitivity cs) \overload operator==() The \a other byte array is converted to a QString using the - fromUtf8() function. This function stops conversion at the - first NUL character found, or the end of the byte array. + fromUtf8() function. You can disable this operator by defining \l QT_NO_CAST_FROM_ASCII when you compile your applications. This @@ -5345,6 +5345,9 @@ QList QtPrivate::convertToUcs4(QStringView string) \since 6.0 Returns a QString initialized with the Latin-1 string \a str. + + \note: any null ('\\0') bytes in the byte array will be included in this + string, converted to Unicode null characters (U+0000). */ QString QString::fromLatin1(QByteArrayView ba) { @@ -5380,6 +5383,10 @@ QString QString::fromLatin1(QByteArrayView ba) \since 5.0 Returns a QString initialized with the Latin-1 string \a str. + + \note: any null ('\\0') bytes in the byte array will be included in this + string, converted to Unicode null characters (U+0000). This behavior is + different from Qt 5.x. */ /*! @@ -5401,6 +5408,10 @@ QString QString::fromLatin1(QByteArrayView ba) \since 5.0 Returns a QString initialized with the 8-bit string \a str. + + \note: any null ('\\0') bytes in the byte array will be included in this + string, converted to Unicode null characters (U+0000). This behavior is + different from Qt 5.x. */ /*! @@ -5409,6 +5420,9 @@ QString QString::fromLatin1(QByteArrayView ba) \since 6.0 Returns a QString initialized with the 8-bit string \a str. + + \note: any null ('\\0') bytes in the byte array will be included in this + string, converted to Unicode null characters (U+0000). */ QString QString::fromLocal8Bit(QByteArrayView ba) { @@ -5463,6 +5477,10 @@ QString QString::fromLocal8Bit(QByteArrayView ba) \since 5.0 Returns a QString initialized with the UTF-8 string \a str. + + \note: any null ('\\0') bytes in the byte array will be included in this + string, converted to Unicode null characters (U+0000). This behavior is + different from Qt 5.x. */ /*! @@ -5471,6 +5489,9 @@ QString QString::fromLocal8Bit(QByteArrayView ba) \since 6.0 Returns a QString initialized with the UTF-8 string \a str. + + \note: any null ('\\0') bytes in the byte array will be included in this + string, converted to Unicode null characters (U+0000). */ QString QString::fromUtf8(QByteArrayView ba) { @@ -8995,6 +9016,10 @@ QString &QString::setRawData(const QChar *unicode, qsizetype size) guarantee that \a str will not be deleted or modified as long as the QLatin1String object exists. + \note: any null ('\\0') bytes in the byte array will be included in this + string, which will be converted to Unicode null characters (U+0000) if this + string is used by QString. This behavior is different from Qt 5.x. + \sa latin1() */ @@ -9027,6 +9052,24 @@ QString &QString::setRawData(const QChar *unicode, qsizetype size) \sa latin1() */ +/*! \fn QLatin1String::QLatin1String(QByteArrayView str) + \since 6.3 + + Constructs a QLatin1String object that stores \a str. + + The string data is \e not copied. The caller must be able to + guarantee that the data which \a str is pointing to will not + be deleted or modified as long as the QLatin1String object + exists. The size is obtained from \a str as-is, without checking + for a null-terminator. + + \note: any null ('\\0') bytes in the byte array will be included in this + string, which will be converted to Unicode null characters (U+0000) if this + string is used by QString. + + \sa latin1() +*/ + /*! \fn QString QLatin1String::toString() const \since 6.0 diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp index 986b12f797e..266b401e5f2 100644 --- a/src/corelib/thread/qatomic.cpp +++ b/src/corelib/thread/qatomic.cpp @@ -68,8 +68,8 @@ The template parameter \c T must be a C++ integer type: \list \li 8-bit: bool, char, signed char, unsigned char, qint8, quint8, char8_t (C++20) - \li 16-bit: short, unsigned short, qint16, quint16, char16_t (C++11) - \li 32-bit: int, unsigned int, qint32, quint32, char32_t (C++11) + \li 16-bit: short, unsigned short, qint16, quint16, char16_t + \li 32-bit: int, unsigned int, qint32, quint32, char32_t \li 64-bit: long long, unsigned long long, qint64, quint64 \li platform-specific size: long, unsigned long \li pointer size: qintptr, quintptr, qptrdiff diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp index a389226a683..b88c7a87bf2 100644 --- a/src/corelib/time/qdatetime.cpp +++ b/src/corelib/time/qdatetime.cpp @@ -1084,12 +1084,14 @@ QString QDate::toString(Qt::DateFormat format) const /*! \fn QString QDate::toString(const QString &format, QCalendar cal) const \fn QString QDate::toString(QStringView format, QCalendar cal) const + \since 5.14 Returns the date as a string. The \a format parameter determines the format of the result string. If \a cal is supplied, it determines the calendar used - to represent the date; it defaults to Gregorian. + to represent the date; it defaults to Gregorian. Prior to Qt 5.14, there was + no \a cal parameter and the Gregorian calendar was always used. - These expressions may be used: + These expressions may be used in the \a format parameter: \table \header \li Expression \li Output @@ -1134,7 +1136,6 @@ QString QDate::toString(Qt::DateFormat format) const QLocale::system().toString(). \sa fromString(), QDateTime::toString(), QTime::toString(), QLocale::toString() - */ QString QDate::toString(QStringView format, QCalendar cal) const { @@ -4190,12 +4191,14 @@ QString QDateTime::toString(Qt::DateFormat format) const /*! \fn QString QDateTime::toString(const QString &format, QCalendar cal) const \fn QString QDateTime::toString(QStringView format, QCalendar cal) const + \since 5.14 Returns the datetime as a string. The \a format parameter determines the - format of the result string. If \a cal is supplied, it determines the calendar - used to represent the date; it defaults to Gregorian. See QTime::toString() - and QDate::toString() for the supported specifiers for time and date, - respectively. + format of the result string. If \a cal is supplied, it determines the + calendar used to represent the date; it defaults to Gregorian. Prior to Qt + 5.14, there was no \a cal parameter and the Gregorian calendar was always + used. See QTime::toString() and QDate::toString() for the supported + specifiers for time and date, respectively, in the \a format parameter. Any sequence of characters enclosed in single quotes will be included verbatim in the output string (stripped of the quotes), even if it contains diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h index e4250cce476..f9877374d11 100644 --- a/src/corelib/tools/qarraydata.h +++ b/src/corelib/tools/qarraydata.h @@ -43,6 +43,7 @@ #include #include +#include #include QT_BEGIN_NAMESPACE diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index 18ce7035d94..4cf9ed260c4 100644 --- a/src/corelib/tools/qbitarray.cpp +++ b/src/corelib/tools/qbitarray.cpp @@ -43,6 +43,9 @@ #include #include #include + +#include + #include QT_BEGIN_NAMESPACE @@ -140,12 +143,33 @@ QT_BEGIN_NAMESPACE * inline qsizetype size() const { return (d.size() << 3) - *d.constData(); } */ +static constexpr qsizetype storage_size(qsizetype size) +{ + // avoid overflow when adding 7, by doing the arithmetic in unsigned space: + return qsizetype((size_t(size) + 7) / 8); +} + +static constexpr qsizetype allocation_size(qsizetype size) +{ + return size <= 0 ? 0 : storage_size(size) + 1; +} + +static void adjust_head_and_tail(char *data, qsizetype storageSize, qsizetype logicalSize) +{ + quint8 *c = reinterpret_cast(data); + // store the difference between storage and logical size in d[0]: + *c = quint8(size_t(storageSize) * 8 - logicalSize); + // reset unallocated bits to 0: + if (logicalSize & 7) + *(c + 1 + logicalSize / 8) &= (1 << (logicalSize & 7)) - 1; +} + /*! Constructs a bit array containing \a size bits. The bits are initialized with \a value, which defaults to false (0). */ QBitArray::QBitArray(qsizetype size, bool value) - : d(size <= 0 ? 0 : 1 + (size + 7) / 8, Qt::Uninitialized) + : d(allocation_size(size), Qt::Uninitialized) { Q_ASSERT_X(size >= 0, "QBitArray::QBitArray", "Size must be greater than or equal to 0."); if (size <= 0) @@ -153,9 +177,7 @@ QBitArray::QBitArray(qsizetype size, bool value) uchar *c = reinterpret_cast(d.data()); memset(c + 1, value ? 0xff : 0, d.size() - 1); - *c = d.size() * 8 - size; - if (value && size && size & 7) - *(c + 1 + size / 8) &= (1 << (size & 7)) - 1; + adjust_head_and_tail(d.data(), d.size(), size); } /*! \fn qsizetype QBitArray::size() const @@ -223,13 +245,11 @@ void QBitArray::resize(qsizetype size) d.resize(0); } else { qsizetype s = d.size(); - d.resize(1 + (size + 7) / 8); + d.resize(allocation_size(size)); uchar *c = reinterpret_cast(d.data()); - if (size > (s << 3)) + if (d.size() > s) memset(c + s, 0, d.size() - s); - else if (size & 7) - *(c + 1 + size / 8) &= (1 << (size & 7)) - 1; - *c = d.size() * 8 - size; + adjust_head_and_tail(d.data(), d.size(), size); } } @@ -328,17 +348,11 @@ QBitArray QBitArray::fromBits(const char *data, qsizetype size) QBitArray result; if (size == 0) return result; - qsizetype nbytes = (size + 7) / 8; - result.d = QByteArray(nbytes + 1, Qt::Uninitialized); - char *bits = result.d.data(); - memcpy(bits + 1, data, nbytes); - - // clear any unused bits from the last byte - if (size & 7) - bits[nbytes] &= 0xffU >> (8 - (size & 7)); - - *bits = result.d.size() * 8 - size; + auto &d = result.d; + d.resize(allocation_size(size)); + memcpy(d.data() + 1, data, d.size() - 1); + adjust_head_and_tail(d.data(), d.size(), size); return result; } @@ -769,19 +783,19 @@ QBitArray operator^(const QBitArray &a1, const QBitArray &a2) QDataStream &operator<<(QDataStream &out, const QBitArray &ba) { + const qsizetype len = ba.size(); if (out.version() < QDataStream::Qt_6_0) { - quint32 len = ba.size(); - out << len; - if (len > 0) - out.writeRawData(ba.d.constData() + 1, ba.d.size() - 1); - return out; + if (Q_UNLIKELY(len > qsizetype{(std::numeric_limits::max)()})) { + out.setStatus(QDataStream::WriteFailed); // ### SizeLimitExceeded + return out; + } + out << quint32(len); } else { - quint64 len = ba.size(); - out << len; - if (len > 0) - out.writeRawData(ba.d.constData() + 1, ba.d.size() - 1); - return out; + out << quint64(len); } + if (len > 0) + out.writeRawData(ba.d.data() + 1, ba.d.size() - 1); + return out; } /*! @@ -799,10 +813,18 @@ QDataStream &operator>>(QDataStream &in, QBitArray &ba) if (in.version() < QDataStream::Qt_6_0) { quint32 tmp; in >> tmp; + if (Q_UNLIKELY(tmp > quint32((std::numeric_limits::max)()))) { + in.setStatus(QDataStream::ReadCorruptData); + return in; + } len = tmp; } else { quint64 tmp; in >> tmp; + if (Q_UNLIKELY(tmp > quint64((std::numeric_limits::max)()))) { + in.setStatus(QDataStream::ReadCorruptData); // ### SizeLimitExeeded + return in; + } len = tmp; } if (len == 0) { @@ -811,7 +833,7 @@ QDataStream &operator>>(QDataStream &in, QBitArray &ba) } const qsizetype Step = 8 * 1024 * 1024; - qsizetype totalBytes = (len + 7) / 8; + const qsizetype totalBytes = storage_size(len); qsizetype allocated = 0; while (allocated < totalBytes) { @@ -825,14 +847,13 @@ QDataStream &operator>>(QDataStream &in, QBitArray &ba) allocated += blockSize; } - qsizetype paddingMask = ~((0x1 << (len & 0x7)) - 1); - if (paddingMask != ~0x0 && (ba.d.constData()[ba.d.size() - 1] & paddingMask)) { + const auto fromStream = ba.d.back(); + adjust_head_and_tail(ba.d.data(), ba.d.size(), len); + if (ba.d.back() != fromStream) { ba.clear(); in.setStatus(QDataStream::ReadCorruptData); return in; } - - *ba.d.data() = ba.d.size() * 8 - len; return in; } #endif // QT_NO_DATASTREAM diff --git a/src/corelib/tools/qbitarray.h b/src/corelib/tools/qbitarray.h index 4466fbc9c05..79e54b84819 100644 --- a/src/corelib/tools/qbitarray.h +++ b/src/corelib/tools/qbitarray.h @@ -64,8 +64,8 @@ public: void swap(QBitArray &other) noexcept { d.swap(other.d); } - inline qsizetype size() const { return (d.size() << 3) - *d.constData(); } - inline qsizetype count() const { return (d.size() << 3) - *d.constData(); } + qsizetype size() const { return qsizetype((size_t(d.size()) << 3) - *d.constData()); } + qsizetype count() const { return size(); } qsizetype count(bool on) const; inline bool isEmpty() const { return d.isEmpty(); } @@ -77,15 +77,15 @@ public: inline bool isDetached() const { return d.isDetached(); } inline void clear() { d.clear(); } - bool testBit(qsizetype i) const; - void setBit(qsizetype i); - void setBit(qsizetype i, bool val); - void clearBit(qsizetype i); - bool toggleBit(qsizetype i); + inline bool testBit(qsizetype i) const; + inline void setBit(qsizetype i); + inline void setBit(qsizetype i, bool val); + inline void clearBit(qsizetype i); + inline bool toggleBit(qsizetype i); - bool at(qsizetype i) const; - QBitRef operator[](qsizetype i); - bool operator[](qsizetype i) const; + inline bool at(qsizetype i) const; + inline QBitRef operator[](qsizetype i); + inline bool operator[](qsizetype i) const; QBitArray &operator&=(const QBitArray &); QBitArray &operator|=(const QBitArray &); @@ -110,35 +110,35 @@ public: inline DataPtr &data_ptr() { return d.data_ptr(); } }; -inline bool QBitArray::fill(bool aval, qsizetype asize) +bool QBitArray::fill(bool aval, qsizetype asize) { *this = QBitArray((asize < 0 ? this->size() : asize), aval); return true; } Q_CORE_EXPORT QBitArray operator&(const QBitArray &, const QBitArray &); Q_CORE_EXPORT QBitArray operator|(const QBitArray &, const QBitArray &); Q_CORE_EXPORT QBitArray operator^(const QBitArray &, const QBitArray &); -inline bool QBitArray::testBit(qsizetype i) const +bool QBitArray::testBit(qsizetype i) const { Q_ASSERT(size_t(i) < size_t(size())); return (*(reinterpret_cast(d.constData())+1+(i>>3)) & (1 << (i & 7))) != 0; } -inline void QBitArray::setBit(qsizetype i) +void QBitArray::setBit(qsizetype i) { Q_ASSERT(size_t(i) < size_t(size())); *(reinterpret_cast(d.data())+1+(i>>3)) |= uchar(1 << (i & 7)); } -inline void QBitArray::clearBit(qsizetype i) +void QBitArray::clearBit(qsizetype i) { Q_ASSERT(size_t(i) < size_t(size())); *(reinterpret_cast(d.data())+1+(i>>3)) &= ~uchar(1 << (i & 7)); } -inline void QBitArray::setBit(qsizetype i, bool val) +void QBitArray::setBit(qsizetype i, bool val) { if (val) setBit(i); else clearBit(i); } -inline bool QBitArray::toggleBit(qsizetype i) +bool QBitArray::toggleBit(qsizetype i) { Q_ASSERT(size_t(i) < size_t(size())); uchar b = uchar(1<<(i&7)); uchar* p = reinterpret_cast(d.data())+1+(i>>3); uchar c = uchar(*p&b); *p^=b; return c!=0; } -inline bool QBitArray::operator[](qsizetype i) const { return testBit(i); } -inline bool QBitArray::at(qsizetype i) const { return testBit(i); } +bool QBitArray::operator[](qsizetype i) const { return testBit(i); } +bool QBitArray::at(qsizetype i) const { return testBit(i); } class Q_CORE_EXPORT QBitRef { @@ -155,7 +155,7 @@ public: QBitRef &operator=(bool val) { a.setBit(i, val); return *this; } }; -inline QBitRef QBitArray::operator[](qsizetype i) +QBitRef QBitArray::operator[](qsizetype i) { Q_ASSERT(i >= 0); return QBitRef(*this, i); } #ifndef QT_NO_DATASTREAM diff --git a/src/corelib/tools/qcommandlineoption.cpp b/src/corelib/tools/qcommandlineoption.cpp index bfb6f68f08b..812e68a815f 100644 --- a/src/corelib/tools/qcommandlineoption.cpp +++ b/src/corelib/tools/qcommandlineoption.cpp @@ -152,8 +152,7 @@ QCommandLineOption::QCommandLineOption(const QStringList &names) The default value for the option is set to \a defaultValue. In Qt versions before 5.4, this constructor was \c explicit. In Qt 5.4 - and later, it no longer is and can be used for C++11-style uniform - initialization: + and later, it no longer is and can be used for uniform initialization: \snippet code/src_corelib_tools_qcommandlineoption.cpp cxx11-init @@ -188,8 +187,7 @@ QCommandLineOption::QCommandLineOption(const QString &name, const QString &descr The default value for the option is set to \a defaultValue. In Qt versions before 5.4, this constructor was \c explicit. In Qt 5.4 - and later, it no longer is and can be used for C++11-style uniform - initialization: + and later, it no longer is and can be used for uniform initialization: \snippet code/src_corelib_tools_qcommandlineoption.cpp cxx11-init-list diff --git a/src/corelib/tools/qcontainerfwd.h b/src/corelib/tools/qcontainerfwd.h index 673e3c3de23..84ba6ddc197 100644 --- a/src/corelib/tools/qcontainerfwd.h +++ b/src/corelib/tools/qcontainerfwd.h @@ -57,7 +57,8 @@ using QPair = std::pair; template class QQueue; template class QSet; template class QStack; -template class QVarLengthArray; +constexpr qsizetype QVarLengthArrayDefaultPrealloc = 256; +template class QVarLengthArray; template class QList; #ifndef Q_CLANG_QDOC template using QVector = QList; diff --git a/src/corelib/tools/qflatmap_p.h b/src/corelib/tools/qflatmap_p.h index 4f8ad3787b0..09ba50fac2c 100644 --- a/src/corelib/tools/qflatmap_p.h +++ b/src/corelib/tools/qflatmap_p.h @@ -1008,7 +1008,9 @@ private: containers c; }; -template> +template > using QVarLengthFlatMap = QFlatMap, QVarLengthArray>; QT_END_NAMESPACE diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 975af3bda56..260fd8f6c84 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -702,6 +702,7 @@ size_t qHash(QStringView key, size_t seed) noexcept return qHashBits(key.data(), key.size()*sizeof(QChar), seed); } +#ifndef QT_BOOTSTRAPPED size_t qHash(const QBitArray &bitArray, size_t seed) noexcept { qsizetype m = bitArray.d.size() - 1; @@ -714,6 +715,7 @@ size_t qHash(const QBitArray &bitArray, size_t seed) noexcept result = ((result << 4) + bitArray.d.at(m)) & ((1 << n) - 1); return result; } +#endif size_t qHash(QLatin1String key, size_t seed) noexcept { @@ -2739,9 +2741,6 @@ size_t qHash(long double key, size_t seed) noexcept Constructs a multi-hash with a copy of each of the elements in the initializer list \a list. - - This function is only available if the program is being - compiled in C++11 mode. */ /*! \fn template QMultiHash::QMultiHash(const QHash &other) diff --git a/src/corelib/tools/qhashfunctions.h b/src/corelib/tools/qhashfunctions.h index 73ce102b25e..a64920423c7 100644 --- a/src/corelib/tools/qhashfunctions.h +++ b/src/corelib/tools/qhashfunctions.h @@ -187,7 +187,9 @@ Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(const QByteArrayView &key, size_ Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(QStringView key, size_t seed = 0) noexcept; inline Q_DECL_PURE_FUNCTION size_t qHash(const QString &key, size_t seed = 0) noexcept { return qHash(QStringView{key}, seed); } +#ifndef QT_BOOTSTRAPPED Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(const QBitArray &key, size_t seed = 0) noexcept; +#endif Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(QLatin1String key, size_t seed = 0) noexcept; Q_DECL_CONST_FUNCTION constexpr inline size_t qHash(QKeyCombination key, size_t seed = 0) noexcept { return qHash(key.toCombined(), seed); } @@ -342,7 +344,9 @@ QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_CREF(QString) QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_VALUE(QStringView) QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_VALUE(QLatin1String) QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_CREF(QByteArray) +#ifndef QT_BOOTSTRAPPED QT_SPECIALIZE_STD_HASH_TO_CALL_QHASH_BY_CREF(QBitArray) +#endif QT_END_NAMESPACE diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 1c45d54ecee..7903f4ea4d1 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -211,7 +211,7 @@ last QSharedPointer instance had. This class is never instantiated directly: the constructors and - destructor are private and, in C++11, deleted. Only the create() function + destructor are deleted. Only the create() function may be called to return an object of this type. See below for construction details. @@ -250,8 +250,7 @@ Like ExternalRefCountWithCustomDeleter, this class is never instantiated directly. This class also provides a create() member that returns the - pointer, and hides its constructors and destructor. With C++11, they're - deleted. + pointer, and deletes its constructors and destructor. The size of this class depends on the size of \tt T. diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc index 117be578981..c07fe83a14b 100644 --- a/src/corelib/tools/qvarlengtharray.qdoc +++ b/src/corelib/tools/qvarlengtharray.qdoc @@ -110,9 +110,6 @@ \since 5.5 Constructs an array from the std::initializer_list given by \a args. - - This constructor is only enabled if the compiler supports C++11 initializer - lists. */ /*! \fn template template QVarLengthArray::QVarLengthArray(InputIterator first, InputIterator last) @@ -419,9 +416,6 @@ \since 5.5 Assigns the values of \a list to this array, and returns a reference to this array. - - This constructor is only enabled if the compiler supports C++11 initializer - lists. */ /*! \fn template QVarLengthArray::QVarLengthArray(const QVarLengthArray &other) diff --git a/src/corelib/tools/qversionnumber.cpp b/src/corelib/tools/qversionnumber.cpp index 8790b80c1ed..ef0406709e2 100644 --- a/src/corelib/tools/qversionnumber.cpp +++ b/src/corelib/tools/qversionnumber.cpp @@ -105,18 +105,13 @@ QT_BEGIN_NAMESPACE \fn QVersionNumber::QVersionNumber(QList &&seg) Move-constructs a version number from the list of numbers contained in \a seg. - - This constructor is only enabled if the compiler supports C++11 move semantics. */ /*! \fn QVersionNumber::QVersionNumber(std::initializer_list args) - Construct a version number from the std::initializer_list specified by + Constructs a version number from the std::initializer_list specified by \a args. - - This constructor is only enabled if the compiler supports C++11 initializer - lists. */ /*! diff --git a/src/dbus/qdbusutil.cpp b/src/dbus/qdbusutil.cpp index 8322ff02c4f..55d2ded2e79 100644 --- a/src/dbus/qdbusutil.cpp +++ b/src/dbus/qdbusutil.cpp @@ -244,6 +244,21 @@ static const char oneLetterTypes[] = "vsogybnqiuxtdh"; static const char basicTypes[] = "sogybnqiuxtdh"; static const char fixedTypes[] = "ybnqiuxtdh"; +/* + D-Bus signature grammar (in ABNF), as of 0.42 (2023-08-21): + https://dbus.freedesktop.org/doc/dbus-specification.html#type-system + + = * + = / / / + = "y" / "b" / "n" / "q" / "i" / "u" / "x" / "t" / "d" / "h" + = "s" / "o" / "g" + = / + = "v" + = "(" 1* ")" + = "a" ( / ) + = "{" "}" +*/ + static bool isBasicType(int c) { return c != DBUS_TYPE_INVALID && strchr(basicTypes, c) != nullptr; @@ -347,13 +362,6 @@ namespace QDBusUtil return true; } - /*! - \internal - \fn bool isValidPartOfObjectPath(const QString &part) - - \overload - */ - /*! \fn bool isValidInterfaceName(const QString &ifaceName) Returns \c true if this is \a ifaceName is a valid interface name. @@ -413,12 +421,6 @@ namespace QDBusUtil return true; } - /*! - \fn bool isValidUniqueConnectionName(const QString &connName) - - \overload - */ - /*! \fn bool isValidBusName(const QString &busName) Returns \c true if \a busName is a valid bus name. @@ -481,12 +483,6 @@ namespace QDBusUtil return true; } - /*! - \fn bool isValidMemberName(const QString &memberName) - - \overload - */ - /*! \fn bool isValidErrorName(const QString &errorName) Returns \c true if \a errorName is a valid error name. Valid error names are valid interface diff --git a/src/gui/accessible/windows/apisupport/uiaclientinterfaces_p.h b/src/gui/accessible/windows/apisupport/uiaclientinterfaces_p.h index a4f3e15baa5..8ab2bf67ae1 100644 --- a/src/gui/accessible/windows/apisupport/uiaclientinterfaces_p.h +++ b/src/gui/accessible/windows/apisupport/uiaclientinterfaces_p.h @@ -52,6 +52,7 @@ // #include +#include "uiatypes_p.h" #ifndef __IUIAutomationElement_INTERFACE_DEFINED__ @@ -66,6 +67,8 @@ struct IUIAutomationFocusChangedEventHandler; struct IUIAutomationProxyFactory; struct IUIAutomationProxyFactoryEntry; struct IUIAutomationProxyFactoryMapping; +struct IUIAutomationTextRangeArray; +struct IUIAutomationTextRange; #ifndef __IAccessible_FWD_DEFINED__ #define __IAccessible_FWD_DEFINED__ struct IAccessible; @@ -261,6 +264,59 @@ __CRT_UUID_DECL(IUIAutomationTreeWalker, 0x4042c624, 0x389c, 0x4afc, 0xa6,0x30, #endif #endif + +#ifndef __IUIAutomationTextPattern_INTERFACE_DEFINED__ +#define __IUIAutomationTextPattern_INTERFACE_DEFINED__ +DEFINE_GUID(IID_IUIAutomationTextPattern, 0x32eba289, 0x3583, 0x42c9, 0x9c,0x59, 0x3b, 0x6d, 0x9a, 0x1e, 0x9b, 0x6a); +MIDL_INTERFACE("32eba289-3583-42c9-9c59-3b6d9a1e9b6a") +IUIAutomationTextPattern : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE RangeFromPoint(POINT pt, __RPC__deref_out_opt IUIAutomationTextRange **range) = 0; + virtual HRESULT STDMETHODCALLTYPE RangeFromChild(__RPC__in_opt IUIAutomationElement *child, __RPC__deref_out_opt IUIAutomationTextRange **range) = 0; + virtual HRESULT STDMETHODCALLTYPE GetSelection(__RPC__deref_out_opt IUIAutomationTextRangeArray **ranges) = 0; + virtual HRESULT STDMETHODCALLTYPE GetVisibleRanges(__RPC__deref_out_opt IUIAutomationTextRangeArray **ranges) = 0; + virtual HRESULT STDMETHODCALLTYPE get_DocumentRange(__RPC__deref_out_opt IUIAutomationTextRange **range) = 0; + virtual HRESULT STDMETHODCALLTYPE get_SupportedTextSelection(__RPC__out enum SupportedTextSelection *supportedTextSelection) = 0; +}; +#ifdef __CRT_UUID_DECL +__CRT_UUID_DECL(IUIAutomationTextPattern, 0x32eba289, 0x3583, 0x42c9, 0x9c,0x59, 0x3b, 0x6d, 0x9a, 0x1e, 0x9b, 0x6a) +#endif +#endif + + +#ifndef __IUIAutomationTextRange_INTERFACE_DEFINED__ +#define __IUIAutomationTextRange_INTERFACE_DEFINED__ +DEFINE_GUID(IID_IUIAutomationTextRange, 0xa543cc6a, 0xf4ae, 0x494b, 0x82,0x39, 0xc8, 0x14, 0x48, 0x11, 0x87, 0xa8); +MIDL_INTERFACE("a543cc6a-f4ae-494b-8239-c814481187a8") +IUIAutomationTextRange : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE Clone(__RPC__deref_out_opt IUIAutomationTextRange **clonedRange) = 0; + virtual HRESULT STDMETHODCALLTYPE Compare(__RPC__in_opt IUIAutomationTextRange *range, __RPC__out BOOL *areSame) = 0; + virtual HRESULT STDMETHODCALLTYPE CompareEndpoints(enum TextPatternRangeEndpoint srcEndPoint, __RPC__in_opt IUIAutomationTextRange *range, enum TextPatternRangeEndpoint targetEndPoint, __RPC__out int *compValue) = 0; + virtual HRESULT STDMETHODCALLTYPE ExpandToEnclosingUnit(enum TextUnit textUnit) = 0; + virtual HRESULT STDMETHODCALLTYPE FindAttribute(TEXTATTRIBUTEID attr, VARIANT val, BOOL backward, __RPC__deref_out_opt IUIAutomationTextRange **found) = 0; + virtual HRESULT STDMETHODCALLTYPE FindText(__RPC__in BSTR text, BOOL backward, BOOL ignoreCase, __RPC__deref_out_opt IUIAutomationTextRange **found) = 0; + virtual HRESULT STDMETHODCALLTYPE GetAttributeValue(TEXTATTRIBUTEID attr, __RPC__out VARIANT *value) = 0; + virtual HRESULT STDMETHODCALLTYPE GetBoundingRectangles(__RPC__deref_out_opt SAFEARRAY * *boundingRects) = 0; + virtual HRESULT STDMETHODCALLTYPE GetEnclosingElement(__RPC__deref_out_opt IUIAutomationElement **enclosingElement) = 0; + virtual HRESULT STDMETHODCALLTYPE GetText(int maxLength, __RPC__deref_out_opt BSTR *text) = 0; + virtual HRESULT STDMETHODCALLTYPE Move(enum TextUnit unit, int count, __RPC__out int *moved) = 0; + virtual HRESULT STDMETHODCALLTYPE MoveEndpointByUnit(enum TextPatternRangeEndpoint endpoint, enum TextUnit unit, int count, __RPC__out int *moved) = 0; + virtual HRESULT STDMETHODCALLTYPE MoveEndpointByRange(enum TextPatternRangeEndpoint srcEndPoint, __RPC__in_opt IUIAutomationTextRange *range, enum TextPatternRangeEndpoint targetEndPoint) = 0; + virtual HRESULT STDMETHODCALLTYPE Select( void) = 0; + virtual HRESULT STDMETHODCALLTYPE AddToSelection( void) = 0; + virtual HRESULT STDMETHODCALLTYPE RemoveFromSelection( void) = 0; + virtual HRESULT STDMETHODCALLTYPE ScrollIntoView(BOOL alignToTop) = 0; + virtual HRESULT STDMETHODCALLTYPE GetChildren(__RPC__deref_out_opt IUIAutomationElementArray **children) = 0; +}; +#ifdef __CRT_UUID_DECL +__CRT_UUID_DECL(IUIAutomationTextRange, 0xa543cc6a, 0xf4ae, 0x494b, 0x82,0x39, 0xc8, 0x14, 0x48, 0x11, 0x87, 0xa8) +#endif +#endif + + DEFINE_GUID(CLSID_CUIAutomation, 0xff48dba4, 0x60ef, 0x4201, 0xaa,0x87, 0x54,0x10,0x3e,0xef,0x59,0x4e); #endif diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 662be6abc96..c0a8947e71e 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4834,14 +4834,24 @@ QImage QImage::transformed(const QTransform &matrix, Qt::TransformationMode mode || (ws * hs) >= (1<<20) #endif ) { + QImage scaledImage; if (mat.m11() < 0.0F && mat.m22() < 0.0F) { // horizontal/vertical flip - return smoothScaled(wd, hd).mirrored(true, true).convertToFormat(format()); + scaledImage = smoothScaled(wd, hd).mirrored(true, true); } else if (mat.m11() < 0.0F) { // horizontal flip - return smoothScaled(wd, hd).mirrored(true, false).convertToFormat(format()); + scaledImage = smoothScaled(wd, hd).mirrored(true, false); } else if (mat.m22() < 0.0F) { // vertical flip - return smoothScaled(wd, hd).mirrored(false, true).convertToFormat(format()); + scaledImage = smoothScaled(wd, hd).mirrored(false, true); } else { // no flipping - return smoothScaled(wd, hd).convertToFormat(format()); + scaledImage = smoothScaled(wd, hd); + } + + switch (format()) { + case QImage::Format_Mono: + case QImage::Format_MonoLSB: + case QImage::Format_Indexed8: + return scaledImage; + default: + return scaledImage.convertToFormat(format()); } } } diff --git a/src/gui/image/qimageiohandler.cpp b/src/gui/image/qimageiohandler.cpp index 8f589cc9c18..79cf0a6535c 100644 --- a/src/gui/image/qimageiohandler.cpp +++ b/src/gui/image/qimageiohandler.cpp @@ -160,13 +160,13 @@ variants should return a list of supported variant names (QList) in this option. - \value OptimizedWrite. A handler which supports this option + \value OptimizedWrite A handler which supports this option is expected to turn on optimization flags when writing. - \value ProgressiveScanWrite. A handler which supports + \value ProgressiveScanWrite A handler which supports this option is expected to write the image as a progressive scan image. - \value ImageTransformation. A handler which supports this option can read + \value ImageTransformation A handler which supports this option can read the transformation metadata of an image. A handler that supports this option should not apply the transformation itself. diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp index 1b455a57bfd..c16bcb7f26a 100644 --- a/src/gui/kernel/qguivariant.cpp +++ b/src/gui/kernel/qguivariant.cpp @@ -99,6 +99,7 @@ struct GuiTypesFilter { }; }; +// NOLINTNEXTLINE(cppcoreguidelines-virtual-class-destructor): this is not a base class static const struct : QMetaTypeModuleHelper { #define QT_IMPL_METATYPEINTERFACE_GUI_TYPES(MetaTypeName, MetaTypeId, RealName) \ diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 5b4faf1c802..2e7c3412d34 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -249,7 +249,8 @@ void QBackingStore::flush(const QRegion ®ion, QWindow *window, const QPoint & void QBackingStore::resize(const QSize &size) { d_ptr->size = size; - handle()->resize(QHighDpi::toNativePixels(size, d_ptr->window), d_ptr->staticContents); + handle()->resize(QHighDpi::toNativePixels(size, d_ptr->window), + QHighDpi::toNativePixels(d_ptr->staticContents, d_ptr->window)); } /*! diff --git a/src/gui/painting/qdrawhelper_avx2.cpp b/src/gui/painting/qdrawhelper_avx2.cpp index c58d0804c7d..0fb384e8684 100644 --- a/src/gui/painting/qdrawhelper_avx2.cpp +++ b/src/gui/painting/qdrawhelper_avx2.cpp @@ -1381,13 +1381,16 @@ const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM_avx2(QRgba64 *buffer, const uch vslo = _mm256_srli_epi32(vslo, 16); vshi = _mm256_srli_epi32(vshi, 16); vs256 = _mm256_packus_epi32(vslo, vshi); + vs256 = _mm256_blend_epi16(vs256, va256, 0x88); _mm256_storeu_si256((__m256i *)(buffer + i), vs256); } for (; i < count; ++i) { + const auto a = s[i].alpha(); __m128i vs = _mm_loadl_epi64((const __m128i *)(s + i)); __m128i va = _mm_shufflelo_epi16(vs, _MM_SHUFFLE(3, 3, 3, 3)); vs = multiplyAlpha65535(vs, va); _mm_storel_epi64((__m128i *)(buffer + i), vs); + buffer[i].setAlpha(a); } return buffer; } diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 85d760dff7d..b143b0233e8 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3399,16 +3399,18 @@ void QRasterPaintEngine::drawBitmap(const QPointF &pos, const QImage &image, QSp // Boundaries int w = image.width(); int h = image.height(); - int ymax = qMin(qRound(pos.y() + h), d->rasterBuffer->height()); - int ymin = qMax(qRound(pos.y()), 0); - int xmax = qMin(qRound(pos.x() + w), d->rasterBuffer->width()); - int xmin = qMax(qRound(pos.x()), 0); + int px = qRound(pos.x()); + int py = qRound(pos.y()); + int ymax = qMin(py + h, d->rasterBuffer->height()); + int ymin = qMax(py, 0); + int xmax = qMin(px + w, d->rasterBuffer->width()); + int xmin = qMax(px, 0); - int x_offset = xmin - qRound(pos.x()); + int x_offset = xmin - px; QImage::Format format = image.format(); for (int y = ymin; y < ymax; ++y) { - const uchar *src = image.scanLine(y - qRound(pos.y())); + const uchar *src = image.scanLine(y - py); if (format == QImage::Format_MonoLSB) { for (int x = 0; x < xmax - xmin; ++x) { int src_x = x + x_offset; diff --git a/src/gui/painting/qpixellayout.cpp b/src/gui/painting/qpixellayout.cpp index 99fb229fbae..13e4b8e4ce1 100644 --- a/src/gui/painting/qpixellayout.cpp +++ b/src/gui/painting/qpixellayout.cpp @@ -1224,10 +1224,12 @@ static const QRgba64 *QT_FASTCALL fetchRGBA64ToRGBA64PM(QRgba64 *buffer, const u const QRgba64 *s = reinterpret_cast(src) + index; #ifdef __SSE2__ for (int i = 0; i < count; ++i) { + const auto a = s[i].alpha(); __m128i vs = _mm_loadl_epi64((const __m128i *)(s + i)); __m128i va = _mm_shufflelo_epi16(vs, _MM_SHUFFLE(3, 3, 3, 3)); vs = multiplyAlpha65535(vs, va); _mm_storel_epi64((__m128i *)(buffer + i), vs); + buffer[i].setAlpha(a); } #else for (int i = 0; i < count; ++i) diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index 7a15174725f..44cfd5e3711 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -87,7 +87,7 @@ QT_BEGIN_NAMESPACE contains() a QPoint or QRect. The bounding rectangle can be found with boundingRect(). - Iteration over the region (with begin(), end(), or C++11 + Iteration over the region (with begin(), end(), or ranged-for loops) gives a decomposition of the region into rectangles. diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp index e026078c25f..4a3a367c10f 100644 --- a/src/gui/rhi/qrhid3d11.cpp +++ b/src/gui/rhi/qrhid3d11.cpp @@ -1156,6 +1156,10 @@ QRhi::FrameOpResult QRhiD3D11::endFrame(QRhiSwapChain *swapChain, QRhi::EndFrame if (!flags.testFlag(QRhi::SkipPresent)) { const UINT presentFlags = 0; + if (!swapChainD->swapChain) { + qWarning("Failed to present: IDXGISwapChain is unavailable"); + return QRhi::FrameOpError; + } HRESULT hr = swapChainD->swapChain->Present(swapChainD->swapInterval, presentFlags); if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET) { qWarning("Device loss detected in Present()"); diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp index 920a4d309e9..afdaa15678a 100644 --- a/src/gui/rhi/qrhigles2.cpp +++ b/src/gui/rhi/qrhigles2.cpp @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include QT_BEGIN_NAMESPACE @@ -5455,7 +5457,12 @@ QRhiRenderTarget *QGles2SwapChain::currentFrameRenderTarget() QSize QGles2SwapChain::surfacePixelSize() { Q_ASSERT(m_window); - return m_window->size() * m_window->devicePixelRatio(); + if (QPlatformWindow *platformWindow = m_window->handle()) + // Prefer using QPlatformWindow geometry and DPR in order to avoid + // errors due to rounded QWindow geometry. + return platformWindow->geometry().size() * platformWindow->devicePixelRatio(); + else + return m_window->size() * m_window->devicePixelRatio(); } QRhiRenderPassDescriptor *QGles2SwapChain::newCompatibleRenderPassDescriptor() diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index ccc5be04828..dc2b671f205 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -955,12 +955,6 @@ int QFont::pointSize() const \li No hinting \endtable - \note Please be aware that altering the hinting preference on Windows is available through - the DirectWrite font engine. This is available on Windows Vista after installing the platform - update, and on Windows 7. In order to use this extension, configure Qt using -directwrite. - The target application will then depend on the availability of DirectWrite on the target - system. - */ /*! diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 52942456a9f..a1cd4b2de21 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1762,8 +1762,10 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, } if (!actualFontEngine->supportsHorizontalSubPixelPositions()) { - for (uint i = 0; i < num_glyphs; ++i) + for (uint i = 0; i < num_glyphs; ++i) { g.advances[i] = g.advances[i].round(); + g.offsets[i].x = g.offsets[i].x.round(); + } } glyphs_shaped += num_glyphs; diff --git a/src/gui/text/windows/qwindowsfontdatabase.cpp b/src/gui/text/windows/qwindowsfontdatabase.cpp index a46374d6b3f..06712d8c84f 100644 --- a/src/gui/text/windows/qwindowsfontdatabase.cpp +++ b/src/gui/text/windows/qwindowsfontdatabase.cpp @@ -594,19 +594,11 @@ static bool addFontToDatabase(QString familyName, writingSystems.setSupported(ws); } - // We came here from populating a different font family, so we have - // to ensure the entire typographic family is populated before we - // mark it as such inside registerFont() - if (!subFamilyName.isEmpty() - && familyName != subFamilyName - && sfp->populatedFontFamily != familyName - && !QPlatformFontDatabase::isFamilyPopulated(familyName)) { - sfp->windowsFontDatabase->populateFamily(familyName); - } - + const bool wasPopulated = QPlatformFontDatabase::isFamilyPopulated(familyName); QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight, style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName)); + // add fonts windows can generate for us: if (weight <= QFont::DemiBold && styleName.isEmpty()) QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold, @@ -618,6 +610,16 @@ static bool addFontToDatabase(QString familyName, QPlatformFontDatabase::registerFont(familyName, QString(), foundryName, QFont::Bold, QFont::StyleItalic, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName)); + // We came here from populating a different font family, so we have + // to ensure the entire typographic family is populated before we + // mark it as such inside registerFont() + if (!subFamilyName.isEmpty() + && familyName != subFamilyName + && sfp->populatedFontFamily != familyName + && !wasPopulated) { + sfp->windowsFontDatabase->populateFamily(familyName); + } + if (!subFamilyName.isEmpty() && familyName != subFamilyName) { QPlatformFontDatabase::registerFont(subFamilyName, subFamilyStyle, foundryName, weight, style, stretch, antialias, scalable, size, fixed, writingSystems, createFontFile(faceName)); diff --git a/src/gui/util/qktxhandler.cpp b/src/gui/util/qktxhandler.cpp index 7efee226c86..0abd96a8ad3 100644 --- a/src/gui/util/qktxhandler.cpp +++ b/src/gui/util/qktxhandler.cpp @@ -74,7 +74,7 @@ struct KTXHeader { quint32 bytesOfKeyValueData; }; -static const quint32 headerSize = sizeof(KTXHeader); +static constexpr quint32 qktxh_headerSize = sizeof(KTXHeader); // Currently unused, declared for future reference struct KTXKeyValuePairItem { @@ -104,18 +104,30 @@ struct KTXMipmapLevel { */ }; -// Returns the nearest multiple of 'rounding' greater than or equal to 'value' -constexpr quint32 withPadding(quint32 value, quint32 rounding) +// Returns the nearest multiple of 4 greater than or equal to 'value' +static const std::optional nearestMultipleOf4(quint32 value) { - Q_ASSERT(rounding > 1); - return value + (rounding - 1) - ((value + (rounding - 1)) % rounding); + constexpr quint32 rounding = 4; + quint32 result = 0; + if (qAddOverflow(value, rounding - 1, &result)) + return std::nullopt; + result &= ~(rounding - 1); + return result; +} + +// Returns a view with prechecked bounds +static QByteArrayView safeView(QByteArrayView view, quint32 start, quint32 length) +{ + quint32 end = 0; + if (qAddOverflow(start, length, &end) || end > quint32(view.length())) + return {}; + return view.sliced(start, length); } bool QKtxHandler::canRead(const QByteArray &suffix, const QByteArray &block) { Q_UNUSED(suffix); - - return (qstrncmp(block.constData(), ktxIdentifier, KTX_IDENTIFIER_LENGTH) == 0); + return block.startsWith(ktxIdentifier); } QTextureFileData QKtxHandler::read() @@ -124,55 +136,122 @@ QTextureFileData QKtxHandler::read() return QTextureFileData(); const QByteArray buf = device()->readAll(); - const quint32 dataSize = quint32(buf.size()); - if (dataSize < headerSize || !canRead(QByteArray(), buf)) { - qCDebug(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData()); + if (static_cast(buf.size()) > std::numeric_limits::max()) { + qWarning(lcQtGuiTextureIO, "Too big KTX file %s", logName().constData()); return QTextureFileData(); } - const KTXHeader *header = reinterpret_cast(buf.data()); - if (!checkHeader(*header)) { - qCDebug(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData()); + if (!canRead(QByteArray(), buf)) { + qWarning(lcQtGuiTextureIO, "Invalid KTX file %s", logName().constData()); + return QTextureFileData(); + } + + if (buf.size() < qsizetype(qktxh_headerSize)) { + qWarning(lcQtGuiTextureIO, "Invalid KTX header size in %s", logName().constData()); + return QTextureFileData(); + } + + KTXHeader header; + memcpy(&header, buf.data(), qktxh_headerSize); + if (!checkHeader(header)) { + qWarning(lcQtGuiTextureIO, "Unsupported KTX file format in %s", logName().constData()); return QTextureFileData(); } QTextureFileData texData; texData.setData(buf); - texData.setSize(QSize(decode(header->pixelWidth), decode(header->pixelHeight))); - texData.setGLFormat(decode(header->glFormat)); - texData.setGLInternalFormat(decode(header->glInternalFormat)); - texData.setGLBaseInternalFormat(decode(header->glBaseInternalFormat)); + texData.setSize(QSize(decode(header.pixelWidth), decode(header.pixelHeight))); + texData.setGLFormat(decode(header.glFormat)); + texData.setGLInternalFormat(decode(header.glInternalFormat)); + texData.setGLBaseInternalFormat(decode(header.glBaseInternalFormat)); - texData.setNumLevels(decode(header->numberOfMipmapLevels)); - texData.setNumFaces(decode(header->numberOfFaces)); + texData.setNumLevels(decode(header.numberOfMipmapLevels)); + texData.setNumFaces(decode(header.numberOfFaces)); - const quint32 bytesOfKeyValueData = decode(header->bytesOfKeyValueData); - if (headerSize + bytesOfKeyValueData < quint64(buf.length())) // oob check - texData.setKeyValueMetadata( - decodeKeyValues(QByteArrayView(buf.data() + headerSize, bytesOfKeyValueData))); - quint32 offset = headerSize + bytesOfKeyValueData; + const quint32 bytesOfKeyValueData = decode(header.bytesOfKeyValueData); + quint32 headerKeyValueSize; + if (qAddOverflow(qktxh_headerSize, bytesOfKeyValueData, &headerKeyValueSize)) { + qWarning(lcQtGuiTextureIO, "Overflow in size of key value data in header of KTX file %s", + logName().constData()); + return QTextureFileData(); + } - constexpr int MAX_ITERATIONS = 32; // cap iterations in case of corrupt data + if (headerKeyValueSize >= quint32(buf.size())) { + qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData()); + return QTextureFileData(); + } - for (int level = 0; level < qMin(texData.numLevels(), MAX_ITERATIONS); level++) { - if (offset + sizeof(quint32) > dataSize) // Corrupt file; avoid oob read - break; + // File contains key/values + if (bytesOfKeyValueData > 0) { + auto keyValueDataView = safeView(buf, qktxh_headerSize, bytesOfKeyValueData); + if (keyValueDataView.isEmpty()) { + qWarning(lcQtGuiTextureIO, "Invalid view in KTX file %s", logName().constData()); + return QTextureFileData(); + } - const quint32 imageSize = decode(qFromUnaligned(buf.data() + offset)); - offset += sizeof(quint32); + auto keyValues = decodeKeyValues(keyValueDataView); + if (!keyValues) { + qWarning(lcQtGuiTextureIO, "Could not parse key values in KTX file %s", + logName().constData()); + return QTextureFileData(); + } - for (int face = 0; face < qMin(texData.numFaces(), MAX_ITERATIONS); face++) { + texData.setKeyValueMetadata(*keyValues); + } + + // Technically, any number of levels is allowed but if the value is bigger than + // what is possible in KTX V2 (and what makes sense) we return an error. + // maxLevels = log2(max(width, height, depth)) + const int maxLevels = (sizeof(quint32) * 8) + - qCountLeadingZeroBits(std::max( + { header.pixelWidth, header.pixelHeight, header.pixelDepth })); + + if (texData.numLevels() > maxLevels) { + qWarning(lcQtGuiTextureIO, "Too many levels in KTX file %s", logName().constData()); + return QTextureFileData(); + } + + if (texData.numFaces() != 1 && texData.numFaces() != 6) { + qWarning(lcQtGuiTextureIO, "Invalid number of faces in KTX file %s", logName().constData()); + return QTextureFileData(); + } + + quint32 offset = headerKeyValueSize; + for (int level = 0; level < texData.numLevels(); level++) { + const auto imageSizeView = safeView(buf, offset, sizeof(quint32)); + if (imageSizeView.isEmpty()) { + qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData()); + return QTextureFileData(); + } + + const quint32 imageSize = decode(qFromUnaligned(imageSizeView.data())); + offset += sizeof(quint32); // overflow checked indirectly above + + for (int face = 0; face < texData.numFaces(); face++) { texData.setDataOffset(offset, level, face); texData.setDataLength(imageSize, level, face); // Add image data and padding to offset - offset += withPadding(imageSize, 4); + const auto padded = nearestMultipleOf4(imageSize); + if (!padded) { + qWarning(lcQtGuiTextureIO, "Overflow in KTX file %s", logName().constData()); + return QTextureFileData(); + } + + quint32 offsetNext; + if (qAddOverflow(offset, *padded, &offsetNext)) { + qWarning(lcQtGuiTextureIO, "OOB request in KTX file %s", logName().constData()); + return QTextureFileData(); + } + + offset = offsetNext; } } if (!texData.isValid()) { - qCDebug(lcQtGuiTextureIO, "Invalid values in header of KTX file %s", logName().constData()); + qWarning(lcQtGuiTextureIO, "Invalid values in header of KTX file %s", + logName().constData()); return QTextureFileData(); } @@ -218,33 +297,83 @@ bool QKtxHandler::checkHeader(const KTXHeader &header) return is2D && (isCubeMap || isCompressedImage); } -QMap QKtxHandler::decodeKeyValues(QByteArrayView view) const +std::optional> QKtxHandler::decodeKeyValues(QByteArrayView view) const { QMap output; quint32 offset = 0; - while (offset < view.size() + sizeof(quint32)) { - const quint32 keyAndValueByteSize = - decode(qFromUnaligned(view.constData() + offset)); - offset += sizeof(quint32); + while (offset < quint32(view.size())) { + const auto keyAndValueByteSizeView = safeView(view, offset, sizeof(quint32)); + if (keyAndValueByteSizeView.isEmpty()) { + qWarning(lcQtGuiTextureIO, "Invalid view in KTX key-value"); + return std::nullopt; + } - if (offset + keyAndValueByteSize > quint64(view.size())) - break; // oob read + const quint32 keyAndValueByteSize = + decode(qFromUnaligned(keyAndValueByteSizeView.data())); + + quint32 offsetKeyAndValueStart; + if (qAddOverflow(offset, quint32(sizeof(quint32)), &offsetKeyAndValueStart)) { + qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value"); + return std::nullopt; + } + + quint32 offsetKeyAndValueEnd; + if (qAddOverflow(offsetKeyAndValueStart, keyAndValueByteSize, &offsetKeyAndValueEnd)) { + qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value"); + return std::nullopt; + } + + const auto keyValueView = safeView(view, offsetKeyAndValueStart, keyAndValueByteSize); + if (keyValueView.isEmpty()) { + qWarning(lcQtGuiTextureIO, "Invalid view in KTX key-value"); + return std::nullopt; + } // 'key' is a UTF-8 string ending with a null terminator, 'value' is the rest. // To separate the key and value we convert the complete data to utf-8 and find the first // null terminator from the left, here we split the data into two. - const auto str = QString::fromUtf8(view.constData() + offset, keyAndValueByteSize); - const int idx = str.indexOf(QLatin1Char('\0')); - if (idx == -1) - continue; - const QByteArray key = str.left(idx).toUtf8(); - const size_t keySize = key.size() + 1; // Actual data size - const QByteArray value = QByteArray::fromRawData(view.constData() + offset + keySize, - keyAndValueByteSize - keySize); + const int idx = keyValueView.indexOf('\0'); + if (idx == -1) { + qWarning(lcQtGuiTextureIO, "Invalid key in KTX key-value"); + return std::nullopt; + } - offset = withPadding(offset + keyAndValueByteSize, 4); - output.insert(key, value); + const QByteArrayView keyView = safeView(view, offsetKeyAndValueStart, idx); + if (keyView.isEmpty()) { + qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value"); + return std::nullopt; + } + + const quint32 keySize = idx + 1; // Actual data size + + quint32 offsetValueStart; + if (qAddOverflow(offsetKeyAndValueStart, keySize, &offsetValueStart)) { + qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value"); + return std::nullopt; + } + + quint32 valueSize; + if (qSubOverflow(keyAndValueByteSize, keySize, &valueSize)) { + qWarning(lcQtGuiTextureIO, "Underflow in KTX key-value"); + return std::nullopt; + } + + const QByteArrayView valueView = safeView(view, offsetValueStart, valueSize); + if (valueView.isEmpty()) { + qWarning(lcQtGuiTextureIO, "Invalid view in KTX key-value"); + return std::nullopt; + } + + output.insert(keyView.toByteArray(), valueView.toByteArray()); + + const auto offsetNext = nearestMultipleOf4(offsetKeyAndValueEnd); + if (!offsetNext) { + qWarning(lcQtGuiTextureIO, "Overflow in KTX key-value"); + return std::nullopt; + } + + offset = *offsetNext; } return output; diff --git a/src/gui/util/qktxhandler_p.h b/src/gui/util/qktxhandler_p.h index 4298433f367..3ca45bd382e 100644 --- a/src/gui/util/qktxhandler_p.h +++ b/src/gui/util/qktxhandler_p.h @@ -53,6 +53,8 @@ #include "qtexturefilehandler_p.h" +#include + QT_BEGIN_NAMESPACE struct KTXHeader; @@ -68,7 +70,7 @@ public: private: bool checkHeader(const KTXHeader &header); - QMap decodeKeyValues(QByteArrayView view) const; + std::optional> decodeKeyValues(QByteArrayView view) const; quint32 decode(quint32 val) const; bool inverseEndian = false; diff --git a/src/gui/vulkan/qvulkanwindow.cpp b/src/gui/vulkan/qvulkanwindow.cpp index 974904bb860..d3de9afdfc4 100644 --- a/src/gui/vulkan/qvulkanwindow.cpp +++ b/src/gui/vulkan/qvulkanwindow.cpp @@ -1834,13 +1834,26 @@ void QVulkanWindowRenderer::logicalDeviceLost() { } +QSize QVulkanWindowPrivate::surfacePixelSize() const +{ + Q_Q(const QVulkanWindow); + VkSurfaceCapabilitiesKHR surfaceCaps = {}; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physDevs.at(physDevIndex), surface, &surfaceCaps); + VkExtent2D bufferSize = surfaceCaps.currentExtent; + if (bufferSize.width == uint32_t(-1)) { + Q_ASSERT(bufferSize.height == uint32_t(-1)); + return q->size() * q->devicePixelRatio(); + } + return QSize(int(bufferSize.width), int(bufferSize.height)); +} + void QVulkanWindowPrivate::beginFrame() { if (!swapChain || framePending) return; Q_Q(QVulkanWindow); - if (q->size() * q->devicePixelRatio() != swapChainImageSize) { + if (swapChainImageSize != surfacePixelSize()) { recreateSwapChain(); if (!swapChain) return; @@ -2425,6 +2438,19 @@ VkFormat QVulkanWindow::depthStencilFormat() const This usually matches the size of the window, but may also differ in case \c vkGetPhysicalDeviceSurfaceCapabilitiesKHR reports a fixed size. + In addition, it has been observed on some platforms that the + Vulkan-reported surface size is different with high DPI scaling active, + meaning the QWindow-reported + \l{QWindow::}{size()} multiplied with the \l{QWindow::}{devicePixelRatio()} + was 1 pixel less or more when compared to the value returned from here, + presumably due to differences in rounding. Rendering code should be aware + of this, and any related rendering logic must be based in the value returned + from here, never on the QWindow-reported size. Regardless of which pixel size + is correct in theory, Vulkan rendering must only ever rely on the Vulkan + API-reported surface size. Otherwise validation errors may occur, e.g. when + setting the viewport, because the application-provided values may become + out-of-bounds from Vulkan's perspective. + \note Calling this function is only valid from the invocation of QVulkanWindowRenderer::initSwapChainResources() up until QVulkanWindowRenderer::releaseSwapChainResources(). diff --git a/src/gui/vulkan/qvulkanwindow_p.h b/src/gui/vulkan/qvulkanwindow_p.h index de69b5c9b07..c727a896a40 100644 --- a/src/gui/vulkan/qvulkanwindow_p.h +++ b/src/gui/vulkan/qvulkanwindow_p.h @@ -72,6 +72,7 @@ public: void init(); void reset(); bool createDefaultRenderPass(); + QSize surfacePixelSize() const; void recreateSwapChain(); uint32_t chooseTransientImageMemType(VkImage img, uint32_t startIndex); bool createTransientImage(VkFormat format, VkImageUsageFlags usage, VkImageAspectFlags aspectMask, diff --git a/src/network/access/qhttp2protocolhandler.cpp b/src/network/access/qhttp2protocolhandler.cpp index 44fc1a77bc6..2324273ceef 100644 --- a/src/network/access/qhttp2protocolhandler.cpp +++ b/src/network/access/qhttp2protocolhandler.cpp @@ -46,10 +46,12 @@ #include #include + #include #include #include #include +#include #include #include @@ -124,8 +126,10 @@ std::vector assemble_hpack_block(const std::vector &frames) std::vector hpackBlock; quint32 total = 0; - for (const auto &frame : frames) - total += frame.hpackBlockSize(); + for (const auto &frame : frames) { + if (qAddOverflow(total, frame.hpackBlockSize(), &total)) + return hpackBlock; + } if (!total) return hpackBlock; @@ -1165,63 +1169,6 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const HPack::HttpHeader } } - const auto handleAuth = [&, this](const QByteArray &authField, bool isProxy) -> bool { - Q_ASSERT(httpReply); - const auto auth = authField.trimmed(); - if (auth.startsWith("Negotiate") || auth.startsWith("NTLM")) { - // @todo: We're supposed to fall back to http/1.1: - // https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10/http2-on-iis#when-is-http2-not-supported - // "Windows authentication (NTLM/Kerberos/Negotiate) is not supported with HTTP/2. - // In this case IIS will fall back to HTTP/1.1." - // Though it might be OK to ignore this. The server shouldn't let us connect with - // HTTP/2 if it doesn't support us using it. - } else if (!auth.isEmpty()) { - // Somewhat mimics parts of QHttpNetworkConnectionChannel::handleStatus - bool resend = false; - const bool authenticateHandled = m_connection->d_func()->handleAuthenticateChallenge( - m_socket, httpReply, isProxy, resend); - if (authenticateHandled && resend) { - httpReply->d_func()->eraseData(); - // Add the request back in queue, we'll retry later now that - // we've gotten some username/password set on it: - httpRequest.d->needResendWithCredentials = true; - m_channel->h2RequestsToSend.insert(httpRequest.priority(), stream.httpPair); - httpReply->d_func()->clearHeaders(); - // If we have data we were uploading we need to reset it: - if (stream.data()) { - stream.data()->reset(); - httpReplyPrivate->totallyUploadedData = 0; - } - return true; - } // else: Authentication failed or was cancelled - } - return false; - }; - - if (httpReply) { - // See Note further down. These statuses would in HTTP/1.1 be handled - // by QHttpNetworkConnectionChannel::handleStatus. But because h2 has - // multiple streams/requests in a single channel this structure does not - // map properly to that function. - if (httpReply->statusCode() == 401) { - const auto wwwAuth = httpReply->headerField("www-authenticate"); - if (handleAuth(wwwAuth, false)) { - sendRST_STREAM(stream.streamID, CANCEL); - markAsReset(stream.streamID); - // The stream is finalized and deleted after returning - return; - } // else: errors handled later - } else if (httpReply->statusCode() == 407) { - const auto proxyAuth = httpReply->headerField("proxy-authenticate"); - if (handleAuth(proxyAuth, true)) { - sendRST_STREAM(stream.streamID, CANCEL); - markAsReset(stream.streamID); - // The stream is finalized and deleted after returning - return; - } // else: errors handled later - } - } - if (QHttpNetworkReply::isHttpRedirect(statusCode) && httpRequest.isFollowRedirects()) { QHttpNetworkConnectionPrivate::ParseRedirectResult result = m_connection->d_func()->parseRedirectResponse(httpReply); @@ -1324,6 +1271,85 @@ void QHttp2ProtocolHandler::updateStream(Stream &stream, const Frame &frame, } } +// After calling this function, either the request will be re-sent or +// the reply will be finishedWithError! Do not emit finished() or similar on the +// reply after this! +void QHttp2ProtocolHandler::handleAuthorization(Stream &stream) +{ + auto *httpReply = stream.reply(); + auto *httpReplyPrivate = httpReply->d_func(); + auto &httpRequest = stream.request(); + + Q_ASSERT(httpReply && (httpReply->statusCode() == 401 || httpReply->statusCode() == 407)); + + const auto handleAuth = [&, this](const QByteArray &authField, bool isProxy) -> bool { + Q_ASSERT(httpReply); + const QByteArray auth = authField.trimmed(); + if (auth.startsWith("Negotiate") || auth.startsWith("NTLM")) { + // @todo: We're supposed to fall back to http/1.1: + // https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10/http2-on-iis#when-is-http2-not-supported + // "Windows authentication (NTLM/Kerberos/Negotiate) is not supported with HTTP/2. + // In this case IIS will fall back to HTTP/1.1." + // Though it might be OK to ignore this. The server shouldn't let us connect with + // HTTP/2 if it doesn't support us using it. + } else if (!auth.isEmpty()) { + // Somewhat mimics parts of QHttpNetworkConnectionChannel::handleStatus + bool resend = false; + const bool authenticateHandled = m_connection->d_func()->handleAuthenticateChallenge( + m_socket, httpReply, isProxy, resend); + if (authenticateHandled && resend) { + httpReply->d_func()->eraseData(); + // Add the request back in queue, we'll retry later now that + // we've gotten some username/password set on it: + httpRequest.d->needResendWithCredentials = true; + m_channel->h2RequestsToSend.insert(httpRequest.priority(), stream.httpPair); + httpReply->d_func()->clearHeaders(); + // If we have data we were uploading we need to reset it: + if (stream.data()) { + stream.data()->reset(); + httpReplyPrivate->totallyUploadedData = 0; + } + // We automatically try to send new requests when the stream is + // closed, so we don't need to call sendRequest ourselves. + return true; + } // else: Authentication failed or was cancelled + } else { + // No authentication header, but we got a 401/407 so we cannot + // succeed. We need to emit signals for headers and data, and then + // finishWithError. + emit httpReply->headerChanged(); + emit httpReply->readyRead(); + QNetworkReply::NetworkError error = httpReply->statusCode() == 401 + ? QNetworkReply::AuthenticationRequiredError + : QNetworkReply::ProxyAuthenticationRequiredError; + finishStreamWithError(stream, QNetworkReply::AuthenticationRequiredError, + m_connection->d_func()->errorDetail(error, m_socket)); + } + return false; + }; + + // These statuses would in HTTP/1.1 be handled by + // QHttpNetworkConnectionChannel::handleStatus. But because h2 has + // multiple streams/requests in a single channel this structure does not + // map properly to that function. + bool authOk = true; + switch (httpReply->statusCode()) { + case 401: + authOk = handleAuth(httpReply->headerField("www-authenticate"), false); + break; + case 407: + authOk = handleAuth(httpReply->headerField("proxy-authenticate"), true); + break; + default: + Q_UNREACHABLE(); + } + if (authOk) { + markAsReset(stream.streamID); + deleteActiveStream(stream.streamID); + } // else: errors handled inside handleAuth +} + +// Called when we have received a frame with the END_STREAM flag set void QHttp2ProtocolHandler::finishStream(Stream &stream, Qt::ConnectionType connectionType) { Q_ASSERT(stream.state == Stream::remoteReserved || stream.reply()); @@ -1331,6 +1357,15 @@ void QHttp2ProtocolHandler::finishStream(Stream &stream, Qt::ConnectionType conn stream.state = Stream::closed; auto httpReply = stream.reply(); if (httpReply) { + int statusCode = httpReply->statusCode(); + if (statusCode == 401 || statusCode == 407) { + // handleAuthorization will either re-send the request or + // finishWithError. In either case we don't want to emit finished + // here. + handleAuthorization(stream); + return; + } + httpReply->disconnect(this); if (stream.data()) stream.data()->disconnect(this); diff --git a/src/network/access/qhttp2protocolhandler_p.h b/src/network/access/qhttp2protocolhandler_p.h index 14deabd70b2..a2870971caf 100644 --- a/src/network/access/qhttp2protocolhandler_p.h +++ b/src/network/access/qhttp2protocolhandler_p.h @@ -130,6 +130,7 @@ private: bool acceptSetting(Http2::Settings identifier, quint32 newValue); + void handleAuthorization(Stream &stream); void updateStream(Stream &stream, const HPack::HttpHeader &headers, Qt::ConnectionType connectionType = Qt::DirectConnection); void updateStream(Stream &stream, const Http2::Frame &dataFrame, diff --git a/src/network/doc/snippets/code/src_network_ssl_qsslconfiguration.cpp b/src/network/doc/snippets/code/src_network_ssl_qsslconfiguration.cpp index b857a57a635..5d90dde5ea7 100644 --- a/src/network/doc/snippets/code/src_network_ssl_qsslconfiguration.cpp +++ b/src/network/doc/snippets/code/src_network_ssl_qsslconfiguration.cpp @@ -53,10 +53,3 @@ QSslConfiguration config = sslSocket.sslConfiguration(); config.setProtocol(QSsl::TlsV1_0); sslSocket.setSslConfiguration(config); //! [0] - - -//! [1] -QSslConfiguration tlsConfig = QSslConfiguration::defaultConfiguration(); -tlsConfig.setCiphers(QStringLiteral("DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA")); -//! [1] - diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index c70b9da7673..284d6297791 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -993,7 +993,7 @@ void QHostInfoLookupManager::rescheduleWithMutexHeld() isAlreadyRunning).second, scheduledLookups.end()); - const int availableThreads = threadPool.maxThreadCount() - currentLookups.size(); + const int availableThreads = (std::max)(threadPool.maxThreadCount(), 1) - currentLookups.size(); if (availableThreads > 0) { int readyToStartCount = qMin(availableThreads, scheduledLookups.size()); auto it = scheduledLookups.begin(); diff --git a/src/network/kernel/qt_attribution.json b/src/network/kernel/qt_attribution.json index e5656897321..fee2ab210e5 100644 --- a/src/network/kernel/qt_attribution.json +++ b/src/network/kernel/qt_attribution.json @@ -20,7 +20,7 @@ supported by Qt (by the QNetworkCookieJar class).", "Homepage": "Consult https://github.com/publicsuffix/list for the sha1 but download from ...", "Homepage": "http://publicsuffix.org/", - "Version": "1a4824549b093abc3077205ae5386ed57f73806d, fetched on 2023-09-21", + "Version": "883ced078a83f9d79a98933145425c221a5e51f0, fetched on 2024-01-25", "License": "Mozilla Public License 2.0", "LicenseFile": "PSL-LICENSE.txt", "LicenseId": "MPL-2.0", diff --git a/src/network/kernel/qurltlds_p.h b/src/network/kernel/qurltlds_p.h index 324c7c7194e..14e62bf6baa 100644 --- a/src/network/kernel/qurltlds_p.h +++ b/src/network/kernel/qurltlds_p.h @@ -61,14878 +61,15681 @@ QT_BEGIN_NAMESPACE -static const quint16 tldCount = 9105; +static const quint16 tldCount = 9562; // After the tldCount "real" entries in tldIndices, include a final entry // that records the sum of the lengths of all the chunks, i.e. the index // just past the end of tldChunks. static constexpr quint32 tldIndices[tldCount + 1] = { 0, -16, -44, -77, -77, -102, -126, -126, -136, -157, -177, -184, -184, -198, -218, -235, -235, -261, -261, -261, -277, -277, -290, -296, -296, -296, -296, -323, -329, -329, -329, -329, -329, -361, -366, -366, -390, -461, -461, -461, -479, -479, +17, +33, +42, +57, +57, +57, +82, +82, +82, +82, +82, +121, +121, +162, +173, +182, +182, +195, +209, +292, +303, +308, +355, +368, +377, +388, +388, +388, +400, +400, +425, +460, +460, +460, +488, 502, -519, -533, -555, -561, -561, -561, -561, -582, -603, -648, -668, -668, -668, -668, -695, -705, -705, -705, -722, -722, -739, -745, -751, -782, -788, -788, -800, -807, -867, -886, -905, -911, -917, -936, -951, -964, -964, -970, -991, -998, -998, -1016, -1022, -1022, -1026, -1026, -1061, -1097, -1117, -1117, -1117, -1117, -1117, -1117, -1122, -1122, -1122, -1122, -1122, -1122, -1139, -1145, -1167, -1174, -1174, -1190, -1198, -1198, -1198, -1203, -1212, -1228, -1234, -1252, -1272, +502, +560, +570, +570, +570, +570, +570, +579, +585, +585, +606, +616, +616, +634, +650, +670, +670, +680, +680, +710, +716, +720, +732, +743, +743, +775, +801, +814, +833, +833, +873, +873, +915, +925, +942, +962, +962, +972, +972, +972, +993, +1000, +1000, +1000, +1019, +1032, +1042, +1053, +1111, +1123, +1161, +1232, +1232, +1239, +1246, +1253, +1253, +1260, 1278, 1278, -1284, -1284, -1337, -1343, -1371, -1389, -1389, -1389, -1402, -1402, -1421, -1428, -1428, -1455, -1494, -1494, -1494, -1494, -1513, -1513, -1519, +1285, +1298, +1298, +1309, +1309, +1330, +1364, +1378, +1397, +1413, +1413, +1429, +1473, +1493, +1526, 1536, -1560, -1566, +1536, +1569, 1576, -1588, -1638, -1638, -1651, -1651, -1651, -1682, -1706, -1706, -1706, -1748, -1748, -1748, -1762, -1796, -1806, -1822, -1849, -1858, -1870, -1909, -1914, -1921, -1943, -1943, -1984, -1984, -1994, -1999, -1999, +1583, +1583, +1583, +1590, +1597, +1604, +1604, +1604, +1670, +1687, +1694, +1760, +1771, +1771, +1778, +1798, +1811, +1834, +1874, +1891, +1891, +1891, +1970, +1970, 2009, 2009, -2033, +2016, +2024, +2030, +2030, 2037, -2059, -2073, -2089, -2089, -2089, -2089, +2037, +2044, +2044, +2050, +2072, +2079, +2079, 2117, -2117, -2132, -2159, -2159, -2159, -2181, -2198, -2198, -2198, -2198, -2209, -2217, -2242, -2262, -2262, +2129, +2136, +2136, +2136, +2150, +2150, +2176, +2187, +2204, +2221, +2239, +2256, +2256, 2270, -2286, -2298, -2317, -2317, -2317, -2323, -2323, -2345, -2349, -2349, -2360, -2360, -2411, -2411, -2417, -2425, -2425, -2425, -2431, -2449, -2465, -2465, -2474, -2474, +2295, +2307, +2342, +2348, +2381, +2395, +2402, +2402, +2402, +2448, +2448, +2454, 2484, -2484, -2484, -2484, -2484, -2496, -2511, -2524, -2524, -2541, -2541, +2516, +2516, +2568, +2586, +2593, +2611, +2618, +2618, 2636, 2647, -2664, -2670, -2676, -2695, -2695, -2695, -2702, -2708, -2715, -2715, -2734, -2753, -2771, -2797, -2827, -2827, -2851, -2867, -2888, -2888, -2901, -2935, -2942, -2950, -2961, -2979, -3002, -3027, -3027, -3034, -3034, -3040, -3077, -3077, -3077, -3077, -3077, -3082, -3104, -3104, -3112, -3112, -3131, -3150, -3150, -3150, -3173, -3184, -3184, -3188, -3188, -3194, -3199, -3199, -3215, -3226, -3226, -3238, -3270, -3270, -3286, -3305, -3316, -3321, -3341, -3352, -3352, +2647, +2654, +2677, +2705, +2705, +2728, +2728, +2741, +2741, +2781, +2824, +2840, +2879, +2879, +2898, +2909, +2916, +2957, +2996, +3014, +3014, +3031, +3031, +3037, +3037, +3079, +3119, +3119, +3119, +3137, +3166, +3166, +3172, +3208, +3221, +3246, +3246, +3246, +3261, +3274, +3281, +3281, +3295, +3295, +3295, +3301, +3301, +3301, +3309, +3334, +3338, +3361, 3395, -3404, -3404, -3404, -3416, -3416, -3416, -3427, -3443, -3443, -3443, -3468, -3481, -3501, -3501, -3513, -3513, -3528, -3528, -3538, +3401, +3401, +3433, +3445, +3445, +3452, +3452, +3471, +3471, +3497, +3517, +3517, +3517, +3517, +3541, +3541, +3547, 3554, -3564, -3582, -3605, -3623, -3623, -3623, -3629, -3646, -3667, -3667, -3682, -3699, -3708, +3574, +3602, +3602, +3602, +3602, +3609, +3638, +3651, +3676, +3683, +3719, 3733, -3733, -3739, -3750, -3760, -3760, -3767, -3774, -3780, -3802, -3802, -3821, -3854, -3873, -3885, -3904, -3904, -3956, -3989, -3989, -4006, -4006, -4011, -4049, -4064, -4094, -4094, -4105, -4111, -4132, -4169, +3751, +3759, +3790, +3797, +3822, +3839, +3839, +3846, +3865, +3865, +3894, +3901, +3905, +3912, +3966, +3966, +3966, +4004, +4028, +4038, +4038, +4051, +4066, +4073, +4087, +4114, +4153, +4167, +4174, 4185, -4185, -4201, -4220, -4220, -4234, -4234, -4254, -4273, -4385, -4396, -4396, +4199, +4199, +4213, +4213, +4213, +4213, +4238, +4244, +4263, +4305, +4311, +4355, +4359, +4359, +4366, +4366, +4366, 4413, -4413, -4431, -4431, -4431, +4439, 4445, -4458, -4458, -4479, -4520, -4531, -4531, -4550, -4550, -4550, -4567, -4584, -4584, -4610, -4621, -4621, +4465, +4472, +4502, +4511, +4511, +4534, +4534, +4544, +4562, +4568, +4568, 4630, -4636, -4665, -4665, -4665, -4678, -4678, -4688, -4711, -4711, -4711, -4711, -4740, +4637, +4637, +4669, +4669, +4669, +4676, +4687, +4713, +4720, 4748, -4756, -4800, -4841, -4841, -4869, +4757, +4791, +4801, +4808, +4808, +4822, +4853, 4885, 4885, -4885, -4885, -4890, -4922, -4932, +4935, 4941, 4941, -4954, -4987, -4987, -4987, -4987, -4987, -5009, -5050, +4977, +5011, +5079, 5093, -5131, -5131, -5131, -5131, -5131, -5162, -5162, -5162, -5173, -5173, -5178, -5178, -5229, -5247, -5247, -5247, -5247, -5247, -5280, -5299, -5312, -5312, -5342, -5342, -5351, -5364, -5376, -5376, -5421, -5421, -5456, -5461, -5492, -5553, -5553, -5587, +5109, +5109, +5109, +5116, +5122, +5122, +5122, +5171, +5171, +5207, +5234, +5250, +5257, +5270, +5326, +5333, +5385, +5399, +5406, +5418, +5418, +5430, +5445, +5460, +5460, +5467, +5487, +5498, +5516, +5523, +5548, +5557, +5563, +5592, +5599, 5612, -5620, -5620, -5650, -5650, -5658, -5658, -5658, -5658, -5658, -5658, -5680, -5701, -5701, -5747, -5747, -5747, +5635, +5648, +5663, +5688, +5710, +5733, +5758, 5765, -5828, -5828, -5841, -5859, -5876, -5876, -5876, -5900, -5900, -5917, -5917, -5927, -5935, -5965, -5975, -6008, -6008, -6037, -6050, -6061, -6085, -6094, -6115, -6122, -6127, -6199, -6248, -6295, -6295, -6295, -6312, -6320, -6330, -6330, -6334, -6334, -6334, -6352, -6372, -6372, -6372, -6418, -6418, -6418, -6442, -6451, -6451, -6457, -6457, -6464, -6469, -6484, -6506, -6506, -6545, -6545, -6568, -6568, -6596, -6622, -6622, -6629, -6629, -6646, -6673, -6722, -6732, -6778, -6814, -6851, -6862, -6867, -6873, -6873, -6873, -6894, -6894, -6906, -6925, -6976, -6976, -6984, -6992, -6992, -6992, -6992, -6992, -6992, -6992, -7019, -7019, -7029, -7029, +5799, +5799, +5806, +5812, +5812, +5824, +5830, +5837, +5857, +5864, +5881, +5881, +5881, +5893, +5893, +5899, +5899, +5919, +5919, +5957, +5957, +5957, +5957, +5971, +5978, +5984, +6009, +6047, +6065, +6093, +6104, +6153, +6169, +6169, +6169, +6176, +6180, +6196, +6202, +6202, +6228, +6241, +6264, +6264, +6264, +6264, +6274, +6284, +6299, +6306, +6318, +6325, +6393, +6393, +6393, +6443, +6463, +6475, +6475, +6475, +6475, +6475, +6514, +6549, +6574, +6591, +6605, +6624, +6636, +6684, +6684, +6696, +6696, +6696, +6696, +6696, +6696, +6700, +6707, +6714, +6714, +6714, +6714, +6714, +6721, +6740, +6740, +6753, +6782, +6794, +6828, +6841, +6874, +6874, +6881, +6881, +6881, +6917, +6950, +6963, +6963, +6963, +6970, +6970, +7003, +7003, 7048, -7048, -7057, -7057, -7057, -7081, -7092, -7097, -7105, -7141, -7141, -7181, -7196, +7060, +7067, +7089, +7089, +7089, +7127, +7179, +7179, +7198, +7203, +7203, +7223, +7223, +7223, 7231, 7231, -7240, -7240, -7262, -7272, -7272, -7285, +7237, +7237, +7284, +7298, +7298, +7298, +7298, 7305, -7305, -7311, -7319, -7319, -7319, -7335, -7335, -7363, -7383, -7383, -7400, +7327, +7327, +7339, +7339, +7386, 7406, -7417, -7436, -7436, -7436, -7436, -7436, -7436, -7436, -7436, -7444, -7452, -7452, -7461, -7471, -7478, -7478, -7478, -7493, -7508, -7547, -7547, -7558, -7558, -7570, -7581, -7585, -7607, -7617, -7630, -7630, -7630, -7647, -7683, -7704, -7704, -7704, -7721, -7739, -7752, -7758, -7765, -7779, -7796, -7796, -7796, +7422, +7440, +7440, +7440, +7446, +7446, +7453, +7477, +7488, +7517, +7527, +7560, +7565, +7565, +7592, +7599, +7604, +7655, +7655, +7663, +7663, +7715, +7715, +7715, +7722, +7722, +7722, +7738, +7738, +7738, +7803, 7828, -7837, -7853, -7853, -7860, -7860, -7860, -7879, -7879, -7879, -7894, -7937, -7956, -7966, -7966, -7966, -7966, -8004, -8019, -8044, -8044, -8071, -8071, +7828, +7834, +7841, +7877, +7887, +7892, +7905, +7905, +7905, +7905, +7905, +7924, +7976, +7976, +8023, +8035, +8045, 8077, -8093, -8114, -8114, -8118, -8118, -8118, -8118, -8118, -8125, -8125, -8135, -8155, -8155, -8155, -8171, -8176, +8077, +8096, +8096, +8096, +8096, +8096, +8124, +8124, +8124, +8142, +8142, +8163, +8163, +8163, +8163, +8181, +8195, +8195, 8205, -8224, -8236, -8253, -8253, -8263, +8219, +8219, +8219, +8219, +8260, 8271, -8275, -8275, -8275, -8275, -8279, -8279, -8288, -8288, -8319, -8344, -8362, -8379, -8379, -8383, -8383, -8417, -8421, -8421, -8440, -8440, -8447, -8473, +8286, +8295, +8295, +8295, +8301, +8301, +8301, +8301, +8301, +8323, +8333, +8343, +8351, +8351, +8351, +8364, +8369, +8381, +8381, +8386, +8386, +8386, +8406, +8426, +8442, +8442, +8449, +8454, +8454, +8462, +8491, 8498, 8505, -8527, -8527, -8542, -8557, -8571, -8593, -8601, -8611, -8611, -8621, -8670, +8512, +8512, +8522, +8555, +8614, +8620, +8668, +8668, +8668, +8668, +8668, 8685, -8706, -8706, -8706, -8706, -8717, -8717, -8717, -8728, -8728, -8761, -8768, -8796, -8806, +8696, +8746, +8752, +8801, +8810, +8839, 8846, -8871, -8871, -8887, -8914, -8918, -8940, -8964, -8964, -8975, -9007, -9007, -9007, -9007, -9039, -9039, -9039, -9043, -9059, -9059, -9078, -9078, -9086, -9104, -9126, -9126, -9150, -9150, -9150, -9178, -9189, -9189, -9189, -9189, -9204, -9204, -9220, -9220, -9220, -9226, -9233, -9233, -9233, -9233, -9239, -9269, -9291, -9326, -9339, -9354, -9369, -9397, -9397, -9397, -9416, -9426, -9443, -9453, -9465, -9484, -9484, -9484, -9504, -9504, -9504, -9512, -9522, -9572, -9591, -9591, -9591, -9591, -9591, -9607, -9607, -9607, -9611, -9611, -9611, -9618, +8864, +8864, +8897, +8910, +8959, +8968, +8992, +8996, +9002, +9016, +9016, +9048, +9048, +9061, +9061, +9061, +9068, +9080, +9080, +9080, +9080, +9098, +9117, +9117, +9135, +9135, +9135, +9142, +9142, +9142, +9142, +9168, +9168, +9187, +9187, +9187, +9199, +9208, +9244, +9244, +9263, +9270, +9270, +9281, +9321, +9356, +9373, +9385, +9405, +9447, +9447, +9447, +9447, +9458, +9466, +9471, +9505, +9505, +9505, +9518, +9518, +9527, +9552, +9559, +9568, +9615, +9615, +9615, +9630, +9635, +9635, 9649, -9649, -9649, -9649, -9659, -9659, -9681, -9688, -9688, -9688, +9664, +9706, +9706, +9706, 9719, -9754, -9845, -9845, -9845, +9726, +9726, +9726, +9726, +9726, +9760, +9760, +9760, +9774, +9781, +9781, +9790, +9844, +9844, +9861, 9877, -9884, -9901, -9901, -9901, -9938, -9938, -9965, -9965, -9965, -9974, -9974, -9993, +9887, +9887, +9887, +9918, +9976, +9976, +9988, +9988, +9988, 10006, -10006, -10041, -10041, -10060, -10060, -10060, -10080, -10080, -10092, -10092, -10112, -10116, -10116, -10148, -10158, -10158, -10158, -10158, -10168, -10168, -10184, -10192, -10192, -10192, -10218, -10233, -10233, +10023, +10061, +10072, +10091, +10121, +10134, +10171, +10179, +10179, +10222, +10222, 10243, -10243, -10243, -10243, -10260, -10269, -10304, -10304, -10316, -10316, -10337, -10337, -10348, -10348, -10348, -10348, -10348, -10348, -10348, -10352, -10374, +10263, +10263, +10263, +10306, +10319, +10319, +10358, 10390, -10390, -10413, -10421, -10421, -10452, -10459, -10459, -10459, -10459, -10459, -10475, -10503, -10520, -10534, -10534, -10557, -10586, -10586, -10586, -10586, +10397, +10406, +10412, +10412, +10412, +10431, +10437, +10458, +10464, +10522, +10522, +10522, +10532, 10590, -10594, -10603, -10603, -10672, -10676, -10693, -10708, -10728, -10744, -10760, -10776, -10801, -10801, -10826, -10826, -10837, -10837, -10846, -10846, -10887, -10887, -10887, -10887, -10887, -10887, -10887, -10896, -10921, -10931, -10931, -10931, -10931, -10931, -10958, -10975, -10975, -10975, -10996, -11023, -11040, -11052, -11052, -11052, -11081, -11109, +10590, +10629, +10665, +10665, +10694, +10694, +10694, +10714, +10714, +10721, +10721, +10721, +10775, +10795, +10795, +10809, +10861, +10861, +10880, +10880, +10880, +10880, +10909, +10965, +10971, +10971, +10971, +10981, +10995, +10995, +10995, +11047, +11082, +11097, +11122, 11136, -11154, -11168, -11183, -11183, -11200, -11200, -11200, -11200, -11215, -11215, -11215, -11244, -11244, -11261, -11288, -11304, -11321, -11339, -11351, -11351, -11366, -11418, -11423, -11437, -11437, -11472, -11530, -11546, -11546, -11546, -11572, -11586, -11605, -11636, -11653, +11152, +11152, +11187, +11210, +11220, +11220, +11271, +11312, +11324, +11324, +11331, +11331, +11331, +11331, +11349, +11384, +11384, +11404, +11404, +11431, +11460, +11475, +11475, +11475, +11475, +11475, +11489, +11489, +11520, +11538, +11547, +11547, +11554, +11575, +11587, +11604, +11630, +11634, +11634, 11666, -11666, -11666, -11666, -11683, -11711, -11716, -11716, -11728, -11734, -11734, -11734, -11744, -11744, -11768, -11780, -11780, -11780, -11824, -11840, -11840, -11880, -11890, -11904, -11913, -11923, -11923, -11941, -11957, -11957, -11971, -11987, -12024, -12042, -12057, -12066, -12079, -12097, -12112, -12126, -12126, -12136, -12136, -12168, -12168, -12174, -12174, -12174, -12185, -12195, -12195, -12195, -12216, -12227, -12256, -12289, -12289, -12289, -12306, -12306, -12306, -12338, +11676, +11702, +11725, +11725, +11725, +11725, +11725, +11742, +11742, +11742, +11763, +11763, +11774, +11781, +11781, +11793, +11793, +11793, +11793, +11843, +11853, +11897, +11897, +11926, +11926, +11926, +11926, +11936, +11952, +11952, +11965, +11965, +11965, +11977, +11977, +11981, +11998, +12013, +12056, +12056, +12056, +12065, +12065, +12065, +12074, +12074, +12081, +12081, +12100, +12111, +12111, +12122, +12127, +12127, +12127, +12150, +12186, +12193, +12223, +12232, +12243, +12247, +12275, +12296, +12296, +12316, +12321, 12343, -12352, -12352, -12400, -12410, -12423, -12423, -12423, -12423, -12423, -12423, -12446, -12486, -12486, -12511, -12518, -12554, -12567, -12567, -12567, -12585, -12597, +12343, +12355, +12373, +12373, +12382, +12382, +12392, +12392, +12392, +12392, +12409, +12409, +12428, +12428, +12438, +12445, +12471, +12479, +12479, +12493, +12493, +12503, +12503, +12533, +12533, +12533, +12549, +12549, +12560, +12581, +12581, 12602, -12606, -12621, -12621, -12621, -12651, -12651, -12664, -12670, -12670, -12682, -12696, -12696, -12720, -12747, -12747, -12747, -12747, -12772, -12772, -12792, -12792, -12815, -12815, -12815, -12815, -12830, -12865, -12876, -12876, -12896, -12918, -12918, -12924, -12935, -12935, +12616, +12632, +12647, +12647, +12647, +12647, +12659, +12674, +12674, +12686, +12686, +12705, +12705, +12728, +12735, +12735, +12777, +12793, +12810, +12817, +12826, +12846, +12890, +12906, +12920, +12936, +12936, 12949, -12959, -12959, -12984, -12984, -13005, -13005, -13005, -13015, -13028, -13028, -13028, -13028, -13028, -13028, -13051, -13051, +12962, +12973, +13013, +13017, +13032, 13067, -13076, -13104, -13141, -13153, -13170, -13170, -13170, -13183, -13229, -13259, -13259, -13259, -13264, -13264, -13264, -13286, -13286, -13286, -13286, -13292, -13292, -13304, -13322, -13330, -13340, -13340, -13340, -13340, -13368, -13368, -13375, -13375, -13375, -13375, -13375, -13375, -13388, -13388, -13398, -13422, -13422, -13437, -13461, -13476, -13486, -13494, -13506, -13506, -13513, -13523, -13539, -13539, -13539, -13539, -13574, -13574, -13574, -13588, -13611, -13626, -13632, -13670, -13675, -13675, -13701, -13741, -13759, -13759, -13779, -13786, -13786, -13786, -13804, -13824, -13842, -13842, -13868, -13875, +13067, +13067, +13067, +13085, +13124, +13124, +13167, +13180, +13180, +13180, +13180, +13180, +13180, +13207, +13228, +13228, +13236, +13249, +13254, +13276, +13294, +13294, +13301, +13311, +13333, +13366, +13400, +13426, +13426, +13467, +13485, +13531, +13569, +13569, +13580, +13585, +13594, +13614, +13614, +13635, +13705, +13705, +13719, +13727, +13731, +13731, +13731, +13758, +13758, +13792, +13802, +13802, +13812, +13840, +13840, 13895, 13895, -13895, -13903, -13907, -13907, -13907, -13907, -13922, -13922, -13938, -13945, +13906, +13906, +13928, 13949, -13949, -13955, -13970, -13993, -13993, -14026, -14059, -14066, -14074, -14093, -14093, -14093, -14093, -14103, -14103, -14146, -14146, -14178, -14178, -14198, -14198, -14198, -14198, -14220, -14220, -14254, -14254, -14254, -14259, -14301, -14301, -14309, -14328, -14328, -14333, -14369, -14375, -14375, -14375, -14375, -14383, -14383, -14383, -14399, -14399, +13978, +13978, +13986, +13986, +13986, +14024, +14033, +14046, +14046, +14058, +14058, +14070, +14070, +14083, +14127, +14158, +14158, +14177, +14177, +14177, +14194, +14211, +14225, +14327, +14373, +14386, +14401, +14411, +14411, 14422, -14434, -14443, -14456, -14467, -14499, -14505, -14505, -14522, -14522, -14541, -14541, -14547, -14547, +14422, +14447, +14461, +14461, +14483, +14483, +14502, +14539, +14539, +14539, 14557, -14567, -14579, -14593, -14593, -14593, -14593, -14593, -14607, -14607, -14607, -14607, -14634, -14654, -14675, -14675, -14675, -14675, -14691, -14715, -14732, -14748, -14748, -14753, -14753, -14753, -14759, -14759, -14769, -14769, -14776, -14776, -14792, -14830, -14830, -14830, -14837, -14851, -14861, -14861, -14875, -14891, -14891, -14907, -14913, -14913, -14962, -14962, -14978, -14978, -15007, -15014, -15029, -15029, -15029, -15043, -15061, -15073, -15073, -15092, -15092, -15110, -15144, -15200, -15217, -15231, -15249, -15249, -15249, -15256, -15275, -15285, +14557, +14557, +14566, +14566, +14575, +14618, +14628, +14643, +14643, +14684, +14684, +14714, +14714, +14725, +14750, +14762, +14770, +14789, +14801, +14822, +14826, +14826, +14826, +14856, +14892, +14912, +14941, +14941, +14948, +14969, +14969, +14969, +14969, +14987, +14992, +15013, +15023, +15030, +15079, +15102, +15140, +15145, +15155, +15155, +15155, +15155, +15155, +15172, +15192, +15207, +15283, +15298, +15313, 15319, 15319, -15372, -15399, -15420, -15420, -15464, -15477, -15489, -15489, -15489, -15499, -15518, -15518, -15518, -15540, -15540, -15540, -15540, -15540, -15571, -15571, -15571, -15571, -15583, -15603, -15628, -15628, -15645, -15654, -15654, -15666, -15678, -15678, -15700, -15700, -15700, -15700, -15726, -15726, -15743, -15743, -15766, -15784, -15793, -15803, -15807, -15821, -15821, -15837, -15862, -15912, -15912, -15925, -15948, -15948, -15948, -15948, -15957, -15961, -15961, -15961, -15961, -15973, -15989, -16007, -16007, -16007, -16022, -16065, -16065, -16091, -16103, -16130, -16153, -16153, -16185, -16240, -16266, -16323, -16323, -16323, -16355, -16373, -16373, -16401, -16401, -16401, -16413, -16413, -16440, -16468, -16492, -16505, -16505, -16511, -16523, -16529, -16529, -16541, -16541, -16570, -16570, -16570, +15352, +15352, +15370, +15370, +15383, +15470, +15490, +15490, +15490, +15500, +15592, +15607, +15648, +15679, +15683, +15687, +15693, +15736, +15736, +15745, +15745, +15745, +15745, +15792, +15823, +15823, +15823, +15836, +15866, +15879, +15901, +15965, +16071, +16071, +16071, +16096, +16096, +16110, +16122, +16148, +16152, +16166, +16166, +16166, +16193, +16299, +16299, +16321, +16331, +16340, +16340, +16347, +16374, +16386, +16386, +16464, +16508, +16508, +16508, +16512, +16512, +16512, +16533, +16555, +16555, 16584, 16584, 16584, 16584, -16607, -16607, -16625, -16652, -16652, -16664, -16664, -16664, -16664, -16664, -16664, -16664, -16677, -16681, -16681, -16711, -16711, -16711, -16720, -16741, -16749, -16758, +16584, +16584, +16602, +16602, +16602, +16612, +16627, +16641, +16641, +16659, +16659, +16695, +16695, +16712, 16770, -16802, -16802, -16802, -16802, -16802, -16842, -16842, -16849, -16853, -16871, -16871, -16882, -16882, -16924, -16945, -16956, -16956, -16956, -16975, +16787, +16807, +16807, +16821, +16821, +16826, +16826, +16826, +16861, +16874, +16874, +16884, +16884, +16947, +16959, +16959, +16976, +16976, 16990, 16990, -16998, -17030, -17030, -17030, -17030, -17049, -17049, -17058, -17073, -17073, -17099, -17125, -17177, -17195, -17248, -17248, -17248, -17274, -17274, -17282, -17300, -17300, -17300, -17328, -17356, -17371, -17381, -17394, -17413, -17470, -17481, -17548, -17548, -17548, -17548, -17562, -17591, -17591, -17615, -17621, -17639, -17639, -17666, -17674, -17679, -17679, -17719, -17731, -17731, -17761, -17761, -17777, -17777, -17777, -17801, -17801, -17801, -17801, -17825, -17825, -17825, -17825, -17855, -17877, -17877, -17900, -17900, -17900, -17906, -17906, -17906, -17914, -17914, -17941, -17941, -17941, -17967, -17976, -18047, -18063, -18116, -18136, -18136, -18136, -18136, -18136, -18149, -18166, -18188, -18210, -18210, -18251, -18251, -18256, -18256, -18264, -18264, -18264, -18295, -18295, -18295, -18346, -18346, -18366, -18397, -18397, -18417, -18424, -18441, -18493, -18514, -18537, -18543, -18558, -18564, -18564, -18581, -18595, -18598, -18623, -18626, -18629, -18642, -18649, -18649, -18649, -18662, -18677, -18695, -18717, -18717, -18739, +17067, +17088, +17101, +17101, +17111, +17122, +17156, +17163, +17163, +17187, +17238, +17260, +17271, +17271, +17271, +17271, +17271, +17271, +17271, +17293, +17310, +17310, +17310, +17322, +17322, +17339, +17351, +17351, +17351, +17351, +17351, +17351, +17351, +17392, +17400, +17416, +17416, +17441, +17458, +17468, +17478, +17537, +17537, +17545, +17545, +17554, +17554, +17566, +17592, +17592, +17604, +17616, +17645, +17682, +17690, +17690, +17690, +17724, +17724, +17749, +17749, +17749, +17799, +17799, +17819, +17819, +17830, +17839, +17839, +17853, +17871, +17871, +17902, +17912, +17922, +17930, +17977, +17983, +18032, +18044, +18051, +18051, +18061, +18061, +18071, +18071, +18071, +18071, +18100, +18144, +18144, +18179, +18192, +18192, +18208, +18220, +18220, +18226, +18226, +18265, +18265, +18275, +18275, +18275, +18275, +18288, +18288, +18288, +18314, +18314, +18354, +18367, +18384, +18384, +18384, +18394, +18414, +18437, +18458, +18474, +18474, +18499, +18499, +18505, +18505, +18509, +18521, +18521, +18533, +18554, +18554, +18554, +18565, +18565, +18585, +18585, +18585, +18612, +18634, +18643, +18666, +18666, +18686, +18686, +18728, 18745, 18756, -18782, -18796, -18816, -18822, -18849, -18858, -18872, -18872, -18872, -18894, -18915, -18938, -18971, -18974, -18995, -19015, +18772, +18800, +18800, +18800, +18800, +18800, +18806, +18862, +18880, +18922, +18936, +18936, +18942, +18959, +18959, +18964, +18964, +19012, +19012, +19012, +19017, +19021, +19030, +19030, +19030, +19035, 19044, -19051, -19075, -19085, -19088, -19102, -19117, -19117, -19141, -19152, +19044, +19052, +19052, +19052, +19052, +19074, +19099, +19106, +19139, +19139, 19155, -19158, -19164, -19164, -19167, -19173, -19173, -19179, -19213, -19216, -19229, +19155, +19174, +19221, +19239, 19251, -19268, 19271, -19283, -19286, -19301, -19304, -19304, -19332, -19341, -19344, -19344, -19347, -19351, -19354, -19372, -19372, -19392, -19400, -19430, -19430, -19440, -19440, -19448, -19448, -19483, -19497, -19527, -19530, -19530, -19549, -19554, -19557, -19560, -19560, -19560, -19570, -19580, -19583, -19583, -19586, -19627, -19627, -19630, -19645, -19676, -19688, -19710, -19713, -19728, -19728, -19776, -19830, -19839, -19846, -19861, -19882, -19904, -19907, -19910, -19924, -19933, -19942, -19977, -19994, +19290, +19320, +19366, +19366, +19373, +19389, +19402, +19402, +19418, +19438, +19438, +19438, +19438, +19438, +19438, +19438, +19438, +19458, +19466, +19466, +19484, +19484, +19494, +19494, +19510, +19510, +19521, +19521, +19536, +19543, +19543, +19550, +19550, +19556, +19556, +19603, +19603, +19611, +19622, +19646, +19675, +19696, +19696, +19735, +19747, +19747, +19763, +19763, +19763, +19780, +19780, +19792, +19798, +19798, +19808, +19824, +19863, +19863, +19975, +19975, +19983, +19999, +20006, +20006, +20006, 20022, -20025, -20031, -20034, -20046, -20046, -20056, -20056, -20059, -20082, -20117, -20123, -20123, -20144, -20156, -20156, -20179, -20179, -20182, -20225, -20228, -20231, -20278, -20292, -20295, +20036, +20043, +20043, +20050, +20110, +20110, +20110, +20145, +20145, +20145, +20145, +20161, +20161, +20161, +20161, +20184, +20198, +20219, +20219, +20230, +20236, +20236, +20261, +20283, +20283, 20298, -20313, -20316, -20316, -20316, -20326, -20340, -20340, -20354, -20354, -20376, -20376, -20386, -20398, -20398, -20430, -20430, -20430, -20458, -20458, -20468, -20468, -20484, -20497, -20508, -20525, +20314, +20314, +20321, +20352, +20361, +20361, +20361, +20375, +20422, +20433, +20433, +20457, +20457, +20457, +20457, +20457, +20457, +20476, +20476, +20482, +20488, +20488, +20488, +20488, +20542, +20548, +20548, +20548, 20555, -20567, -20590, -20615, +20574, +20584, 20618, -20624, -20646, -20677, -20677, -20695, -20710, -20753, -20811, -20830, -20859, -20880, -20892, -20892, -20892, -20915, -20942, -20952, -20982, -21015, -21040, -21049, -21052, -21061, -21078, -21099, -21108, -21111, -21123, -21130, -21145, -21172, -21184, -21187, -21283, -21286, -21292, -21314, -21320, -21339, -21345, -21352, -21352, -21355, -21355, -21390, -21399, -21399, -21399, -21421, -21421, -21452, -21461, -21472, -21508, -21527, -21546, -21549, -21574, -21590, -21600, -21624, -21661, -21686, -21707, -21713, -21713, -21738, -21741, -21744, -21757, -21777, -21777, +20627, +20641, +20683, +20683, +20736, +20740, +20740, +20740, +20740, +20750, +20750, +20795, +20795, +20795, +20854, +20862, +20869, +20869, +20874, +20874, +20895, +20895, +20895, +20911, +20927, +20927, +20939, +20946, +20962, +20962, +20962, +21018, +21018, +21018, +21056, +21077, +21077, +21077, +21077, +21095, +21134, +21134, +21160, +21171, +21214, +21214, +21214, +21214, +21221, +21221, +21221, +21221, +21317, +21317, +21325, +21342, +21342, +21370, +21386, +21405, +21418, +21438, +21441, +21447, +21469, +21489, +21533, +21557, +21568, +21586, +21596, +21596, +21636, +21648, +21671, +21700, +21706, +21716, +21722, +21728, +21731, +21753, +21753, +21765, 21811, -21819, -21822, -21837, +21826, +21829, 21840, -21854, -21854, -21862, -21877, -21894, -21903, -21903, -21930, +21853, +21856, +21898, +21904, +21904, 21933, -21940, -21943, -21943, -21949, -21949, -21957, -21957, -21957, -22006, -22006, -22019, -22025, -22054, -22065, -22065, -22091, -22091, -22091, -22099, -22132, -22138, -22138, -22144, -22147, -22147, -22150, -22153, -22164, -22185, -22215, -22240, -22253, -22264, -22267, -22293, -22329, +21990, +21993, +21999, +22023, +22050, +22094, +22113, +22131, +22148, +22225, +22284, +22301, 22342, -22345, -22348, -22392, -22408, -22425, -22428, -22434, -22460, -22513, -22564, -22582, -22601, -22604, -22621, -22624, -22695, -22737, -22754, -22757, -22757, -22780, -22790, -22801, -22825, -22838, -22866, -22878, -22888, -22899, -22908, -22915, -22915, -22946, -22946, -22946, -22954, -22968, -22968, -22985, -23011, -23022, -23051, -23054, -23076, -23105, -23125, -23131, +22361, +22380, +22414, +22441, +22444, +22447, +22491, +22503, +22520, +22548, +22569, +22617, +22617, +22642, +22657, +22660, +22660, +22670, +22705, +22718, +22768, +22784, +22817, +22817, +22836, +22851, +22863, +22863, +22863, +22863, +22863, +22876, +22918, +22963, +22974, +22974, +22980, +22983, +22999, +22999, +22999, +23037, +23037, +23066, +23080, +23083, +23096, +23115, +23118, +23133, 23146, -23157, -23166, -23166, -23186, -23194, -23234, -23254, -23266, -23280, -23307, -23307, -23307, -23315, -23323, -23333, -23341, -23379, -23400, -23421, +23149, +23207, +23224, +23224, +23224, +23235, +23265, +23274, +23290, +23313, +23326, +23329, +23347, +23368, +23371, +23375, +23378, +23390, 23431, -23437, -23450, -23478, -23478, -23478, -23478, -23478, -23478, -23478, -23478, -23485, -23485, -23496, -23507, -23507, -23507, -23516, -23536, -23536, -23557, -23576, -23595, -23595, -23635, -23641, -23641, -23641, -23641, -23641, -23655, -23655, -23672, +23452, +23455, +23455, +23470, +23490, +23533, +23537, +23537, +23563, +23575, +23587, +23593, +23612, +23612, +23612, +23625, +23625, +23666, +23669, 23682, -23682, -23690, -23701, -23701, -23750, -23750, -23750, -23761, -23775, -23782, -23782, -23785, -23793, +23685, +23688, +23688, +23699, +23739, +23742, +23745, +23756, +23756, +23770, 23800, -23813, -23813, -23813, -23813, -23813, -23813, -23823, +23811, 23832, -23832, -23832, -23841, -23854, -23864, -23930, -23930, -23948, -23948, -23948, -23980, -23987, -23987, -24011, -24019, -24031, -24040, -24040, -24040, -24046, -24046, -24058, -24067, -24106, -24151, -24151, +23879, +23926, +23950, +23977, +23986, +24007, +24020, +24020, +24066, +24066, +24082, +24082, +24085, +24085, +24088, +24088, +24139, +24139, +24157, +24160, 24174, -24174, -24181, -24187, -24208, -24217, -24217, -24217, -24230, -24241, -24241, -24271, -24271, -24271, -24277, -24297, -24309, -24356, -24356, -24375, -24396, -24419, -24419, -24437, -24457, -24474, -24487, -24487, -24487, -24510, -24528, -24528, -24534, -24561, -24568, -24568, -24568, -24568, -24588, -24588, -24588, -24604, -24604, -24611, -24624, -24635, -24655, -24667, -24667, -24667, -24667, -24693, +24177, +24180, +24220, +24232, +24232, +24232, +24232, +24253, +24269, +24275, +24295, +24328, +24328, +24335, +24335, +24335, +24335, +24338, +24352, +24370, +24432, +24442, +24453, +24520, +24540, +24543, +24562, +24565, +24583, +24602, +24605, +24608, +24650, +24715, 24718, -24718, -24751, -24751, -24751, -24762, -24778, -24778, -24791, -24814, -24818, -24851, -24889, -24889, -24895, -24918, -24923, -24933, -24933, -24952, -24952, -24965, -24996, -25000, -25009, -25009, -25027, -25040, -25076, -25076, -25103, -25118, -25130, -25130, -25172, -25187, -25187, -25187, -25187, -25187, -25187, -25196, -25231, -25240, -25240, -25252, -25252, -25271, -25300, -25300, -25300, -25306, -25311, -25311, -25311, -25311, -25311, -25328, -25349, -25370, -25370, -25370, -25370, -25392, -25392, -25429, -25481, -25485, -25523, -25523, -25541, -25564, +24724, +24754, +24857, +24863, +24869, +24913, +24925, +24928, +25011, +25014, +25014, +25030, +25033, +25033, +25043, +25062, +25062, +25084, +25158, +25173, +25230, +25230, +25253, +25305, +25315, +25315, +25336, +25336, +25336, +25371, +25374, +25374, +25394, +25394, +25397, +25406, +25406, +25409, +25409, +25409, +25412, +25450, +25465, +25473, +25473, +25473, +25489, +25506, +25522, +25525, +25525, +25561, 25579, -25585, -25585, -25592, -25592, -25641, -25641, -25651, -25651, -25668, -25668, -25686, -25701, -25701, +25579, +25582, +25607, +25607, +25636, +25661, +25661, +25680, 25701, 25712, -25721, -25721, -25727, -25748, -25758, -25766, -25789, -25789, -25825, -25825, -25848, -25856, -25856, -25874, -25874, -25878, -25882, -25896, -25896, -25923, -25935, -25955, -25962, -25962, -25983, -25990, +25712, +25726, +25726, +25729, +25736, +25747, +25747, +25747, +25776, +25783, +25807, +25820, +25829, +25839, +25859, +25862, +25881, +25911, +25928, +25934, +25934, +25968, +25986, 26029, -26040, -26050, -26056, -26075, -26075, -26097, -26122, -26136, -26136, -26136, -26164, -26164, -26180, -26213, -26250, -26250, -26260, -26317, -26317, -26344, -26352, -26386, -26414, -26427, -26477, -26477, -26477, -26483, -26483, -26499, -26505, -26546, -26546, -26564, -26564, -26581, -26591, -26591, -26599, -26599, -26637, -26637, -26649, -26678, -26694, -26694, +26055, +26066, +26105, +26123, +26133, +26188, +26188, +26205, +26223, +26236, +26268, +26282, +26296, +26346, +26365, +26381, +26420, +26508, +26535, +26538, +26550, +26574, +26596, +26625, +26628, +26647, +26656, +26669, +26680, +26710, 26743, -26743, -26756, -26788, -26792, -26800, +26750, +26770, +26773, +26773, +26787, +26787, +26799, 26816, -26825, -26850, -26860, -26860, -26860, -26860, -26876, -26876, -26876, -26903, -26910, -26916, -26916, -26928, -26942, -26968, -26997, -27017, -27058, -27074, -27074, -27074, -27082, -27082, -27088, -27088, -27088, -27146, -27158, -27158, -27184, -27184, -27184, -27184, -27184, -27220, -27250, -27259, -27259, -27280, -27293, -27293, -27293, -27293, -27302, -27324, -27342, -27342, -27342, -27342, -27342, -27342, -27361, -27368, -27368, -27368, -27378, -27401, -27401, -27433, -27453, -27453, -27453, -27453, -27472, -27492, -27492, -27496, -27505, -27505, -27517, -27553, -27553, -27578, +26831, +26831, +26859, +26875, +26937, +26952, +26992, +27011, +27027, +27030, +27030, +27046, +27053, +27080, +27080, +27080, +27080, +27123, +27123, +27130, +27140, +27156, +27215, +27226, +27246, +27270, +27278, +27278, +27312, +27343, +27350, +27350, +27362, +27369, +27379, +27407, +27407, +27431, +27448, +27455, +27455, +27462, +27484, +27516, +27522, +27529, +27545, +27545, 27584, -27584, -27618, -27630, -27665, -27683, -27683, -27683, -27683, -27691, -27697, -27730, -27737, -27756, -27791, -27791, -27813, -27820, -27820, -27820, -27820, -27844, -27844, -27854, -27854, -27854, -27854, -27854, -27859, +27625, +27632, +27639, +27649, +27660, +27679, +27686, +27686, +27709, +27709, +27727, +27746, +27753, +27775, +27781, +27788, +27793, +27811, 27873, 27873, -27873, -27880, -27880, -27913, -27959, -27976, -27976, -28011, -28011, +27910, +27917, +27955, +27979, +27979, +27994, +28036, 28046, -28052, -28052, -28052, -28071, -28071, -28093, -28093, -28107, -28107, -28107, -28107, -28113, -28123, -28140, -28160, -28171, -28199, -28199, -28199, -28215, -28215, -28215, -28215, -28215, -28242, -28283, -28283, -28290, -28290, -28290, -28301, -28301, -28313, -28336, -28342, -28351, -28382, -28386, -28386, -28400, -28431, -28435, -28446, -28458, -28475, -28475, -28481, -28503, -28510, -28524, -28604, -28624, -28624, -28634, -28645, -28645, -28650, -28650, -28683, -28683, -28698, -28731, -28735, -28735, -28735, -28772, -28779, -28797, -28815, -28815, -28815, -28840, -28864, -28880, -28891, -28891, -28912, -28916, -28922, -28934, -28934, -28944, -28952, -29010, -29010, -29010, -29016, -29016, -29025, -29025, -29035, -29043, +28053, +28110, +28120, +28120, +28141, +28189, +28196, +28196, +28241, +28244, +28266, +28308, +28345, +28345, +28352, +28380, +28380, +28395, +28395, +28415, +28436, +28443, +28469, +28476, +28499, +28506, +28531, +28545, +28552, +28559, +28585, +28612, +28618, +28618, +28642, +28659, +28659, +28666, +28691, +28714, +28714, +28729, +28767, +28801, +28832, +28839, +28875, +28905, +28905, +28917, +28936, +28963, +28963, +28979, +28979, +28986, +29039, +29049, 29077, -29096, -29096, -29096, -29100, -29100, -29100, -29100, -29106, -29129, +29084, +29115, 29142, -29148, -29148, -29148, -29148, -29148, -29148, -29167, -29175, -29201, -29210, -29210, -29218, -29223, -29223, -29232, -29269, -29269, -29315, -29336, -29385, -29394, -29394, -29394, -29406, -29410, -29423, +29152, +29208, +29222, +29229, +29250, +29264, +29289, +29303, +29318, +29318, +29342, +29342, +29342, +29362, +29369, +29369, +29405, +29405, 29436, 29436, -29456, -29469, -29469, -29509, -29509, -29528, -29540, -29550, -29560, -29560, -29560, -29569, -29569, -29598, -29606, -29606, -29618, -29636, -29636, -29648, -29665, -29691, -29691, -29691, -29691, -29698, -29716, -29737, -29762, -29762, -29811, -29811, -29811, -29827, -29827, -29827, -29834, -29834, -29858, -29864, +29464, +29464, +29464, +29464, +29471, +29471, +29476, +29483, +29488, +29500, +29543, +29556, +29561, +29576, +29593, +29613, +29620, +29620, +29627, +29627, +29627, +29634, +29641, +29651, +29658, +29675, +29748, +29783, +29800, +29807, +29829, +29829, 29874, -29905, -29921, -29933, -29955, -29979, -29987, -29993, -30026, -30040, -30063, -30077, -30081, -30081, -30090, -30100, -30128, -30128, -30128, -30164, -30164, -30192, -30211, -30211, -30211, -30211, -30238, -30261, -30261, -30273, -30290, -30306, -30322, -30322, -30330, -30330, -30347, -30363, -30363, -30391, -30400, -30400, -30400, -30427, -30427, -30437, -30437, -30444, -30454, -30475, -30475, -30475, -30506, -30506, -30531, -30537, -30547, -30565, -30599, -30610, -30643, -30643, -30643, -30643, -30673, -30699, -30735, -30735, -30765, -30765, -30780, -30791, -30791, -30807, -30829, -30829, -30854, -30864, -30882, -30892, -30892, -30892, -30898, -30898, -30898, -30898, -30898, -30898, -30898, -30910, -30929, -30929, -30957, -30957, -30957, -30987, -31009, +29890, +29911, +29918, +29918, +29937, +29949, +29949, +29967, +30032, +30066, +30076, +30104, +30104, +30104, +30121, +30154, +30154, +30177, +30193, +30193, +30208, +30222, +30272, +30272, +30279, +30315, +30355, +30362, +30376, +30413, +30438, +30457, +30516, +30523, +30533, +30612, +30621, +30648, +30656, +30685, +30697, +30715, +30732, +30784, +30848, +30855, +30877, +30888, +30888, +30905, +30932, +30946, +30978, +30978, +31032, 31039, -31080, -31086, -31086, -31098, -31114, -31127, -31141, -31150, -31150, -31150, -31209, -31209, -31227, -31250, -31257, -31257, -31293, -31325, -31334, -31334, -31334, -31334, -31334, -31340, -31340, -31380, -31418, -31436, -31452, -31452, -31468, -31468, -31502, -31511, -31517, -31517, -31517, -31517, -31537, -31547, -31547, -31554, -31554, -31566, -31589, -31589, -31589, -31599, -31607, -31646, -31696, -31696, -31696, -31696, -31708, -31708, -31708, -31718, -31718, -31754, -31768, -31776, -31791, -31791, -31811, -31827, -31852, -31879, -31879, -31879, -31889, -31889, -31907, -31913, -31913, +31053, +31060, +31082, +31128, +31128, +31155, +31155, +31155, +31195, +31195, +31195, +31195, +31202, +31202, +31222, +31222, +31230, +31241, +31241, +31241, +31308, +31320, +31327, +31327, +31327, +31354, +31375, +31399, +31424, +31431, +31448, +31469, +31469, +31476, +31487, +31504, +31534, +31534, +31593, +31593, +31593, +31593, +31593, +31593, +31598, +31619, +31632, +31647, +31658, +31705, +31731, +31752, +31759, +31780, +31817, +31817, +31821, +31825, +31830, +31830, +31830, +31830, +31836, +31860, +31869, +31869, +31887, +31887, +31887, +31887, +31894, 31919, -31919, -31939, -31939, -31955, -31975, -31981, -31981, -31981, -31997, -31997, -32008, -32025, -32025, -32039, -32060, -32090, -32090, -32101, -32101, -32111, -32111, -32111, -32125, -32125, -32154, -32162, -32162, -32173, -32178, -32187, -32197, -32216, -32237, -32258, -32258, -32277, -32287, -32294, -32294, -32304, -32323, -32323, -32342, -32352, -32363, -32378, -32378, -32396, -32403, -32403, -32403, -32403, -32448, -32463, -32485, -32518, -32518, -32539, -32539, -32539, -32539, -32539, -32539, -32539, -32554, -32563, -32596, -32654, -32708, -32722, -32722, -32758, -32778, -32778, -32798, +31924, +31924, +31924, +31958, +31968, +31968, +31977, +31989, +32000, +32000, +32007, +32024, +32038, +32064, +32069, +32069, +32085, +32085, +32096, +32118, +32118, +32130, +32137, +32165, +32165, +32204, +32217, +32234, +32242, +32264, +32314, +32327, +32334, +32334, +32343, +32343, +32359, +32359, +32385, +32385, +32385, +32420, +32420, +32420, +32420, +32468, +32468, +32506, +32506, +32506, +32523, +32569, +32569, +32569, +32576, +32576, +32576, +32576, +32604, +32612, +32612, +32632, +32666, +32683, +32728, +32749, +32749, +32749, +32756, +32756, +32765, 32807, -32830, -32840, -32840, -32840, -32848, -32848, -32848, -32859, +32807, +32807, +32817, +32837, +32837, +32856, 32875, 32875, -32903, -32949, -32964, -32975, -32984, -33001, -33008, -33028, -33046, -33046, -33046, -33070, -33070, -33092, -33107, -33121, -33135, -33142, -33151, -33169, -33169, -33169, -33177, -33177, -33184, -33211, -33242, -33254, -33271, -33282, -33282, -33289, -33296, -33314, -33321, -33321, -33337, -33337, -33355, -33355, -33367, -33367, -33380, -33380, -33393, -33404, +32875, +32914, +32914, +32914, +32921, +32921, +32938, +32956, +33021, +33021, +33050, +33064, +33075, +33102, +33102, +33102, +33102, +33109, +33109, +33122, +33145, +33164, +33164, +33171, +33171, +33171, +33171, +33187, +33187, +33187, +33195, +33195, +33268, +33277, +33277, +33277, +33281, +33281, +33297, +33297, +33297, +33297, +33313, +33320, +33320, +33320, +33333, +33333, +33368, +33387, +33409, +33413, +33417, 33430, +33430, +33446, 33455, -33455, -33475, -33485, -33505, -33520, +33467, +33472, +33498, +33498, +33527, 33537, -33555, -33555, -33555, -33574, -33574, -33580, -33587, -33587, -33612, -33612, -33629, -33629, -33654, -33654, -33661, -33711, -33711, -33724, -33747, -33747, -33779, -33779, -33785, -33802, -33802, -33824, -33824, -33845, -33855, -33863, -33885, -33920, -33938, -34008, -34008, -34008, -34015, -34015, -34015, -34032, -34037, -34037, -34049, -34059, -34071, -34078, -34097, -34097, -34097, -34126, -34146, -34165, -34181, -34181, -34191, -34210, -34210, -34222, -34247, -34247, -34253, +33547, +33565, +33602, +33602, +33617, +33617, +33633, +33645, +33662, +33673, +33681, +33698, +33698, +33705, +33719, +33726, +33754, +33754, +33783, +33793, +33843, +33868, +33868, +33876, +33876, +33876, +33925, +33936, +33947, +33947, +33947, +33965, +33986, +33986, +33986, +33986, +34050, +34089, +34089, +34098, +34112, +34124, +34128, +34173, +34173, +34173, +34173, +34194, +34209, +34209, +34228, +34263, 34267, -34324, -34346, -34377, -34377, -34377, -34377, -34405, -34437, -34484, -34494, -34547, -34547, -34547, -34547, -34558, -34558, -34596, -34596, -34607, -34607, -34612, -34638, -34664, -34664, -34680, -34680, -34697, -34697, -34697, -34697, -34710, -34725, -34725, -34725, -34725, -34745, -34755, -34755, -34775, -34802, -34802, -34813, -34831, -34839, -34839, -34839, -34856, -34911, -34915, -34915, -34975, -35018, -35025, -35041, -35090, -35111, -35133, -35152, -35152, -35152, -35169, -35179, -35179, -35179, -35179, -35189, -35204, -35238, -35238, -35257, -35257, -35275, -35275, -35298, -35308, -35308, -35308, -35308, -35316, -35323, -35352, -35377, -35435, -35450, -35450, -35450, -35458, -35458, -35472, -35472, -35479, -35479, -35489, -35493, -35522, -35537, -35549, -35568, -35586, -35596, -35596, -35596, -35618, -35618, -35637, -35650, -35667, -35675, -35690, -35694, -35735, -35735, -35735, +34275, +34282, +34353, +34376, +34400, +34428, +34441, +34441, +34512, +34549, +34549, +34567, +34567, +34577, +34598, +34616, +34627, +34635, +34635, +34657, +34657, +34666, +34671, +34678, +34678, +34678, +34678, +34685, +34706, +34746, +34751, +34751, +34774, +34774, +34784, +34807, +34819, +34819, +34835, +34835, +34913, +34913, +34913, +34932, +34951, +34951, +34956, +34974, +34974, +34992, +35003, +35026, +35031, +35053, +35059, +35098, +35108, +35114, +35139, +35149, +35162, +35181, +35181, +35190, +35209, +35222, +35222, +35222, +35222, +35222, +35226, +35226, +35226, +35226, +35251, +35251, +35302, +35302, +35302, +35302, +35351, +35351, +35387, +35387, +35387, +35387, +35391, +35424, +35440, +35462, +35462, +35498, +35505, +35505, +35505, +35505, +35520, +35529, +35545, +35545, +35555, +35562, +35562, +35594, +35594, +35621, +35621, +35640, +35646, +35646, +35646, +35659, +35659, +35680, 35744, -35749, -35749, -35756, -35756, -35756, -35775, -35775, -35793, -35793, -35815, -35832, -35838, -35838, -35838, -35869, -35884, -35884, -35904, -35918, -35951, -35951, -35979, -35979, -35984, -35984, -35993, -35993, -35997, -36022, -36046, -36063, -36063, -36063, -36063, -36069, -36086, -36092, -36092, -36092, -36111, -36119, -36130, -36130, -36134, -36144, -36144, -36144, -36159, -36181, -36181, -36181, -36181, -36219, -36223, -36228, -36228, -36228, -36228, -36228, -36228, -36228, -36228, -36280, -36299, -36309, -36309, -36316, +35751, +35751, +35777, +35796, +35796, +35796, +35810, +35822, +35836, +35842, +35858, +35858, +35901, +35901, +35901, +35901, +35965, +35965, +35973, +35986, +35986, +35986, +36000, +36006, +36014, +36014, +36031, +36045, +36045, +36045, +36057, +36066, +36066, +36066, +36066, +36083, +36083, +36088, +36088, +36102, +36109, +36120, +36120, +36143, +36147, +36147, +36166, +36177, +36202, +36217, +36242, +36278, +36278, +36278, +36293, +36293, +36322, 36334, -36352, -36352, -36370, -36377, -36407, -36416, -36426, -36442, -36456, -36463, -36463, -36463, -36463, -36463, -36463, -36482, -36489, -36489, -36489, -36489, -36500, +36334, +36334, +36334, +36334, +36334, +36369, +36369, +36376, +36398, +36445, +36469, +36476, +36511, 36518, -36518, -36528, -36528, -36551, -36551, -36564, -36564, -36576, -36576, -36597, -36597, -36626, -36643, -36685, -36685, -36727, -36727, -36727, -36733, -36733, -36733, -36740, -36740, -36740, -36740, -36757, -36769, -36782, -36795, -36795, -36795, -36803, -36900, -36907, -36919, -36919, -36919, -36925, -36925, -36935, -36945, +36535, +36577, +36584, +36676, +36676, +36676, +36676, +36683, +36706, +36752, +36752, +36784, +36798, +36805, +36812, +36857, +36881, +36881, +36881, +36888, +36895, +36906, +36906, +36916, +36923, +36954, +36961, +36961, 36986, -36986, -37017, -37017, -37017, -37029, -37064, -37084, -37118, -37134, -37161, -37161, -37169, -37169, -37233, -37233, -37244, -37244, -37244, -37244, -37244, -37271, -37283, -37308, -37308, -37334, -37334, -37334, -37341, -37341, -37347, -37374, -37415, -37446, -37502, -37502, -37534, -37563, -37580, -37589, -37600, -37616, -37622, -37631, -37631, -37631, -37650, -37650, -37650, -37650, -37650, -37650, -37666, -37666, -37694, -37700, -37740, -37747, -37747, -37753, -37753, -37753, -37753, -37769, -37790, -37820, -37865, -37869, -37869, +37011, +37034, +37057, +37090, +37105, +37146, +37217, +37240, +37284, +37302, +37338, +37352, +37352, +37352, +37375, +37391, +37398, +37402, +37409, +37420, +37455, +37455, +37472, +37504, +37523, +37551, +37567, +37567, +37620, +37620, +37627, +37645, +37671, +37699, +37699, +37727, +37743, +37743, +37781, +37781, +37781, +37781, +37781, +37792, +37799, +37816, +37816, +37816, +37822, +37822, +37834, +37847, +37852, +37887, +37894, +37894, 37905, -37915, -37915, -37915, -37937, -37937, -37937, -37969, -37969, -37969, -37974, -37974, -37984, -37984, -37984, -37995, -37995, -38014, -38014, -38014, -38032, -38032, -38032, -38032, -38032, -38047, -38047, -38055, -38055, -38055, -38072, -38085, -38085, -38106, -38112, -38112, -38125, -38125, -38125, -38125, -38131, -38131, -38143, -38151, -38151, -38162, -38162, -38162, -38188, -38213, -38213, -38213, -38213, -38231, -38250, -38256, -38256, -38271, -38271, +37909, +37909, +37916, +37916, +37923, +37936, +37951, +37963, +37970, +38017, +38022, +38022, +38070, +38070, +38087, +38087, +38094, +38101, +38119, +38126, +38146, +38153, +38153, +38171, +38171, +38178, +38193, +38200, +38206, +38218, +38225, +38225, +38225, +38238, +38245, +38296, 38303, -38315, -38315, -38315, -38337, -38337, -38348, -38366, -38403, -38403, -38403, -38432, -38432, +38352, +38352, +38358, +38370, +38370, +38421, +38421, +38421, +38435, +38442, 38455, -38455, -38461, -38471, -38494, -38510, -38521, -38557, -38563, -38563, -38597, -38597, -38604, -38604, -38604, -38604, -38640, -38640, -38640, -38650, -38662, -38677, -38677, -38677, -38677, -38687, -38687, -38698, -38707, -38707, -38727, -38739, -38739, -38744, -38761, -38761, -38776, -38776, -38776, -38821, -38821, -38829, -38839, -38839, -38845, +38467, +38484, +38503, +38536, +38540, +38540, +38540, +38540, +38556, +38556, +38556, +38556, +38572, +38618, +38618, +38634, +38634, +38634, +38634, +38654, +38661, +38710, +38710, +38717, +38752, +38771, +38771, +38785, +38785, +38808, +38832, +38871, 38878, -38878, -38890, -38938, -38949, -38949, -38960, -38984, -38984, -38984, -38984, -39027, -39027, -39033, -39033, -39033, -39049, -39055, -39055, -39073, -39081, +38891, +38898, +38905, +38923, +38923, +38923, +38930, +38961, +38968, +38994, +39018, +39018, +39062, +39076, +39086, 39097, -39097, -39119, -39119, -39119, -39119, -39124, -39124, -39124, -39136, -39186, -39186, -39186, -39186, -39186, -39206, -39247, -39262, -39300, -39300, -39307, -39307, -39357, -39357, -39366, -39383, -39383, -39420, -39420, -39420, +39109, +39122, +39132, +39132, +39132, +39139, +39152, +39152, +39176, +39202, +39209, +39237, +39237, +39244, +39251, +39251, +39258, +39258, +39265, +39272, +39285, +39299, +39328, +39342, +39364, +39401, +39401, +39405, +39405, +39411, 39438, -39438, -39448, -39457, -39473, -39490, -39503, -39510, -39519, -39531, -39531, -39544, -39584, -39611, -39623, -39644, -39644, -39644, -39644, -39644, -39662, -39678, -39678, -39708, -39729, -39729, -39740, -39740, -39757, -39757, -39773, -39796, -39796, -39833, -39833, -39845, -39845, -39863, -39874, -39874, -39901, -39917, -39928, -39949, -39949, -39958, -40000, -40020, -40020, -40020, -40040, +39480, +39480, +39507, +39513, +39513, +39513, +39541, +39553, +39553, +39587, +39609, +39609, +39615, +39680, +39697, +39726, +39737, +39750, +39775, +39775, +39811, +39818, +39857, +39866, +39873, +39886, +39916, +39923, +39930, +39947, +39982, +39988, +39988, +40011, +40018, +40044, +40051, 40057, -40078, -40088, -40098, -40114, -40122, +40072, +40072, +40072, +40090, +40090, +40106, +40106, 40146, 40146, -40146, -40146, -40155, -40172, -40241, -40265, -40265, -40278, +40210, +40210, +40225, +40238, +40238, +40245, +40252, +40258, +40258, +40286, 40296, -40296, -40296, -40296, -40331, +40306, +40313, +40313, +40351, +40351, 40358, -40358, -40358, -40370, -40370, -40370, -40370, -40382, -40401, -40419, -40419, -40419, -40419, -40434, -40442, -40482, -40501, -40517, -40524, -40524, -40534, -40549, -40573, -40573, -40608, -40608, -40608, -40635, -40635, -40635, -40635, -40635, -40663, -40663, -40676, -40688, -40688, -40688, -40695, -40695, -40710, -40710, -40710, -40710, -40741, -40765, -40779, -40779, -40787, -40803, -40803, -40817, -40817, -40837, -40847, -40866, -40902, -40913, -40928, -40991, -40991, -41017, -41029, -41044, -41044, -41077, -41077, -41077, -41086, +40403, +40410, +40417, +40424, +40431, +40463, +40476, +40483, +40525, +40595, +40629, +40629, +40656, +40656, +40673, +40690, +40709, +40709, +40715, +40745, +40774, +40778, +40785, +40827, +40843, +40861, +40885, +40892, +40892, +40899, +40912, +40919, +40924, +40931, +40938, +41047, +41076, +41076, 41091, -41091, -41114, -41114, -41123, -41123, -41123, -41138, -41138, -41138, -41176, -41243, -41243, -41243, -41243, -41248, -41266, -41307, -41307, -41345, +41105, +41105, +41131, +41162, +41174, +41181, +41190, +41190, +41194, +41225, +41225, +41262, +41295, +41295, +41319, +41319, +41319, +41328, +41342, +41349, +41360, +41360, +41377, 41396, -41405, -41432, -41432, -41441, -41441, -41441, -41441, -41462, -41476, -41491, -41519, -41519, -41519, -41526, -41535, -41560, -41560, -41560, -41585, -41611, -41637, -41637, -41653, -41653, -41653, -41666, -41666, -41681, -41690, -41690, -41690, -41708, -41726, -41730, -41730, +41396, +41424, +41456, +41456, +41468, +41508, +41525, +41543, +41543, +41552, +41552, +41552, +41552, +41552, +41552, +41552, +41552, +41567, +41577, +41577, +41596, +41603, +41603, +41603, +41621, +41639, +41639, +41659, +41659, +41659, +41659, +41659, +41692, +41692, +41692, +41692, +41692, +41712, 41730, +41751, +41751, 41770, -41774, -41787, -41787, -41787, +41770, +41770, +41783, 41801, -41801, -41817, -41835, -41847, -41860, -41860, -41874, -41874, -41891, -41929, -41938, -41938, -41938, -41948, -41948, -41965, -41978, -41978, -41978, -41992, -42004, -42016, -42043, -42098, -42098, -42098, -42098, -42098, -42098, -42098, -42098, -42098, -42118, -42118, -42118, -42138, -42158, -42158, -42169, -42169, -42212, -42212, -42234, -42249, -42265, -42265, -42282, -42282, -42294, -42294, -42310, -42310, -42310, -42321, -42321, -42321, -42362, -42369, -42379, -42396, -42396, -42416, -42447, -42447, -42458, -42458, -42474, -42533, -42549, -42574, -42609, -42609, -42621, -42639, -42684, -42708, -42717, -42800, -42800, -42800, -42800, -42800, -42812, -42857, -42883, -42898, -42910, -42910, -42927, -42927, -42936, -42936, -42936, -42950, -42950, -42973, -42973, -42973, -42973, -42973, -42984, -42996, -42996, -43015, -43047, -43047, -43068, -43095, -43095, -43095, -43095, -43100, -43100, -43100, -43115, -43131, -43131, +41809, +41816, +41834, +41853, +41853, +41853, +41866, +41866, +41866, +41866, +41902, +41943, +41975, +41975, +41975, +41996, +42013, +42040, +42051, +42064, +42087, +42087, +42087, +42106, +42126, +42182, +42196, +42203, +42203, +42246, +42253, +42272, +42272, +42298, +42343, +42343, +42343, +42372, +42419, +42456, +42462, +42480, +42493, +42518, +42529, +42535, +42535, +42535, +42535, +42555, +42567, +42581, +42616, +42616, +42626, +42662, +42685, +42685, +42740, +42740, +42766, +42794, +42798, +42798, +42798, +42809, +42839, +42839, +42839, +42844, +42854, +42854, +42869, +42879, +42929, +42988, +42997, +43003, +43014, +43025, +43059, +43059, +43108, +43108, +43108, +43118, +43136, 43152, -43176, -43176, -43176, -43176, -43196, +43168, +43185, 43219, -43242, -43242, -43246, -43270, -43270, -43270, -43278, -43288, -43321, -43329, -43349, -43370, -43370, -43370, -43370, -43382, -43407, -43411, -43427, -43435, -43450, -43450, -43463, -43567, -43567, -43584, -43609, -43609, -43627, -43627, -43627, -43700, -43717, -43756, -43768, -43768, -43768, -43768, -43779, +43234, +43234, +43241, +43241, +43241, +43253, +43253, +43257, +43257, +43257, +43257, +43257, +43267, +43285, +43295, +43361, +43361, +43361, +43378, +43397, +43397, +43397, +43418, +43418, +43418, +43428, +43428, +43428, +43436, +43451, +43456, +43488, +43488, +43488, +43488, +43488, +43504, +43504, +43522, +43522, +43540, +43547, +43547, +43570, +43570, +43570, +43570, +43576, +43583, +43590, +43618, +43618, +43629, +43643, +43663, +43670, +43709, +43744, +43759, 43787, -43828, -43833, -43833, -43873, -43873, -43883, -43883, -43893, -43893, -43893, -43893, -43893, -43905, -43905, -43905, -43905, -43930, -43930, -43930, -43930, -43956, -43960, -43979, -43990, -44038, -44070, -44070, -44070, +43879, +43885, +43934, +43934, +43940, +43945, +43965, +43972, +43998, +43998, +44015, +44031, +44057, +44057, +44057, +44057, +44073, +44073, 44086, -44086, -44109, -44113, -44113, -44113, -44120, -44130, -44155, -44155, -44155, -44165, -44165, -44183, -44190, -44200, +44137, +44189, +44196, 44215, 44215, -44222, -44222, -44243, -44243, -44250, -44250, -44269, -44286, -44286, -44286, -44295, +44260, +44260, +44260, +44260, +44264, +44270, +44270, 44313, -44313, -44336, -44336, -44353, -44353, -44353, -44364, -44364, -44381, +44324, +44354, +44379, +44379, +44386, 44408, -44425, -44425, -44425, -44439, -44464, -44471, -44471, +44458, 44481, 44481, -44496, -44509, -44509, -44515, -44515, -44550, -44565, -44565, -44606, -44628, -44628, -44641, -44649, -44664, -44664, -44664, -44682, -44691, -44708, -44723, -44747, -44770, -44770, -44777, -44777, -44777, -44777, -44792, -44799, -44806, -44806, -44806, -44824, -44830, -44835, +44481, +44481, +44481, +44481, +44481, +44481, +44488, +44520, +44538, +44571, +44571, +44591, +44598, +44604, +44615, +44625, +44638, +44638, +44638, +44657, +44674, +44692, +44692, +44692, +44737, +44758, +44758, +44775, +44784, +44801, +44801, +44801, +44812, +44826, +44834, 44852, -44852, -44874, -44874, -44889, -44926, -44964, -44964, -44980, -44987, -44994, -44994, -45015, -45050, -45065, -45074, -45078, -45110, -45117, -45144, -45156, -45156, -45156, -45156, -45163, -45163, -45180, -45194, -45194, -45225, -45225, -45240, -45270, -45280, -45280, -45297, -45304, -45326, -45347, -45403, -45410, -45410, -45410, -45429, -45429, -45429, -45448, -45448, -45448, -45465, -45465, -45509, -45526, -45526, -45536, -45546, -45546, -45560, -45560, -45569, -45569, -45595, -45603, -45603, -45650, -45650, -45650, -45667, -45707, -45707, -45721, -45736, -45740, -45740, -45751, -45751, -45762, -45762, -45808, -45831, -45835, -45854, -45854, -45888, -45888, -45894, -45906, -45918, -45918, -45945, -45996, -45996, -45996, -46007, -46023, -46023, -46041, -46057, -46057, -46057, -46075, -46091, -46091, -46097, -46116, -46128, -46128, -46160, -46170, -46170, -46220, -46224, -46224, -46252, -46262, -46266, -46266, -46280, -46295, -46322, -46322, -46322, -46337, -46337, -46337, -46348, -46348, -46348, -46352, -46359, -46378, -46378, -46378, -46397, -46397, -46419, -46431, -46451, -46455, -46481, -46487, -46494, +44864, +44864, +44879, +44886, +44886, +44886, +44886, +44893, +44893, +44897, +44897, +44942, +44961, +44968, +44975, +44996, +44996, +45003, +45003, +45016, +45016, +45016, +45080, +45093, +45093, +45108, +45108, +45143, +45152, +45159, +45159, +45171, +45184, +45211, +45248, +45255, +45255, +45295, +45310, +45317, +45352, +45412, +45412, +45426, +45471, +45495, +45495, +45511, +45518, +45523, +45529, +45535, +45535, +45552, +45558, +45583, +45583, +45583, +45606, +45612, +45641, +45659, +45659, +45659, +45714, +45714, +45752, +45766, +45776, +45789, +45789, +45789, +45805, +45842, +45886, +45886, +45886, +45886, +45886, +45898, +45916, +45930, +45951, +45969, +45969, +45999, +46011, +46024, +46024, +46042, +46073, +46080, +46080, +46080, +46080, +46111, +46131, +46141, +46190, +46213, +46226, +46226, +46226, +46226, +46226, +46245, +46245, +46245, +46272, +46279, +46334, +46371, +46432, +46453, +46453, +46459, +46484, +46498, +46498, +46498, +46506, +46506, +46506, +46523, +46523, +46523, 46542, -46542, -46542, -46550, -46554, -46560, -46578, -46617, -46624, -46674, +46549, +46573, +46579, +46593, +46600, +46600, +46616, +46640, +46640, +46647, 46681, -46681, -46681, -46698, -46706, -46706, -46715, -46715, -46715, -46715, -46729, -46785, -46807, -46807, -46824, -46832, -46832, -46848, -46848, -46848, -46858, -46872, -46884, -46884, -46884, -46884, -46908, -46908, -46915, -46915, -46954, -46968, -46968, -46986, -47012, -47012, -47012, -47012, -47034, -47044, -47049, -47049, -47056, -47056, -47067, -47067, -47067, -47090, -47090, -47120, -47120, -47124, -47124, +46693, +46703, +46719, +46719, +46730, +46747, +46747, +46761, +46761, +46809, +46809, +46828, +46828, +46828, +46828, +46828, +46838, +46838, +46838, +46838, +46860, +46860, +46899, +46923, +46923, +46923, +46923, +46930, +46939, +46939, +46956, +46999, +47084, +47084, +47084, +47091, +47091, +47099, +47110, +47110, +47125, 47142, -47189, -47189, -47221, -47284, -47284, -47284, -47284, -47290, +47201, +47201, +47224, +47268, +47268, +47279, +47279, +47279, 47310, -47310, -47331, -47341, -47384, -47384, -47392, -47392, -47392, -47392, -47392, -47392, -47392, -47410, -47424, -47481, -47481, -47481, -47481, -47481, -47481, -47490, +47344, +47344, +47348, +47364, +47402, +47413, +47429, +47443, +47461, +47496, +47496, 47512, -47531, -47531, -47531, -47542, -47542, -47542, -47542, -47542, -47552, -47563, -47585, -47605, -47620, -47641, -47665, -47665, -47675, -47688, -47692, -47692, -47700, -47700, -47700, -47715, -47732, -47744, -47766, -47766, -47793, -47793, -47793, -47793, -47844, -47854, -47860, -47880, -47880, -47906, -47930, -47930, -47930, -47945, -47974, -47997, -47997, -47997, -47997, -48004, -48004, -48014, -48038, -48038, -48038, +47512, +47550, +47571, +47615, +47625, +47638, +47669, +47676, +47683, +47695, +47719, +47814, +47845, +47862, +47874, +47874, +47887, +47898, +47898, +47933, +47940, +47940, +47940, +47981, +47995, +48002, +48020, +48041, +48041, 48048, -48091, -48109, -48119, -48119, -48148, -48162, -48190, -48213, -48220, -48232, -48238, -48238, -48238, -48244, -48291, -48298, -48324, -48324, -48324, -48324, -48324, -48332, -48332, -48332, -48360, -48379, +48048, +48103, +48113, +48120, +48127, +48141, +48180, +48234, +48234, +48241, +48241, +48253, +48260, +48260, +48278, +48315, +48315, +48334, +48354, +48354, +48354, +48361, +48368, +48375, 48386, -48386, -48386, -48392, -48406, -48419, -48419, -48425, -48425, -48425, -48429, -48446, -48446, -48452, -48452, -48452, -48459, -48479, -48492, -48508, -48525, -48525, -48537, -48537, -48553, -48568, -48568, -48595, -48595, -48610, -48627, -48657, -48670, -48701, -48707, -48707, -48726, -48726, -48726, -48726, -48748, -48748, -48764, -48764, -48825, -48825, -48825, -48869, +48397, +48412, +48462, +48483, +48483, +48516, +48578, +48578, +48603, +48636, +48636, +48673, +48673, +48673, +48682, +48682, +48744, +48754, +48762, +48804, +48855, +48878, +48885, 48896, -48903, -48922, -48942, -48952, -48998, -49019, -49019, -49052, -49076, -49085, -49085, -49108, -49120, -49120, -49120, -49124, -49124, -49124, -49171, -49171, -49171, -49182, -49182, -49199, -49222, -49222, -49239, -49239, -49246, -49258, -49286, -49302, -49307, -49307, +48896, +48896, +48896, +48917, +48973, +48985, +48985, +48996, +48996, +48996, +48996, +48996, +49010, +49042, +49042, +49042, +49042, +49042, +49042, +49053, +49053, +49064, +49092, +49106, +49106, +49106, +49106, +49123, +49142, +49184, +49211, +49221, +49221, +49221, +49228, +49250, +49250, +49266, +49266, +49266, +49285, +49316, +49316, +49316, +49316, +49332, 49339, -49352, -49378, -49383, -49383, -49392, -49399, -49417, -49447, -49458, -49458, -49505, -49505, -49505, -49515, -49515, -49519, -49530, -49565, -49565, -49571, -49590, -49636, -49656, -49665, -49707, -49735, -49735, -49735, -49740, -49756, -49756, -49756, -49769, -49778, -49792, -49805, -49819, -49819, -49829, -49847, -49860, -49884, -49894, -49907, -49907, -49920, -49941, -49941, -49955, -49965, -49985, +49368, +49384, +49384, +49384, +49403, +49420, +49420, +49428, +49466, +49489, +49489, +49547, +49563, +49563, +49563, +49563, +49598, +49603, +49614, +49614, +49614, +49635, +49635, +49644, +49654, +49668, +49668, +49687, +49687, +49693, +49693, +49698, +49739, +49771, +49780, +49780, +49803, +49822, +49822, +49822, +49822, +49822, +49840, +49873, +49873, +49885, +49900, +49900, +49912, +49912, +49926, +49926, +49961, +49974, +49974, +49980, +49980, +49989, +50006, 50011, -50011, -50023, -50023, -50044, -50044, -50082, -50082, -50082, -50088, -50106, -50123, -50123, -50123, -50131, -50164, -50164, -50164, -50184, -50213, -50242, -50252, -50252, -50259, -50268, -50268, -50268, -50281, -50287, -50292, -50299, -50318, -50324, -50324, -50324, -50324, -50324, -50342, -50353, -50353, -50376, -50382, +50018, +50018, +50018, +50073, +50073, +50091, +50091, +50155, +50182, +50191, +50211, +50211, +50231, +50231, +50231, +50254, +50270, +50270, +50270, +50290, +50301, +50301, +50301, +50301, +50301, +50323, +50345, +50345, +50370, +50370, +50399, +50399, 50417, -50439, -50493, -50500, -50500, -50537, -50557, -50557, -50557, -50571, -50571, -50589, -50589, -50624, +50417, +50433, +50433, +50433, +50459, +50459, +50498, +50515, +50590, +50590, +50594, +50594, 50658, -50673, -50673, -50688, -50707, -50707, -50713, +50690, +50690, +50697, +50697, +50722, 50733, -50750, -50774, -50808, -50816, -50839, -50856, -50875, -50897, -50897, -50897, -50897, -50897, -50897, -50921, -50936, -50936, -50945, -50945, -50945, -50969, -50969, -50969, -50976, -50986, -50993, -50993, -51019, -51040, -51056, -51103, -51120, -51120, -51120, -51146, -51146, -51146, -51161, -51161, -51170, -51212, -51212, -51212, -51244, -51259, -51280, -51280, -51297, -51297, -51304, -51323, -51327, -51327, -51334, -51348, -51356, -51370, -51397, -51397, -51422, -51422, +50733, +50765, +50790, +50806, +50821, +50831, +50866, +50885, +50907, +50907, +50971, +50978, +50978, +51005, +51022, +51022, +51022, +51043, +51049, +51110, +51110, +51117, +51142, +51214, +51243, +51243, +51272, +51279, +51295, +51295, +51330, +51351, +51366, +51393, +51400, +51410, +51410, +51410, +51436, 51468, -51482, -51507, -51536, -51543, -51550, -51563, -51570, -51582, -51589, -51589, -51612, -51619, -51626, -51633, -51633, -51633, -51647, -51654, -51678, -51696, -51710, -51716, -51730, -51778, -51801, -51819, -51826, -51833, -51840, -51847, -51847, -51923, -51932, -51940, -51955, -51983, -51983, -51983, -51997, -52004, -52024, -52024, -52024, -52031, -52031, -52046, -52056, -52056, -52068, -52075, -52084, -52098, -52098, -52126, -52144, -52151, -52158, -52165, -52175, -52175, -52175, -52199, -52220, -52225, -52225, -52235, -52258, -52258, -52266, +51468, +51468, +51516, +51524, +51524, +51529, +51529, +51553, +51567, +51567, +51577, +51595, +51595, +51595, +51629, +51643, +51676, +51676, +51676, +51676, +51699, +51714, +51741, +51741, +51771, +51779, +51779, +51779, +51779, +51806, +51815, +51853, +51874, +51890, +51910, +51929, +51962, +51962, +51970, +52037, +52064, +52115, +52148, +52169, +52194, +52218, +52218, +52245, +52261, +52271, +52271, 52279, -52310, -52310, -52317, -52349, -52366, -52385, -52414, -52426, -52426, -52426, -52451, +52279, +52305, +52305, +52305, +52305, +52305, +52321, +52321, +52321, +52348, +52377, +52377, +52377, +52377, +52377, +52386, +52403, +52428, +52428, 52469, -52482, -52489, -52497, -52497, -52511, -52534, -52534, -52557, -52599, -52599, -52606, -52616, -52622, +52469, +52469, +52524, +52539, +52539, +52553, +52558, +52569, +52569, +52581, +52598, +52614, +52614, +52619, +52619, +52631, 52639, -52678, -52678, -52726, -52763, -52785, -52791, -52808, -52815, -52824, -52847, -52851, -52851, -52851, -52865, -52865, -52895, -52924, -52942, -52942, -52949, -52969, -53012, -53033, -53033, -53033, -53055, -53062, -53089, -53096, -53117, -53137, -53168, -53175, -53200, -53224, -53260, -53286, -53304, -53320, -53331, -53357, -53357, -53383, -53399, -53399, -53406, -53418, -53464, -53464, +52650, +52657, +52657, +52657, +52671, +52671, +52691, +52691, +52691, +52713, +52799, +52816, +52816, +52816, +52869, +52919, +52934, +52953, +52953, +52953, +53006, +53048, +53124, +53144, +53152, +53152, +53152, +53152, +53159, +53216, +53221, +53221, +53232, +53271, +53287, +53287, +53287, +53292, +53309, +53309, +53316, +53350, +53401, +53422, +53422, +53451, +53456, +53465, +53481, 53491, 53491, 53491, 53491, -53517, -53530, -53555, -53567, -53657, -53689, -53729, -53736, -53755, -53780, +53521, +53532, +53541, +53541, +53559, +53566, +53566, +53583, +53602, +53611, +53623, +53637, +53666, +53685, +53685, +53692, +53692, +53725, +53725, +53779, +53779, +53800, 53813, -53820, -53835, -53852, -53870, -53881, -53939, +53813, +53834, +53841, +53841, +53862, +53898, +53905, +53905, +53925, 53943, -53997, -54023, -54030, -54030, -54048, -54048, -54058, -54082, -54096, -54103, -54110, -54117, -54154, -54170, -54190, -54190, -54205, -54205, -54212, -54236, -54236, -54271, -54305, -54315, -54315, -54322, -54335, -54335, -54349, -54366, -54391, -54404, -54442, -54449, -54464, -54471, -54471, -54500, -54522, -54528, -54534, -54547, -54553, -54553, -54553, -54559, -54592, -54597, -54638, -54649, -54681, -54693, -54700, -54700, -54700, -54700, -54707, -54737, -54737, -54748, -54748, -54784, +53963, +53963, +53968, +53980, +53995, +54024, +54024, +54033, +54051, +54051, +54051, +54091, +54091, +54091, +54091, +54108, +54126, +54184, +54194, +54210, +54210, +54226, +54284, +54299, +54299, +54312, +54337, +54361, +54394, +54412, +54412, +54412, +54423, +54456, +54498, +54498, +54498, +54498, +54510, +54510, +54510, +54510, +54510, +54531, +54531, +54551, +54577, +54586, +54586, +54630, +54639, +54654, +54654, +54664, +54684, +54684, +54717, +54717, +54724, +54742, +54762, +54778, +54778, +54794, +54807, +54807, 54826, -54842, -54848, -54864, -54894, -54907, -54937, -54976, -55009, -55021, -55028, -55035, -55079, -55086, -55114, -55127, -55164, -55164, -55183, -55190, -55190, -55190, -55199, -55231, -55231, -55248, +54826, +54831, +54831, +54831, +54831, +54850, +54850, +54850, +54850, +54850, +54850, +54850, +54870, +54920, +54920, +54920, +54971, +54971, +54971, +54971, +54971, +54971, +54978, +54978, +54978, +54978, +54992, +55016, +55016, +55058, +55075, +55090, +55123, +55133, +55133, +55133, +55146, +55182, +55209, +55216, +55240, 55258, -55291, -55291, -55309, -55320, -55335, -55335, -55356, -55365, -55365, -55394, -55394, -55404, -55404, -55428, -55444, -55459, -55481, -55501, -55521, +55258, +55274, +55289, +55289, +55325, +55337, +55344, +55344, +55348, +55357, +55376, +55416, +55431, +55436, +55453, +55453, +55480, +55508, 55535, -55556, -55570, -55596, -55616, -55661, -55661, -55677, -55677, +55542, +55542, +55542, +55572, +55572, +55611, +55621, +55650, +55650, +55669, +55674, +55681, +55688, +55688, +55694, 55705, -55712, -55712, -55730, -55730, -55749, -55749, -55749, -55761, -55776, -55783, -55790, -55797, -55797, -55829, -55836, -55843, -55861, -55861, -55904, -55926, -55926, -55933, -55959, -55959, -55971, -55971, -55971, -55971, -55992, -56023, -56031, -56031, -56038, -56076, -56076, -56086, -56106, -56128, -56135, -56135, -56146, -56154, -56154, -56154, -56174, -56174, -56187, -56207, -56207, -56229, -56268, -56286, -56322, -56339, -56386, -56386, -56413, -56413, -56438, -56495, -56495, -56495, -56501, -56519, -56526, -56526, -56526, -56526, -56533, -56542, -56560, -56566, -56588, -56588, -56598, -56626, -56626, -56642, -56659, -56672, -56672, -56688, -56688, -56709, -56741, -56741, -56748, -56748, -56748, -56758, -56780, -56780, -56799, -56845, -56845, -56875, -56875, -56875, -56882, -56882, -56889, -56895, -56895, -56918, -56925, -56925, -56932, -56932, -56941, -56963, -56979, -56989, -56989, -56989, -57010, -57054, -57054, -57054, -57054, -57087, -57112, -57152, -57166, -57212, -57219, -57233, -57263, -57284, -57291, -57305, -57325, -57325, -57332, -57339, -57355, -57359, -57359, -57399, -57406, -57413, -57413, -57420, -57430, -57430, -57488, +55714, +55735, +55735, +55735, +55744, +55744, +55744, +55744, +55780, +55854, +55884, +55914, +55919, +55919, +55950, +55960, +55960, +55960, +55968, +55981, +55981, +55998, +55998, +56018, +56059, +56065, +56083, +56083, +56110, +56139, +56139, +56211, +56211, +56211, +56211, +56228, +56240, +56260, +56260, +56294, +56294, +56294, +56306, +56338, +56407, +56426, +56437, +56437, +56443, +56453, +56509, +56509, +56509, +56509, +56515, +56539, +56546, +56546, +56546, +56584, +56602, +56602, +56622, +56634, +56652, +56660, +56674, +56674, +56729, +56729, +56729, +56750, +56788, +56788, +56793, +56793, +56793, +56793, +56813, +56835, +56873, +56896, +56944, +56980, +57001, +57032, +57051, +57061, +57061, +57073, +57073, +57082, +57092, +57092, +57092, +57104, +57115, +57115, +57115, +57121, +57133, +57133, +57133, +57153, +57183, +57198, +57198, +57216, +57232, +57248, +57259, +57296, +57316, +57316, +57322, +57333, +57351, +57367, +57375, +57419, +57419, +57431, +57441, +57441, +57460, +57476, 57495, -57512, -57512, -57512, -57519, -57526, -57547, -57554, -57564, -57574, -57589, +57495, +57511, +57511, +57521, +57521, +57521, +57531, +57558, +57603, +57603, +57603, 57609, -57616, -57623, -57623, -57623, -57623, -57635, -57652, -57687, -57694, -57717, -57736, -57736, -57767, -57774, -57786, -57793, -57793, -57800, -57800, -57819, -57826, -57826, -57841, -57864, -57895, -57895, -57902, -57912, +57627, +57662, +57668, +57677, +57677, +57685, +57685, +57696, +57711, +57721, +57743, +57765, +57782, +57782, +57789, +57789, +57789, +57789, +57811, +57811, +57811, +57828, +57844, +57844, +57844, +57886, +57891, +57918, +57918, +57918, +57918, 57926, -57940, -57947, -57977, -57997, +57930, +57967, +57967, +57973, +57973, 58001, -58023, -58043, -58050, -58083, -58083, -58090, -58116, -58116, -58116, -58122, -58122, -58138, -58145, -58152, -58152, -58152, -58175, -58200, -58241, -58254, -58279, -58301, -58330, -58337, -58362, -58381, -58388, -58388, -58409, -58428, -58428, -58428, -58442, -58449, -58449, -58471, -58482, -58512, -58519, -58519, -58519, -58519, -58533, -58543, -58570, -58591, -58591, -58591, -58591, -58640, -58640, -58650, -58660, -58673, -58713, -58719, -58743, -58772, -58783, -58800, -58839, -58851, -58896, -58919, -58929, -58929, -58943, -58943, -58943, -58957, -58957, -58971, -58971, -58983, -58983, -58983, -59017, -59023, -59023, -59045, -59108, -59125, -59125, -59125, -59136, -59154, -59217, -59236, -59292, -59299, -59323, -59330, -59330, -59344, -59344, -59351, -59351, -59374, -59381, -59388, -59425, -59425, -59448, -59463, -59479, -59490, -59520, -59527, -59556, -59583, -59605, -59628, -59655, -59694, -59735, -59742, -59749, -59749, -59756, -59771, -59771, -59791, -59808, -59825, -59832, -59851, -59858, -59888, +58036, +58070, +58070, +58070, +58076, +58084, +58084, +58098, +58124, +58140, +58147, +58166, +58183, +58230, +58238, +58238, +58255, +58267, +58292, +58302, +58320, +58320, +58335, +58335, +58372, +58372, +58372, +58401, +58421, +58432, +58444, +58450, +58468, +58468, +58486, +58486, +58520, +58535, +58535, +58535, +58535, +58545, +58554, +58568, +58617, +58617, +58630, +58678, +58684, +58701, +58701, +58701, +58701, +58701, +58739, +58739, +58739, +58746, +58746, +58803, +58823, +58823, +58823, +58853, +58871, +58952, +58963, +58963, +58970, +58970, +58988, +58997, +59013, +59018, +59025, +59025, +59031, +59044, +59063, +59069, +59069, +59127, +59146, +59146, +59146, +59168, +59168, +59179, +59179, +59191, +59207, +59219, +59258, +59265, +59315, +59315, +59315, +59320, +59320, +59320, +59320, +59350, +59367, +59377, +59423, +59423, +59438, +59488, +59488, +59494, +59494, +59507, +59540, +59540, +59540, +59540, +59540, +59540, +59578, +59618, +59630, +59639, +59639, +59733, +59733, +59751, +59751, +59766, +59783, +59783, +59790, +59798, +59804, +59854, +59854, +59869, +59869, +59875, +59875, 59895, -59921, -59952, -59952, -59960, -59960, -59960, -59998, +59895, +59934, +59961, +59961, +59961, +59967, +59973, +59973, +59999, 60008, -60015, -60049, -60085, -60085, -60085, -60112, -60112, -60119, -60119, -60146, -60146, -60156, -60163, -60163, -60163, -60231, -60262, -60271, -60284, -60303, -60348, -60355, -60355, -60362, -60362, -60362, -60384, -60391, -60391, -60415, -60435, -60444, -60476, -60483, -60490, -60504, -60504, -60504, -60536, -60556, -60592, -60592, -60623, -60623, -60642, -60652, -60652, -60674, -60674, -60711, -60711, -60723, -60767, -60779, -60779, -60788, -60817, -60860, -60879, -60879, -60889, -60889, -60894, +60008, +60008, +60036, +60036, +60036, +60046, +60060, +60060, +60060, +60068, +60086, +60086, +60096, +60096, +60117, +60159, +60204, +60228, +60228, +60241, +60241, +60297, +60313, +60319, +60319, +60389, +60396, +60396, +60396, +60396, +60412, +60412, +60452, +60452, +60477, +60489, +60509, +60509, +60521, +60541, +60550, +60559, +60559, +60571, +60597, +60631, +60646, +60657, +60663, +60663, +60672, +60701, +60701, +60709, +60715, +60715, +60757, +60768, +60768, +60768, +60768, +60795, +60805, +60805, +60805, +60805, +60805, +60852, +60867, +60867, +60867, +60867, +60867, +60882, 60898, -60941, -60948, -61007, -61014, -61021, -61027, -61034, -61034, -61034, -61034, -61044, -61051, -61068, -61103, -61118, -61118, -61118, -61118, -61125, -61140, -61140, -61147, -61147, -61147, -61154, -61168, -61187, -61187, -61217, -61239, -61261, -61261, -61318, -61325, -61338, -61382, -61382, -61401, -61408, +60898, +60913, +60913, +60932, +61031, +61047, +61064, +61064, +61078, +61078, +61110, +61142, +61142, +61142, +61167, +61167, +61167, +61167, +61199, +61218, +61218, +61247, +61254, +61290, +61290, +61290, +61290, +61301, +61301, +61301, +61301, +61301, +61336, +61342, +61342, +61349, +61349, +61370, +61370, +61393, 61425, -61425, -61425, -61432, -61445, -61445, -61445, -61466, -61466, -61482, +61442, +61442, +61468, 61496, -61509, -61520, -61527, -61527, -61544, -61544, -61551, -61551, -61557, -61557, -61557, -61582, -61597, -61619, -61639, -61639, -61658, -61658, -61665, -61665, -61665, -61665, -61665, -61672, -61672, -61692, -61692, -61707, -61707, -61727, -61766, -61779, +61502, +61502, +61502, +61512, +61525, +61525, +61542, +61595, +61640, +61684, +61710, +61710, +61737, +61750, +61786, +61786, 61803, -61803, -61839, -61852, -61865, -61865, -61886, +61889, +61889, +61889, 61908, -61918, -61918, -61918, -61918, -61935, -61948, -61964, -61974, -61974, -61982, -61989, -61995, -62007, -62007, -62025, -62036, -62036, -62036, -62048, -62048, -62064, -62064, -62079, -62079, -62108, -62140, -62153, -62153, -62153, -62187, -62209, -62235, -62235, -62240, -62247, +61914, +61938, +61953, +61972, +62009, +62033, +62039, +62039, +62057, +62063, +62074, +62093, +62113, +62113, +62119, +62119, +62125, +62125, +62146, +62159, +62159, +62165, +62199, +62216, +62225, +62225, +62231, +62237, +62237, +62237, +62237, 62265, -62265, -62277, -62277, -62287, -62306, -62306, -62306, -62306, -62313, -62326, -62326, -62326, -62334, -62334, -62353, -62366, -62366, -62366, -62366, -62366, -62385, -62385, -62385, -62385, +62278, +62317, +62323, +62323, +62323, +62323, +62323, +62339, +62359, +62388, +62394, +62394, +62394, +62400, +62406, +62416, 62416, -62435, -62441, -62441, 62447, 62447, -62459, -62459, -62466, -62495, -62524, -62524, -62537, -62576, -62589, -62589, -62608, -62608, -62608, -62624, -62656, -62688, -62688, -62688, -62702, -62721, -62737, -62737, -62737, -62754, -62772, -62808, -62808, -62808, -62808, -62808, -62817, -62855, -62873, -62903, -62920, -62920, -62920, -62920, -62920, -62939, -62939, -62939, -62947, -62973, -62992, -62992, -63044, -63055, -63083, -63119, -63144, -63179, -63200, -63200, -63213, -63213, -63267, -63276, -63290, -63290, -63290, -63318, -63318, -63366, -63378, -63378, -63394, -63394, -63414, -63414, -63421, -63421, -63434, -63448, -63486, -63499, -63499, -63499, -63506, -63506, -63522, -63522, -63577, -63607, -63607, -63607, -63616, -63616, -63624, -63653, -63653, -63653, -63653, -63657, -63657, -63657, -63657, -63689, -63703, -63741, -63752, -63775, -63775, -63792, -63804, -63804, -63831, -63831, -63850, -63850, -63875, -63886, -63886, -63886, -63893, -63899, -63899, -63899, -63911, -63930, -63930, -63930, -63950, -63987, -63987, -63987, -63999, -64010, -64019, -64019, -64019, -64039, +62475, +62475, +62491, +62491, +62531, +62531, +62531, +62531, +62559, +62572, +62586, +62601, +62601, +62601, +62625, +62635, +62658, +62658, +62670, +62682, +62703, +62703, +62709, +62716, +62736, +62775, +62785, +62790, +62796, +62796, +62813, +62828, +62845, +62853, +62853, +62853, +62874, +62887, +62893, +62909, +62922, +62971, +62971, +63013, +63013, +63021, +63021, +63053, +63087, +63150, +63150, +63150, +63160, +63166, +63166, +63166, +63177, +63212, +63243, +63243, +63243, +63243, +63243, +63243, +63243, +63243, +63252, +63263, +63269, +63269, +63269, +63275, +63289, +63301, +63301, +63316, +63316, +63316, +63316, +63335, +63391, +63413, +63439, +63445, +63445, +63457, +63457, +63472, +63472, +63472, +63494, +63500, +63545, +63545, +63557, +63557, +63580, +63676, +63682, +63711, +63718, +63731, +63750, +63750, +63771, +63799, +63822, +63822, +63849, +63880, +63903, +63910, +63929, +63929, +63936, +63942, +63955, +63955, +63955, +64014, +64020, +64020, +64040, 64051, -64084, -64084, -64112, -64122, -64122, -64122, -64135, -64164, -64164, -64164, -64164, -64164, -64164, -64164, -64169, -64189, -64189, -64203, -64218, -64218, -64230, -64255, -64255, -64284, -64297, -64297, -64313, -64313, -64313, -64324, -64357, -64364, -64378, -64378, -64378, -64378, -64378, -64378, -64378, -64378, -64378, -64388, -64417, -64433, -64448, -64460, -64460, -64481, -64514, +64067, +64082, +64104, +64104, +64110, +64141, +64141, +64152, +64159, +64208, +64231, +64231, +64231, +64286, +64286, +64310, +64329, +64360, +64360, +64391, +64391, +64397, +64397, +64410, +64410, +64427, +64434, +64434, +64454, +64454, +64454, +64454, +64454, +64463, +64463, +64469, +64469, +64492, +64492, 64521, -64543, -64543, -64543, -64560, -64574, -64583, -64583, -64617, -64627, -64647, -64662, -64662, -64662, -64670, -64734, +64532, +64590, +64605, +64633, +64663, +64695, +64701, +64707, +64707, +64720, +64745, 64752, -64752, -64770, -64806, -64833, -64867, -64886, +64766, +64776, +64791, +64791, +64813, +64823, +64823, +64823, +64829, +64853, +64853, +64884, +64884, +64884, +64884, 64893, -64893, -64904, -64904, +64903, 64925, -64925, -64925, -64933, -64933, -64933, -64933, -64943, -64953, -64972, -65032, -65041, -65041, +64934, +64958, +64958, +64958, +64965, +64978, +64999, +65018, +65024, +65031, 65046, -65090, -65090, -65099, -65116, -65146, -65152, -65152, -65169, -65186, -65194, -65194, -65223, -65223, -65233, -65255, -65296, -65306, -65313, -65332, -65368, -65388, -65388, -65388, +65061, +65095, +65114, +65114, +65137, +65148, +65148, +65209, +65226, +65226, +65264, +65275, +65286, +65292, +65292, +65305, +65305, +65315, +65315, +65338, +65338, +65354, +65361, +65361, +65361, +65361, +65373, +65373, +65382, +65397, 65404, -65404, -65404, -65404, -65404, -65421, -65421, -65421, -65428, -65428, -65465, -65500, -65519, -65525, -65556, -65600, -65626, -65626, -65634, -65640, -65656, -65677, -65707, -65707, -65731, -65731, -65731, -65731, -65742, -65755, -65835, -65835, -65835, -65850, +65431, +65437, +65454, +65454, +65472, +65486, +65486, +65492, +65510, +65516, +65516, +65516, +65541, +65541, +65541, +65541, +65550, +65591, +65591, +65591, +65612, +65643, +65666, +65666, +65685, +65685, +65691, +65691, +65703, +65713, +65727, +65733, +65749, +65749, +65759, +65839, 65870, -65870, -65898, -65914, -65942, -65948, -65958, -65990, -65990, -66011, -66029, -66040, -66057, -66057, -66095, -66095, -66095, -66095, -66095, -66131, -66147, -66159, -66169, +65885, +65891, +65918, +65937, +65951, +65951, +65967, +65973, +65979, +65979, +66030, +66079, +66088, +66088, +66088, +66107, +66113, +66129, 66184, -66221, -66221, -66228, -66235, -66235, -66245, -66245, -66245, -66252, -66258, -66258, -66275, -66328, -66361, -66417, -66417, -66417, -66428, -66428, -66439, -66446, -66461, -66472, -66472, -66479, -66487, -66499, -66499, -66528, -66549, -66558, -66567, -66567, -66577, -66584, -66633, -66658, -66669, -66669, -66677, -66700, -66709, -66719, -66730, -66754, -66764, -66764, -66776, -66783, -66794, -66794, -66801, -66828, -66869, -66869, -66901, -66901, -66908, -66935, -66958, -66964, -66973, -66973, -66973, -66973, -66973, -66973, -66979, -66979, -66979, -66997, -66997, -66997, -66997, -67017, -67017, -67017, -67033, -67033, -67033, -67059, -67059, -67071, -67092, -67092, -67092, -67092, -67105, -67117, -67128, -67155, -67187, -67187, -67187, +66184, +66184, +66207, +66255, +66271, +66313, +66313, +66323, +66340, +66350, +66370, +66370, +66404, +66404, +66404, +66411, +66427, +66438, +66438, +66438, +66438, +66448, +66462, +66473, +66473, +66501, +66501, +66501, +66536, +66536, +66536, +66536, +66536, +66536, +66536, +66536, +66536, +66536, +66536, +66582, +66582, +66599, +66608, +66624, +66624, +66624, +66631, +66656, +66656, +66679, +66679, +66701, +66728, +66751, +66758, +66792, +66814, +66814, +66814, +66860, +66903, +66903, +66903, +66919, +66919, +66919, +66926, +66989, +67022, +67074, +67090, +67121, +67121, +67121, +67132, +67197, +67197, 67205, -67214, -67214, -67214, -67225, -67241, -67265, -67277, -67277, -67286, -67286, -67304, -67330, -67330, -67330, -67350, +67224, +67250, +67266, +67282, +67282, +67282, +67295, +67295, +67311, +67322, +67322, +67329, +67348, +67348, +67348, +67348, 67368, -67405, -67424, -67430, -67450, -67450, -67450, -67450, -67450, +67395, +67395, +67419, +67428, +67428, +67449, +67463, +67463, 67470, -67493, -67536, -67536, -67536, -67536, -67536, -67548, -67548, -67575, -67575, +67487, +67515, +67534, +67534, +67534, +67576, +67576, +67590, 67609, -67609, -67629, -67660, -67660, -67660, -67666, -67671, -67691, -67708, -67738, -67748, -67748, -67748, -67790, -67790, -67790, -67806, -67806, -67806, -67822, -67822, -67822, -67822, -67829, -67860, -67883, -67883, -67900, +67632, +67632, +67632, +67642, +67675, +67688, +67693, +67700, +67713, +67713, +67744, +67771, +67797, +67816, +67824, +67824, +67831, +67851, +67851, +67851, +67856, +67869, +67880, +67890, +67890, +67890, 67914, 67914, -67959, -67959, -67976, -67999, -68025, -68046, -68065, -68065, -68065, -68074, -68074, -68091, -68091, -68091, -68091, -68091, -68111, -68111, -68111, -68111, -68124, -68141, -68162, -68162, -68177, -68195, -68195, -68210, -68210, -68223, -68242, -68242, -68258, -68258, -68304, -68314, -68314, -68324, -68345, -68365, -68382, -68399, -68420, -68434, -68452, -68472, -68472, -68472, -68486, -68498, -68498, -68531, -68584, -68615, -68622, -68639, -68651, -68671, +67968, +67968, +67975, +67985, +67997, +67997, +68012, +68012, +68012, +68062, +68062, +68094, +68094, +68128, +68137, +68153, +68153, +68178, +68190, +68190, +68190, +68190, +68200, +68241, +68241, +68260, +68260, +68260, +68260, +68270, +68270, +68270, +68270, +68286, +68318, +68318, +68318, +68325, +68349, +68349, +68358, +68376, +68376, +68402, +68439, +68481, +68490, +68490, +68490, +68508, +68508, +68521, +68534, +68574, +68606, +68606, +68606, +68644, +68644, +68672, 68691, -68691, -68691, -68700, -68707, -68733, -68750, -68750, -68750, -68750, -68763, -68784, -68798, -68816, -68833, -68833, -68897, -68897, -68913, -68926, -68926, -68926, -68926, -68948, -68948, -68989, -68999, -69007, -69027, -69036, +68713, +68742, +68742, +68752, +68752, +68752, +68752, +68752, +68789, +68789, +68789, +68837, +68837, +68837, +68837, +68847, +68883, +68934, +68955, +68955, +68972, +68972, +68972, +68982, +68982, +69000, +69012, +69026, +69026, +69031, 69051, -69073, -69073, -69086, -69111, -69111, -69119, -69139, -69139, -69148, -69148, -69161, -69168, -69168, -69168, -69185, -69185, -69192, -69192, -69192, -69209, -69209, -69209, -69231, -69253, -69265, -69272, -69287, -69287, -69315, -69320, -69326, -69326, -69333, -69333, -69343, -69343, -69370, -69383, -69383, -69391, -69441, -69461, -69461, -69461, -69461, -69461, -69495, -69495, -69495, -69522, -69522, -69531, -69538, -69549, -69549, -69549, -69567, -69580, -69595, -69626, -69626, -69626, -69655, -69701, -69720, -69720, -69769, -69769, -69779, -69787, -69800, -69800, -69811, -69811, -69826, -69841, -69856, -69874, -69874, -69884, -69912, -69917, +69071, +69071, +69071, +69071, +69109, +69109, +69109, +69109, +69109, +69125, +69133, +69133, +69133, +69133, +69133, +69133, +69189, +69197, +69197, +69235, +69247, +69247, +69259, +69294, +69294, +69294, +69314, +69325, +69377, +69399, +69420, +69431, +69536, +69547, +69547, +69547, +69559, +69559, +69559, +69582, +69582, +69582, +69582, +69599, +69638, +69638, +69648, +69648, +69667, +69667, +69687, +69721, +69721, +69748, +69748, +69748, +69748, +69777, +69798, +69798, +69807, +69822, +69832, +69832, +69840, +69847, +69847, +69847, +69855, +69855, +69863, +69863, +69863, +69875, +69875, +69908, 69927, -69947, -69963, -69963, -69963, -69963, -70007, -70019, -70019, -70040, -70060, -70060, -70081, -70081, -70106, -70141, -70173, -70184, -70219, -70245, -70245, -70274, -70281, -70311, -70323, -70323, -70330, -70344, -70364, -70364, -70376, -70410, -70410, -70417, -70424, -70463, -70463, -70490, -70497, -70511, -70527, -70551, -70551, -70563, -70570, -70577, -70590, -70590, -70597, -70597, -70618, -70648, -70686, -70706, -70722, -70744, -70789, -70789, -70799, -70816, -70816, -70816, -70846, +69927, +69932, +69932, +69932, +69932, +69932, +69960, +69960, +69976, +69990, +69997, +69997, +69997, +70008, +70031, +70052, +70052, +70066, +70102, +70102, +70111, +70111, +70127, +70127, +70151, +70151, +70168, +70175, +70196, +70214, +70260, +70300, +70309, +70309, +70309, +70318, +70318, +70318, +70325, +70354, +70368, +70379, +70400, +70420, +70429, +70449, +70449, +70465, +70491, +70507, +70507, +70538, +70538, +70571, +70571, +70571, +70601, +70601, +70601, +70601, +70601, +70613, +70613, +70674, +70674, +70732, +70732, +70779, +70814, 70861, -70868, -70868, -70875, -70875, -70881, -70906, -70919, -70935, -70942, -70942, -70963, -71002, -71020, -71037, -71065, -71087, -71106, -71164, -71164, -71171, -71171, -71171, -71195, -71208, -71221, -71221, -71233, -71233, -71240, -71247, -71257, -71257, -71274, -71302, -71302, -71327, -71339, -71355, -71362, -71362, -71393, -71398, -71441, -71441, -71460, -71480, -71499, -71512, -71531, -71538, -71545, -71582, -71582, +70861, +70918, +70931, +70974, +70974, +70974, +70986, +71001, +71039, +71044, +71062, +71127, +71139, +71146, +71177, +71177, +71193, +71193, +71215, +71215, +71215, +71231, +71231, +71236, +71236, +71248, +71248, +71248, +71248, +71300, +71337, +71361, +71386, +71420, +71420, +71420, +71453, +71453, +71453, +71488, +71507, +71515, +71527, +71537, +71537, +71537, 71589, 71589, -71621, -71621, -71640, -71640, -71662, -71689, -71751, -71776, -71776, -71792, -71792, -71799, -71827, -71843, -71856, -71856, -71894, -71894, -71915, -71915, -71915, -71951, -71981, -72004, -72034, -72034, -72041, -72058, -72081, -72081, -72103, -72110, -72146, -72155, -72171, -72198, +71608, +71631, +71631, +71631, +71643, +71649, +71688, +71700, +71715, +71715, +71715, +71715, +71715, +71715, +71715, +71715, +71745, +71745, +71745, +71750, +71750, +71750, +71750, +71750, +71768, +71818, +71833, +71861, +71861, +71873, +71873, +71873, +71889, +71889, +71908, +71908, +71914, +71942, +71942, +71953, +71953, +71976, +71991, +71991, +72003, +72003, +72003, +72019, +72033, +72069, +72069, +72085, +72129, +72129, +72161, 72205, -72212, -72224, -72272, -72293, -72321, -72344, -72349, -72373, -72385, -72420, -72427, +72240, +72290, +72322, +72334, +72346, +72346, +72395, +72437, +72437, +72437, 72458, -72465, -72465, -72496, -72496, 72513, -72530, -72530, -72536, -72543, -72557, -72582, -72600, -72609, -72609, -72626, -72644, -72644, -72651, -72680, -72687, -72710, -72733, -72751, +72520, +72520, +72533, +72533, +72545, +72545, +72558, +72565, +72565, +72565, +72565, +72565, +72585, +72590, +72590, +72608, +72608, +72608, +72608, +72664, +72677, +72682, +72711, +72721, +72730, +72730, +72752, +72752, +72775, 72787, -72809, -72809, -72832, -72839, -72868, -72868, -72896, -72904, -72904, -72923, -72930, -72942, -72949, -72963, -72997, -73009, -73038, +72794, +72794, +72838, +72864, +72891, +72891, +72907, +72922, +72935, +72935, +72966, +72991, +72991, +72991, +72991, +72998, +73031, 73057, -73064, -73064, -73084, -73122, -73136, -73155, -73194, -73215, -73222, -73222, +73062, +73071, +73097, +73113, +73127, +73127, +73127, +73140, +73140, +73173, +73183, +73193, +73217, 73229, -73253, -73299, -73322, -73378, -73416, +73229, +73236, +73254, +73254, +73262, +73262, +73262, +73262, +73274, +73274, +73291, +73291, +73291, +73298, +73316, +73316, +73343, +73350, +73350, +73359, +73359, +73359, +73398, +73405, 73430, -73456, -73469, -73481, -73506, -73506, -73506, -73531, -73531, -73538, -73547, -73588, -73595, -73635, -73648, +73430, +73457, +73472, +73495, +73495, +73515, +73551, +73551, +73563, +73571, +73571, +73606, +73612, +73647, +73647, 73674, -73690, -73697, -73697, -73702, -73761, -73787, -73809, -73822, -73829, -73861, -73889, +73683, +73703, +73727, +73747, +73763, +73782, +73782, +73793, +73834, +73834, +73844, +73863, +73863, +73863, +73875, 73894, -73913, -73920, -73947, -73980, -73980, -74009, -74016, +73927, +73936, +73955, +73955, +73988, 74023, -74029, -74036, -74056, -74080, -74105, +74039, +74051, +74051, +74051, +74051, +74058, +74069, +74087, +74099, 74137, -74154, -74161, -74176, -74182, -74194, -74200, -74207, -74218, -74230, -74230, -74250, -74250, -74256, -74278, -74319, -74319, -74328, -74333, -74374, -74374, -74374, -74374, -74374, -74402, -74452, -74475, -74475, -74507, -74534, +74137, +74137, +74156, +74175, +74186, +74198, +74209, +74225, +74235, +74266, +74294, +74304, +74304, +74324, +74366, +74366, +74429, +74429, +74447, +74490, +74490, +74513, +74513, 74539, -74546, -74563, -74616, -74623, -74643, -74673, -74713, -74720, -74720, -74720, -74728, -74747, -74747, -74766, -74773, -74799, -74813, -74836, -74876, -74883, -74892, -74909, -74943, -74970, -74977, -75008, -75059, -75059, +74571, +74593, +74625, +74646, +74657, +74657, +74657, +74671, +74671, +74680, +74690, +74721, +74731, +74760, +74767, +74782, +74810, +74878, +74878, +74878, +74885, +74905, +74905, +74928, +74928, +74957, +74976, +74976, +74983, +74990, +75002, +75002, +75015, +75049, +75049, 75066, -75095, -75118, -75118, -75149, -75190, -75199, -75206, -75206, -75206, -75220, -75220, -75220, -75238, -75245, -75267, -75279, -75287, -75307, -75333, -75353, -75353, -75379, -75379, -75400, -75444, -75444, -75444, -75458, -75502, -75521, -75521, -75551, -75558, +75066, +75073, +75073, +75085, +75085, +75085, +75091, +75091, +75133, +75163, +75177, +75177, +75177, +75177, +75177, +75198, +75198, +75235, +75248, +75288, +75294, +75310, +75330, +75330, +75355, +75355, +75355, +75375, +75394, +75412, +75412, +75412, +75424, +75448, +75484, +75484, +75495, +75495, +75507, +75517, +75524, +75524, 75570, -75570, -75591, -75603, -75603, -75661, -75674, -75686, -75716, -75798, -75798, -75811, -75841, -75841, -75852, -75863, -75863, -75883, -75913, -75925, -75940, -75940, -75979, -76018, -76037, -76037, -76064, -76090, -76106, -76106, -76125, -76134, -76154, -76154, -76154, -76173, -76183, -76193, -76211, -76223, -76254, -76285, -76285, -76285, -76304, -76304, -76319, -76330, -76330, -76372, -76379, -76391, -76447, -76465, -76465, -76479, -76504, -76544, -76550, -76575, -76615, -76629, -76641, -76654, -76674, -76684, -76700, -76700, -76710, -76716, -76716, -76740, -76772, -76772, -76779, -76779, -76779, -76779, -76784, -76784, -76784, -76798, -76798, +75577, +75577, +75599, +75623, +75623, +75680, +75680, +75720, +75734, +75750, +75750, +75785, +75785, +75796, +75796, +75806, +75822, +75828, +75861, +75861, +75898, +75898, +75904, +75904, +75904, +75968, +75981, +75991, +76028, +76028, +76057, +76057, +76068, +76075, +76102, +76118, +76118, +76126, +76126, +76146, +76151, +76151, +76151, +76163, +76181, +76181, +76210, +76229, +76234, +76234, +76248, +76271, +76302, +76341, +76341, +76364, +76403, +76403, +76411, +76418, +76428, +76470, +76490, +76497, +76534, +76589, +76601, +76601, +76601, +76622, +76637, +76676, +76702, +76719, +76719, +76719, +76741, +76741, +76741, +76782, +76799, 76812, 76819, -76838, -76838, -76862, -76872, -76872, -76885, -76885, -76906, -76953, -76982, -76982, -76982, -76982, -77010, -77038, -77038, -77049, -77049, -77064, -77093, -77126, -77144, -77144, -77144, -77150, -77168, -77176, -77176, -77182, -77182, -77202, -77202, -77207, -77217, -77237, -77237, -77237, -77237, -77252, -77252, -77252, -77260, -77260, -77276, -77291, -77291, +76826, +76826, +76826, +76853, +76859, +76884, +76884, +76884, +76899, +76899, +76909, +76909, +76917, +76924, +76948, +77011, +77011, +77011, +77011, +77018, +77018, +77018, +77025, +77041, +77054, +77082, +77082, +77082, +77092, +77109, +77119, +77119, +77119, +77158, +77177, +77183, +77193, +77238, +77268, +77268, +77274, +77274, +77280, +77280, +77280, 77301, -77338, -77338, -77344, -77344, -77353, -77383, -77422, -77427, -77444, -77444, -77444, -77444, -77454, -77454, -77454, -77470, -77508, -77508, -77521, -77521, -77521, -77548, -77604, -77604, -77604, -77615, -77630, -77655, -77655, -77665, -77681, +77301, +77309, +77319, +77319, +77319, +77319, +77340, +77385, +77385, +77385, +77404, +77437, +77437, +77453, +77453, +77453, +77453, +77463, +77463, +77489, +77499, +77499, +77515, +77537, +77537, +77596, +77596, +77616, +77621, +77656, +77656, +77673, +77673, +77697, +77697, +77697, 77702, 77702, -77702, -77724, -77760, -77794, -77803, -77811, -77818, -77818, -77818, -77818, -77841, -77862, -77862, -77862, -77862, -77862, -77886, -77886, -77886, -77919, -77919, -77925, -77925, -77932, -77937, -77958, -77977, -77977, -77977, -77990, -78012, -78024, -78024, -78041, -78041, -78041, -78048, -78054, -78054, -78071, -78087, -78137, -78146, -78146, -78152, -78175, -78186, -78186, -78237, -78266, -78266, -78280, -78301, -78311, -78311, -78311, -78311, -78311, -78311, -78318, -78328, -78328, -78328, -78347, -78347, -78363, -78386, -78396, -78402, -78412, -78412, -78412, -78440, -78440, -78459, -78474, -78474, -78474, -78492, -78511, -78511, -78523, -78523, +77708, +77731, +77731, +77731, +77731, +77731, +77738, +77747, +77765, +77771, +77771, +77781, +77802, +77802, +77831, +77831, +77845, +77877, +77877, +77895, +77945, +77955, +77955, +77976, +77976, +77997, +77997, +78020, +78020, +78047, +78055, +78055, +78064, +78070, +78076, +78076, +78128, +78154, +78198, +78198, +78198, +78215, +78215, +78226, +78241, +78241, +78279, +78294, +78294, +78294, +78294, +78319, +78319, +78335, +78352, +78372, +78372, +78389, +78389, +78405, +78405, +78405, +78419, +78419, +78463, +78463, +78463, +78480, +78493, +78493, 78535, -78535, -78553, -78553, -78553, -78558, -78558, -78558, -78568, -78568, -78573, -78589, -78589, -78589, -78605, -78605, +78552, +78552, +78587, +78593, 78624, -78657, -78657, +78624, +78624, +78624, +78660, 78670, -78670, -78670, -78682, -78706, -78706, -78722, -78731, -78760, -78775, -78775, -78780, -78780, -78803, -78816, -78834, -78860, -78872, -78879, -78895, -78895, -78895, -78914, -78954, -78995, -78995, -79008, -79008, -79008, -79008, -79026, -79054, -79068, -79077, -79096, -79110, -79110, -79110, -79120, -79145, -79145, -79152, -79188, -79231, -79231, -79231, -79250, -79257, -79278, -79278, -79311, -79311, -79311, -79321, -79334, -79385, -79385, -79406, -79406, -79412, -79412, -79412, -79412, -79412, -79424, -79445, -79484, -79484, -79490, -79511, -79511, -79525, -79531, -79570, -79570, -79570, -79570, -79593, -79593, -79627, -79663, -79663, -79675, -79675, -79675, -79675, -79675, -79687, -79707, -79707, -79730, -79742, -79742, -79742, -79749, -79749, -79749, -79754, -79754, -79811, -79827, -79847, -79847, -79853, -79876, -79876, -79876, -79899, -79917, -79917, -79917, -79917, -79917, -79941, -79948, -79948, -79948, -79968, -79968, -79968, -79968, -79968, -79983, -80024, -80024, -80024, -80024, -80045, -80045, -80054, -80054, -80084, -80098, -80110, -80110, -80130, -80146, -80157, -80157, -80157, -80167, -80167, -80215, -80215, -80227, -80232, -80232, -80239, -80239, -80251, -80269, -80292, -80320, -80320, -80320, -80320, -80328, -80351, -80351, -80351, -80351, -80363, -80397, -80397, -80397, -80397, -80408, -80408, -80408, -80408, -80467, -80467, -80487, -80487, -80535, -80535, -80552, -80580, -80619, -80619, -80659, -80668, -80668, -80668, -80695, -80710, -80710, -80717, -80729, -80729, -80729, -80729, -80741, -80760, -80777, -80777, -80792, -80792, -80813, -80831, -80846, -80846, -80846, -80896, -80896, -80913, -80929, -80929, -80929, -80929, -80929, -80929, +78680, +78693, +78708, +78716, +78750, +78750, +78765, +78778, +78795, +78804, +78817, +78817, +78817, +78840, +78850, +78850, +78861, +78878, +78893, +78893, +78909, +78947, +78985, +78985, +78985, +78999, +79018, +79027, +79035, +79035, +79053, +79066, +79066, +79066, +79084, +79084, +79084, +79101, +79101, +79119, +79133, +79140, +79162, +79162, +79162, +79206, +79206, +79216, +79276, +79303, +79303, +79303, +79303, +79303, +79303, +79303, +79315, +79315, +79347, +79356, +79370, +79370, +79370, +79376, +79376, +79376, +79376, +79391, +79391, +79391, +79391, +79403, +79403, +79415, +79455, +79461, +79461, +79474, +79494, +79500, +79500, +79500, +79523, +79535, +79535, +79535, +79558, +79591, +79591, +79591, +79591, +79601, +79601, +79608, +79608, +79621, +79621, +79621, +79621, +79621, +79628, +79634, +79634, +79644, +79662, +79696, +79712, +79712, +79746, +79772, +79812, +79822, +79822, +79834, +79834, +79834, +79877, +79896, +79896, +79896, +79896, +79896, +79910, +79910, +79910, +80002, +80027, +80042, +80042, +80042, +80042, +80051, +80064, +80073, +80094, +80114, +80114, +80114, +80114, +80114, +80114, +80141, +80181, +80181, +80208, +80218, +80241, +80241, +80241, +80246, +80252, +80294, +80300, +80308, +80308, +80308, +80308, +80308, +80318, +80318, +80318, +80318, +80340, +80340, +80366, +80366, +80366, +80366, +80366, +80366, +80366, +80384, +80403, +80430, +80430, +80430, +80436, +80436, +80436, +80448, +80460, +80460, +80492, +80503, +80503, +80544, +80544, +80555, +80555, +80578, +80578, +80591, +80591, +80591, +80614, +80614, +80625, +80632, +80662, +80662, +80675, +80697, +80721, +80771, +80771, +80776, +80783, +80783, +80783, +80783, +80783, +80814, +80828, +80834, +80842, +80856, +80856, +80904, +80920, 80938, -80953, -80969, -80992, -81006, -81020, -81020, -81036, -81036, -81042, -81042, -81042, -81048, -81062, -81072, -81078, -81084, -81106, -81126, -81143, -81163, -81169, +80958, +80958, +80989, +80996, +81003, +81017, +81017, +81054, +81061, +81068, +81090, +81104, +81104, +81114, +81127, +81134, +81141, +81148, +81166, +81166, 81179, -81196, -81219, -81219, -81231, -81249, -81249, -81249, -81249, -81277, -81294, -81294, -81311, -81311, -81311, -81344, -81356, -81356, -81356, -81356, -81356, -81356, -81363, -81383, -81405, -81415, +81194, +81230, +81230, +81265, +81297, +81316, +81323, +81330, +81375, +81387, 81422, 81422, -81434, -81442, -81442, -81477, -81477, -81482, -81482, -81482, -81482, -81482, -81482, -81492, -81492, -81492, -81492, -81501, -81501, -81516, -81526, -81526, -81553, -81570, -81570, -81591, -81591, -81607, -81607, -81607, -81623, -81667, -81703, -81710, -81733, -81733, -81733, -81733, -81733, -81768, -81768, -81790, -81802, -81874, -81874, -81888, -81910, -81910, -81936, -81936, -81942, -81942, -81942, -81942, -81978, -81984, -82001, -82007, -82007, -82018, -82028, -82035, -82053, -82066, -82092, -82092, -82115, -82115, -82115, -82123, -82123, -82129, -82159, -82159, -82177, -82177, +81422, +81422, +81458, +81469, +81488, +81506, +81506, +81540, +81594, +81600, +81626, +81645, +81652, +81652, +81671, +81678, +81695, +81701, +81720, +81726, +81736, +81742, +81742, +81771, +81805, +81829, +81829, +81829, +81829, +81829, +81829, +81829, +81829, +81829, +81843, +81843, +81843, +81861, +81887, +81904, +81904, +81911, +81924, +81924, +81939, +81966, +82029, +82029, +82062, +82089, +82101, +82117, +82161, +82168, +82174, 82187, 82187, -82187, -82238, -82244, -82263, -82263, +82203, +82217, +82234, +82259, +82259, +82273, +82273, 82286, -82306, 82316, -82332, -82352, -82395, -82411, -82458, -82458, -82467, -82504, -82524, -82524, -82524, -82537, -82543, -82543, -82553, -82581, -82581, -82581, -82606, -82606, -82629, -82629, -82637, -82656, -82656, -82656, -82656, -82656, -82656, -82675, -82700, -82700, -82706, -82706, -82739, -82739, -82748, -82769, -82787, -82787, -82787, -82804, -82804, -82819, -82819, -82851, -82891, -82891, -82909, -82919, -82926, -82932, -82932, -82942, +82316, +82323, +82323, +82349, +82355, +82355, +82381, +82394, +82438, +82448, +82448, +82461, +82489, +82489, +82502, +82502, +82561, +82568, +82601, +82601, +82608, +82608, +82615, +82622, +82672, +82672, +82678, +82710, +82746, +82752, +82785, +82785, +82816, +82847, +82861, +82861, +82879, +82897, +82914, +82914, 82965, -82978, -83018, -83068, -83075, -83119, -83141, -83181, -83188, -83202, -83222, -83237, -83237, -83244, -83258, -83285, -83303, -83303, -83310, -83329, -83339, -83362, -83369, -83391, -83391, -83398, -83409, -83423, -83423, -83454, -83461, +82965, +82972, +82972, +82979, +82991, +82991, +83029, +83047, +83093, +83093, +83100, +83130, +83137, +83153, +83153, +83153, +83171, +83178, +83178, +83185, +83212, +83219, +83236, +83276, +83276, +83276, +83276, +83276, +83289, +83335, +83351, +83371, +83378, +83400, +83412, 83468, -83481, -83481, -83489, -83496, -83510, -83517, -83529, -83541, -83556, -83556, -83586, -83599, -83599, -83599, -83624, -83638, -83664, -83683, -83701, -83701, -83701, -83707, -83714, -83721, -83728, -83781, -83788, -83816, -83816, -83816, -83833, -83851, -83891, -83920, -83937, -83937, -83944, -83971, -83971, -83971, -84012, -84056, -84056, -84097, -84170, -84176, -84208, -84208, -84208, -84208, -84208, -84214, -84214, -84229, -84254, -84271, -84271, -84271, -84271, -84284, -84292, -84292, +83480, +83487, +83501, +83528, +83563, +83579, +83579, +83588, +83588, +83603, +83616, +83616, +83623, +83650, +83657, +83671, +83678, +83678, +83715, +83727, +83767, +83808, +83815, +83828, +83835, +83848, +83848, +83885, +83885, +83902, +83921, +83921, +83921, +83921, +83921, +83934, +83953, +83967, +83982, +84007, +84017, +84027, +84044, +84051, +84079, +84079, +84115, +84115, +84136, +84150, +84194, +84194, +84230, +84230, +84230, +84237, +84244, +84251, +84258, +84258, +84278, +84293, +84293, +84300, 84306, -84306, -84313, -84320, -84345, -84345, -84345, -84371, -84385, -84400, -84407, -84425, -84425, -84425, -84445, -84452, -84452, -84473, -84492, -84516, -84540, -84547, -84547, -84572, -84592, -84605, -84635, -84666, -84689, -84689, -84696, +84312, +84321, +84321, +84339, +84378, +84378, +84419, +84431, +84431, +84431, +84431, +84431, +84437, +84459, +84469, +84488, +84497, +84497, +84522, +84528, +84528, +84528, +84545, +84573, +84587, +84594, +84607, +84627, +84643, +84643, +84643, +84643, +84648, +84655, +84655, +84662, 84715, 84715, -84729, -84729, -84769, -84769, -84779, -84810, -84855, +84715, +84731, +84738, +84763, +84770, +84777, +84795, +84795, +84850, +84857, +84857, +84857, 84873, -84887, -84924, -84966, -84966, -84966, -84981, -84988, -85002, -85017, -85017, -85017, -85031, -85055, -85068, -85075, -85089, -85089, -85163, -85163, +84892, +84911, +84911, +84918, +84949, +84958, +85013, +85013, +85046, +85058, +85081, +85108, +85108, +85118, +85139, +85189, +85189, +85198, +85216, 85222, -85241, -85248, -85272, -85314, -85314, -85341, -85389, -85389, -85395, -85465, -85472, -85485, -85492, -85533, -85561, -85568, -85588, -85610, -85617, -85636, +85233, +85240, +85240, +85247, +85289, +85324, +85324, +85331, +85340, +85340, +85368, +85374, +85410, +85452, +85468, +85486, +85507, +85550, +85585, +85609, +85609, +85615, +85615, +85637, +85637, +85637, +85646, 85688, -85713, -85733, -85747, -85761, -85768, -85788, -85788, -85795, -85830, -85837, -85849, -85871, -85885, -85892, -85899, -85924, -85924, -85934, -85982, -86015, -86047, -86054, -86068, -86075, -86082, -86099, -86106, -86106, +85688, +85727, +85727, +85749, +85790, +85877, +85877, +85877, +85893, +85921, +85943, +85943, +85951, +85951, +85951, +85959, +85980, +85991, +85991, +85991, +86002, +86010, +86010, +86017, +86024, +86024, +86024, +86071, +86077, +86077, +86092, +86102, +86102, +86108, +86108, 86120, -86127, -86149, -86149, -86156, -86156, -86163, -86179, -86193, -86221, -86249, -86285, +86141, +86157, +86157, +86167, +86199, +86199, +86217, +86217, +86254, +86265, +86273, +86280, 86299, -86320, -86340, -86355, -86355, -86355, -86399, -86407, -86407, -86425, -86457, -86487, -86487, -86487, -86497, -86497, -86519, -86534, -86539, +86315, +86315, +86331, +86342, +86358, +86373, +86396, +86405, +86432, +86453, +86458, +86488, +86488, +86504, +86511, +86511, 86546, -86563, -86563, -86570, -86581, -86593, -86600, -86607, -86622, -86629, -86647, +86569, +86583, +86583, +86583, +86596, +86596, +86612, +86634, 86662, -86679, -86686, -86708, -86708, -86715, -86741, -86755, -86762, -86776, -86791, -86798, -86815, -86849, -86880, -86893, -86934, -86952, -86971, +86671, +86671, +86676, +86707, +86707, +86745, +86745, +86745, +86745, +86789, +86805, +86805, +86805, +86812, +86812, +86812, +86841, +86841, +86841, +86878, +86878, +86878, +86878, +86878, +86886, +86921, +86931, +86931, +86931, +86939, +86946, 86992, -87028, -87038, -87086, -87100, -87100, -87109, -87109, -87122, -87122, -87153, -87153, -87171, +86998, +86998, +86998, +87020, +87020, +87040, +87040, +87040, +87053, +87053, +87068, +87076, +87076, +87076, +87076, +87076, +87093, +87126, +87133, +87133, +87149, +87149, +87156, +87180, 87195, -87195, -87195, -87195, -87219, -87219, -87234, -87248, -87255, -87255, -87262, -87262, -87276, -87311, -87325, -87332, -87351, -87358, -87387, -87426, -87433, -87446, -87471, -87478, -87485, -87499, -87506, -87506, -87517, -87517, -87540, -87567, -87580, -87591, -87618, -87667, -87691, -87698, -87721, -87721, -87775, +87215, +87229, +87260, +87312, +87335, +87392, +87414, +87427, +87427, +87441, +87441, +87451, +87451, +87451, +87467, +87472, +87472, +87488, +87488, +87488, +87508, +87508, +87508, +87508, +87539, +87549, +87566, +87620, +87638, +87648, +87648, +87673, +87708, +87719, +87738, +87738, +87758, +87758, +87767, 87789, -87803, -87840, -87896, -87903, -87903, -87925, -87932, -87971, -87995, -88002, -88015, -88015, +87789, +87789, +87789, +87797, +87807, +87807, +87823, +87823, +87829, +87898, +87912, +87912, +87912, +87912, +87950, +87950, +87957, +87973, +87973, +87973, +88006, +88006, +88006, +88006, +88006, +88006, 88022, -88053, -88053, -88053, -88059, -88077, -88077, +88062, +88093, +88093, +88093, +88103, +88103, 88114, -88121, -88165, -88179, -88186, -88203, -88217, -88246, -88268, -88268, -88268, -88275, -88297, -88332, -88332, -88339, -88363, -88379, -88412, -88462, -88469, -88499, -88516, -88567, -88616, +88122, +88122, +88130, +88182, +88191, +88207, +88207, +88238, +88257, +88257, +88278, +88309, +88325, +88344, +88361, +88361, +88361, +88361, +88361, +88361, +88361, +88375, +88380, +88380, +88380, +88385, +88399, +88418, +88436, +88436, +88446, +88458, +88479, +88489, +88489, +88512, +88520, +88566, +88590, +88595, +88595, +88595, 88626, 88626, -88668, -88675, -88675, -88705, -88705, -88723, -88737, -88761, -88761, -88761, -88767, -88783, -88783, -88801, -88829, -88842, -88842, -88849, -88873, -88900, -88909, -88918, -88925, -88932, -88958, -88995, -89004, -89011, -89026, +88643, +88643, +88663, +88684, +88684, +88699, +88715, +88724, +88724, +88740, +88740, +88748, +88748, +88805, +88805, +88815, +88815, +88825, +88835, +88835, +88856, +88856, +88866, +88898, +88967, +88976, +89007, +89035, +89043, 89055, -89089, -89089, -89089, -89106, -89163, -89198, -89226, -89241, -89241, -89241, -89271, -89279, -89296, -89349, -89366, -89366, -89390, -89411, -89455, -89455, -89467, -89467, -89486, -89493, -89507, -89547, -89555, -89562, -89587, -89612, +89063, +89095, +89103, +89129, +89165, +89165, +89179, +89218, +89239, +89337, +89337, +89342, +89342, +89384, +89384, +89395, +89408, +89418, +89439, +89439, +89458, +89458, +89546, +89575, +89595, +89602, 89621, -89643, -89643, -89655, -89662, -89676, -89711, -89718, -89725, -89745, -89779, -89786, -89793, -89800, -89806, -89806, -89820, +89621, +89639, +89681, +89705, +89715, +89739, +89749, +89749, +89802, +89809, +89837, +89845, 89853, -89871, -89878, -89885, -89946, -89970, -89984, -89998, -90005, -90005, -90012, -90012, -90018, -90040, -90047, -90047, -90047, -90054, -90061, -90079, -90079, -90093, -90128, -90159, -90179, -90193, -90210, -90224, -90224, -90224, -90275, -90302, -90302, +89853, +89873, +89873, +89873, +89879, +89935, +89942, +89942, +90006, +90032, +90032, +90041, +90041, +90041, +90089, +90089, +90094, +90102, +90102, +90110, +90144, +90152, +90160, +90172, +90191, +90200, +90200, +90221, +90231, +90287, +90287, 90309, -90309, -90316, -90338, -90338, -90352, -90359, -90369, +90328, +90328, +90346, +90346, +90353, +90375, 90404, -90430, -90440, -90450, -90464, -90478, -90478, -90478, -90492, -90512, -90512, -90528, -90551, -90551, -90561, -90585, -90602, -90609, -90630, -90658, -90658, -90699, -90708, -90708, -90715, -90715, -90715, -90729, -90746, -90746, -90773, -90795, -90822, -90822, -90822, -90850, -90855, -90871, -90892, -90905, -90916, -90943, -90950, -90956, -90991, -91025, -91031, -91055, -91062, -91084, -91091, -91097, -91097, -91132, -91156, -91167, -91167, -91193, -91193, -91209, -91281, -91313, +90441, +90452, +90549, +90568, +90638, +90659, +90696, +90696, +90696, +90696, +90706, +90732, +90834, +90848, +90857, +90878, +90878, +90903, +90914, +90924, +90978, +90985, +91009, +91042, +91042, +91070, +91087, +91087, +91107, +91107, +91139, +91153, +91180, +91180, +91230, +91230, +91244, +91252, +91262, +91270, +91278, +91278, +91278, +91291, +91304, 91320, -91338, -91338, -91351, -91351, -91363, -91385, -91385, -91385, -91401, -91408, -91423, -91441, +91370, +91381, +91394, +91394, +91428, +91453, +91470, +91477, +91477, +91477, 91485, -91485, -91485, -91492, -91492, -91519, -91526, -91551, -91570, -91593, -91598, -91605, -91605, -91614, -91621, -91621, -91621, -91621, -91647, -91662, -91728, -91758, -91765, -91765, -91765, -91772, -91772, -91772, -91794, -91826, -91826, -91851, -91851, -91870, -91891, -91904, -91904, -91925, -91925, -91953, -91964, -91964, -91964, -91964, -91977, -91977, -91995, +91505, +91505, +91505, +91523, +91523, +91523, +91571, +91571, +91607, +91615, +91643, +91643, +91643, +91660, +91660, +91674, +91688, +91703, +91703, +91739, +91767, +91767, +91799, +91818, +91829, +91829, +91829, +91837, +91843, +91843, +91868, +91868, +91868, +91868, +91868, +91888, +91888, +91888, +91888, +91919, +91954, +91954, +91954, +91970, +91979, +91984, +91984, +92001, +92001, 92026, 92026, -92026, -92036, -92042, -92061, -92078, -92078, -92096, -92130, -92144, -92153, -92153, -92153, -92160, -92198, -92198, -92198, -92198, -92198, -92221, -92221, -92227, -92227, -92227, -92238, -92238, -92238, -92250, -92257, +92038, +92055, +92055, +92072, +92077, +92083, +92091, +92140, +92140, +92181, +92188, +92208, +92279, 92284, -92302, -92316, -92316, +92294, +92294, +92327, +92327, 92337, -92337, -92360, -92360, -92360, -92367, -92367, -92367, -92385, 92392, -92397, -92397, -92404, -92420, -92420, -92466, -92466, -92466, -92482, -92497, -92497, -92507, -92543, -92543, -92550, -92550, -92550, -92573, -92588, -92607, -92607, -92613, -92613, -92647, -92660, -92660, -92660, -92660, -92660, -92660, -92666, -92666, -92666, -92676, -92708, -92729, -92729, -92739, -92739, -92739, -92764, -92781, -92793, -92823, -92872, -92886, -92886, -92911, -92911, -92999, -92999, -93009, -93009, -93038, -93038, -93038, -93038, -93059, -93074, -93074, -93074, -93084, -93114, -93114, -93151, -93183, -93193, -93193, -93212, -93223, -93223, -93223, -93237, -93257, -93275, -93275, -93284, -93284, -93333, -93333, -93353, +92392, +92419, +92427, +92455, +92461, +92461, +92461, +92479, +92505, +92505, +92531, +92531, +92560, +92577, +92577, +92586, +92595, +92595, +92622, +92653, +92665, +92685, +92696, +92696, +92738, +92738, +92758, +92807, +92818, +92836, +92836, +92836, +92844, +92844, +92856, +92856, +92856, +92862, +92862, +92880, +92880, +92929, +92968, +92991, +92991, +92991, +92991, +93005, +93005, +93005, +93023, +93030, +93066, +93096, +93096, +93096, +93115, +93145, +93159, +93187, +93211, +93226, +93251, +93251, +93251, +93251, +93260, +93267, +93282, +93282, +93282, +93282, +93345, +93350, +93350, +93364, 93372, -93381, -93381, -93395, -93459, -93459, -93479, -93491, -93501, -93515, -93553, -93553, -93553, -93590, -93590, -93590, -93590, +93393, +93393, +93406, +93425, +93425, +93425, +93431, +93442, +93468, +93468, +93468, +93530, +93530, +93530, +93560, +93570, +93579, +93600, 93616, 93616, -93673, -93673, -93680, -93680, -93699, -93699, -93721, -93721, -93721, -93737, -93737, -93737, -93757, -93769, -93769, -93769, -93769, -93769, -93808, -93821, -93821, -93821, -93821, -93838, -93838, -93838, -93838, -93838, -93856, -93872, -93887, -93904, -93911, -93931, -93931, -93950, -93950, -93959, -93975, -93975, -93975, -93975, -94014, -94035, -94054, -94066, -94066, -94066, -94066, -94066, -94085, -94097, -94166, -94174, -94181, -94187, -94200, +93616, +93638, +93646, +93646, +93646, +93653, +93653, +93661, +93661, +93691, +93714, +93714, +93714, +93714, +93714, +93751, +93799, +93826, +93826, +93826, +93826, +93826, +93849, +93855, +93861, +93894, +93929, +93935, +93935, +93935, +93947, +93947, +93947, +93960, +93979, +93985, +94004, +94023, +94055, +94072, +94092, +94092, +94102, +94113, +94122, +94122, +94148, +94156, +94171, 94236, -94246, -94263, -94263, -94278, -94311, -94311, -94311, +94236, +94236, +94257, +94257, +94310, +94317, 94322, -94338, -94349, -94362, -94362, -94378, -94378, -94393, -94393, -94393, -94402, -94419, -94437, -94437, -94442, -94448, -94448, -94473, -94488, -94494, -94494, -94494, -94503, -94503, -94503, -94503, -94503, -94519, -94527, -94527, -94549, -94549, -94579, -94615, -94623, -94653, -94659, -94667, -94675, -94698, -94709, -94709, -94709, -94714, -94714, -94714, -94734, -94734, -94734, -94734, -94744, -94756, -94761, -94761, -94761, -94761, -94798, -94798, -94798, -94851, -94887, -94892, -94892, -94915, -94941, -94951, -94974, -94974, -94984, -95002, -95002, -95031, -95040, -95040, -95040, -95040, -95058, -95086, -95086, -95102, -95102, -95102, -95130, -95155, -95173, -95173, -95173, -95173, -95193, -95214, -95214, -95223, -95230, -95262, -95268, -95268, -95268, -95268, -95268, -95268, -95279, -95292, -95342, -95377, -95397, -95421, -95433, -95451, -95484, -95490, -95514, -95514, -95536, -95536, -95536, -95536, -95536, -95545, -95564, -95564, -95633, -95640, -95649, -95668, +94322, +94322, +94329, +94337, +94360, +94360, +94383, +94395, +94445, +94465, +94465, +94465, +94465, +94483, +94502, +94531, +94593, +94593, +94599, +94618, +94624, +94654, +94665, +94686, +94712, +94712, +94743, +94766, +94766, +94774, +94774, +94801, +94828, +94828, +94845, +94845, +94845, +94880, +94894, +94894, +94901, +94901, +94917, +94924, +94989, +94989, +94989, +94989, +95014, +95038, +95038, +95068, +95076, +95097, +95153, +95165, +95215, +95221, +95250, +95281, +95281, +95337, +95352, +95373, +95385, +95385, +95402, +95402, +95402, +95402, +95425, +95446, +95452, +95478, +95486, +95486, +95486, +95486, +95492, +95508, +95528, +95528, +95555, +95566, +95566, +95566, +95575, +95591, +95665, +95665, +95677, 95685, -95685, -95685, -95685, -95685, -95685, -95702, -95711, -95737, +95704, +95704, +95704, +95710, +95710, +95725, +95725, +95725, 95765, -95802, -95802, -95817, -95817, -95837, -95837, -95879, -95879, -95879, -95879, -95879, -95879, -95888, -95895, -95905, -95916, -95932, -95932, -95932, -95932, -95932, -95932, -95952, -95968, -95978, -95978, -95984, -95984, -96007, -96028, -96078, -96096, -96096, -96096, +95765, +95785, +95815, +95828, +95828, +95877, +95902, +95919, +95919, +95953, +95953, +96013, +96013, +96041, +96053, +96053, +96093, +96093, 96106, -96117, -96168, -96168, -96182, -96182, -96203, -96221, -96227, -96249, -96281, -96319, -96335, -96335, -96335, -96345, -96351, -96360, -96381, -96381, -96394, -96407, -96458, -96490, -96490, -96490, -96490, -96522, -96522, -96522, -96550, -96550, -96550, -96562, -96572, -96572, -96615, -96645, -96677, -96677, -96704, -96753, -96759, -96794, -96794, -96808, -96808, -96858, -96865, -96865, -96865, -96865, -96865, -96865, -96882, -96919, -96919, -96929, -96929, -96929, -96929, -96929, -96929, -96940, -96958, -96958, -96964, -96996, -96996, -97015, -97038, -97038, -97051, -97060, -97060, -97080, -97080, -97080, -97080, -97080, -97101, -97120, -97132, -97132, -97132, -97132, -97132, -97160, -97160, -97160, -97160, -97160, -97171, -97186, -97196, -97212, -97212, -97230, -97266, -97275, -97290, -97290, -97290, -97315, -97349, -97349, -97349, -97349, -97372, -97377, -97377, -97387, -97416, -97436, -97456, -97495, -97500, -97511, -97517, -97577, -97597, -97604, -97694, -97722, -97727, -97727, -97746, -97763, -97763, -97773, -97773, -97773, -97792, -97792, -97792, -97816, -97839, -97839, -97859, -97859, -97859, -97859, -97859, -97889, -97889, -97914, -97949, -97949, -97949, -97963, -97963, -97963, -97975, -97975, -98009, -98024, -98032, -98032, -98032, -98032, -98043, -98043, -98052, -98052, -98058, -98058, -98058, -98085, -98085, -98098, -98098, -98098, -98098, -98109, -98143, -98143, -98161, -98161, -98172, -98172, -98183, -98183, -98183, -98189, +96106, +96112, +96218, +96234, +96255, +96255, +96255, +96255, +96310, +96331, +96331, +96331, +96371, +96387, +96404, +96421, +96440, +96440, +96445, +96461, +96492, +96492, +96504, +96504, +96504, +96521, +96553, +96576, +96576, +96583, +96583, +96583, +96599, +96619, +96619, +96637, +96646, +96646, +96696, +96719, +96719, +96719, +96727, +96727, +96727, +96757, +96757, +96779, +96779, +96779, +96796, +96816, +96822, +96822, +96822, +96822, +96828, +96859, +96859, +96859, +96920, +96927, +96941, +96952, +96952, +96999, +97024, +97036, +97036, +97049, +97049, +97049, +97049, +97065, +97100, +97108, +97108, +97108, +97108, +97121, +97157, +97207, +97242, +97242, +97248, +97248, +97328, +97337, +97337, +97348, +97386, +97409, +97421, +97441, +97465, +97465, +97465, +97465, +97512, +97529, +97529, +97529, +97529, +97529, +97563, +97581, +97600, +97621, +97621, +97621, +97631, +97631, +97631, +97652, +97660, +97660, +97660, +97666, +97677, +97677, +97677, +97677, +97689, +97723, +97734, +97744, +97750, +97769, +97784, +97828, +97867, +97887, +97901, +97901, +97919, +97950, +97956, +97976, +97976, +97998, +97998, +98005, +98033, +98033, +98039, +98039, +98093, +98093, +98093, +98127, +98167, +98167, +98181, +98181, +98181, +98217, 98224, -98243, -98243, -98243, -98264, -98278, -98285, -98285, -98329, -98341, -98375, -98375, -98402, -98419, -98419, -98419, -98434, -98434, -98458, -98484, -98515, -98565, -98599, -98611, -98631, -98636, -98657, -98657, +98249, +98249, +98283, +98319, +98343, +98404, +98414, +98432, +98452, +98461, +98477, +98477, +98488, +98488, +98525, +98536, +98558, +98603, +98603, +98615, +98647, 98663, 98663, -98699, -98712, +98681, +98697, +98697, +98707, +98707, +98707, +98714, +98714, 98718, -98718, -98754, -98754, -98754, -98804, -98804, -98813, -98822, -98822, -98858, -98858, -98874, -98874, -98881, -98899, -98915, -98928, -98928, -98936, -98936, -98936, -98936, -98952, -98999, -99050, +98759, +98759, +98779, +98779, +98779, +98787, +98808, +98815, +98815, +98837, +98837, +98851, +98851, +98851, +98909, +98923, +98938, +98951, +98984, +99030, 99050, 99050, +99056, 99060, 99060, -99093, -99103, -99141, -99166, -99202, -99202, -99215, -99245, -99261, -99268, -99268, -99268, -99268, -99268, -99268, -99305, -99305, -99314, -99314, -99314, -99325, -99325, -99325, -99349, -99367, -99367, -99367, -99371, -99385, -99418, -99444, -99444, -99459, -99459, -99481, -99481, -99518, -99534, -99558, -99624, -99624, -99624, -99624, +99074, +99112, +99112, +99133, +99133, +99145, +99145, +99163, +99163, +99181, +99181, +99204, +99204, +99217, +99217, +99223, +99230, +99241, +99303, +99323, +99398, +99424, +99424, +99424, +99424, +99431, +99442, +99480, +99543, +99543, +99550, +99564, +99581, 99651, -99675, +99658, +99665, +99665, 99679, -99679, -99690, -99690, -99690, -99725, -99725, -99748, -99748, -99762, -99762, -99778, -99798, -99798, -99798, -99810, -99822, -99841, -99855, -99908, -99920, -99920, -99920, -99936, -99941, -99955, -99955, -99955, -99983, -99983, -99997, -100018, -100028, -100028, -100028, -100028, -100028, -100028, -100028, -100028, -100028, -100028, -100083, -100083, -100122, +99723, +99730, +99739, +99739, +99754, +99767, +99793, +99837, +99850, +99857, +99864, +99902, +99915, +99939, +99939, +99957, +100043, +100050, +100050, +100057, +100064, +100071, +100078, +100078, +100139, +100139, 100147, -100147, -100157, -100161, -100161, -100174, -100186, -100190, -100218, -100218, -100227, -100265, -100265, -100310, -100320, -100352, -100366, -100378, -100378, -100392, -100404, -100423, -100442, -100442, -100460, -100460, -100472, -100486, -100503, -100503, -100503, -100513, -100523, -100531, -100537, -100537, +100166, +100191, +100225, +100236, +100260, +100286, +100311, +100319, +100319, +100326, +100363, +100382, +100403, +100403, +100403, +100410, +100420, +100451, +100462, +100518, +100524, 100560, -100560, -100560, -100579, -100579, -100597, -100617, +100583, +100583, +100601, +100610, +100610, +100610, +100610, +100610, +100623, +100623, 100650, -100674, -100681, -100701, -100711, -100731, -100737, -100737, -100737, -100737, -100737, -100737, -100749, -100783, -100783, -100783, -100783, -100803, -100810, -100829, -100829, -100862, -100878, -100878, -100878, -100888, -100888, -100895, -100913, -100913, -100929, -100964, -100964, -100964, -100964, -100964, -100964, -100975, -100975, -100990, -100998, -101050, -101050, -101078, -101093, -101093, -101093, -101110, -101110, -101110, -101110, -101134, -101134, -101159, -101159, -101159, -101159, -101175, -101175, -101175, -101175, -101175, -101206, -101215, -101238, -101238, -101238, -101251, -101251, -101262, -101262, -101298, -101345, -101374, -101374, -101374, -101374, -101379, -101390, -101399, -101399, -101415, -101428, -101428, -101442, -101455, -101484, -101506, -101513, -101513, -101523, -101523, -101523, -101574, -101574, -101574, -101574, -101574, -101603, -101613, -101631, -101640, -101656, -101656, -101665, -101684, -101716, -101716, -101716, +100650, +100650, +100650, +100650, +100696, +100703, +100703, +100710, +100717, +100734, +100837, +100846, +100846, +100853, +100853, +100876, +100917, +100917, +100924, +100931, +100938, +100952, +100971, +100971, +100977, +101000, +101000, +101000, +101000, +101015, +101015, +101015, +101032, +101048, +101067, +101073, +101080, +101098, +101115, +101138, +101138, +101150, +101150, +101150, +101150, +101170, +101178, +101197, +101204, +101228, +101277, +101305, +101372, +101386, +101405, +101412, +101420, +101427, +101427, +101434, +101471, +101478, +101514, +101525, +101557, +101561, +101588, +101630, +101641, +101657, +101672, +101715, +101722, +101722, +101729, +101740, 101746, -101746, -101758, -101758, -101758, -101758, -101758, -101777, -101787, -101801, -101813, +101779, +101779, +101779, +101803, +101803, 101821, -101828, -101845, -101851, -101851, -101851, -101887, -101911, -101917, -101947, -101964, -101992, -102005, -102048, -102048, -102048, -102048, -102048, -102060, -102135, -102143, -102154, -102171, -102187, -102207, -102207, -102220, -102234, -102281, -102332, -102332, -102344, -102357, -102412, -102423, -102423, -102423, -102442, -102449, -102449, -102449, -102449, +101831, +101838, +101859, +101869, +101877, +101919, +101926, +101957, +101981, +101996, +102003, +102010, +102018, +102040, +102062, +102069, +102069, +102069, +102094, +102101, +102140, +102150, +102150, +102155, +102163, +102191, +102228, +102243, +102250, +102282, +102289, +102296, +102296, +102334, +102334, +102384, +102400, +102408, +102433, +102448, +102448, +102462, +102511, 102518, -102535, -102535, -102535, -102535, -102548, -102590, -102605, -102605, -102605, -102632, -102649, -102693, -102698, -102698, -102731, +102545, +102566, +102579, +102598, +102617, +102675, +102682, +102688, +102712, +102721, +102721, +102721, +102745, +102745, 102752, 102752, -102752, -102785, -102813, -102813, -102823, -102831, -102838, -102838, -102873, -102873, -102884, -102891, -102891, -102891, -102891, -102908, -102908, -102934, -102960, -102960, -102960, -102978, -103002, -103032, -103032, -103050, -103055, -103055, -103075, -103134, -103141, -103141, -103141, -103148, -103148, -103188, +102774, +102808, +102828, +102828, +102844, +102892, +102892, +102912, +102928, +102953, +102973, +103000, +103000, +103012, +103021, +103021, +103031, +103031, +103031, +103031, +103056, +103063, +103063, +103079, +103086, +103086, +103097, +103142, +103142, +103154, +103179, 103205, -103205, -103205, -103212, -103222, -103222, -103235, -103235, -103235, -103270, -103270, -103270, -103270, -103298, -103311, -103311, -103356, -103373, -103405, -103405, -103420, -103420, -103420, -103420, -103420, -103430, -103430, -103445, -103458, -103468, -103468, -103473, -103473, -103473, -103494, -103494, -103511, -103511, -103511, -103511, -103584, -103584, -103584, -103584, -103591, -103591, -103613, -103613, -103630, -103639, -103639, -103639, -103639, +103228, +103238, +103238, +103238, +103264, +103288, +103288, +103306, +103306, +103306, +103306, +103315, +103339, +103339, +103339, +103362, +103372, +103428, +103438, +103461, +103471, +103471, +103471, +103480, +103480, +103524, +103524, +103524, +103524, +103568, +103610, +103634, 103651, -103690, -103690, -103696, -103696, -103696, -103712, -103730, -103737, -103737, -103737, -103750, -103777, -103777, -103777, -103777, -103792, -103792, -103792, -103792, -103813, -103813, -103839, -103853, -103865, -103865, -103865, -103877, -103877, -103901, -103901, -103901, -103901, -103915, -103951, -103961, -103961, -103983, -104016, -104016, -104024, -104042, -104042, -104042, -104056, -104064, -104064, -104064, -104064, -104064, -104064, -104064, -104072, -104089, -104099, -104122, -104122, -104158, -104158, -104158, -104164, -104187, -104193, -104193, -104193, -104193, -104216, -104230, -104230, -104240, -104254, -104264, -104294, -104294, -104294, -104320, -104332, +103680, +103680, +103694, +103701, +103701, +103701, +103775, +103782, +103801, +103826, +103850, +103850, +103886, +103886, +103909, +103918, +103926, +103926, +103931, +103982, +103993, +104000, +104044, +104051, +104095, +104102, +104109, +104127, +104134, +104162, +104162, +104183, +104261, +104261, +104268, +104275, +104280, +104297, +104304, 104337, -104344, -104366, -104411, -104420, -104432, -104432, -104440, -104458, -104458, -104458, -104481, -104504, -104504, -104508, -104514, -104543, -104543, -104547, -104547, -104547, -104547, -104547, -104547, -104547, -104562, -104591, -104598, -104625, -104666, -104692, -104703, -104718, -104718, -104737, -104743, -104743, -104762, -104771, -104778, -104803, -104803, -104817, -104823, -104830, -104841, -104841, -104855, -104875, -104875, -104875, -104879, -104886, -104894, -104894, -104922, -104922, -104922, -104922, +104351, +104363, +104363, +104373, +104441, +104453, +104460, +104493, +104617, +104617, +104653, +104653, +104715, +104715, +104715, +104752, +104784, +104798, +104798, +104798, +104814, +104814, +104814, +104814, +104833, +104833, +104859, +104859, +104859, +104859, +104907, +104926, +104933, 104943, -104954, -104966, -104979, -104990, -104990, -105013, -105013, -105041, -105041, -105041, -105041, -105069, -105073, -105073, -105082, -105082, -105086, -105090, -105104, -105122, -105122, -105134, -105134, -105134, -105163, -105173, -105186, -105186, -105186, -105197, -105229, -105229, -105252, -105272, -105276, -105276, -105306, -105306, -105306, -105322, -105322, -105328, -105328, -105341, -105341, -105341, -105341, -105341, -105392, -105397, -105418, +104943, +104943, +104986, +105042, +105049, +105068, +105095, +105095, +105103, +105120, +105120, +105129, +105136, +105136, +105140, +105140, +105140, +105158, +105162, +105162, +105162, +105162, +105169, +105169, +105175, +105193, +105193, +105193, +105193, +105206, +105206, +105215, +105215, +105215, +105268, +105279, +105311, +105324, +105333, +105333, +105355, +105375, +105401, +105413, +105413, 105436, -105444, -105452, -105458, -105458, -105474, -105498, -105516, -105516, -105516, -105521, -105551, -105551, -105576, -105583, -105600, -105600, -105635, -105650, -105650, -105679, -105679, -105679, -105689, -105705, -105735, -105735, -105739, -105739, -105753, -105753, -105753, -105757, -105764, -105764, -105764, -105791, -105795, -105815, -105827, -105837, +105443, +105447, +105447, +105447, +105447, +105462, +105473, +105473, +105473, +105473, +105480, +105501, +105501, +105524, +105529, +105548, +105558, +105558, +105580, +105592, +105592, +105592, +105592, +105613, +105623, +105672, +105686, +105696, +105712, +105720, +105749, +105774, +105774, +105800, +105811, +105811, +105816, +105849, +105857, +105857, 105868, -105868, -105902, -105902, -105916, -105916, -105932, -105939, -105953, -105953, -105953, -105953, -105953, -105962, -105962, -106008, -106008, -106064, -106070, -106070, -106085, -106092, -106092, -106106, -106123, -106123, -106123, -106157, -106166, -106166, -106166, -106186, -106186, -106204, -106222, -106222, -106254, -106265, -106265, -106265, -106265, -106265, -106281, +105894, +105931, +105966, +106016, +106016, +106016, +106022, +106029, +106041, +106062, +106109, +106120, +106133, +106149, +106170, +106211, +106211, +106239, +106239, +106239, +106273, +106280, +106280, +106291, 106298, -106328, -106356, -106362, -106380, -106390, -106396, -106396, -106411, -106430, -106430, -106430, -106430, -106466, -106466, -106466, -106470, -106507, -106507, -106529, -106546, +106298, +106310, +106324, +106371, +106371, +106398, +106409, +106426, +106477, +106477, +106477, +106477, +106477, +106477, +106498, +106498, +106511, +106511, +106516, +106548, 106558, -106568, -106578, -106578, -106578, -106578, -106585, -106585, -106600, -106622, -106645, -106645, -106645, -106645, -106645, -106708, -106708, -106708, -106730, -106740, -106750, -106750, -106795, -106812, -106812, -106812, -106822, -106874, -106926, -106926, -106946, -106960, -106971, -107007, -107023, -107032, -107041, -107048, -107054, -107054, -107054, -107069, -107093, -107093, -107093, -107113, -107123, +106558, +106558, +106558, +106590, +106609, +106658, +106658, +106683, +106725, +106732, +106736, +106736, +106736, +106736, +106736, +106746, +106746, +106755, +106766, +106809, +106809, +106821, +106821, +106821, +106821, +106821, +106841, +106841, +106841, +106877, +106877, +106877, +106915, +106939, +106939, +106955, +106955, +106955, +106981, +106991, +106991, +107025, +107049, +107049, +107049, +107049, +107049, +107049, +107065, +107065, +107065, +107072, +107081, +107103, +107103, +107103, +107103, +107103, +107120, +107120, +107120, +107120, 107131, -107149, -107159, +107166, 107179, -107197, -107210, -107224, +107190, +107190, +107199, +107199, +107207, +107220, +107234, 107244, -107244, -107281, -107290, -107309, -107329, -107329, -107341, +107249, +107249, +107249, +107249, +107262, +107286, +107300, +107300, +107300, +107300, +107310, +107338, +107348, 107358, -107358, -107386, -107404, -107404, -107404, -107404, -107404, -107404, -107429, -107429, -107445, -107445, -107463, -107463, -107463, -107476, -107526, -107530, -107530, -107530, -107561, -107608, -107608, -107641, -107649, -107665, -107720, -107720, -107720, -107756, -107756, -107764, -107770, -107770, -107776, -107776, -107802, -107802, -107819, -107819, -107829, -107829, -107859, -107885, -107885, -107928, -107938, -107944, -107944, -107951, -107957, -107983, -107989, +107408, +107408, +107451, +107513, +107555, +107566, +107566, +107566, +107566, +107582, +107597, +107597, +107597, +107597, +107597, +107628, +107638, +107646, +107660, +107673, +107673, +107685, +107685, +107685, +107691, +107691, +107696, +107728, +107728, +107728, +107728, +107728, +107797, +107806, +107806, +107806, +107822, +107838, +107838, +107862, +107889, +107889, +107905, +107914, +107927, +107934, +107934, +107947, +107947, +107947, +107947, +107947, +107956, +107956, +107961, +107971, +107978, +107978, 107995, -108012, -108049, -108073, -108088, -108088, -108103, -108116, -108132, -108132, -108152, -108199, -108207, -108213, -108213, -108227, -108227, -108244, -108254, +107995, +108006, +108024, +108060, +108069, +108069, +108069, +108069, +108082, +108091, +108125, +108125, +108157, +108219, +108232, +108242, +108248, 108260, -108273, -108273, -108279, -108279, -108305, -108322, -108322, -108322, -108322, -108336, -108336, -108336, -108362, -108375, -108375, -108398, -108398, +108278, +108290, +108302, +108306, +108323, +108323, +108323, +108332, +108332, +108332, +108374, +108421, 108451, -108486, -108522, -108535, -108561, -108593, -108634, -108655, -108655, -108655, -108655, -108674, -108674 +108451, +108473, +108473, +108516, +108534, +108534, +108534, +108550, +108550, +108567, +108567, +108574, +108574, +108574, +108574, +108579, +108579, +108596, +108596, +108596, +108596, +108596, +108596, +108611, +108611, +108618, +108618, +108618, +108632, +108683, +108687, +108707, +108717, +108717, +108730, +108750, +108750, +108750, +108764, +108785, +108789, +108831, +108846, +108881, +108881, +108906, +108906, +108906, +108906, +108926, +108926, +108926, +108972, +108972, +108972, +108986, +108986, +108986, +109077, +109102, +109131, +109216, +109216, +109236, +109297, +109297, +109319, +109319, +109319, +109319, +109319, +109330, +109351, +109351, +109377, +109377, +109377, +109395, +109395, +109418, +109418, +109418, +109418, +109441, +109441, +109441, +109451, +109470, +109470, +109470, +109470, +109474, +109474, +109509, +109509, +109509, +109509, +109588, +109597, +109625, +109625, +109639, +109655, +109655, +109664, +109680, +109680, +109728, +109760, +109760, +109772, +109772, +109772, +109798, +109810, +109817, +109825, +109825, +109825, +109842, +109859, +109859, +109864, +109908, +109908, +109923, +109934, +109934, +109934, +109963, +109963, +109977, +110007, +110007, +110026, +110026, +110076, +110094, +110094, +110104, +110104, +110115, +110115, +110122, +110147, +110147, +110160, +110187, +110187, +110187, +110187, +110199, +110199, +110220, +110229, +110241, +110301, +110322, +110326, +110326, +110336, +110341, +110341, +110341, +110360, +110360, +110360, +110360, +110360, +110365, +110391, +110441, +110441, +110463, +110475, +110475, +110475, +110488, +110498, +110504, +110504, +110539, +110565, +110565, +110581, +110588, +110588, +110595, +110595, +110602, +110645, +110661, +110690, +110711, +110711, +110711, +110711, +110726, +110726, +110738, +110738, +110746, +110754, +110796, +110817, +110843, +110892, +110892, +110900, +110921, +110921, +110939, +110949, +110955, +110955, +110981, +111018, +111034, +111034, +111048, +111057, +111057, +111057, +111086, +111092, +111112, +111112, +111112, +111128, +111144, +111153, +111170, +111203, +111232, +111232, +111272, +111276, +111290, +111300, +111338, +111345, +111354, +111367, +111367, +111399, +111407, +111447, +111480, +111487, +111501, +111594, +111630, +111636, +111657, +111657, +111681, +111691, +111691, +111691, +111705, +111733, +111733, +111733, +111756, +111765, +111765, +111819, +111855, +111855, +111868, +111874, +111874, +111914, +111914, +111914, +111934, +111967, +111993, +112002, +112031, +112031, +112068, +112075, +112082, +112082, +112137, +112137, +112156, +112186, +112186, +112186, +112186, +112213, +112231, +112231, +112231, +112239, +112268, +112268, +112279, +112298, +112298, +112309, +112321, +112336, +112336, +112336, +112346, +112350, +112361, +112361, +112361, +112369, +112377, +112377, +112418, +112418, +112418, +112468, +112468, +112468, +112488, +112488, +112502, +112509, +112526, +112554, +112554, +112554, +112592, +112596, +112613, +112627, +112696, +112781, +112804, +112873, +112913, +112913, +112920, +112931, +112931, +112947, +112976, +112991, +112997, +112997, +113022, +113073, +113103, +113114, +113123, +113123, +113130, +113153, +113221, +113221, +113255, +113271, +113290, +113290, +113290, +113290, +113309, +113368, +113368, +113368, +113411, +113423, +113445, +113445, +113445, +113553, +113564, +113576, +113598, +113650, +113677, +113677, +113677, +113677, +113687, +113693, +113693, +113698, +113698, +113698, +113711, +113728, +113743, +113753, +113753, +113753, +113753, +113753, +113753, +113764, +113779, +113786, +113786, +113792, +113798, +113798, +113798, +113798, +113798, +113804, +113819, +113819, +113819, +113819, +113843, +113843, +113843, +113894, +113919, +113928, +113940, +113959, +113959, +113977, +113977, +113983, +113983, +114005, +114005, +114005, +114021, +114035, +114077, +114093, +114093, +114131, +114131, +114131, +114131, +114137, +114169, +114182, +114182, +114196, +114196, +114196, +114215, +114230, +114243, +114250, +114250, +114269, +114269, +114331, +114331, +114331, +114331, +114331, +114331, +114331, +114331, +114331, +114343, +114358, +114358, +114364, +114392, +114417, +114433, +114439, +114446, +114454, +114472, +114484, +114490, +114553, +114560, +114604, +114604, +114613, +114613, +114623, +114623, +114623, +114623, +114635, +114660, +114660, +114660, +114718, +114724, +114724, +114743, +114756, +114776, +114790, +114790, +114790, +114810, +114897, +114897, +114906, +114906, +114917, +114923, +114923, +114953, +114962, +114999, +114999, +114999, +114999, +115005, +115012, +115012, +115030, +115030, +115040, +115060, +115104, +115112, +115136, +115171, +115171, +115191, +115209, +115227, +115262, +115276, +115284, +115284, +115319, +115319, +115338, +115388, +115388, +115388, +115388, +115403, +115415, +115415, +115415, +115432, +115485, +115502, +115502, +115502, +115502, +115502, +115502, +115502, +115502, +115502, +115519, +115528, +115528, +115534, +115565, +115586, +115664, +115685, +115685, +115748, +115748, +115763, +115768, +115768, +115768, +115825, +115839, +115839, +115848, +115854, +115869, +115869, +115892, +115900, +115900, +115900, +115908, +115942, +115950, +115950, +115976, +115982, +115999, +116021, +116021, +116021, +116041, +116041, +116041, +116060, +116088, +116088, +116088, +116088, +116104, +116143, +116143, +116143, +116143, +116165, +116169, +116183, +116183, +116194, +116194, +116219, +116219, +116244, +116254, +116254, +116254, +116254, +116275, +116292, +116292, +116299, +116350, +116395, +116395, +116422, +116422, +116442, +116450, +116467, +116476, +116482, +116492, +116492, +116492, +116512, +116512, +116566, +116594, +116604, +116640, +116665, +116712, +116712, +116720, +116733, +116733, +116733, +116749, +116749, +116761, +116782, +116802, +116802, +116802, +116802, +116825, +116831, +116841, +116879, +116879, +116885, +116885, +116885, +116901, +116901, +116901, +116907, +116923, +116933, +116942, +116968, +116968, +117006, +117006, +117006, +117006, +117006, +117027, +117048, +117064, +117093, +117167, +117167, +117175, +117193, +117202, +117213, +117213, +117252, +117294, +117294, +117307, +117307, +117325, +117341, +117351, +117358, +117358, +117366, +117366, +117378, +117378, +117378, +117390, +117426, +117477, +117485, +117526, +117547, +117556, +117556, +117565, +117565, +117607, +117631, +117631, +117631, +117631, +117649, +117682, +117682, +117682, +117682, +117692, +117711, +117711, +117741, +117746, +117778, +117778, +117791, +117791, +117791, +117791, +117809, +117819, +117819, +117819, +117844, +117949, +117974, +118018, +118057, +118057, +118065, +118065, +118065, +118075, +118087, +118092, +118092, +118098, +118115, +118121, +118144, +118168, +118180, +118180, +118221, +118271, +118309, +118322, +118322, +118322, +118328, +118328, +118347, +118347, +118378, +118388, +118392, +118404, +118404, +118425, +118425, +118425, +118435, +118485, +118514, +118524, +118535, +118549, +118549, +118549, +118562, +118562, +118599, +118599, +118606, +118606, +118610, +118610, +118610, +118652, +118656, +118665, +118684, +118736, +118746, +118746, +118746, +118752, +118752, +118756, +118792, +118792, +118796, +118833, +118856, +118918, +118952, +118952, +118977, +118994, +119012, +119012, +119037, +119037, +119037, +119049, +119049, +119086, +119086, +119086, +119091, +119091, +119102, +119126, +119126, +119126, +119133, +119133, +119148, +119161, +119200, +119200, +119200, +119200, +119200, +119221, +119268, +119268, +119268, +119282, +119314, +119320, +119351, +119368, +119368, +119381, +119381, +119462, +119462, +119462, +119512, +119512, +119516, +119516, +119516, +119516, +119516, +119526, +119544, +119544, +119544, +119615, +119615, +119629, +119666, +119678, +119687, +119720, +119720, +119737, +119737, +119747, +119755, +119755, +119755, +119787, +119787, +119787, +119812, +119844, +119855, +119855, +119855, +119862, +119862, +119862, +119862, +119862, +119885, +119920, +119920, +119929, +119929, +119973, +119995, +120013, +120013, +120019, +120019, +120036, +120036, +120036, +120056, +120077, +120077, +120105, +120105, +120105, +120119, +120119, +120172, +120176, +120188, +120194, +120201, +120201, +120212, +120229, +120229, +120229, +120250, +120264, +120264, +120302, +120302, +120337, +120337, +120337, +120345, +120357, +120357, +120357, +120373, +120373, +120373, +120373, +120406, +120421, +120421, +120421, +120421, +120431, +120450, +120459, +120475, +120475, +120475, +120529, +120548, +120560, +120569, +120595, +120595, +120607, +120607, +120611, +120633, +120633, +120692, +120692, +120702, +120702, +120702, +120742, +120749, +120758, +120778, +120827, +120827, +120863, +120863, +120871, +120890, +120936, +120936, +120965, +120978, +121038, +121038, +121038, +121038, +121042, +121042, +121042, +121042, +121050, +121057, +121064, +121064, +121076, +121126, +121126, +121126, +121157, +121157, +121162, +121162, +121162, +121170, +121170, +121198, +121217, +121217, +121217, +121231, +121241, +121260, +121260, +121284, +121289, +121289, +121289, +121289, +121348, +121352, +121361, +121368, +121378, +121382, +121427, +121495, +121508, +121517, +121534, +121550, +121550, +121550, +121550, +121557, +121566, +121634, +121634, +121634, +121642, +121642, +121650, +121667, +121700, +121706, +121706, +121742, +121742, +121756, +121774, +121805, +121815, +121815, +121815, +121815, +121829, +121885, +121885, +121885, +121929, +121929, +121939, +121949, +121961, +122011, +122011, +122011, +122015, +122037, +122053, +122089, +122089, +122102, +122125, +122144, +122178, +122219, +122253, +122288, +122288, +122315, +122315, +122315, +122325, +122339, +122393, +122420, +122427, +122437, +122447, +122468, +122468, +122505, +122505, +122505, +122523, +122523, +122523, +122523, +122523, +122523, +122545, +122563, +122563, +122583, +122583, +122608, +122608, +122608, +122608, +122608, +122615, +122632, +122632, +122632, +122642, +122652, +122652, +122652, +122670, +122706, +122722, +122742, +122761, +122795, +122795, +122810, +122815, +122846, +122906, +122906, +122918, +122931, +122931, +122937, +122956, +122989, +122989, +123038, +123038, +123064, +123101, +123140, +123150, +123150, +123150, +123175, +123224, +123224, +123224, +123251, +123251, +123251, +123301, +123301, +123312, +123312, +123348, +123348, +123372, +123372, +123372, +123372, +123390, +123390, +123445, +123445, +123452, +123458, +123458, +123490, +123490, +123490, +123490, +123490, +123505, +123505, +123512, +123544, +123554, +123575, +123596, +123629, +123629, +123656, +123756, +123760, +123760, +123760, +123820, +123820, +123829, +123843, +123843, +123843, +123853, +123873, +123885, +123885, +123902, +123902, +123902, +123902, +123930, +123930, +123950, +123950, +123980, +123980, +124002, +124024, +124043, +124112, +124112, +124128, +124139, +124163, +124174, +124209, +124209, +124209, +124258, +124285, +124290, +124290, +124290, +124297, +124309, +124309, +124355, +124371, +124371, +124379, +124379, +124379, +124426, +124426, +124438, +124479, +124504, +124521, +124521, +124546, +124546, +124556, +124589, +124589, +124589, +124589, +124631, +124642, +124664, +124664, +124664, +124664, +124664, +124678, +124702, +124702, +124702, +124748, +124753, +124773, +124773, +124785, +124785, +124785, +124817, +124841, +124841, +124855, +124855, +124895, +124895, +124895, +124895, +124910, +124920, +124920, +124920, +124945, +124991, +125024, +125033, +125033, +125049, +125064, +125087, +125087, +125087, +125109, +125120, +125128, +125138, +125138, +125148, +125160, +125171, +125171, +125181, +125181, +125181, +125191, +125197, +125217, +125217, +125227, +125227, +125242, +125250, +125262, +125312, +125346, +125373, +125381, +125396, +125413, +125418, +125418, +125426, +125426, +125468, +125468, +125468, +125484, +125484, +125484, +125484, +125506, +125510, +125510, +125510, +125530, +125530, +125545, +125545, +125545, +125545, +125555, +125569, +125594, +125594, +125603, +125603, +125645, +125674, +125719, +125731, +125750, +125779, +125779, +125789, +125832, +125842, +125842, +125842, +125842, +125855, +125855, +125855, +125855, +125855, +125873, +125873, +125940, +125957, +125978, +125978, +125978, +125978, +126000, +126009, +126009, +126028, +126028, +126036, +126057, +126078, +126097, +126111, +126128, +126128, +126134, +126134, +126153, +126166, +126166, +126173, +126195, +126216, +126216, +126216, +126216, +126286, +126286, +126292, +126292, +126292, +126316, +126316, +126326, +126326, +126366, +126387, +126387, +126451, +126460, +126460, +126460, +126460, +126467, +126503, +126529, +126529, +126551, +126567, +126567, +126567, +126597, +126597, +126597, +126602, +126621, +126628, +126628, +126639, +126675, +126686, +126686, +126686, +126695, +126751, +126762, +126762, +126806, +126857, +126874, +126886, +126948, +126948, +126948, +126956, +126956, +126984, +126984, +127001, +127015, +127027, +127046, +127046 }; static const quint16 tldChunkCount = 2; static const char * const tldData[tldChunkCount] = { -"trentino.it\0dds\0" -"fuel.aero\0kure.hiroshima.jp\0" -"hofu.yamaguchi.jp\0isla.pr\0alsace\0" -"oyodo.nara.jp\0elverum.no\0" -"\xe7\xb6\xb2\xe7\xb5\xa1.\xe9\xa6\x99\xe6\xb8\xaf\0kuokgroup\0" -"dst.mi.us\0" -"yamanouchi.nagano.jp\0" -"mo-i-rana.no\0nagoya\0" -"mol.it\0" -"togo.aichi.jp\0" -"film.hu\0homeftp.net\0" -"chizu.tottori.jp\0" -"kasuga.hyogo.jp\0k12.sc.us\0" -"dev\0selfip.info\0" -"ando.nara.jp\0" -"fg.it\0" -"yamanobe.yamagata.jp\0edeka\0" -"co.gg\0" -"co.gl\0ostroda.pl\0jpmorgan\0media\0" -"\xd0\xb1\xd0\xb3\0" -"cuiaba.br\0tosa.kochi.jp\0" -"kamigori.hyogo.jp\0bryne.no\0fusa.no\0vfs.cloud9.me-south-1.amazonaws.com\0" -"ichikawa.chiba.jp\0" -"yali.mythic-beasts.com\0" -"ookuwa.nagano.jp\0" -"serveblog.net\0" -"channel\0koobin.events\0" -"co.gy\0" -"shichinohe.aomori.jp\0" -"wiw.gov.pl\0lib.mo.us\0" -"moriyoshi.akita.jp\0kyotanabe.kyoto.jp\0natura\0" -"chikusei.ibaraki.jp\0" -"co.id\0immobilien\0co.events\0" -"co.hu\0dhl\0" -"\xe9\xab\x98\xe7\x9f\xa5.jp\0gallup\0" -"ham-radio-op.net\0" -"mo.us\0" -"co.il\0" -"co.im\0monza-e-della-brianza.it\0" -"co.in\0" -"kvalsund.no\0" -"app.br\0" -"co.ir\0toyokawa.aichi.jp\0noshiro.akita.jp\0chikuho.fukuoka.jp\0" -"loginline.services\0" -"airport.aero\0co.it\0" -"co.je\0" -"tushu\0" -"east-kazakhstan.su\0" -"deal\0\xe3\x82\xb9\xe3\x83\x88\xe3\x82\xa2\0" -"co.education\0" -"movie\0" -"yukuhashi.fukuoka.jp\0" -"hs.run\0" -"house\0halfmoon.jp\0" -"co.jp\0" -"diy\0" -"koryo.nara.jp\0k8s.pl-waw.scw.cloud\0" -"co.ke\0s3-eu-central-1.amazonaws.com\0" -"kanegasaki.iwate.jp\0" -"w.bg\0" -"abruzzo.it\0co.kr\0" -"co.lc\0" -"from-or.com\0us.eu.org\0" -"health\0" -"davvenj\xc3\xa1rga.no\0" -"etne.no\0" -"sncf\0" -"chiba.jp\0" -"kepno.pl\0\xd9\x82\xd8\xb7\xd8\xb1\0" -"sh.cn\0" -"yasuoka.nagano.jp\0" -"k12.ms.us\0k12.nc.us\0" -"co.ma\0" -"co.ls\0" -"c.bg\0trentino-sued-tirol.it\0co.me\0dating\0now-dns.top\0" -"ag.it\0" -"ishikawa.fukushima.jp\0co.mg\0" -"polkowice.pl\0\xd0\xb5\xd1\x8e\0" -"cloud66.zone\0" -"shinshiro.aichi.jp\0" -"nat.tn\0" -"imabari.ehime.jp\0s\xc3\xb8rum.no\0" -"chambagri.fr\0kouzushima.tokyo.jp\0co.na\0" -"co.mu\0rost.no\0vana\0" -"co.mw\0" -"fuji.shizuoka.jp\0" -"vt.it\0co.ni\0tysfjord.no\0" -"co.mz\0" -"pepper.jp\0" -"pp.az\0co.nl\0" -"trani-andria-barletta.it\0thruhere.net\0dagestan.ru\0" -"co.no\0app.gp\0" -"misato.wakayama.jp\0lamborghini\0" -"sykkylven.no\0wolomin.pl\0" -"soni.nara.jp\0cc.as.us\0is-a-linux-user.org\0" -"dnp\0cyon.link\0" -"higashimatsushima.miyagi.jp\0co.nz\0" -"fnwk.site\0" -"up.in\0landrover\0" -"smola.no\0co.om\0dagestan.su\0" -"stord.no\0" -"mints.ne.jp\0" -"campidano-medio.it\0gs.st.no\0dog\0chu.jp\0" -"band\0" -"airbus\0" -"university\0boxfuse.io\0" -"joburg\0knightpoint.systems\0vaporcloud.io\0" -"tynset.no\0" -"bank\0" -"nohost.me\0" -"taiji.wakayama.jp\0co.pl\0" -"dot\0" -"koga.ibaraki.jp\0co.pn\0" -"k8s.scw.cloud\0" -"oshima.tokyo.jp\0" -"higashi.fukushima.jp\0gol.no\0" -"coop.ht\0sel.no\0" -"co.pw\0couchpotatofries.org\0" -"\xe5\x95\x86\xe5\xba\x97\0land-4-sale.us\0" -"cloudaccess.host\0" -"pomorze.pl\0" -"coop.in\0" -"higashiyodogawa.osaka.jp\0" -"kunigami.okinawa.jp\0" -"coop.ar\0" -"lcube-server.de\0" -"from-wi.com\0" -"marumori.miyagi.jp\0" -"omega\0" -"sakuragawa.ibaraki.jp\0" -"eat\0" -"arab\0co.ro\0" -"vfs.cloud9.eu-west-1.amazonaws.com\0itcouldbewor.se\0" -"co.rs\0" -"coop.br\0" -"co.rw\0" -"tadotsu.kagawa.jp\0" -"osaki.miyagi.jp\0" -"cc.tx.us\0" -"aquarelle\0" -"quangnam.vn\0" -"dnsiskinky.com\0" -"dev.br\0co.st\0" -"md.ci\0lavagis.no\0" -"reggioemilia.it\0fukushima.hokkaido.jp\0co.th\0eco\0webview-assets.cloud9.me-south-1.amazonaws.com\0" -"slattum.no\0" -"co.sz\0co.tj\0fido\0" -"zp.ua\0" -"tatar\0" -"folkebibl.no\0co.tm\0" -"tur.ar\0" -"co.ua\0" -"villas\0" -"co.tt\0chernihiv.ua\0" -"amami.kagoshima.jp\0" -"lib.co.us\0noho.st\0" -"higashiomi.shiga.jp\0co.ug\0" -"hjelmeland.no\0r\xc3\xb8""d\xc3\xb8y.no\0dell\0" -"co.tz\0eero-stage.online\0" -"mutual.ar\0co.uk\0" -"kamiizumi.saitama.jp\0" -"edu\0camau.vn\0" -"ravenna.it\0mitou.yamaguchi.jp\0dtv\0" -"tur.br\0" -"16-b.it\0" -"isernia.it\0" -"s\xc3\xb8rfold.no\0co.us\0" -"gs.nt.no\0theworkpc.com\0" -"numata.hokkaido.jp\0co.ve\0" -"viajes\0" -"co.vi\0" -"oharu.aichi.jp\0bearalv\xc3\xa1hki.no\0co.uz\0" -"c.la\0" -"hamamatsu.shizuoka.jp\0" -"law.pro\0" -"yusui.kagoshima.jp\0" -"lyngdal.no\0florist\0" -"kagoshima.kagoshima.jp\0" -"swidnik.pl\0" -"dvr\0" -"jl.cn\0" -"\xd1\x80\xd1\x84\0" -"kanmaki.nara.jp\0" -"dyndns.org\0" -"scrysec.com\0" -"construction\0g\xc3\xbcnstigliefern.de\0" -"hattfjelldal.no\0" -"accountant\0watches\0" -"lezajsk.pl\0" -"ltda\0" -"cam.it\0ddnsfree.com\0" -"grondar.za\0" -"osasco.br\0mishima.shizuoka.jp\0ringerike.no\0" -"frogn.no\0" -"from-co.net\0" -"tsu.mie.jp\0" -"sandvikcoromant\0" -"seiyo.ehime.jp\0k12.dc.us\0" -"crafting.xyz\0" -"naganohara.gunma.jp\0" -"nikolaev.ua\0" -"luroy.no\0earth\0" -"\xe7\xa7\x8b\xe7\x94\xb0.jp\0" -"lib.ak.us\0co.za\0" -"\xe4\xb8\xaa\xe4\xba\xba.hk\0" -"\xe5\xb1\xb1\xe6\xa2\xa8.jp\0hosp.uk\0" -"t3l3p0rt.net\0jele.host\0" -"tsuno.miyazaki.jp\0" -"vt.us\0" -"komoro.nagano.jp\0" -"kawaguchi.saitama.jp\0" -"mitake.gifu.jp\0" -"co.zm\0cistron.nl\0" -"deta.app\0" -"kariwa.niigata.jp\0boy.jp\0" -"lt.it\0" -"pagexl.com\0" -"tr\xc3\xa6na.no\0" -"fnd.br\0" -"emerck\0" -"co.zw\0" -"global.ssl.fastly.net\0" -"tobishima.aichi.jp\0" -"ngrok.pizza\0fnc.fr-par.scw.cloud\0" -"hidaka.wakayama.jp\0" -"myamaze.net\0" -"selje.no\0homesense\0" -"b\xc3\xb8mlo.no\0static-access.net\0lublin.pl\0tuxfamily.org\0" -"hakodate.hokkaido.jp\0stargard.pl\0" -"toyooka.hyogo.jp\0" -"desi\0" -"kumatori.osaka.jp\0hatoyama.saitama.jp\0" -"davvenjarga.no\0" -"moriya.ibaraki.jp\0\xe1\x83\x92\xe1\x83\x94\0film\0" -"ol.no\0w.se\0" -"quest\0" -"cosenza.it\0idrett.no\0" -"tonaki.okinawa.jp\0r\xc3\xb8mskog.no\0zappos\0" -"platter-app.com\0" -"izu.shizuoka.jp\0" -"stjordalshalsen.no\0" -"aktyubinsk.su\0" -"mx.na\0herokussl.com\0" -"ichikai.tochigi.jp\0" -"shonai.fukuoka.jp\0matsushima.miyagi.jp\0wegrow.pl\0courses\0exchange\0webview-assets.cloud9.eu-west-3.amazonaws.com\0" -"gjemnes.no\0" -"ofunato.iwate.jp\0" -"suginami.tokyo.jp\0" -"movimiento.bo\0" -"riobranco.br\0" -"shimogo.fukushima.jp\0" -"sayama.saitama.jp\0c.se\0allstate\0bar0.net\0" -"edu.eu.org\0" -"eidfjord.no\0law.za\0" -"blackbaudcdn.net\0" -"takagi.nagano.jp\0" -"ny-1.paas.massivegrid.net\0" -"dopaas.com\0" -"jampa.br\0" -"space\0" -"ichinomiya.aichi.jp\0commbank\0" -"pizza\0in.net\0" -"kl\xc3\xa6""bu.no\0" -"pp.se\0pp.ru\0opal.ne.jp\0" -"\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0kasuga.fukuoka.jp\0" -"jewelry\0" -"ddns.me\0" -"furudono.fukushima.jp\0gulen.no\0drayddns.com\0" -"press.cy\0independent-review.uk\0jele.club\0" -"moriguchi.osaka.jp\0meloy.no\0" -"development.run\0" -"army\0" -"chigasaki.kanagawa.jp\0byen.site\0" -"\xe7\xb6\xb2\xe7\xb5\xa1.cn\0" -"repl.run\0" -"\xd0\xbc\xd0\xbe\xd1\x81\xd0\xba\xd0\xb2\xd0\xb0\0" -"bahcavuotna.no\0jprs\0mydobiss.com\0" -"\xd1\x83\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0wedding\0" -"kushima.miyazaki.jp\0nowruz\0myshopify.com\0" -"is-a-bruinsfan.org\0iobb.net\0mcpre.ru\0pp.ua\0" -"uryu.hokkaido.jp\0cafjs.com\0gliwice.pl\0" -"sa-east-1.elasticbeanstalk.com\0" -"bnpparibas\0" -"arpa\0" -"mikasa.hokkaido.jp\0niimi.okayama.jp\0utsira.no\0fire\0" -"eniwa.hokkaido.jp\0" -"oyamazaki.kyoto.jp\0namsskogan.no\0" -"fan\0\xd8\xa7\xd9\x84\xd8\xb9\xd9\x84\xd9\x8a\xd8\xa7\xd9\x86\0" -"iyo.ehime.jp\0" -"sohu\0sphinx.mythic-beasts.com\0" -"grane.no\0" -"dynalias.org\0" -"mazowsze.pl\0" -"rebun.hokkaido.jp\0saku.nagano.jp\0getmyip.com\0" -"chirurgiens-dentistes-en-france.fr\0" -"fish\0" -"nakagawa.fukuoka.jp\0namdinh.vn\0" -"webview-assets.aws-cloud9.ap-south-1.amazonaws.com\0fr.eu.org\0" -"trentinosued-tirol.it\0gjerdrum.no\0" -"nakatombetsu.hokkaido.jp\0" -"coop.rw\0" -"katsushika.tokyo.jp\0royken.no\0" -"desa.id\0" -"nissan\0groks-the.info\0" -"ako.hyogo.jp\0agakhan\0" -"webview-assets.cloud9.eu-west-2.amazonaws.com\0" -"shikama.miyagi.jp\0" -"koori.fukushima.jp\0esq\0vfs.cloud9.ap-northeast-3.amazonaws.com\0" -"mongolian.jp\0" -"onagawa.miyagi.jp\0" -"nissay\0in-brb.de\0" -"skanland.no\0supabase.in\0" -"ibaraki.osaka.jp\0" -"\xe7\xb6\xb2\xe7\xb5\xa1.hk\0" -"coop.tt\0" -"\xd7\x90\xd7\xa7\xd7\x93\xd7\x9e\xd7\x99\xd7\x94.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0nh.us\0" -"ce.leg.br\0" -"trentinoa-adige.it\0anquan\0lefrak\0" -"trentinos\xc3\xbc""d-tirol.it\0alt.za\0" -"ui.nabu.casa\0" -"troitsk.su\0" -"hyllestad.no\0lt.ua\0asda\0" -"lundbeck\0" -"kembuchi.hokkaido.jp\0" -"\xe7\x82\xb9\xe7\x9c\x8b\0" -"arte\0" -"\xe6\x84\x9b\xe5\xaa\x9b.jp\0tsuga.tochigi.jp\0lib.nh.us\0s3-website-eu-west-1.amazonaws.com\0" -"ibaraki.jp\0hirado.nagasaki.jp\0yatsuka.shimane.jp\0" -"leangaviika.no\0lillesand.no\0demo.datacenter.fi\0" -"shiga.jp\0coop.mv\0" -"coop.mw\0" -"ce.gov.br\0" -"eus\0" -"iizuka.fukuoka.jp\0" -"md.us\0loginline.dev\0" -"g\xc3\xa1\xc5\x8bgaviika.no\0k12.or.us\0firewalledreplit.co\0" -"tatamotors\0for-more.biz\0" -"gs.ah.no\0" -"bt.it\0" -"vgs.no\0" -"song\0" -"loginline.site\0" -"bbva\0servesarcasm.com\0" -"takata.fukuoka.jp\0miyoshi.tokushima.jp\0" -"contractors\0vpnplus.to\0" -"ashoro.hokkaido.jp\0\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82\0" -"higashisumiyoshi.osaka.jp\0" -"dev.vu\0" -"eu.encoway.cloud\0" -"kasaoka.okayama.jp\0contact\0" -"\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4\0ap-northeast-3.elasticbeanstalk.com\0" -"k12.nv.us\0" -"us.org\0readmyblog.org\0smartlabeling.scw.cloud\0" -"komae.tokyo.jp\0sony\0internet-dns.de\0" -"\xe5\xb1\xb1\xe5\xbd\xa2.jp\0gujo.gifu.jp\0otsu.shiga.jp\0" -"modalen.no\0" -"l.bg\0" -"ap.it\0" -"messerli.app\0myds.me\0" -"verbania.it\0" -"oksnes.no\0skaun.no\0" -"vibovalentia.it\0s3-website-sa-east-1.amazonaws.com\0" -"coop.py\0" -"jur.pro\0" -"tainai.niigata.jp\0gs.va.no\0" -"k12.nj.us\0" -"omitama.ibaraki.jp\0" -"molde.no\0" -"funabashi.chiba.jp\0meet\0" -"vao.it\0fit\0" -"asia\0" -"recipes\0" -"*.sapporo.jp\0vinhphuc.vn\0seidat.net\0" -"khmelnitskiy.ua\0musician.io\0supabase.co\0" -"\xd9\x83\xd8\xa7\xd8\xab\xd9\x88\xd9\x84\xd9\x8a\xd9\x83\0" -"winners\0oops.jp\0pythonanywhere.com\0" -"fermo.it\0" -"shimokawa.hokkaido.jp\0" -"pdns.page\0" -"homeunix.net\0" -"incheon.kr\0gs.tm.no\0" -"vi.it\0" -"coop.km\0" -"imizu.toyama.jp\0" -"\xd7\xa6\xd7\x94\xd7\x9c.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0mc.eu.org\0" -"cc.wy.us\0cupcake.is\0" -"hanyu.saitama.jp\0" -"pe.ca\0" -"gangwon.kr\0" -"pvh.br\0zhytomyr.ua\0" -"city.hu\0" -"mycd.eu\0" -"clinique\0" -"on-web.fr\0" -"srv.br\0" -"aju.br\0support\0" -"saijo.ehime.jp\0" -"0.bg\0minakami.gunma.jp\0soka.saitama.jp\0" -"webhop.biz\0" -"\xc3\xa5lesund.no\0" -"v\xc3\xa6r\xc3\xb8y.no\0" -"fly\0" -"obanazawa.yamagata.jp\0" -"lt.eu.org\0" -"neat-url.com\0" -"myshopblocks.com\0" -"\xd7\x9e\xd7\x9e\xd7\xa9\xd7\x9c.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0otaki.nagano.jp\0" -"is-into-cartoons.com\0" -"fukudomi.saga.jp\0" -"seihi.nagasaki.jp\0" -"nord-odal.no\0" -"ta.it\0" -"\xd9\x83\xd9\x88\xd9\x85\0" -"fuso.aichi.jp\0" -"minamiise.mie.jp\0" -"\xe0\xb9\x80\xe0\xb8\x99\xe0\xb9\x87\xe0\xb8\x95.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0hospital\0" -"cc.va.us\0" -"krym.ua\0coupons\0" -"emp.br\0" -"sodegaura.chiba.jp\0" -"ryuoh.shiga.jp\0" -"ikeda.fukui.jp\0wassamu.hokkaido.jp\0bentley\0" -"bulsan-sudtirol.it\0" -"fortal.br\0" -"hiratsuka.kanagawa.jp\0yawata.kyoto.jp\0" -"foo\0industries\0" -"rm.it\0niigata.niigata.jp\0" -"creditcard\0shiftcrypto.dev\0" -"cx.ua\0" -"mihara.kochi.jp\0" -"sampa.br\0khanhhoa.vn\0" -"fox\0" -"tjmaxx\0" -"bloomberg\0" -"kitamoto.saitama.jp\0" -"toyone.aichi.jp\0" -"meme\0" -"urbino-pesaro.it\0nerdpol.ovh\0" -"atsuma.hokkaido.jp\0" -"szczecin.pl\0" -"matsusaka.mie.jp\0" -"myftp.org\0" -"from.hr\0" -"gal\0" -"gap\0" -"press.se\0" -"kikonai.hokkaido.jp\0twmail.net\0" -"lasalle\0eu.meteorapp.com\0" -"tohma.hokkaido.jp\0" -"seiro.niigata.jp\0" -"gay\0" -"krokstadelva.no\0\xe6\x8b\x9b\xe8\x81\x98\0ufcfan.org\0" -"frl\0" -"nanbu.yamanashi.jp\0" -"repair\0" -"moskenes.no\0myasustor.com\0" -"pe.it\0zentsuji.kagawa.jp\0" -"agency\0" -"menu\0is-a-liberal.com\0" -"omachi.saga.jp\0" -"fh-muenster.io\0" -"aknoluokta.no\0" -"kitakata.fukushima.jp\0" -"oyer.no\0" -"richardli\0" -"pinoko.jp\0" -"tromsa.no\0\xe9\x9b\xbb\xe8\xa8\x8a\xe7\x9b\x88\xe7\xa7\x91\0d.gv.vc\0is-an-actress.com\0" -"forlicesena.it\0" -"miyashiro.saitama.jp\0" -"hra.health\0" -"in-dsl.org\0" -"yamamoto.miyagi.jp\0kita.tokyo.jp\0" -"n4t.co\0" -"higashimatsuyama.saitama.jp\0" -"in-dsl.de\0" -"paas.hosted-by-previder.com\0au.ngrok.io\0" -"rankoshi.hokkaido.jp\0gdn\0" -"pe.kr\0\xc3\xa1lt\xc3\xa1.no\0" -"kawaminami.miyazaki.jp\0gea\0" -"ftr\0" -"nishikawa.yamagata.jp\0" -"miyota.nagano.jp\0est.pr\0" -"sn\xc3\xa5""ase.no\0" -"shiwa.iwate.jp\0skedsmokorset.no\0" -"journalist.aero\0americanexpress\0" -"fun\0" -"translated.page\0" -"yamashina.kyoto.jp\0" -"rome.it\0" -"*.bzz.dapps.earth\0" -"is-a-photographer.com\0" -"glogow.pl\0nsupdate.info\0" -"toyosato.shiga.jp\0uw.gov.pl\0" -"tickets.io\0" -"sondre-land.no\0" -"joso.ibaraki.jp\0" -"vi.us\0" -"safety\0" -"aetna\0" -"bhz.br\0arkhangelsk.su\0jele.io\0" -"malopolska.pl\0compare\0" -"s3-website.eu-west-2.amazonaws.com\0" -"li.it\0h\xc3\xa5.no\0" -"press.ma\0eu.ax\0" -"kawaue.gifu.jp\0" -"mugi.tokushima.jp\0lib.vi.us\0" -"bifuka.hokkaido.jp\0" -"snoasa.no\0" -"fantasyleague.cc\0" -"vads\xc3\xb8.no\0" -"gyeonggi.kr\0" -"iwafune.tochigi.jp\0" -"ciencia.bo\0kuron.jp\0" -"jpn.com\0" -"go.leg.br\0" -"yokaichiba.chiba.jp\0k12.wy.us\0\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0rehab\0spot\0" -"jobs.tt\0goupile.fr\0" -"vic.edu.au\0l.se\0" -"fyi\0" -"inc.hk\0" -"cc.me.us\0edgesuite-staging.net\0" -"go.gov.br\0" -"vet.br\0\xd8\xa7\xd9\x84\xd8\xa8\xd8\xad\xd8\xb1\xd9\x8a\xd9\x86\0" -"\xd9\x85\xd8\xb5\xd8\xb1\0" -"kasukabe.saitama.jp\0g\xc3\xa1ls\xc3\xa1.no\0" -"chosei.chiba.jp\0myspreadshop.co.uk\0" -"tomakomai.hokkaido.jp\0kwp.gov.pl\0webview-assets.cloud9.af-south-1.amazonaws.com\0vologda.su\0" -"s3-ap-southeast-1.amazonaws.com\0" -"\xe8\xb0\xb7\xe6\xad\x8c\0" -"sakahogi.gifu.jp\0" -"yokoshibahikari.chiba.jp\0squares.net\0" -"brescia.it\0sakawa.kochi.jp\0" -"cc.la.us\0" -"hakone.kanagawa.jp\0" -"krasnodar.su\0" -"airkitapps.eu\0mk.eu.org\0lug.org.uk\0" -"schools.nsw.edu.au\0" -"safety.aero\0gifu.jp\0" -"magnet.page\0" -"valleeaoste.it\0luxe\0" -"gle\0" -"kunneppu.hokkaido.jp\0gj\xc3\xb8vik.no\0" -"lohmus.me\0" -"miasta.pl\0" -"mibu.tochigi.jp\0" -"company\0" -"karuizawa.nagano.jp\0ju.mp\0" -"ogata.akita.jp\0" -"mandal.no\0" -"union.aero\0xz.cn\0" -"pymnt.uk\0" -"kaminoyama.yamagata.jp\0from-nj.com\0" -"bridgestone\0" -"yashiro.hyogo.jp\0gmo\0" -"ise.mie.jp\0" -"gmx\0" -"trentino-s\xc3\xbc""dtirol.it\0" -"valleedaoste.it\0" -"sakaiminato.tottori.jp\0" -"mine.nu\0" -"yamakita.kanagawa.jp\0marine.ru\0" -"nyc.mn\0" -"*.vps.myjino.ru\0" -"kurotaki.nara.jp\0l\xc3\xa1hppi.no\0" -"carrara-massa.it\0" -"realestate.pl\0" -"fe.it\0vibo-valentia.it\0" -"deta.dev\0lu.eu.org\0me.eu.org\0" -"goo\0" -"gop\0" -"cc.gu.us\0" -"valle-daosta.it\0webview-assets.aws-cloud9.ca-central-1.amazonaws.com\0" -"got\0" -"fujimi.nagano.jp\0" -"gov\0aremark.no\0" -"latina.it\0venice.it\0" -"pesarourbino.it\0" -"kaho.fukuoka.jp\0" -"dyndns-work.com\0" -"iwanuma.miyagi.jp\0futbol\0" -"toyota.aichi.jp\0supplies\0" -"int.eu.org\0" -"gs.bu.no\0" -"hm.no\0tjome.no\0cust.testing.thingdust.io\0" -"cc.ga.us\0" -"*.banzai.cloud\0lv.eu.org\0" -"tozsde.hu\0" -"kontum.vn\0uk.reclaim.cloud\0" -"parachuting.aero\0" -"ishikari.hokkaido.jp\0" -"muika.niigata.jp\0k12.pa.us\0" -"misato.miyagi.jp\0" -"servers.run\0" -"aosta-valley.it\0stj\xc3\xb8rdal.no\0" -"!city.sendai.jp\0vanylven.no\0" -"kiryu.gunma.jp\0minisite.ms\0" -"misasa.tottori.jp\0" -"lib.me.us\0hbo\0" -"airkitapps.com\0" -"unnan.shimane.jp\0" -"dattolocal.com\0" -"consulting.aero\0kagoshima.jp\0" -"iide.yamagata.jp\0" -"fujikawa.shizuoka.jp\0ky.us\0" -"tj.cn\0longan.vn\0" -"friulivgiulia.it\0" -"akishima.tokyo.jp\0" -"from-md.com\0" -"*.futurecms.at\0" -"caa.aero\0tottori.tottori.jp\0mo\xc3\xa5reke.no\0static.land\0" -"u.bg\0" -"priv.hu\0bi.it\0" -"vfs.cloud9.us-west-1.amazonaws.com\0" -"her\xc3\xb8y.m\xc3\xb8re-og-romsdal.no\0kyiv.ua\0lib.ky.us\0cloudns.club\0" -"lebork.pl\0weibo\0" -"es.eu.org\0firebaseapp.com\0" -"b\xc3\xa5tsfjord.no\0" -"dyndns-at-work.com\0" -"us-west-1.elasticbeanstalk.com\0" -"greta.fr\0news.hu\0" -"smushcdn.com\0" -"nikko.tochigi.jp\0" -"br\xc3\xb8nn\xc3\xb8y.no\0virtualuser.de\0" -"talk\0" -"podzone.net\0" -"tokyo\0" -"a.bg\0audi\0" -"yamada.iwate.jp\0from.tv\0" -"hokkaido.jp\0" -"jogasz.hu\0kasahara.gifu.jp\0hiraya.nagano.jp\0" -"pantheonsite.io\0" -"vfs.cloud9.ap-southeast-2.amazonaws.com\0" -"avoues.fr\0" -"wolterskluwer\0" -"hdfcbank\0" -"\xe5\xbe\xb3\xe5\xb3\xb6.jp\0" -"unusualperson.com\0" -"yono.saitama.jp\0" -"catering.aero\0" -"choshi.chiba.jp\0" -"tec.br\0vr.it\0vision\0is-very-nice.org\0" -"\xe5\xb1\xb1\xe5\x8f\xa3.jp\0voss.no\0" -"tamba.hyogo.jp\0" -"ardal.no\0" -"homeunix.org\0" -"taiki.mie.jp\0beer\0" -"fudai.iwate.jp\0" -"j\xc3\xb8rpeland.no\0" -"lib.ia.us\0" -"gunma.jp\0meguro.tokyo.jp\0lawyer\0" -"gives\0" -"cuisinella\0" -"fr\xc3\xb8ya.no\0" -"nishikata.tochigi.jp\0" -"tysv\xc3\xa6r.no\0" -"ondigitalocean.app\0sytes.net\0" -"hosting-cluster.nl\0cdn-edges.net\0" -"vestre-slidre.no\0" -"davvesiida.no\0verm\xc3\xb6gensberater\0" -"9.bg\0" -"under.jp\0" -"masuda.shimane.jp\0klabu.no\0porsgrunn.no\0bauhaus\0" -"lib.gu.us\0" -"flir\0priv.at\0" -"*.elb.amazonaws.com.cn\0" -"lazio.it\0kr.eu.org\0mcdir.me\0adimo.co.uk\0" -"kautokeino.no\0prudential\0" -"\xe6\x89\x8b\xe6\x9c\xba\0" -"hayashima.okayama.jp\0ritto.shiga.jp\0" -"vevelstad.no\0" -"eu-4.evennode.com\0" -"rhcloud.com\0" -"host\0" -"hiv\0" -"discordsez.com\0" -"kunimi.fukushima.jp\0um.gov.pl\0" -"sarpsborg.no\0" -"nf.ca\0" -"grosseto.it\0" -"muko.kyoto.jp\0" -"minamioguni.kumamoto.jp\0" -"motoyama.kochi.jp\0yokohama\0" -"ip.linodeusercontent.com\0" -"asakuchi.okayama.jp\0" -"kudamatsu.yamaguchi.jp\0" -"game-server.cc\0" -"hayakawa.yamanashi.jp\0arvo.network\0" -"dongnai.vn\0" -"kawajima.saitama.jp\0" -"hkt\0serveexchange.com\0" -"mb.ca\0" -"tuscany.it\0" -"taifun-dns.de\0" -"shangrila\0" -"det.br\0obira.hokkaido.jp\0" -"whm.fr-par.scw.cloud\0" -"pages.dev\0" -"yamanashi.jp\0" -"agr.br\0midori.gunma.jp\0" -"owani.aomori.jp\0" -"redstone\0" -"oslo.no\0stockholm\0twmail.cc\0" -"\xe6\x84\x9b\xe7\x9f\xa5.jp\0notaires.km\0better-than.tv\0" -"square7.net\0" -"bci.dnstrace.pro\0" -"uji.kyoto.jp\0" -"rotorcraft.aero\0progressive\0eu-3.evennode.com\0" -"memorial\0saves-the-whales.com\0" -"diet\0" -"*.sendai.jp\0us.gov.pl\0" -"pn.it\0" -"wsse.gov.pl\0" -"heroy.nordland.no\0" -"kids.us\0" -"\xe9\x9d\x99\xe5\xb2\xa1.jp\0" -"h\xc3\xa1mm\xc3\xa1rfeasta.no\0namsos.no\0" -"now.sh\0" -"framer.media\0" -"clerk.app\0" -"onna.okinawa.jp\0android\0" -"hot\0in-dsl.net\0" -"synology-diskstation.de\0" -"even\xc3\xa1\xc5\xa1\xc5\xa1i.no\0" -"sf.no\0how\0" -"web.app\0" -"definima.io\0" -"foz.br\0" -"fi.eu.org\0" -"asahi.nagano.jp\0" -"trentinosud-tirol.it\0loginline.app\0" -"lebtimnetz.de\0" -"kujukuri.chiba.jp\0taxi\0" -"shiso.hyogo.jp\0" -"wv.us\0" -"sakaki.nagano.jp\0mysecuritycamera.net\0" -"kddi\0" -"mihama.fukui.jp\0lur\xc3\xb8y.no\0" -"s3.dualstack.eu-central-1.amazonaws.com\0" -"trentinoaadige.it\0" -"togitsu.nagasaki.jp\0" -"slg.br\0" -"eu-2.evennode.com\0" -"yonaguni.okinawa.jp\0" -"zamami.okinawa.jp\0" -"njs.jelastic.vps-host.net\0" -"\xec\x82\xbc\xec\x84\xb1\0" -"\xe7\xa6\x8f\xe5\xb2\xa1.jp\0museum.tt\0" -"surgery\0" -"ibm\0" -"ikata.ehime.jp\0" -"trd.br\0boutique\0" -"uk.com\0" -"ice\0" -"hb.cn\0" -"abeno.osaka.jp\0" -"mb.it\0kijo.miyazaki.jp\0" -"sandvik\0id.forgerock.io\0mcdir.ru\0" -"tamamura.gunma.jp\0chtr.k12.ma.us\0" -"rogers\0" -"na4u.ru\0" -"hadano.kanagawa.jp\0" -"wa.gov.au\0" -"kiyose.tokyo.jp\0icu\0id.firewalledreplit.co\0" -"fastvps-server.com\0my-router.de\0" -"sogndal.no\0\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0" -"nirasaki.yamanashi.jp\0" -"\xe4\xb8\x89\xe9\x87\x8d.jp\0storage.yandexcloud.net\0" -"u.se\0" -"s3.dualstack.ap-northeast-1.amazonaws.com\0" -"repl.co\0" -"medio-campidano.it\0" -"best\0" -"iz.hr\0hachirogata.akita.jp\0cc.mn.us\0" -"koeln\0" -"prof.pr\0" -"lib.ee\0sonla.vn\0" -"auto\0eu-1.evennode.com\0" -"dynserv.org\0" -"business\0" -"app.lmpm.com\0" -"twmail.org\0" -"nomi.ishikawa.jp\0*.stgstage.dev\0" -"rv.ua\0" -"a.se\0from-nv.com\0" -"ifm\0diskstation.me\0" -"trade\0" -"\xe7\xbd\x91\xe7\xb5\xa1.hk\0" -"caxias.br\0" -"flakstad.no\0" -"kami.kochi.jp\0" -"taka.hyogo.jp\0" -"campania.it\0diskstation.eu\0" -"mel\xc3\xb8y.no\0k12.ut.us\0" -"kiyosato.hokkaido.jp\0" -"\xd0\xba\xd1\x80\xd1\x8b\xd0\xbc.\xd1\x80\xd1\x83\xd1\x81\0" -"ina.ibaraki.jp\0sochi.su\0" -"niihama.ehime.jp\0" -"varese.it\0deals\0" -"cyou\0" -"guide\0" -"milano.it\0" -"611.to\0" -"government.aero\0" -"s3-website.eu-central-1.amazonaws.com\0" -"de.com\0" -"mangyshlak.su\0" -"k12.tx.us\0" -"komono.mie.jp\0" -"activetrail.biz\0" -"kouhoku.saga.jp\0" -"gr.it\0" -"tranibarlettaandria.it\0towada.aomori.jp\0forte.id\0" -"is-a-soxfan.org\0" -"umbria.it\0\xe4\xbd\x90\xe8\xb3\x80.jp\0abudhabi\0" -"tec.ve\0" -"izumi.osaka.jp\0" -"codeberg.page\0" -"gr.jp\0eidsvoll.no\0" -"trader.aero\0" -"tachikawa.tokyo.jp\0" -"abr.it\0bielawa.pl\0" -"sos.pl\0s3.us-east-2.amazonaws.com\0" -"nsw.edu.au\0hakusan.ishikawa.jp\0priv.instances.scw.cloud\0" -"toya.hokkaido.jp\0" -"lolitapunk.jp\0" -"reise\0is-gone.com\0" -"quebec\0" -"\xd2\x9b\xd0\xb0\xd0\xb7\0hashbang.sh\0" -"bergen.no\0" -"ouda.nara.jp\0saltdal.no\0lib.or.us\0" -"tomigusuku.okinawa.jp\0museum.mv\0dish\0is-a-hunter.com\0" -"museum.mw\0radoy.no\0priv.pl\0" -"etajima.hiroshima.jp\0" -"kaga.ishikawa.jp\0ringebu.no\0forgot.her.name\0" -"feste-ip.net\0" -"sdscloud.pl\0" -"museum.no\0" -"trentinos-tirol.it\0" -"kaminokawa.tochigi.jp\0" -"chihayaakasaka.osaka.jp\0\xe9\xa3\x9f\xe5\x93\x81\0" -"vennesla.no\0" -"museum.om\0lib.nv.us\0" -"massacarrara.it\0encr.app\0" -"ogawa.saitama.jp\0" -"rovno.ua\0" -"rawa-maz.pl\0" -"swidnica.pl\0" -"hashimoto.wakayama.jp\0" -"priv.no\0nis.za\0barsy.club\0" -"vall\xc3\xa9""edaoste.it\0" -"inc\0paas.datacenter.fi\0" -"tsushima.aichi.jp\0" -"merckmsd\0" -"*.otap.co\0" +"noshiro.akita.jp\0" +"k12.dc.us\0rs.ba\0" +"fbxos.fr\0" +"\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0" +"vr.it\0itano.tokushima.jp\0" +"execute-api.ca-central-1.amazonaws.com\0" +"lib.or.us\0s3-us-gov-east-1.amazonaws.com\0" +"tochigi.jp\0" +"\xc3\xb8yer.no\0" +"\xe3\x82\xb0\xe3\x83\xbc\xe3\x82\xb0\xe3\x83\xab\0" +"misugi.mie.jp\0" +"auth.eu-central-1.amazoncognito.com\0analytics-gateway.ap-northeast-1.amazonaws.com\0" +"twmail.net\0" +"room\0" +"travel.in\0shimofusa.chiba.jp\0kyowa.hokkaido.jp\0" +"familyds.com\0" +"shiga.jp\0" +"enebakk.no\0" +"soctrang.vn\0" +"sc.cn\0bihoro.hokkaido.jp\0" +"is-a-player.com\0enterprisecloud.nu\0" +"godo.gifu.jp\0fussa.tokyo.jp\0" +"gildesk\xc3\xa5l.no\0" +"s3-accesspoint-fips.dualstack.us-gov-west-1.amazonaws.com\0" +"vivian.jp\0" +"salat.no\0" +"to.gt\0" +"psc.br\0sango.nara.jp\0" +"\xe5\x80\x8b\xe4\xba\xba.hk\0" +"no.com\0api.gov.uk\0" +"sumita.iwate.jp\0" +"sorfold.no\0bradesco\0" +"glass\0inc\0" +"tv.im\0lib.ny.us\0mein-vigor.de\0" +"tv.in\0" "ing\0" -"tama.tokyo.jp\0" -"kazo.saitama.jp\0" -"tas.gov.au\0lib.nj.us\0ink\0" -"ote.bj\0!city.kitakyushu.jp\0tajiri.osaka.jp\0juegos\0" -"quangbinh.vn\0" -"kochi.jp\0miki.hyogo.jp\0" -"plumbing\0" -"int\0" -"certmgr.org\0" -"ballooning.aero\0" -"zushi.kanagawa.jp\0" -"vestv\xc3\xa5g\xc3\xb8y.no\0" -"inawashiro.fukushima.jp\0is-a-candidate.org\0" -"nishikatsura.yamanashi.jp\0" -"br.it\0cb.it\0" -"s3-eu-west-2.amazonaws.com\0" -"mazury.pl\0applinzi.com\0" -"web.bo\0arai.shizuoka.jp\0priv.me\0" -"webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com\0" -"fr-1.paas.massivegrid.net\0" -"\xd9\xbe\xd8\xa7\xd9\x83\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0analytics-gateway.us-east-1.amazonaws.com\0" -"b\xc3\xa1jddar.no\0l\xc3\xa6rdal.no\0clan.rip\0" -"atami.shizuoka.jp\0" -"sennan.osaka.jp\0badaddja.no\0" -"*.rss.my.id\0" -"geisei.kochi.jp\0jeonbuk.kr\0" -"toscana.it\0community-pro.de\0" -"web.co\0biev\xc3\xa1t.no\0ubank\0" -"servebbs.net\0" -"baidu\0" -"j.bg\0sydney\0" -"an.it\0" -"podzone.org\0" -"\xe0\xb8\xad\xe0\xb8\x87\xe0\xb8\x84\xe0\xb9\x8c\xe0\xb8\x81\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"mock.pstmn.io\0" -"web.do\0settsu.osaka.jp\0" -"yamada.fukuoka.jp\0" -"mizunami.gifu.jp\0\xe3\x82\xbb\xe3\x83\xbc\xe3\x83\xab\0" -"chungbuk.kr\0" -"if.ua\0mobile\0" -"jcb\0" -"research.aero\0kyuragi.saga.jp\0" -"natal.br\0" -"kurashiki.okayama.jp\0" -"flowers\0" -"cc.az.us\0" -"dsmynas.org\0" -"tome.miyagi.jp\0s\xc3\xb8r-varanger.no\0" -"vfs.cloud9.ap-northeast-2.amazonaws.com\0" -"rdv.to\0" -"ist\0" -"nagai.yamagata.jp\0" -"chowder.jp\0" -"\xe6\x85\x88\xe5\x96\x84\0vfs.cloud9.us-east-1.amazonaws.com\0" -"omotego.fukushima.jp\0" -"lucania.it\0" -"miyoshi.saitama.jp\0" -"kanna.gunma.jp\0" -"mex.com\0" -"jelastic.regruhosting.ru\0cat.ax\0" -"kami.miyagi.jp\0itv\0" -"sogne.no\0" -"filegear-gb.me\0" -"web.gu\0trentino-aadige.it\0" -"psp.gov.pl\0damnserver.com\0" -"amakusa.kumamoto.jp\0gehirn.ne.jp\0cloudsite.builders\0" -"takahama.aichi.jp\0" -"ts.it\0analytics-gateway.ap-northeast-1.amazonaws.com\0" -"sakura.tochigi.jp\0realtor\0" -"college\0" -"\xe9\xb3\xa5\xe5\x8f\x96.jp\0rana.no\0" -"okazaki.aichi.jp\0gorlice.pl\0" -"bozen-suedtirol.it\0mckinsey\0" -"web.id\0de.cool\0" -"sirdal.no\0" -"\xe9\xb9\xbf\xe5\x85\x90\xe5\xb3\xb6.jp\0" -"beta.tailscale.net\0" -"build\0dh.bytemark.co.uk\0static.observableusercontent.com\0" -"istmein.de\0" -"vercelli.it\0rygge.no\0webview-assets.cloud9.ap-east-1.amazonaws.com\0" -"gos.pk\0web.in\0" +"chicappa.jp\0" +"cloud.goog\0" +"ink\0s3.eu-south-1.amazonaws.com\0" +"tv.it\0kumejima.okinawa.jp\0" +"ktistory.com\0" +"amami.kagoshima.jp\0" +"ono.fukushima.jp\0anpachi.gifu.jp\0aid.pl\0" +"emrappui-prod.cn-north-1.amazonaws.com.cn\0" +"lib.mn.us\0" +"int\0ama.aichi.jp\0" +"k12.ar.us\0amsterdam\0" +"tr\xc3\xa6na.no\0" +"to.it\0awaji.hyogo.jp\0" +"\xd0\xbe\xd1\x80\xd0\xb3\0" +"pp.az\0akamaihd.net\0" +"studio\0tv.kg\0" +"danang.vn\0" +"ivanovo.su\0" +"fuso.aichi.jp\0minoh.osaka.jp\0hikawa.shimane.jp\0dedibox.fr\0" +"photography\0" +"takagi.nagano.jp\0nagasaki.nagasaki.jp\0" +"net.ac\0vaapste.no\0webview-assets.aws-cloud9.ca-central-1.amazonaws.com\0" +"net.ae\0" +"net.af\0" +"net.ag\0" +"net.ai\0" +"hyuga.miyazaki.jp\0" +"net.al\0" +"net.am\0pb.ao\0" +"prvcy.page\0" +"net.ba\0myasustor.com\0" +"net.ar\0or.at\0net.bb\0simplesite.gr\0" +"onfabrica.com\0" +"ta.it\0\xd8\xa7\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\0" +"net.au\0\xd8\xa8\xd9\x8a\xd8\xaa\xd9\x83\0" +"or.bi\0and\xc3\xb8y.no\0" +"net.bh\0bando.ibaraki.jp\0scalebook.scw.cloud\0" +"*.elb.amazonaws.com\0" +"net.az\0net.bj\0kitaaiki.nagano.jp\0" +"lib.me.us\0" +"net.bm\0loten.no\0k12.ak.us\0qcx.io\0" +"net.bn\0" +"net.bo\0" +"net.br\0" +"net.bs\0" +"net.bt\0" +"or.ci\0tv.na\0s3-accesspoint.dualstack.ap-southeast-2.amazonaws.com\0" +"fakefur.jp\0to.md\0" +"net.ci\0" +"net.bz\0campidanomedio.it\0hakusan.ishikawa.jp\0kadogawa.miyazaki.jp\0" +"healthcare\0" +"net.cm\0" +"net.cn\0homeunix.net\0" +"nt.au\0net.co\0" +"or.cr\0wodzislaw.pl\0jcb\0" +"s3-website.ap-northeast-2.amazonaws.com\0" +"ojiya.niigata.jp\0" +"net.cu\0s3-accesspoint-fips.dualstack.ca-central-1.amazonaws.com\0operaunite.com\0" +"net.cw\0lib.ks.us\0myactivedirectory.com\0" +"net.cy\0" +"asti.it\0" +"nt.ca\0" +"net.dm\0" +"net.do\0" +"sc.ke\0" +"takata.fukuoka.jp\0ist\0" +"net.ec\0" +"s3.ap-south-1.amazonaws.com\0grozny.su\0" +"edgeapp.net\0" +"net.eg\0" +"net.dz\0abr.it\0" +"re.it\0kawajima.saitama.jp\0" +"aurland.no\0" +"okinawa.jp\0sc.kr\0" +"giehtavuoatna.no\0" +"tagawa.fukuoka.jp\0" +"guovdageaidnu.no\0" +"is-a-chef.org\0" +"net.et\0malopolska.pl\0itv\0" +"webhop.info\0" +"nm.cn\0kimitsu.chiba.jp\0chungnam.kr\0" +"nf.ca\0" +"tobishima.aichi.jp\0kami.kochi.jp\0" +"servebeer.com\0" +"net.fj\0" +"net.fm\0s3-accesspoint.us-east-2.amazonaws.com\0" +"sc.ls\0" +"hakuba.nagano.jp\0embaixada.st\0" +"s3-ap-northeast-1.amazonaws.com\0" +"wi.us\0webview-assets.cloud9.us-west-2.amazonaws.com\0" +"azumino.nagano.jp\0" +"net.ge\0" +"kasuya.fukuoka.jp\0" +"net.gg\0" +"serveexchange.com\0" +"re.kr\0fund\0" +"net.gl\0" +"servecounterstrike.com\0" +"net.gn\0omihachiman.shiga.jp\0" +"net.gp\0ikaruga.nara.jp\0" +"mo.cn\0net.gr\0" +"net.gt\0fujioka.gunma.jp\0soka.saitama.jp\0" +"net.gu\0translated.page\0grozny.ru\0lima.zone\0" +"oguchi.aichi.jp\0" +"execute-api.eu-central-2.amazonaws.com\0" +"net.gy\0from-nv.com\0" +"tv.sd\0gent\0" +"net.hk\0" +"otaru.hokkaido.jp\0rikuzentakata.iwate.jp\0" +"\xe7\xb5\x84\xe7\xb9\x94.hk\0kommunalforbund.se\0jambyl.su\0" +"net.hn\0vercel.app\0" +"zama.kanagawa.jp\0" +"or.id\0" +"net.ht\0net.id\0pi.it\0shimamaki.hokkaido.jp\0" +"emrstudio-prod.me-south-1.amazonaws.com\0" +"yawara.ibaraki.jp\0" +"rl.no\0from-id.com\0uber.space\0" +"boats\0" +"net.il\0umbria.it\0ferrara.it\0neustar\0" +"net.im\0ut.us\0" +"net.in\0kasamatsu.gifu.jp\0" +"net.iq\0lanxess\0" +"net.ir\0or.it\0" +"net.is\0" +"net.je\0spb.ru\0" +"tv.tr\0" +"courses\0" +"namaste.jp\0simplesite.pl\0" +"jio\0" +"or.jp\0misawa.aomori.jp\0" +"net.jo\0dvrcam.info\0read-books.org\0" +"tv.tz\0" +"kaita.hiroshima.jp\0ide.kyoto.jp\0" +"or.ke\0oy.lc\0" +"spb.su\0" +"net.kg\0eidsvoll.no\0" +"net.ki\0kpmg\0is-a-chef.com\0" +"gotemba.shizuoka.jp\0" +"resto.bj\0gifu.jp\0net.kn\0" +"or.kr\0" +"net.la\0" +"lombardia.it\0net.lb\0" +"net.lc\0v\xc3\xa5g\xc3\xa5.no\0su.paba.se\0" +"net.kw\0" "fr-par-1.baremetal.scw.cloud\0" -"nishiawakura.okayama.jp\0" -"so.it\0" -"shinjuku.tokyo.jp\0" -"ogano.saitama.jp\0ic.gov.pl\0" -"godaddy\0" -"ollo\0" -"filegear-jp.me\0jelastic.saveincloud.net\0" -"*.on-k3s.io\0" -"takatori.nara.jp\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4\0" -"doesntexist.org\0" -"elementor.cool\0demon.nl\0" -"armenia.su\0temp-dns.com\0" -"dreamhosters.com\0u2.xnbay.com\0" -"ch.trendhosting.cloud\0" -"notaires.fr\0ketrzyn.pl\0" -"cv.ua\0" -"name.hr\0" -"is-a-nurse.com\0*.owo.codes\0" -"usa.oita.jp\0pors\xc3\xa1\xc5\x8bgu.no\0" -"pavia.it\0" -"okayama.okayama.jp\0izumo.shimane.jp\0ruovat.no\0jio\0issmarterthanyou.com\0" -"gojome.akita.jp\0" -"web.lk\0webview-assets.cloud9.us-east-1.amazonaws.com\0" -"nakatsugawa.gifu.jp\0" -"for-some.biz\0" -"iwama.ibaraki.jp\0" -"shimotsuke.tochigi.jp\0" -"name.et\0mymediapc.net\0" -"ascoli-piceno.it\0storage\0*.developer.app\0" -"star\0" -"name.fj\0" -"\xe5\x80\x8b\xe4\xba\xba.hk\0*.advisor.ws\0fool.jp\0" -"tromso.no\0cloudns.info\0eastus2.azurestaticapps.net\0" -"fukuroi.shizuoka.jp\0" -"eu-west-2.elasticbeanstalk.com\0" -"\xe5\xa4\xa7\xe5\x88\x86.jp\0beiarn.no\0" -"web.nf\0" -"ibara.okayama.jp\0" -"shobara.hiroshima.jp\0bydgoszcz.pl\0\xd0\xb1\xd0\xb5\xd0\xbb\0no-ip.info\0" -"web.ni\0\xe5\x80\x8b\xe4\xba\xba.\xe9\xa6\x99\xe6\xb8\xaf\0" -"bmd.br\0hashima.gifu.jp\0" -"js.cn\0" -"asuke.aichi.jp\0" -"pc.it\0" -"hekinan.aichi.jp\0" -"ac\0gloppen.no\0" -"ad\0" -"ae\0trapani.it\0seljord.no\0" -"af\0" -"ag\0" -"blogspot.com\0" -"ai\0jll\0" -"al\0\xe6\xa0\x83\xe6\x9c\xa8.jp\0" -"am\0vapor.cloud\0" -"kadena.okinawa.jp\0" -"ao\0raffleentry.org.uk\0" -"aq\0ba\0andoy.no\0taobao\0" -"ar\0bb\0" -"as\0academy\0" -"at\0soctrang.vn\0ladesk.com\0" -"au\0be\0network\0" -"bf\0okawa.fukuoka.jp\0" -"aw\0bg\0" -"ax\0bh\0mysecuritycamera.org\0" -"bi\0no.it\0" -"az\0bj\0name.eg\0" -"bm\0b\xc3\xa5""d\xc3\xa5""ddj\xc3\xa5.no\0jmp\0" -"bn\0s\xc3\xa1l\xc3\xa1t.no\0web.pk\0" -"bo\0kagamino.okayama.jp\0" -"muroran.hokkaido.jp\0\xd0\xbe\xd0\xbd\xd0\xbb\xd0\xb0\xd0\xb9\xd0\xbd\0" -"ca\0" -"br\0sakado.saitama.jp\0" -"bs\0cc\0zao.miyagi.jp\0" -"bt\0cd\0direct.quickconnect.cn\0" -"hol.no\0" -"bv\0cf\0ayagawa.kagawa.jp\0" -"bw\0cg\0jnj\0" -"ch\0" -"by\0ci\0okinawa\0" -"bz\0ternopil.ua\0" -"cl\0sakegawa.yamagata.jp\0" -"name.az\0cm\0" -"cn\0" -"co\0" +"net.ky\0ninja\0" +"seirou.niigata.jp\0net.kz\0" +"net.lk\0" +"ogori.fukuoka.jp\0shinagawa.tokyo.jp\0" +"kicks-ass.org\0" +"tomisato.chiba.jp\0" +"mcpe.me\0" +"kagawa.jp\0kunitomi.miyazaki.jp\0" +"net.ma\0" +"fujisawa.iwate.jp\0net.lr\0" +"net.ls\0lib.hi.us\0" +"net.me\0" +"net.lv\0zakopane.pl\0" +"abiko.chiba.jp\0miki.hyogo.jp\0" +"net.ly\0" +"jll\0" +"net.mk\0" +"net.ml\0s3-accesspoint.cn-northwest-1.amazonaws.com.cn\0" +"net.mo\0or.na\0bievat.no\0land-4-sale.us\0" +"firenze.it\0\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0" +"stange.no\0" +"net.ms\0or.mu\0" +"net.mt\0caravan\0" +"net.mu\0" +"net.mv\0net.nf\0" +"net.mw\0net.ng\0kvanangen.no\0" +"mo.it\0net.mx\0ny-2.paas.massivegrid.net\0" +"net.my\0net.ni\0" +"net.mz\0" +"tran\xc3\xb8y.no\0" +"taka.hyogo.jp\0" +"naples.it\0jmp\0" +"dell-ogliastra.it\0net.nr\0" +"sc.ug\0" +"takashima.shiga.jp\0" +"s3.il-central-1.amazonaws.com\0mytabit.com\0" +"sc.tz\0" +"emrstudio-prod.ap-northeast-3.amazonaws.com\0" +"jnj\0" +"net.nz\0" +"molde.no\0net.om\0studio.eu-west-3.sagemaker.aws\0" +"njs.jelastic.vps-host.net\0" +"sc.us\0" +"haibara.shizuoka.jp\0" +"net.pa\0" +"bifuka.hokkaido.jp\0grajewo.pl\0" +"delivery\0" +"nes.buskerud.no\0net.pe\0" +"wa.edu.au\0" +"net.ph\0swidnik.pl\0" +"nt.no\0" +"net.pk\0news\0webview-assets.aws-cloud9.eu-west-2.amazonaws.com\0" +"net.pl\0" +"aisho.shiga.jp\0mielno.pl\0net.pn\0" +"net.qa\0" +"net.pr\0jot\0" +"entertainment.aero\0net.ps\0" +"net.pt\0" +"or.pw\0independent-review.uk\0" +"encr.app\0" +"\xc3\xb8ystre-slidre.no\0pp.se\0joy\0pp.ru\0" +"\xe7\x9f\xb3\xe5\xb7\x9d.jp\0" +"net.py\0" +"dontexist.org\0" +"next\0sg-1.paas.massivegrid.net\0" +"avocat.pro\0browsersafetymark.io\0" +"hamburg\0mex.com\0filegear-jp.me\0jelastic.dogado.eu\0" +"lc.it\0" +"vall\xc3\xa9""e-aoste.it\0izumiotsu.osaka.jp\0" +"nis.za\0*.backyards.banzaicloud.io\0" +"trentino-s-tirol.it\0handcrafted.jp\0vip.jelastic.cloud\0mydissent.net\0" +"hb.cldmail.ru\0" +"sennan.osaka.jp\0" +"\xed\x95\x9c\xea\xb5\xad\0" "hk.cn\0" -"cr\0" -"gg.ax\0" -"cu\0de\0" -"cv\0dellogliastra.it\0sango.nara.jp\0" -"cw\0" -"cx\0*.lcl.dev\0" -"cy\0nagano.jp\0cc.ok.us\0" -"cz\0dj\0laquila.it\0" -"dk\0" -"ena.gifu.jp\0" -"dm\0" -"filegear-sg.me\0" -"do\0" -"firm.ht\0kagami.kochi.jp\0jot\0" -"hippy.jp\0" -"ec\0" -"ee\0" -"joy\0" -"eg\0" -"tsuruta.aomori.jp\0" -"dz\0s3.amazonaws.com\0" -"firm.in\0" -"basilicata.it\0es.leg.br\0es.ax\0" -"lyngen.no\0" -"cricket\0" -"hakui.ishikawa.jp\0hamatama.saga.jp\0" -"es\0karpacz.pl\0" -"et\0hachinohe.aomori.jp\0co.krd\0" -"eu\0" -"lg.jp\0mjondalen.no\0" -"qpon\0" -"fi\0" -"fj\0" -"fm\0web.tj\0" -"es.gov.br\0" -"fo\0" -"ga\0" -"fr\0gb\0asahi.mie.jp\0iamallama.com\0kaas.gg\0" -"gd\0" -"ge\0web.tr\0mini\0" -"gf\0jed.wafaicloud.com\0barsy.me\0" -"gg\0barum.no\0" -"gh\0pc.pl\0actor\0family\0" -"gi\0" -"kanan.osaka.jp\0" -"firm.co\0gl\0takasaki.gunma.jp\0nemuro.hokkaido.jp\0" -"gm\0horonobe.hokkaido.jp\0matsubushi.saitama.jp\0clubmed\0" -"gn\0paris\0" +"s3-accesspoint.dualstack.us-east-1.amazonaws.com\0" +"ap-northeast-2.elasticbeanstalk.com\0" +"higashichichibu.saitama.jp\0" +"grong.no\0net.sa\0" +"net.sb\0" +"net.sc\0pp.ua\0" +"net.sd\0cn-northwest-1.eb.amazonaws.com.cn\0lolitapunk.jp\0" +"net.ru\0" +"kamikoani.akita.jp\0kozaki.chiba.jp\0*.svc.firenet.ch\0" +"net.rw\0net.sg\0" +"net.sh\0" +"sex.hu\0safe\0" +"konyvelo.hu\0" +"net.sl\0clubmed\0" +"filegear-gb.me\0" +"net.so\0" +"yanagawa.fukuoka.jp\0" +"africa.com\0" +"iwade.wakayama.jp\0" +"net.ss\0" +"obama.nagasaki.jp\0net.st\0" +"andoy.no\0" +"or.th\0" +"nissedal.no\0paroch.k12.ma.us\0" +"net.th\0" +"nt.ro\0net.sy\0" +"9guacu.br\0net.tj\0earth\0" +"marnardal.no\0" +"showa.gunma.jp\0" +"net.tm\0lpages.co\0tcp4.me\0" +"kanie.aichi.jp\0net.tn\0" +"catholic.edu.au\0net.to\0" +"est.pr\0*.bzz.dapps.earth\0" +"net.ua\0" +"kamimine.saga.jp\0net.tr\0icurus.jp\0" +"net.tt\0" +"or.ug\0" +"net.tw\0play\0" +"or.tz\0" +"mod.gi\0" +"takamatsu.kagawa.jp\0" +"net.uk\0" +"oirase.aomori.jp\0" +"blogdns.org\0" +"or.us\0" +"kraanghke.no\0net.vc\0" +"hitra.no\0net.ve\0graphics\0\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\x89\0" +"net.uy\0net.vi\0" +"net.uz\0" +"od.ua\0" +"obama.fukui.jp\0jcloud.kz\0" +"notebook.ap-northeast-2.sagemaker.aws\0" +"net.vn\0nobushi.jp\0" +"equipment.aero\0ok.us\0us.com\0" +"krasnik.pl\0" +"plc.ly\0s3-fips.dualstack.us-east-2.amazonaws.com\0" +"minami.kyoto.jp\0" +"net.vu\0" +"kfh\0" +"microlight.aero\0" +"ju.mp\0" +"tono.iwate.jp\0toba.mie.jp\0" +"blogsyte.com\0" +"higashiizu.shizuoka.jp\0" +"\xe7\xa6\x8f\xe4\xba\x95.jp\0" +"firestone\0" +"umaji.kochi.jp\0" +"net.ws\0" +"now-dns.top\0" +"supply\0" +"itoman.okinawa.jp\0emrnotebooks-prod.cn-northwest-1.amazonaws.com.cn\0" +"lib.ar.us\0publishproxy.com\0id.firewalledreplit.co\0" +"trentinosudtirol.it\0" +"nm.us\0guide\0" +"oamishirasato.chiba.jp\0nogi.tochigi.jp\0" +"s3-website.us-east-1.amazonaws.com\0" +"priv.instances.scw.cloud\0" +"is-a-caterer.com\0" +"se.net\0ru.net\0" +"net.ye\0murmansk.su\0" +"does-it.net\0" +"store\0s3.dualstack.ap-southeast-2.amazonaws.com\0" +"sale\0unicom\0" +"kia\0" "jor.br\0" -"gp\0degree\0mint\0" -"gq\0lowicz.pl\0aca.pro\0" -"gr\0reserve-online.net\0" -"gs\0" -"gt\0" -"gu\0kartuzy.pl\0" -"lecce.it\0" -"gw\0io.in\0" -"namegata.ibaraki.jp\0web.ve\0firm.dk\0" -"gy\0h\xc3\xb8ylandet.no\0" -"fedorainfracloud.org\0iki.fi\0" +"net.za\0" +"emr.it\0" +"overhalla.no\0mo.us\0" +"arvo.network\0" +"matsudo.chiba.jp\0warszawa.pl\0" +"kim\0jpn.com\0" +"molise.it\0tamba.hyogo.jp\0heavy.jp\0" +"net.zm\0dance\0" +"iglesiascarbonia.it\0yufu.oita.jp\0" +"sex.pl\0" +"execute-api.us-west-2.amazonaws.com\0" +"kamiichi.toyama.jp\0mediatech.dev\0" +"serveftp.com\0" +"center\0" +"noboribetsu.hokkaido.jp\0camau.vn\0" +"higashihiroshima.hiroshima.jp\0eu.platform.sh\0" +"narviika.no\0" +"ote.bj\0" +"bamble.no\0kustanai.ru\0" +"ibigawa.gifu.jp\0""6.azurestaticapps.net\0" +"ma.us\0s3-website.dualstack.eu-south-1.amazonaws.com\0" +"kl\xc3\xa6""bu.no\0rauma.no\0" +"land\0" +"manaus.br\0ma.leg.br\0" +"kvam.no\0" +"ks.ua\0" +"pharmaciens.km\0school.za\0kustanai.su\0xnbay.com\0" +"tarnobrzeg.pl\0" +"sar.it\0" +"alpha.bounty-full.com\0" +"mydrobo.com\0" +"emrnotebooks-prod.ap-northeast-1.amazonaws.com\0" +"kutchan.hokkaido.jp\0" +"lcube-server.de\0" +"kosai.shizuoka.jp\0" +"ks.us\0" +"sec.ps\0" +"sanuki.kagawa.jp\0gsj.bz\0" +"university\0" +"kamikawa.hyogo.jp\0catfood.jp\0" +"\xe0\xba\xa5\xe0\xba\xb2\xe0\xba\xa7\0" +"omi.niigata.jp\0uk.primetel.cloud\0" +"zara\0" +"bearalvahki.no\0bplaced.com\0" +"\xe5\x85\xac\xe7\x9b\x8a\0" +"ggee\0" +"trentino.it\0andriabarlettatrani.it\0forl\xc3\xac""cesena.it\0" +"theater\0" +"shichinohe.aomori.jp\0ayabe.kyoto.jp\0sandvikcoromant\0" +"plc.uk\0" +"hamura.tokyo.jp\0" +"\xe7\xae\x87\xe4\xba\xba.hk\0emrappui-prod.us-east-2.amazonaws.com\0is-a-painter.com\0" +"bmd.br\0soma.fukushima.jp\0" +"de.gt\0" +"\xe5\x95\x86\xe5\xba\x97\0" +"tachikawa.tokyo.jp\0tabitorder.co.il\0" +"habmer.no\0" +"sarl\0" +"homeunix.org\0" +"kahoku.ishikawa.jp\0" +"s3-object-lambda.eu-south-2.amazonaws.com\0spdns.org\0" +"tranoy.no\0notebook.us-gov-west-1.sagemaker.aws\0" +"mazowsze.pl\0" +"cyon.link\0" +"masaki.ehime.jp\0minato.tokyo.jp\0" +"nagasu.kumamoto.jp\0" +"is-an-artist.com\0twmail.org\0" +"tochio.niigata.jp\0" +"trentinos\xc3\xbc""dtirol.it\0" +"kamo.kyoto.jp\0kpn\0" +"\xd0\xba\xd0\xbe\xd0\xbc.\xd1\x80\xd1\x83\xd1\x81\0" +"pl.eu.org\0" +"is-a-chef.net\0" +"cn.in\0valleedaoste.it\0kawanishi.hyogo.jp\0" +"fuossko.no\0" +"tokai.aichi.jp\0" +"gs.vf.no\0" +"cn.it\0" +"cloud.nospamproxy.com\0" +"avocat.fr\0" +"ybo.trade\0" +"krd\0lat\0" +"cc.wy.us\0law\0" +"kred\0" +"medicina.bo\0" +"save\0" +"s3.nl-ams.scw.cloud\0" +"\xe6\x95\x99\xe8\x82\xb2.hk\0rindal.no\0" +"biz.bb\0tgory.pl\0" +"biz.at\0" +"blog\0" +"conf.au\0" +"\xd7\x99\xd7\xa9\xd7\x95\xd7\x91.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0bihar.in\0" +"oracle\0" +"biz.az\0" +"\xd1\x80\xd1\x83\xd1\x81\0" +"marketing\0" +"ofunato.iwate.jp\0ureshino.mie.jp\0" +"lotte\0webview-assets.cloud9.af-south-1.amazonaws.com\0de.ls\0" +"de.md\0" +"home.dyndns.org\0demo.datacenter.fi\0dscloud.mobi\0" +"baria-vungtau.vn\0" +"mosjoen.no\0" +"bi.it\0\xe0\xb8\x97\xe0\xb8\xab\xe0\xb8\xb2\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0k8s.fr-par.scw.cloud\0" +"lotto\0" +"tokamachi.niigata.jp\0gehirn.ne.jp\0bookonline.app\0" +"fidelity\0" +"inabe.mie.jp\0nerima.tokyo.jp\0" +"\xe7\xbd\x91\xe5\xba\x97\0" +"rebun.hokkaido.jp\0" +"takaharu.miyazaki.jp\0coolblog.jp\0" +"\xd9\x85\xd9\x84\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa7\0" +"laquila.it\0!city.kitakyushu.jp\0ayagawa.kagawa.jp\0" +"cc.vt.us\0" +"daito.osaka.jp\0vanguard\0" +"lds\0" +"ar.it\0" +"frogn.no\0saxo\0" +"biz.cy\0rollag.no\0aramco\0audible\0" +"fh.se\0biz.dk\0" +"udi.br\0" +"is-leet.com\0" +"v\xc3\xa5ler.hedmark.no\0" +"nishiarita.saga.jp\0" +"yusuhara.kochi.jp\0" +"george\0" +"independent-commission.uk\0" +"verm\xc3\xb6gensberatung\0" +"expert\0imdb\0" +"varoy.no\0" +"econo.bj\0biz.et\0murakami.niigata.jp\0" +"furano.hokkaido.jp\0" +"c66.me\0" +"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0" +"biz.fj\0koka.shiga.jp\0susono.shizuoka.jp\0" +"media.aero\0\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0svn-repos.de\0" +"niimi.okayama.jp\0" +"*.on-k3s.io\0" +"ad.jp\0kita.tokyo.jp\0" +"snillfjord.no\0hotels\0mel.cloudlets.com.au\0" +"kherson.ua\0" +"monster\0" +"plus\0" +"yawatahama.ehime.jp\0sayo.hyogo.jp\0" +"austrheim.no\0" +"cc.tx.us\0" +"kawanishi.nara.jp\0biz.gl\0" +"sanofi\0" +"istanbul\0" +"studio.me-south-1.sagemaker.aws\0resindevice.io\0" +"izumi.osaka.jp\0" +"blue\0" +"homelinux.com\0" +"aoki.nagano.jp\0" +"analytics-gateway.us-west-2.amazonaws.com\0" +"tara.saga.jp\0" +"bostik\0" +"ac.gov.br\0\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86.ir\0\xe9\x9d\x92\xe6\xa3\xae.jp\0" +"accesscam.org\0" +"biz.id\0" +"hotel.tz\0" +"s3-accesspoint-fips.dualstack.us-west-1.amazonaws.com\0" +"is-a-teacher.com\0" +"mizuho.tokyo.jp\0" +"loabat.no\0" +"biz.in\0kagamiishi.fukushima.jp\0" +"flight.aero\0s3-fips.dualstack.us-gov-east-1.amazonaws.com\0" +"from-va.com\0" +"sasayama.hyogo.jp\0" +"matta-varjjat.no\0" +"chieti.it\0*.sapporo.jp\0us.platform.sh\0" +"r\xc3\xb8""d\xc3\xb8y.no\0" +"shimoji.okinawa.jp\0" +"championship.aero\0sor-fron.no\0" +"ozu.ehime.jp\0" +"*.eu-central-1.airflow.amazonaws.com\0" +"16-b.it\0" +"bet.ar\0hisayama.fukuoka.jp\0development.run\0" +"daknong.vn\0nikita.jp\0" +"is-with-theband.com\0" +"ine.kyoto.jp\0kunitachi.tokyo.jp\0gangwon.kr\0" +"donna.no\0llc\0" +"emrappui-prod.af-south-1.amazonaws.com\0" +"aguni.okinawa.jp\0nishi.osaka.jp\0" +"biz.ki\0" +"\xd8\xa8\xd8\xa7\xd8\xb1\xd8\xaa\0" +"cn.ua\0" +"campidano-medio.it\0" +"de.us\0" +"kikugawa.shizuoka.jp\0" +"pizza\0" +"imperia.it\0shinshiro.aichi.jp\0makurazaki.kagoshima.jp\0llp\0" +"vard\xc3\xb8.no\0" +"business.in\0emrnotebooks-prod.cn-north-1.amazonaws.com.cn\0" +"flog.br\0bolzano.it\0memorial\0vercel.dev\0" +"union.aero\0kristiansund.no\0yalta.ua\0" +"nittedal.no\0vestre-slidre.no\0" +"jls-sto3.elastx.net\0" +"imamat\0" +"biz.ls\0analytics-gateway.ap-southeast-1.amazonaws.com\0" +"nakagawa.fukuoka.jp\0" +"wolterskluwer\0" +"s3-accesspoint.dualstack.eu-central-2.amazonaws.com\0" +"sells-for-less.com\0" +"gulen.no\0ezproxy.kuleuven.be\0" +"toyono.osaka.jp\0yaizu.shizuoka.jp\0global.ssl.fastly.net\0" +"cn.vu\0" +"musica.ar\0" +"namdalseid.no\0" +"kawaue.gifu.jp\0takinoue.hokkaido.jp\0biz.mv\0zgora.pl\0" +"qld.gov.au\0museum\0biz.mw\0skj\xc3\xa5k.no\0" +"ato.br\0vlog.br\0" +"cargo.aero\0biz.my\0biz.ni\0" +"sosa.chiba.jp\0" +"gs.of.no\0\xd1\x81\xd1\x80\xd0\xb1\0" +"us-gov-west-1.elasticbeanstalk.com\0" +"boston\0lol\0syncloud.it\0" +"musica.bo\0" +"abbvie\0s3-object-lambda.me-central-1.amazonaws.com\0" +"utazu.kagawa.jp\0biz.nr\0barclaycard\0jetzt\0" +"kerryhotels\0" +"reg.dk\0" +"is-into-anime.com\0" +"choshi.chiba.jp\0aikawa.kanagawa.jp\0" +"chitose.hokkaido.jp\0" +"sagamihara.kanagawa.jp\0lpl\0" +"cleaning\0immo\0is-a-llama.com\0" +"ikawa.akita.jp\0" +"ar.us\0base.ec\0" +"hotel.lk\0cc.pr.us\0mydobiss.com\0" +"kurume.fukuoka.jp\0" +"4lima.de\0" +"biz.pk\0" +"mar.it\0biz.pl\0ath.cx\0" +"unj\xc3\xa1rga.no\0" +"gonohe.aomori.jp\0" +"is-saved.org\0wixstudio.io\0" +"man\0" +"omotego.fukushima.jp\0biz.pr\0map\0" +"ak.us\0mba\0" +"taiki.mie.jp\0saga.saga.jp\0" +"gok.pk\0theatre\0wanggou\0" +"aomori.jp\0maison\0" +"couchpotatofries.org\0" +"kafjord.no\0" +"tmp.br\0" +"oirm.gov.pl\0" +"treviso.it\0s3-website.cn-north-1.amazonaws.com.cn\0" +"aejrie.no\0" +"shiranuka.hokkaido.jp\0shima.mie.jp\0""4lima.at\0" +"travinh.vn\0flt.cloud.muni.cz\0" +"iserv.dev\0" +"vega.no\0charity\0" +"soundcast.me\0" +"bplaced.net\0" +"ltd\0" +"hlx.page\0conf.se\0" +"kuleuven.cloud\0" +"t.bg\0auth.ap-northeast-3.amazoncognito.com\0" +"4lima.ch\0" +"cc.nv.us\0" +"review\0" +"biz.ss\0from-nj.com\0" +"en-root.fr\0" +"ggf.br\0med\0" +"m.bg\0" +"biz.tj\0edgecompute.app\0" +"execute-api.eu-west-3.amazonaws.com\0" +"tos.it\0" +"groks-the.info\0is-a-green.com\0" +"discover\0" +"no-ip.info\0" +"men\0" +"hotel.hu\0eidfjord.no\0biz.ua\0" +"biz.tr\0pharmacien.fr\0" +"biz.tt\0tempurl.host\0" +"f.bg\0" +"tosu.saga.jp\0gonna.jp\0" +"siracusa.it\0" +"is-into-games.com\0" +"cc.nh.us\0" +"aseral.no\0" +"is-very-nice.org\0" +"naroy.no\0no.eu.org\0" +"vagsoy.no\0" +"app.br\0" +"bargains\0whoswho\0pstmn.io\0" +"oops.jp\0" +"onavstack.net\0" +"mg.leg.br\0" +"legnica.pl\0biz.vn\0haiduong.vn\0" +"kerryproperties\0" +"inderoy.no\0" +"samukawa.kanagawa.jp\0" +"nose.osaka.jp\0biz.wf\0" +"kr\xc3\xa5""anghke.no\0" +"sayama.osaka.jp\0" +"coupons\0js.org\0" +"abkhazia.su\0" +"motosu.gifu.jp\0" +"blogdns.net\0" +"rokunohe.aomori.jp\0" +"construction\0hicam.net\0" +"its.me\0" +"g\xc3\xa1ls\xc3\xa1.no\0studio.eu-west-1.sagemaker.aws\0" +"happou.akita.jp\0" +"caa.aero\0booking\0" +"tsk.tr\0" +"airforce\0" +"hokuto.yamanashi.jp\0" +"emrstudio-prod.ap-southeast-2.amazonaws.com\0" +"mil\0topaz.ne.jp\0" +"aland.fi\0info\0" +"otari.nagano.jp\0" +"hida.gifu.jp\0" +"smushcdn.com\0" +"dnsking.ch\0" +"\xe5\x98\x89\xe9\x87\x8c\xe5\xa4\xa7\xe9\x85\x92\xe5\xba\x97\0dynalias.com\0mypep.link\0" +"mit\0" +"apps.fbsbx.com\0" +"nakagyo.kyoto.jp\0tainai.niigata.jp\0" +"maebashi.gunma.jp\0" +"emrappui-prod.ap-south-1.amazonaws.com\0" +"nikolaev.ua\0studio.us-east-1.sagemaker.aws\0" +"feste-ip.net\0" +"bizen.okayama.jp\0gialai.vn\0" +"etnedal.no\0lanbib.se\0" +"film.hu\0" +"\xe7\xbb\x84\xe7\xbb\x87\xe6\x9c\xba\xe6\x9e\x84\0" +"nico\0" +"tanagura.fukushima.jp\0" +"biz.zm\0tatamotors\0" +"\xd7\xa7\xd7\x95\xd7\x9d\0" +"al.gov.br\0" +"\xc3\xa5lg\xc3\xa5rd.no\0nesset.no\0" +"chikuzen.fukuoka.jp\0consulado.st\0" +"nesodden.no\0royken.no\0mydatto.com\0" +"como.it\0mlb\0\xe5\x85\xab\xe5\x8d\xa6\0app.gp\0" +"minamiechizen.fukui.jp\0auction\0mypsx.net\0" +"5.bg\0servep2p.com\0" +"yamanouchi.nagano.jp\0oshima.tokyo.jp\0\xd1\x81\xd0\xb0\xd0\xb9\xd1\x82\0" +"k12.mt.us\0office\0endoftheinternet.org\0" +"bygland.no\0" +"scot\0" +"gs.hm.no\0" +"sasaguri.fukuoka.jp\0" +"takahata.yamagata.jp\0" +"aerodrome.aero\0jur.pro\0analytics-gateway.ap-northeast-2.amazonaws.com\0" +"mma\0nz.eu.org\0" +"lomo.jp\0" +"mls\0" +"parma.it\0kamijima.ehime.jp\0" +"ueda.nagano.jp\0kumenan.okayama.jp\0" +"glitch.me\0" +"myjino.ru\0" +"mantova.it\0okutama.tokyo.jp\0" +"etajima.hiroshima.jp\0tottori.tottori.jp\0usercontent.jp\0" +"barsy.club\0" +"\xe9\xab\x98\xe7\x9f\xa5.jp\0kiwa.mie.jp\0" +"fuel.aero\0varggat.no\0" +"the.br\0oharu.aichi.jp\0dupont\0" +"conf.lv\0" +"auth.ap-southeast-3.amazoncognito.com\0" +"ddns.net\0" +"rennes\xc3\xb8y.no\0" +"lavangen.no\0" +"definima.io\0" +"kviteseid.no\0" +"forlicesena.it\0yuu.yamaguchi.jp\0sunnyday.jp\0" +"ap-east-1.elasticbeanstalk.com\0" +"amusement.aero\0moe\0" +"yachiyo.chiba.jp\0" +"moi\0drayddns.com\0" +"homelinux.net\0" +"accountants\0emrappui-prod.eu-central-1.amazonaws.com\0s3-accesspoint.dualstack.eu-west-3.amazonaws.com\0" +"gift\0clerkstage.app\0privatelink.snowflake.app\0" +"diamonds\0mom\0" +"for-better.biz\0" +"\xe5\x95\x86\xe6\xa5\xad.tw\0" +"in-vpn.org\0" +"qld.au\0ilovecollege.info\0" +"santoandre.br\0" +"mov\0cloudycluster.net\0" +"komagane.nagano.jp\0" +"*.ca-central-1.airflow.amazonaws.com\0" +"tonosho.kagawa.jp\0" +"giske.no\0" +"cc.id.us\0" +"ishikawa.okinawa.jp\0kotoura.tottori.jp\0nab\0" +"tysvar.no\0" +"weatherchannel\0" +"echizen.fukui.jp\0rishirifuji.hokkaido.jp\0" +"satosho.okayama.jp\0bambina.jp\0" +"belluno.it\0" +"masfjorden.no\0unjarga.no\0" +"nowaruda.pl\0" +"wiki.bo\0" +"wajima.ishikawa.jp\0" +"certmgr.org\0" +"wiki.br\0quangninh.vn\0" +"nba\0" +"lombardy.it\0miyama.fukuoka.jp\0" +"s3-fips.us-gov-east-1.amazonaws.com\0" +"itoigawa.niigata.jp\0" +"berlevag.no\0*.compute.estate\0" +"inc.hk\0" +"aju.br\0omi.nagano.jp\0" +"atami.shizuoka.jp\0" +"nike\0" +"tsuruoka.yamagata.jp\0" +"ddnss.org\0" +"vxl.sh\0" +"hdfcbank\0s3-website.ap-southeast-2.amazonaws.com\0" +"yachimata.chiba.jp\0msd\0" +"etne.no\0lib.vt.us\0firewall-gateway.de\0" +"rsvp\0" +"ris\xc3\xb8r.no\0" +"kamioka.akita.jp\0" +"*.landing.myjino.ru\0" +"leg.br\0cricket\0" +"slattum.no\0s3.dualstack.ap-northeast-2.amazonaws.com\0yali.mythic-beasts.com\0" +"ritto.shiga.jp\0" +"dyn.cosidns.de\0" +"za.bz\0" +"kasukabe.saitama.jp\0kwpsp.gov.pl\0" +"nanae.hokkaido.jp\0" +"pomorskie.pl\0" +"joburg\0emrappui-prod.us-west-1.amazonaws.com\0analytics-gateway.eu-west-1.amazonaws.com\0" +"yokaichiba.chiba.jp\0" +"hemnes.no\0" +"shimamoto.osaka.jp\0hamamatsu.shizuoka.jp\0minami.tokushima.jp\0tabuse.yamaguchi.jp\0bbs.tr\0mtn\0" +"ferrari\0rogers\0" +"narashino.chiba.jp\0tokuyama.yamaguchi.jp\0" +"us-west-1.elasticbeanstalk.com\0" +"mtr\0" +"nec\0" +"xz.cn\0" +"t.se\0s3-website.me-central-1.amazonaws.com\0" +"cc.ga.us\0" +"s3.dualstack.eu-central-1.amazonaws.com\0iki.fi\0" +"iwate.iwate.jp\0kanmaki.nara.jp\0" +"spydeberg.no\0" +"kawachinagano.osaka.jp\0london\0" +"*.sys.qcx.io\0" +"utashinai.hokkaido.jp\0" +"airline.aero\0m.se\0s3-ap-northeast-2.amazonaws.com\0dontexist.com\0" +"sorocaba.br\0tempioolbia.it\0taishi.hyogo.jp\0nonoichi.ishikawa.jp\0taketa.oita.jp\0net\0barefoot\0\xe5\x85\xac\xe5\x8f\xb8\0in.net\0" +"control.aero\0godaddy\0new\0" +"mj\xc3\xb8ndalen.no\0" +"usa.oita.jp\0" +"bremanger.no\0cherkassy.ua\0" +"nfl\0" +"co.technology\0" +"lucania.it\0toda.saitama.jp\0" +"groundhandling.aero\0f.se\0auth.eu-south-1.amazoncognito.com\0emrnotebooks-prod.ap-northeast-3.amazonaws.com\0" +"fl\xc3\xa5.no\0hasura-app.io\0" +"sytes.net\0" +"lutsk.ua\0" +"aip.ee\0" +"tsu.mie.jp\0cloudaccess.net\0" +"*.dweb.link\0" +"emrnotebooks-prod.us-west-1.amazonaws.com\0s3-fips-us-gov-west-1.amazonaws.com\0" +"kotohira.kagawa.jp\0chirurgiens-dentistes.fr\0" +"ngo\0" +"shakotan.hokkaido.jp\0" +"lebesby.no\0meraker.no\0" +"jessheim.no\0k\xc3\xa1r\xc3\xa1\xc5\xa1johka.no\0" +"nhk\0sakuraweb.com\0" +"kuokgroup\0" +"dnsupdate.info\0" +"ochi.kochi.jp\0" +"taiki.hokkaido.jp\0" +"tatsuno.hyogo.jp\0doshi.yamanashi.jp\0" +"urayasu.chiba.jp\0" +"trader.aero\0s3-us-west-1.amazonaws.com\0dyndns-at-work.com\0" +"cri.br\0gdynia.pl\0" +"l\xc3\xb8ten.no\0k12.ga.us\0" +"tas.au\0tennis\0" +"bofa\0" +"inuyama.aichi.jp\0motoyama.kochi.jp\0" +"\xe9\xa6\x99\xe6\xa0\xbc\xe9\x87\x8c\xe6\x8b\x89\0" +"webhop.me\0" +"zakarpattia.ua\0studio.ap-southeast-3.sagemaker.aws\0dagestan.ru\0" +"miyazaki.jp\0" +"\xd1\x83\xd0\xba\xd1\x80\0\xe3\x82\xb9\xe3\x83\x88\xe3\x82\xa2\0" +"swiebodzin.pl\0" +"fukushima.hokkaido.jp\0yoka.hyogo.jp\0nishinoshima.shimane.jp\0stargard.pl\0pohl\0" +"is-into-cartoons.com\0" +"readymade.jp\0" +"ntdll.top\0" +"gausdal.no\0" +"masuda.shimane.jp\0*.developer.app\0" +"comsec\0" +"engine.aero\0dagestan.su\0" +"shimodate.ibaraki.jp\0saarland\0*.kunden.ortsinfo.at\0" +"r\xc3\xb8st.no\0applinzi.com\0" +"suwalki.pl\0" +"vefsn.no\0cloudns.asia\0" +"iwama.ibaraki.jp\0" +"jp.ngrok.io\0" +"is-certified.com\0" +"urown.cloud\0" +"s3-object-lambda.us-west-2.amazonaws.com\0" +"pioneer\0" +"knowsitall.info\0" +"pages.it.hs-heilbronn.de\0" +"matsusaka.mie.jp\0" +"ltd.co.im\0" +"olkusz.pl\0" +"s3-accesspoint.il-central-1.amazonaws.com\0dynamic-dns.info\0" +"leclerc\0" +"mytis.ru\0" +"doomdns.org\0" +"\xe6\x9d\xb1\xe4\xba\xac.jp\0tenkawa.nara.jp\0" +"salvador.br\0" +"mordovia.su\0" +"shitara.aichi.jp\0*.build.run\0" +"execute-api.ap-south-2.amazonaws.com\0" +"univ.bj\0" +"auth.me-south-1.amazoncognito.com\0" +"paragliding.aero\0tinn.no\0" +"nishikatsura.yamanashi.jp\0seat\0eating-organic.net\0" +"komatsu.ishikawa.jp\0" +"fukuoka.jp\0" +"vagan.no\0" +"dnsupdater.de\0" +"reggiocalabria.it\0" +"motegi.tochigi.jp\0\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4\0" +"\xe7\xbb\x84\xe7\xbb\x87.hk\0" +"fbx-os.fr\0" +"rana.no\0" +"emrstudio-prod.cn-northwest-1.amazonaws.com.cn\0" +"tm.cy\0" +"nasushiobara.tochigi.jp\0higashimurayama.tokyo.jp\0" +"in.ngrok.io\0" +"\xe6\x97\xb6\xe5\xb0\x9a\0" +"arezzo.it\0" +"\xe9\x9d\x99\xe5\xb2\xa1.jp\0" +"yonago.tottori.jp\0pigboat.jp\0" +"emrstudio-prod.ap-northeast-2.amazonaws.com\0" +"\xd0\xbe\xd0\xb1\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0now\0*.amplifyapp.com\0" +"nara.nara.jp\0" +"tm.dz\0\xe9\xb3\xa5\xe5\x8f\x96.jp\0" +"hjartdal.no\0" +"sa.au\0" +"clinique\0builtwithdark.com\0mordovia.ru\0" +"mt.eu.org\0" +"vevelstad.no\0" +"sh.cn\0nanporo.hokkaido.jp\0" +"misato.shimane.jp\0edgesuite-staging.net\0" +"bitbucket.io\0" +"liguria.it\0vi.it\0" +"flor\xc3\xb8.no\0" +"bond\0schokokeks.net\0" +"hagebostad.no\0nra\0seek\0" +"tm.fr\0cloudfront.net\0" +"ownprovider.com\0" +"app.os.fedoraproject.org\0" +"sucks\0" +"obi\0" +"sa.cr\0vb.it\0" +"yamagata.jp\0" +"firewall-gateway.com\0" +"wsa.gov.pl\0" +"uk.in\0oyodo.nara.jp\0" +"f\xc3\xb8rde.no\0\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xd8\xa9\0" +"otoineppu.hokkaido.jp\0" +"book\0nrw\0" +"kudamatsu.yamaguchi.jp\0" +"odawara.kanagawa.jp\0" +"trentin-suedtirol.it\0tachiarai.fukuoka.jp\0" +"jevnaker.no\0work\0" +"ostroda.pl\0" +"tt.im\0lib.ok.us\0" +"takikawa.hokkaido.jp\0social\0" +"tm.hu\0" +"ud.it\0gojome.akita.jp\0kagamino.okayama.jp\0bialowieza.pl\0" +"workinggroup.aero\0" +"ravpage.co.il\0s3-website.fr-par.scw.cloud\0" +"h\xc3\xb8ylandet.no\0" +"uk.kg\0" +"sakaki.nagano.jp\0" +"porn\0" +"mobara.chiba.jp\0akashi.hyogo.jp\0sakae.nagano.jp\0" +"lego\0" +"ntt\0" +"risor.no\0" +"ruhr\0" +"deloitte\0" +"cruises\0" +"is-a-photographer.com\0" +"cri.nz\0*.webpaas.ovh.net\0" +"juegos\0" +"valled-aosta.it\0sv.it\0weblike.jp\0" +"post\0framer.app\0" +"shibukawa.gunma.jp\0" +"n\xc3\xb8tter\xc3\xb8y.no\0\xd9\x83\xd8\xa7\xd8\xab\xd9\x88\xd9\x84\xd9\x8a\xd9\x83\0ravendb.community\0" +"mizusawa.iwate.jp\0" +"badaddja.no\0" +"shimada.shizuoka.jp\0" +"firmdale\0al.eu.org\0" +"kaneyama.yamagata.jp\0jozi.biz\0" +"tm.km\0execute-api.us-gov-east-1.amazonaws.com\0" +"energy\0" +"so.it\0pepper.jp\0" +"kv\xc3\xa6""fjord.no\0" +"gotpantheon.com\0" +"trieste.it\0\xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\0" +"yonabaru.okinawa.jp\0" +"shiksha\0" +"unusualperson.com\0" +"hareid.no\0" +"tm.mc\0jele.site\0" +"gotdns.org\0" +"tm.mg\0broadway\0" +"nic.in\0" +"ppg.br\0" +"sa.it\0" +"sakurai.nara.jp\0sakado.saitama.jp\0freeboxos.fr\0" +"desa.id\0" +"troitsk.su\0" +"inawashiro.fukushima.jp\0" +"economia.bo\0nannestad.no\0nyc\0" +"ama.shimane.jp\0ricoh\0" +"studio.cn-northwest-1.sagemaker.com.cn\0" +"skjervoy.no\0" +"is-a-hunter.com\0" +"nishi.fukuoka.jp\0" +"piacenza.it\0" +"tm.no\0" +"nombre.bo\0" +"onjuku.chiba.jp\0" +"s3-accesspoint.ap-east-1.amazonaws.com\0" +"s3-accesspoint.dualstack.ca-central-1.amazonaws.com\0webview-assets.aws-cloud9.eu-north-1.amazonaws.com\0lenug.su\0" +"science\0" +"rc.it\0ybo.faith\0" +"eun.eg\0" +"shiftcrypto.dev\0" +"engineer.aero\0" +"eti.br\0" +"cim.br\0" +"emrappui-prod.us-west-2.amazonaws.com\0my.eu.org\0*.frusky.de\0" +"kosuge.yamanashi.jp\0bc.platform.sh\0" +"nantan.kyoto.jp\0" +"tadaoka.osaka.jp\0tm.pl\0" +"homelinux.org\0" +"kitagawa.miyazaki.jp\0" +"pescara.it\0" +"vodka\0" +"sphinx.mythic-beasts.com\0" +"pu.it\0fashionstore.jp\0" +"honai.ehime.jp\0" +"firebaseapp.com\0" +"hu.com\0" +"karasuyama.tochigi.jp\0staba.jp\0" +"redstone\0" +"muko.kyoto.jp\0" +"webview-assets.cloud9.me-south-1.amazonaws.com\0" +"angiang.vn\0" +"pn.it\0cloudapps.digital\0" +"iwafune.tochigi.jp\0" +"pg.in\0" +"vi.us\0" +"tm.ro\0execute-api.us-east-1.amazonaws.com\0vladimir.su\0" +"pg.it\0" +"yachts\0" +"ibaraki.ibaraki.jp\0" +"tm.se\0one\0" +"ichinomiya.aichi.jp\0kita.osaka.jp\0" +"ong\0zero\0" +"mytabit.co.il\0" +"emrnotebooks-prod.ap-east-1.amazonaws.com\0" +"emrappui-prod.us-east-1.amazonaws.com\0geekgalaxy.com\0" +"onl\0" +"\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\0" +"tokushima.jp\0kayabe.hokkaido.jp\0supersale.jp\0" +"lib.id.us\0webview-assets.cloud9.ca-central-1.amazonaws.com\0" +"univ.sn\0" +"uy.com\0" +"dvag\0" +"independent-panel.uk\0" +"moka.tochigi.jp\0" +"ooo\0pleskns.com\0" +"from-ia.com\0" +"\xe3\x82\xb3\xe3\x83\xa0\0" +"recreation.aero\0" +"yokote.akita.jp\0sakegawa.yamagata.jp\0user.aseinet.ne.jp\0" +"s3.dualstack.ap-south-2.amazonaws.com\0" +"alto-adige.it\0amazon\0" +"wakasa.tottori.jp\0" +"iris.arpa\0\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xdb\x83\0vladimir.ru\0" +"groks-this.info\0nl.eu.org\0" +"olsztyn.pl\0" +"us-gov-east-1.elasticbeanstalk.com\0nyan.to\0" +"fhv.se\0" +"s3-object-lambda.eu-west-3.amazonaws.com\0webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com\0" +"repl.co\0" +"iizuna.nagano.jp\0" +"higashimatsuyama.saitama.jp\0" +"ac\0is-slick.com\0" +"ad\0osasco.br\0js.cn\0" +"ae\0\xe7\xbd\x91\xe7\xb5\xa1.hk\0" +"af\0ogimi.okinawa.jp\0" +"ag\0" +"mt.it\0" +"ai\0org\0filegear-de.me\0" +"yamagata.ibaraki.jp\0" +"pay\0s3-accesspoint.eu-south-1.amazonaws.com\0" +"al\0kouyama.kagoshima.jp\0" +"am\0jele.io\0" +"tanohata.iwate.jp\0" +"ao\0shw.io\0" +"aq\0ba\0*.eu-west-3.airflow.amazonaws.com\0" +"ar\0bb\0jl.cn\0" +"as\0cloudflare-ipfs.com\0" +"at\0recife.br\0kisosaki.mie.jp\0" +"au\0be\0" +"bf\0nic.tj\0" +"aw\0bg\0" +"ax\0bh\0" +"bi\0" +"az\0bj\0inami.toyama.jp\0" +"oji.nara.jp\0" +"bm\0divtasvuodna.no\0s3.ap-east-1.amazonaws.com\0" +"bn\0for-the.biz\0" +"bo\0" +"in-vpn.net\0" +"ca\0zapto.org\0" +"br\0" +"bs\0cc\0klabu.no\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa4\xae\xe0\xa5\x8d\0forsale\0" +"bt\0cd\0" +"bv\0cf\0direct.quickconnect.cn\0" +"bw\0cg\0nhs.uk\0s3-accesspoint-fips.us-east-2.amazonaws.com\0" +"ch\0" +"by\0ci\0" +"bz\0yamagata.yamagata.jp\0" +"s3-ap-east-1.amazonaws.com\0" +"cl\0ota.gunma.jp\0ninomiya.kanagawa.jp\0dunlop\0" +"cm\0is-an-actor.com\0" +"cn\0heguri.nara.jp\0" +"co\0athleta\0swiss\0" +"aizubange.fukushima.jp\0gyeongnam.kr\0s3.dualstack.cn-north-1.amazonaws.com.cn\0" +"parachuting.aero\0s3-accesspoint.eu-central-2.amazonaws.com\0" +"cr\0lo.it\0isla.pr\0" +"flatanger.no\0tm.za\0n4t.co\0""123kotisivu.fi\0" +"fujiidera.osaka.jp\0" +"cu\0de\0dnsalias.com\0" +"cv\0ott\0*.dapps.earth\0wpmudev.host\0" +"cw\0*.compute.amazonaws.com\0" +"cx\0" +"cy\0" +"cz\0dj\0joboji.iwate.jp\0matsubushi.saitama.jp\0" +"dk\0acct.pro\0" +"goto.nagasaki.jp\0" +"dm\0hol.no\0is-a-musician.com\0" +"mishima.fukushima.jp\0" +"do\0grimstad.no\0auth.us-east-2.amazoncognito.com\0" +"sexy\0*.azurecontainer.io\0" +"chofu.tokyo.jp\0" +"ec\0" +"ee\0condos\0" +"hirosaki.aomori.jp\0binhdinh.vn\0pet\0" +"eg\0lib.fl.us\0" +"internet.in\0kawanabe.kagoshima.jp\0mihara.kochi.jp\0" +"claims\0shopping\0" +"dz\0gouv.fr\0!city.yokohama.jp\0ovh\0" +"tsukiyono.gunma.jp\0" +"dattorelay.com\0" +"augustow.pl\0" +"es\0ng.eu.org\0" +"eng.br\0et\0shunan.yamaguchi.jp\0vinhphuc.vn\0" +"eu\0evje-og-hornnes.no\0eu.com\0is-uberleet.com\0" +"caserta.it\0" +"hi.cn\0" +"fi\0" +"fj\0meiwa.mie.jp\0" +"fm\0studio.us-gov-east-1.sagemaker.aws\0" +"fo\0lelux.site\0loginline.site\0" +"snowflake.app\0" +"ga\0" +"emp.br\0fr\0gb\0" +"*.customer-oci.com\0" +"gd\0" +"ge\0mykolaiv.ua\0" +"hb.cn\0gf\0phd\0" +"gg\0" +"gh\0wazuka.kyoto.jp\0myfast.host\0nodes.k8s.nl-ams.scw.cloud\0" +"gi\0\xc3\xa1laheadju.no\0" +"gl\0gouv.ht\0" +"gm\0halsa.no\0l\xc3\xa6rdal.no\0nic.za\0" +"gn\0final\0" +"barsycenter.com\0" +"gp\0edgekey-staging.net\0" +"gq\0lib.dc.us\0" +"gr\0" +"gs\0flekkefjord.no\0" +"gt\0nakama.fukuoka.jp\0" +"gu\0" +"pid\0" +"gw\0" +"pussycat.jp\0" +"gy\0auth-fips.us-west-2.amazoncognito.com\0" +"trentino-sudtirol.it\0" "hk\0" -"radio\0" -"hm\0" -"hn\0verisign\0" -"lib.sc.us\0" -"hr\0" -"kumamoto.jp\0hoabinh.vn\0" -"ht\0id\0kakogawa.hyogo.jp\0komforb.se\0" +"hm\0from-sc.com\0" +"hn\0watari.miyagi.jp\0" +"emrnotebooks-prod.eu-north-1.amazonaws.com\0" +"pin\0" +"gd.cn\0hr\0komoro.nagano.jp\0" +"cafe\0viajes\0" +"fm.br\0ht\0id\0" "hu\0ie\0" -"ecn.br\0www.ro\0\xe9\xa6\x99\xe6\xb8\xaf\0" -"politica.bo\0" -"mihama.aichi.jp\0tel.tr\0" +"higashi.fukuoka.jp\0" +"alaheadju.no\0" +"execute-api.ap-southeast-2.amazonaws.com\0" "il\0" -"im\0ogawara.miyagi.jp\0alpha-myqnapcloud.com\0" +"im\0lib.ca.us\0" "in\0" "io\0" -"urayasu.chiba.jp\0chippubetsu.hokkaido.jp\0io.kg\0" -"iq\0schaeffler\0" -"ir\0" +"gouv.ci\0iq\0" +"ir\0toyota.aichi.jp\0\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0*.code.run\0" "is\0" -"it\0dvrcam.info\0" -"je\0" -"jp.eu.org\0" -"hagebostad.no\0" -"moonscale.net\0" -"ac.ae\0nes.buskerud.no\0" -"jo\0\xe7\xa7\xbb\xe5\x8a\xa8\0" -"jp\0penne.jp\0" -"shimizu.shizuoka.jp\0edgekey.net\0" -"shikokuchuo.ehime.jp\0ke\0kfh\0" -"kg\0pub.sa\0" -"tosu.saga.jp\0ki\0" -"lolipopmc.jp\0" -"belluno.it\0" -"ac.at\0svelvik.no\0" -"ac.be\0mombetsu.hokkaido.jp\0km\0" -"kn\0\xd8\xa8\xd9\x8a\xd8\xaa\xd9\x83\0" -"nakamichi.yamanashi.jp\0" -"tsukigata.hokkaido.jp\0kp\0" -"la\0" -"kr\0lb\0" -"mitsuke.niigata.jp\0lc\0" -"nishiokoppe.hokkaido.jp\0web.za\0" -"alibaba\0goldpoint\0" -"kw\0uk0.bigv.io\0" -"gushikami.okinawa.jp\0dyn-ip24.de\0fbx-os.fr\0" -"rieti.it\0ky\0li\0caobang.vn\0sunnyday.jp\0azurestaticapps.net\0" -"kz\0myqnapcloud.com\0" -"internet.in\0lk\0sevastopol.ua\0" +"it\0" +"je\0singles\0" +"omasvuotna.no\0" +"meiwa.gunma.jp\0ina.ibaraki.jp\0" +"cupcake.is\0" "tosashimizu.kochi.jp\0" -"egersund.no\0" -"*.triton.zone\0barsy.ro\0" -"ac.ci\0ma\0hsbc\0icbc\0jeez.jp\0" -"lr\0ath.cx\0" -"ls\0mc\0website.yandexcloud.net\0" -"kawara.fukuoka.jp\0lt\0md\0staba.jp\0" -"art.br\0lu\0me\0photography\0" -"ac.cn\0lv\0" -"mg\0" -"fc.it\0mh\0" -"kizu.kyoto.jp\0ly\0" -"ac.cr\0ikawa.akita.jp\0" -"mk\0tools\0" -"ml\0" -"vladimir.su\0" -"mn\0kia\0" -"mo\0rendalen.no\0" -"yamanakako.yamanashi.jp\0mp\0" -"ac.cy\0mq\0na\0" -"mr\0" -"fujisato.akita.jp\0ms\0nc\0uzs.gov.pl\0vfs.cloud9.us-east-2.amazonaws.com\0privatelink.snowflake.app\0" -"mt\0" -"mu\0ne\0" -"sakae.nagano.jp\0mv\0nf\0" -"mw\0ng\0" -"mx\0dyndns-home.com\0" -"my\0ni\0" -"mz\0kim\0" -"nl\0" -"isa.us\0\xe9\xa4\x90\xe5\x8e\x85\0browsersafetymark.io\0" -"no\0mk.ua\0" -"art.do\0nr\0coolblog.jp\0" -"avocat.pro\0lib.ms.us\0lib.nc.us\0" -"nu\0xx.gl\0" -"es.kr\0team\0" -"iwanai.hokkaido.jp\0iheya.okinawa.jp\0" -"kotoura.tottori.jp\0" -"j.layershift.co.uk\0" -"nz\0" -"federation.aero\0discover\0" -"\xe6\x94\xbf\xe5\xba\x9c\0barsy.uk\0" -"art.dz\0om\0" -"clinic\0akamaiorigin.net\0" -"asakawa.fukushima.jp\0mymailer.com.tw\0" -"pages.it.hs-heilbronn.de\0" -"\xe6\xb2\x96\xe7\xb8\x84.jp\0pa\0name.vn\0" -"ac.fj\0" -"homelinux.com\0utwente.io\0" -"pe\0" -"pf\0" -"tr\xc3\xb8gstad.no\0" -"ph\0lg.ua\0bss.design\0" -"minobu.yamanashi.jp\0keliweb.cloud\0" -"pk\0zone\0" -"pl\0" -"pm\0vladimir.ru\0" -"pn\0" -"pisa.it\0crown\0" -"qa\0tech\0" -"pr\0from-mn.com\0" -"ps\0game-host.org\0" -"pt\0nikon\0" -"ac.gn\0pages.torproject.net\0" -"pw\0" -"stream\0" -"py\0" -"sx.cn\0" -"name.tj\0" -"webview-assets.cloud9.ca-central-1.amazonaws.com\0" -"s.bg\0firm.ve\0" -"bg.it\0" -"e164.arpa\0v\xc3\xa5ler.\xc3\xb8stfold.no\0" -"re\0name.tr\0" -"name.tt\0*.platformsh.site\0" -"domains\0" -"tokoname.aichi.jp\0\xd8\xa7\xd8\xaa\xd8\xb5\xd8\xa7\xd9\x84\xd8\xa7\xd8\xaa\0" -"ac.id\0" -"parts\0" -"ro\0" -"sa\0" -"sb\0" -"rs\0sc\0food\0" -"sd.cn\0ac.il\0sd\0party\0" -"ac.im\0ru\0se\0usr.cloud.muni.cz\0" -"ac.in\0mifune.kumamoto.jp\0" -"art.ht\0rw\0sg\0" -"sh\0qa2.com\0" -"si\0" -"ac.ir\0sj\0is-certified.com\0" -"rifu.miyagi.jp\0sk\0bacninh.vn\0gr.com\0" -"sl\0hlx3.page\0" -"sm\0" -"sn\0" -"iwakuni.yamaguchi.jp\0so\0firestone\0jele.site\0" -"kadoma.osaka.jp\0" -"giehtavuoatna.no\0" -"sr\0" -"ss\0tc\0" -"hirono.fukushima.jp\0st\0td\0" -"livorno.it\0toho.fukuoka.jp\0su\0direct.quickconnect.to\0" -"asahi.yamagata.jp\0sv\0tf\0lon-2.paas.massivegrid.net\0" -"tg\0shopselect.net\0" -"ac.jp\0sx\0th\0global\0" -"sy\0" -"sz\0tj\0barsy.menu\0" -"tk\0" -"takazaki.miyazaki.jp\0bomlo.no\0tl\0vfs.cloud9.ca-central-1.amazonaws.com\0" -"avellino.it\0abashiri.hokkaido.jp\0ac.ke\0tm\0" -"tn\0canva-apps.cn\0" -"to\0" -"ua\0is-a-republican.com\0" -"ltd.cy\0tr\0" -"r\xc3\xa5holt.no\0" -"tt\0lugansk.ua\0statebank\0" -"kiengiang.vn\0" -"onjuku.chiba.jp\0skien.no\0tv\0" -"tw\0ug\0io.vn\0" -"velvet.jp\0" -"karlsoy.no\0" -"ac.kr\0tz\0" -"uk\0kpn\0" -"minamiawaji.hyogo.jp\0s\xc3\xb8gne.no\0" -"name.pm\0" -"cargo.aero\0va\0" -"ac.lk\0us\0vc\0ford\0" -"name.qa\0volyn.ua\0agric.za\0" -"name.pr\0ve\0" -"santoandre.br\0tajimi.gifu.jp\0" -"vg\0" -"shimokitayama.nara.jp\0" -"como.it\0ac.ma\0uy\0vi\0softbank\0" -"association.aero\0uz\0" -"ac.ls\0" -"firm.ro\0coffee\0" -"7.bg\0ac.me\0" -"vn\0irish\0" -"kitaura.miyazaki.jp\0" -"krd\0lat\0" -"haboro.hokkaido.jp\0grainger\0from-ak.com\0" -"per.la\0autocode.dev\0" -"name.na\0law\0" -"vu\0volkswagen\0" -"wf\0genting\0hostyhosting.io\0" -"name.mv\0" -"name.ng\0" -"myftp.biz\0" -"name.my\0" -"ac.mu\0spydeberg.no\0brasilia.me\0ras.ru\0" -"bialowieza.pl\0pictet\0" -"nx.cn\0ac.mw\0gs.rl.no\0" -"\xe9\xa6\x99\xe5\xb7\x9d.jp\0" -"ac.ni\0" -"ltd.gi\0ac.mz\0" -"fuossko.no\0ws\0on-the-web.tv\0" -"eng.br\0" -"eidskog.no\0" -"r\xc3\xb8yken.no\0" -"nesna.no\0" -"ullensaker.no\0ac.nz\0" -"ochi.kochi.jp\0ltd.hk\0" -"chiryu.aichi.jp\0ye\0" -"toyako.hokkaido.jp\0" -"control.aero\0bandai.fukushima.jp\0per.nf\0" -"ac.pa\0" -"fst.br\0ar.com\0" -"lds\0bashkiria.ru\0" -"\xe7\x86\x8a\xe6\x9c\xac.jp\0" -"firm.nf\0" -"yt\0firm.ng\0" -"psc.br\0yugawa.fukushima.jp\0\xd8\xa8\xd8\xa7\xd8\xb1\xd8\xaa\0servebbs.org\0" -"cocotte.jp\0" -"ac.pr\0lanxess\0" -"jab.br\0" -"zm\0" -"name.mk\0" -"art.pl\0" -"bashkiria.su\0" -"wielun.pl\0" -"ck.ua\0zw\0" -"vikna.no\0" -"jan-mayen.no\0" -"lib.dc.us\0" -"zama.kanagawa.jp\0kyotamba.kyoto.jp\0lolipop.io\0hotelwithflight.com\0" -"dnipropetrovsk.ua\0" -"name.jo\0snillfjord.no\0krakow.pl\0" -"bel.tr\0" -"thaibinh.vn\0dsmynas.net\0" -"enna.it\0" -"pinb.gov.pl\0" -"barsy.bg\0" -"ac.rs\0" -"ac.se\0ac.ru\0" -"bytom.pl\0" -"m\xc3\xa1tta-v\xc3\xa1rjjat.no\0ac.rw\0platform0.app\0" -"audnedaln.no\0sdn.gov.pl\0whm.nl-ams.scw.cloud\0" -"hizen.saga.jp\0barsy.ca\0" -"ltd.lk\0" -"loans\0" -"lighting\0from-al.com\0" -"\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\0" -"industria.bo\0" -"qbuser.com\0" -"mutsu.aomori.jp\0mokuren.ne.jp\0" -"ac.th\0" -"joinville.br\0art.sn\0" -"ac.sz\0ac.tj\0" -"id.au\0tomisato.chiba.jp\0parasite.jp\0ravendb.me\0" -"otake.hiroshima.jp\0" -"barsy.de\0ybo.science\0" -"oamishirasato.chiba.jp\0" -"lebesby.no\0per.sg\0" -"*.nom.br\0royrvik.no\0" -"cs.keliweb.cloud\0" -"\xd8\xa7\xd8\xa8\xd9\x88\xd8\xb8\xd8\xa8\xd9\x8a\0" -"\xc3\xa5mli.no\0ac.ug\0hamburg\0" -"pescara.it\0ltd.ng\0" -"ac.tz\0" -"trentino-sudtirol.it\0ac.uk\0" -"act.au\0" -"tobetsu.hokkaido.jp\0" -"gs.jan-mayen.no\0" -"center\0" -"vic.au\0mt.it\0" -"drive\0surf\0" -"iwatsuki.saitama.jp\0" -"websozai.jp\0" -"s3.isk02.sakurastorage.jp\0" -"voagat.no\0ac.vn\0barsy.eu\0" -"ponpes.id\0edgestack.me\0is.eu.org\0" -"varggat.no\0" -"sor-varanger.no\0" -"lplfinancial\0" -"binhthuan.vn\0ddns5.com\0" -"llc\0" -"katsuyama.fukui.jp\0arita.saga.jp\0" -"bato.tochigi.jp\0myactivedirectory.com\0" -"cisco\0" -"leirvik.no\0pcloud.host\0" -"bike\0" -"v\xc3\xa5g\xc3\xa5.no\0" -"kunitachi.tokyo.jp\0" -"tjeldsund.no\0" -"brumunddal.no\0nore-og-uvdal.no\0" -"llp\0" -"tokke.no\0" -"demo.jelastic.com\0" -"servemp3.com\0" -"fly.dev\0s3-website.fr-par.scw.cloud\0" -"kanagawa.jp\0*.database.run\0" -"ayabe.kyoto.jp\0" -"langevag.no\0" -"ina.nagano.jp\0kanuma.tochigi.jp\0it.eu.org\0" -"tselinograd.su\0" -"volda.no\0" -"kakegawa.shizuoka.jp\0s.se\0bar1.net\0" -"skjak.no\0" -"kirkenes.no\0" -"ohkura.yamagata.jp\0" -"oygarden.no\0gentlentapis.com\0" -"ac.za\0" -"teva\0" -"ferrari\0barsy.in\0" -"pruszkow.pl\0barsy.io\0" -"yugawara.kanagawa.jp\0" -"recreation.aero\0ac.zm\0" -"satosho.okayama.jp\0gs.hl.no\0haram.no\0" -"bing\0webview-assets.cloud9.eu-south-1.amazonaws.com\0" -"lol\0" -"info.gu\0s3.ca-central-1.amazonaws.com\0" -"flt.cloud.muni.cz\0" -"uozu.toyama.jp\0comcast\0" -"umi.fukuoka.jp\0" -"ac.zw\0" -"energy\0" -"kira.aichi.jp\0s3-website-us-west-1.amazonaws.com\0" -"lifestyle\0" -"suzaka.nagano.jp\0" -"info.ht\0sd.us\0lpl\0" -"info.hu\0ltd.ua\0" -"treviso.it\0" -"odesa.ua\0" -"id.ir\0" -"jcloud.ik-server.com\0" -"jondal.no\0" -"info.in\0" -"toyono.osaka.jp\0ltd.uk\0" -"shinanomachi.nagano.jp\0steinkjer.no\0" -"\xe5\x8c\x97\xe6\xb5\xb7\xe9\x81\x93.jp\0in.eu.org\0" -"info.et\0" -"man\0homelinux.net\0" -"map\0" -"mba\0" -"info.fj\0za.bz\0" -"okutama.tokyo.jp\0gamvik.no\0" -"wuoz.gov.pl\0" -"hikari.yamaguchi.jp\0" -"js.org\0" -"thanhphohochiminh.vn\0" -"aid.pl\0" -"nachikatsuura.wakayama.jp\0ballangen.no\0" -"pl.ua\0visa\0" -"lunner.no\0" -"gallo\0" -"cloudfunctions.net\0" -"salud.bo\0tiengiang.vn\0" -"nabari.mie.jp\0mywire.org\0" -"kumano.mie.jp\0" -"webthings.io\0quicksytes.com\0" -"taishi.hyogo.jp\0" -"balsan-sudtirol.it\0suzuka.mie.jp\0" -"s3.dualstack.eu-west-3.amazonaws.com\0" -"base.shop\0" -"oumu.hokkaido.jp\0takatsuki.shiga.jp\0is-a-hard-worker.com\0" -"nosegawa.nara.jp\0jcloud.kz\0" -"info.cx\0" -"honjyo.akita.jp\0naamesjevuemie.no\0" -"shika.ishikawa.jp\0rad\xc3\xb8y.no\0" -"tlon.network\0" -"crotone.it\0yame.fukuoka.jp\0ltd\0*.quipelements.com\0" -"id.lv\0" -"sumita.iwate.jp\0" -"id.ly\0" -"info.ec\0shimizu.hokkaido.jp\0homeunix.com\0" -"minami.fukuoka.jp\0" -"wellbeingzone.eu\0" -"ma.gov.br\0" -"amot.no\0" -"kahoku.ishikawa.jp\0minoh.osaka.jp\0med\0" -"sorocaba.br\0" -"trentino-s\xc3\xbc""d-tirol.it\0oh.us\0" -"sumida.tokyo.jp\0" -"info.bb\0ohtawara.tochigi.jp\0fuefuki.yamanashi.jp\0" -"viva\0info.at\0" -"info.au\0mizusawa.iwate.jp\0lamer\0" -"men\0" -"lviv.ua\0" -"lea\xc5\x8bgaviika.no\0" -"realm.cz\0" -"info.az\0info.bj\0ventures\0" -"lib.oh.us\0" -"info.bo\0wroc.pl\0" -"utashinai.hokkaido.jp\0vivo\0" -"eek.jp\0" -"nowtv\0" -"tananger.no\0" -"prochowice.pl\0" -"kamo.kyoto.jp\0mt.us\0nd.us\0" -"nl-ams-1.baremetal.scw.cloud\0" -"ezproxy.kuleuven.be\0" -"tempioolbia.it\0kunohe.iwate.jp\0k12.pr.us\0" -"sandnessjoen.no\0" -"info.co\0" -"ct.it\0" -"revista.bo\0takayama.nagano.jp\0bo.nordland.no\0vps.mcdir.ru\0" -"kvits\xc3\xb8y.no\0" -"sande.m\xc3\xb8re-og-romsdal.no\0" -"vfs.cloud9.af-south-1.amazonaws.com\0" -"sci.eg\0lubin.pl\0keymachine.de\0" -"grong.no\0" -"nishihara.okinawa.jp\0" -"stavanger.no\0" -"naklo.pl\0" -"health-carereform.com\0" -"opencraft.hosting\0" -"fujiidera.osaka.jp\0" -"esp.br\0" -"\xe6\x95\x8e\xe8\x82\xb2.hk\0" -"valdaosta.it\0melbourne\0" -"altoadige.it\0konan.shiga.jp\0mil\0" -"wellbeingzone.co.uk\0" -"kounosu.saitama.jp\0" -"fi.cloudplatform.fi\0" -"mit\0" -"frana.no\0" -"jaworzno.pl\0" -"kurobe.toyama.jp\0shonai.yamagata.jp\0" -"h.bg\0myjino.ru\0khplay.nl\0" -"al.it\0" -"shibukawa.gunma.jp\0canva-apps.com\0" -"birkenes.no\0" -"tokai.aichi.jp\0gialai.vn\0ntdll.top\0" -"skierv\xc3\xa1.no\0boats\0" -"suli.hu\0" -"store\0" -"ieee\0angry.jp\0u2-local.xnbay.com\0" +"webview-assets.cloud9.ap-south-1.amazonaws.com\0" +"toei.aichi.jp\0okoppe.hokkaido.jp\0noda.iwate.jp\0" +"dnipropetrovsk.ua\0ny.us\0" +"nodes.k8s.fr-par.scw.cloud\0" +"jo\0study\0" +"jp\0yasugi.shimane.jp\0" +"br\xc3\xb8nn\xc3\xb8y.no\0" +"s3-object-lambda.ap-southeast-1.amazonaws.com\0" +"ke\0lillesand.no\0" +"kg\0" +"ki\0" +"notebook.ap-southeast-4.sagemaker.aws\0homeunix.com\0" +"km\0quicksytes.com\0" +"kn\0" +"servepics.com\0" +"kp\0" +"la\0" +"\xd7\x90\xd7\xa7\xd7\x93\xd7\x9e\xd7\x99\xd7\x94.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0kr\0lb\0gotdns.ch\0" +"lc\0sochi.su\0" +"kw\0media\0reservd.com\0" +"shiroi.chiba.jp\0" +"ky\0li\0" +"otaki.saitama.jp\0kz\0" +"!www.ck\0lk\0loppa.no\0stj\xc3\xb8rdal.no\0" "plo.ps\0" -"quangtri.vn\0london\0" -"kitahata.saga.jp\0globo\0from-ks.com\0" -"okawa.kochi.jp\0gsm.pl\0" -"hu.net\0" -"phone\0rugby\0*.dweb.link\0" -"games\0mlb\0" -"game\0" -"nz.basketball\0" -"red.sv\0" -"pharmaciens.km\0trafficplex.cloud\0" -"webview-assets.cloud9.eu-west-1.amazonaws.com\0" -"isshiki.aichi.jp\0" -"coupon\0mma\0pub.instances.scw.cloud\0" -"svalbard.no\0mls\0*.sensiosite.cloud\0" -"id.us\0" -"ve.it\0drangedal.no\0" -"iwamizawa.hokkaido.jp\0" -"webhosting.be\0" -"id.vn\0" -"lib.il.us\0" -"tagajo.miyagi.jp\0" -"kannami.shizuoka.jp\0" -"webhop.org\0" -"higashine.yamagata.jp\0toray\0" -"inami.toyama.jp\0" -"stuff-4-sale.org\0leczna.pl\0" -"chuo.chiba.jp\0*.backyards.banzaicloud.io\0" -"\xe9\x9b\x86\xe5\x9b\xa2\0" -"dscloud.me\0" -"from-me.org\0" -"kahoku.yamagata.jp\0moe\0" -"al.no\0" -"cc.wa.us\0" -"m\xc3\xa5s\xc3\xb8y.no\0myspreadshop.com.au\0" -"moi\0" -"mayfirst.info\0" -"business.in\0kashiwara.osaka.jp\0" -"mom\0" -"jc.neen.it\0" -"jp.ngrok.io\0" -"ericsson\0rexroth\0" -"amfam\0" -"\xd7\xa7\xd7\x95\xd7\x9d\0akamaiedge.net\0" -"unicom\0" -"veg\xc3\xa5rshei.no\0" -"fl.us\0mov\0webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com\0schulserver.de\0" -"software.aero\0nm.cn\0" -"lindas.no\0" -"gujarat.in\0" -"open\0" -"bulsan-s\xc3\xbc""dtirol.it\0shima.mie.jp\0" -"taketa.oita.jp\0" -"mashike.hokkaido.jp\0appchizi.com\0" -"nab\0" -"kawanehon.shizuoka.jp\0betainabox.com\0" -"tkmaxx\0" -"wakasa.tottori.jp\0" -"maebashi.gunma.jp\0" -"citic\0akamai-staging.net\0" -"from-ms.com\0from-nc.com\0" -"aero.tt\0info.ve\0" -"co.network\0" -"trentinoaltoadige.it\0" -"nba\0" -"ri.it\0" -"kids\0za.net\0" -"\xe5\x8d\x83\xe8\x91\x89.jp\0" -"info.vn\0" -"schwarz\0webview-assets.aws-cloud9.sa-east-1.amazonaws.com\0" -"photo\0" -"aoste.it\0" -"\xe4\xba\x9a\xe9\xa9\xac\xe9\x80\x8a\0" -"aero.mv\0" -"urbinopesaro.it\0beauty\0editorx.io\0" -"tsukui.kanagawa.jp\0" -"msd\0" -"ct.us\0" -"ozu.ehime.jp\0\xe3\x81\xbf\xe3\x82\x93\xe3\x81\xaa\0" -"kusu.oita.jp\0" -"pu.it\0" -"geometre-expert.fr\0" -"lodi.it\0" -"kinko.kagoshima.jp\0xii.jp\0" -"akita.jp\0" -"info.tn\0" -"free\0" -"parti.se\0" -"daiwa.hiroshima.jp\0r\xc3\xa1isa.no\0info.tr\0" -"trentinosuedtirol.it\0eiheiji.fukui.jp\0info.tt\0" -"matsuura.nagasaki.jp\0" -"s\xc3\xbc""dtirol.it\0kaisei.kanagawa.jp\0ninhthuan.vn\0mtn\0" -"loppa.no\0" -"info.tz\0mtr\0" -"nec\0" -"pa.it\0vxl.sh\0" -"myddns.rocks\0" -"aibetsu.hokkaido.jp\0" -"wloclawek.pl\0" -"and\xc3\xb8y.no\0qoto.io\0alpha.bounty-full.com\0" -"\xe3\x82\xb3\xe3\x83\xa0\0mytabit.com\0" -"murmansk.su\0" -"stange.no\0" -"b-data.io\0" -"frontier\0" -"kaizuka.osaka.jp\0net\0hotmail\0" -"arte.bo\0" -"info.ro\0new\0" -"builtwithdark.com\0" -"al.us\0ninja\0" -"date.hokkaido.jp\0" -"info.sd\0thainguyen.vn\0nfl\0" -"adm.br\0" -"yusuhara.kochi.jp\0" -"wakkanai.hokkaido.jp\0" -"biz.bb\0nanao.ishikawa.jp\0" -"s3.dualstack.ap-southeast-1.amazonaws.com\0biz.at\0" -"messwithdns.com\0" -"biz.az\0" -"wi.us\0ecommerce-shop.pl\0" -"vodka\0" -"ngo\0ua.rs\0" -"lom.it\0from-mt.com\0from-nd.com\0" -"ilawa.pl\0\xe5\x95\x86\xe6\xa0\x87\0" -"notteroy.no\0" -"info.pk\0barsy.support\0" -"hi.cn\0\xe5\xb2\xa9\xe6\x89\x8b.jp\0info.pl\0" -"roma.it\0" -"mi.it\0" -"uchinada.ishikawa.jp\0griw.gov.pl\0" -"onavstack.net\0" -"lib.wi.us\0soundcast.me\0" -"info.pr\0poker\0" -"nhk\0" -"cc.ny.us\0" -"mus.mi.us\0" -"yokawa.hyogo.jp\0shacknet.nu\0" -"ota.gunma.jp\0is-a-cubicle-slave.com\0" -"noticias.bo\0taishi.osaka.jp\0" -"asti.it\0norddal.no\0" -"tsuru.yamanashi.jp\0info.na\0" -"feira.br\0zlg.br\0biz.cy\0" -"gbiz\0biz.dk\0" -"omachi.nagano.jp\0" -"info.mv\0info.nf\0" -"le.it\0k12.ar.us\0" -"info.ni\0" -"suzu.ishikawa.jp\0" -"recht.pro\0autos\0" -"podlasie.pl\0cc.ne.us\0george\0" -"bargains\0" -"certification.aero\0info.nr\0" -"marker.no\0" -"fed.us\0" -"solutions\0" -"matsumae.hokkaido.jp\0" -"ostroleka.pl\0endofinternet.net\0" -"biz.et\0iwade.wakayama.jp\0" -"sm.ua\0" -"matera.it\0" -"benevento.it\0h.se\0" -"toyo.kochi.jp\0info.la\0backdrop.jp\0" -"os\xc3\xb8yro.no\0" -"biz.fj\0\xd0\xb0\xd0\xba.\xd1\x81\xd1\x80\xd0\xb1\0rsc.cdn77.org\0" -"osen.no\0zachpomor.pl\0cc.ma.us\0" -"kitahiroshima.hokkaido.jp\0" -"deporte.bo\0olawa.pl\0lima-city.rocks\0" -"yahiko.niigata.jp\0kikirara.jp\0" -"miyake.nara.jp\0" -"cymru\0docs\0" -"valled-aosta.it\0" -"tabayama.yamanashi.jp\0" -"info.ls\0lom.no\0k12.va.us\0" -"d\xc3\xb8nna.no\0" -"dvrdns.org\0biz.gl\0" -"novara.it\0" -"im.it\0" -"netlify.app\0" -"yamato.kumamoto.jp\0" -"hidaka.saitama.jp\0pt.eu.org\0" -"divttasvuotna.no\0consulado.st\0" -"vagsoy.no\0duckdns.org\0" -"from-ia.com\0linkyard-cloud.ch\0" -"kawatana.nagasaki.jp\0ri.us\0homelinux.org\0" -"zj.cn\0" -"from-nm.com\0" -"biz.id\0trana.no\0" -"hepforge.org\0" -"miyama.mie.jp\0" -"gs.fm.no\0" -"namikata.ehime.jp\0tokai.ibaraki.jp\0yakumo.shimane.jp\0be.ax\0" -"info.ke\0lib.ri.us\0" -"kosaka.akita.jp\0\xe4\xbd\x9b\xe5\xb1\xb1\0" -"biz.in\0" -"otaru.hokkaido.jp\0info.ki\0verran.no\0" -"show.aero\0cust.dev.thingdust.io\0" -"klepp.no\0" -"locus\0" -"berlev\xc3\xa5g.no\0*.compute.amazonaws.com.cn\0" -"fujinomiya.shizuoka.jp\0iservschule.de\0" -"u.channelsdvr.net\0" -"olbia-tempio.it\0" -"phx.enscaled.us\0" -"kamifurano.hokkaido.jp\0gausdal.no\0" -"perso.ht\0" -"ge.it\0" -"mizuho.tokyo.jp\0now\0" -"muosat.no\0" -"biz.ki\0" -"*.nagoya.jp\0" -"friuliveneziagiulia.it\0" -"mg.gov.br\0" -"brother\0" -"friuli-veneziagiulia.it\0eu.platform.sh\0" -"minamiyamashiro.kyoto.jp\0tateyama.toyama.jp\0pa.us\0" -"troandin.no\0" -"\xe8\x8c\xa8\xe5\x9f\x8e.jp\0" -"trentinos\xc3\xbc""dtirol.it\0aisho.shiga.jp\0" -"insure\0hzc.io\0" -"dentist\0" -"kyowa.akita.jp\0" -"nishio.aichi.jp\0nra\0" -"bostik\0hopto.me\0" -"page\0est-a-la-maison.com\0" -"tos.it\0biz.ls\0gentapps.com\0" -"\xe7\xbb\x84\xe7\xbb\x87.hk\0" -"obi\0easypanel.app\0" -"mi.th\0" -"nm.us\0" -"agrar.hu\0h\xc3\xa1pmir.no\0" -"instantcloud.cn\0" -"read\0handcrafted.jp\0" -"click\0" -"is-uberleet.com\0" -"biz.mv\0nrw\0" -"biz.mw\0lib.ne.us\0" -"biz.my\0biz.ni\0" -"k12.ec\0!city.kobe.jp\0" -"takasu.hokkaido.jp\0krasnik.pl\0" -"alesund.no\0" -"stokke.no\0" -"biz.nr\0datsun\0" -"mi.us\0graphox.us\0from-dc.com\0" -"country\0" -"skoczow.pl\0" -"kiwi\0" -"training\0" -"community\0" -"*.sys.qcx.io\0be.gy\0" -"principe.st\0fidelity\0" -"ci.it\0parma.it\0chase\0" -"izumisano.osaka.jp\0" -"lib.mi.us\0" -"eti.br\0" -"5g.in\0ntt\0" -"marugame.kagawa.jp\0" -"amagasaki.hyogo.jp\0" -"drobak.no\0" -"press.aero\0" -"saobernardo.br\0" -"biz.pk\0net.eu.org\0" -"biz.pl\0" -"curitiba.br\0k12.ny.us\0*.cloud.metacentrum.cz\0" -"s\xc3\xb8r-aurdal.no\0" -"stor-elvdal.no\0biz.pr\0" -"kumakogen.ehime.jp\0sebastopol.ua\0" -"q.bg\0tanabe.kyoto.jp\0" -"asago.hyogo.jp\0" -"cc.de.us\0" -"hino.tokyo.jp\0torsken.no\0monster\0" -"matsumoto.kagoshima.jp\0yura.wakayama.jp\0sagae.yamagata.jp\0" -"nagara.chiba.jp\0tsunan.niigata.jp\0\xd1\x81\xd0\xb0\xd0\xbc\xd0\xb0\xd1\x80\xd0\xb0.\xd1\x80\xd1\x83\xd1\x81\0" -"ravendb.cloud\0" -"sicily.it\0africa.com\0filegear-de.me\0" -"taketomi.okinawa.jp\0" -"chitose.hokkaido.jp\0" -"gs.vf.no\0" -"fla.no\0*.alces.network\0" -"k12.nm.us\0" -"tuva.su\0" -"basketball\0" -"koge.tottori.jp\0" -"anpachi.gifu.jp\0accountants\0" -"k12.il\0vestby.no\0auto.pl\0api.gov.uk\0dynns.com\0" -"boston\0leclerc\0" -"akamai.net\0" -"cc.ca.us\0" -"ojiya.niigata.jp\0" -"credit\0" -"setouchi.okayama.jp\0" -"hirara.okinawa.jp\0" -"santamaria.br\0cyon.site\0" -"tanagura.fukushima.jp\0" -"oz.au\0gs.tr.no\0" -"1337.pictures\0" -"k12.la.us\0nyc\0" -"biz.ss\0" -"dyroy.no\0" -"itabashi.tokyo.jp\0" -"berg.no\0" -"biz.tj\0" -"ouchi.saga.jp\0ddnslive.com\0" -"boleslawiec.pl\0tiaa\0golffan.us\0" -"lombardy.it\0" -"emiliaromagna.it\0" -"barsy.mobi\0" -"biz.ua\0" -"biz.tr\0" -"githubpreview.dev\0" -"biz.tt\0" -"midori.chiba.jp\0" -"hi.us\0from-ct.com\0" -"from-wv.com\0" -"gratangen.no\0" -"servebbs.com\0" -"laichau.vn\0" -"5.bg\0clothing\0from-az.net\0" -"andria-trani-barletta.it\0" -"anamizu.ishikawa.jp\0" -"lib.hi.us\0" -"*.elb.amazonaws.com\0" -"fem.jp\0""12hp.de\0" -"oyama.tochigi.jp\0" -"nogata.fukuoka.jp\0" -"ujitawara.kyoto.jp\0" -"of.by\0" -"biz.vn\0" -"fukumitsu.toyama.jp\0reit\0" -"kusatsu.gunma.jp\0" -"bozen-s\xc3\xbc""dtirol.it\0sv.it\0" -"biz.wf\0" -"izumi.kagoshima.jp\0okegawa.saitama.jp\0mordovia.su\0" -"\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4\0" -"uruma.okinawa.jp\0aa.no\0" -"adobeio-static.net\0mytuleap.com\0" -"nb.ca\0" -"paroch.k12.ma.us\0" -"jelastic.tsukaeru.net\0" -"kvitsoy.no\0l\xc3\xb8ten.no\0" -"travel.pl\0" -"12hp.at\0" -"nago.okinawa.jp\0total\0" -"filegear-ie.me\0s3.nl-ams.scw.cloud\0" -"iwaizumi.iwate.jp\0" -"yuu.yamaguchi.jp\0gs.svalbard.no\0akamaiedge-staging.net\0for-better.biz\0" -"mus.br\0" -"machida.tokyo.jp\0" -"pars\0" -"tingvoll.no\0" -"solund.no\0" -"info.zm\0one\0" -"za.org\0" -"anan.nagano.jp\0ong\0" -"conf.au\0trondheim.no\0""12hp.ch\0" -"mashiki.kumamoto.jp\0" -"onl\0wpdevcloud.com\0" -"\xc4\x8d\xc3\xa1hcesuolo.no\0" -"tranoy.no\0" -"fuettertdasnetz.de\0" -"casacam.net\0" -"shari.hokkaido.jp\0dealer\0" -"ln.cn\0" -"mihama.mie.jp\0" -"k12.ga.us\0hotels\0vfs.cloud9.ap-southeast-1.amazonaws.com\0" -"biella.it\0mordovia.ru\0" -"us-east-2.elasticbeanstalk.com\0" -"kui.hiroshima.jp\0\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0" -"musashimurayama.tokyo.jp\0biz.zm\0" -"anani.br\0iruma.saitama.jp\0ooo\0*.svc.firenet.ch\0" -"lib.de.us\0" -"\xeb\x8b\xb7\xec\xbb\xb4\0webview-assets.cloud9.us-west-2.amazonaws.com\0" -"eurodir.ru\0" -"obu.aichi.jp\0bedzin.pl\0wafflecell.com\0" -"appudo.net\0" -"blog\0" -"gamagori.aichi.jp\0xfinity\0" -"kamagaya.chiba.jp\0politie\0" -"cesenaforl\xc3\xac.it\0" -"rent\0from-mi.com\0" -"readymade.jp\0" -"*.paywhirl.com\0" -"shiraoi.hokkaido.jp\0" -"suldal.no\0" -"travel.tt\0zapto.org\0" -"yonago.tottori.jp\0czest.pl\0" -"webhop.net\0" -"saito.miyazaki.jp\0" -"arna.no\0" -"kamioka.akita.jp\0" -"toyama.jp\0kusatsu.shiga.jp\0gmail\0""1.azurestaticapps.net\0" -"org\0" -"hitachinaka.ibaraki.jp\0yamada.toyama.jp\0pay\0in-the-band.net\0" -"hirogawa.wakayama.jp\0of.je\0ent.platform.sh\0" -"latino\0" -"adv.br\0perso.sn\0" -"ichikawamisato.yamanashi.jp\0is-a-libertarian.com\0" -"toyotomi.hokkaido.jp\0" -"stackhero-network.com\0" -"atsugi.kanagawa.jp\0" -"monzaebrianza.it\0" -"crimea.ua\0" -"aomori.jp\0" -"ainan.ehime.jp\0" -"k12.tr\0nodes.k8s.nl-ams.scw.cloud\0" -"perso.tn\0\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\x9f\0" -"kitakami.iwate.jp\0" -"vn.ua\0map.fastlylb.net\0" -"analytics\0" -"tula.su\0" -"crd.co\0" -"experts-comptables.fr\0hk.org\0" -"*.digitaloceanspaces.com\0" -"trentinsud-tirol.it\0kppsp.gov.pl\0zaporizhzhia.ua\0cc.or.us\0" -"\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" -"vaga.no\0" -"co.technology\0" -"k12.vi\0" -"casino.hu\0" -"ott\0" -"fukuoka.jp\0shioya.tochigi.jp\0" -"clerkstage.app\0" -"is-lost.org\0" -"bio.br\0engerdal.no\0" -"campidanomedio.it\0" -"hurdal.no\0" -"h\xc3\xb8nefoss.no\0attorney\0" -"takashima.shiga.jp\0" -"l\xc3\xb8""dingen.no\0" -"rest\0for-the.biz\0" -"frei.no\0" -"veterinaire.km\0" -"pet\0" -"shikaoi.hokkaido.jp\0omihachiman.shiga.jp\0" -"mobi\0ovh\0" -"blue\0" -"dupont\0" -"\xe6\xb8\xb8\xe6\x88\x8f\0candypop.jp\0" -"hachioji.tokyo.jp\0" -"fj.cn\0misato.akita.jp\0" -"yaita.tochigi.jp\0" -"of.no\0" -"hirosaki.aomori.jp\0dscloud.biz\0" -"gb.net\0o0o0.jp\0" -"zagan.pl\0namaste.jp\0" -"noda.iwate.jp\0" -"bando.ibaraki.jp\0azimuth.network\0" -"itayanagi.aomori.jp\0grue.no\0" -"moda\0" -"asnes.no\0" -"phd\0" -"yamagata.jp\0lorenskog.no\0" -"nordre-land.no\0acct.pro\0" -"k12.vt.us\0design\0" -"sb.ua\0" -"kashiwa.chiba.jp\0" -"mr.no\0" -"shiogama.miyagi.jp\0" -"assn.lk\0" -"perugia.it\0" -"pid\0" -"\xe9\xa3\x9e\xe5\x88\xa9\xe6\xb5\xa6\0" -"veterinaire.fr\0" -"nozawaonsen.nagano.jp\0" -"trentino-altoadige.it\0naha.okinawa.jp\0" -"pin\0" -"tips\0" -"shinto.gunma.jp\0ap-southeast-1.elasticbeanstalk.com\0" -"wajima.ishikawa.jp\0" -"kirara.st\0" -"dep.no\0" -"shiroishi.saga.jp\0" -"ginoza.okinawa.jp\0" -"warabi.saitama.jp\0" -"e12.ve\0" -"iijima.nagano.jp\0nord-fron.no\0" -"ibxos.it\0" -"\xe7\xb5\x84\xe7\xbb\x87.hk\0" -"kyonan.chiba.jp\0" -"vald-aosta.it\0" -"\xe6\x9c\xba\xe6\x9e\x84\0" -"ato.br\0oppegard.no\0" -"makeup\0" -"bronnoy.no\0" -"lib.pr.us\0netbank\0" -"police.uk\0" -"*.yokohama.jp\0cc.in.us\0" -"marnardal.no\0" -"eidsberg.no\0" -"nagasaki.nagasaki.jp\0" -"skj\xc3\xa5k.no\0reserve-online.com\0" -"monash\0ma.leg.br\0" -"odawara.kanagawa.jp\0aridagawa.wakayama.jp\0" -"yamagata.ibaraki.jp\0official.ec\0dojin.com\0" -"dubai\0" -"moo.jp\0" -"otaki.saitama.jp\0" -"piemonte.it\0" -"pixolino.com\0" -"haugesund.no\0" -"fhsk.se\0" -"takamatsu.kagawa.jp\0nakagyo.kyoto.jp\0foundation\0pnc\0nordeste-idc.saveincloud.net\0ditchyourip.com\0" -"adv.mz\0" -"cutegirl.jp\0" -"nv.us\0" -"is.gov.pl\0" -"warmia.pl\0" -"\xc3\xa1laheadju.no\0vestnes.no\0komvux.se\0us.ax\0" -"manno.kagawa.jp\0vossevangen.no\0" -"agents.aero\0" -"heguri.nara.jp\0*.hosting.myjino.ru\0" -"kamikawa.saitama.jp\0" -"togakushi.nagano.jp\0edgesuite.net\0" -"imperia.it\0pccw\0" -"infiniti\0endofinternet.org\0" -"ferrero\0" -"journal.aero\0passenger-association.aero\0uki.kumamoto.jp\0conf.se\0" -"q-a.eu.org\0" -"cesena-forl\xc3\xac.it\0trento.it\0" -"academia.bo\0" -"shinkamigoto.nagasaki.jp\0" -"consultant.aero\0miyagi.jp\0" -"dunlop\0" -"cr.it\0" -"minamiashigara.kanagawa.jp\0" -"haga.tochigi.jp\0alaheadju.no\0siiites.com\0" -"kamikawa.hokkaido.jp\0orkdal.no\0" -"wazuka.kyoto.jp\0forsale\0home-webserver.de\0*.telebit.xyz\0" -"trentinsued-tirol.it\0dr\xc3\xb8""bak.no\0" -"iiyama.nagano.jp\0freeddns.us\0" -"msk.ru\0oxa.cloud\0" -"romsa.no\0" -"romskog.no\0" -"r\xc3\xb8st.no\0circle\0" -"amica\0" -"somna.no\0" -"tochigi.tochigi.jp\0" -"fbxos.fr\0col.ng\0" -"z.bg\0mitaka.tokyo.jp\0msk.su\0" -"bn.it\0" -"kitami.hokkaido.jp\0beta.bounty-full.com\0" -"vda.it\0" -"sk.ca\0" -"servehumour.com\0" -"authgear-staging.com\0" -"commune.am\0shinonsen.hyogo.jp\0" -"higashihiroshima.hiroshima.jp\0aus.basketball\0" -"pro\0" -"sakyo.kyoto.jp\0nakayama.yamagata.jp\0" -"daklak.vn\0" -"oldnavy\0pru\0gotdns.ch\0" -"kawanishi.nara.jp\0mo-siemens.io\0" -"f.bg\0" -"\xe9\x9d\x92\xe6\xa3\xae.jp\0" +"ma\0" +"goiania.br\0lr\0" +"ls\0mc\0from-il.com\0" +"\xe6\xb2\x96\xe7\xb8\x84.jp\0sarufutsu.hokkaido.jp\0lt\0md\0west1-us.cloudjiffy.net\0" +"lu\0me\0pnc\0" +"lv\0omg.lol\0" +"mg\0mt.us\0nd.us\0s3-accesspoint.dualstack.eu-central-1.amazonaws.com\0" +"agano.niigata.jp\0mh\0" +"ly\0" +"shinonsen.hyogo.jp\0" +"mk\0" +"gr.it\0ml\0uh-oh.jp\0" +"galsa.no\0sirdal.no\0" +"mn\0" +"mo\0" +"kamiamakusa.kumamoto.jp\0mp\0""123homepage.it\0" +"mq\0na\0in.na\0lv.ua\0analytics-gateway.ap-southeast-2.amazonaws.com\0" +"mr\0" +"ms\0nc\0" +"yoshida.saitama.jp\0mt\0weather\0" +"mu\0ne\0mus.mi.us\0*.ap-southeast-1.airflow.amazonaws.com\0s3-website.dualstack.ca-central-1.amazonaws.com\0" +"mv\0nf\0" +"mw\0ng\0" +"gr.jp\0honjo.saitama.jp\0mx\0githubpreview.dev\0" +"my\0ni\0in.ni\0" +"mz\0" +"group.aero\0krodsherad.no\0investments\0s3-external-1.amazonaws.com\0folionetwork.site\0" +"nl\0" +"onga.fukuoka.jp\0" +"no\0" +"lib.ak.us\0" +"minato.osaka.jp\0nr\0" +"kimobetsu.hokkaido.jp\0" +"nu\0auth.eu-west-1.amazoncognito.com\0s3.dualstack.eu-north-1.amazonaws.com\0" +"kasai.hyogo.jp\0" +"gjemnes.no\0webview-assets.cloud9.us-east-2.amazonaws.com\0" +"\xe7\xb6\xb2\xe7\xbb\x9c.hk\0freemyip.com\0" +"tomigusuku.okinawa.jp\0nz\0call\0lgbt\0blackbaudcdn.net\0" +"sigdal.no\0" +"om\0lpusercontent.com\0" +"uji.kyoto.jp\0""2.azurestaticapps.net\0" +"pa\0" +"v\xc3\xa6r\xc3\xb8y.no\0pymnt.uk\0" +"pe\0" +"fm.it\0pf\0" +"ph\0" +"pk\0" +"pl\0chirurgiens-dentistes-en-france.fr\0" +"design.aero\0pm\0" +"pn\0camp\0" +"qa\0servemp3.com\0" +"vald-aosta.it\0pr\0" +"ps\0webthings.io\0" +"pt\0" +"lancaster\0akamaiedge.net\0goupile.fr\0" +"pw\0miniserver.com\0" +"py\0" +"\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86\0vapor.cloud\0" +"trentinoaadige.it\0podhale.pl\0" +"org.ac\0tingvoll.no\0la.us\0" +"org.ae\0shacknet.nu\0" +"org.af\0keliweb.cloud\0" +"org.ag\0pro\0" +"org.ai\0emb.kw\0" +"re\0" +"org.al\0" +"org.am\0pru\0" +"kazo.saitama.jp\0\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4\0" +"org.ba\0" +"org.ar\0org.bb\0ragusa.it\0" +"s\xc3\xb8r-fron.no\0" +"kochi.jp\0" +"org.au\0ro\0" +"gujo.gifu.jp\0\xeb\x8b\xb7\xec\xbb\xb4\0" +"sa\0" +"org.bh\0sb\0verse.jp\0" +"org.bi\0fuoisku.no\0rs\0in.rs\0sc\0" +"org.az\0org.bj\0sd\0" +"ru\0se\0" +"org.bm\0rw\0sg\0ae.org\0jdevcloud.com\0" +"org.bn\0coop.ht\0sh\0" +"org.bo\0si\0notebook.ap-east-1.sagemaker.aws\0" +"mamurogawa.yamagata.jp\0sj\0" +"sk\0youtube\0" +"org.br\0otaki.chiba.jp\0usuki.oita.jp\0sl\0" +"org.bs\0osen.no\0sm\0" +"org.bt\0sn\0" +"so\0game-host.org\0rackmaze.com\0reservd.dev.thingdust.io\0" +"org.bw\0dynns.com\0" +"coop.in\0sr\0her.jp\0" +"org.ci\0ss\0tc\0" +"org.bz\0kiyama.saga.jp\0st\0td\0pub\0" +"su\0dvrdns.org\0" +"coop.ar\0sv\0tf\0" +"tg\0*.sch.uk\0readthedocs.io\0direct.quickconnect.to\0" +"org.cn\0sx\0th\0in.th\0" +"ab.ca\0org.co\0sy\0" +"\xe5\xb2\x90\xe9\x98\x9c.jp\0fujinomiya.shizuoka.jp\0sz\0tj\0" +"tk\0execute-api.eu-west-2.amazonaws.com\0s3-accesspoint.dualstack.us-west-2.amazonaws.com\0" +"cz.it\0yakage.okayama.jp\0tl\0" +"tm\0" +"ulsan.kr\0tn\0" +"research.aero\0org.cu\0to\0" +"org.cv\0watarai.mie.jp\0" +"org.cw\0fm.no\0ua\0in.ua\0caa.li\0" +"tr\0" +"org.cy\0care\0chrome\0" +"cs.in\0tt\0" +"for-our.info\0" +"coop.br\0tv\0" +"association.aero\0org.dm\0tw\0ug\0" +"minokamo.gifu.jp\0aya.miyazaki.jp\0" +"org.do\0" +"brescia.it\0cs.it\0tz\0" +"uk\0" +"org.ec\0realty\0" +"org.ee\0casa\0" +"towada.aomori.jp\0" +"org.eg\0va\0cars\0" +"us\0in.us\0vc\0case\0bukhara.su\0" +"org.dz\0sejny.pl\0" +"ve\0pwc\0s3-accesspoint.ca-central-1.amazonaws.com\0appchizi.com\0" +"cash\0homedepot\0" +"\xc3\xa5s.no\0vg\0s3-ca-central-1.amazonaws.com\0" +"cl.it\0dlugoleka.pl\0" +"uy\0vi\0furniture\0" +"uz\0" +"sakura.chiba.jp\0" +"org.es\0" +"org.et\0toshima.tokyo.jp\0vn\0" +"barueri.br\0yamamoto.miyagi.jp\0fastvps.host\0" +"org.fj\0" +"\xc3\xa5l.no\0vu\0" +"ce.it\0elk.pl\0wf\0" +"org.fm\0engineering\0s3-website-ap-southeast-1.amazonaws.com\0" "debian.net\0" -"dyndns-at-home.com\0" -"airkitapps-au.com\0" -"webspace.rocks\0" -"shiksha\0" -"laz.it\0k12.md.us\0" -"embaixada.st\0" -"yamagata.gifu.jp\0pub\0" -"sucks\0" -"fastvps.host\0" -"qc.ca\0" -"babyblue.jp\0" -"time.no\0" -"cloudns.eu\0" -"hisayama.fukuoka.jp\0to.gt\0" -"us.in\0\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0" -"abira.hokkaido.jp\0" -"travel.in\0\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb8\0" -"vc.it\0" -"skygearapp.com\0" -"sakura.chiba.jp\0is-an-actor.com\0" -"sauherad.no\0" -"karasuyama.tochigi.jp\0" -"draydns.de\0" -"ikoma.nara.jp\0pwc\0" -"s3.dualstack.us-east-2.amazonaws.com\0" -"\xe0\xb8\x98\xe0\xb8\xb8\xe0\xb8\xa3\xe0\xb8\x81\xe0\xb8\xb4\xe0\xb8\x88.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"pulawy.pl\0cloudapp.net\0" -"us.kg\0" -"mimoza.jp\0" -"miyakonojo.miyazaki.jp\0" -"thuathienhue.vn\0" -"kafjord.no\0" -"pilot.aero\0chirurgiens-dentistes.fr\0" -"to.it\0" -"*.bd\0kurogi.fukuoka.jp\0*.0emm.com\0" -"geo.br\0" -"suwa.nagano.jp\0koshigaya.saitama.jp\0" -"cranky.jp\0" -"cf-ipfs.com\0" -"\xe5\xae\xae\xe5\xb4\x8e.jp\0moto\0" -"*.kobe.jp\0" -"suwalki.pl\0" -"upper.jp\0" -"fjell.no\0cloudns.in\0" -"telebit.app\0" -"*.ck\0" -"conf.lv\0helsinki\0" -"kr\xc3\xb8""dsherad.no\0" -"noda.chiba.jp\0it1.eur.aruba.jenv-aruba.cloud\0" -"hs.zone\0" -"\xe7\xa6\x8f\xe5\xb3\xb6.jp\0" -"us.na\0" -"tahara.aichi.jp\0service.gov.scot\0" -"playstation\0" -"niteroi.br\0s3.dualstack.eu-west-1.amazonaws.com\0" -"cieszyn.pl\0" -"cloudns.cc\0" -"friulivenezia-giulia.it\0" -"nishi.fukuoka.jp\0demo.datadetect.com\0to.md\0" -"rg.it\0" -"akashi.hyogo.jp\0" -"cr.ua\0" -"shinjo.okayama.jp\0" -"moss.no\0" -"sannan.hyogo.jp\0" -"cya.gg\0""123homepage.it\0" -"*.er\0" -"c.cdn77.org\0" -"civilaviation.aero\0tokorozawa.saitama.jp\0risor.no\0" -"aerobatic.aero\0*.fk\0" -"isa-hockeynut.com\0affinitylottery.org.uk\0" -"schokokeks.net\0" -"haibara.shizuoka.jp\0nanyo.yamagata.jp\0" -"oya.to\0" -"aeroclub.aero\0harima.hyogo.jp\0r2.dev\0dnsalias.com\0" -"cc.sc.us\0" -"club.aero\0nid.io\0" -"aseral.no\0m\xc4\x81ori.nz\0fund\0kerryhotels\0" -"miyako.fukuoka.jp\0" -"pl.eu.org\0" -"dovre.no\0" -"kozaki.chiba.jp\0" -"nisshin.aichi.jp\0" -"krellian.net\0" -"\xc3\xa5l.no\0" -"tgory.pl\0" -"engine.aero\0" -"kuju.oita.jp\0" -"engineer.aero\0k12.fl.us\0groks-this.info\0" -"utsunomiya.tochigi.jp\0gent\0" -"ap.ngrok.io\0" -"paas.massivegrid.com\0" -"inami.wakayama.jp\0" -"lib.ar.us\0tours\0" -"leasing.aero\0aomori.aomori.jp\0" -"is-an-accountant.com\0" -"lind\xc3\xa5s.no\0" -"stage.nodeart.io\0" -"barsycenter.com\0" -"higashinaruse.akita.jp\0" -"uchiko.ehime.jp\0ninomiya.kanagawa.jp\0" -"tado.mie.jp\0" -"yaizu.shizuoka.jp\0" -"\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0" -"honjo.akita.jp\0from-ar.com\0" -"misaki.osaka.jp\0" -"rocky.page\0" -"mel.cloudlets.com.au\0" -"gmina.pl\0" -"analytics-gateway.eu-west-1.amazonaws.com\0" -"ichinoseki.iwate.jp\0" -"owariasahi.aichi.jp\0" -"*.jm\0cloudns.pro\0" -"est-mon-blogueur.com\0" -"\xe5\xa4\xa7\xe9\x98\xaa.jp\0" -"gjovik.no\0" -"kyoto.jp\0\xe5\xbe\xae\xe5\x8d\x9a\0" -"auspost\0" -"aki.kochi.jp\0mypep.link\0" -"maori.nz\0" -"*.kh\0is-leet.com\0" -"hanno.saitama.jp\0starachowice.pl\0vfs.cloud9.ap-south-1.amazonaws.com\0" -"osaka.jp\0loseyourip.com\0" -"kv\xc3\xa6""fjord.no\0" -"nakanojo.gunma.jp\0" -"praxi\0\xd0\xba\xd0\xbe\xd0\xbc.\xd1\x80\xd1\x83\xd1\x81\0mail-box.ne.jp\0" -"gc.ca\0ryugasaki.ibaraki.jp\0" -"lugs.org.uk\0" -"nfshost.com\0" -"\xd9\x85\xd9\x88\xd8\xb1\xd9\x8a\xd8\xaa\xd8\xa7\xd9\x86\xd9\x8a\xd8\xa7\0" -"bozen-sudtirol.it\0" -"website\0br.com\0" -"goip.de\0" -"lc.it\0inder\xc3\xb8y.no\0z.se\0a.ssl.fastly.net\0" -"shiojiri.nagano.jp\0" -"ikeda.nagano.jp\0" -"abc.br\0" -"glitch.me\0" -"aivencloud.com\0" -"cc.ms.us\0cc.nc.us\0dabur\0" -"shimoichi.nara.jp\0cheap\0healthcare\0" -"numata.gunma.jp\0*.mm\0lexus\0" -"ikeda.gifu.jp\0misugi.mie.jp\0" -"broke-it.net\0" -"kopervik.no\0" -"dental\0" -"f.se\0k12.al.us\0" -"matsuyama.ehime.jp\0*.frusky.de\0" -"sakai.osaka.jp\0samsclub\0" -"busan.kr\0*.np\0" -"flog.br\0" -"home.dyndns.org\0" -"red\0my-wan.de\0" -"bungotakada.oita.jp\0" -"marketing\0" -"kharkov.ua\0lincoln\0" -"vallee-aoste.it\0nagareyama.chiba.jp\0" -"gotdns.org\0" -"discourse.team\0" -"biratori.hokkaido.jp\0nogi.tochigi.jp\0swinoujscie.pl\0cloudns.us\0" -"shirahama.wakayama.jp\0ren\0" -"mydatto.com\0" -"awaji.hyogo.jp\0" -"macerata.it\0upaas.kazteleport.kz\0" -"stryn.no\0" -"*.pg\0" -"rzeszow.pl\0from-tn.com\0" -"balat.no\0" -"chita.aichi.jp\0" -"kawanabe.kagoshima.jp\0perspecta.cloud\0" -"vlog.br\0haiduong.vn\0is-a-geek.com\0jotelulu.cloud\0lpusercontent.com\0" -"bofa\0" -"mod.gi\0budejju.no\0" -"kyowa.hokkaido.jp\0minato.tokyo.jp\0flickr\0" -"kuroishi.aomori.jp\0writesthisblog.com\0" -"matsuno.ehime.jp\0kiso.nagano.jp\0matsubara.osaka.jp\0" -"lucca.it\0" -"nakama.fukuoka.jp\0asker.no\0" -"mortgage\0" -"samukawa.kanagawa.jp\0" -"kuwana.mie.jp\0" -"kiyama.saga.jp\0" -"bc.ca\0tamakawa.fukushima.jp\0" -"casino\0" -"noop.app\0" -"yawara.ibaraki.jp\0""4u.com\0" -"shimonoseki.yamaguchi.jp\0" -"lig.it\0sor-odal.no\0rocher\0" -"himeji.hyogo.jp\0mg.leg.br\0" -"withyoutube.com\0" -"alstahaug.no\0" -"mitsue.nara.jp\0" -"belau.pw\0" -"kurume.fukuoka.jp\0" -"ashiya.fukuoka.jp\0" -"ril\0" -"yatomi.aichi.jp\0yoka.hyogo.jp\0rio\0wales\0" -"rip\0" -"rackmaze.com\0" -"karasjohka.no\0" -"kanzaki.saga.jp\0" -"schulplattform.de\0" -"bjark\xc3\xb8y.no\0" -"ota.tokyo.jp\0" -"hammerfest.no\0" -"kawakami.nara.jp\0" -"yonabaru.okinawa.jp\0wien.funkfeuer.at\0" -"*.sch.uk\0" -"ltd.co.im\0" -"daigo.ibaraki.jp\0" -"ono.hyogo.jp\0" -"hazu.aichi.jp\0" -"zhitomir.ua\0" -"v\xc3\xa5gs\xc3\xb8y.no\0" -"mielno.pl\0us.reclaim.cloud\0" -"higashiura.aichi.jp\0kozagawa.wakayama.jp\0zpisdn.gov.pl\0" -"lodingen.no\0kiwi.nz\0" -"ven.it\0in-berlin.de\0" -"trentins\xc3\xbc""dtirol.it\0" -"capitalone\0" -"\xc3\xa5seral.no\0s3.ap-northeast-2.amazonaws.com\0" -"s\xc3\xb8mna.no\0motorcycles\0" -"bearalvahki.no\0" -"ashiya.hyogo.jp\0" -"matsudo.chiba.jp\0" -"sa.ngrok.io\0" -"is-a-knight.org\0" -"\xd9\x87\xd9\x85\xd8\xb1\xd8\xa7\xd9\x87\0" -"fujimino.saitama.jp\0ks.ua\0myfirewall.org\0" -"sex.hu\0" -"\xe5\xb3\xb6\xe6\xa0\xb9.jp\0" -"\xe5\x9f\xbc\xe7\x8e\x89.jp\0grp.lk\0" -"x443.pw\0my-vigor.de\0" -"oishida.yamagata.jp\0folldal.no\0" -"123sait.ru\0" -"ito.shizuoka.jp\0" -"asaka.saitama.jp\0analytics-gateway.us-west-2.amazonaws.com\0" -"study\0dynv6.net\0" -"friuli-venezia-giulia.it\0" -"evje-og-hornnes.no\0\xc3\xa1k\xc5\x8boluokta.no\0" -"pussycat.jp\0" -"leka.no\0tec.mi.us\0" -"erotika.hu\0esashi.hokkaido.jp\0ks.us\0barclays\0" -"kisofukushima.nagano.jp\0" -"lesja.no\0" -"aisai.aichi.jp\0webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com\0togliatti.su\0" -"o.bg\0med.br\0" -"bond\0cloud.interhostsolutions.be\0*.build.run\0" -"fedorapeople.org\0""4lima.de\0" -"resindevice.io\0" -"babymilk.jp\0" -"ujiie.tochigi.jp\0" -"cc.dc.us\0" -"saiki.oita.jp\0" -"republican\0cloudns.org\0" -"mitsubishi\0" -"\xd0\xbe\xd0\xb4.\xd1\x81\xd1\x80\xd0\xb1\0" -"saitama.saitama.jp\0" -"thingdustdata.com\0*.webhare.dev\0" -"konin.pl\0book\0\xe4\xb8\xad\xe4\xbf\xa1\0" -"asahi.toyama.jp\0cloudns.pw\0" -"name\0" -"iwate.iwate.jp\0" -"med.ec\0""4lima.at\0" -"med.ee\0freeboxos.com\0" -"dyr\xc3\xb8y.no\0is-a-geek.org\0" -"*.linodeobjects.com\0" -"mashiko.tochigi.jp\0sap\0" -"halsa.no\0konskowola.pl\0" -"sas\0" -"londrina.br\0appspot.com\0" -"mods.jp\0" -"\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"fujikawaguchiko.yamanashi.jp\0sbi\0" -"aure.no\0" -"okuizumo.shimane.jp\0" -"zakopane.pl\0""4lima.ch\0" -"from-tx.com\0" -"cc.ak.us\0sca\0from-pa.com\0" -"scb\0" -"sbs\0kustanai.ru\0" -"nara.jp\0" -"scientist.aero\0" -"freeboxos.fr\0" -"equipment.aero\0webview-assets.cloud9.ap-northeast-1.amazonaws.com\0pagespeedmobilizer.com\0lk3.ru\0jpn.org\0" -"minokamo.gifu.jp\0" -"nt.au\0siena.it\0no.eu.org\0" -"kasama.ibaraki.jp\0" -"taishin.fukushima.jp\0nakagawa.hokkaido.jp\0edogawa.tokyo.jp\0discount\0vote\0" -"akagi.shimane.jp\0" -"3.bg\0git-repos.de\0mysecuritycamera.com\0" -"kustanai.su\0" -"nt.ca\0ggee\0" -"vang.no\0" -"itoman.okinawa.jp\0gyeongbuk.kr\0nghean.vn\0" -"voto\0" -"kanra.gunma.jp\0rag-cloud-ch.hosteur.com\0" -"kalisz.pl\0" -"pa.gov.br\0" -"sex.pl\0rich\0" -"med.ht\0futsu.nagasaki.jp\0" -"myoko.niigata.jp\0cc.ut.us\0" -"run\0" -"friuli-vegiulia.it\0" -"aurland.no\0" -"mp.br\0delhi.in\0nakai.kanagawa.jp\0buyshouses.net\0" -"carraramassa.it\0kerryproperties\0" -"\xe0\xb4\xad\xe0\xb4\xbe\xe0\xb4\xb0\xe0\xb4\xa4\xe0\xb4\x82\0" -"kommunalforbund.se\0sew\0" -"sex\0" -"soccer\0" -"al.eu.org\0" -"heroy.more-og-romsdal.no\0" -"pb.gov.br\0" -"chernovtsy.ua\0sfr\0" -"pro.az\0" -"homedepot\0" -"tran\xc3\xb8y.no\0rwe\0" -"umb.it\0" -"ullensvang.no\0\xe4\xb8\x96\xe7\x95\x8c\0" -"pro.br\0" -"bod\xc3\xb8.no\0luster.no\0" -"r\xc3\xa1hkker\xc3\xa1vju.no\0" -"galsa.no\0" -"is-very-sweet.org\0" -"h\xc3\xb8yanger.no\0christmas\0" -"kamitsue.oita.jp\0" -"pubtls.org\0" -"matta-varjjat.no\0" -"shimada.shizuoka.jp\0aramco\0" -"futuremailing.at\0" -"meinforum.net\0" -"bardu.no\0stufftoread.com\0" -"pro.cy\0" -"vivian.jp\0" -"aostavalley.it\0" -"mazeplay.com\0" -"it.ao\0" -"\xe7\xa6\x8f\xe4\xba\x95.jp\0origins\0uk.net\0nz.eu.org\0" -"pro.ec\0organic\0" -"wada.nagano.jp\0med.ly\0coach\0definima.net\0" -"jx.cn\0gs.nl.no\0reisen\0" -"st.no\0hiphop\0" -"hiho.jp\0" -"homebuilt.aero\0" -"saga.jp\0vard\xc3\xb8.no\0" -"180r.com\0" -"postman-echo.com\0" -"kongsvinger.no\0" -"\xe0\xba\xa5\xe0\xba\xb2\xe0\xba\xa7\0servebeer.com\0" -"js.wpenginepowered.com\0" -"ppg.br\0" -"oe.yamagata.jp\0" -"inf.br\0" -"pro.fj\0" -"omura.nagasaki.jp\0" -"as.us\0" -"navy\0" -"ski\0sells-it.net\0" -"pug.it\0\xc3\xb8vre-eiker.no\0" -"user.party.eus\0" -"fot.br\0kitaaiki.nagano.jp\0sorfold.no\0" -"okuma.fukushima.jp\0sasebo.nagasaki.jp\0" -"cable-modem.org\0" -"med.om\0" -"luxury\0" -"inf.cu\0namdalseid.no\0" -"med.pa\0nobushi.jp\0woltlab-demo.com\0" -"aoki.nagano.jp\0" -"hlx.live\0" -"sky\0" -"gran.no\0us-east-1.amazonaws.com\0" -"imb.br\0" -"satsumasendai.kagoshima.jp\0" -"orsites.com\0" -"med.pl\0" -"arao.kumamoto.jp\0" -"beppu.oita.jp\0" -"works.aero\0hirata.fukushima.jp\0" -"hobby-site.com\0" -"akadns.net\0enterprisecloud.nu\0" -"\xe6\x95\x99\xe8\x82\xb2.hk\0" -"semine.miyagi.jp\0" -"pro.ht\0" -"rikubetsu.hokkaido.jp\0" -"shakotan.hokkaido.jp\0" -"trentino-a-adige.it\0vfs.cloud9.eu-north-1.amazonaws.com\0" -"taa.it\0" -"sells-for-less.com\0" -"pro.in\0no-ip.co.uk\0" -"iizuna.nagano.jp\0" -"fuchu.tokyo.jp\0bar2.net\0dev-myqnapcloud.com\0" -"k\xc3\xa1r\xc3\xa1\xc5\xa1johka.no\0" -"lib.ut.us\0" -"fresenius\0" -"qsl.br\0photos\0" -"hitra.no\0" -"med.sa\0adobeioruntime.net\0" -"guam.gu\0" -"minamata.kumamoto.jp\0doshi.yamanashi.jp\0med.sd\0" -"bologna.it\0tx.us\0" -"ed.ao\0a\xc3\xa9roport.ci\0osakasayama.osaka.jp\0" -"kawai.nara.jp\0" -"net-freaks.com\0" -"spa\0" -"vercel.app\0" -"nt.no\0o.se\0" -"itakura.gunma.jp\0ome.tokyo.jp\0os.hordaland.no\0" -"lib.tx.us\0diadem.cloud\0" -"soy\0" -"\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88\0" -"\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xaa\xe0\xaf\x82\xe0\xae\xb0\xe0\xaf\x8d\0" -"0e.vc\0" -"hoplix.shop\0" -"naustdal.no\0" -"binhduong.vn\0tab\0fldrv.com\0" -"webview-assets.cloud9.ap-southeast-1.amazonaws.com\0" -"\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa\0" -"nt.edu.au\0ed.ci\0" -"ebino.miyazaki.jp\0" -"miyako.iwate.jp\0" -"grajewo.pl\0kosher\0" -"paas.beebyte.io\0" -"ed.cr\0" -"vip.jelastic.cloud\0" -"productions\0" -"omi.nagano.jp\0notogawa.shiga.jp\0" -"lierne.no\0" -"higashikawa.hokkaido.jp\0ny-2.paas.massivegrid.net\0" -"tax\0" -"kuriyama.hokkaido.jp\0pro.na\0" -"lpages.co\0" -"srl\0" -"my-gateway.de\0" -"pro.mv\0pisz.pl\0" -"rennes\xc3\xb8y.no\0tana.no\0ox.rs\0" -"valle-aosta.it\0" -"vpndns.net\0" -"tci\0" -"doctor\0" -"etnedal.no\0farmers\0" -"kotohira.kagawa.jp\0" -"salvador.br\0giize.com\0" -"*.beget.app\0" -"sandefjord.no\0swiss\0" -"stc\0" -"oncilla.mythic-beasts.com\0" -"nt.ro\0" -"pro.om\0" -"mitane.akita.jp\0s3-ap-northeast-1.amazonaws.com\0" -"gallery\0" -"tdk\0" -"archi\0" -"hasuda.saitama.jp\0" -"onomichi.hiroshima.jp\0is-into-cars.com\0" -"\xd0\xba\xd0\xbe\xd0\xbc\0" -"pi.gov.br\0vall\xc3\xa9""e-aoste.it\0wskr.gov.pl\0*.awdev.ca\0" -"author\0" -"agano.niigata.jp\0" -"club.tw\0" -"cc.il.us\0" -"inf.mk\0pro.pr\0" -"tel\0s3.dualstack.ca-central-1.amazonaws.com\0from-sc.com\0" -"services\0blogsite.xyz\0" -"fujioka.gunma.jp\0" -"szex.hu\0" -"\xd1\x81\xd0\xbe\xd1\x87\xd0\xb8.\xd1\x80\xd1\x83\xd1\x81\0" -"no-ip.org\0" -"\xe6\x95\x99\xe8\x82\xb2.\xe9\xa6\x99\xe6\xb8\xaf\0" -"ah.cn\0od.ua\0" -"reggio-emilia.it\0garden\0" -"\xe6\xbe\xb3\xe9\x96\x80\0" -"mihama.wakayama.jp\0mj\xc3\xb8ndalen.no\0we.bs\0" -"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x81\xd1\x80\xd0\xb1\0" -"urasoe.okinawa.jp\0" -"gouv.fr\0ichikawa.hyogo.jp\0" -"nakagusuku.okinawa.jp\0" -"gdansk.pl\0" -"cafe\0" -"qld.au\0" -"pistoia.it\0" -"barlettatraniandria.it\0" -"sund.no\0obninsk.su\0logoip.com\0" -"thd\0" -"misato.saitama.jp\0" -"hanamigawa.chiba.jp\0inderoy.no\0*.statics.cloud\0" -"yoshioka.gunma.jp\0likes-pie.com\0" -"kaneyama.fukushima.jp\0yomitan.okinawa.jp\0salat.no\0chernigov.ua\0" -"ed.jp\0" -"scalebook.scw.cloud\0" -"express\0remotewd.com\0" -"online.th\0" -"*.compute.amazonaws.com\0app.banzaicloud.io\0" -"gouv.ht\0" -"moriyama.shiga.jp\0" -"pro.tt\0\xe6\x97\xb6\xe5\xb0\x9a\0" -"ueno.gunma.jp\0app.os.stg.fedoraproject.org\0impertrix.com\0" -"vadso.no\0" -"shimotsuma.ibaraki.jp\0" -"dazaifu.fukuoka.jp\0" -"wroclaw.pl\0" -"furniture\0" -"gorizia.it\0" -"shimamaki.hokkaido.jp\0" -"tokigawa.saitama.jp\0" -"ulvik.no\0kh.ua\0" -"x.bg\0hirono.iwate.jp\0" -"championship.aero\0bl.it\0" -"barcelona\0" -"tm.cy\0pro.vn\0" -"tjx\0" -"gouv.ci\0" -"cooperativa.bo\0" -"oiso.kanagawa.jp\0" -"potager.org\0" -"karmoy.no\0from-sd.com\0" -"kuleuven.cloud\0syncloud.it\0" -"cesenaforli.it\0ap-northeast-2.elasticbeanstalk.com\0" -"k12.mn.us\0" -"tm.dz\0" -"est-a-la-masion.com\0" -"dyndns-web.com\0pointto.us\0" -"d.bg\0shinjo.yamagata.jp\0" -"googlecode.com\0" -"pe.gov.br\0tsuwano.shimane.jp\0" -"naka.ibaraki.jp\0inf.ua\0" -"\xe6\xbe\xb3\xe9\x97\xa8\0" -"*.stg.dev\0" -"flor\xc3\xb8.no\0is-a-geek.net\0" -"mt.eu.org\0" -"nanjo.okinawa.jp\0\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0\0site.transip.me\0" -"b\xc3\xa6rum.no\0netflix\0" -"afjord.no\0" -"tm.fr\0call\0dyndns-office.com\0" -"\xd0\xbc\xd0\xb8\xd1\x80.\xd1\x80\xd1\x83\xd1\x81\0" -"sanagochi.tokushima.jp\0wang\0" -"fukushima.fukushima.jp\0" -"idf.il\0" -"dienbien.vn\0" -"sport\0" -"sener\0" -"webview-assets.cloud9.eu-north-1.amazonaws.com\0" -"otsuka\0" -"niiza.saitama.jp\0store.nf\0" -"cooking\0" -"gotsu.shimane.jp\0camp\0delta\0" -"ed.pw\0wpmudev.host\0" -"bsb.br\0" -"va.it\0" -"mobi.gp\0fh.se\0" -"freeddns.org\0" -"rocks\0" -"top\0" -"nyuzen.toyama.jp\0" -"tm.hu\0" -"oracle\0" -"fujieda.shizuoka.jp\0" -"rackmaze.net\0" -"blogspot.com.cy\0" -"jaguar\0dynvpn.de\0" -"tonsberg.no\0" -"myspreadshop.nl\0" -"taito.tokyo.jp\0" -"bygland.no\0myspreadshop.no\0" -"cloudfront.net\0" -"donna.no\0hyundai\0" -"sosa.chiba.jp\0blogspot.com.ee\0" -"gaivuotna.no\0" -"service.gov.uk\0blogspot.com.eg\0" -"ah.no\0" -"hitachi.ibaraki.jp\0" -"inagi.tokyo.jp\0""2ix.at\0" -"stuff-4-sale.us\0" -"mincom.tn\0cn-northwest-1.eb.amazonaws.com.cn\0blogspot.com.ar\0" -"tonami.toyama.jp\0nextdirect\0blogspot.com.au\0" -"minamiaiki.nagano.jp\0sharp\0" -"atm.pl\0" -"nagaoka.niigata.jp\0" -"imakane.hokkaido.jp\0" -"pa.gov.pl\0" -"si.it\0izumizaki.fukushima.jp\0tm.km\0syno-ds.de\0" -"kv\xc3\xa6nangen.no\0suzuki\0" -"*.ex.ortsinfo.at\0myspreadshop.pl\0" -"pvt.ge\0uwajima.ehime.jp\0" -"varoy.no\0" -"blogspot.com.br\0""2ix.ch\0" -"exposed\0ubs\0" -"trv\0" -"higashikagura.hokkaido.jp\0care\0blogspot.com.by\0" -"\xc3\xb8rland.no\0" -"deno-staging.dev\0" -"blogspot.com.co\0""2ix.de\0" -"tm.mc\0ivanovo.su\0" -"fet.no\0" -"re.it\0va.no\0" -"tm.mg\0phuyen.vn\0casa\0claims\0" -"myspreadshop.it\0" -"cars\0" -"case\0s3-us-west-1.amazonaws.com\0" -"ostrowiec.pl\0" -"tempio-olbia.it\0ris\xc3\xb8r.no\0" -"cash\0" -"aosta.it\0" -"eu.com\0" -"dnepropetrovsk.ua\0" -"sk\xc3\xa5nland.no\0teaches-yoga.com\0" -"gwangju.kr\0" -"minami.kyoto.jp\0anan.tokushima.jp\0familyds.com\0" -"habmer.no\0" -"tui\0" -"floripa.br\0" -"shinyoshitomi.fukuoka.jp\0yodobashi\0" -"tm.no\0" -"travelersinsurance\0" -"toride.ibaraki.jp\0miyada.nagano.jp\0sandnes.no\0" -"shikabe.hokkaido.jp\0" -"computer\0" -"hanamaki.iwate.jp\0oguni.yamagata.jp\0re.kr\0" -"doomdns.org\0blogspot.com.es\0" -"gift\0" -"nesoddtangen.no\0" -"kvanangen.no\0" -"store.ve\0" -"usuki.oita.jp\0" -"dlugoleka.pl\0" -"aioi.hyogo.jp\0" -"pr.gov.br\0" -"ayase.kanagawa.jp\0" -"flatanger.no\0" -"mormon\0tvs\0sumomo.ne.jp\0" -"torino.it\0" -"\xe0\xa8\xad\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\xa4\0" -"hita.oita.jp\0" -"kiyokawa.kanagawa.jp\0" -"tm.pl\0bona.jp\0" -"my.eu.org\0" -"n\xc3\xa5\xc3\xa5mesjevuemie.no\0" -"kviteseid.no\0shiftedit.io\0" -"my.id\0we.tc\0" -"tokashiki.okinawa.jp\0" -"mango\0verm\xc3\xb6gensberatung\0scrapping.cc\0" -"wy.us\0" -"neyagawa.osaka.jp\0" -"onflashdrive.app\0" -"flop.jp\0" -"oguchi.aichi.jp\0nanbu.tottori.jp\0" -"horten.no\0equipment\0" -"prd.fr\0koshimizu.hokkaido.jp\0" -"\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x90\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\xa5.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"lib.wy.us\0" -"its.me\0" -"lenug.su\0" -"cloudns.asia\0" -"rodeo\0" -"dvag\0" -"hof.no\0" -"tsuyama.okayama.jp\0" -"tm.ro\0" -"me.in\0dsmynas.com\0" -"tm.se\0imdb\0" -"investments\0framer.app\0" -"he.cn\0" -"toki.gifu.jp\0soo.kagoshima.jp\0kpmg\0" -"foggia.it\0lu.it\0me.it\0" -"urn.arpa\0cruises\0s3.dualstack.eu-west-2.amazonaws.com\0" -"pol.dz\0" -"beskidy.pl\0ninhbinh.vn\0freebox-os.fr\0" -"hirokawa.fukuoka.jp\0" -"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x80\xd1\x83\xd1\x81\0" -"vallee-d-aoste.it\0" -"shingu.hyogo.jp\0hioki.kagoshima.jp\0" -"bunkyo.tokyo.jp\0store.ro\0gonna.jp\0" -"beagleboard.io\0" -"roros.no\0va.us\0" -"me.ke\0s\xc3\xb8r-odal.no\0" -"sling\0" -"rishiri.hokkaido.jp\0" -"kunisaki.oita.jp\0" -"bib.br\0asahi.ibaraki.jp\0" -"gouv.sn\0*.compute-1.amazonaws.com\0" -"nome.cv\0" -"orsta.no\0x.se\0rulez.jp\0" -"zp.gov.pl\0report\0" -"uchinomi.kagawa.jp\0" -"balsan.it\0parallel.jp\0" -"store.st\0vladikavkaz.ru\0" -"obama.fukui.jp\0" -"guardian\0" -"kani.gifu.jp\0weblike.jp\0" -"odo.br\0" -"k12.wa.us\0" -"\xeb\x8b\xb7\xeb\x84\xb7\0" -"larvik.no\0myspreadshop.se\0" -"nichinan.miyazaki.jp\0" -"reklam.hu\0skype\0" -"tochigi.jp\0sn\xc3\xa5sa.no\0d.se\0press\0vladikavkaz.su\0" -"prd.km\0nl.eu.org\0" -"kokonoe.oita.jp\0""1kapp.com\0" -"withgoogle.com\0" -"sejny.pl\0" -"pol.ht\0*.usercontent.goog\0blogspot.com.mt\0" -"katori.chiba.jp\0blogspot.com.ng\0" +"is-an-anarchist.com\0" +"minamiuonuma.niigata.jp\0" +"lund.no\0" +"studio.me-central-1.sagemaker.aws\0" +"moriyoshi.akita.jp\0fedex\0trust\0" +"org.ge\0" +"org.gg\0java\0" +"org.gh\0" +"org.gi\0ws\0" +"bn.it\0auspost\0meinforum.net\0" +"org.gl\0cloudaccess.host\0" +"divttasvuotna.no\0" +"org.gn\0" +"org.gp\0" +"chernovtsy.ua\0staples\0" +"org.gr\0aso.kumamoto.jp\0democrat\0" +"hi.us\0" +"org.gt\0" +"org.gu\0cc.wi.us\0" +"emrstudio-prod.sa-east-1.amazonaws.com\0" +"bg.it\0mukawa.hokkaido.jp\0settsu.osaka.jp\0" +"org.gy\0" +"gob.ar\0" +"org.hk\0ye\0" +"niteroi.br\0" +"sund.no\0edu.eu.org\0" +"org.hn\0" +"ibaraki.jp\0khanhhoa.vn\0" +"warabi.saitama.jp\0" +"charter.aero\0baidu\0" +"org.ht\0" +"org.hu\0ciscofreak.com\0" +"ap.it\0" +"gob.bo\0" +"gmbh\0" +"amli.no\0\xe7\xb6\xb2\xe8\xb7\xaf.tw\0" +"bulsan-suedtirol.it\0longan.vn\0yt\0nordeste-idc.saveincloud.net\0" +"org.il\0kaminokawa.tochigi.jp\0gouv.sn\0" +"org.im\0" +"bhz.br\0ai.in\0org.in\0anan.tokushima.jp\0" +"uk.com\0stage.nodeart.io\0" +"guam.gu\0org.iq\0" +"eco.bj\0org.ir\0iizuka.fukuoka.jp\0pa.leg.br\0" +"org.is\0zm\0" +"gob.cl\0" +"org.je\0s3-website.us-west-2.amazonaws.com\0diskstation.me\0" +"nagano.jp\0" +"nakadomari.aomori.jp\0" +"komforb.se\0notebook.us-gov-east-1.sagemaker.aws\0" +"eco.br\0" +"rovigo.it\0mashiko.tochigi.jp\0\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xa0\xe0\xa4\xa8\0" +"zw\0" +"nakatane.kagoshima.jp\0" +"org.jo\0cc.ut.us\0oncilla.mythic-beasts.com\0" +"taxi.br\0kuji.iwate.jp\0oe.yamagata.jp\0" +"\xe5\xbe\xae\xe5\x8d\x9a\0" +"public-inquiry.uk\0in-dsl.de\0" +"diskstation.eu\0" +"gob.do\0org.kg\0bu.no\0" +"sunagawa.hokkaido.jp\0" +"org.ki\0" +"aoste.it\0wakuya.miyagi.jp\0" +"gob.ec\0" +"umi.fukuoka.jp\0govt.nz\0" +"org.km\0" +"sayama.saitama.jp\0org.kn\0" +"likes-pie.com\0" +"org.kp\0" +"org.la\0" +"org.lb\0hospital\0pb.leg.br\0" +"org.lc\0j.scaleforce.com.cy\0" +"poker\0" +"tsumagoi.gunma.jp\0canon\0" +"org.kw\0k12.wy.us\0" +"org.ky\0" +"bibai.hokkaido.jp\0org.kz\0" +"gob.es\0org.lk\0gs.rl.no\0" +"collegefan.org\0" +"shingu.hyogo.jp\0nakagusuku.okinawa.jp\0" +"fnwk.site\0from-mt.com\0from-nd.com\0" +"matsuura.nagasaki.jp\0on-web.fr\0" +"org.ma\0" +"kokubunji.tokyo.jp\0org.lr\0no-ip.biz\0" +"org.ls\0sula.no\0dyndns-web.com\0" +"org.me\0shaw\0" +"org.lv\0olayangroup\0" +"org.mg\0sogne.no\0troms\xc3\xb8.no\0" +"org.ly\0fedje.no\0" +"org.mk\0" +"varese.it\0hakone.kanagawa.jp\0minowa.nagano.jp\0org.ml\0" +"fauske.no\0" +"kamiizumi.saitama.jp\0org.mn\0" +"org.mo\0" +"basilicata.it\0biei.hokkaido.jp\0" +"org.na\0wpenginepowered.com\0" +"miyagi.jp\0" +"org.ms\0s3-accesspoint.dualstack.eu-west-2.amazonaws.com\0" +"trd.br\0org.mt\0" +"org.mu\0" +"org.mv\0serveblog.net\0" +"org.mw\0org.ng\0" +"kyotango.kyoto.jp\0org.mx\0" +"org.my\0org.ni\0" +"org.mz\0prof.pr\0" +"gob.gt\0aomori.aomori.jp\0" +"r\xc3\xb8yken.no\0business\0" +"eek.jp\0" +"katsuragi.nara.jp\0org.nr\0wroclaw.pl\0" +"chuo.chiba.jp\0goshiki.hyogo.jp\0" +"gob.hn\0iwakuni.yamaguchi.jp\0" +"org.nz\0" +"prod\0" +"org.om\0" +"prof\0" +"ralingen.no\0" +"veneto.it\0takayama.gunma.jp\0aga.niigata.jp\0" +"org.pa\0wales\0" +"xbox\0" +"freebox-os.com\0" +"us.reclaim.cloud\0" +"org.pe\0\xe3\x82\xa2\xe3\x83\x9e\xe3\x82\xbe\xe3\x83\xb3\0" +"org.pf\0" +"org.ph\0" +"org.pk\0" +"org.pl\0" +"malvik.no\0" +"org.pn\0" +"tas.edu.au\0dc.us\0" +"barlettatraniandria.it\0kawara.fukuoka.jp\0katano.osaka.jp\0mibu.tochigi.jp\0" +"m\xc3\xa1tta-v\xc3\xa1rjjat.no\0org.qa\0cc.sc.us\0" +"org.pr\0gdansk.pl\0" +"org.ps\0" +"org.pt\0jotelulu.cloud\0" +"s3.dualstack.cn-northwest-1.amazonaws.com.cn\0" +"*.cloudera.site\0" +"kakamigahara.gifu.jp\0" +"org.py\0" +"gouv.km\0int.eu.org\0" +"backdrop.jp\0" +"a.prod.fastly.net\0" +"express.aero\0frana.no\0statefarm\0notebook.eu-west-2.sagemaker.aws\0" +"nosegawa.nara.jp\0uk.reclaim.cloud\0" +"\xe6\xb7\xa1\xe9\xa9\xac\xe9\x94\xa1\0" +"higashimatsushima.miyagi.jp\0" +"pagefrontapp.com\0" +"mihama.fukui.jp\0hamatama.saga.jp\0" +"togane.chiba.jp\0school\0" +"dyndns-pics.com\0" "tvedestrand.no\0" -"ustka.pl\0from-id.com\0" -"gov.ac\0verdal.no\0" -"gov.ae\0" -"gov.af\0from-ky.com\0" +"dynathome.net\0" +"cipriani\0mytuleap.com\0paris.eu.org\0googlecode.com\0" +"org.ro\0" +"noheji.aomori.jp\0katsuyama.fukui.jp\0" +"org.sa\0githubusercontent.com\0barsy.site\0" +"org.sb\0" +"org.rs\0org.sc\0" +"firm.ht\0kushimoto.wakayama.jp\0org.sd\0" +"askvoll.no\0org.se\0org.ru\0" +"miyoshi.saitama.jp\0" +"org.rw\0org.sg\0s3-fips.dualstack.ca-central-1.amazonaws.com\0" +"org.sh\0" +"meldal.no\0" +"sera.hiroshima.jp\0gouv.ml\0s3-accesspoint.dualstack.cn-north-1.amazonaws.com.cn\0" +"gs.nt.no\0" +"ohda.shimane.jp\0org.sl\0red\0" +"ferrero\0" +"firm.in\0suzuka.mie.jp\0org.sn\0" +"org.so\0shia\0" +"nakamura.kochi.jp\0" +"royrvik.no\0drive\0" +"yamada.fukuoka.jp\0matsushima.miyagi.jp\0\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa6\xb0\xe0\xa6\xa4\0" +"org.ss\0analytics-gateway.us-east-2.amazonaws.com\0user.party.eus\0" +"org.st\0" +"fr\xc3\xb8ya.no\0holtalen.no\0" +"org.sv\0ren\0" +"nagiso.nagano.jp\0" +"veterinaire.km\0org.sy\0cbre\0" +"org.sz\0org.tj\0" +"studio.ap-south-1.sagemaker.aws\0" +"org.tm\0webview-assets.cloud9.eu-north-1.amazonaws.com\0" +"org.tn\0" +"org.to\0gratis\0" +"gob.mx\0" +"gob.ni\0coop.rw\0org.ua\0" +"fukuroi.shizuoka.jp\0ohkura.yamagata.jp\0org.tr\0" +"kushiro.hokkaido.jp\0org.tt\0" +"gop.pk\0org.tw\0org.ug\0writesthisblog.com\0" +"org.uk\0" +"termez.su\0gitapp.si\0" +"firm.co\0" +"sassari.it\0" +"author.aero\0veg\xc3\xa5rshei.no\0org.vc\0auth.eu-north-1.amazoncognito.com\0" +"lovesick.jp\0" +"org.ve\0" +"minamiboso.chiba.jp\0target\0" +"gob.pa\0org.uy\0org.vi\0" +"cesena-forl\xc3\xac.it\0org.uz\0" +"firm.dk\0stuff-4-sale.org\0" +"gallup\0" +"gob.pe\0twmail.cc\0" +"coop.tt\0ai.vn\0org.vn\0" +"arq.br\0" +"dyndns1.de\0" +"unnan.shimane.jp\0" +"gob.pk\0cc.or.us\0mo-siemens.io\0" +"org.vu\0emrstudio-prod.eu-west-1.amazonaws.com\0hostedpi.com\0" +"y.bg\0" +"res.in\0beppu.oita.jp\0" +"\xc3\xa5krehamn.no\0" +"veterinaire.fr\0" +"001www.com\0" +"rel.ht\0sodegaura.chiba.jp\0coop.mv\0boyfriend.jp\0" +"tksat.bo\0coop.mw\0cc.ok.us\0" +"uchinada.ishikawa.jp\0" +"org.ws\0" +"monza-brianza.it\0ril\0" +"kasserver.com\0*.ocp.customer-oci.com\0" +"rio\0" +"rip\0" +"r.bg\0" +"autos\0" +"minamisanriku.miyagi.jp\0" +"snasa.no\0" +"dyndns-server.com\0" +"org.ye\0" +"nagawa.nagano.jp\0geek.nz\0" +"k.bg\0" +"ena.gifu.jp\0ravendb.cloud\0jeez.jp\0" +"apigee.io\0" +"cc.nm.us\0" +"campinas.br\0" +"telebit.io\0" +"org.za\0" +"lom.it\0pi.leg.br\0" +"b\xc3\xa5tsfjord.no\0" +"yusui.kagoshima.jp\0org.yt\0" +"d.bg\0" +"hyundai\0mypi.co\0" +"vestnes.no\0" +"trentin-sued-tirol.it\0" +"wios.gov.pl\0" +"org.zm\0" +"tajiri.osaka.jp\0gob.sv\0shop\0" +"jab.br\0tako.chiba.jp\0takasaki.gunma.jp\0" +"gaivuotna.no\0" +"takatori.nara.jp\0" +"coop.py\0" +"shimokitayama.nara.jp\0" +"show\0studio.us-west-1.sagemaker.aws\0go.dyndns.org\0" +"\xd0\xbc\xd0\xbe\xd1\x81\xd0\xba\xd0\xb2\xd0\xb0\0" +"org.zw\0" +"cc.mo.us\0" +"davvenj\xc3\xa1rga.no\0" +"frosta.no\0khmelnitskiy.ua\0" +"geo.br\0neyagawa.osaka.jp\0pulawy.pl\0" +"morena.br\0kainan.wakayama.jp\0shinjo.yamagata.jp\0" +"dazaifu.fukuoka.jp\0mragowo.pl\0agakhan\0" +"noip.us\0*.s5y.io\0" +"ukiha.fukuoka.jp\0privatizehealthinsurance.net\0" +"gob.ve\0" +"paas.hosted-by-previder.com\0" +"noor.jp\0" +"urakawa.hokkaido.jp\0" +"cc.ma.us\0*.digitaloceanspaces.com\0" +"gosen.niigata.jp\0" +"coop.km\0execute-api.ap-south-1.amazonaws.com\0" +"kuriyama.hokkaido.jp\0" +"web.bo\0" +"raisa.no\0" +"tempio-olbia.it\0eniwa.hokkaido.jp\0fool.jp\0" +"tromsa.no\0" +"friuli-ve-giulia.it\0" +"friuli-v-giulia.it\0" +"nsw.au\0from-or.com\0" +"togitsu.nagasaki.jp\0matsubara.osaka.jp\0" +"web.co\0" +"lom.no\0k12.oh.us\0" +"hachioji.tokyo.jp\0" +"s3-website.dualstack.af-south-1.amazonaws.com\0lon.wafaicloud.com\0" +"cc.ks.us\0is-a-landscaper.com\0" +"realestate.pl\0" +"modalen.no\0" +"sanda.hyogo.jp\0quangnam.vn\0" +"rel.pl\0" +"schoolbus.jp\0" +"web.do\0k12.mo.us\0tires\0" +"haebaru.okinawa.jp\0" +"bas.it\0" +"chonan.chiba.jp\0" +"firm.ve\0" +"3.bg\0\xd1\x83\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0s3-accesspoint-fips.dualstack.us-east-2.amazonaws.com\0" +"lidl\0sap\0" +"sas\0" +"daemon.panel.gg\0" +"sbi\0mircloud.us\0" +"atm.pl\0" +"gratangen.no\0" +"air-traffic-control.aero\0k12.ma.us\0" +"tawaramoto.nara.jp\0" +"act.edu.au\0gs.oslo.no\0" +"scb\0" +"sbs\0" +"autocode.dev\0" +"discourse.group\0" +"abudhabi\0" +"telebit.app\0" +"life\0" +"asahi.nagano.jp\0pe.leg.br\0" +"\xe5\x85\xac\xe5\x8f\xb8.cn\0aogashima.tokyo.jp\0" +"k12.md.us\0" +"sp.gov.br\0" +"sola.no\0gitlab.io\0" +"trentins\xc3\xbc""dtirol.it\0nanbu.tottori.jp\0" +"asuke.aichi.jp\0" +"mihama.aichi.jp\0" +"filegear.me\0" +"monzaebrianza.it\0" +"works.aero\0" +"rome.it\0" +"web.gu\0\xe5\x85\xac\xe5\x8f\xb8.hk\0" +"sydney\0" +"littlestar.jp\0" +"giving\0" +"miyama.mie.jp\0mymediapc.net\0" +"hachinohe.aomori.jp\0observer\0" +"kaluga.su\0" +"gniezno.pl\0pisz.pl\0functions.fnc.fr-par.scw.cloud\0" +"itau\0myspreadshop.com.au\0" +"domains\0" +"web.id\0yotsukaido.chiba.jp\0cloudns.biz\0dynv6.net\0" +"bjarkoy.no\0" +"caobang.vn\0" +"gives\0wpmucdn.com\0" +"run\0mimoza.jp\0za.net\0" +"friuli-venezia-giulia.it\0higashiyamato.tokyo.jp\0web.in\0blush.jp\0" +"emrstudio-prod.us-west-2.amazonaws.com\0" +"salud.bo\0" +"akamaized.net\0" +"firm.ro\0sew\0" +"sex\0" +"pokrovsk.su\0static.observableusercontent.com\0" +"issmarterthanyou.com\0" +"kanra.gunma.jp\0" +"tanabe.wakayama.jp\0" +"s3-website.eu-west-3.amazonaws.com\0" +"sfr\0" +"jewelry\0" +"dev.br\0" +"rwe\0webview-assets.cloud9.ap-northeast-1.amazonaws.com\0ditchyourip.com\0" +"nishiaizu.fukushima.jp\0" +"nord-aurdal.no\0trana.no\0" +"takaishi.osaka.jp\0so.gov.pl\0" +"leirfjord.no\0" +"askim.no\0*.us-east-2.airflow.amazonaws.com\0mircloud.ru\0*.vps.myjino.ru\0" +"uryu.hokkaido.jp\0isehara.kanagawa.jp\0" +"inami.wakayama.jp\0" +"\xe5\x85\xb5\xe5\xba\xab.jp\0" +"lib.wa.us\0vologda.su\0" +"nanyo.yamagata.jp\0" +"mycloud.by\0" +"yamaxun\0" +"trentino-sud-tirol.it\0" +"hanam.vn\0" +"like\0" +"lel.br\0" +"fot.br\0" +"web.lk\0nsupdate.info\0" +"shijonawate.osaka.jp\0yoshimi.saitama.jp\0" +"silk\0" +"fredrikstad.no\0noip.me\0" +"christmas\0" +"minamidaito.okinawa.jp\0" +"noticias.bo\0" +"b\xc3\xb8.telemark.no\0" +"emrnotebooks-prod.us-east-1.amazonaws.com\0s3-fips-us-gov-east-1.amazonaws.com\0" +"firm.nf\0ketrzyn.pl\0" +"harstad.no\0firm.ng\0" +"y.se\0" +"lowicz.pl\0realtor\0" +"kofu.yamanashi.jp\0" +"karacol.su\0" +"shirakawa.fukushima.jp\0" +"sina\0" +"shiriuchi.hokkaido.jp\0" +"praxi\0" +"bunkyo.tokyo.jp\0web.nf\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8b\xe0\xa4\xa4\0" +"lib.ut.us\0" +"tirol\0" +"web.ni\0servehalflife.com\0" +"\xe5\x9f\xbc\xe7\x8e\x89.jp\0" +"r.se\0hs.zone\0" +"ginowan.okinawa.jp\0" +"sklep.pl\0" +"limo\0meteorapp.com\0" +"rackmaze.net\0" +"ski\0" +"k.se\0firewalledreplit.co\0" +"link\0webview-assets.cloud9.us-west-1.amazonaws.com\0" +"ap-southeast-2.elasticbeanstalk.com\0lima-city.de\0" +"auth.il-central-1.amazoncognito.com\0" +"sky\0" +"xj.cn\0ikusaka.nagano.jp\0rulez.jp\0" +"erotika.hu\0d.se\0" +"horokanai.hokkaido.jp\0" +"reggio-calabria.it\0kui.hiroshima.jp\0" +"web.pk\0" +"davvenjarga.no\0" +"demon.nl\0" +"withyoutube.com\0" +"k12.gu.us\0" +"srv.br\0" +"nishikawa.yamagata.jp\0pr.leg.br\0" +"friuli-vegiulia.it\0jobs.tt\0" +"toyako.hokkaido.jp\0" +"lilly\0" +"lima-city.at\0" +"shikokuchuo.ehime.jp\0" +"s3-accesspoint.dualstack.me-central-1.amazonaws.com\0from-vt.com\0" +"agr.br\0" +"microsoft\0channelsdvr.net\0" +"s\xc3\xb8rreisa.no\0we.bs\0" +"fashion\0xx.gl\0" +"tysfjord.no\0" +"koryo.nara.jp\0" +"lease\0" +"misaki.osaka.jp\0" +"\xe7\xa5\x9e\xe5\xa5\x88\xe5\xb7\x9d.jp\0centralus.azurestaticapps.net\0" +"tama.tokyo.jp\0notebook.cn-north-1.sagemaker.com.cn\0lima-city.ch\0" +"crap.jp\0" +"hepforge.org\0" +"k8s.scw.cloud\0" +"ikano\0" +"nara.jp\0" +"emiliaromagna.it\0" +"voagat.no\0spa\0" +"cutegirl.jp\0" +"cc.de.us\0" +"steinkjer.no\0soy\0" +"site\0" +"toolforge.org\0" +"web.tj\0" +"jolster.no\0" +"politica.bo\0plesk.page\0" +"tab\0" +"cloudfunctions.net\0" +"*.0emm.com\0" +"itabashi.tokyo.jp\0web.tr\0" +"3utilities.com\0" +"sr.gov.pl\0easypanel.host\0" +"vfs.cloud9.eu-south-1.amazonaws.com\0" +"tajimi.gifu.jp\0" +"trentin-s\xc3\xbc""d-tirol.it\0sub.jp\0" +"eu.ngrok.io\0" +"\xd8\xb4\xd8\xa8\xd9\x83\xd8\xa9\0net.eu.org\0googleapis.com\0" +"com.ac\0" +"hirara.okinawa.jp\0tax\0" +"web.ve\0s3-accesspoint.eu-south-2.amazonaws.com\0" +"com.af\0forl\xc3\xac-cesena.it\0" +"com.ag\0" +"shonai.fukuoka.jp\0srl\0familyds.net\0" +"com.ai\0" +"kitagata.saga.jp\0" +"emrnotebooks-prod.eu-west-1.amazonaws.com\0" +"com.al\0" +"com.am\0\xe3\x82\xbb\xe3\x83\xbc\xe3\x83\xab\0s3-accesspoint.eu-west-1.amazonaws.com\0notebook.il-central-1.sagemaker.aws\0" +"com.ba\0" +"com.ar\0com.bb\0busan.kr\0" +"oygarden.no\0notebook.ap-south-2.sagemaker.aws\0" +"com.au\0live\0tci\0trading\0mine.nu\0" +"mihama.mie.jp\0" +"com.aw\0" +"com.bh\0" +"com.bi\0s3-website.il-central-1.amazonaws.com\0" +"com.az\0com.bj\0clerk.app\0" +"com.bm\0" +"com.bn\0" +"com.bo\0stc\0" +"\xe7\xb5\x84\xe7\xbb\x87.hk\0" +"com.br\0" +"com.bs\0synology-diskstation.de\0" +"com.bt\0" +"uonuma.niigata.jp\0pya.jp\0" +"skanland.no\0cc.ar.us\0tdk\0" +"kuzumaki.iwate.jp\0gold\0" +"com.by\0com.ci\0rissa.no\0" +"com.bz\0golf\0whm.nl-ams.scw.cloud\0" +"dattolocal.com\0" +"mashike.hokkaido.jp\0jaguar\0typedream.app\0" +"broker.aero\0com.cm\0tunes\0webview-assets.cloud9.sa-east-1.amazonaws.com\0" +"com.cn\0elementor.cloud\0" +"com.co\0zhytomyr.ua\0cust.disrec.thingdust.io\0" +"kumiyama.kyoto.jp\0" +"tana.no\0s3-me-south-1.amazonaws.com\0" +"koto.shiga.jp\0" +"com.cu\0cc.ak.us\0com.de\0" +"com.cv\0jpmorgan\0" +"com.cw\0" +"tel\0" +"com.cy\0" +"barsy.shop\0" +"vfs.cloud9.eu-west-3.amazonaws.com\0" +"com.dm\0lib.pa.us\0" +"komae.tokyo.jp\0yuza.yamagata.jp\0" +"com.do\0scrysec.com\0" +"verona.it\0saito.miyazaki.jp\0" +"hurum.no\0web.za\0" +"com.ec\0emrnotebooks-prod.us-gov-east-1.amazonaws.com\0" +"com.ee\0" +"shinjuku.tokyo.jp\0" +"com.eg\0here-for-more.info\0" +"carrara-massa.it\0pup.gov.pl\0" +"com.dz\0ryugasaki.ibaraki.jp\0" +"sweetpepper.org\0" +"vfs.cloud9.ca-central-1.amazonaws.com\0" +"crotone.it\0" +"com.es\0" +"com.et\0ug.gov.pl\0" +"ws.na\0" +"fyresdal.no\0" +"com.fj\0up.in\0" +"goog\0" +"nakijin.okinawa.jp\0kashima.saga.jp\0" +"com.fm\0" +"vaksdal.no\0" +"thd\0" +"com.fr\0" +"pro.az\0" +"com.ge\0zt.ua\0" +"oi.kanagawa.jp\0" +"orkanger.no\0" +"com.gh\0" +"com.gi\0execute-api.us-gov-west-1.amazonaws.com\0" +"jeep\0" +"pro.br\0com.gl\0fujikawa.yamanashi.jp\0*.beget.app\0" +"com.gn\0\xe9\xa6\x99\xe5\xb7\x9d.jp\0" +"com.gp\0" +"vp4.me\0" +"com.gr\0akadns.net\0" +"emerck\0" +"com.gt\0\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0" +"com.gu\0" +"k12.as.us\0rentals\0" +"com.gy\0" +"isumi.chiba.jp\0" +"com.hk\0" +"tr.it\0" +"karasjok.no\0" +"com.hn\0" +"porsanger.no\0" +"com.hr\0" +"show.aero\0pro.cy\0studio.eu-central-1.sagemaker.aws\0" +"com.ht\0" +"windows\0execute-api.ap-southeast-1.amazonaws.com\0" +"qc.ca\0" +"playstation\0" +"higashikagawa.kagawa.jp\0suwa.nagano.jp\0ogi.saga.jp\0" +"pro.ec\0com.im\0" +"com.in\0" +"com.io\0dubai\0" +"wsse.gov.pl\0" +"com.iq\0hapmir.no\0" +"kuroiso.tochigi.jp\0" +"com.is\0homesecuritypc.com\0dev.vu\0" +"tjx\0" +"vallee-aoste.it\0" +"in-the-band.net\0" +"s3-object-lambda.ap-southeast-2.amazonaws.com\0" +"com.jo\0volda.no\0" +"pe.ca\0kv\xc3\xa6nangen.no\0" +"pro.fj\0" +"nsw.edu.au\0notebook.ap-southeast-3.sagemaker.aws\0" +"com.kg\0" +"kazuno.akita.jp\0akamai-staging.net\0" +"com.ki\0from-in.com\0" +"ullensaker.no\0" +"og.ao\0com.km\0lib.mi.us\0" +"vet.br\0deno-staging.dev\0" +"execute-api.me-central-1.amazonaws.com\0" +"com.kp\0" +"on.ca\0com.la\0" +"com.lb\0" +"com.lc\0" +"onagawa.miyagi.jp\0" +"com.kw\0" +"niihama.ehime.jp\0saiki.oita.jp\0" +"com.ky\0" +"omitama.ibaraki.jp\0com.kz\0" +"com.lk\0cloudns.eu\0ro.im\0" +"s3-accesspoint.ap-southeast-3.amazonaws.com\0" +"hino.tokyo.jp\0" +"komvux.se\0" +"jeonbuk.kr\0" +"motorcycles\0" +"ro.it\0com.lr\0" +"utsira.no\0" +"com.lv\0" +"com.mg\0tr.no\0" +"com.ly\0fjell.no\0med.pro\0" +"fuji.shizuoka.jp\0discount\0" +"com.mk\0" +"abruzzo.it\0com.ml\0floppy.jp\0" +"pro.ht\0" +"com.mo\0" +"com.na\0" +"com.ms\0" +"com.mt\0" +"com.mu\0we.tc\0" +"com.mv\0com.nf\0" +"homebuilt.aero\0com.mw\0com.ng\0" +"pro.in\0com.mx\0" +"com.my\0com.ni\0lviv.ua\0" +"sjc.br\0miharu.fukushima.jp\0*.stg.dev\0" +"top\0" +"ra.it\0" +"stavanger.no\0sebastopol.ua\0" +"higashiagatsuma.gunma.jp\0nankoku.kochi.jp\0" +"toyota.yamaguchi.jp\0com.nr\0" +"st.no\0" +"\xe9\x95\xb7\xe5\xb4\x8e.jp\0u.channelsdvr.net\0" +"b\xc3\xa1jddar.no\0" +"nb.ca\0withgoogle.com\0h\xc3\xa4kkinen.fi\0" +"kaneyama.fukushima.jp\0" +"pz.it\0" +"federation.aero\0hurdal.no\0k\xc3\xa5""fjord.no\0com.om\0careers\0is-lost.org\0" +"shingo.aomori.jp\0" +"*.linodeobjects.com\0panel.gg\0" +"jele.cloud\0" +"com.pa\0vn.ua\0" +"esp.br\0kariwa.niigata.jp\0" +"intuit\0cloudns.in\0linkyard-cloud.ch\0" +"com.pe\0" +"toki.gifu.jp\0shimonita.gunma.jp\0com.pf\0" +"tokke.no\0" +"com.ph\0" +"hornindal.no\0" +"to.gov.br\0carboniaiglesias.it\0" +"com.pk\0" +"com.pl\0" +"snoasa.no\0za.org\0" +"boavista.br\0wegrow.pl\0tn.oxa.cloud\0" +"sf.no\0" +"assn.lk\0stat.no\0com.qa\0" +"com.pr\0" +"com.ps\0s3-1.amazonaws.com\0" +"com.pt\0" +"style\0" +"tomi.nagano.jp\0" +"com.py\0cloudns.cc\0" +"washtenaw.mi.us\0" +"md.ci\0notebook.eu-south-1.sagemaker.aws\0" +"law.pro\0cards\0ubs\0vfs.cloud9.sa-east-1.amazonaws.com\0lug.org.uk\0" +"beagleboard.io\0" +"fermo.it\0trv\0" +"bayern\0" +"com.re\0" +"pe.it\0" +"iwata.shizuoka.jp\0pecori.jp\0" +"d\xc3\xb8nna.no\0" +"\xe5\xba\x83\xe5\xb3\xb6.jp\0" +"pro.na\0" +"lib.ia.us\0\xe5\xa4\xa9\xe4\xb8\xbb\xe6\x95\x99\0is-a-designer.com\0" +"com.ro\0" +"kikonai.hokkaido.jp\0fukaya.saitama.jp\0pro.mv\0" +"com.sa\0" +"com.sb\0" +"com.sc\0" +"com.sd\0" +"malselv.no\0pub.sa\0com.se\0com.ru\0" +"kuju.oita.jp\0" +"com.sg\0" +"caltanissetta.it\0tamano.okayama.jp\0com.sh\0" +"s3.af-south-1.amazonaws.com\0notebook-fips.us-gov-west-1.sagemaker.aws\0" +"asahi.toyama.jp\0*.hosting.ovh.net\0" +"nagareyama.chiba.jp\0com.sl\0" +"mutual.ar\0com.sn\0" +"com.so\0tec.mi.us\0" +"trentino-aadige.it\0" +"og.it\0" +"com.ss\0lighting\0azerbaijan.su\0" +"susaki.kochi.jp\0pe.kr\0com.st\0" +"tui\0" +"com.sv\0" +"pro.om\0studio.us-gov-west-1.sagemaker.aws\0" +"komaki.aichi.jp\0" +"granvin.no\0com.sy\0" +"ookuwa.nagano.jp\0com.tj\0" +"\xe5\x95\x86\xe6\xa0\x87\0" +"com.tm\0" +"my.id\0com.tn\0" +"com.to\0" +"skin\0" +"com.ua\0" +"com.tr\0" +"b\xc3\xa1l\xc3\xa1t.no\0s3-object-lambda.eu-central-1.amazonaws.com\0s3-object-lambda.me-south-1.amazonaws.com\0from-oh.com\0" +"sukagawa.fukushima.jp\0com.tt\0" +"\xe5\xb1\xb1\xe6\xa2\xa8.jp\0cern\0" +"com.tw\0com.ug\0" +"aknoluokta.no\0us.ngrok.io\0" +"jx.cn\0andria-trani-barletta.it\0" +"notodden.no\0" +"pro.pr\0" +"orsta.no\0" +"tvs\0" +"shiogama.miyagi.jp\0limanowa.pl\0" +"oumu.hokkaido.jp\0kouzushima.tokyo.jp\0" +"gloppen.no\0sm.ua\0com.vc\0dyn53.io\0" +"com.ve\0streamlitapp.com\0" +"osaka.jp\0" +"com.uy\0com.vi\0" +"com.uz\0" +"biev\xc3\xa1t.no\0" +"kapsi.fi\0myds.me\0" +"com.vn\0mydatto.net\0" +"kariya.aichi.jp\0gets-it.net\0" +"h\xc3\xa5.no\0rade.no\0sk\xc3\xa1nit.no\0rv.ua\0" +"balashov.su\0" +"trani-barletta-andria.it\0fudai.iwate.jp\0" +"com.vu\0mypets.ws\0" +"vda.it\0\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0" +"*.nom.br\0" +"elementor.cool\0" +"tj\xc3\xb8me.no\0" +"v\xc3\xa5gs\xc3\xb8y.no\0com.ws\0" +"repair\0" +"aquarelle\0tuva.su\0" +"lt.it\0myamaze.net\0" +"miyawaka.fukuoka.jp\0" +"auth.us-east-1.amazoncognito.com\0" +"livorno.it\0torun.pl\0" +"ekloges.cy\0com.ye\0" +"\xe5\xb3\xb6\xe6\xa0\xb9.jp\0foundation\0" +"\xe0\xae\x87\xe0\xae\xb2\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xaf\x88\0" +"hyllestad.no\0" +"taiji.wakayama.jp\0" +"winners\0" +"pro.tt\0" +"trycloudflare.com\0" +"hongo.hiroshima.jp\0" +"austevoll.no\0" +"studio.ap-northeast-3.sagemaker.aws\0" +"africa.bj\0it1.eur.aruba.jenv-aruba.cloud\0" +"s3.ap-northeast-3.amazonaws.com\0" +"*.user.localcert.dev\0" +"stokke.no\0com.zm\0" +"hn.cn\0izumozaki.niigata.jp\0" +"obninsk.su\0" +"messerli.app\0" +"sorreisa.no\0q-a.eu.org\0" +"riopreto.br\0hiphop\0" +"site.tb-hosting.com\0" +"kaisei.kanagawa.jp\0higashiomi.shiga.jp\0comcast\0penne.jp\0" +"mr.no\0alibaba\0" +"pro.vn\0" +"catania.it\0\xe5\xb2\xa9\xe6\x89\x8b.jp\0kitakata.fukushima.jp\0" +"google\0" +"adobeioruntime.net\0" +"kitanakagusuku.okinawa.jp\0" +"balestrand.no\0is-very-bad.org\0s3.teckids.org\0" +"yamakita.kanagawa.jp\0test.tj\0" +"\xc3\xb8ksnes.no\0in-brb.de\0*.nodebalancer.linode.com\0" +"friulive-giulia.it\0yashio.saitama.jp\0" +"pl.ua\0" +"takasago.hyogo.jp\0" +"\xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\0" +"bsb.br\0appengine.flow.ch\0" +"cloudns.us\0" +"iz.hr\0" +"chikusei.ibaraki.jp\0" +"from-ct.com\0" +"nabari.mie.jp\0" +"*.eu-north-1.airflow.amazonaws.com\0" +"1kapp.com\0" +"ebetsu.hokkaido.jp\0noto.ishikawa.jp\0" +"vps.mcdir.ru\0lib.de.us\0" +"\xe5\xae\xb6\xe9\x9b\xbb\0s3.eu-south-2.amazonaws.com\0cloudcontrolapp.com\0" +"ballangen.no\0sellfy.store\0" +"thanhphohochiminh.vn\0cat.ax\0" "uno\0" -"locker\0" -"airtel\0pfizer\0" -"hosting\0" -"gov.al\0vp4.me\0" -"cremona.it\0aichi.jp\0prd.mg\0" -"trani-barletta-andria.it\0" -"gov.ba\0!city.yokohama.jp\0elasticbeanstalk.com\0" +"palermo.it\0" +"iservschule.de\0shopitsite.com\0" +"buzz\0" +"\xe4\xb8\xaa\xe4\xba\xba.hk\0" +"cooperativa.bo\0" +"ms.leg.br\0" +"\xd0\xb0\xd0\xba.\xd1\x81\xd1\x80\xd0\xb1\0emrappui-prod.eu-west-3.amazonaws.com\0" +"yokosuka.kanagawa.jp\0szkola.pl\0uol\0smartlabeling.scw.cloud\0" +"ghost.io\0" +"is.it\0" +"gitpage.si\0" +"bss.design\0" +"laakesvuemie.no\0police.uk\0test.ru\0" +"lenvik.no\0emrstudio-prod.ap-east-1.amazonaws.com\0" +"jele.club\0" +"dnepropetrovsk.ua\0" +"koga.fukuoka.jp\0" +"gs.jan-mayen.no\0" +"fujimi.nagano.jp\0" +"v\xc3\xa5ler.\xc3\xb8stfold.no\0simplesite.com\0" +"anan.nagano.jp\0" +"cci.fr\0" +"v-info.info\0" +"ups\0" +"egoism.jp\0" +"dyndns-office.com\0" +"mt.leg.br\0" +"insurance.aero\0webview-assets.cloud9.ap-northeast-3.amazonaws.com\0" +"otsuchi.iwate.jp\0" +"dynamisches-dns.de\0" +"tsubetsu.hokkaido.jp\0" +"s\xc3\xb8rum.no\0" +"rexroth\0" +"app.render.com\0" +"hair\0" +"supplies\0tr.eu.org\0mayfirst.org\0" +"sowa.ibaraki.jp\0" +"hasuda.saitama.jp\0" +"ichikawa.hyogo.jp\0" +"fam.pk\0" +"res.aero\0\xd1\x81\xd0\xbf\xd0\xb1.\xd1\x80\xd1\x83\xd1\x81\0" +"mk.ua\0" +"xii.jp\0" +"kindle\0" +"kitakami.iwate.jp\0*.lcl.dev\0" +"boomla.net\0" +"mil.ac\0alsace\0" +"kawahara.tottori.jp\0" +"mil.ae\0" +"jampa.br\0tenei.fukushima.jp\0lezajsk.pl\0" +"vfs.cloud9.ap-east-1.amazonaws.com\0" +"kyowa.akita.jp\0" +"s3.ap-south-2.amazonaws.com\0" +"honjyo.akita.jp\0nakatombetsu.hokkaido.jp\0kitayama.wakayama.jp\0ostrowiec.pl\0j.scaleforce.net\0" +"lt.ua\0" +"mil.al\0andria-barletta-trani.it\0uwajima.ehime.jp\0" +"sport\0" +"vana\0" +"takahagi.ibaraki.jp\0" +"mil.ba\0" +"mil.ar\0vall\xc3\xa9""e-d-aoste.it\0" +"chiyoda.tokyo.jp\0" +"ann-arbor.mi.us\0" +"\xe0\xb8\xa8\xe0\xb8\xb6\xe0\xb8\x81\xe0\xb8\xa9\xe0\xb8\xb2.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"mil.az\0pavia.it\0" +"\xe0\xa6\xad\xe0\xa6\xbe\xe0\xa7\xb0\xe0\xa6\xa4\0" +"md.us\0s3-website.dualstack.eu-west-1.amazonaws.com\0" +"cq.cn\0kawakami.nara.jp\0tochigi.tochigi.jp\0digick.jp\0" +"mil.bo\0" +"nagaoka.niigata.jp\0" +"mil.br\0fr.it\0yatsuka.shimane.jp\0definima.net\0" +"vet\0" +"kv.ua\0" +"mil.by\0skedsmokorset.no\0zhitomir.ua\0url.tw\0" +"heteml.net\0" +"s3.me-central-1.amazonaws.com\0" +"mil.cl\0eu.int\0perugia.it\0" +"mil.cn\0" +"mil.co\0odesa.ua\0phone\0" +"ichinohe.iwate.jp\0higashiosaka.osaka.jp\0slupsk.pl\0" +"lur\xc3\xb8y.no\0familyds.org\0" +"mil.cy\0" +"cam.it\0shimonoseki.yamaguchi.jp\0" +"midtre-gauldal.no\0" +"bozen-sudtirol.it\0ryuoh.shiga.jp\0" +"ichinomiya.chiba.jp\0" +"mil.do\0" +"be.ax\0" +"industries\0" +"powiat.pl\0" +"mil.ec\0kh.ua\0" +"chips.jp\0oxa.cloud\0" +"mil.eg\0skanit.no\0" +"katsuura.chiba.jp\0" +"s3-website.dualstack.us-east-1.amazonaws.com\0" +"miyoshi.hiroshima.jp\0" +"miyoshi.aichi.jp\0" +"no-ip.ca\0" +"inazawa.aichi.jp\0" +"cloudns.pw\0" +"nz.basketball\0" +"sumy.ua\0" +"himeshima.oita.jp\0" +"dnsdojo.org\0" +"h\xc3\xa1""bmer.no\0vig\0" +"mil.fj\0" +"pictet\0" +"vin\0" +"shinshinotsu.hokkaido.jp\0starachowice.pl\0vip\0" +"is-a-anarchist.com\0" +"kep.tr\0" +"mil.ge\0" +"higashiyama.kyoto.jp\0" +"mil.gh\0" +"kinghost.net\0" +"toshiba\0vfs.cloud9.ap-northeast-1.amazonaws.com\0servehumour.com\0" +"thruhere.net\0" +"shinjo.nara.jp\0" +"hekinan.aichi.jp\0futsu.nagasaki.jp\0" +"r\xc3\xa5""de.no\0" +"mil.gt\0" +"blockbuster\0" +"r\xc3\xa6lingen.no\0" +"shizuoka.jp\0rs.webaccel.jp\0" +"s3.dualstack.us-east-1.amazonaws.com\0" +"zlg.br\0" +"okawa.kochi.jp\0inagi.tokyo.jp\0phutho.vn\0" +"omega\0""180r.com\0" +"mil.hn\0" +"sande.m\xc3\xb8re-og-romsdal.no\0clothing\0" +"gyokuto.kumamoto.jp\0namegawa.saitama.jp\0fukumitsu.toyama.jp\0" +"valleaosta.it\0" +"roros.no\0studio.ap-southeast-1.sagemaker.aws\0" +"mil.id\0eiheiji.fukui.jp\0" +"nanto.toyama.jp\0" +"voyage\0" +"aarp\0" +"ie.ua\0" +"cc.hn\0" +"azure-mobile.net\0" +"il.us\0" +"mil.in\0gorizia.it\0ens.tn\0" +"mil.iq\0vestby.no\0globo\0" +"bz.it\0" +"alesund.no\0barsyonline.co.uk\0" +"kure.hiroshima.jp\0" +"sk\xc3\xa5nland.no\0emrnotebooks-prod.eu-west-3.amazonaws.com\0" +"herad.no\0bo.telemark.no\0organic\0photo\0" +"togo.aichi.jp\0" +"nohost.me\0" +"servebbs.net\0" +"mil.jo\0stord.no\0" +"bs.it\0fukuchiyama.kyoto.jp\0peewee.jp\0" +"notebook-fips.us-east-2.sagemaker.aws\0be.gy\0" +"winb.gov.pl\0" +"mil.kg\0ybo.review\0" +"cdn77-ssl.net\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.\xe9\xa6\x99\xe6\xb8\xaf\0orange\0" +"kisarazu.chiba.jp\0" +"kawazu.shizuoka.jp\0wif.gov.pl\0" +"mil.km\0haus\0" +"bl.it\0mie.jp\0" +"kitagawa.kochi.jp\0" +"studio.eu-west-2.sagemaker.aws\0" +"mil.kr\0" +"maringa.br\0shiraoka.saitama.jp\0" +"outsystemscloud.com\0" +"\xe5\xa5\x88\xe8\x89\xaf.jp\0" +"ecologia.bo\0movimiento.bo\0gs.tm.no\0bharti\0sa.com\0" +"otaki.nagano.jp\0mil.kz\0" +"myddns.rocks\0" +"takamori.nagano.jp\0" +"s3-sa-east-1.amazonaws.com\0" +"bio.br\0" +"storfjord.no\0s3-object-lambda.ap-south-2.amazonaws.com\0" +"mil.lv\0buyshouses.net\0redirectme.net\0" +"szex.hu\0mil.mg\0batsfjord.no\0auth.us-west-2.amazoncognito.com\0" +"kanazawa.ishikawa.jp\0" +"an.it\0" +"dyn.ddnss.de\0ashgabad.su\0" +"cdn-edges.net\0" +"genting\0" +"tagajo.miyagi.jp\0" +"luster.no\0cc.vi.us\0" +"mil.mv\0" +"mil.ng\0fedorapeople.org\0" +"ag.it\0" +"mil.my\0mil.ni\0" +"mil.mz\0" +"annaka.gunma.jp\0" +"cc.na\0halden.no\0hitachi\0" +"mil.no\0" +"shioya.tochigi.jp\0myspreadshop.nl\0" +"from-mo.com\0" +"hungry.jp\0" +"myspreadshop.no\0" +"r\xc3\xa5holt.no\0" +"koza.wakayama.jp\0" +"oshu.iwate.jp\0" +"saogonca.br\0niiza.saitama.jp\0mil.nz\0principe.st\0" +"higashi.okinawa.jp\0" +"mandal.no\0" +"mil.pe\0net-freaks.com\0" +"s3-eu-north-1.amazonaws.com\0syno-ds.de\0" +"yamagata.gifu.jp\0mil.ph\0" +"mil.pl\0" +"barclays\0" +"is-very-good.org\0" +"ishikawa.jp\0tsuno.kochi.jp\0myspreadshop.pl\0" +"city.hu\0\xc3\xb8stre-toten.no\0mil.qa\0\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0emrappui-prod.us-gov-west-1.amazonaws.com\0" +"select\0" +"jeju.kr\0" +"in-dsl.org\0" +"mil.py\0jpn.org\0" +"campinagrande.br\0" +"k12.ec\0vestvagoy.no\0*.ap-southeast-2.airflow.amazonaws.com\0" +"chernihiv.ua\0uk.eu.org\0" +"venezia.it\0gsm.pl\0\xe0\xb4\xad\xe0\xb4\xbe\xe0\xb4\xb0\xe0\xb4\xa4\xe0\xb4\x82\0leczna.pl\0" +"jc.neen.it\0" +"studio.ap-east-1.sagemaker.aws\0" +"fujikawa.shizuoka.jp\0binhduong.vn\0" +"wed\0" +"k12.wi.us\0kyoto\0" +"nakaniikawa.toyama.jp\0myspreadshop.it\0" +"loab\xc3\xa1t.no\0" +"usui.fukuoka.jp\0" +"my-gateway.de\0" +"pippu.hokkaido.jp\0" +"able\0*.triton.zone\0opensocial.site\0" +"is-a-doctor.com\0" +"notebook.ap-northeast-3.sagemaker.aws\0" +"tone.ibaraki.jp\0chat\0" +"notebook.ap-southeast-1.sagemaker.aws\0cx.ua\0" +"education\0" +"press\0mil.ru\0" +"sampa.br\0higashine.yamagata.jp\0" +"mil.rw\0" +"mil.sh\0" +"enscaled.sg\0" +"restaurant.bj\0cuiaba.br\0" +"s3-website.dualstack.ap-south-1.amazonaws.com\0s3.eu-central-1.amazonaws.com\0is-a-bulls-fan.com\0" +"westeurope.azurestaticapps.net\0" +"gentlentapis.com\0" +"from-ny.net\0" +"bydgoszcz.pl\0" +"gleeze.com\0" +"s3-website.eu-west-2.amazonaws.com\0" +"mil.st\0" +"s3.dualstack.us-gov-west-1.amazonaws.com\0" +"zpisdn.gov.pl\0" +"mil.sy\0" +"cieszyn.pl\0mil.tj\0" +"l\xc3\xa1hppi.no\0co.events\0" +"mil.tm\0" +"kvinnherad.no\0mil.to\0notebook.af-south-1.sagemaker.aws\0" +"rj.gov.br\0" +"gub.uy\0" +"mil.tr\0" +"aktyubinsk.su\0" +"\xe6\xbb\x8b\xe8\xb3\x80.jp\0kasama.ibaraki.jp\0lamdong.vn\0" +"s3-accesspoint.dualstack.ap-southeast-4.amazonaws.com\0" +"mil.tw\0" +"selfip.info\0" +"mil.tz\0" +"sakura.tochigi.jp\0" +"revista.bo\0mo-i-rana.no\0cc.ua\0us.org\0" +"afjord.no\0luroy.no\0" +"rishiri.hokkaido.jp\0" +"mil.vc\0" +"k12.il\0" +"mil.ve\0" +"\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0" +"*.tst.site\0" +"achi.nagano.jp\0" +"navuotna.no\0mil.uy\0eu-west-2.elasticbeanstalk.com\0" +"minamata.kumamoto.jp\0" +"yamanakako.yamanashi.jp\0targi.pl\0" +"k12.tx.us\0emrnotebooks-prod.us-east-2.amazonaws.com\0secaas.hk\0" +"goip.de\0virtualserver.io\0" +"rec.br\0win\0de.trendhosting.cloud\0" +"nakai.kanagawa.jp\0ondigitalocean.app\0" +"sauda.no\0" +"webview-assets.aws-cloud9.eu-south-1.amazonaws.com\0*.awdev.ca\0" +"ownip.net\0" +"country\0" +"laocai.vn\0eurovision\0it1.jenv-aruba.cloud\0" +"norddal.no\0s3-accesspoint.af-south-1.amazonaws.com\0" +"hitachinaka.ibaraki.jp\0" +"rec.co\0" +"akamai.net\0" +"abashiri.hokkaido.jp\0" +"s3-deprecated.us-east-1.amazonaws.com\0dyndns-remote.com\0" +"from-az.net\0" +"accountant\0" +"koobin.events\0" +"ikeda.hokkaido.jp\0worse-than.tv\0" +"republican\0" +"nhlfan.net\0" +"mel\xc3\xb8y.no\0mil.ye\0ufcfan.org\0" +"kobierzyce.pl\0" +"eu.encoway.cloud\0" +"gon.pk\0*.on-rio.io\0" +"kunigami.okinawa.jp\0nirasaki.yamanashi.jp\0" +"vestre-toten.no\0""123sait.ru\0" +"a.run.app\0" +"mil.za\0" +"ishikawa.fukushima.jp\0" +"kashiba.nara.jp\0" +"scientist.aero\0wme\0" +"yoshinogari.saga.jp\0hoabinh.vn\0" +"yahaba.iwate.jp\0" +"mil.zm\0" +"genoa.it\0nagatoro.saitama.jp\0" +"messwithdns.com\0" +"hosting-cluster.nl\0" +"official.academy\0" +"surgery\0" +"ayase.kanagawa.jp\0azurestaticapps.net\0" +"eng.pro\0club.tw\0mil.zw\0" +"aaa.pro\0studio.ca-central-1.sagemaker.aws\0myspreadshop.se\0" +"karatsu.saga.jp\0" +"bozen-suedtirol.it\0yatomi.aichi.jp\0" +"w.bg\0" +"dyndns.biz\0" +"sunndal.no\0dnsfor.me\0" +"cc.ny.us\0" +"\xe5\xb1\xb1\xe5\xbd\xa2.jp\0" +"nh-serv.co.uk\0" +"*.usercontent.goog\0" +"aetna\0" +"p.bg\0" +"itayanagi.aomori.jp\0sncf\0yandexcloud.net\0" +"s3-fips.us-east-1.amazonaws.com\0" +"slask.pl\0" +"nakamichi.yamanashi.jp\0" +"raffleentry.org.uk\0" +"kashihara.nara.jp\0" +"sevastopol.ua\0wow\0virtualuser.de\0" +"i.bg\0schule\0" +"kami.miyagi.jp\0" +"macerata.it\0" +"mokuren.ne.jp\0" +"anani.br\0uozu.toyama.jp\0wkz.gov.pl\0" +"airport.aero\0" +"rugby\0" +"holdings\0" +"shiki.saitama.jp\0" +"b.bg\0" +"iwi.nz\0" +"webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com\0" +"cc.mt.us\0cc.nd.us\0" +"skjak.no\0webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com\0" +"suifu.ibaraki.jp\0mincom.tn\0" +"mckinsey\0" +"b.br\0sabae.fukui.jp\0" +"kitaura.miyazaki.jp\0" +"is-a-cubicle-slave.com\0" +"wakasa.fukui.jp\0" +"pramerica\0myftp.org\0" +"vlaanderen\0" +"playstation-cloud.com\0" +"tsukigata.hokkaido.jp\0" +"jelastic.saveincloud.net\0" +"kani.gifu.jp\0hidaka.kochi.jp\0" +"namikata.ehime.jp\0" +"mihama.chiba.jp\0" +"cust.testing.thingdust.io\0" +"s3-accesspoint.eu-west-2.amazonaws.com\0" +"oiso.kanagawa.jp\0" +"emrnotebooks-prod.eu-south-1.amazonaws.com\0eu-south-1.elasticbeanstalk.com\0" +"wtc\0" +"h\xc3\xb8yanger.no\0webview-assets.cloud9.ap-southeast-2.amazonaws.com\0" +"wtf\0s3-website.nl-ams.scw.cloud\0" +"k12.tr\0" +"int.ar\0kadena.okinawa.jp\0" +"dyn-vpn.de\0" +"stordal.no\0cust.retrosnub.co.uk\0" +"kuromatsunai.hokkaido.jp\0" +"\xc3\xa5rdal.no\0lipsy\0" +"shiso.hyogo.jp\0" +"sa.gov.au\0" +"int.az\0rec.nf\0computer\0dnsdojo.net\0" +"empresa.bo\0finance\0" +"tabayama.yamanashi.jp\0" +"bozen-s\xc3\xbc""dtirol.it\0s3-object-lambda.cn-north-1.amazonaws.com.cn\0" +"int.bo\0" +"berlev\xc3\xa5g.no\0vaporcloud.io\0" +"tomioka.gunma.jp\0" +"works\0loseyourip.com\0" +"world\0" +"k12.nv.us\0k12.vi\0emrstudio-prod.ap-northeast-1.amazonaws.com\0" +"int.ci\0" +"toyo.kochi.jp\0vpndns.net\0" +"cc.la.us\0s3.ap-northeast-1.amazonaws.com\0studio.sa-east-1.sagemaker.aws\0" +"\xe0\xb8\x98\xe0\xb8\xb8\xe0\xb8\xa3\xe0\xb8\x81\xe0\xb8\xb4\xe0\xb8\x88.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"virgin\0watson.jp\0halfmoon.jp\0" +"int.co\0" +"nago.okinawa.jp\0" +"nikko.tochigi.jp\0static-access.net\0" +"8.bg\0storebase.store\0" +"suita.osaka.jp\0" +"k12.ne.us\0fantasyleague.cc\0" +"int.cv\0" +"andebu.no\0" +"ranzan.saitama.jp\0bona.jp\0" +"\xe3\x83\x95\xe3\x82\xa1\xe3\x83\x83\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0dattoweb.com\0" +"inf.br\0namie.fukushima.jp\0katsuragi.wakayama.jp\0" +"bokn.no\0" +"1.bg\0" +"k12.nh.us\0jelastic.team\0" +"tarui.gifu.jp\0" +"rr.gov.br\0" +"volvo\0tech.orange\0" +"abira.hokkaido.jp\0ikeda.nagano.jp\0" +"dyndns-ip.com\0" +"*.bd\0massa-carrara.it\0hagiang.vn\0" +"novara.it\0\xe5\x92\x8c\xe6\xad\x8c\xe5\xb1\xb1.jp\0" +"inf.cu\0college\0" +"aizuwakamatsu.fukushima.jp\0" +"benevento.it\0semine.miyagi.jp\0" +"komatsu\0" +"vardo.no\0is-a-rockstar.com\0" +"capoo.jp\0" +"emrappui-prod.eu-west-1.amazonaws.com\0" +"firewall-gateway.net\0" +"myspreadshop.es\0" +"oshima.yamaguchi.jp\0" +"lib.ee\0siiites.com\0" +"chikuhoku.nagano.jp\0netgamers.jp\0" +"holy.jp\0" +"*.ck\0asnes.no\0h\xc3\xa6gebostad.no\0rec.ro\0damnserver.com\0myspreadshop.fi\0" +"taranto.it\0ninohe.iwate.jp\0" +"webview-assets.aws-cloud9.ap-south-1.amazonaws.com\0" +"rs.gov.br\0sc.gov.br\0xin\0perma.jp\0" +"in-vpn.de\0loginto.me\0" +"savona.it\0*.stgstage.dev\0" +"wmcloud.org\0ybo.science\0" +"s3.eu-west-1.amazonaws.com\0" +"myspreadshop.fr\0" +"k12.la.us\0" +"frei.no\0" +"b\xc3\xa1hccavuotna.no\0cc.in.us\0" +"hashima.gifu.jp\0" +"s3-eu-west-1.amazonaws.com\0" +"dongthap.vn\0a.ssl.fastly.net\0" +"gs.fm.no\0" +"kasugai.aichi.jp\0" +"ocelot.mythic-beasts.com\0" +"s3.dualstack.us-gov-east-1.amazonaws.com\0" +"yao.osaka.jp\0przeworsk.pl\0\xe0\xb8\xa3\xe0\xb8\xb1\xe0\xb8\x90\xe0\xb8\x9a\xe0\xb8\xb2\xe0\xb8\xa5.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"api.stdlib.com\0" +"mein-iserv.de\0" +"*.er\0" +"stranda.no\0" +"homeftp.org\0" +"int.in\0kontum.vn\0" +"myspreadshop.ie\0" +"i.ng\0" +"*.fk\0int.is\0" +"florist\0" +"\xc3\xb8rland.no\0" +"det.br\0" +"rec.ve\0airbus\0" +"cc.hi.us\0nalchik.ru\0" +"legal\0myspreadshop.at\0" +"riik.ee\0aurskog-h\xc3\xb8land.no\0framer.website\0cloud.interhostsolutions.be\0myspreadshop.be\0" +"kasahara.gifu.jp\0" +"muosat.no\0\xeb\x8b\xb7\xeb\x84\xb7\0boldlygoingnowhere.org\0homelink.one\0" +"tateyama.chiba.jp\0taketomi.okinawa.jp\0daynight.jp\0" +"airkitapps.com\0" +"kawakami.nagano.jp\0" +"meloy.no\0s3-accesspoint.ap-southeast-2.amazonaws.com\0" +"trani-andria-barletta.it\0seiro.niigata.jp\0" +"safety\0s3.dualstack.ap-southeast-4.amazonaws.com\0nalchik.su\0myspreadshop.ca\0" +"limited\0static.land\0" +"grocery\0" +"int.la\0" +"def.br\0setouchi.okayama.jp\0i.ph\0curv.dev\0myspreadshop.ch\0" +"hdfc\0" +"qld.edu.au\0" +"kamoenai.hokkaido.jp\0ooshika.nagano.jp\0" +"mymailer.com.tw\0" +"loan\0" +"int.lk\0stockholm\0" +"dni.us\0" +"intl.tn\0ric.jelastic.vps-host.net\0" +"heroy.more-og-romsdal.no\0lib.va.us\0myspreadshop.de\0" +"trentinosuedtirol.it\0" +"puglia.it\0mikawa.yamagata.jp\0" +"w.se\0" +"hyogo.jp\0" +"myspreadshop.dk\0" +"rn.gov.br\0" +"agematsu.nagano.jp\0in-dsl.net\0" +"adygeya.su\0" +"udine.it\0" +"office-on-the.net\0" +"csx.cc\0" +"p.se\0bridgestone\0" +"fuchu.hiroshima.jp\0" +"infiniti\0" +"laspezia.it\0" +"*.jm\0commbank\0" +"int.mv\0""7.azurestaticapps.net\0" +"int.mw\0inder\xc3\xb8y.no\0" +"int.ni\0" +"azure\0barsy.online\0novecore.site\0" +"s3-accesspoint.dualstack.ap-northeast-1.amazonaws.com\0" +"i.se\0azimuth.network\0" +"*.kh\0hotmail\0" +"honbetsu.hokkaido.jp\0" +"estate\0" +"netbank\0servebbs.org\0" +"ro.gov.br\0kitashiobara.fukushima.jp\0" +"inf.mk\0" +"cloudcontrolled.com\0" +"yahiko.niigata.jp\0" +"k12.il.us\0cafjs.com\0" +"b.se\0" +"chungbuk.kr\0" +"gs.bu.no\0amfam\0" +"karuizawa.nagano.jp\0opole.pl\0" +"wlocl.pl\0" +"*.diher.solutions\0" +"ichikawa.chiba.jp\0shimotsuma.ibaraki.jp\0" +"nagano.nagano.jp\0" +"rar.ve\0adygeya.ru\0" +"hatsukaichi.hiroshima.jp\0kawai.nara.jp\0saitama.saitama.jp\0" +"dyr\xc3\xb8y.no\0" +"kouhoku.saga.jp\0" +"takko.aomori.jp\0" +"paris\0security\0emrnotebooks-prod.ap-south-1.amazonaws.com\0" +"tome.miyagi.jp\0" +"int.pt\0gmail\0" +"*.mm\0est-a-la-masion.com\0" +"nishiawakura.okayama.jp\0" +"notebook.eu-west-3.sagemaker.aws\0" +"friulivegiulia.it\0" +"square7.de\0" +"monza.it\0ogawa.ibaraki.jp\0gda.pl\0" +"s3.us-west-1.amazonaws.com\0amscompute.com\0" +"brasilia.me\0" +"shobara.hiroshima.jp\0" +"kochi.kochi.jp\0*.np\0" +"is-a-financialadvisor.com\0" +"engineer\0" +"shirako.chiba.jp\0shibuya.tokyo.jp\0ac.leg.br\0" +"\xd9\x85\xd9\x88\xd9\x82\xd8\xb9\0" +"konan.aichi.jp\0" +"df.gov.br\0" +"ibestad.no\0barsy.me\0" +"sohu\0from-wa.com\0stuff-4-sale.us\0" +"int.ru\0" +"oguni.kumamoto.jp\0" +"kvitsoy.no\0cc.dc.us\0" +"sanok.pl\0swatch\0" +"naka.ibaraki.jp\0" +"pixolino.com\0" +"indigena.bo\0agency\0" +"*.pg\0" +"fastvps-server.com\0" +"int.tj\0sakura.ne.jp\0" +"webview-assets.aws-cloud9.sa-east-1.amazonaws.com\0" +"square7.ch\0mongolian.jp\0lon-2.paas.massivegrid.net\0" +"int.tt\0" +"frenchkiss.jp\0" +"levanger.no\0blogdns.com\0" +"tushu\0execute-api.ap-east-1.amazonaws.com\0" +"myoko.niigata.jp\0" +"citi\0kurgan.su\0" +"tw.cn\0cdn.prod.atlassian-dev.net\0" +"crew.aero\0" +"soc.srcf.net\0" +"s3-website.af-south-1.amazonaws.com\0" +"modena.it\0nakano.nagano.jp\0" +"int.ve\0" +"kunisaki.oita.jp\0flickr\0" +"eidskog.no\0toyota\0" +"b\xc3\xb8.nordland.no\0" +"sakyo.kyoto.jp\0" +"adv.br\0\xe0\xb8\xad\xe0\xb8\x87\xe0\xb8\x84\xe0\xb9\x8c\xe0\xb8\x81\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"city\0inf.ua\0" +"int.vn\0" +"xxx\0" +"skien.no\0" +"okinawa.okinawa.jp\0" +"s3.dualstack.ca-central-1.amazonaws.com\0" +"handa.aichi.jp\0" +"zone\0" +"omuta.fukuoka.jp\0" +"vix.br\0bandai.fukushima.jp\0" +"lifeinsurance\0kilatiron.com\0" +"cloud.jelastic.open.tim.it\0" +"nsn.us\0" +"prato.it\0s\xc3\xbc""dtirol.it\0netflix\0" +"fujisawa.kanagawa.jp\0hinohara.tokyo.jp\0" +"giize.com\0" +"ostroleka.pl\0xyz\0myfritz.net\0" +"kazimierz-dolny.pl\0" +"song\0" +"cnt.br\0" +"e12.ve\0" +"sk.ca\0" +"nextdirect\0" +"barsy.ro\0" +"valleeaoste.it\0vs.it\0" +"rovno.ua\0" +"studio.ap-northeast-2.sagemaker.aws\0" +"minamiizu.shizuoka.jp\0hyatt\0emrappui-prod.cn-northwest-1.amazonaws.com.cn\0" +"vic.au\0independent-inquiry.uk\0" +"arida.wakayama.jp\0thanhhoa.vn\0" +"sony\0" +"airtraffic.aero\0wpdevcloud.com\0" +"zapto.xyz\0" +"time.no\0" +"kolobrzeg.pl\0" +"morioka.iwate.jp\0" +"yonaguni.okinawa.jp\0" +"mrap.accesspoint.s3-global.amazonaws.com\0" +"sd.cn\0" +"graphox.us\0uwu.ai\0" +"svalbard.no\0sondre-land.no\0" +"ve.it\0izumizaki.fukushima.jp\0" +"nichinan.miyazaki.jp\0okuizumo.shimane.jp\0cn-north-1.eb.amazonaws.com.cn\0" +"misato.miyagi.jp\0" +"sor-odal.no\0" +"nagato.yamaguchi.jp\0" +"trentino-sued-tirol.it\0dongnai.vn\0" +"rhcloud.com\0" +"se.gov.br\0contact\0on-the-web.tv\0" +"sandnessj\xc3\xb8""en.no\0emrappui-prod.ap-northeast-1.amazonaws.com\0barsy.uk\0" +"kitaakita.akita.jp\0" +"elverum.no\0" +"deals\0" +"matrix.jp\0" +"lib.nv.us\0s3-accesspoint.us-west-1.amazonaws.com\0nov.ru\0" +"parts\0" +"taa.it\0akagi.shimane.jp\0" +"voting\0" +"gokase.miyazaki.jp\0watch\0siteleaf.net\0" +"flakstad.no\0party\0" +"saltdal.no\0radio.am\0" +"vercelli.it\0" +"cpa.pro\0lib.mo.us\0" +"kill.jp\0" +"\xe6\x9b\xb8\xe7\xb1\x8d\0nov.su\0" +"valer.hedmark.no\0notebook.ap-northeast-1.sagemaker.aws\0" +"tp.it\0kin.okinawa.jp\0" +"emrappui-prod.eu-west-2.amazonaws.com\0" +"guge\0" +"lib.mt.us\0lib.nd.us\0" +"tondabayashi.osaka.jp\0" +"salangen.no\0edgestack.me\0gentapps.com\0" +"qh.cn\0!city.sapporo.jp\0" +"certification.aero\0you\0iamallama.com\0nflfan.org\0" +"radio.br\0*.compute.amazonaws.com.cn\0" +"oz.au\0alt.za\0flowers\0" +"pug.it\0itakura.gunma.jp\0direct\0" +"bmoattachments.org\0" +"\xe7\xa6\x8f\xe5\xb2\xa1.jp\0" +"kanagawa.jp\0" +"sonla.vn\0" +"lib.nm.us\0" +"casacam.net\0" +"siellak.no\0" +"sr.it\0" +"\xc3\xa5lesund.no\0" +"mishima.shizuoka.jp\0" +"filegear-sg.me\0""123webseite.de\0" +"seiyo.ehime.jp\0" +"kurate.fukuoka.jp\0" +"kristiansand.no\0" +"oyabe.toyama.jp\0" +"skedsmo.no\0" +"amagasaki.hyogo.jp\0iwaizumi.iwate.jp\0" +"accenture\0*.user.fm\0" +"today\0" +"oum.gov.pl\0" +"sande.vestfold.no\0" +"kyuragi.saga.jp\0" +"guitars\0" +"shinyoshitomi.fukuoka.jp\0misato.wakayama.jp\0" +"florence.it\0" +"alvdal.no\0" +"sld.do\0rendalen.no\0" +"marriott\0hu.net\0" +"loginline.services\0" +"s\xc3\xa1lat.no\0homes\0" +"marshalls\0" +"sa.gov.pl\0" +"love\0dyn.home-webserver.de\0" +"shikabe.hokkaido.jp\0cranky.jp\0""123webseite.at\0" +"nu.ca\0" +"tokoname.aichi.jp\0" +"getmyip.com\0pagespeedmobilizer.com\0" +"rm.it\0" +"radio.fm\0" +"markets\0" +"mywire.org\0" +"boleslawiec.pl\0" +"lib.ky.us\0" +"iwamizawa.hokkaido.jp\0" +"air-surveillance.aero\0" +"ham-radio-op.net\0" +"adv.mz\0" +"takanezawa.tochigi.jp\0" +"dyroy.no\0upli.io\0" +"nagara.chiba.jp\0" +"notebook-fips.us-gov-east-1.sagemaker.aws\0" +"help\0" +"ostre-toten.no\0ap.ngrok.io\0" +"i234.me\0" +"yun\0" +"in-addr.arpa\0pimienta.org\0karelia.su\0" +"music\0" +"bjugn.no\0farsund.no\0farmers\0" +"yoichi.hokkaido.jp\0voorloper.cloud\0" +"notebook.me-south-1.sagemaker.aws\0" +"mp.br\0" +"frogans\0" +"catering.aero\0" +"konskowola.pl\0edgekey.net\0" +"dyndns-home.com\0" +"sos.pl\0" +"balena-devices.com\0" +"toyama.toyama.jp\0" +"emrnotebooks-prod.ap-northeast-2.amazonaws.com\0" +"enna.it\0" +"pol.dz\0al.leg.br\0" +"au.ngrok.io\0" +"higashiyodogawa.osaka.jp\0" +"horten.no\0" +"hidaka.saitama.jp\0" +"alwaysdata.net\0" +"marumori.miyagi.jp\0realm.cz\0sopot.pl\0" +"agdenes.no\0institute\0systems\0" +"mizumaki.fukuoka.jp\0" +"bajddar.no\0" +"homeftp.net\0" +"mb.ca\0" +"yasuoka.nagano.jp\0" +"sugito.saitama.jp\0" +"takatsuki.osaka.jp\0himi.toyama.jp\0" +"zaporizhzhe.ua\0" +"idrett.no\0" +"download\0" +"is-a-guru.com\0" +"tamaki.mie.jp\0taishi.osaka.jp\0kounosu.saitama.jp\0" +"\xe5\x8c\x97\xe6\xb5\xb7\xe9\x81\x93.jp\0" +"vaga.no\0emrstudio-prod.eu-south-1.amazonaws.com\0" +"pc.it\0" +"teaches-yoga.com\0" +"rieti.it\0okayama.okayama.jp\0sp.leg.br\0" +"alipay\0" +"emrnotebooks-prod.ca-central-1.amazonaws.com\0from-ks.com\0" +"kaho.fukuoka.jp\0zip\0" +"nore-og-uvdal.no\0s\xc3\xb8r-odal.no\0" +"gamagori.aichi.jp\0" +"emrappui-prod.eu-south-1.amazonaws.com\0studio.ap-southeast-2.sagemaker.aws\0x0.to\0" +"tottori.jp\0" +"far.br\0" +"takaoka.toyama.jp\0" +"barsy.bg\0" +"shisui.chiba.jp\0" +"here\0" +"pol.ht\0" +"nu.it\0" +"h\xc3\xb8nefoss.no\0" +"toyotsu.fukuoka.jp\0" +"sling\0" +"barsy.ca\0webview-assets.cloud9.eu-central-1.amazonaws.com\0" +"izumisano.osaka.jp\0" +"health-carereform.com\0" +"froland.no\0" +"guru\0viking\0" +"sannan.hyogo.jp\0" +"\xd0\xbe\xd0\xb4.\xd1\x81\xd1\x80\xd0\xb1\0" +"yaita.tochigi.jp\0tayninh.vn\0hra.health\0" +"tattoo\0" +"nozawaonsen.nagano.jp\0endofinternet.net\0krakow.pl\0" +"aero\0" +"midsund.no\0sn\xc3\xa5sa.no\0barsy.de\0" +"spot\0workers.dev\0" +"ro.eu.org\0" +"tsurugi.ishikawa.jp\0ny-1.paas.massivegrid.net\0" +"blogspot.co.at\0" +"webview-assets.aws-cloud9.us-east-2.amazonaws.com\0" +"skype\0" +"onrender.com\0" +"gushikami.okinawa.jp\0wedeploy.sh\0" +"yura.wakayama.jp\0murayama.yamagata.jp\0" +"s3-website-ap-northeast-1.amazonaws.com\0" +"calabria.it\0" +"floro.no\0" +"s3-website-ap-southeast-2.amazonaws.com\0notebook-fips.us-east-1.sagemaker.aws\0qualifioapp.com\0" +"\xc3\xa5seral.no\0sld.pa\0" +"vipsinaapp.com\0" +"koya.wakayama.jp\0" +"sic.it\0" +"ivgu.no\0" +"mi.it\0" +"execute-api.ap-northeast-3.amazonaws.com\0barsy.eu\0" +"hobby-site.com\0" +"ol.no\0" +"suzuki\0l-o-g-i-n.de\0" +"sd.us\0notebook.us-west-1.sagemaker.aws\0" +"oseto.nagasaki.jp\0konin.pl\0" +"prime\0" +"mb.it\0" +"sicily.it\0yamada.iwate.jp\0" +"flora.no\0" +"kobayashi.miyazaki.jp\0pc.pl\0" +"sm\xc3\xb8la.no\0" +"bitbridge.net\0" +"bauhaus\0" +"hakata.fukuoka.jp\0" +"jele.host\0" +"akamaihd-staging.net\0" +"emrappui-prod.us-gov-east-1.amazonaws.com\0" +"sano.tochigi.jp\0hayakawa.yamanashi.jp\0\xe7\xa7\xbb\xe5\x8a\xa8\0" +"os.hedmark.no\0si.eu.org\0" +"sch.ae\0bible\0" +"melbourne\0s3-website-us-west-1.amazonaws.com\0camdvr.org\0" +"naha.okinawa.jp\0" +"honda\0" +"auth.af-south-1.amazoncognito.com\0ap-northeast-3.elasticbeanstalk.com\0" +"\xd8\xb9\xd8\xb1\xd8\xa8\0" +"uchiko.ehime.jp\0" +"sagae.yamagata.jp\0akamaized-staging.net\0" +"hl.cn\0sakata.yamagata.jp\0" +"tonsberg.no\0" +"funahashi.toyama.jp\0" +"rawa-maz.pl\0" +"skierv\xc3\xa1.no\0bar.pro\0" +"barsy.in\0" +"barsy.io\0" +"uk0.bigv.io\0" +"sadist.jp\0dev.static.land\0" +"\xe4\xbd\x9b\xe5\xb1\xb1\0in-butter.de\0""123minsida.se\0" +"honjo.akita.jp\0" +"ladesk.com\0" +"he.cn\0" +"cnpy.gdn\0" +"discordsays.com\0git-repos.de\0" +"gallery\0" +"gg.ax\0" +"*.cn-northwest-1.airflow.amazonaws.com.cn\0" +"bronnoy.no\0" +"s3-us-east-2.amazonaws.com\0" +"\xe0\xa4\x95\xe0\xa5\x89\xe0\xa4\xae\0" +"samsung\0s3-accesspoint.sa-east-1.amazonaws.com\0" +"blogspot.co.id\0" +"nedre-eiker.no\0" +"nagi.okayama.jp\0" +"blogspot.co.il\0" +"mitsuke.niigata.jp\0" +"\xe0\xae\x9a\xe0\xae\xbf\xe0\xae\x99\xe0\xaf\x8d\xe0\xae\x95\xe0\xae\xaa\xe0\xaf\x8d\xe0\xae\xaa\xe0\xaf\x82\xe0\xae\xb0\xe0\xaf\x8d\0s3-website.ca-central-1.amazonaws.com\0s3.eu-west-3.amazonaws.com\0" +"koga.ibaraki.jp\0" +"\xd2\x9b\xd0\xb0\xd0\xb7\0sk.eu.org\0" +"impertrix.com\0" +"drobak.no\0somna.no\0myiphost.com\0" +"yabu.hyogo.jp\0tsuno.miyazaki.jp\0" +"realestate\0mayfirst.info\0" +"fage\0s3-eu-west-3.amazonaws.com\0" +"ichikai.tochigi.jp\0" +"nishitosa.kochi.jp\0glogow.pl\0" +"\xe7\x82\xb9\xe7\x9c\x8b\0" +"kujukuri.chiba.jp\0sites.static.land\0" +"vicenza.it\0" +"s3-website-eu-west-1.amazonaws.com\0" +"fi.cr\0" +"mol.it\0" +"sado.niigata.jp\0maif\0" +"sukumo.kochi.jp\0pol.tr\0" +"ed.ao\0\xc3\xa5mli.no\0myhome-server.de\0" +"sakuho.nagano.jp\0" +"wiw.gov.pl\0ngrok-free.dev\0" +"m\xc3\xa1latvuopmi.no\0wedeploy.me\0" +"bosch\0" +"cog.mi.us\0" +"aparecida.br\0" +"futuremailing.at\0" +"s3-website-sa-east-1.amazonaws.com\0eero-stage.online\0" +"oshino.yamanashi.jp\0wielun.pl\0*.banzai.cloud\0" +"tas.gov.au\0nes.akershus.no\0lib.as.us\0msk.ru\0" +"perso.ht\0machida.tokyo.jp\0" +"shinichi.hiroshima.jp\0fail\0" +"mediatech.by\0" +"reggioemilia.it\0hokuryu.hokkaido.jp\0" +"nanmoku.gunma.jp\0" +"s3-accesspoint.dualstack.ap-southeast-1.amazonaws.com\0is-a-celticsfan.org\0awsmppl.com\0" +"saigawa.fukuoka.jp\0" +"ed.ci\0" +"friuli-veneziagiulia.it\0" +"is-a-nurse.com\0" +"tateyama.toyama.jp\0" +"ru.eu.org\0se.eu.org\0msk.su\0srht.site\0" +"sch.id\0piw.gov.pl\0mi.th\0" +"co.ae\0" +"co.ag\0from-al.com\0" +"ed.cr\0" +"cymru\0talk\0" +"mino.gifu.jp\0hs.kr\0" +"lesja.no\0lugansk.ua\0" +"co.am\0" +"co.ao\0" +"vs.mythic-beasts.com\0" +"co.bb\0sch.ir\0" +"co.at\0" +"il-central-1.elasticbeanstalk.com\0" +"omachi.nagano.jp\0" +"agrar.hu\0" +"co.bi\0" +"co.bj\0" +"okinoshima.shimane.jp\0co.bn\0" +"sch.jo\0mi.us\0" +"yomitan.okinawa.jp\0ashikaga.tochigi.jp\0" +"co.ca\0" +"taiwa.miyagi.jp\0" +"co.bw\0\xd0\xbc\xd1\x81\xd0\xba.\xd1\x80\xd1\x83\xd1\x81\0" +"aisai.aichi.jp\0kawaiishop.jp\0" +"co.ci\0" +"co.cl\0" +"co.cm\0" +"ponpes.id\0" +"ba.gov.br\0trentin-sud-tirol.it\0" +"co.cr\0onomichi.hiroshima.jp\0" +"cesenaforl\xc3\xac.it\0" +"furubira.hokkaido.jp\0tsuwano.shimane.jp\0" +"co.cz\0experts-comptables.fr\0" +"sch.lk\0co.dk\0" +"chuo.osaka.jp\0" +"webspace.rocks\0" +"fi.it\0tsugaru.aomori.jp\0" +"my-wan.de\0" +"shinanomachi.nagano.jp\0" +"griw.gov.pl\0" +"hl.no\0km.ua\0" +"funagata.yamagata.jp\0" +"er.in\0" +"sch.ly\0" +"naruto.tokushima.jp\0" +"execute-api.eu-central-1.amazonaws.com\0" +"\xe3\x81\xbf\xe3\x82\x93\xe3\x81\xaa\0" +"fans\0" +"epson\0" +"valle-d-aosta.it\0" +"leangaviika.no\0" +"yamada.toyama.jp\0" +"chintai\0" +"trentinsued-tirol.it\0" +"sch.ng\0archi\0" +"bj.cn\0" +"bc.ca\0homesense\0" +"for-some.biz\0" +"namsos.no\0*.ap-northeast-1.airflow.amazonaws.com\0" +"emrstudio-prod.ca-central-1.amazonaws.com\0" +"amot.no\0" +"localhost.daplie.me\0lugs.org.uk\0" +"uchihara.ibaraki.jp\0iliadboxos.it\0" +"s\xc3\xb8ndre-land.no\0emrnotebooks-prod.ap-southeast-1.amazonaws.com\0" +"backan.vn\0" +"co.gg\0" +"seidat.net\0" +"luhansk.ua\0from-ms.com\0from-nc.com\0" +"co.gl\0hanyu.saitama.jp\0channel\0" +"uni5.net\0" +"kragero.no\0" +"ed.jp\0" +"co.gy\0" +"ginan.gifu.jp\0" +"from-ca.com\0" +"blogspot.co.uk\0" +"sch.qa\0ngrok.pizza\0" +"yamaguchi.jp\0emrstudio-prod.cn-north-1.amazonaws.com.cn\0" +"sor-aurdal.no\0watches\0" +"co.id\0*.magentosite.cloud\0" +"co.hu\0" +"per.la\0farm\0" +"aivencloud.com\0" +"co.il\0obuse.nagano.jp\0" +"co.im\0" +"co.in\0iruma.saitama.jp\0boo.jp\0torproject.net\0" +"unicloud.pl\0" +"co.ir\0edogawa.tokyo.jp\0" +"s3-object-lambda.eu-west-2.amazonaws.com\0webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com\0" +"co.it\0" +"co.je\0\xe9\x80\x9a\xe8\xb2\xa9\0dyndns.ddnss.de\0" +"uk.net\0" +"khakassia.su\0" +"kasaoka.okayama.jp\0" +"minamiaiki.nagano.jp\0" +"saves-the-whales.com\0own.pm\0" +"better-than.tv\0pupu.jp\0" +"sakai.fukui.jp\0fast\0jp.net\0" +"studio.us-west-2.sagemaker.aws\0" +"co.jp\0naie.hokkaido.jp\0" +"sch.sa\0" +"ch.it\0yamanashi.jp\0" +"2ix.at\0" +"co.ke\0" +"walbrzych.pl\0" +"ask\xc3\xb8y.no\0hlx3.page\0s3-accesspoint.eu-west-3.amazonaws.com\0" +"ca.in\0" +"gose.nara.jp\0per.nf\0" +"osteroy.no\0" +"ogawa.nagano.jp\0" +"reviews\0sch.so\0" +"am.gov.br\0ca.it\0irish\0" +"co.kr\0" +"co.lc\0sch.ss\0amica\0wedeploy.io\0" +"vic.gov.au\0" +"sch.tf\0" +"dovre.no\0mer\xc3\xa5ker.no\0reservd.disrec.thingdust.io\0" +"valle-daosta.it\0""2ix.ch\0" +"gs.tr.no\0kirkenes.no\0eu-central-1.elasticbeanstalk.com\0" +"educator.aero\0bloomberg\0" +"med.br\0candypop.jp\0" +"democracia.bo\0is-a-blogger.com\0" +"accident-prevention.aero\0co.ma\0" +"co.ls\0" +"co.me\0""2ix.de\0" +"co.mg\0gu.us\0taxi\0" +"coupon\0" +"balsan-suedtirol.it\0" +"ngrok.io\0" +"co.na\0" +"casino\0barsyonline.com\0" +"co.mu\0*.stg-builder.code.com\0" +"beskidy.pl\0" +"co.mw\0gs.st.no\0shop.brendly.rs\0from-ky.com\0blogspot.co.ke\0" +"yaotsu.gifu.jp\0" +"co.ni\0alpha-myqnapcloud.com\0" +"al.it\0co.mz\0*.cryptonomic.net\0" +"s3.ap-northeast-2.amazonaws.com\0" +"co.nl\0" +"ed.pw\0" +"med.ec\0co.no\0" +"nakano.tokyo.jp\0zarow.pl\0" +"med.ee\0" +"ogaki.gifu.jp\0" +"verdal.no\0" +"asago.hyogo.jp\0" +"fuchu.tokyo.jp\0sch.wf\0" +"jondal.no\0" +"co.nz\0" +"extraspace\0servebbs.com\0" +"ca.na\0co.om\0jed.wafaicloud.com\0" +"parti.se\0" +"to.leg.br\0" +"gs.sf.no\0balsfjord.no\0" +"hanoi.vn\0" +"exchange.aero\0recht.pro\0" +"tkmaxx\0" +"hoylandet.no\0" +"kinokawa.wakayama.jp\0" +"cloudsite.builders\0" +"co.pl\0" +"per.sg\0" +"aosta.it\0co.pn\0" +"*.moonscale.io\0" +"yamatotakada.nara.jp\0bialystok.pl\0" +"civilaviation.aero\0" +"independent-inquest.uk\0" +"prudential\0" +"club\0s3-deprecated.cn-north-1.amazonaws.com.cn\0freebox-os.fr\0" +"sandnes.no\0co.pw\0" +"s3-deprecated.us-west-2.amazonaws.com\0" +"laichau.vn\0" +"bplaced.de\0" +"quest\0" +"obu.aichi.jp\0" +"ap.gov.br\0" +"global.prod.fastly.net\0" +"chuo.fukuoka.jp\0" +"eu.org\0" +"contractors\0" +"brand.se\0" +"blogspot.co.nz\0" +"sch.zm\0" +"trentinostirol.it\0perso.sn\0" +"co.ro\0" +"med.ht\0sakura.tv\0" +"shari.hokkaido.jp\0" +"co.rs\0express\0" +"al.no\0" +"tamamura.gunma.jp\0" +"co.rw\0", + +"fukui.fukui.jp\0ap.gov.pl\0" +"perso.tn\0" +"execute-api.ap-southeast-3.amazonaws.com\0" +"fujishiro.ibaraki.jp\0" +"cv.ua\0fh-muenster.io\0\xd1\x8f.\xd1\x80\xd1\x83\xd1\x81\0" +"reggio-emilia.it\0co.st\0" +"kuroishi.aomori.jp\0" +"co.th\0" +"co.sz\0co.tj\0" +"\xe0\xb8\x84\xe0\xb8\xad\xe0\xb8\xa1\0" +"kota.aichi.jp\0" +"co.tm\0" +"toho.fukuoka.jp\0" +"hatinh.vn\0" +"emrstudio-prod.eu-north-1.amazonaws.com\0pointto.us\0workisboring.com\0co.ua\0ch.tc\0" +"toyonaka.osaka.jp\0krellian.net\0" +"k12.vi.us\0erni\0" +"co.tt\0" +"lefrak\0hosp.uk\0minisite.ms\0" +"ashoro.hokkaido.jp\0" +"moss.no\0co.ug\0" +"internet-dns.de\0" +"co.tz\0" +"co.uk\0" +"*.awsapprunner.com\0dyn-ip24.de\0hotelwithflight.com\0" +"tsuruga.fukui.jp\0imakane.hokkaido.jp\0uda.nara.jp\0" +"pharmacy\0" +"kinko.kagoshima.jp\0" +"co.us\0" +"geisei.kochi.jp\0" +"valer.ostfold.no\0co.ve\0s3-fips.us-west-2.amazonaws.com\0" +"kartuzy.pl\0swidnica.pl\0" +"co.vi\0auth-fips.us-gov-west-1.amazoncognito.com\0" +"\xe7\xbd\x91\xe7\xbb\x9c.cn\0co.uz\0" +"s3.dualstack.ap-southeast-1.amazonaws.com\0" +"ee.eu.org\0" +"akamaiorigin.net\0" +"richardli\0" +"kushima.miyazaki.jp\0" +"nobeoka.miyazaki.jp\0thainguyen.vn\0" +"med.ly\0" +"turin.it\0pfizer\0" +"tickets.io\0" +"melhus.no\0" +"canva-apps.cn\0" +"\xd8\xa8\xd8\xa7\xd8\xb2\xd8\xa7\xd8\xb1\0" +"ca.us\0nokia\0mozilla-iot.org\0" +"vall\xc3\xa9""eaoste.it\0olayan\0supabase.in\0" +"az.us\0endofinternet.org\0cloud-fr1.unispace.io\0" +"gol.no\0panasonic\0" +"ericsson\0" +"krokstadelva.no\0" +"jdf.br\0" +"customer.speedpartner.de\0" +"onza.mythic-beasts.com\0" +"med.om\0americanfamily\0" +"kyoto.jp\0toride.ibaraki.jp\0" +"r\xc3\xa1hkker\xc3\xa1vju.no\0as.us\0" +"rgr.jp\0" +"med.pa\0gos.pk\0\xd1\x81\xd0\xb0\xd0\xbc\xd0\xb0\xd1\x80\xd0\xb0.\xd1\x80\xd1\x83\xd1\x81\0" +"teshikaga.hokkaido.jp\0" +"co.za\0vfs.cloud9.ap-southeast-2.amazonaws.com\0" +"s3-website.cn-northwest-1.amazonaws.com.cn\0" +"\xd1\x81\xd0\xbe\xd1\x87\xd0\xb8.\xd1\x80\xd1\x83\xd1\x81\0" +"med.pl\0" +"skydiving.aero\0al.us\0emrnotebooks-prod.us-west-2.amazonaws.com\0" +"qsl.br\0fujieda.shizuoka.jp\0tmall\0" +"gs.mr.no\0finn\xc3\xb8y.no\0s3.ap-southeast-4.amazonaws.com\0" +"shoo.okayama.jp\0" +"langevag.no\0co.zm\0shiftedit.io\0" +"mmafan.biz\0" +"gjerdrum.no\0kongsvinger.no\0auth.ap-northeast-1.amazoncognito.com\0" +"fujitsu\0" +"tozawa.yamagata.jp\0" +"oystre-slidre.no\0yombo.me\0" +"art.br\0samsclub\0" +"\xe7\xbd\x91\xe7\xbb\x9c.hk\0co.zw\0" +"valdaosta.it\0" +"kosaka.akita.jp\0" +"ciencia.bo\0" +"natura\0" +"moriguchi.osaka.jp\0" +"kannami.shizuoka.jp\0" +"s3-us-west-2.amazonaws.com\0" +"from-md.com\0dray-dns.de\0" +"dynu.net\0" +"minamimaki.nagano.jp\0" +"services.aero\0" +"med.sa\0" +"asaka.saitama.jp\0" +"u.bg\0affinitylottery.org.uk\0" +"med.sd\0hoplix.shop\0" +"art.do\0is-a-linux-user.org\0blogspot.co.za\0" +"tecnologia.bo\0" +"viterbo.it\0beep.pl\0" +"askoy.no\0pvt.k12.ma.us\0" +"sth.ac.at\0" +"lierne.no\0cust.prod.thingdust.io\0" +"frosinone.it\0" +"n.bg\0" +"art.dz\0" +"mazeplay.com\0" +"us-east-1.elasticbeanstalk.com\0" +"wada.nagano.jp\0kikirara.jp\0" +"lebtimnetz.de\0supabase.co\0" +"tsukui.kanagawa.jp\0" +"conn.uk\0" +"off.ai\0" +"inatsuki.fukuoka.jp\0" +"g.bg\0" +"dynalias.net\0" +"vic.edu.au\0" +"ancona.it\0" +"g\xc3\xa1ivuotna.no\0solund.no\0" +"accident-investigation.aero\0\xe7\xb5\x84\xe7\xb9\x94.\xe9\xa6\x99\xe6\xb8\xaf\0lamborghini\0" +"online\0" +"matera.it\0" +"magnet.page\0" +"malatvuopmi.no\0" +"actor\0akamaiedge-staging.net\0whm.fr-par.scw.cloud\0" +"sobetsu.hokkaido.jp\0wiih.gov.pl\0" +"hirono.fukushima.jp\0*.webhare.dev\0" +"uri.arpa\0" +"activetrail.biz\0" +"shinkamigoto.nagasaki.jp\0" +"from-tn.com\0" +"mosvik.no\0" +"nemuro.hokkaido.jp\0matsuzaki.shizuoka.jp\0" +"okuma.fukushima.jp\0" +"foggia.it\0" +"chiryu.aichi.jp\0" +"club.aero\0tysnes.no\0from-fl.com\0" +"art.ht\0" +"cloud.fedoraproject.org\0" +"cc.md.us\0" +"akaiwa.okayama.jp\0" +"nishinoomote.kagoshima.jp\0" +"s3.dualstack.us-west-1.amazonaws.com\0" +"shiraoi.hokkaido.jp\0custom.metacentrum.cz\0" +"bod\xc3\xb8.no\0" +"maniwa.okayama.jp\0" +"\xd8\xa7\xd8\xb1\xd8\xa7\xd9\x85\xd9\x83\xd9\x88\0" +"loginline.io\0" +"soja.okayama.jp\0tsurugashima.saitama.jp\0" +"me-south-1.elasticbeanstalk.com\0" +"seranishi.hiroshima.jp\0swinoujscie.pl\0" +"ikoma.nara.jp\0platform0.app\0" +"east-kazakhstan.su\0" +"tokorozawa.saitama.jp\0" +"lunner.no\0is-a-nascarfan.com\0" +"k12.ny.us\0" +"higashikurume.tokyo.jp\0citadel\0sharp\0" +"s3-website.dualstack.eu-central-1.amazonaws.com\0" +"solutions\0" +"ogawara.miyagi.jp\0kumatori.osaka.jp\0" +"*.alces.network\0vfs.cloud9.eu-west-2.amazonaws.com\0" +"kiwi.nz\0crafting.xyz\0" +"vibo-valentia.it\0" +"cyon.site\0" +"\xe8\xb4\xad\xe7\x89\xa9\0logoip.com\0" +"piedmont.it\0" +"dyn-berlin.de\0" +"6.bg\0" +"delhi.in\0bacninh.vn\0" +"k12.ms.us\0k12.nc.us\0" +"auth.ap-southeast-1.amazoncognito.com\0" +"ind.br\0clan.rip\0" +"bentley\0" +"origins\0studio.ap-northeast-1.sagemaker.aws\0spacekit.io\0" +"deca.jp\0" +"trentinos\xc3\xbc""d-tirol.it\0futtsu.chiba.jp\0" +"skiptvet.no\0" +"sandcats.io\0" +"ebino.miyazaki.jp\0miyota.nagano.jp\0" +"*.hosting.myjino.ru\0" +"pomorze.pl\0" +"k12.me.us\0emrstudio-prod.me-central-1.amazonaws.com\0" +"shirataka.yamagata.jp\0" +"sauherad.no\0hopto.me\0" +"theshop.jp\0" +"execute-api.af-south-1.amazonaws.com\0s3-accesspoint.us-gov-east-1.amazonaws.com\0is-a-personaltrainer.com\0" +"crown\0star\0" +"agents.aero\0" +"yamatokoriyama.nara.jp\0" +"kodaira.tokyo.jp\0" +"s3-accesspoint.us-west-2.amazonaws.com\0" +"r\xc3\xa1isa.no\0" +"is-a-socialist.com\0" +"x.mythic-beasts.com\0" +"kakuda.miyagi.jp\0urawa.saitama.jp\0" +"roma.it\0shibata.niigata.jp\0" +"shinjo.okayama.jp\0oia.gov.pl\0" +"is-not-certified.com\0" +"cc.il.us\0" +"aus.basketball\0" +"cn.eu.org\0" +"flights\0" +"art.pl\0" +"recipes\0" +"academy\0" +"blogspot.vn\0" +"katsushika.tokyo.jp\0homesklep.pl\0" +"pythonanywhere.com\0" +"ltda\0" +"polkowice.pl\0ngrok-free.app\0" +"ohira.miyagi.jp\0" +"gangaviika.no\0" +"kaufen\0" +"moareke.no\0" +"ind.gt\0sumida.tokyo.jp\0" +"is-an-accountant.com\0" +"hjelmeland.no\0" +"shibecha.hokkaido.jp\0*.lclstage.dev\0" +"ilawa.pl\0" +"osaki.miyagi.jp\0" +"nom.ad\0isa.kagoshima.jp\0" +"kurotaki.nara.jp\0" +"nom.ag\0" +"takamori.kumamoto.jp\0" +"demo.jelastic.com\0" +"lig.it\0rikubetsu.hokkaido.jp\0hanno.saitama.jp\0" +"s3-website.ap-northeast-3.amazonaws.com\0" +"tokyo.jp\0" +"ipiranga\0" +"art.sn\0" +"emergency.aero\0*.transurl.be\0" +"not.br\0ind.in\0" +"qbuser.com\0" +"mysecuritycamera.net\0" +"ringebu.no\0selje.no\0" +"bar2.net\0" +"finnoy.no\0odessa.ua\0" +"is-a-soxfan.org\0" +"kitahiroshima.hokkaido.jp\0" +"k12.in.us\0loans\0" +"yk.ca\0blogspot.re\0mintere.site\0" +"auth.sa-east-1.amazoncognito.com\0" +"wakayama.jp\0naka.hiroshima.jp\0" +"blogspot.ro\0" +"\xe6\x94\xbf\xe5\xba\x9c.\xe9\xa6\x99\xe6\xb8\xaf\0s3.dualstack.me-south-1.amazonaws.com\0is-by.us\0" +"u.se\0emrappui-prod.me-central-1.amazonaws.com\0blogspot.rs\0" +"conference.aero\0nom.co\0blogspot.ru\0blogspot.se\0" +"oizumi.gunma.jp\0ryokami.saitama.jp\0" +"*.ap-south-1.airflow.amazonaws.com\0blogspot.sg\0" +"analytics-gateway.eu-central-1.amazonaws.com\0blogspot.si\0" +"ohi.fukui.jp\0" +"trogstad.no\0blogspot.sk\0*.quipelements.com\0" +"blogspot.sn\0" +"jobs\0iopsys.se\0" +"miasa.nagano.jp\0yazu.tottori.jp\0rehab\0" +"n.se\0" +"hikimi.shimane.jp\0" +"ind.kw\0fairwinds\0s3.dualstack.eu-south-1.amazonaws.com\0cy.eu.org\0" +"blogspot.td\0" +"isa.us\0" +"olawa.pl\0""3.azurestaticapps.net\0" +"kutno.pl\0church\0" +"asahikawa.hokkaido.jp\0" +"is-a-knight.org\0" +"g.se\0" +"bloxcms.com\0" +"racing\0s3-website.dualstack.eu-west-3.amazonaws.com\0" +"inashiki.ibaraki.jp\0uw.gov.pl\0doctor\0" +"blogspot.tw\0blogspot.ug\0" +"fnd.br\0shika.ishikawa.jp\0" +"nom.es\0cloud66.zone\0*.transurl.eu\0" +"ogose.saitama.jp\0koge.tottori.jp\0" +"knightpoint.systems\0*.paywhirl.com\0" +"yurihonjo.akita.jp\0" +"fishing\0" +"blogspot.mr\0" +"cz.eu.org\0" +"pisa.it\0!city.kobe.jp\0wassamu.hokkaido.jp\0zp.gov.pl\0" +"nom.fr\0blogspot.mx\0" +"arendal.no\0blogspot.my\0" +"blogspot.nl\0" +"wa.au\0" +"pistoia.it\0yamanobe.yamagata.jp\0gb.net\0" +"blogspot.no\0" +"abeno.osaka.jp\0" +"forli-cesena.it\0chuo.tokyo.jp\0" +"visa\0" +"community-pro.net\0" +"webview-assets.aws-cloud9.us-west-1.amazonaws.com\0" +"ikeda.fukui.jp\0" +"natural.bo\0living\0dk.eu.org\0" +"blogspot.pe\0" +"daisen.akita.jp\0" +"daiwa.hiroshima.jp\0" +"us.ax\0" +"game-server.cc\0freeddns.org\0" +"armenia.su\0" +"leksvik.no\0blogspot.qa\0" +"toga.toyama.jp\0" +"blogspot.pt\0" +"itcouldbewor.se\0" +"tosa.kochi.jp\0" +"s3-website.eu-south-2.amazonaws.com\0" +"americanexpress\0" +"higashikagura.hokkaido.jp\0moriya.ibaraki.jp\0" +"riobranco.br\0podlasie.pl\0design\0" +"s3-object-lambda.eu-central-2.amazonaws.com\0" +"nishio.aichi.jp\0freetls.fastly.net\0" +"s3-website.dualstack.ap-northeast-2.amazonaws.com\0" +"nomi.ishikawa.jp\0konan.shiga.jp\0" +"blogspot.is\0" +"blogspot.it\0" +"tamatsukuri.ibaraki.jp\0chizu.tottori.jp\0under.jp\0" +"jan-mayen.no\0b\xc3\xa5""d\xc3\xa5""ddj\xc3\xa5.no\0\xe5\x80\x8b\xe4\xba\xba.\xe9\xa6\x99\xe6\xb8\xaf\0" +"bolzano-altoadige.it\0" +"viva\0s3-accesspoint.dualstack.af-south-1.amazonaws.com\0" +"garden\0" +"\xd8\xa7\xd8\xa8\xd9\x88\xd8\xb8\xd8\xa8\xd9\x8a\0" +"blogspot.jp\0" +"blogsite.xyz\0" +"nom.km\0" +"napoli.it\0rj.leg.br\0" +"vivo\0" +"lib.ri.us\0bestbuy\0" +"hisamitsu\0emrnotebooks-prod.us-gov-west-1.amazonaws.com\0" +"zgorzelec.pl\0" +"team\0" +"yaese.okinawa.jp\0blogspot.kr\0" +"de.eu.org\0" +"zagan.pl\0" +"tarumizu.kagoshima.jp\0" +"fukushima.fukushima.jp\0" +"blogspot.li\0" +"ind.tn\0" +"kagoshima.jp\0wanouchi.gifu.jp\0barsy.support\0" +"nom.mg\0travelersinsurance\0" +"kira.aichi.jp\0oschr.gov.pl\0" +"bato.tochigi.jp\0" +"translate.goog\0" +"soni.nara.jp\0" +"\xe5\xb9\xbf\xe4\xb8\x9c\0blogspot.lt\0blogspot.md\0" +"nord-odal.no\0blogspot.lu\0" +"nom.nc\0" +"adm.br\0nachikatsuura.wakayama.jp\0" +"nog.community\0blogspot.mk\0" +"tech\0" +"co.place\0" +"cosenza.it\0itami.hyogo.jp\0" +"nom.ni\0property\0" +"*.transurl.nl\0" +"rakkestad.no\0" +"elasticbeanstalk.com\0from-wy.com\0" +"myftp.biz\0" +"k12.ct.us\0" +"teramo.it\0ina.nagano.jp\0" +"blogspot.fi\0" +"fin.ci\0" +"nanao.ishikawa.jp\0" +"pila.pl\0" +"blogspot.fr\0" +"exposed\0punyu.jp\0" +"nom.pa\0" +"shibata.miyagi.jp\0" +"hikari.yamaguchi.jp\0lawyer\0" +"nom.pe\0" +"selbu.no\0" +"moriyama.shiga.jp\0szczytno.pl\0grainger\0" +"\xe6\x96\xb0\xe9\x97\xbb\0" +"us.in\0nom.pl\0blogspot.gr\0" +"shop.ht\0kawasaki.miyagi.jp\0" +"fin.ec\0shop.hu\0" +"psi.br\0hino.tottori.jp\0" +"vc.it\0zao.miyagi.jp\0" +"execute-api.sa-east-1.amazonaws.com\0" +"blogspot.hk\0" +"tank.jp\0" +"ibaraki.osaka.jp\0akishima.tokyo.jp\0" +"gallo\0" +"soc.dz\0ichikawamisato.yamanashi.jp\0" +"genkai.saga.jp\0blogspot.hr\0" +"hemne.no\0" +"tateshina.nagano.jp\0" +"blogspot.hu\0blogspot.ie\0" +"ce.gov.br\0cool\0meet\0" +"hammarfeasta.no\0" +"ujitawara.kyoto.jp\0" +"coop\0sener\0" +"nom.re\0zp.ua\0rag-cloud.hosteur.com\0us.kg\0" +"lib.oh.us\0" +"r2.dev\0blogspot.in\0" +"blogspot.ba\0" +"fukuchi.fukuoka.jp\0" +"medecin.km\0siljan.no\0forumz.info\0" +"angry.jp\0" +"nom.ro\0blogspot.be\0" +"blogspot.bg\0weeklylottery.org.uk\0" +"otsuki.yamanashi.jp\0storipress.app\0" +"forgeblocks.com\0" +"blogspot.bj\0" +"abc.br\0" +"seljord.no\0" +"chuo.yamanashi.jp\0" +"blogspot.ca\0" +"tn.it\0\xe7\xa7\x8b\xe7\x94\xb0.jp\0ashibetsu.hokkaido.jp\0" +"myspreadshop.co.uk\0" +"tel.tr\0blogspot.cf\0" +"torsken.no\0" +"blogspot.ch\0" +"h\xc3\xa1pmir.no\0" +"owani.aomori.jp\0" +"k12.az.us\0" +"balsan-sudtirol.it\0blogspot.cl\0" +"s3-ap-south-1.amazonaws.com\0" +"barsy.net\0" +"obihiro.hokkaido.jp\0" +"s3-fips.dualstack.us-east-1.amazonaws.com\0" +"hammerfest.no\0nom.tm\0ca.eu.org\0dnsiskinky.com\0wellbeingzone.eu\0" +"us.na\0blogspot.de\0" +"owariasahi.aichi.jp\0greater.jp\0blogspot.cv\0" +"yamatsuri.fukushima.jp\0" +"kizu.kyoto.jp\0blogspot.cz\0" +"\xe6\x94\xbf\xe5\x8a\xa1\0blogspot.dk\0yolasite.com\0" +"localzone.xyz\0""32-b.it\0" +"kids.us\0exchange\0simple-url.com\0" +"sp.it\0mitake.gifu.jp\0" +"\xc3\xa5""fjord.no\0" +"koto.tokyo.jp\0" +"hacca.jp\0" +"lib.md.us\0" +"messina.it\0kamikawa.saitama.jp\0" +"k12.al.us\0" +"tendo.yamagata.jp\0karpacz.pl\0" +"lab.ms\0" +"\xd8\xa7\xd9\x84\xd8\xb9\xd9\x84\xd9\x8a\xd8\xa7\xd9\x86\0" +"fla.no\0nom.ve\0video\0nyaa.am\0" +"mus.br\0si.it\0sumoto.kumamoto.jp\0yasaka.nagano.jp\0hidaka.wakayama.jp\0" +"kr.com\0" +"hatoyama.saitama.jp\0" +"tranibarlettaandria.it\0" +"basketball\0locker\0selfip.net\0" +"schools.nsw.edu.au\0" +"nid.io\0" +"makeup\0" +"doomdns.com\0" +"neat-url.com\0" +"okagaki.fukuoka.jp\0mail-box.ne.jp\0" +"omigawa.chiba.jp\0" +"prd.fr\0" +"katowice.pl\0" +"ns.ca\0" +"s3.dualstack.ap-northeast-1.amazonaws.com\0" +"hiji.oita.jp\0johana.toyama.jp\0" +"servegame.com\0" +"kitakata.miyazaki.jp\0" +"yuki.ibaraki.jp\0kudoyama.wakayama.jp\0" +"soc.lk\0wv.us\0" +"joinville.br\0\xe5\xae\xae\xe5\xb4\x8e.jp\0minamiise.mie.jp\0" +"nl.ca\0" +"yono.saitama.jp\0" +"dating\0dynalias.org\0" +"meme\0d.gv.vc\0from-pr.com\0" +"jaworzno.pl\0main.jp\0" +"lindesnes.no\0nl.ci\0" +"norton\0webhop.biz\0" +"from-wi.com\0" +"pesaro-urbino.it\0\xe4\xb8\x96\xe7\x95\x8c\0" +"s3-website.ap-south-2.amazonaws.com\0" +"\xc3\xb8rskog.no\0" +"blogspot.ae\0" +"um.gov.pl\0" +"nom.za\0" +"s3-object-lambda.ap-northeast-3.amazonaws.com\0" +"etc.br\0" +"zombie.jp\0blogspot.al\0" +"mosj\xc3\xb8""en.no\0blogspot.am\0" +"analytics-gateway.ap-south-1.amazonaws.com\0""1337.pictures\0" +"emrstudio-prod.af-south-1.amazonaws.com\0" +"pv.it\0edu.krd\0" +"games\0cd.eu.org\0" +"v\xc3\xa1rgg\xc3\xa1t.no\0cust.dev.thingdust.io\0" +"uz.ua\0menu\0" +"lib.in.us\0" +"!city.nagoya.jp\0" +"wa.us\0" +"higashiizumo.shimane.jp\0forte.id\0" +"kawaguchi.saitama.jp\0clickrising.net\0" +"po.it\0" +"s3-object-lambda.af-south-1.amazonaws.com\0dyndns.info\0logoip.de\0" +"diadem.cloud\0" +"e164.arpa\0" +"kiyokawa.kanagawa.jp\0kanzaki.saga.jp\0" +"kumakogen.ehime.jp\0rr.leg.br\0" +"sdn.gov.pl\0" +"prd.km\0" +"ascoli-piceno.it\0wnext.app\0" +"video.hu\0ngo.lk\0" +"lier.no\0" +"baidar.no\0shangrila\0" +"akdn\0" +"lodingen.no\0" +"mugi.tokushima.jp\0" +"hashimoto.wakayama.jp\0skr.jp\0" +"lardal.no\0stryn.no\0" +"surf\0" +"pa.it\0schmidt\0" +"boxfuse.io\0from-dc.com\0" +"emilia-romagna.it\0udono.mie.jp\0" +"emrappui-prod.me-south-1.amazonaws.com\0" +"*.ocs.customer-oci.com\0" +"muroran.hokkaido.jp\0mimata.miyazaki.jp\0" +"lincoln\0" +"prd.mg\0" +"us.gov.pl\0" +"s3-object-lambda.eu-south-1.amazonaws.com\0" +"rs.leg.br\0sc.leg.br\0" +"ngo.ng\0" +"choyo.kumamoto.jp\0nakagawa.nagano.jp\0" +"vgs.no\0fhsk.se\0s3.dualstack.il-central-1.amazonaws.com\0" +"witd.gov.pl\0" +"mysecuritycamera.org\0" +"tomika.gifu.jp\0" +"emrstudio-prod.eu-west-3.amazonaws.com\0" +"funabashi.chiba.jp\0health\0" +"horse\0id.repl.co\0" +"shimokawa.hokkaido.jp\0" +"s3-object-lambda.us-west-1.amazonaws.com\0" +"okazaki.aichi.jp\0" +"folkebibl.no\0" +"durban\0" +"law.za\0" +"\xe4\xb8\x89\xe9\x87\x8d.jp\0toya.hokkaido.jp\0" +"tn.us\0" +"wskr.gov.pl\0dnsalias.net\0" +"wafflecell.com\0" +"myvnc.com\0" +"arts.co\0" +"ngo.ph\0" +"safety.aero\0progressive\0" +"trentinsud-tirol.it\0miyazu.kyoto.jp\0qpon\0ch.trendhosting.cloud\0" +"fin.tn\0" +"zappos\0" +"izu.shizuoka.jp\0" +"arte.bo\0teva\0" +"jus.br\0koshigaya.saitama.jp\0" +"barsy.pro\0" +"arakawa.tokyo.jp\0" +"lib.ga.us\0" +"shizukuishi.iwate.jp\0nagahama.shiga.jp\0" +"nexus\0leadpages.co\0" +"ne.jp\0" +"verran.no\0" +"mn.it\0hatogaya.saitama.jp\0takatsuki.shiga.jp\0" +"gotdns.com\0u2-local.xnbay.com\0" +"ne.ke\0" +"sb.ua\0" +"miyoshi.tokushima.jp\0" +"android\0" +"larvik.no\0" +"suli.hu\0framer.media\0" +"saobernardo.br\0\xe6\x96\xb0\xe6\xbd\x9f.jp\0tenri.nara.jp\0ne.kr\0" +"her\xc3\xb8y.nordland.no\0" +"inzai.chiba.jp\0motobu.okinawa.jp\0" +"kawaba.gunma.jp\0" +"barsy.pub\0" +"pmn.it\0iwanai.hokkaido.jp\0" +"wa.gov.au\0" +"doesntexist.com\0" +"chikushino.fukuoka.jp\0" +"iglesias-carbonia.it\0futaba.fukushima.jp\0mima.tokushima.jp\0" +"bulsan-s\xc3\xbc""dtirol.it\0" +"luxe\0" +"fukudomi.saga.jp\0shop.th\0rn.leg.br\0" +"iijima.nagano.jp\0" +"li.it\0tohnosho.chiba.jp\0" +"jprs\0" +"nl.no\0" +"kamifurano.hokkaido.jp\0" +"hof.no\0" +"cheap.jp\0" +"oslo.no\0lerdal.no\0" +"kr.it\0" +"lublin.pl\0" +"chtr.k12.ma.us\0ox.rs\0" +"jcloud-ver-jpc.ik-server.com\0" +"small-web.org\0" +"higashinaruse.akita.jp\0bytom.pl\0" +"gz.cn\0bacgiang.vn\0" +"webview-assets.aws-cloud9.ap-east-1.amazonaws.com\0" +"go.gov.br\0" +"ro.leg.br\0medecin.fr\0" +"ishikari.hokkaido.jp\0" +"trentino-s\xc3\xbc""d-tirol.it\0" +"akita.jp\0hiroo.hokkaido.jp\0" +"shop.ro\0" +"carrd.co\0" +"gs.cn\0" +"reise\0" +"s3-accesspoint.dualstack.il-central-1.amazonaws.com\0" +"haboro.hokkaido.jp\0global\0" +"ap-northeast-1.elasticbeanstalk.com\0x443.pw\0" +"matsuno.ehime.jp\0" +"toscana.it\0" +"\xc3\xb8vre-eiker.no\0" +"s3.dualstack.af-south-1.amazonaws.com\0" +"rifu.miyagi.jp\0" +"fastlylb.net\0fireweb.app\0" +"kameyama.mie.jp\0" +"ne.pw\0ravendb.me\0" +"trentinsuedtirol.it\0" +"inagawa.hyogo.jp\0" +"post.in\0shop.pl\0" +"kirovograd.ua\0" +"s3-accesspoint-fips.us-west-2.amazonaws.com\0" +"toyoake.aichi.jp\0" +"haugesund.no\0" +"s3-accesspoint.me-central-1.amazonaws.com\0" +"daigo.ibaraki.jp\0" +"io.in\0sakai.ibaraki.jp\0ivory.ne.jp\0" +"pa.us\0" +"from.hr\0*.elb.amazonaws.com.cn\0" +"\xe7\xbe\xa4\xe9\xa6\xac.jp\0s3.isk01.sakurastorage.jp\0" +"nt.edu.au\0" +"df.leg.br\0" +"ngo.za\0locus\0" +"aostavalley.it\0" +"ismaili\0" +"izumi.kagoshima.jp\0kanan.osaka.jp\0" +"iida.nagano.jp\0" +"ddnsfree.com\0" +"iiyama.nagano.jp\0" +"software\0" +"ako.hyogo.jp\0" +"arts.ve\0altervista.org\0" +"macapa.br\0" +"baclieu.vn\0" +"mlbfan.org\0io.kg\0" +"miyake.nara.jp\0" +"kiyosu.aichi.jp\0" +"navigation.aero\0bnpparibas\0mitsubishi\0" +"moseushi.hokkaido.jp\0aero.tt\0\xd8\xb9\xd8\xb1\xd8\xa7\xd9\x82\0" +"test-iserv.de\0" +"mifune.kumamoto.jp\0" +"helsinki\0" +"64-b.it\0" +"scrapper-site.net\0" +"vinnytsia.ua\0" +"setagaya.tokyo.jp\0" +"lavagis.no\0ne.ug\0" +"opencraft.hosting\0" +"aero.mv\0ne.tz\0" +"taipei\0" +"samegawa.fukushima.jp\0" +"s3-accesspoint.ap-southeast-4.amazonaws.com\0" +"lib.az.us\0" +"otobe.hokkaido.jp\0toyoura.hokkaido.jp\0uenohara.yamanashi.jp\0" +"karm\xc3\xb8y.no\0ne.us\0analytics\0" +"hokkaido.jp\0" +"ouda.nara.jp\0nanbu.yamanashi.jp\0" +"games.hu\0" +"loginline.dev\0" +"mn.us\0" +"even\xc3\xa1\xc5\xa1\xc5\xa1i.no\0" +"dsmynas.org\0" +"sinaapp.com\0" +"toyotomi.hokkaido.jp\0yamaga.kumamoto.jp\0" +"promo\0" +"langev\xc3\xa5g.no\0" +"balsan-s\xc3\xbc""dtirol.it\0" +"dy.fi\0" +"ge.it\0service.gov.scot\0" +"from-me.org\0" +"makinohara.shizuoka.jp\0" +"arts.ro\0quebec\0technology\0hk.com\0" +"casino.hu\0" +"\xe4\xb8\xad\xe4\xbf\xa1\0" +"krasnodar.su\0" +"nat.tn\0" +"kr.ua\0" +"hopto.org\0" +"ebina.kanagawa.jp\0" +"trainer.aero\0ky.us\0shopware.store\0" +"ent.platform.sh\0" +"chosei.chiba.jp\0unzen.nagasaki.jp\0" +"travelers\0backplaneapp.io\0" +"fg.it\0saka.hiroshima.jp\0uto.kumamoto.jp\0" +"barsy.org\0" +"merseine.nu\0" +"saijo.ehime.jp\0tanabe.kyoto.jp\0haugiang.vn\0" +"ryd.wafaicloud.com\0" +"*.telebit.xyz\0" +"notebook.eu-south-2.sagemaker.aws\0vfs.cloud9.eu-central-1.amazonaws.com\0wellbeingzone.co.uk\0" +"salerno.it\0ostrowwlkp.pl\0" +"likescandy.com\0" +"lundbeck\0" +"binhthuan.vn\0" +"klepp.no\0" +"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86\0se.leg.br\0" +"ac.ae\0chernivtsi.ua\0" +"her\xc3\xb8y.m\xc3\xb8re-og-romsdal.no\0" +"aioi.hyogo.jp\0tsunan.niigata.jp\0arts.nf\0" +"ueno.gunma.jp\0cloudapp.net\0" +"ch.eu.org\0" +"dr.in\0yorii.saitama.jp\0" +"ollo\0" +"ac.at\0" +"ac.be\0vfs.cloud9.af-south-1.amazonaws.com\0" +"shell\0" +"corsica\0" +"\xe5\xa4\xa7\xe5\x88\x86.jp\0" +"shimabara.nagasaki.jp\0" +"uruma.okinawa.jp\0naklo.pl\0" +"ac.ci\0chimkent.su\0" +"reserve-online.net\0" +"aerobatic.aero\0naustdal.no\0" +"ac.cn\0" +"moskenes.no\0" +"ac.cr\0ct.it\0" +"*.kawasaki.jp\0seihi.nagasaki.jp\0" +"stavern.no\0" +"s3-object-lambda.us-east-1.amazonaws.com\0" +"ac.cy\0ally\0" +"industria.bo\0patria.bo\0" +"trondheim.no\0" +"friuliveneziagiulia.it\0" +"kaszuby.pl\0" +"edu.ac\0" +"loisirs.bj\0kishiwada.osaka.jp\0" +"edu.af\0io.vn\0" +"data\0""123hjemmeside.no\0" +"odate.akita.jp\0upper.jp\0" +"emrappui-prod.ap-southeast-2.amazonaws.com\0br.com\0" +"date\0" +"edu.al\0" +"edu.ba\0gjerstad.no\0potager.org\0" +"edu.ar\0edu.bb\0" +"dr.na\0" +"dentist\0" +"edu.au\0www.ro\0" +"ia.us\0s3-accesspoint.eu-central-1.amazonaws.com\0" +"edu.bh\0terni.it\0" +"edu.bi\0drammen.no\0" +"edu.az\0edu.bj\0ac.fj\0" +"bo.it\0kamisunagawa.hokkaido.jp\0" +"edu.bm\0" +"edu.bn\0" +"edu.bo\0oya.to\0" +"s3.dualstack.us-west-2.amazonaws.com\0" +"edu.br\0" +"edu.bs\0" +"edu.bt\0ikeda.osaka.jp\0" +"\xe6\x95\x99\xe8\x82\xb2.\xe9\xa6\x99\xe6\xb8\xaf\0" +"vads\xc3\xb8.no\0" +"zachpomor.pl\0" +"edu.ci\0" +"edu.bz\0" +"cbg.ru\0" +"misasa.tottori.jp\0" +"edu.cn\0ac.gn\0" +"edu.co\0lasalle\0" +"trapani.it\0ogata.akita.jp\0bentre.vn\0" +"verbania.it\0kashiwazaki.niigata.jp\0" +"studio.af-south-1.sagemaker.aws\0" +"beta.tailscale.net\0" +"edu.cu\0" +"edu.cv\0" +"edu.cw\0\xd0\xb1\xd0\xb5\xd0\xbb\0studio.us-east-2.sagemaker.aws\0" +"aq.it\0ba.it\0" +"philips\0s3.sa-east-1.amazonaws.com\0" +"edu.dm\0kongsberg.no\0campaign.gov.uk\0" +"saotome.st\0" +"edu.do\0notteroy.no\0" +"habikino.osaka.jp\0" +"joyo.kyoto.jp\0fly.dev\0pcloud.host\0" +"edu.ec\0stjordal.no\0vfs.cloud9.eu-west-1.amazonaws.com\0" +"ac.id\0" +"edu.ee\0*.vultrobjects.com\0" +"naoshima.kagawa.jp\0" +"edu.eg\0" +"vanylven.no\0drr.ac\0" +"edu.dz\0" +"authgearapps.com\0" +"ac.il\0" +"ac.im\0l\xc3\xb8""dingen.no\0" +"ac.in\0" +"at.eu.org\0" +"6g.in\0" +"ac.ir\0minamiminowa.nagano.jp\0" +"edu.es\0selfip.org\0myqnapcloud.com\0" +"edu.et\0map.fastlylb.net\0" +"ltd.cy\0edu.fm\0" +"ac.jp\0wuoz.gov.pl\0" +"eid.no\0pages.wiardweb.com\0" +"starostwo.gov.pl\0" +"edu.gd\0" +"edu.ge\0ac.ke\0" +"canva-apps.com\0" +"edu.gh\0hanamigawa.chiba.jp\0" +"trading.aero\0edu.gi\0emrappui-prod.ap-northeast-3.amazonaws.com\0" +"auth.us-west-1.amazoncognito.com\0" +"edu.gl\0ohtawara.tochigi.jp\0" +"enterprises\0" +"edu.gn\0gmina.pl\0" +"s3.us-east-1.amazonaws.com\0myspreadshop.com\0" +"edu.gp\0" +"trade\0" +"edu.gr\0ac.kr\0" +"feira.br\0edu.gt\0" +"edu.gu\0shouji\0" +"onflashdrive.app\0" +"vacations\0schulserver.de\0" +"edu.gy\0photos\0" +"edu.hk\0ac.lk\0" +"lecce.it\0wloclawek.pl\0from.tv\0" +"edu.hn\0" +"kashiwara.osaka.jp\0tjmaxx\0" +"ac.ma\0" +"ac.ls\0n\xc3\xa5\xc3\xa5mesjevuemie.no\0" +"edu.ht\0dr.tr\0" +"ac.me\0s3-website.eu-central-2.amazonaws.com\0" +"museum.tt\0" +"amex\0free.hr\0" +"troandin.no\0stada\0ooguy.com\0" +"is-found.org\0" +"ltd.gi\0karmoy.no\0s3-fips.dualstack.us-west-2.amazonaws.com\0" +"edu.in\0" +"auth.eu-west-3.amazoncognito.com\0" +"edu.iq\0" +"edu.is\0" +"edu.it\0" +"ac.mu\0s3-accesspoint-fips.us-west-1.amazonaws.com\0" +"ac.mw\0" +"mitaka.tokyo.jp\0stalowa-wola.pl\0" +"ac.ni\0s3-eu-central-1.amazonaws.com\0" +"ac.mz\0" +"notebook.us-east-1.sagemaker.aws\0" +"eu-west-3.elasticbeanstalk.com\0" +"kurashiki.okayama.jp\0velvet.jp\0" +"edu.jo\0ltd.hk\0" +"est-le-patron.com\0" +"notogawa.shiga.jp\0" +"123hjemmeside.dk\0" +"webview-assets.cloud9.ap-northeast-2.amazonaws.com\0" +"edu.kg\0" +"edu.ki\0" +"ac.nz\0faith\0" +"kasumigaura.ibaraki.jp\0otoyo.kochi.jp\0" +"edu.km\0fetsund.no\0" +"furukawa.miyagi.jp\0bungotakada.oita.jp\0edu.kn\0" +"edu.kp\0" +"edu.la\0lind\xc3\xa5s.no\0ac.pa\0ct.us\0" +"edu.lb\0" +"edu.lc\0cc.sd.us\0" +"opoczno.pl\0\xe1\x83\x92\xe1\x83\x94\0" +"edu.kw\0" +"edu.ky\0" +"edu.kz\0lebork.pl\0online.th\0" +"edu.lk\0" +"ogawa.saitama.jp\0" +"s3-website.ap-southeast-3.amazonaws.com\0" +"edu.lr\0ac.pr\0" +"edu.ls\0*.ap-northeast-2.airflow.amazonaws.com\0" +"shinto.gunma.jp\0" +"edu.me\0nordreisa.no\0" +"edu.lv\0" +"edu.mg\0nordre-land.no\0" +"gyeonggi.kr\0" +"edu.ly\0s3-accesspoint.dualstack.ap-east-1.amazonaws.com\0" +"sdscloud.pl\0" +"edu.mk\0" +"edu.ml\0author\0" +"fastvps.site\0\xd0\xbc\xd0\xb8\xd1\x80.\xd1\x80\xd1\x83\xd1\x81\0" +"edu.mn\0eastus2.azurestaticapps.net\0" +"edu.mo\0gs.ol.no\0" +"training\0" +"edu.ms\0voss.no\0" +"edu.mt\0green\0" +"edu.mv\0" +"edu.mw\0edu.ng\0u2.xnbay.com\0" +"edu.mx\0" +"edu.my\0edu.ni\0" +"edu.mz\0" +"arakawa.saitama.jp\0adobeaemcloud.net\0" +"productions\0" +"*.yokohama.jp\0atl.jelastic.vps-host.net\0" +"ltd.lk\0notebook.eu-north-1.sagemaker.aws\0" +"log.br\0" +"dnsalias.org\0" +"edu.nr\0" +"ac.rs\0degree\0" +"ac.se\0ac.ru\0pagexl.com\0myshopify.com\0" +"ac.rw\0rocky.page\0" +"kahoku.yamagata.jp\0" +"edu.om\0place\0" +"es-1.axarnet.cloud\0" +"fylkesbibl.no\0" +"ariake.saga.jp\0" +"edu.pa\0*.platformsh.site\0" +"caxias.br\0" +"s\xc3\xb8gne.no\0" +"semboku.akita.jp\0" +"edu.pe\0" +"edu.pf\0pages.torproject.net\0" +"sakaiminato.tottori.jp\0edu.ph\0ac.th\0" +"ac.sz\0ac.tj\0kuron.jp\0" +"edu.pk\0ltd.ng\0" +"iheya.okinawa.jp\0wajiki.tokushima.jp\0edu.pl\0" +"edu.pn\0phuyen.vn\0now-dns.net\0ts.net\0" +"edu.qa\0" +"edu.pr\0" +"edu.ps\0" +"edu.pt\0" +"mihara.hiroshima.jp\0" +"ac.ug\0services\0" +"edu.py\0" +"ac.tz\0" +"ac.uk\0" +"other.nf\0" +"hiranai.aomori.jp\0" +"s3-website.us-gov-west-1.amazonaws.com\0" +"webcam\0*.eu-west-2.airflow.amazonaws.com\0" +"raindrop.jp\0" +"ubank\0" +"cagliari.it\0museum.mv\0" +"museum.mw\0" +"nayoro.hokkaido.jp\0" +"yokohama\0" +"z.bg\0fi.cloudplatform.fi\0" +"ac.vn\0" +"museum.no\0edu.sa\0" +"hachirogata.akita.jp\0edu.sb\0" +"edu.rs\0edu.sc\0" +"edu.sd\0" +"tokyo\0edu.ru\0" +"tobetsu.hokkaido.jp\0" +"belau.pw\0edu.sg\0" +"s.bg\0" +"edu.sl\0" +"edu.sn\0" +"museum.om\0edu.so\0s3-website.me-south-1.amazonaws.com\0" +"yamazoe.nara.jp\0" +"edu.ss\0" +"mobi.gp\0\xe4\xba\xac\xe9\x83\xbd.jp\0edu.st\0" +"bir.ru\0" +"edu.sv\0" +"naamesjevuemie.no\0" +"l.bg\0edu.sy\0emrstudio-prod.us-gov-east-1.amazonaws.com\0" +"edu.tj\0" +"rodoy.no\0edu.tm\0" +"shonai.yamagata.jp\0" +"edu.to\0from-ma.com\0" +"edu.ua\0" +"muroto.kochi.jp\0edu.tr\0sblo.jp\0" +"allstate\0" +"name.hr\0saitama.jp\0edu.tt\0fr-par-2.baremetal.scw.cloud\0" +"minakami.gunma.jp\0saku.nagano.jp\0" +"e.bg\0edu.tw\0" +"karumai.iwate.jp\0weber\0" +"m\xc3\xa5lselv.no\0skygearapp.com\0" +"crimea.ua\0" +"takahashi.okayama.jp\0" +"s3-website.dualstack.ap-northeast-1.amazonaws.com\0" +"bykle.no\0" +"usr.cloud.muni.cz\0" +"ac.za\0" +"creditcard\0" +"edu.vc\0" +"edu.ve\0" +"name.et\0hannan.osaka.jp\0unazuki.toyama.jp\0" +"kvalsund.no\0tysv\xc3\xa6r.no\0barsy.co.uk\0" +"edu.uy\0" +"radom.pl\0" +"name.fj\0chijiwa.nagasaki.jp\0" +"ac.zm\0" +"maibara.shiga.jp\0edu.vn\0from-co.net\0" +"emrnotebooks-prod.eu-west-2.amazonaws.com\0" +"*.statics.cloud\0" +"council.aero\0tiaa\0" +"takazaki.miyazaki.jp\0" +"emrappui-prod.ap-southeast-3.amazonaws.com\0" +"adachi.tokyo.jp\0verisign\0half.host\0" +"gen.mi.us\0edu.vu\0ltd.ua\0" +"ac.zw\0" +"gliding.aero\0cc.mi.us\0" +"flier.jp\0" +"emrstudio-prod.eu-central-1.amazonaws.com\0" +"ternopil.ua\0ltd.uk\0au.eu.org\0be.eu.org\0" +"\xe6\x95\x8e\xe8\x82\xb2.hk\0kvafjord.no\0" +"aizumisato.fukushima.jp\0tomiya.miyagi.jp\0" +"edu.ws\0execute-api.ap-northeast-1.amazonaws.com\0emrstudio-prod.us-east-2.amazonaws.com\0" +"meguro.tokyo.jp\0" +"os.hordaland.no\0no-ip.co.uk\0" +"kawanishi.yamagata.jp\0" +"publ.pt\0" +"cooking\0" +"gunma.jp\0ipifony.net\0" +"folldal.no\0" +"indie.porn\0" +"website\0" +"edu.ye\0" +"odo.br\0" +"name.eg\0s3-website.us-gov-east-1.amazonaws.com\0" +"smart\0" +"sakai.osaka.jp\0" +"\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0" +"house\0" +"edu.za\0dclk\0" +"taishin.fukushima.jp\0" +"blogspot.com.cy\0" +"bergen.no\0" +"nuoro.it\0yasuda.kochi.jp\0broker\0" +"yakumo.shimane.jp\0" +"fst.br\0shimoichi.nara.jp\0stripper.jp\0" +"sokndal.no\0" +"name.az\0" +"edu.zm\0" +"chiba.jp\0ba.leg.br\0" +"blogspot.com.ee\0" +"blogspot.com.eg\0" +"skoczow.pl\0" +"id.forgerock.io\0" +"oto.fukuoka.jp\0" +"co.network\0adimo.co.uk\0" +"czest.pl\0" +"passenger-association.aero\0" +"asakawa.fukushima.jp\0" +"4.bg\0" +"minobu.yamanashi.jp\0pinoko.jp\0" +"blogspot.com.ar\0" +"tienda\0" +"gs.hl.no\0bg.eu.org\0blogspot.com.au\0" +"oke.gov.pl\0thaibinh.vn\0" +"theworkpc.com\0" +"quangngai.vn\0" +"midori.chiba.jp\0" +"raholt.no\0framer.wiki\0" +"s3-website.pl-waw.scw.cloud\0" +"exnet.su\0" +"fido\0" +"map.fastly.net\0blogspot.com.br\0" +"koshimizu.hokkaido.jp\0hinode.tokyo.jp\0" +"yoita.niigata.jp\0primetel.cloud\0dsmynas.net\0" +"blogspot.com.by\0" +"fvg.it\0" +"samnanger.no\0blogspot.com.co\0" +"trentinosued-tirol.it\0ainan.ehime.jp\0" +"okinawa\0" +"belem.br\0catanzaro.it\0\xd9\x81\xd9\x84\xd8\xb3\xd8\xb7\xd9\x8a\xd9\x86\0" +"deatnu.no\0" +"asso.fr\0" +"\xe8\x87\xba\xe7\x81\xa3\0" +"barletta-trani-andria.it\0nakanoto.ishikawa.jp\0" +"0e.vc\0" +"ic.gov.pl\0babyblue.jp\0" +"bel.tr\0\xe0\xac\xad\xe0\xac\xbe\xe0\xac\xb0\xe0\xac\xa4\0" +"oppeg\xc3\xa5rd.no\0" +"dyn-o-saur.com\0" +"asso.gp\0" +"\xce\xb5\xce\xbb\0from-pa.com\0" +"shimane.jp\0higashitsuno.kochi.jp\0" +"rdv.to\0" +"blogspot.com.es\0" +"cya.gg\0" +"nowruz\0b.ssl.fastly.net\0" +"vestv\xc3\xa5g\xc3\xb8y.no\0" +"\xd0\xb4\xd0\xb5\xd1\x82\xd0\xb8\0lovepop.jp\0" +"\xce\xb5\xcf\x85\0partners\0" +"ozora.hokkaido.jp\0ota.tokyo.jp\0" +"modum.no\0notebook.us-east-2.sagemaker.aws\0github.io\0" +"higashiyoshino.nara.jp\0" +"vfs.cloud9.us-west-2.amazonaws.com\0stackhero-network.com\0" +"asso.ht\0noda.chiba.jp\0" +"audnedaln.no\0" +"vindafjord.no\0" +"lib.wy.us\0" +"fuchu.toyama.jp\0" +"kddi\0" +"sor-varanger.no\0" +"aizumi.tokushima.jp\0" +"padua.it\0chigasaki.kanagawa.jp\0" +"gamvik.no\0" +"iwakura.aichi.jp\0" +"s3-accesspoint.dualstack.ap-southeast-3.amazonaws.com\0" +"takahama.aichi.jp\0" +"hr.eu.org\0" +"cc.gu.us\0\xd0\xba\xd1\x80\xd1\x8b\xd0\xbc.\xd1\x80\xd1\x83\xd1\x81\0" +"takayama.nagano.jp\0wake.okayama.jp\0" +"muos\xc3\xa1t.no\0" +"numazu.shizuoka.jp\0" +"jls-sto2.elastx.net\0" +"baseball\0" +"is-a-conservative.com\0" +"asso.ci\0" +"am.leg.br\0" +"pesarourbino.it\0" +"xy.ax\0" +"s3.dualstack.sa-east-1.amazonaws.com\0ap-south-1.elasticbeanstalk.com\0" +"loginline.app\0" +"kikuchi.kumamoto.jp\0tatsuno.nagano.jp\0" +"tec.br\0" +"z.se\0barsy.menu\0" +"minami-alps.yamanashi.jp\0lapy.pl\0" +"misato.akita.jp\0" +"lillehammer.no\0t\xc3\xb8nsberg.no\0httpbin.org\0" +"yatsushiro.kumamoto.jp\0schwarz\0" +"s.se\0film\0" +"vpnplus.to\0" +"capital\0" +"asso.dz\0" +"nesoddtangen.no\0ap-southeast-3.elasticbeanstalk.com\0" +"bar1.net\0" +"zaporizhzhia.ua\0" +"us-west-2.elasticbeanstalk.com\0" +"marugame.kagawa.jp\0" +"tobe.ehime.jp\0kosher\0" +"l.se\0mini\0is-a-hard-worker.com\0" +"olbia-tempio.it\0" +"hoyanger.no\0hughes\0" +"esan.hokkaido.jp\0" +"mock.pstmn.io\0" +"mint\0" +"e.se\0" +"parliament.nz\0" +"gran.no\0svelvik.no\0" +"date.fukushima.jp\0" +"dnsup.net\0" +"egersund.no\0" +"shintomi.miyazaki.jp\0" +"\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\0" +"skjerv\xc3\xb8y.no\0lib.tx.us\0" +"name.vn\0" +"s3-object-lambda.ap-northeast-2.amazonaws.com\0" +"chihayaakasaka.osaka.jp\0" +"tips\0" +"okawa.fukuoka.jp\0moonscale.net\0" +"futurehosting.at\0" +"kainan.tokushima.jp\0" +"media.hu\0flesberg.no\0" +"shiftcrypto.io\0" +"blogspot.com.mt\0" +"ip6.arpa\0" +"blogspot.com.ng\0" +"aca.pro\0" +"emrnotebooks-prod.ap-southeast-3.amazonaws.com\0lohmus.me\0" +"oppdal.no\0" +"hob\xc3\xb8l.no\0" +"latina.it\0" +"seki.gifu.jp\0name.tj\0" +"ap.leg.br\0" +"magazine.aero\0schulplattform.de\0" +"kunimi.fukushima.jp\0shiroishi.miyagi.jp\0fujikawaguchiko.yamanashi.jp\0" +"plumbing\0" +"es.gov.br\0kozagawa.wakayama.jp\0" +"mangyshlak.su\0sakuratan.com\0" +"name.tr\0" +"wmflabs.org\0" +"name.tt\0" +"s3-fips.us-east-2.amazonaws.com\0" +"mobi.tt\0" +"sandnessjoen.no\0gjovik.no\0" +"olecko.pl\0girlfriend.jp\0lubartow.pl\0" +"mircloud.host\0" +"emrstudio-prod.eu-west-2.amazonaws.com\0" +"suedtirol.it\0mobi.tz\0" +"webview-assets.cloud9.ap-east-1.amazonaws.com\0vfs.cloud9.ap-northeast-3.amazonaws.com\0freeddns.us\0" +"fire\0" +"vegarshei.no\0daplie.me\0members.linode.com\0" +"gjesdal.no\0" +"sells-it.net\0" +"lib.sd.us\0" +"horonobe.hokkaido.jp\0" +"otama.fukushima.jp\0" +"asahi.ibaraki.jp\0misaki.okayama.jp\0kakegawa.shizuoka.jp\0dental\0blogspot.com.tr\0gov.scot\0" +"info.gu\0cc.co.us\0asso.eu.org\0" +"higashiura.aichi.jp\0" +"hzc.io\0" +"trentinos-tirol.it\0" +"chikuma.nagano.jp\0" +"sa-east-1.elasticbeanstalk.com\0eurodir.ru\0" +"chikuho.fukuoka.jp\0fish\0" +"statebank\0" +"hitachiomiya.ibaraki.jp\0" +"strand.no\0" +"webview-assets.aws-cloud9.eu-central-1.amazonaws.com\0" +"pvh.br\0" +"presse.km\0airkitapps-au.com\0" +"info.ht\0" +"info.hu\0" +"stj\xc3\xb8rdalshalsen.no\0" +"email\0" +"black\0webview-assets.aws-cloud9.us-east-1.amazonaws.com\0" +"report\0" +"info.in\0yokoshibahikari.chiba.jp\0yakumo.hokkaido.jp\0kiho.mie.jp\0" +"softbank\0servesarcasm.com\0" +"cc.ca.us\0" +"info.et\0chikugo.fukuoka.jp\0nishigo.fukushima.jp\0" +"read\0" +"name.pm\0" +"kaas.gg\0" +"info.fj\0urbinopesaro.it\0kalisz.pl\0" +"name.qa\0" +"name.pr\0" +"platterp.us\0" +"otake.hiroshima.jp\0" +"cc.az.us\0" +"dep.no\0encoreapi.com\0" +"presse.ml\0" +"evenassi.no\0s3-accesspoint.ap-northeast-2.amazonaws.com\0" +"n\xc3\xa1vuotna.no\0brussels\0" +"yamato.kanagawa.jp\0" +"\xe5\xb1\xb1\xe5\x8f\xa3.jp\0mods.jp\0" +"monash\0" +"name.na\0kautokeino.no\0" +"kamisu.ibaraki.jp\0uzs.gov.pl\0" +"jogasz.hu\0mobi.na\0cc.as.us\0us.eu.org\0" +"selfip.biz\0" +"auth-fips.us-east-1.amazoncognito.com\0emrnotebooks-prod.af-south-1.amazonaws.com\0dyndns-mail.com\0" +"ise.mie.jp\0name.mv\0" +"name.ng\0s3-accesspoint.dualstack.me-south-1.amazonaws.com\0from-ar.com\0" +"fuefuki.yamanashi.jp\0" +"a\xc3\xa9roport.ci\0name.my\0mobi.ng\0kyiv.ua\0" +"k12.co.us\0" +"keisen.fukuoka.jp\0info.cx\0" +"act.au\0auth.ap-south-1.amazoncognito.com\0webview-assets.aws-cloud9.eu-west-1.amazonaws.com\0golffan.us\0" +"media.pl\0deal\0" +"cc.al.us\0" +"valle-aosta.it\0vv.it\0" +"bieszczady.pl\0langson.vn\0" +"dopaas.com\0" +"ma.gov.br\0" +"rivne.ua\0emrnotebooks-prod.me-central-1.amazonaws.com\0" +"2-d.jp\0" +"info.ec\0\xc3\xa1k\xc5\x8boluokta.no\0" +"aosta-valley.it\0satte.saitama.jp\0" +"sn.cn\0trentino-suedtirol.it\0" +"s\xc3\xb8r-varanger.no\0" +"dev-myqnapcloud.com\0" +"blogspot.com.uy\0diskstation.org\0" +"123website.nl\0" +"rotorcraft.aero\0dyndns.org\0" +"s3-website.dualstack.ap-southeast-1.amazonaws.com\0" +"l\xc3\xb8renskog.no\0" +"info.bb\0" +"k12.ca.us\0" +"info.at\0" +"info.au\0" +"\xe0\xa8\xad\xe0\xa8\xbe\xe0\xa8\xb0\xe0\xa8\xa4\0" +"karaganda.su\0" +"info.az\0info.bj\0" +"aurskog-holand.no\0s3-ap-southeast-2.amazonaws.com\0" +"mup.gov.pl\0" +"alstahaug.no\0" +"info.bo\0\xd5\xb0\xd5\xa1\xd5\xb5\0\xd9\x82\xd8\xb7\xd8\xb1\0from-wv.com\0" +"g12.br\0erimo.hokkaido.jp\0" +"bomlo.no\0asso.re\0" +"market\0" +"name.mk\0" +"va.it\0prochowice.pl\0" +"h\xc3\xa1mm\xc3\xa1rfeasta.no\0" +"kijo.miyazaki.jp\0shimane.shimane.jp\0pruszkow.pl\0" +"kumano.hiroshima.jp\0okaya.nagano.jp\0" +"info.co\0" +"hiraizumi.iwate.jp\0goodyear\0" +"fie.ee\0\xc3\xb8rsta.no\0" +"123website.lu\0" +"streamlit.app\0" +"kr\xc3\xb8""dsherad.no\0" +"name.jo\0s3.me-south-1.amazonaws.com\0" +"takanabe.miyazaki.jp\0anquan\0" +"chippubetsu.hokkaido.jp\0kilo.jp\0" +"idv.hk\0synology.me\0" +"tuscany.it\0" +"mobi.ke\0" +"ts.it\0" +"arao.kumamoto.jp\0mail.pl\0" +"lib.ms.us\0lib.nc.us\0" +"community\0rocks\0service.gov.uk\0" +"studio.cn-north-1.sagemaker.com.cn\0" +"dyndns-blog.com\0" +"football\0" +"vote\0" +"pro.typeform.com\0" +"lib.nh.us\0arkhangelsk.su\0" +"now-dns.org\0" +"slg.br\0\xe4\xba\x9a\xe9\xa9\xac\xe9\x80\x8a\0" +"ogano.saitama.jp\0" +"voto\0" +"te.it\0" +"asso.nc\0" +"s3-object-lambda.cn-northwest-1.amazonaws.com.cn\0" +"takasu.hokkaido.jp\0hiratsuka.kanagawa.jp\0" +"pri.ee\0" +"ichinoseki.iwate.jp\0" +"lib.ma.us\0s3-website.dualstack.us-west-2.amazonaws.com\0dyndns-wiki.com\0" +"reit\0" +"il.eu.org\0" +"naturbruksgymn.se\0myfirewall.org\0" +"dojin.com\0" +"higashishirakawa.gifu.jp\0hita.oita.jp\0arai.shizuoka.jp\0" +"izunokuni.shizuoka.jp\0host\0" +"kiev.ua\0" +"kasuga.hyogo.jp\0ravendb.run\0" +"va.no\0" +"mediocampidano.it\0" +"tec.ve\0prequalifyme.today\0" +"isa-geek.org\0ddnsgeek.com\0" +"honefoss.no\0framercanvas.com\0" +"ribeirao.br\0open\0" +"frontier\0" +"reliance\0" +"\xe5\x9c\xa8\xe7\xba\xbf\0tuleap-partners.com\0" +"nishimera.miyazaki.jp\0stcgroup\0" +"homedns.org\0" +"jls-sto1.elastx.net\0" +"s\xc3\xa1l\xc3\xa1t.no\0" +"s3.dualstack.ap-southeast-3.amazonaws.com\0" +"hu.eu.org\0ie.eu.org\0" +"money.bj\0ono.fukui.jp\0mito.ibaraki.jp\0oow.gov.pl\0" +"consulting\0" +"takahama.fukui.jp\0" +"storage\0" +"kvits\xc3\xb8y.no\0" +"nx.cn\0" +"tadotsu.kagawa.jp\0" +"ri.it\0furudono.fukushima.jp\0matsumae.hokkaido.jp\0" +"profesional.bo\0kommune.no\0leikanger.no\0" +"gwangju.kr\0hashbang.sh\0" +"freesite.host\0" +"us-4.evennode.com\0" +"\xe5\xa8\xb1\xe4\xb9\x90\0" +"execute-api.us-west-1.amazonaws.com\0" +"toyooka.hyogo.jp\0cloudns.club\0" +"appspacehosted.com\0" +"tsushima.aichi.jp\0ugim.gov.pl\0" +"aeroclub.aero\0" +"omura.nagasaki.jp\0kirara.st\0" +"appspaceusercontent.com\0" +"dell\0ngrok.app\0" +"bolivia.bo\0clinic\0\xec\x82\xbc\xec\x84\xb1\0" +"hobol.no\0" +"poa.br\0" +"bo.nordland.no\0" +"snaase.no\0s3-accesspoint.dualstack.us-gov-east-1.amazonaws.com\0" +"rent\0" +"val-daosta.it\0" +"asso.km\0" +"kiyosato.hokkaido.jp\0" +"altoadige.it\0" +"dgca.aero\0mortgage\0" +"pt.it\0" +"selfip.com\0" +"oga.akita.jp\0kusu.oita.jp\0" +"s3.ap-southeast-2.amazonaws.com\0dyndns-free.com\0""123website.be\0" +"esashi.hokkaido.jp\0czeladz.pl\0" +"fosnes.no\0" +"itigo.jp\0" +"jcloud.ik-server.com\0" +"tsukumi.oita.jp\0" +"asso.mc\0is-a-geek.com\0" +"hiho.jp\0" +"stream\0" +"info.ve\0" +"circle\0co.com\0virtual-user.de\0" +"deta.app\0""123website.ch\0" +"s3.dualstack.eu-west-3.amazonaws.com\0" +"koori.fukushima.jp\0kembuchi.hokkaido.jp\0info.vn\0" +"ulvik.no\0us-3.evennode.com\0" +"yamanashi.yamanashi.jp\0" +"va.us\0" +"ln.cn\0" +"consultant.aero\0money\0istmein.de\0" +"s3.cn-northwest-1.amazonaws.com.cn\0" +"rodeo\0" +"nerdpol.ovh\0" +"xs4all.space\0" +"hirado.nagasaki.jp\0" +"beats\0" +"tomari.hokkaido.jp\0" +"delta\0blogsite.org\0" +"ven.it\0genova.it\0chita.aichi.jp\0" +"is-a-liberal.com\0" +"nichinan.tottori.jp\0" +"balsan.it\0" +"vinnica.ua\0" +"tychy.pl\0" +"hidaka.hokkaido.jp\0mormon\0" +"drud.io\0" +"info.tn\0fem.jp\0" +"abo.pa\0lib.il.us\0apartments\0s3.dualstack.us-east-2.amazonaws.com\0" +"info.tr\0binhphuoc.vn\0" +"sakuragawa.ibaraki.jp\0kagoshima.kagoshima.jp\0info.tt\0" +"qc.com\0" +"rest\0" +"idv.tw\0" +"info.tz\0" +"te.ua\0traeumtgerade.de\0" +"lib.gu.us\0scrapping.cc\0" +"calvinklein\0" +"vikna.no\0s3-object-lambda.us-east-2.amazonaws.com\0" +"ishigaki.okinawa.jp\0" +"yokoze.saitama.jp\0" +"dyndns-at-home.com\0" +"trentinosud-tirol.it\0saga.jp\0" +"desi\0webview-assets.cloud9.eu-west-2.amazonaws.com\0bryansk.su\0" +"mango\0" +"\xe7\x86\x8a\xe6\x9c\xac.jp\0lomza.pl\0" +"it.ao\0" +"aki.kochi.jp\0ube.yamaguchi.jp\0" +"barsy.mobi\0" +"k8s.nl-ams.scw.cloud\0" +"info.ro\0us-2.evennode.com\0" +"hadsel.no\0masoy.no\0nordkapp.no\0" +"ms.it\0kaizuka.osaka.jp\0" +"info.sd\0" +"nodes.k8s.pl-waw.scw.cloud\0" +"\xe9\xa6\x99\xe6\xb8\xaf\0gr.eu.org\0ybo.party\0" +"*.cns.joyent.com\0" +"mitane.akita.jp\0hitachi.ibaraki.jp\0" +"ullensvang.no\0" +"fet.no\0" +"bearalv\xc3\xa1hki.no\0" +"yandex\0" +"ski.no\0xfinity\0s3-accesspoint.dualstack.eu-south-2.amazonaws.com\0" +"awsglobalaccelerator.com\0" +"me.in\0daejeon.kr\0chu.jp\0" +"seg.br\0warmia.pl\0\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0" +"info.pk\0" +"ome.tokyo.jp\0info.pl\0" +"s3-accesspoint.ap-northeast-3.amazonaws.com\0from-ak.com\0" +"lu.it\0me.it\0" +"presse.ci\0emrstudio-prod.ap-south-1.amazonaws.com\0" +"ms.kr\0" +"vossevangen.no\0servegame.org\0" +"kuchinotsu.nagasaki.jp\0info.pr\0" +"nakagawa.hokkaido.jp\0suzu.ishikawa.jp\0daklak.vn\0orx.biz\0" +"\xc3\xa5mot.no\0radio\0" +"fnc.fr-par.scw.cloud\0" +"cf-ipfs.com\0" +"eu.meteorapp.com\0" +"suldal.no\0isa-geek.com\0" +"nishikata.tochigi.jp\0" +"me.ke\0" +"piemonte.it\0tuyenquang.vn\0" +"info.na\0" +"ri.us\0" +"info.mv\0info.nf\0" +"is-a-republican.com\0" +"info.ni\0stjordalshalsen.no\0" +"kwp.gov.pl\0" +"romsa.no\0" +"iki.nagasaki.jp\0" +"s3-website.us-west-1.amazonaws.com\0us-1.evennode.com\0paas.massivegrid.com\0" +"cherkasy.ua\0" +"info.nr\0" +"\xd9\x85\xd9\x88\xd8\xb1\xd9\x8a\xd8\xaa\xd8\xa7\xd9\x86\xd9\x8a\xd8\xa7\0" +"lg.jp\0" +"kanna.gunma.jp\0" +"software.aero\0kozow.com\0site.transip.me\0" +"securitytactics.com\0" +"enf.br\0trentino-alto-adige.it\0" +"apps.lair.io\0" +"info.la\0randaberg.no\0baby\0tools\0wphostedmail.com\0" +"gx.cn\0vao.it\0dscloud.biz\0" +"plc.co.im\0\xe9\xa3\x9f\xe5\x93\x81\0" +"*.us-east-1.airflow.amazonaws.com\0" +"s3-website.dualstack.sa-east-1.amazonaws.com\0vladikavkaz.ru\0" +"webhosting.be\0is-a-geek.org\0" +"websozai.jp\0" +"atsuma.hokkaido.jp\0tsushima.nagasaki.jp\0" +"kppsp.gov.pl\0" +"ha.cn\0" +"emrappui-prod.ap-northeast-2.amazonaws.com\0s3-accesspoint.dualstack.ap-south-2.amazonaws.com\0serveirc.com\0" +"nikaho.akita.jp\0" +"info.ls\0ftpaccess.cc\0" +"mjondalen.no\0s3.us-east-2.amazonaws.com\0vladikavkaz.su\0" +"shimogo.fukushima.jp\0" +"gs.svalbard.no\0rag-cloud-ch.hosteur.com\0" +"kadoma.osaka.jp\0" +"postman-echo.com\0" +"urbino-pesaro.it\0" +"gc.ca\0andasuolo.no\0" +"page\0" +"harima.hyogo.jp\0" +"osoyro.no\0est-mon-blogueur.com\0" +"j\xc3\xb8lster.no\0" +"togura.nagano.jp\0" +"discordsez.com\0impertrixcdn.com\0" +"hichiso.gifu.jp\0but.jp\0" +"\xe5\x98\x89\xe9\x87\x8c\0" +"government.aero\0" +"tokigawa.saitama.jp\0" +"mints.ne.jp\0eu.ax\0" +"hamar.no\0" +"info.ke\0s3-fips.dualstack.us-west-1.amazonaws.com\0" +"*.sendai.jp\0homeip.net\0" +"info.ki\0" +"akkeshi.hokkaido.jp\0bitter.jp\0" +"im.it\0ito.shizuoka.jp\0" +"kropyvnytskyi.ua\0" +"fujimino.saitama.jp\0" +"cisco\0" +"oh.us\0" +"munakata.fukuoka.jp\0pgafan.net\0" +"\xc3\xa1lt\xc3\xa1.no\0s3.us-gov-west-1.amazonaws.com\0is-a-bookkeeper.com\0" +"moo.jp\0" +"davvesiida.no\0" +"gujarat.in\0" +"mg.gov.br\0dellogliastra.it\0oishida.yamagata.jp\0" +"dielddanuorri.no\0drud.us\0" +"upow.gov.pl\0" +"ora.gunma.jp\0" +"padova.it\0dabur\0" +"s3-website.sa-east-1.amazonaws.com\0" +"port.fr\0" +"supabase.net\0" +"notebook.me-central-1.sagemaker.aws\0" +"kunneppu.hokkaido.jp\0sanagochi.tokushima.jp\0nc.tr\0" +"s3-website-us-east-1.amazonaws.com\0" +"nj.us\0" +"s3-website.ap-northeast-1.amazonaws.com\0s3-website.ap-southeast-4.amazonaws.com\0" +"guardian\0" +"hasura.app\0" +"me.so\0s3-fips.us-west-1.amazonaws.com\0" +"rzeszow.pl\0dienbien.vn\0" +"vennesla.no\0" +"anamizu.ishikawa.jp\0" +"tananger.no\0me.ss\0me.tc\0" +"ms.us\0nc.us\0s3-fips.ca-central-1.amazonaws.com\0" +"nanjo.okinawa.jp\0" +"*.us-west-2.airflow.amazonaws.com\0" +"kasuga.fukuoka.jp\0" +"is-a-candidate.org\0" +"niikappu.hokkaido.jp\0" +"mc.eu.org\0" +"higashi.fukushima.jp\0" +"berg.no\0" +"me.tz\0" +"me.uk\0wang\0" +"is-gone.com\0" +"takayama.gifu.jp\0ibara.okayama.jp\0" +"dnshome.de\0" +"\xe6\xa0\x83\xe6\x9c\xa8.jp\0" +"me.us\0" +"sasebo.nagasaki.jp\0" +"on-aptible.com\0" +"kumano.mie.jp\0iwatsuki.saitama.jp\0ngrok.dev\0" +"s3-accesspoint.us-east-1.amazonaws.com\0" +"hanawa.fukushima.jp\0" +"namsskogan.no\0" +"is-an-actress.com\0" +"s3.cn-north-1.amazonaws.com.cn\0" +"lg.ua\0" +"matsukawa.nagano.jp\0" +"4.azurestaticapps.net\0" +"umb.it\0" +"cahcesuolo.no\0aaa\0lt.eu.org\0" +"me.vu\0" +"s3-accesspoint.dualstack.ap-northeast-3.amazonaws.com\0" +"trentins\xc3\xbc""d-tirol.it\0vps-host.net\0" +"vfs.cloud9.ap-southeast-1.amazonaws.com\0" +"onthewifi.com\0" +"isshiki.aichi.jp\0yamashina.kyoto.jp\0" +"ru.com\0" +"yamato.fukushima.jp\0band\0" +"friulivenezia-giulia.it\0fe.it\0abb\0" +"abc\0s3.ap-southeast-3.amazonaws.com\0" +"shichikashuku.miyagi.jp\0" +"s3-website.dualstack.us-west-1.amazonaws.com\0forgot.his.name\0" +"bedzin.pl\0" +"tr\xc3\xb8gstad.no\0bank\0" +"isahaya.nagasaki.jp\0" +"volyn.ua\0" +"tourism.tn\0flir\0" +"management\0" +"pordenone.it\0ninhthuan.vn\0cocotte.jp\0" +"barsy.info\0" +"en.it\0takino.hyogo.jp\0" +"s3-object-lambda.us-gov-east-1.amazonaws.com\0" +"duckdns.org\0" +"sardinia.it\0otofuke.hokkaido.jp\0" +"ha.no\0pgfog.com\0" +"dh.bytemark.co.uk\0" +"jelenia-gora.pl\0" +"ce.leg.br\0" +"mobile\0" +"aco\0" +"takarazuka.hyogo.jp\0omaezaki.shizuoka.jp\0" +"amakusa.kumamoto.jp\0" +"cologne\0" +"mombetsu.hokkaido.jp\0" +"\xd9\x83\xd9\x88\xd9\x85\0" +"meland.no\0appspot.com\0" +"spjelkavik.no\0" +"sakae.chiba.jp\0minamioguni.kumamoto.jp\0arab\0""123siteweb.fr\0" +"airkitapps.eu\0" +"akita.akita.jp\0" +"lorenskog.no\0" +"kuki.saitama.jp\0flynnhosting.net\0" +"ads\0pars\0g\xc3\xbcnstigbestellen.de\0paas.beebyte.io\0" +"boy.jp\0jellybean.jp\0" +"ah.cn\0" +"aeg\0" +"click\0network\0" +"kagami.kochi.jp\0morotsuka.miyazaki.jp\0" +"hirogawa.wakayama.jp\0" +"netlify.app\0" +"router.management\0" +"ichihara.chiba.jp\0" +"miyakonojo.miyazaki.jp\0" +"kiengiang.vn\0" +"cr.it\0" +"gov.ac\0" +"appudo.net\0" +"gov.ae\0webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com\0" +"gov.af\0\xda\x80\xd8\xa7\xd8\xb1\xd8\xaa\0afl\0" +"eigersund.no\0if.ua\0bingo\0s3-accesspoint.dualstack.eu-north-1.amazonaws.com\0" +"tur.ar\0katashina.gunma.jp\0" +"gov.al\0" +"erotica.hu\0" +"soo.kagoshima.jp\0\xd8\xa7\xd9\x84\xd9\x8a\xd9\x85\xd9\x86\0poznan.pl\0" +"webview-assets.cloud9.eu-west-3.amazonaws.com\0woltlab-demo.com\0" +"gov.ba\0" "gov.ar\0gov.bb\0" -"gov.as\0kamijima.ehime.jp\0" -"iwate.jp\0nahari.kochi.jp\0uol\0" +"gov.as\0rad\xc3\xb8y.no\0" +"nakasatsunai.hokkaido.jp\0ami.ibaraki.jp\0osakasayama.osaka.jp\0store.nf\0" "gov.au\0" "gov.bf\0" -"ora.gunma.jp\0" -"gov.bh\0" -"r\xc3\xb8yrvik.no\0" +"gov.bh\0tur.br\0" +"emrstudio-prod.ap-southeast-3.amazonaws.com\0" "gov.az\0" -"tokushima.tokushima.jp\0" -"gov.bm\0" -"gov.bn\0" -"\xd0\xbc\xd0\xba\xd0\xb4\0" -"gov.br\0office\0" +"cc.wv.us\0" +"gov.bm\0tula.su\0" +"gov.bn\0bt.it\0" +"from-ne.com\0herokuapp.com\0" +"cesena-forli.it\0omiya.saitama.jp\0chowder.jp\0" +"kvinesdal.no\0" +"gov.br\0" "gov.bs\0" -"gov.bt\0gov.cd\0\xd1\x8f.\xd1\x80\xd1\x83\xd1\x81\0" -"shirakawa.gifu.jp\0" -"hasura-app.io\0" -"tm.za\0" -"freesite.host\0" -"gov.by\0barrel-of-knowledge.info\0storebase.store\0" -"gov.bz\0blogspot.com.tr\0" -"gob.ar\0ups\0rdy.jp\0" +"gov.bt\0gov.cd\0isesaki.gunma.jp\0\xe6\x8b\x9b\xe8\x81\x98\0" +"remotewd.com\0" +"kisofukushima.nagano.jp\0" +"ashiya.fukuoka.jp\0" +"gov.by\0s3-object-lambda.us-gov-west-1.amazonaws.com\0studio.il-central-1.sagemaker.aws\0" +"gov.bz\0" "gov.cl\0" "gov.cm\0" "gov.cn\0" "gov.co\0" -"trentinosudtirol.it\0minamiminowa.nagano.jp\0kudoyama.wakayama.jp\0ashgabad.su\0" -"radio.am\0" -"ebiz.tw\0" -"port.fr\0chrome\0" -"gov.cu\0shizukuishi.iwate.jp\0" -"gob.bo\0gov.cx\0" -"gov.cy\0" -"szkola.pl\0no-ip.net\0" -"gov.dm\0" -"gov.do\0free.hr\0" -"lib.pa.us\0" -"chimkent.su\0" -"gov.ec\0" -"cc.ia.us\0" -"gob.cl\0gov.ee\0" -"radio.br\0gov.eg\0fyresdal.no\0" -"naroy.no\0sanok.pl\0" -"\xe5\xae\xb6\xe9\x9b\xbb\0" -"gov.dz\0" -"fie.ee\0" -"mosvik.no\0" -"skedsmo.no\0myiphost.com\0" -"shibecha.hokkaido.jp\0" -"cbre\0" -"ng.eu.org\0" -"gov.et\0wake.okayama.jp\0" -"gouv.km\0" -"trading.aero\0" -"gob.do\0immo\0freetls.fastly.net\0" -"gov.fj\0" -"tsukumi.oita.jp\0me.so\0hopto.org\0" -"gob.ec\0health.nz\0" -"higashi.fukuoka.jp\0" -"minamimaki.nagano.jp\0hangout\0" -"me.ss\0me.tc\0" -"hasama.oita.jp\0gen.mi.us\0" -"haugiang.vn\0cloud\0" -"tv.bb\0gov.gd\0" -"gov.ge\0" -"mobi.tt\0" -"gov.gh\0\xd0\xbc\xd0\xbe\xd0\xbd\0" -"conference.aero\0gov.gi\0" -"nara.nara.jp\0frosta.no\0" -"gob.es\0kawazu.shizuoka.jp\0ivgu.no\0mobi.tz\0" -"gov.gn\0" -"averoy.no\0" -"forex\0" -"tv.bo\0vercel.dev\0" -"gov.gr\0hatogaya.saitama.jp\0dnsdojo.com\0" -"tv.br\0sekigahara.gifu.jp\0pup.gov.pl\0blockbuster\0" -"gov.gu\0""6g.in\0gouv.ml\0kristiansund.no\0" -"susaki.kochi.jp\0me.tz\0" -"me.uk\0" -"satte.saitama.jp\0" -"gov.gy\0" -"genoa.it\0" -"gov.hk\0muroto.kochi.jp\0" -"vet\0" -"me.us\0yamaxun\0" -"pvt.k12.ma.us\0blogspot.com.uy\0" -"trysil.no\0po.gov.pl\0radio.fm\0" -"tomobe.ibaraki.jp\0" -"gov.ie\0" -"komatsu.ishikawa.jp\0" -"keisen.fukuoka.jp\0yoro.gifu.jp\0mosj\xc3\xb8""en.no\0" -"ce.it\0h\xc3\xa6gebostad.no\0" -"diskussionsbereich.de\0" -"gov.il\0" -"gob.gt\0yamato.fukushima.jp\0" -"gov.in\0" -"kitagawa.miyazaki.jp\0" -"edgekey-staging.net\0" -"gov.iq\0erimo.hokkaido.jp\0me.vu\0" -"gov.ir\0" -"gov.is\0sera.hiroshima.jp\0" -"gov.it\0nieruchomosci.pl\0" -"watarai.mie.jp\0wakayama.wakayama.jp\0" -"airtraffic.aero\0sigdal.no\0" -"gob.hn\0sassari.it\0" -"la.us\0termez.su\0" -"salerno.it\0" -"dyndns-server.com\0mcpe.me\0" -"aguni.okinawa.jp\0r\xc3\xa5""de.no\0" -"myspreadshop.es\0" -"gov.jo\0" -"m.bg\0kep.tr\0" -"aq.it\0ba.it\0ca-central-1.elasticbeanstalk.com\0" -"angiang.vn\0myspreadshop.fi\0" -"shibata.niigata.jp\0gov.kg\0" -"gildeskal.no\0" -"misaki.okayama.jp\0gov.ki\0" -"awsmppl.com\0" -"meland.no\0webview-assets.cloud9.eu-central-1.amazonaws.com\0us-west-2.elasticbeanstalk.com\0" -"forgeblocks.com\0myspreadshop.fr\0" -"riopreto.br\0gov.km\0akamaihd-staging.net\0" -"gov.kn\0" -"vig\0\xd0\xba\xd0\xb0\xd1\x82\xd0\xbe\xd0\xbb\xd0\xb8\xd0\xba\0" -"bibai.hokkaido.jp\0gov.kp\0" -"tokyo.jp\0gov.la\0azure-mobile.net\0" -"gov.lb\0" -"gov.lc\0mobi.na\0" -"teo.br\0k12.ma.us\0" -"olecko.pl\0toshiba\0" -"viking\0vin\0" -"gov.kw\0webview-assets.aws-cloud9.me-south-1.amazonaws.com\0" -"vip\0" -"mobi.ng\0webview-assets.cloud9.us-east-2.amazonaws.com\0" -"gov.kz\0salangen.no\0pol.tr\0" -"gov.lk\0" -"friulivegiulia.it\0" -"morena.br\0" -"store.bb\0sabae.fukui.jp\0" -"gov.ma\0tsk.tr\0" -"gov.lr\0" -"gov.ls\0" -"gov.lt\0" -"hidaka.hokkaido.jp\0gov.me\0skierva.no\0" -"bozen.it\0gov.lv\0" -"gov.mg\0zgorzelec.pl\0" -"gov.ly\0fashion\0" -"gov.mk\0" -"gov.ml\0land\0from-wy.com\0" -"watari.miyagi.jp\0gov.mn\0podhale.pl\0" -"gov.mo\0boutir.com\0myspreadshop.ie\0" -"health.vn\0" -"gov.mr\0" -"gov.ms\0bu.no\0" -"gov.mu\0kaufen\0" -"gov.mv\0kozow.com\0" -"venezia.it\0gov.mw\0gov.ng\0" -"ringsaker.no\0" -"gov.my\0gitpage.si\0jls-sto2.elastx.net\0" -"gov.mz\0" -"weatherchannel\0" -"gov.nl\0" -"cherkassy.ua\0myspreadshop.at\0" -"tv.im\0myspreadshop.be\0" -"tv.in\0" -"codes\0" -"gov.nr\0canon\0" -"gu.us\0" -"tv.it\0" -"independent-inquiry.uk\0pa.leg.br\0" -"info\0" -"property\0store.dk\0cust.prod.thingdust.io\0" -"sko.gov.pl\0" -"1.bg\0liguria.it\0myspreadshop.ca\0" -"balashov.su\0" -"gov.om\0" -"gob.mx\0" -"tas.au\0gob.ni\0myspreadshop.ch\0" -"heteml.net\0" -"aizumisato.fukushima.jp\0sorreisa.no\0" -"*.kitakyushu.jp\0ric.jelastic.vps-host.net\0" -"rissa.no\0gov.ph\0" -"tv.kg\0" -"hamura.tokyo.jp\0" -"yatsushiro.kumamoto.jp\0gov.pk\0" -"gov.pl\0ga.us\0" -"soja.okayama.jp\0spjelkavik.no\0" -"gov.pn\0cloud-fr1.unispace.io\0barsy.net\0" -"sr.it\0mycloud.by\0myspreadshop.de\0" -"gets-it.net\0" -"gov.qa\0" -"gov.pr\0" -"hitachiomiya.ibaraki.jp\0kongsberg.no\0gov.ps\0" -"gov.pt\0" -"upow.gov.pl\0myspreadshop.dk\0" -"kmpsp.gov.pl\0" -"chikujo.fukuoka.jp\0mobi.ke\0pb.leg.br\0" -"gov.py\0bib.ve\0pics\0" -"gob.pa\0" -"security\0" -"tanohata.iwate.jp\0gob.pe\0estate\0" -"wakuya.miyagi.jp\0" -"loabat.no\0" -"takaharu.miyazaki.jp\0glug.org.uk\0" -"tas.edu.au\0gob.pk\0" -"bolivia.bo\0" -"iida.nagano.jp\0" -"ambulance.aero\0rn.it\0" -"askoy.no\0" -"saka.hiroshima.jp\0nesseby.no\0" -"panasonic\0" -"kochi.kochi.jp\0cc.tn.us\0" -"campaign.gov.uk\0" -"gov.sa\0singles\0" -"pr.gov.pl\0gov.sb\0town\0" -"tv.na\0gov.rs\0gov.sc\0" -"gov.sd\0homelink.one\0" -"gov.ru\0pya.jp\0" -"nome.pt\0ktistory.com\0" -"gov.rw\0gov.sg\0" -"shimoji.okinawa.jp\0gov.sh\0" -"itoigawa.niigata.jp\0" -"oristano.it\0minamiboso.chiba.jp\0holt\xc3\xa5len.no\0" -"gov.sl\0deloitte\0" -"does-it.net\0daemon.panel.gg\0" -"gov.so\0" -"pz.it\0from-ok.com\0" -"gov.ss\0spacekit.io\0" -"*.on-rio.io\0" -"kin.okinawa.jp\0" -"gov.sx\0" -"gov.sy\0" -"gov.tj\0" -"gov.tl\0kred\0jls-sto1.elastx.net\0" -"gov.tm\0" -"gov.tn\0" -"gov.to\0dyndns1.de\0" -"gov.ua\0is-a-musician.com\0public-inquiry.uk\0" -"alta.no\0gov.tr\0csx.cc\0" -"gov.tt\0" -"tsukiyono.gunma.jp\0\xc3\xa5s.no\0" -"gov.tw\0toys\0" -"joyo.kyoto.jp\0gov.uk\0" -"us-east-1.elasticbeanstalk.com\0" -"lier.no\0" -"gob.sv\0" -"kitagawa.kochi.jp\0tuleap-partners.com\0" -"orskog.no\0" -"bremanger.no\0gov.vc\0" -"kisosaki.mie.jp\0volvo\0" -"gov.ve\0" -"legnica.pl\0" -"deci.jp\0" -"ind.br\0\xd9\x85\xd9\x84\xd9\x8a\xd8\xb3\xd9\x8a\xd8\xa7\0" -"\xd8\xa7\xd9\x84\xd9\x85\xd8\xba\xd8\xb1\xd8\xa8\0" -"ama.aichi.jp\0gov.vn\0" -"katsuragi.wakayama.jp\0" -"kokubunji.tokyo.jp\0lapy.pl\0lubartow.pl\0" -"hikimi.shimane.jp\0" -"econo.bj\0customer.mythic-beasts.com\0" -"abu.yamaguchi.jp\0" -"trentin-s\xc3\xbc""d-tirol.it\0vall\xc3\xa9""e-d-aoste.it\0forum\0" -"aizuwakamatsu.fukushima.jp\0" -"awsglobalaccelerator.com\0" -"toyota.yamaguchi.jp\0skjerv\xc3\xb8y.no\0cc.pr.us\0us.platform.sh\0" -"style\0" -"media.aero\0gob.ve\0" -"poa.br\0" -"gov.ws\0" -"flora.no\0" -"kamisu.ibaraki.jp\0" -"tv.sd\0" -"uenohara.yamanashi.jp\0" -"secaas.hk\0" -"hn.cn\0uz.ua\0dev.static.land\0" -"mn.it\0k12.ca.us\0" -"caltanissetta.it\0" -"servep2p.com\0" -"hino.tottori.jp\0" -"sk\xc3\xa1nit.no\0mw.gov.pl\0" -"kimobetsu.hokkaido.jp\0a.run.app\0" -"gov.ye\0" -"r\xc3\xb8ros.no\0" -"morotsuka.miyazaki.jp\0" -"nishitosa.kochi.jp\0" -"setagaya.tokyo.jp\0s3-external-1.amazonaws.com\0" -"ogori.fukuoka.jp\0myeffect.net\0" -"gov.za\0" -"boo.jp\0" -"tv.tr\0" -"reviews\0miniserver.com\0" -"fam.pk\0" -"edu.ac\0" -"hanoi.vn\0" -"edu.af\0tv.tz\0cc.nj.us\0" -"money.bj\0gov.zm\0" -"\xe7\xb6\xb2\xe8\xb7\xaf.tw\0" -"ishinomaki.miyagi.jp\0" -"edu.al\0reggiocalabria.it\0nishiwaki.hyogo.jp\0" -"hasami.nagasaki.jp\0dontexist.net\0" -"edu.ba\0gov.zw\0bryansk.su\0" -"edu.ar\0edu.bb\0ms.gov.br\0wakasa.fukui.jp\0" -"l\xc3\xb8renskog.no\0" -"webview-assets.cloud9.us-west-1.amazonaws.com\0" -"edu.au\0" -"onthewifi.com\0" -"ind.gt\0sande.vestfold.no\0ping\0" -"edu.bh\0m.se\0cnpy.gdn\0" -"edu.bi\0" -"edu.az\0edu.bj\0" -"ueda.nagano.jp\0pink\0" -"edu.bm\0" -"edu.bn\0" -"edu.bo\0ddns.net\0" -"win\0" -"edu.br\0fukagawa.hokkaido.jp\0mer\xc3\xa5ker.no\0" -"edu.bs\0" -"edu.bt\0" -"madrid\0" -"watson.jp\0" -"edu.ci\0webview-assets.cloud9.ap-northeast-3.amazonaws.com\0" -"edu.bz\0" -"tabitorder.co.il\0" -"edu.cn\0" -"edu.co\0" -"takahata.yamagata.jp\0" -"ind.in\0" -"mt.gov.br\0" -"barsy.pro\0" -"read-books.org\0" -"edu.cu\0meiwa.mie.jp\0" -"edu.cv\0" -"edu.cw\0" -"economia.bo\0" -"tadaoka.osaka.jp\0" -"edu.dm\0yashio.saitama.jp\0education\0" -"studio\0" -"edu.do\0fastly-edge.com\0" -"itano.tokushima.jp\0" -"yoita.niigata.jp\0*.transurl.be\0" -"edu.ec\0" -"tmp.br\0news\0" -"edu.ee\0" -"edu.eg\0" -"hiraizumi.iwate.jp\0" -"edu.dz\0" -"fukui.fukui.jp\0" -"*.ocp.customer-oci.com\0" -"yk.ca\0higashimurayama.tokyo.jp\0" -"cbg.ru\0" -"pi.leg.br\0" -"nh-serv.co.uk\0" -"edu.es\0select\0" -"edu.et\0" -"taiki.hokkaido.jp\0next\0fin.ci\0" -"\xe6\xb7\xa1\xe9\xa9\xac\xe9\x94\xa1\0barsy.pub\0" -"wme\0" -"samegawa.fukushima.jp\0" -"securitytactics.com\0" -"ind.kw\0" -"togura.nagano.jp\0taira.toyama.jp\0" -"edu.fm\0" -"nishi.osaka.jp\0pigboat.jp\0" -"bj.cn\0" -"miho.ibaraki.jp\0" -"edu.gd\0" -"edu.ge\0" -"edu.gh\0webredirect.org\0" -"edu.gi\0myforum.community\0" -"\xe6\x96\xb0\xe6\xbd\x9f.jp\0akune.kagoshima.jp\0limanowa.pl\0" -"charter.aero\0" -"edu.gl\0bykle.no\0heavy.jp\0" -"hitachiota.ibaraki.jp\0" -"edu.gn\0asahikawa.hokkaido.jp\0" -"fin.ec\0" -"edu.gp\0soma.fukushima.jp\0" -"saroma.hokkaido.jp\0" -"edu.gr\0" -"edu.gt\0\xd0\xbe\xd0\xb1\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" -"edu.gu\0berlevag.no\0" -"ogaki.gifu.jp\0" -"edu.gy\0" -"edu.hk\0oi.kanagawa.jp\0" +"aig\0gripe\0notebook.us-west-2.sagemaker.aws\0thingdustdata.com\0" +"bolt.hu\0" +"atsugi.kanagawa.jp\0" +"gov.cu\0isa-hockeynut.com\0" +"kunohe.iwate.jp\0mielec.pl\0banamex\0" "associates\0" -"tsuruga.fukui.jp\0co.financial\0" -"edu.hn\0" -"*.transurl.eu\0" -"\xe6\x96\xb0\xe5\x8a\xa0\xe5\x9d\xa1\0" -"\xe7\xb6\xb2\xe7\xbb\x9c.hk\0edu.ht\0bentre.vn\0" -"yabu.hyogo.jp\0shw.io\0" -"sanjo.niigata.jp\0wow\0is-a-bookkeeper.com\0undo.jp\0" -"onred.one\0" -"insurance\0" -"oga.akita.jp\0" -"student.aero\0edu.in\0friuli-ve-giulia.it\0" -"dr.in\0" -"sayo.hyogo.jp\0baidar.no\0" -"edu.iq\0\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\0" -"agdenes.no\0" -"utazas.hu\0edu.is\0" -"edu.it\0otaki.chiba.jp\0*.cns.joyent.com\0" -"calvinklein\0" -"toda.saitama.jp\0reservd.testing.thingdust.io\0" -"niigata.jp\0nissedal.no\0" -"lib.mn.us\0" -"aircraft.aero\0" -"kita.osaka.jp\0" -"edu.jo\0alstom\0" -"bloxcms.com\0" -"yokkaichi.mie.jp\0bungoono.oita.jp\0" -"mn.us\0" -"edu.kg\0holmestrand.no\0" -"cn.in\0s3-website-us-east-1.amazonaws.com\0""2.azurestaticapps.net\0" -"edu.ki\0saloon.jp\0" -"nalchik.ru\0" -"edu.km\0farsund.no\0" -"cn.it\0edu.kn\0webview-assets.aws-cloud9.us-east-2.amazonaws.com\0" -"kaita.hiroshima.jp\0" -"akaiwa.okayama.jp\0johana.toyama.jp\0edu.kp\0g\xc3\xa1ivuotna.no\0" -"edu.la\0" -"yasaka.nagano.jp\0edu.lb\0" -"edu.lc\0" -"\xe7\xb5\x84\xe7\xb9\x94.\xe9\xa6\x99\xe6\xb8\xaf\0" -"edu.kw\0" -"nakano.tokyo.jp\0edu.ky\0" -"edu.kz\0" -"edu.lk\0" -"nalchik.su\0nog.community\0wpmucdn.com\0" -"sardinia.it\0su.paba.se\0" -"vipsinaapp.com\0" -"tenkawa.nara.jp\0" -"consulting\0" -"edu.lr\0servecounterstrike.com\0" -"edu.ls\0" -"toyama.toyama.jp\0redumbrella\0" -"nasu.tochigi.jp\0edu.me\0wtc\0" -"v.bg\0bulsan.it\0edu.lv\0" -"!city.nagoya.jp\0edu.mg\0" -"karm\xc3\xb8y.no\0wtf\0myfritz.net\0" -"edu.ly\0s3-ap-northeast-2.amazonaws.com\0" -"saitama.jp\0kasuya.fukuoka.jp\0sandcats.io\0" -"edu.mk\0" -"edu.ml\0" -"edu.mn\0" -"edu.mo\0nysa.pl\0" -"beardu.no\0pe.leg.br\0" -"maringa.br\0dr.na\0" -"edu.ms\0snaase.no\0" -"edu.mt\0" -"webhop.me\0gov.scot\0" -"edu.mv\0" -"edu.mw\0edu.ng\0shop.brendly.rs\0" -"edu.mx\0" -"edu.my\0edu.ni\0mydatto.net\0" -"edu.mz\0k12.mt.us\0dyn-berlin.de\0" -"bari.it\0" -"b.bg\0miyazaki.jp\0it1.jenv-aruba.cloud\0" -"\xe6\x9d\xb1\xe4\xba\xac.jp\0" -"ind.tn\0" -"fuchu.hiroshima.jp\0edu.nr\0orx.biz\0" -"kawasaki.miyagi.jp\0kamimine.saga.jp\0" -"\xe7\xae\x87\xe4\xba\xba.hk\0sakuho.nagano.jp\0" -"\xd0\xbe\xd1\x80\xd0\xb3\0" -"b.br\0izunokuni.shizuoka.jp\0" -"skanit.no\0" -"edu.om\0" -"fujimi.saitama.jp\0webview-assets.aws-cloud9.us-west-1.amazonaws.com\0" -"gaular.no\0edu.pa\0framer.photos\0" -"wlocl.pl\0" -"vs.it\0direct\0" -"*.vultrobjects.com\0" -"hongo.hiroshima.jp\0aikawa.kanagawa.jp\0edu.pe\0" -"edu.pf\0" -"edu.ph\0" -"otoyo.kochi.jp\0edu.pk\0" -"edu.pl\0" -"suifu.ibaraki.jp\0edu.pn\0" -"futaba.fukushima.jp\0" -"cc.ar.us\0" -"sande.more-og-romsdal.no\0edu.qa\0" -"edu.pr\0" -"edu.ps\0" -"bas.it\0edu.pt\0" -"modelling.aero\0omigawa.chiba.jp\0" -"is-a-landscaper.com\0" -"hara.nagano.jp\0edu.py\0*.transurl.nl\0" -"okinoshima.shimane.jp\0edu.scot\0" -"*.builder.code.com\0" -"gov.nc.tr\0" -"otoineppu.hokkaido.jp\0" -"fujikawa.yamanashi.jp\0\xd8\xa7\xd9\x84\xd8\xac\xd8\xb2\xd8\xa7\xd8\xa6\xd8\xb1\0" -"psse.gov.pl\0" -"naka.hiroshima.jp\0fukusaki.hyogo.jp\0med.pro\0" -"orkanger.no\0" -"hanam.vn\0" -"daisen.akita.jp\0langev\xc3\xa5g.no\0" -"paragliding.aero\0levanger.no\0test-iserv.de\0" -"nakagawa.nagano.jp\0" -"\xe7\xbb\x84\xe7\xb9\x94.hk\0" -"weir\0" -"xin\0" -"kawamata.fukushima.jp\0edu.sa\0pyatigorsk.ru\0" -"edu.sb\0" -"edu.rs\0edu.sc\0s3-website.ap-south-1.amazonaws.com\0no-ip.ca\0" -"edu.sd\0" -"edu.ru\0" -"azure\0" -"edu.sg\0" -"barsy.org\0" -"edu.sl\0" -"echizen.fukui.jp\0" -"reggio-calabria.it\0edu.sn\0capoo.jp\0" -"agro.bj\0edu.so\0" -"edu.ss\0" -"agro.bo\0edu.st\0" -"edu.sv\0" -"edu.sy\0" -"gok.pk\0edu.tj\0" -"yoshimi.saitama.jp\0" -"askvoll.no\0edu.tm\0lovesick.jp\0" -"k12.id.us\0asso.eu.org\0" -"edu.to\0software\0mc.ax\0" -"edu.ua\0vfs.cloud9.eu-central-1.amazonaws.com\0unicloud.pl\0" -"edu.tr\0" -"log.br\0dr.tr\0" -"narita.chiba.jp\0edu.tt\0shell\0operaunite.com\0" -"saigawa.fukuoka.jp\0" -"edu.tw\0" -"gobo.wakayama.jp\0" -"lab.ms\0" -"lindesnes.no\0" -"konyvelo.hu\0punyu.jp\0" -"sukumo.kochi.jp\0" -"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86.ir\0" -"edu.vc\0tires\0" -"cloud.goog\0" -"edu.ve\0" -"rc.it\0aarp\0bible\0" -"edu.uy\0" -"cn.ua\0" -"edu.vn\0us-4.evennode.com\0" -"shopware.store\0" -"shiranuka.hokkaido.jp\0" -"tecnologia.bo\0video\0" -"numazu.shizuoka.jp\0" -"edu.vu\0" -"fin.tn\0" -"molise.it\0kurgan.su\0" -"fussa.tokyo.jp\0" -"po.it\0fylkesbibl.no\0" -"restaurant.bj\0pr.leg.br\0app.render.com\0" -"schoolbus.jp\0" -"mitoyo.kagawa.jp\0edu.ws\0" -"\xe7\xb5\x84\xe7\xb9\x94.tw\0is-a-financialadvisor.com\0" -"nordreisa.no\0" -"songdalen.no\0" -"yanaizu.fukushima.jp\0" -"swatch\0""123webseite.de\0" -"gitlab.io\0" -"kharkiv.ua\0cn.vu\0" -"khakassia.su\0" -"nes.akershus.no\0" -"oppdal.no\0" -"weather\0" -"edu.ye\0" -"az.us\0" -"jessheim.no\0" -"*.cryptonomic.net\0" -"kommune.no\0" -"stjordal.no\0" -"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa5\x8b\xe0\xa4\xa4\0" -"arts.co\0edu.za\0" -"padua.it\0*.landing.myjino.ru\0" -"cal.it\0kvafjord.no\0\xe0\xb2\xad\xe0\xb2\xbe\xe0\xb2\xb0\xe0\xb2\xa4\0" -"balsfjord.no\0" -"urakawa.hokkaido.jp\0girlfriend.jp\0" -"cri.br\0""123webseite.at\0" -"trentinsudtirol.it\0iwi.nz\0" -"gmbh\0" -"edu.zm\0" -"us-3.evennode.com\0" -"katowice.pl\0" -"k12.ct.us\0" -"ac.gov.br\0holdings\0" -"social\0" -"agrigento.it\0" -"kill.jp\0" -"xerox\0fastvps.site\0" -"randaberg.no\0" -"kamiichi.toyama.jp\0" -"westeurope.azurestaticapps.net\0" -"yoshida.saitama.jp\0" -"gs.cn\0" -"mc.it\0" -"protonet.io\0" -"africa\0" -"kamikoani.akita.jp\0spdns.org\0" -"trentin-sued-tirol.it\0reg.dk\0" -"v\xc3\xa1rgg\xc3\xa1t.no\0" -"masaki.ehime.jp\0cern\0homeoffice.gov.uk\0" -"s\xc3\xb8rreisa.no\0" -"bolt.hu\0vaapste.no\0" -"noticeable.news\0" -"cesena-forli.it\0my-firewall.org\0" -"oto.fukuoka.jp\0naie.hokkaido.jp\0" -"onfabrica.com\0" -"tenei.fukushima.jp\0" -"dyndns-pics.com\0" -"b.ssl.fastly.net\0" -"miura.kanagawa.jp\0" -"s3.eu-west-3.amazonaws.com\0carrd.co\0" -"cc.mo.us\0" -"kunitomi.miyazaki.jp\0toshima.tokyo.jp\0" -"sellsyourhome.org\0" -"us-2.evennode.com\0dray-dns.de\0" -"goto.nagasaki.jp\0" -"shimofusa.chiba.jp\0" -"pupu.jp\0" -"sardegna.it\0azerbaijan.su\0" -"*.on-rancher.cloud\0" -"namie.fukushima.jp\0shimosuwa.nagano.jp\0h\xc3\xa4kkinen.fi\0" -"able\0tirol\0" -"airline.aero\0lardal.no\0b.se\0" -"prime\0s3-ca-central-1.amazonaws.com\0" -"camera\0*.webpaas.ovh.net\0" -"joetsu.niigata.jp\0from-in.com\0v.ua\0" -"takahashi.okayama.jp\0" -"whitesnow.jp\0" -"nobeoka.miyazaki.jp\0kitagata.saga.jp\0akiruno.tokyo.jp\0" -"builders\0" -"isteingeek.de\0" -"s3.ap-south-1.amazonaws.com\0" -"senasa.ar\0dynalias.com\0ocelot.mythic-beasts.com\0" -"from-la.net\0" -"togane.chiba.jp\0" -"mizumaki.fukuoka.jp\0" -"ryukyu\0" -"wixstudio.io\0" -"n\xc3\xb8tter\xc3\xb8y.no\0" -"s3-website.ca-central-1.amazonaws.com\0" -"onporter.run\0" -"leg.br\0" -"knowsitall.info\0" -"insurance.aero\0tsuchiura.ibaraki.jp\0wnext.app\0yombo.me\0" -"delivery\0weeklylottery.org.uk\0" -"aukra.no\0" -"caravan\0" -"balestrand.no\0senseering.net\0" -"xxx\0" -"us-1.evennode.com\0novecore.site\0" -"dynathome.net\0" -"accident-prevention.aero\0pomorskie.pl\0" -"ferrara.it\0" -"svn-repos.de\0zapto.xyz\0" -"melhus.no\0virgin\0" -"rzgw.gov.pl\0" -"ragusa.it\0valer.hedmark.no\0" -"mikawa.yamagata.jp\0" -"minami-alps.yamanashi.jp\0" -"nom.ad\0xyz\0" -"nom.ag\0" -"onion\0" -"skiptvet.no\0" -"shimamoto.osaka.jp\0" -"nittedal.no\0arts.ve\0" -"takasago.hyogo.jp\0es-1.axarnet.cloud\0" -"framer.wiki\0" -"*.code.run\0" -"sopot.pl\0" -"ishikawa.okinawa.jp\0" -"surnadal.no\0" -"kikugawa.shizuoka.jp\0httpbin.org\0" -"ssl.origin.cdn77-secure.org\0" -"sm\xc3\xb8la.no\0" -"cim.br\0ok.us\0" -"dyndns-free.com\0serveirc.com\0" -"buzz\0" -"north-kazakhstan.su\0" -"dontexist.org\0" -"achi.nagano.jp\0" -"from-wa.com\0" -"workinggroup.aero\0nom.co\0" -"tsurugashima.saitama.jp\0play\0" -"suedtirol.it\0" -"brand.se\0jp.net\0" -"aver\xc3\xb8y.no\0" -"oppeg\xc3\xa5rd.no\0s3.fr-par.scw.cloud\0" -"cri.nz\0" -"ostrowwlkp.pl\0" -"genova.it\0" -"youtube\0endoftheinternet.org\0" -"lerdal.no\0cc.hn\0" -"s3.teckids.org\0" -"uppo.gov.pl\0" -"shintomi.miyazaki.jp\0" -"biei.hokkaido.jp\0dyndns.ddnss.de\0" -"tienda\0" -"shirataka.yamagata.jp\0" -"yaese.okinawa.jp\0" -"chuo.tokyo.jp\0" -"tunk.org\0" -"nom.es\0b\xc3\xa1hccavuotna.no\0marshalls\0" -"directory\0" -"the.br\0\xd8\xa7\xd8\xb1\xd8\xa7\xd9\x85\xd9\x83\xd9\x88\0" -"tsuno.kochi.jp\0" -"arts.ro\0" -"valle-d-aosta.it\0carboniaiglesias.it\0s3-sa-east-1.amazonaws.com\0" -"bs.it\0now-dns.net\0" -"tateyama.chiba.jp\0" -"s3-fips-us-gov-west-1.amazonaws.com\0" -"etc.br\0stalowa-wola.pl\0you\0" -"huissier-justice.fr\0g.vbrplsbx.io\0" -"yurihonjo.akita.jp\0" -"nom.fr\0" -"arendal.no\0" -"trentin-sud-tirol.it\0" -"agro.pl\0" -"macapa.br\0" -"k12.ok.us\0" -"rokunohe.aomori.jp\0" -"tomari.hokkaido.jp\0tsubetsu.hokkaido.jp\0cpa.pro\0service.one\0" -"cleaning\0" -"k.bg\0" -"ao.it\0hidaka.kochi.jp\0starostwo.gov.pl\0room\0" -"loten.no\0" -"kakuda.miyagi.jp\0" -"kashima.ibaraki.jp\0homeip.net\0" -"cards\0" -"tinn.no\0cc.co.us\0" -"honjo.saitama.jp\0" -"fitness\0" -"obihiro.hokkaido.jp\0marriott\0" -"\xe7\xb5\x84\xe7\xb9\x94.hk\0" -"nakaniikawa.toyama.jp\0" -"terni.it\0ichinomiya.chiba.jp\0nordkapp.no\0" -"hareid.no\0" -"\xe4\xb8\xad\xe5\x9b\xbd\0" -"sklep.pl\0tr.eu.org\0" -"mihara.hiroshima.jp\0fedex\0financial\0" -"daplie.me\0dnsup.net\0" -"dyndns-mail.com\0" -"arts.nf\0flier.jp\0" -"\xe4\xb8\xad\xe5\x9c\x8b\0" -"kristiansand.no\0sosnowiec.pl\0wix.run\0" -"trentinoalto-adige.it\0kvinesdal.no\0" -"koshu.yamanashi.jp\0" -"cc.na\0", - -"osaka\0customer.speedpartner.de\0" -"bulsan-suedtirol.it\0unj\xc3\xa1rga.no\0nowaruda.pl\0" -"al.gov.br\0shisui.chiba.jp\0" -"cologne\0" -"qh.cn\0" -"jelenia-gora.pl\0" -"natural.bo\0k12.ks.us\0" -"ogose.saitama.jp\0uk.oxa.cloud\0" -"boomla.net\0codespot.com\0" -"oum.gov.pl\0" -"kinghost.net\0" -"yamatsuri.fukushima.jp\0takayama.gifu.jp\0lego\0vfs.cloud9.sa-east-1.amazonaws.com\0" -"bc.platform.sh\0" -"nom.km\0pimienta.org\0" -"empresa.bo\0ube.yamaguchi.jp\0" -"is-a-doctor.com\0" -"jdf.br\0yokosuka.kanagawa.jp\0" -"tt.im\0" -"verona.it\0" -"tsuruoka.yamagata.jp\0midsund.no\0" -"jgora.pl\0pokrovsk.su\0" -"nagahama.shiga.jp\0" -"fhs.no\0yun\0" -"ud.it\0muos\xc3\xa1t.no\0" -"!city.sapporo.jp\0miyazaki.miyazaki.jp\0" -"cc.vt.us\0ru.com\0royal-commission.uk\0" -"aya.miyazaki.jp\0" -"ecologia.bo\0" -"ybo.party\0" -"bronnoysund.no\0" -"tsushima.nagasaki.jp\0katano.osaka.jp\0" -"nom.mg\0" -"yandex\0" -"nyanta.jp\0" -"2-d.jp\0" -"watch\0" -"iwakura.aichi.jp\0" -"analytics-gateway.us-east-2.amazonaws.com\0uber.space\0" -"ingatlan.hu\0olbiatempio.it\0sp.it\0" -"niki.hokkaido.jp\0maniwa.okayama.jp\0nom.nc\0lifeinsurance\0" -"dedibox.fr\0" -"music\0nico\0" -"nom.ni\0" -"framer.website\0" -"firenze.it\0" -"cci.fr\0" -"tickets\0" -"broker.aero\0" -"ask\xc3\xb8y.no\0is-a-anarchist.com\0" -"k8s.fr-par.scw.cloud\0" -"belem.br\0" -"istanbul\0" -"pueblo.bo\0" -"gratis\0" -"godo.gifu.jp\0americanfamily\0*.user.localcert.dev\0" -"barletta-trani-andria.it\0" -"stavern.no\0" -"corsica\0" -"onza.mythic-beasts.com\0" -"partners\0" -"aejrie.no\0" -"catania.it\0" -"nom.pa\0is-a-caterer.com\0" -"fitjar.no\0" -"from-ca.com\0" -"nom.pe\0" -"harstad.no\0" -"aip.ee\0" -"travelers\0*.compute.estate\0" -"dell-ogliastra.it\0zip\0is-a-bulls-fan.com\0" -"nom.pl\0readthedocs.io\0lima.zone\0" -"\xd1\x80\xd1\x83\xd1\x81\0" -"nagawa.nagano.jp\0mielec.pl\0" -"andriatranibarletta.it\0" -"salon\0" -"gs.ol.no\0" -"cc.ua\0" -"ebina.kanagawa.jp\0" -"otofuke.hokkaido.jp\0" -"sumoto.hyogo.jp\0" -"takamori.nagano.jp\0nom.re\0" -"bplaced.com\0" -"fujisawa.kanagawa.jp\0" -"test.tj\0java\0" -"ot.it\0pd.it\0" -"realestate\0" -"nom.ro\0cloudcontrolapp.com\0" -"tobe.ehime.jp\0takayama.gunma.jp\0" -"iveland.no\0\xe8\x87\xba\xe7\x81\xa3\0" -"other.nf\0" -"nhlfan.net\0" -"discourse.group\0" -"tysnes.no\0""123minsida.se\0" -"j\xc3\xb8lster.no\0" -"tydal.no\0" -"naturbruksgymn.se\0" -"kitashiobara.fukushima.jp\0" -"hotel.tz\0camdvr.org\0" -"hamada.shimane.jp\0" -"\xe7\xbd\x91\xe7\xbb\x9c.cn\0blogsite.org\0jelastic.team\0" -"tsukuba.ibaraki.jp\0" -"rl.no\0" -"yotsukaido.chiba.jp\0" -"rep.br\0fukushima.jp\0" -"\xc3\xb8stre-toten.no\0nom.tm\0" -"trentins\xc3\xbc""d-tirol.it\0takehara.hiroshima.jp\0" -"blogdns.org\0" -"nodes.k8s.pl-waw.scw.cloud\0" -"test.ru\0atl.jelastic.vps-host.net\0" -"yabuki.fukushima.jp\0" -"matsuda.kanagawa.jp\0lelux.site\0" -"hl.cn\0" -"nike\0" -"takarazuka.hyogo.jp\0" -"shirako.chiba.jp\0" -"123paginaweb.pt\0user.srcf.net\0" -"lib.vt.us\0" -"nom.ve\0us-gov-west-1.elasticbeanstalk.com\0" -"onga.fukuoka.jp\0" -"barsyonline.com\0" -"coz.br\0" -"hagi.yamaguchi.jp\0nannestad.no\0" -"guitars\0storipress.app\0" -"urawa.saitama.jp\0" -"cdn77-ssl.net\0" -"rishirifuji.hokkaido.jp\0parliament.nz\0caa.li\0" -"k12.as.us\0market\0" -"ms.leg.br\0tn.oxa.cloud\0" -"caracal.mythic-beasts.com\0" -"microlight.aero\0plus\0" -"takatsuki.osaka.jp\0" -"cc.nh.us\0" -"is-a-student.com\0" -"pharmacy\0hasura.app\0" -"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\0" -"forl\xc3\xac-cesena.it\0" -"cust.retrosnub.co.uk\0" -"tomi.nagano.jp\0" -"gru.br\0protection\0" -"\xe7\xbd\x91\xe7\xbb\x9c.hk\0k.se\0" -"\xd9\x81\xd9\x84\xd8\xb3\xd8\xb7\xd9\x8a\xd9\x86\0" -"hokuto.hokkaido.jp\0" -"nikaho.akita.jp\0" -"cc.md.us\0reservd.dev.thingdust.io\0wmcloud.org\0" -"mt.leg.br\0" -"nesset.no\0" -"bolzano-altoadige.it\0" -"outsystemscloud.com\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd9\x87\0" -"dielddanuorri.no\0" -"*.spectrum.myjino.ru\0" -"g12.br\0nom.za\0" -"chat\0bitbucket.io\0" -"niyodogawa.kochi.jp\0" -"meteorapp.com\0" -"cherkasy.ua\0" -"wajiki.tokushima.jp\0mayfirst.org\0" -"furukawa.miyagi.jp\0unjarga.no\0blogspot.co.at\0""32-b.it\0" -"tokushima.jp\0matsue.shimane.jp\0" -"eco.bj\0" -"noto.ishikawa.jp\0" -"hemsedal.no\0" -"naruto.tokushima.jp\0" -"eu.int\0udono.mie.jp\0" -"hotel.lk\0" -"eco.br\0" -"drammen.no\0ciscofreak.com\0" -"\xe4\xbf\xa1\xe6\x81\xaf\0uk.eu.org\0" -"myfast.space\0" -"niikappu.hokkaido.jp\0" -"nose.osaka.jp\0" -"kofu.yamanashi.jp\0" -"moareke.no\0xy.ax\0" -"higashiizumo.shimane.jp\0lillehammer.no\0\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0mond.jp\0" -"misconfused.org\0" -"paris.eu.org\0" -"nakatane.kagoshima.jp\0" -"chikushino.fukuoka.jp\0tawaramoto.nara.jp\0" -"gitapp.si\0" -"wiki.bo\0" -"\xc3\xb8ygarden.no\0webcam\0" -"nuoro.it\0" -"wiki.br\0\xd1\x81\xd1\x80\xd0\xb1\0" -"akamaized-staging.net\0" -"ddnsgeek.com\0" -"augustow.pl\0l-o-g-i-n.de\0" -"univ.bj\0" -"stj\xc3\xb8rdalshalsen.no\0" -"masoy.no\0" -"onrender.com\0" -"rep.kp\0" -"is-a-painter.com\0" -"elk.pl\0" -"chiyoda.tokyo.jp\0" -"minamiizu.shizuoka.jp\0" -"oki.fukuoka.jp\0moscow\0" -"mircloud.us\0" -"berlin\0" -"place\0spdns.eu\0" -"choyo.kumamoto.jp\0mypsx.net\0" -"safe\0" -"wa.au\0" -"ens.tn\0" -"lahppi.no\0" -"cloud.jelastic.open.tim.it\0" -"ohi.fukui.jp\0" -"omg.lol\0" -"webview-assets.aws-cloud9.eu-west-1.amazonaws.com\0" -"hobol.no\0indie.porn\0" -"hotel.hu\0is-a-personaltrainer.com\0" -"azumino.nagano.jp\0diamonds\0" -"selbu.no\0" -"school\0" -"tourism.tn\0" -"date.fukushima.jp\0" -"serveftp.net\0" -"kanie.aichi.jp\0" -"ichihara.chiba.jp\0hornindal.no\0" -"oirase.aomori.jp\0uda.nara.jp\0" -"chikuhoku.nagano.jp\0hokuto.yamanashi.jp\0hl.no\0" -"ebetsu.hokkaido.jp\0" -"musica.ar\0sumoto.kumamoto.jp\0mochizuki.nagano.jp\0" -"\xe0\xb8\x84\xe0\xb8\xad\xe0\xb8\xa1\0" -"wanggou\0" -"vps-host.net\0" -"hagiang.vn\0" -"itami.hyogo.jp\0" -"blogspot.co.id\0" -"\xe5\xa5\x88\xe8\x89\xaf.jp\0tube\0" -"oguni.kumamoto.jp\0" -"musica.bo\0" -"palmas.br\0yuasa.wakayama.jp\0" -"gold\0" -"sa.edu.au\0" -"golf\0blogspot.co.il\0" -"mihama.chiba.jp\0" -"cl.it\0chichibu.saitama.jp\0chuo.yamanashi.jp\0" -"reservd.com\0" -"bergamo.it\0lib.md.us\0" -"murakami.niigata.jp\0" -"org.ac\0go.dyndns.org\0" -"org.ae\0ikusaka.nagano.jp\0" -"org.af\0shitara.aichi.jp\0medecin.km\0" -"org.ag\0hatsukaichi.hiroshima.jp\0" -"dnshome.de\0" -"org.ai\0lombardia.it\0primetel.cloud\0" -"asahi.chiba.jp\0karelia.su\0" -"org.al\0custom.metacentrum.cz\0" -"org.am\0" -"s3.eu-central-1.amazonaws.com\0" -"mircloud.ru\0" -"org.ba\0" -"org.ar\0org.bb\0" -"sekd1.beebyteapp.io\0" -"org.au\0t.bg\0" -"ishikawa.jp\0wsa.gov.pl\0*.tst.site\0" -"org.bh\0" -"org.bi\0" -"org.az\0org.bj\0austrheim.no\0blogspot.vn\0" -"idv.hk\0ashikaga.tochigi.jp\0" -"org.bm\0" -"org.bn\0realty\0" -"org.bo\0spdns.de\0" -"hermes\0flynnhosting.net\0" -"org.br\0sale\0" -"org.bs\0" -"org.bt\0" -"turystyka.pl\0" -"org.bw\0" -"uri.arpa\0org.ci\0goog\0" -"org.bz\0minamidaito.okinawa.jp\0" -"inuyama.aichi.jp\0statefarm\0jele.cloud\0" -"erotica.hu\0yalta.ua\0" -"bounty-full.com\0" -"org.cn\0usercontent.jp\0" -"org.co\0toyohashi.aichi.jp\0dynamisches-dns.de\0" -"ybo.trade\0" -"ono.fukushima.jp\0" -"org.cu\0kuchinotsu.nagasaki.jp\0" -"org.cv\0philips\0" -"org.cw\0" -"org.cy\0" -"ad.jp\0" -"magazine.aero\0poltava.ua\0" -"org.dm\0adult\0" -"*.migration.run\0" -"org.do\0" -"takikawa.hokkaido.jp\0" -"nango.fukushima.jp\0minami.tokushima.jp\0" -"org.ec\0jeonnam.kr\0" -"lgbt\0eu.ngrok.io\0" -"org.ee\0kinokawa.wakayama.jp\0" -"kawanishi.yamagata.jp\0" -"org.eg\0vinhlong.vn\0" -"mie.jp\0soeda.fukuoka.jp\0altervista.org\0here-for-more.info\0" -"org.dz\0" -"holtalen.no\0tashkent.su\0" -"yufu.oita.jp\0" -"is-a-cpa.com\0" -"blogspot.re\0" -"org.es\0" -"org.et\0" -"backan.vn\0" -"buzen.fukuoka.jp\0" -"osoyro.no\0hamar.no\0kutno.pl\0" -"org.fj\0katsuragi.nara.jp\0" -"blogspot.ro\0" -"forgot.his.name\0" -"org.fm\0" -"blogspot.rs\0instances.spawn.cc\0" -"8.bg\0" -"tanabe.wakayama.jp\0blogspot.ru\0blogspot.se\0" -"cruise\0blogspot.sg\0" -"bplaced.net\0flap.id\0" -"org.ge\0blogspot.si\0" -"in-addr.arpa\0" -"org.gg\0blogspot.sk\0" -"org.gh\0" -"org.gi\0" -"kuromatsunai.hokkaido.jp\0blogspot.sn\0" -"org.gl\0" -"org.gn\0cust.disrec.thingdust.io\0" -"org.gp\0blogspot.td\0" -"org.gr\0konan.aichi.jp\0" -"ogimi.okinawa.jp\0orland.no\0" -"org.gt\0kawakami.nagano.jp\0ostre-toten.no\0k12.in.us\0greater.jp\0" -"org.gu\0noip.us\0dd-dns.de\0" -"miasa.nagano.jp\0" -"org.gy\0" -"campinagrande.br\0sunndal.no\0" -"org.hk\0cc.vi.us\0" -"ogliastra.it\0" -"amusement.aero\0org.hn\0hikone.shiga.jp\0" -"yoshikawa.saitama.jp\0" -"chicappa.jp\0blogspot.tw\0blogspot.ug\0" -"org.ht\0adygeya.su\0now-dns.org\0" -"org.hu\0yasuda.kochi.jp\0" -"natori.miyagi.jp\0ddnsking.com\0" -"racing\0" -"wios.gov.pl\0sarl\0" -"minamiechizen.fukui.jp\0" -"org.il\0knx-server.net\0" -"org.im\0" -"org.in\0oystre-slidre.no\0blogspot.mr\0" -"fedje.no\0" -"forli-cesena.it\0" -"org.iq\0ginan.gifu.jp\0dp.ua\0" -"org.ir\0" -"org.is\0" -"blogspot.mx\0" -"contagem.br\0org.je\0oarai.ibaraki.jp\0blogspot.my\0" -"granvin.no\0lib.fl.us\0" -"mobara.chiba.jp\0binhdinh.vn\0" -"tourism.pl\0blogspot.nl\0" -"wien\0" -"cloud.fedoraproject.org\0" -"blogspot.no\0" -"kvinnherad.no\0vanguard\0in.ngrok.io\0" -"des.br\0" -"viterbo.it\0targi.pl\0oia.gov.pl\0" -"org.jo\0" -"isen.kagoshima.jp\0\xe9\xa6\x99\xe6\xa0\xbc\xe9\x87\x8c\xe6\x8b\x89\0" -"hachijo.tokyo.jp\0" -"ca.reclaim.cloud\0" -"ra.it\0" -"org.kg\0" -"dyndns-ip.com\0" -"yuzawa.niigata.jp\0org.ki\0" -"miyama.fukuoka.jp\0" -"uni5.net\0" -"\xe5\xaf\x8c\xe5\xb1\xb1.jp\0org.km\0" -"org.kn\0saotome.st\0" -"org.kp\0" -"arezzo.it\0org.la\0blogspot.pe\0" -"org.lb\0" -"annaka.gunma.jp\0org.lc\0" -"nesodden.no\0adygeya.ru\0" -"sugito.saitama.jp\0" -"tourism.bj\0finnoy.no\0collegefan.org\0" -"org.kw\0blogspot.co.uk\0" -"org.ky\0alp1.ae.flow.ch\0" -"org.kz\0" -"air-surveillance.aero\0org.lk\0" -"ogawa.nagano.jp\0blogspot.qa\0" -"univ.sn\0" -"sub.jp\0blogspot.pt\0" -"org.ma\0" -"org.lr\0save\0" -"org.ls\0" -"masfjorden.no\0" -"org.me\0\xc3\xa5rdal.no\0traeumtgerade.de\0" -"org.lv\0itau\0" -"ami.ibaraki.jp\0org.mg\0nov.ru\0" -"eaton.mi.us\0target\0" -"org.ly\0" -"\xe5\x92\x8c\xe6\xad\x8c\xe5\xb1\xb1.jp\0org.mk\0" -"hashikami.aomori.jp\0org.ml\0dyndns.biz\0" -"kita.kyoto.jp\0" -"org.mn\0sinaapp.com\0" -"kushiro.hokkaido.jp\0org.mo\0blogspot.is\0" -"res.aero\0blogspot.it\0" -"org.na\0" -"org.ms\0" -"org.mt\0at-band-camp.net\0" -"iwaki.fukushima.jp\0org.mu\0is-a-celticsfan.org\0" -"org.mv\0backplaneapp.io\0" -"org.mw\0org.ng\0s3-website-us-west-2.amazonaws.com\0nov.su\0" -"slz.br\0komaki.aichi.jp\0org.mx\0kiev.ua\0" -"org.my\0org.ni\0" -"naoshima.kagawa.jp\0org.mz\0" -"\xe7\xa5\x9e\xe5\xa5\x88\xe5\xb7\x9d.jp\0" -"blogspot.jp\0" -"higashishirakawa.gifu.jp\0" -"ac.leg.br\0cloudjiffy.net\0" -"org.nr\0" -"\xd8\xb4\xd8\xa8\xd9\x83\xd8\xa9\0" -"kanazawa.ishikawa.jp\0is-with-theband.com\0" -"vix.br\0" -"inazawa.aichi.jp\0\xe0\xb8\x97\xe0\xb8\xab\xe0\xb8\xb2\xe0\xb8\xa3.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" -"akamaihd.net\0" -"okoppe.hokkaido.jp\0idv.tw\0" -"konsulat.gov.pl\0" -"org.nz\0" -"saxo\0" -"org.om\0pramerica\0trading\0cdn.prod.atlassian-dev.net\0qcx.io\0" -"koka.shiga.jp\0blogspot.kr\0" -"tokuyama.yamaguchi.jp\0" -"homesklep.pl\0" -"org.pa\0" -"soc.srcf.net\0pages.wiardweb.com\0" -"s3-ap-south-1.amazonaws.com\0" -"wiki\0" -"org.pe\0blogspot.li\0" -"org.pf\0" -"milan.it\0staging.onred.one\0" -"omiya.saitama.jp\0giske.no\0org.ph\0" -"lib.al.us\0is-a-socialist.com\0" -"org.pk\0" -"org.pl\0" -"ne.jp\0" -"org.pn\0" -"gamo.shiga.jp\0final\0" -"blogspot.lt\0blogspot.md\0" -"org.qa\0wa.us\0blogspot.lu\0" -"kitaakita.akita.jp\0ne.ke\0org.pr\0" -"org.ps\0dyndns.tv\0" -"org.pt\0" -"genkai.saga.jp\0" -"green\0" -"blogspot.mk\0" -"ha.cn\0" -"org.py\0" -"gniezno.pl\0" -"tonkotsu.jp\0" -"rimini.it\0lib.va.us\0" -"ne.kr\0" -"bjerkreim.no\0co.place\0" -"blogspot.co.ke\0sg-1.paas.massivegrid.net\0" -"feedback\0" -"aero\0" -"fm.br\0bindal.no\0t\xc3\xb8nsberg.no\0blogspot.fi\0" -"minano.saitama.jp\0fairwinds\0" -"\xd7\x99\xd7\xa9\xd7\x95\xd7\x91.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0nagiso.nagano.jp\0shoparena.pl\0" -"bplaced.de\0wmflabs.org\0" -"blogspot.fr\0homesecuritymac.com\0" -"org.ro\0*.devcdnaccesso.com\0" -"wine\0" -"org.sa\0" -"tj\xc3\xb8me.no\0org.sb\0" -"okinawa.jp\0oschr.gov.pl\0org.rs\0org.sc\0t.se\0k12.az.us\0" -"org.sd\0" -"org.se\0seven\0org.ru\0" -"friuliv-giulia.it\0shizuoka.jp\0" -"ranzan.saitama.jp\0org.rw\0org.sg\0noip.me\0" -"org.sh\0" -"charity\0" -"szczytno.pl\0org.sl\0" -"org.sn\0blogspot.gr\0" -"org.so\0" -"ozu.kumamoto.jp\0dyndns.ws\0" -"mein-iserv.de\0" -"aso.kumamoto.jp\0bnr.la\0" -"isa.kagoshima.jp\0org.ss\0virtual-user.de\0" -"org.st\0" -"lecco.it\0" -"fauske.no\0org.sv\0" -"dyn.home-webserver.de\0blogspot.hk\0" -"gonohe.aomori.jp\0yenbai.vn\0" -"org.sy\0" -"gs.hm.no\0org.sz\0org.tj\0neustar\0" -"medecin.fr\0yokote.akita.jp\0appspaceusercontent.com\0" -"org.tm\0" -"org.tn\0blogspot.hr\0ybo.faith\0" -"org.to\0gifts\0gdynia.pl\0" -"org.ua\0blogspot.hu\0blogspot.ie\0" -"komatsushima.tokushima.jp\0org.tr\0sumy.ua\0" -"cc.ky.us\0" -"org.tt\0" -"org.tw\0org.ug\0" -"dance\0blogspot.in\0" -"org.uk\0" -"tarumizu.kagoshima.jp\0" -"blogspot.ba\0" -"fl\xc3\xa5.no\0" -"k12.vi.us\0phutho.vn\0" -"ngrok-free.dev\0nflfan.org\0" -"post.in\0blogspot.be\0" -"org.vc\0\xd1\x83\xd0\xba\xd1\x80\0blogspot.bg\0" -"campobasso.it\0org.ve\0" -"blogspot.bj\0blogspot.co.nz\0j.scaleforce.net\0" -"org.uy\0org.vi\0" -"udine.it\0yachiyo.ibaraki.jp\0tychy.pl\0org.uz\0" -"kayabe.hokkaido.jp\0" -"yokoze.saitama.jp\0blogspot.ca\0" -"org.vn\0" -"author.aero\0" -"nishinomiya.hyogo.jp\0" -"blogspot.cf\0" -"ne.pw\0quangninh.vn\0s3-eu-west-1.amazonaws.com\0blogspot.ch\0" -"org.vu\0dy.fi\0" -"blogdns.net\0" -"sweetpepper.org\0dontexist.com\0" -"ascolipiceno.it\0kimino.wakayama.jp\0vfs.cloud9.eu-west-3.amazonaws.com\0blogspot.cl\0" -"boyfriend.jp\0" -"allfinanz\0firewall-gateway.de\0" -"qld.gov.au\0" -"dnsking.ch\0" -"j.scaleforce.com.cy\0" -"toyonaka.osaka.jp\0blogspot.de\0" -"blogspot.cv\0" -"intl.tn\0org.ws\0" -"trentino-alto-adige.it\0ohira.miyagi.jp\0" -"trentinostirol.it\0download\0blogspot.cz\0" -"asn.au\0blogspot.dk\0" -"am.br\0tachiarai.fukuoka.jp\0" -"pohl\0firewall-gateway.com\0" -"usui.fukuoka.jp\0" -"kishiwada.osaka.jp\0" -"resto.bj\0" -"is-an-anarchist.com\0" -"kawagoe.saitama.jp\0" -"recife.br\0" -"kagawa.jp\0" -"org.ye\0prvcy.page\0" -"r.cdn77.net\0" -"fm.it\0hlx.page\0dyndns-blog.com\0" -"cn-north-1.eb.amazonaws.com.cn\0" -"bmoattachments.org\0" -"\xd8\xb9\xd9\x85\xd8\xa7\xd9\x86\0yahoo\0" -"daejeon.kr\0" -"fukuchiyama.kyoto.jp\0kitadaito.okinawa.jp\0" -"org.za\0" -"oster\xc3\xb8y.no\0" -"val-daosta.it\0s3.dualstack.ap-northeast-2.amazonaws.com\0" -"czeladz.pl\0org.yt\0" -"valleaosta.it\0" -"saikai.nagasaki.jp\0ny.us\0" -"balsan-suedtirol.it\0samsung\0wixsite.com\0" -"de.gt\0" -"nakasatsunai.hokkaido.jp\0" -"kumejima.okinawa.jp\0shunan.yamaguchi.jp\0" -"herokuapp.com\0" -"org.zm\0citi\0" -"dscloud.mobi\0" -"uchihara.ibaraki.jp\0" -"veneto.it\0" -"shoo.okayama.jp\0" -"lib.ny.us\0" -"ne.ug\0" -"otsuki.kochi.jp\0hole.no\0" -"ne.tz\0org.zw\0user.aseinet.ne.jp\0" -"spb.ru\0" -"city\0" -"ne.us\0kitchen\0" -"educator.aero\0" -"\xe5\xb9\xbf\xe4\xb8\x9c\0" -"\xe0\xa4\xad\xe0\xa4\xbe\xe0\xa4\xb0\xe0\xa4\xa4\xe0\xa4\xae\xe0\xa5\x8d\0" -"mantova.it\0in-butter.de\0" -"peewee.jp\0" -"ha.no\0spb.su\0" -"kouyama.kagoshima.jp\0" -"modum.no\0piw.gov.pl\0lib.nm.us\0is-a-teacher.com\0" -"trentino-stirol.it\0hvaler.no\0" -"taiwa.miyagi.jp\0blogspot.ae\0" -"habikino.osaka.jp\0microsoft\0" -"act.edu.au\0" -"filegear-au.me\0" -"campinas.br\0izena.okinawa.jp\0" -"nakanoto.ishikawa.jp\0blogspot.al\0" -"ma.us\0blogspot.am\0" -"ca.in\0" -"ravendb.community\0" -"holy.jp\0" -"km.ua\0" -"ca.it\0fm.no\0sula.no\0" -"hair\0" -"lib.la.us\0" -"kumano.hiroshima.jp\0" -"abiko.chiba.jp\0" -"amli.no\0" -"sport.hu\0\xd5\xb0\xd5\xa1\xd5\xb5\0" -"rahkkeravju.no\0" -"iris.arpa\0" -"sn.cn\0itako.ibaraki.jp\0imari.saga.jp\0" -"am.in\0" -"observer\0" -"nagasaki.jp\0""123miweb.es\0de.ls\0" -"fredrikstad.no\0scrapper-site.net\0de.md\0" -"i.bg\0" -"pesaro-urbino.it\0" -"\xe5\x85\xb5\xe5\xba\xab.jp\0" -"freedesktop.org\0" -"nakadomari.aomori.jp\0science\0dyn53.io\0" -"tara.saga.jp\0" -"higashichichibu.saitama.jp\0" -"hamatonbetsu.hokkaido.jp\0bounceme.net\0community-pro.net\0" -"selfip.net\0" -"blogspot.co.za\0" -"k12.me.us\0tele.amune.org\0" -"al.leg.br\0" -"jeep\0square7.de\0" -"kawai.iwate.jp\0ie.ua\0" -"githubusercontent.com\0" -"tsuiki.fukuoka.jp\0fukaya.saitama.jp\0" -"shikatsu.aichi.jp\0gotpantheon.com\0" -"pstmn.io\0" -"upli.io\0" -"bir.ru\0" -"higashiizu.shizuoka.jp\0" -"pb.ao\0ca.na\0dedyn.io\0" -"or.at\0adobeaemcloud.net\0" -"kashiwazaki.niigata.jp\0k12.ky.us\0" -"or.bi\0" -"ggf.br\0" -"porn\0" -"nishiizu.shizuoka.jp\0" -"\xe5\x85\xac\xe5\x8f\xb8.cn\0cc.wv.us\0" -"serveftp.org\0" -"kushimoto.wakayama.jp\0" -"uzhgorod.ua\0" -"karumai.iwate.jp\0" -"asn.lv\0" -"or.ci\0" -"\xe5\x85\xac\xe5\x8f\xb8.hk\0us.com\0" -"*.r.appspot.com\0" -"trainer.aero\0okagaki.fukuoka.jp\0hikawa.shimane.jp\0" -"gs.sf.no\0" -"tr.it\0" -"yamatokoriyama.nara.jp\0" -"or.cr\0post\0" -"showa.fukushima.jp\0yamatotakada.nara.jp\0square7.ch\0" -"sola.no\0*.kunden.ortsinfo.at\0" -"\xe5\x85\xac\xe5\x8f\xb8.\xe9\xa6\x99\xe6\xb8\xaf\0" -"kitakata.miyazaki.jp\0" -"lib.ga.us\0" -"gub.uy\0" -"powiat.pl\0" -"toyotsu.fukuoka.jp\0" -"navigation.aero\0" -"school.na\0n\xc3\xa1vuotna.no\0" -"malvik.no\0" -"smart\0" -"k12.ia.us\0" -"girly.jp\0edu.krd\0telebit.io\0" -"assabu.hokkaido.jp\0" -"zaporizhzhe.ua\0" -"ilovecollege.info\0" -"friulive-giulia.it\0" -"thanhhoa.vn\0" -"ribeirao.br\0" -"dyndns-remote.com\0" -"lidl\0" -"school.nz\0" -"scot\0" -"vf.no\0k12.gu.us\0" -"yandexcloud.net\0" -"aogashima.tokyo.jp\0" -"transporte.bo\0nagasu.kumamoto.jp\0" -"miami\0\xe8\xb4\xad\xe7\x89\xa9\0" -"blackfriday\0" -"media.hu\0dattolocal.net\0" -"hannan.osaka.jp\0" -"turek.pl\0" -"dongthap.vn\0workisboring.com\0" -"valledaosta.it\0" -"life\0" -"ulsan.kr\0kobierzyce.pl\0" -"de.us\0\xe7\xbd\x91\xe5\x9d\x80\0" -"takaoka.toyama.jp\0" -"umig.gov.pl\0wzmiuw.gov.pl\0" -"pv.it\0tr.no\0" -"int.ar\0" -"opensocial.site\0" -"bacgiang.vn\0\xe7\xbd\x91\xe7\xab\x99\0" -"vfs.cloud9.ap-northeast-1.amazonaws.com\0" -"nerima.tokyo.jp\0app.os.fedoraproject.org\0" -"int.az\0or.id\0" -"azurewebsites.net\0" -"int.bo\0bokn.no\0quangngai.vn\0" -"*.dapps.earth\0" -"baseball\0" -"kainan.wakayama.jp\0" -"is-a-guru.com\0" -"alvdal.no\0" -"pri.ee\0ca.us\0kalmykia.su\0" -"int.ci\0" -"or.it\0kasugai.aichi.jp\0for-our.info\0" -"uto.kumamoto.jp\0haus\0cloud.nospamproxy.com\0" -"aurskog-h\xc3\xb8land.no\0" -"int.co\0" -"k8s.nl-ams.scw.cloud\0" -"nasushiobara.tochigi.jp\0snasa.no\0" -"ddnss.org\0" -"int.cv\0or.jp\0" -"malselv.no\0s3-website-ap-northeast-1.amazonaws.com\0" -"yamagata.yamagata.jp\0" -"or.ke\0" -"i.ng\0comsec\0" -"hjartdal.no\0shopping\0" -"ginowan.okinawa.jp\0localhost.daplie.me\0" -"trust\0" -"kamakura.kanagawa.jp\0" -"mytabit.co.il\0" -"or.kr\0" -"alto-adige.it\0geek.nz\0is-a-blogger.com\0" -"nishiaizu.fukushima.jp\0" -"minamisanriku.miyagi.jp\0no-ip.biz\0" -"friuli-vgiulia.it\0space-to-rent.com\0" -"honefoss.no\0" -"kalmykia.ru\0" -"nagatoro.saitama.jp\0" -"gz.cn\0esan.hokkaido.jp\0" -"events\0like\0" -"\xe4\xbc\x81\xe4\xb8\x9a\0" -"i.ph\0" -"kariya.aichi.jp\0minamifurano.hokkaido.jp\0ibestad.no\0rsvp\0" -"shiroi.chiba.jp\0" -"kikuchi.kumamoto.jp\0" -"or.na\0" -"miyazu.kyoto.jp\0hughes\0" -"or.mu\0bosch\0technology\0" -"yakage.okayama.jp\0" -"kamishihoro.hokkaido.jp\0" -"intuit\0" -"lease\0servehttp.com\0" -"shiftcrypto.io\0" -"otsuki.yamanashi.jp\0media.pl\0eero.online\0" -"higashiyama.kyoto.jp\0" -"kapsi.fi\0" -"worse-than.tv\0mozilla-iot.org\0" -"kawaiishop.jp\0" -"cnt.br\0limo\0" -"nichinan.tottori.jp\0" -"qualifioapp.com\0" -"vicenza.it\0" -"manaus.br\0" -"asso.fr\0int.in\0kodaira.tokyo.jp\0i.se\0memset.net\0" -"barclaycard\0" -"link\0" -"int.is\0" -"ogi.saga.jp\0" -"\xc3\xb8ystre-slidre.no\0" -"*.oci.customer-oci.com\0" -"takaishi.osaka.jp\0cantho.vn\0" -"asso.gp\0" -"misawa.aomori.jp\0or.pw\0" -"olayangroup\0" -"eng.pro\0capital\0theater\0ro.eu.org\0" -"fuoisku.no\0" -"trentin-s\xc3\xbc""dtirol.it\0takko.aomori.jp\0herad.no\0kolobrzeg.pl\0" -"takahagi.ibaraki.jp\0" -"forl\xc3\xac""cesena.it\0nonoichi.ishikawa.jp\0\xd8\xb3\xd9\x88\xd8\xaf\xd8\xa7\xd9\x86\0" -"asso.ht\0froya.no\0" -"int.la\0b\xc3\xb8.telemark.no\0yoga\0" -"sagamihara.kanagawa.jp\0is-a-techie.com\0" -"hinohara.tokyo.jp\0eu.pythonanywhere.com\0" -"airforce\0" -"nodes.k8s.fr-par.scw.cloud\0" -"translate.goog\0" -"int.lk\0" -"from-fl.com\0" -"from-oh.com\0" -"kumenan.okayama.jp\0" -"\xd8\xb9\xd8\xb1\xd8\xa8\0icurus.jp\0" -"api.stdlib.com\0" -"honbetsu.hokkaido.jp\0" -"katagami.akita.jp\0" -"kasai.hyogo.jp\0" -"motosu.gifu.jp\0kamitonda.wakayama.jp\0wodzislaw.pl\0" -"tomioka.gunma.jp\0" -"or.th\0iserv.dev\0" -"capetown\0" -"asso.ci\0voting\0" -"int.mv\0goodyear\0" -"int.mw\0vestre-toten.no\0" -"tarnobrzeg.pl\0" -"seg.br\0int.ni\0" -"elementor.cloud\0" -"or.ug\0" -"or.tz\0" -"akamaized.net\0" -"si.eu.org\0" -"ab.ca\0" -"in.na\0" -"playstation-cloud.com\0" -"site.tb-hosting.com\0" -"baria-vungtau.vn\0" -"yoshinogari.saga.jp\0" -"or.us\0" -"hob\xc3\xb8l.no\0" -"not.br\0hatinh.vn\0" -"er.in\0in.ni\0olsztyn.pl\0" -"cloudns.biz\0" -"pippu.hokkaido.jp\0" -"hiroo.hokkaido.jp\0ee.eu.org\0" -"tomiya.miyagi.jp\0" -"asso.dz\0hurum.no\0" -"mima.tokushima.jp\0flekkefjord.no\0" -"lavangen.no\0" -"sic.it\0" -"2000.hu\0enscaled.sg\0" -"imamat\0alwaysdata.net\0" -"tranby.no\0" -"int.pt\0" -"gjerstad.no\0" -"roan.no\0" -"vfs.cloud9.ap-east-1.amazonaws.com\0" -"live\0" -"\xe5\xae\xae\xe5\x9f\x8e.jp\0" -"radom.pl\0" -"deatnu.no\0seat\0" -"myvnc.com\0" -"fentiger.mythic-beasts.com\0" -"shibuya.tokyo.jp\0" -"trentin-suedtirol.it\0" -"kiyosu.aichi.jp\0" -"kv.ua\0sk.eu.org\0" -"shirakawa.fukushima.jp\0fujishiro.ibaraki.jp\0" -"bz.it\0showa.yamanashi.jp\0boehringer\0" -"int.ru\0" -"lynx.mythic-beasts.com\0" -"kasumigaura.ibaraki.jp\0flesberg.no\0" -"higashitsuno.kochi.jp\0" -"m\xc3\xa5lselv.no\0" -"nayoro.hokkaido.jp\0namerikawa.toyama.jp\0simple-url.com\0virtualserver.io\0" -"rs.ba\0lomo.jp\0" -"rovigo.it\0warszawa.pl\0" -"eun.eg\0chieti.it\0lomza.pl\0" -"in.rs\0" -"int.tj\0penza.su\0wpenginepowered.com\0" -"homes\0" -"r.bg\0sortland.no\0" -"av.it\0" -"n\xc3\xa6r\xc3\xb8y.no\0" -"bamble.no\0" -"voyage\0" -"ichinohe.iwate.jp\0" -"is-slick.com\0" -"int.tt\0homesecuritypc.com\0" -"rauma.no\0\xd0\xbc\xd1\x81\xd0\xba.\xd1\x80\xd1\x83\xd1\x81\0" -"chintai\0" -"in.th\0" -"sado.niigata.jp\0pioneer\0promo\0" -"sc.cn\0seek\0cn.com\0" -"k12.nh.us\0" -"otari.nagano.jp\0s3-website.us-east-2.amazonaws.com\0" -"in.ua\0" -"int.ve\0wedeploy.sh\0" -"fra1-de.cloudjiffy.net\0" -"rennesoy.no\0publ.pt\0" -"lib.in.us\0" -"far.br\0barefoot\0" -"kirovograd.ua\0beats\0" -"kakamigahara.gifu.jp\0teshikaga.hokkaido.jp\0" -"khmelnytskyi.ua\0" -"yoshida.shizuoka.jp\0int.vn\0x.mythic-beasts.com\0" -"bradesco\0" -"qld.edu.au\0independent-commission.uk\0" -"ru.eu.org\0se.eu.org\0" -"bialystok.pl\0" -"in.us\0" -"homegoods\0" -"przeworsk.pl\0hobby-site.org\0" -"andria-barletta-trani.it\0" -"\xc3\xb8ksnes.no\0merseine.nu\0" -"avianca\0" -"nishiazai.shiga.jp\0" -"mimata.miyazaki.jp\0" -"aeroport.fr\0xs4all.space\0" -"og.ao\0" -"uk.in\0hiroshima.jp\0ovre-eiker.no\0" -"thick.jp\0" -"osteroy.no\0dnsfor.me\0" -"iwata.shizuoka.jp\0" -"myspreadshop.com\0" -"ruhr\0sp.leg.br\0" -"6.bg\0sakae.chiba.jp\0from-va.com\0" -"s3-website.ap-northeast-2.amazonaws.com\0" -"tohnosho.chiba.jp\0" -"\xe9\x95\xb7\xe9\x87\x8e.jp\0" -"orange\0" -"ws.na\0" -"\xe5\xb2\x90\xe9\x98\x9c.jp\0" -"oita.jp\0ngrok-free.app\0" -"familyds.net\0" -"s3-website-ap-southeast-1.amazonaws.com\0" -"webview-assets.aws-cloud9.us-east-1.amazonaws.com\0" -"net.ac\0" -"omuta.fukuoka.jp\0takanabe.miyazaki.jp\0uk.kg\0" -"net.ae\0is-a-green.com\0" -"net.af\0sp.gov.br\0*.dev-builder.code.com\0" -"net.ag\0" -"seto.aichi.jp\0" -"net.ai\0ide.kyoto.jp\0" -"sakai.fukui.jp\0" -"net.al\0" -"net.am\0\xe5\x9c\xa8\xe7\xba\xbf\0" -"yasu.shiga.jp\0dnsalias.net\0" -"misato.shimane.jp\0" -"net.ba\0" -"net.ar\0net.bb\0\xce\xb5\xce\xbb\0" -"sakura.tv\0" -"enf.br\0kashiba.nara.jp\0" -"net.au\0" -"seki.gifu.jp\0football\0" -"net.bh\0" -"in-vpn.org\0" -"net.az\0net.bj\0" -"\xce\xb5\xcf\x85\0komatsu\0is-a-designer.com\0" -"net.bm\0" -"net.bn\0" -"net.bo\0lotte\0" -"odda.no\0" -"net.br\0" -"net.bs\0no.com\0" -"net.bt\0" -"fireweb.app\0" -"forumz.info\0" -"dn.ua\0hacca.jp\0" -"net.ci\0lotto\0publishproxy.com\0" -"net.bz\0ricoh\0" -"net.cm\0\xc3\xa5mot.no\0opole.pl\0" -"net.cn\0\xe5\xa8\xb1\xe4\xb9\x90\0" -"net.co\0yamaga.kumamoto.jp\0" -"fetsund.no\0asso.re\0" -"servehalflife.com\0" -"sc.ke\0" -"net.cu\0" -"rar.ve\0" -"net.cw\0" -"council.aero\0trieste.it\0kuzumaki.iwate.jp\0siellak.no\0" -"net.cy\0" -"cagliari.it\0kamo.niigata.jp\0" -"net.dm\0half.host\0" -"institute\0juniper\0" -"net.do\0piedmont.it\0fastly-terrarium.com\0" -"shimane.shimane.jp\0so.gov.pl\0" -"sc.kr\0finn\xc3\xb8y.no\0" -"net.ec\0" -"washtenaw.mi.us\0selfip.org\0" -"net.eg\0!city.kawasaki.jp\0sano.tochigi.jp\0" -"democracia.bo\0aizumi.tokushima.jp\0laocai.vn\0" -"net.dz\0chonan.chiba.jp\0vm.bytemark.co.uk\0" -"akita.akita.jp\0ariake.saga.jp\0akrehamn.no\0eu-west-1.elasticbeanstalk.com\0" -"money\0" -"balsan-s\xc3\xbc""dtirol.it\0porsangu.no\0" -"sc.ls\0" -"net.et\0theatre\0" -"hemnes.no\0apps.fbsbx.com\0" -"myhome-server.de\0" -"net.fj\0av.tr\0" -"noor.jp\0" -"net.fm\0\xe9\x80\x9a\xe8\xb2\xa9\0" -"condos\0" -"sakura\0" -"batsfjord.no\0wedeploy.me\0" -"kitanakagusuku.okinawa.jp\0" -"net.ge\0\xe8\x81\x94\xe9\x80\x9a\0" -"dyn-o-saur.com\0" -"net.gg\0" -"udi.br\0catfood.jp\0" -"chijiwa.nagasaki.jp\0" -"net.gl\0" -"net.gn\0og.it\0asso.nc\0" -"saarland\0kaluga.su\0" -"net.gp\0onojo.fukuoka.jp\0" -"minamitane.kagoshima.jp\0" -"net.gr\0" -"net.gt\0sannohe.aomori.jp\0" -"net.gu\0vinnytsia.ua\0" -"\xd8\xa7\xd9\x84\xd8\xa7\xd8\xb1\xd8\xaf\xd9\x86\0" -"sasaguri.fukuoka.jp\0lib.az.us\0" -"shiroishi.miyagi.jp\0mmafan.biz\0" -"net.gy\0chino.nagano.jp\0" -"net.hk\0" -"okinawa.okinawa.jp\0" -"net.hn\0bbs.tr\0" -"logistics.aero\0tagawa.fukuoka.jp\0bharti\0" -"cn.eu.org\0" -"piacenza.it\0shiiba.miyazaki.jp\0" -"net.ht\0net.id\0seirou.niigata.jp\0sellfy.store\0" -"kashihara.nara.jp\0" -"streamlit.app\0" -"ms.it\0s3-us-gov-west-1.amazonaws.com\0" -"services.aero\0morimachi.shizuoka.jp\0honda\0" -"likescandy.com\0" -"net.il\0" -"rec.br\0net.im\0" -"net.in\0fujitsu\0" -"com.ac\0net.iq\0" -"net.ir\0shingo.aomori.jp\0" -"net.is\0nexus\0" -"com.af\0" -"com.ag\0net.je\0" -"com.ai\0yachiyo.chiba.jp\0webview-assets.aws-cloud9.ap-east-1.amazonaws.com\0" -"go.ci\0webview-assets.aws-cloud9.eu-central-1.amazonaws.com\0" -"com.al\0rec.co\0hdfc\0" -"com.am\0" -"klodzko.pl\0karaganda.su\0" -"nishihara.kumamoto.jp\0moroyama.saitama.jp\0" -"com.ba\0net.jo\0yolasite.com\0" -"com.ar\0com.bb\0lo.it\0""001www.com\0authgearapps.com\0" -"go.cr\0" -"com.au\0goiania.br\0ushiku.ibaraki.jp\0eu-central-1.elasticbeanstalk.com\0" -"sld.do\0" -"com.aw\0ms.kr\0" -"com.bh\0" -"com.bi\0net.kg\0loginline.io\0mein-vigor.de\0" -"com.az\0com.bj\0international\0" -"net.ki\0" -"brindisi.it\0walmart\0" -"com.bm\0rindal.no\0club\0" -"com.bn\0" -"com.bo\0calabria.it\0" -"wanouchi.gifu.jp\0net.kn\0winb.gov.pl\0\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0" -"london.cloudapps.digital\0" -"com.br\0oita.oita.jp\0" -"com.bs\0net.la\0" -"com.bt\0net.lb\0" -"net.lc\0" -"ichiba.tokushima.jp\0" -"c66.me\0" -"com.by\0com.ci\0net.kw\0snowflake.app\0" -"com.bz\0" -"net.ky\0r.se\0" -"net.kz\0mattel\0crap.jp\0" -"com.cm\0net.lk\0" -"com.cn\0" -"com.co\0" -"shinshinotsu.hokkaido.jp\0" -"\xe6\x94\xbf\xe5\xba\x9c.hk\0" -"traniandriabarletta.it\0fujisawa.iwate.jp\0net.ma\0" -"urausu.hokkaido.jp\0emb.kw\0net.lr\0" -"avocats.bj\0com.cu\0net.ls\0com.de\0" -"com.cv\0" -"com.cw\0net.me\0" -"net.lv\0" -"com.cy\0" -"asso.km\0\xc3\xb8yer.no\0" -"net.ly\0" -"com.dm\0net.mk\0" -"net.ml\0" -"com.do\0kosei.shiga.jp\0" -"net.mo\0" -"com.ec\0" -"hammarfeasta.no\0" -"com.ee\0net.ms\0" -"kitayama.wakayama.jp\0net.mt\0" -"com.eg\0kota.aichi.jp\0net.mu\0" -"net.mv\0net.nf\0sc.ug\0drr.ac\0ddnss.de\0" -"net.mw\0net.ng\0" -"bet.ar\0com.dz\0net.mx\0" -"net.my\0net.ni\0sc.tz\0" -"net.mz\0govt.nz\0" -"nanae.hokkaido.jp\0barrell-of-knowledge.info\0" -"asso.mc\0" -"bodo.no\0sr.gov.pl\0" -"com.es\0versicherung\0us.ngrok.io\0" -"com.et\0net.nr\0sc.us\0cy.eu.org\0" -"fosnes.no\0" -"prod\0futurehosting.at\0" -"com.fj\0grocery\0" -"prof\0" -"net.nz\0" -"com.fm\0f\xc3\xb8rde.no\0" -"net.om\0" -"vlaanderen\0" -"abkhazia.su\0" -"com.fr\0" -"net.pa\0" -"geekgalaxy.com\0" -"com.ge\0" -"go.id\0skjervoy.no\0" -"net.pe\0beep.pl\0" -"com.gh\0\xe7\x9f\xb3\xe5\xb7\x9d.jp\0" -"com.gi\0" -"nedre-eiker.no\0net.ph\0" -"com.gl\0" -"net.pk\0sexy\0servegame.com\0" -"com.gn\0net.pl\0" -"mil.ac\0" -"com.gp\0net.pn\0" -"mil.ae\0citadel\0" -"com.gr\0" -"net.qa\0vacations\0" -"com.gt\0rybnik.pl\0net.pr\0cz.eu.org\0" -"com.gu\0net.ps\0odessa.ua\0online\0" -"go.it\0net.pt\0" -"iglesias-carbonia.it\0shimoda.shizuoka.jp\0" -"mil.al\0b\xc3\xa1l\xc3\xa1t.no\0" -"com.gy\0haiphong.vn\0" -"omaezaki.shizuoka.jp\0" -"com.hk\0hs.kr\0vardo.no\0net.py\0abbott\0" -"\xe5\xa4\xa9\xe4\xb8\xbb\xe6\x95\x99\0" -"mil.ba\0profesional.bo\0school.za\0cloudaccess.net\0" -"mil.ar\0com.hn\0" -"fukui.jp\0" -"com.hr\0go.jp\0" -"com.ht\0nishinoshima.shimane.jp\0" -"mil.az\0loisirs.bj\0" -"palermo.it\0go.ke\0daa.jp\0" -"sch.ae\0mil.bo\0lanbib.se\0" -"com.im\0finance\0" -"mil.br\0com.in\0" -"com.io\0" -"com.iq\0" -"com.is\0net.sa\0" -"go.kr\0net.sb\0from-vt.com\0dk.eu.org\0" -"mil.by\0net.sc\0" -"net.sd\0" -"from-mo.com\0net.ru\0" -"mil.cl\0" -"net.rw\0net.sg\0simplesite.com\0" -"mil.cn\0tra.kp\0net.sh\0office-on-the.net\0" -"mil.co\0" -"epson\0\xe5\x98\x89\xe9\x87\x8c\0" -"hostedpi.com\0wedeploy.io\0" -"net.sl\0" -"com.jo\0" -"frenchkiss.jp\0" -"net.so\0" -"properties\0" -"mil.cy\0hyogo.jp\0net.ss\0" -"trentino-s-tirol.it\0net.st\0" -"com.kg\0nc.tr\0" -"extraspace\0" -"tsubata.ishikawa.jp\0com.ki\0" -"takamori.kumamoto.jp\0kamikitayama.nara.jp\0net.th\0" -"mil.do\0net.sy\0lib.ok.us\0" -"net.tj\0" -"oyabe.toyama.jp\0com.km\0" -"mil.ec\0higashiagatsuma.gunma.jp\0net.tm\0fage\0matrix.jp\0" -"com.kp\0net.tn\0" -"com.la\0net.to\0" -"oshima.yamaguchi.jp\0com.lb\0ug.gov.pl\0" -"mil.eg\0com.lc\0rec.nf\0net.ua\0\xe0\xa4\x95\xe0\xa5\x89\xe0\xa4\xae\0est-le-patron.com\0" -"net.tr\0" -"net.tt\0shopitsite.com\0" -"com.kw\0" -"fuchu.toyama.jp\0ms.us\0nc.us\0\xd8\xa8\xd8\xa7\xd8\xb2\xd8\xa7\xd8\xb1\0" -"com.ky\0\xc3\xa5snes.no\0net.tw\0" -"com.kz\0" -"cs.in\0com.lk\0" -"net.uk\0" -"shiki.saitama.jp\0\xe6\x94\xbf\xe5\xba\x9c.\xe9\xa6\x99\xe6\xb8\xaf\0" -"cs.it\0" -"com.lr\0eurovision\0" -"friuli-v-giulia.it\0aurskog-holand.no\0" -"net.vc\0" -"mil.fj\0bihoro.hokkaido.jp\0com.lv\0mup.gov.pl\0" -"com.mg\0net.ve\0" -"sld.pa\0" -"aquila.it\0com.ly\0" -"toon.ehime.jp\0" -"com.mk\0net.uy\0net.vi\0markets\0" -"com.ml\0net.uz\0lacaixa\0" -"com.mo\0" -"daito.osaka.jp\0net.vn\0" -"mil.ge\0video.hu\0com.na\0homedns.org\0" -"com.ms\0" -"mil.gh\0com.mt\0de.eu.org\0" -"aland.fi\0com.mu\0" -"com.mv\0com.nf\0bieszczady.pl\0fail\0" -"\xe5\xb2\xa1\xe5\xb1\xb1.jp\0com.mw\0com.ng\0net.vu\0xihuan\0tech.orange\0" -"com.mx\0" -"com.my\0com.ni\0b\xc3\xb8.nordland.no\0" -"bo.it\0\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86\0" -"higashikurume.tokyo.jp\0tysvar.no\0is-into-anime.com\0" -"minowa.nagano.jp\0ohda.shimane.jp\0bestbuy\0temasek\0" -"lib.ks.us\0" -"emilia-romagna.it\0\xe4\xba\xac\xe9\x83\xbd.jp\0chernivtsi.ua\0" -"mil.gt\0" -"com.nr\0chanel\0channelsdvr.net\0" -"abo.pa\0buyshop.jp\0" -"net.ws\0yachts\0" -"vaksdal.no\0\xe7\xbb\x84\xe7\xbb\x87\xe6\x9c\xba\xe6\x9e\x84\0" -"go.pw\0" -"mil.hn\0verse.jp\0" -"kumiyama.kyoto.jp\0" -"com.om\0mragowo.pl\0k12.mo.us\0" -"serveftp.com\0" -"mil.id\0" -"sanuki.kagawa.jp\0com.pa\0" -"g.bg\0aarborte.no\0frontdoor\0" -"sveio.no\0" -"tolga.no\0" -"com.pe\0" -"com.pf\0" -"narashino.chiba.jp\0net.ye\0" -"entertainment.aero\0com.ph\0gotdns.com\0" -"\xda\x80\xd8\xa7\xd8\xb1\xd8\xaa\0" -"mil.in\0" -"!www.ck\0com.pk\0" -"com.pl\0rec.ro\0is-a-llama.com\0" -"mil.iq\0lon-1.paas.massivegrid.net\0" -"9guacu.br\0living\0" -"puglia.it\0matsuzaki.shizuoka.jp\0com.qa\0uk.primetel.cloud\0" -"katsuura.chiba.jp\0com.pr\0sadist.jp\0" -"com.ps\0net.za\0kilatiron.com\0" -"pila.pl\0com.pt\0" -"happou.akita.jp\0typedream.app\0" -"whoswho\0" -"com.py\0pgfog.com\0" -"sch.id\0inashiki.ibaraki.jp\0rentals\0cloudapps.digital\0" -"mil.jo\0strand.no\0" -"ikeda.osaka.jp\0etisalat\0" -"kumamoto.kumamoto.jp\0" -"sukagawa.fukushima.jp\0net.zm\0synology-ds.de\0" -"\xc3\xa5lg\xc3\xa5rd.no\0" -"mil.kg\0urown.cloud\0" -"travel\0" -"com.re\0bip.sh\0" -"tokamachi.niigata.jp\0hokksund.no\0\xe6\x9b\xb8\xe7\xb1\x8d\0" -"staples\0" -"sch.ir\0" -"mil.km\0schule\0karacol.su\0" -"go.th\0is-an-engineer.com\0" -"cuneo.it\0" -"nanto.toyama.jp\0go.tj\0" -"mil.kr\0guge\0" -"com.ro\0" -"oshu.iwate.jp\0" -"kimitsu.chiba.jp\0com.sa\0restaurant\0" -"com.sb\0" -"com.sc\0" -"mat.br\0com.sd\0gripe\0" -"sch.jo\0com.se\0is-saved.org\0com.ru\0" -"mil.kz\0" -"com.sg\0" -"com.sh\0" -"go.ug\0" -"littlestar.jp\0" -"embetsu.hokkaido.jp\0com.sl\0go.tz\0" -"fans\0supersale.jp\0" -"com.sn\0" -"com.so\0" -"semboku.akita.jp\0adachi.tokyo.jp\0eu.org\0g\xc3\xbcnstigbestellen.de\0" -"zombie.jp\0xen.prgmr.com\0" -"mil.lv\0rec.ve\0" -"mil.mg\0com.ss\0" -"com.st\0" -"com.sv\0" -"tp.it\0" -"com.sy\0torproject.net\0" -"com.tj\0" -"com.tm\0" -"com.tn\0" -"gs.oslo.no\0com.to\0" -"sch.lk\0com.ua\0" -"nl.ca\0mil.mv\0com.tr\0zara\0logoip.de\0" -"mil.ng\0career\0is-an-artist.com\0" -"gliding.aero\0com.tt\0" -"mil.my\0mil.ni\0" -"mil.mz\0to.leg.br\0" -"com.tw\0com.ug\0" -"oketo.hokkaido.jp\0s3-eu-west-3.amazonaws.com\0nl.ci\0" -"gotemba.shizuoka.jp\0mil.no\0" -"gop.pk\0" -"sch.ly\0" -"trentino-suedtirol.it\0" -"\xd8\xa7\xdb\x8c\xd8\xb1\xd8\xa7\xd9\x86.ir\0" -"com.vc\0" -"ca.eu.org\0" -"okayama.jp\0sakai.ibaraki.jp\0com.ve\0" -"ogasawara.tokyo.jp\0mil.nz\0" -"\xe9\x95\xb7\xe5\xb4\x8e.jp\0" -"to.gov.br\0" -"com.uy\0com.vi\0" -"com.uz\0expert\0" -"sch.ng\0own.pm\0" -"aparecida.br\0com.vn\0" -"kawaba.gunma.jp\0" -"mil.pe\0ownprovider.com\0" -"mypets.ws\0" -"mil.ph\0kropyvnytskyi.ua\0" -"com.vu\0iopsys.se\0" -"amazon\0" -"kazuno.akita.jp\0farm\0" -"mil.pl\0zt.ua\0point2this.com\0" -"stripper.jp\0privatizehealthinsurance.net\0" -"tksat.bo\0" -"mil.qa\0" -"tenri.nara.jp\0" -"hakuba.nagano.jp\0" -"inatsuki.fukuoka.jp\0com.ws\0" -"takanezawa.tochigi.jp\0" -"kamisato.saitama.jp\0mil.py\0" -"kerrylogistics\0freemyip.com\0" -"help\0" -"def.br\0mytis.ru\0" -"group.aero\0modena.it\0" -"vegarshei.no\0" -"h\xc3\xa1""bmer.no\0" -"jolster.no\0wif.gov.pl\0fast\0" -"bayern\0" -"dc.us\0" -"monza-brianza.it\0motobu.okinawa.jp\0" -"mishima.fukushima.jp\0storfjord.no\0" -"pt.it\0" -"instance.datadetect.com\0" -"com.ye\0" -"tondabayashi.osaka.jp\0" -"sch.qa\0" -"audio\0" -"cc.sd.us\0sa.com\0is-a-nascarfan.com\0" -"booking\0\xe5\x81\xa5\xe5\xba\xb7\0itigo.jp\0" -"en-root.fr\0" -"jus.br\0narvik.no\0is-by.us\0" -"prato.it\0\xe5\x95\x86\xe5\x9f\x8e\0" -"tomika.gifu.jp\0omasvuotna.no\0mil.ru\0*.diher.solutions\0a.prod.fastly.net\0" -"siljan.no\0rivne.ua\0\xe3\x83\x9d\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0" -"mil.rw\0" -"mil.sh\0ybo.review\0" -"\xe3\x82\xa2\xe3\x83\x9e\xe3\x82\xbe\xe3\x83\xb3\0" -"boavista.br\0" -"monzaedellabrianza.it\0" -"aogaki.hyogo.jp\0" -"com.zm\0" -"honai.ehime.jp\0" -"simplesite.com.br\0" -"algard.no\0mil.st\0s3-us-east-2.amazonaws.com\0" -"maison\0" -"mil.sy\0lib.as.us\0danang.vn\0" -"mil.tj\0" -"ikeda.hokkaido.jp\0sch.sa\0" -"fishing\0loginto.me\0" -"kashima.saga.jp\0mil.tm\0" -"akdn\0" -"mil.to\0" -"floro.no\0" -"mil.tr\0" -"matsukawa.nagano.jp\0ak.us\0" -"mil.tw\0zuerich\0" -"muni.il\0fjaler.no\0engineer\0appspacehosted.com\0cd.eu.org\0bitter.jp\0" -"k12.co.us\0sch.so\0familyds.org\0" -"mil.tz\0" -"sch.ss\0" -"3utilities.com\0sch.tf\0" -"yawatahama.ehime.jp\0hoyanger.no\0" -"mil.vc\0*.ex.futurecms.at\0" -"design.aero\0mil.ve\0" -"enebakk.no\0olkusz.pl\0" -"dnsalias.org\0" -"mil.uy\0simplesite.gr\0" -"off.ai\0pordenone.it\0windows\0" -"in-vpn.net\0" -"gx.cn\0hockey\0" -"overhalla.no\0here\0" -"tonosho.kagawa.jp\0apps.lair.io\0" -"meldal.no\0" -"ikano\0" -"kuroiso.tochigi.jp\0" -"cc.oh.us\0blog.gt\0" -"tsugaru.aomori.jp\0" -"nishigo.fukushima.jp\0lilly\0supply\0" -"mydissent.net\0" -"jozi.biz\0" -"broker\0" -"walbrzych.pl\0ut.us\0guru\0jdevcloud.com\0" -"tatsuno.hyogo.jp\0x0.to\0" -"gd.cn\0" -"\xc3\xb8rskog.no\0" -"co.business\0" -"sch.wf\0" -"hokuryu.hokkaido.jp\0waw.pl\0" -"cc.mt.us\0cc.nd.us\0" -"leitungsen.de\0" -"mil.ye\0\xd1\x81\xd0\xbf\xd0\xb1.\xd1\x80\xd1\x83\xd1\x81\0" -"seranishi.hiroshima.jp\0" -"walter\0" -"ntr.br\0baclieu.vn\0" -"\xe7\xbd\x91\xe7\xbb\x9c\0" -"shaw\0" -"mil.za\0" -"nagi.okayama.jp\0" -"blog.bo\0nl.no\0g.se\0k12.ak.us\0*.northflank.app\0" -"blog.br\0nyan.to\0" -"dyn.cosidns.de\0" -"bievat.no\0" -"kanonji.kagawa.jp\0loab\xc3\xa1t.no\0norton\0" -"mil.zm\0" -"mamurogawa.yamagata.jp\0" -"meiwa.gunma.jp\0" -"is-a-therapist.com\0" -"shoes\0" -"takahama.fukui.jp\0is-very-bad.org\0" -"mil.zw\0jp.kg\0" -"stada\0" -"lib.sd.us\0" -"rel.ht\0fujiyoshida.yamanashi.jp\0" -"lel.br\0babia-gora.pl\0" -"hadsel.no\0" -"sch.zm\0erni\0poniatowa.pl\0" -"seoul.kr\0systems\0" -"from-ri.com\0" -"kurate.fukuoka.jp\0from-pr.com\0" -"tagami.niigata.jp\0unazuki.toyama.jp\0mintere.site\0" -"cleverapps.io\0" -"kamisunagawa.hokkaido.jp\0" -"k12.tn.us\0s3.dualstack.ap-southeast-2.amazonaws.com\0fr-par-2.baremetal.scw.cloud\0ts.net\0" -"floppy.jp\0" -"saogonca.br\0dyn-vpn.de\0jp.md\0" -"tako.chiba.jp\0toyota\0" -"*.moonscale.io\0" -"\xe6\xbb\x8b\xe8\xb3\x80.jp\0" -"messina.it\0selfip.biz\0main.jp\0" -"lakas.hu\0showa.gunma.jp\0gyeongnam.kr\0" -"shibata.miyagi.jp\0\xd0\xb1\xd0\xb8\xd0\xb7.\xd1\x80\xd1\x83\xd1\x81\0" -"secret.jp\0" -"ibaraki.ibaraki.jp\0" -"ekloges.cy\0" -"toolforge.org\0" -"oshino.yamanashi.jp\0" -"barsyonline.co.uk\0" -"blush.jp\0" -"shinichi.hiroshima.jp\0kuki.saitama.jp\0gjesdal.no\0" -"nagaokakyo.kyoto.jp\0" -"durban\0dnsdojo.org\0" -"cipriani\0" -"simplesite.pl\0" -"toba.mie.jp\0austevoll.no\0trycloudflare.com\0vs.mythic-beasts.com\0" -"vinnica.ua\0cc.id.us\0" -"medicina.bo\0" -"apigee.io\0" -"frogans\0e4.cz\0" -"trentinsuedtirol.it\0hakata.fukuoka.jp\0" -"s3.dualstack.sa-east-1.amazonaws.com\0" -"seika.kyoto.jp\0hungyen.vn\0" -"jcloud-ver-jpc.ik-server.com\0s3-website.nl-ams.scw.cloud\0" -"arq.br\0" -"gokase.miyazaki.jp\0" -"goshiki.hyogo.jp\0shia\0" -"tone.ibaraki.jp\0" -"sekikawa.niigata.jp\0" -"florence.it\0" -"akkeshi.hokkaido.jp\0prequalifyme.today\0" -"la-spezia.it\0" -"yorii.saitama.jp\0" -"himeshima.oita.jp\0" -"hisamitsu\0vegas\0" -"alessandria.it\0" -"maintenance.aero\0" -"vik.no\0" -"lib.mt.us\0lib.nd.us\0" -"mukawa.hokkaido.jp\0" -"cc.fl.us\0" -"divtasvuodna.no\0" -"furano.hokkaido.jp\0ciao.jp\0barsy.co.uk\0" -"kadogawa.miyazaki.jp\0" -"siracusa.it\0ski.no\0" -"krager\xc3\xb8.no\0" -"jelastic.dogado.eu\0" -"from-ny.net\0" -"ikaruga.nara.jp\0\xed\x95\x9c\xea\xb5\xad\0webview-assets.cloud9.sa-east-1.amazonaws.com\0" -"auction\0" -"rel.pl\0" -"ch.it\0" -"netgamers.jp\0" -"vfs.cloud9.eu-south-1.amazonaws.com\0" -"crew.aero\0" -"plc.ly\0lancaster\0" -"ama.shimane.jp\0" -"sunagawa.hokkaido.jp\0trogstad.no\0" -"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa7\0" -"monzabrianza.it\0" -"\xd8\xb3\xd9\x88\xd8\xb1\xd9\x8a\xd8\xa9\0" -"eigersund.no\0" -"vall\xc3\xa9""eaoste.it\0" -"sa.au\0perma.jp\0" -"catholic\0" -"chiyoda.gunma.jp\0" -"ooshika.nagano.jp\0" -"p.bg\0" -"at.it\0" -"vindafjord.no\0daknong.vn\0" -"bananarepublic\0" -"tunes\0" -"cc.ct.us\0" -"shop.ht\0ismaili\0" -"shop.hu\0" -"shiriuchi.hokkaido.jp\0" -"sakata.yamagata.jp\0stranda.no\0" -"ap-northeast-1.elasticbeanstalk.com\0" -"aaa.pro\0" -"groundhandling.aero\0presse.km\0" -"sa.cr\0" -"bar.pro\0" -"blog.vu\0" -"shingu.fukuoka.jp\0cool\0" -"bjarkoy.no\0" -"coop\0" -"\xe7\xbe\xa4\xe9\xa6\xac.jp\0slupsk.pl\0" -"s\xc3\xa1lat.no\0" -"webhop.info\0" -"shop\0" -"africa.bj\0moseushi.hokkaido.jp\0il.us\0" -"takino.hyogo.jp\0kosai.shizuoka.jp\0koto.tokyo.jp\0show\0" -"funahashi.toyama.jp\0voorloper.cloud\0" -"work\0" -"is-a-patsfan.org\0at.md\0" -"yachimata.chiba.jp\0\xe5\x8f\xb0\xe6\xb9\xbe\0" -"patria.bo\0" -"presse.ml\0fastlylb.net\0" -"lib.id.us\0" -"yasugi.shimane.jp\0" -"shimane.jp\0nakamura.kochi.jp\0" -"cc.al.us\0" -"kisarazu.chiba.jp\0" -"leksvik.no\0\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xd8\xa9\0" -"m\xc3\xa1latvuopmi.no\0" -"reservd.disrec.thingdust.io\0" -"hanggliding.aero\0flights\0" -"kamaishi.iwate.jp\0" -"jls-sto3.elastx.net\0" -"4.bg\0obuse.nagano.jp\0" -"cc.wi.us\0" -"\xe6\x94\xbf\xe5\x8a\xa1\0" -"koganei.tokyo.jp\0amscompute.com\0" -"nu.ca\0" -"oke.gov.pl\0" -"jellybean.jp\0" -"ong.br\0tsubame.niigata.jp\0kraanghke.no\0storj.farm\0" -"odate.akita.jp\0yanagawa.fukuoka.jp\0" -"kosuge.yamanashi.jp\0" -"minamiuonuma.niigata.jp\0" -"myfast.host\0" -"cloudycluster.net\0" -"shimabara.nagasaki.jp\0selfip.com\0" -"te.it\0" -"gangaviika.no\0\xe5\x95\x86\xe6\xa5\xad.tw\0" -"is-a-conservative.com\0" -"zarow.pl\0" -"agematsu.nagano.jp\0" -"webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com\0servepics.com\0" -"kr.com\0" -"reliance\0" -"arakawa.saitama.jp\0" -"teramo.it\0plc.uk\0" -"bizen.okayama.jp\0" -"catering\0" -"jinsekikogen.hiroshima.jp\0" -"accident-investigation.aero\0" -"laspezia.it\0sa.it\0balena-devices.com\0" -"ina.saitama.jp\0" -"miyawaka.fukuoka.jp\0" -"today\0independent-panel.uk\0*.uberspace.de\0" -"lutsk.ua\0" -"tennis\0" -"ch.eu.org\0" -"ally\0ch.tc\0" -"sells-for-u.com\0" -"iglesiascarbonia.it\0" -"legal\0github.io\0" -"sandoy.no\0" -"bd.se\0" -"turin.it\0*.kawasaki.jp\0" -"tarui.gifu.jp\0nsn.us\0" -"webview-assets.aws-cloud9.eu-west-3.amazonaws.com\0" -"arida.wakayama.jp\0" -"lib.ct.us\0" -"lovepop.jp\0" -"enterprises\0eastasia.azurestaticapps.net\0ngrok.app\0" -"123website.nl\0" -"from-hi.com\0chips.jp\0" -"sasayama.hyogo.jp\0" -"works\0" -"okaya.nagano.jp\0world\0" -"hanawa.fukushima.jp\0from-ne.com\0" -"koga.fukuoka.jp\0ashibetsu.hokkaido.jp\0" -"kameyama.mie.jp\0" -"nombre.bo\0" -"pi.it\0" -"rodoy.no\0" -"shimodate.ibaraki.jp\0" -"express.aero\0" -"yao.osaka.jp\0" -"webview-assets.cloud9.ap-northeast-2.amazonaws.com\0" -"daegu.kr\0cc.ri.us\0hb.cldmail.ru\0" -"s3-ap-southeast-2.amazonaws.com\0" -"isesaki.gunma.jp\0tayninh.vn\0" -"*.stolos.io\0" -"cog.mi.us\0" -"isa-geek.org\0centralus.azurestaticapps.net\0" -"iki.nagasaki.jp\0os.hedmark.no\0" -"wa.edu.au\0""3.azurestaticapps.net\0" -"ivano-frankivsk.ua\0sblo.jp\0" -"nu.it\0shintoku.hokkaido.jp\0black\0olayan\0deno.dev\0" -"at.vg\0" -"kobayashi.miyazaki.jp\0scholarships\0" -"123website.lu\0" -"ibigawa.gifu.jp\0*.lclstage.dev\0barsy.online\0oy.lc\0" -"taipei\0" -"official.academy\0" -"maizuru.kyoto.jp\0kumagaya.saitama.jp\0" -"pecori.jp\0" -"mlbfan.org\0" -"napoli.it\0blog.kg\0" -"na.it\0" -"v\xc3\xa5ler.hedmark.no\0mircloud.host\0" -"lib.wa.us\0woodside\0" -"higashiyoshino.nara.jp\0" -"ono.fukui.jp\0" -"cc.pa.us\0" -"sobetsu.hokkaido.jp\0" -"kawakita.ishikawa.jp\0" -"64-b.it\0plesk.page\0" -"navuotna.no\0" -"silk\0*.ocs.customer-oci.com\0" -"gleeze.com\0" -"rollag.no\0loan\0" -"rj.leg.br\0" -"futtsu.chiba.jp\0" -"torahime.shiga.jp\0" -"cc.nm.us\0lamdong.vn\0is-a-player.com\0" -"vefsn.no\0" -"redirectme.net\0" -"\xe5\xa4\xa7\xe6\x8b\xbf\0*.hosting.ovh.net\0" -"yamazoe.nara.jp\0is-a-rockstar.com\0" -"samnanger.no\0at.eu.org\0" -"sina\0" -"df.leg.br\0" -"rj.gov.br\0kazimierz-dolny.pl\0" -"tateshina.nagano.jp\0" -"te.ua\0sakuraweb.com\0" -"shirosato.ibaraki.jp\0folionetwork.site\0" -"p.se\0" -"kherson.ua\0" -"fi.cr\0" -"kuji.iwate.jp\0makinohara.shizuoka.jp\0yamanashi.yamanashi.jp\0" -"toyoura.hokkaido.jp\0" -"nsw.au\0" -"miharu.fukushima.jp\0nishinoomote.kagoshima.jp\0matsumoto.nagano.jp\0koza.wakayama.jp\0gsj.bz\0" -"cc.mi.us\0jetzt\0tempurl.host\0" -"amex\0" -"her\xc3\xb8y.nordland.no\0" -"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xdb\x8c\xdb\x83\0" -"df.gov.br\0" -"cng.br\0evenassi.no\0" -"tono.iwate.jp\0k12.wi.us\0" -"sondrio.it\0k\xc3\xa5""fjord.no\0" -"kanoya.kagoshima.jp\0" -"kamogawa.chiba.jp\0raindrop.jp\0" -"joboji.iwate.jp\0valle.no\0" -"fukuchi.fukuoka.jp\0edgecompute.app\0" -"bitbridge.net\0" -"chillout.jp\0" -"kinder\0qc.com\0s3.pl-waw.scw.cloud\0" -"rs.webaccel.jp\0" -"banamex\0" -"cloud66.ws\0" -"cityeats\0" -"cq.cn\0" -"kwpsp.gov.pl\0nokia\0shop.th\0" -"gose.nara.jp\0" -"steigen.no\0" -"izumozaki.niigata.jp\0leirfjord.no\0" -"chikuma.nagano.jp\0" -"kaszuby.pl\0" -"langson.vn\0" -"yn.cn\0" -"unzen.nagasaki.jp\0impertrixcdn.com\0" -"physio\0doomdns.com\0" -"tamaki.mie.jp\0gda.pl\0" -"123website.be\0" -"her.jp\0" -"fakefur.jp\0*.nodebalancer.linode.com\0skr.jp\0" -"dnsdojo.net\0" -"oseto.nagasaki.jp\0fashionstore.jp\0" -"shimonita.gunma.jp\0mypi.co\0" -"morioka.iwate.jp\0" -"toga.toyama.jp\0" -"kagamiishi.fukushima.jp\0" -"kai.yamanashi.jp\0zgora.pl\0" -"tendo.yamagata.jp\0\xe0\xb6\xbd\xe0\xb6\x82\xe0\xb6\x9a\xe0\xb7\x8f\0" -"trentino-sud-tirol.it\0koriyama.fukushima.jp\0glass\0" -"\xe0\xb8\xa8\xe0\xb8\xb6\xe0\xb8\x81\xe0\xb8\xa9\xe0\xb8\xb2.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0shop.ro\0" -"engineering\0" -"xj.cn\0""123website.ch\0" -"site\0" -"kamoenai.hokkaido.jp\0" -"solar\0" -"shishikui.tokushima.jp\0stathelle.no\0" -"\xe0\xaa\xad\xe0\xaa\xbe\xe0\xaa\xb0\xe0\xaa\xa4\0" -"fi.it\0" -"nishiarita.saga.jp\0wphostedmail.com\0" -"webview-assets.aws-cloud9.us-west-2.amazonaws.com\0" -"cc.hi.us\0" -"cheap.jp\0" -"naples.it\0ninohe.iwate.jp\0v\xc3\xa5gan.no\0" -"clickrising.net\0" -"museum\0" -"tochio.niigata.jp\0" -"laakesvuemie.no\0" -"s\xc3\xb8r-fron.no\0" -"shop.pl\0" -"is-a-lawyer.com\0" -"kamiamakusa.kumamoto.jp\0eid.no\0ing.pa\0uh-oh.jp\0" -"webview-assets.cloud9.ap-southeast-2.amazonaws.com\0" -"hasvik.no\0" -"furubira.hokkaido.jp\0karasjok.no\0" -"presse.ci\0" -"hichiso.gifu.jp\0horokanai.hokkaido.jp\0" -"air-traffic-control.aero\0" -"ftpaccess.cc\0isa-geek.com\0grozny.su\0" -"hida.gifu.jp\0" -"avocat.fr\0kindle\0is-found.org\0" -"raholt.no\0bingo\0" -"uy.com\0" -"s3.dualstack.us-east-1.amazonaws.com\0" -"bjugn.no\0" -"meraker.no\0" -"lib.ma.us\0is-a-chef.org\0" -"git-pages.rit.edu\0" -"aaa\0" -"123siteweb.fr\0" -"narusawa.yamanashi.jp\0malbork.pl\0" -"showtime\0myspreadshop.net\0" -"linkyard.cloud\0" -"sayama.osaka.jp\0tmall\0" -"tatebayashi.gunma.jp\0yazu.tottori.jp\0" -"bahccavuotna.no\0" -"marche.it\0kr\xc3\xa5""anghke.no\0" -"shinjo.nara.jp\0webview-assets.aws-cloud9.eu-south-1.amazonaws.com\0" -"gs.aa.no\0appengine.flow.ch\0" -"y.bg\0abb\0easypanel.host\0" -"abc\0" -"wkz.gov.pl\0" -"vfs.cloud9.eu-west-2.amazonaws.com\0" -"yamaguchi.jp\0grozny.ru\0" -"accesscam.org\0" -"platter-app.dev\0" -"nagato.yamaguchi.jp\0" -"from-il.com\0" -"from-de.com\0" -"ryokami.saitama.jp\0" -"pharmacien.fr\0" -"ai.in\0k12.ne.us\0ann-arbor.mi.us\0from-nh.com\0copro.uk\0" -"from-ma.com\0" -"discordsays.com\0" -"e.bg\0" -"se.net\0ru.net\0" -"leikanger.no\0donetsk.ua\0aco\0" -"swiebodzin.pl\0" -"troms\xc3\xb8.no\0hicam.net\0" -"sa.gov.au\0" -"komagane.nagano.jp\0yuza.yamagata.jp\0broadway\0*.user.fm\0" -"vv.it\0k12.mi.us\0boldlygoingnowhere.org\0" -"yaotsu.gifu.jp\0\xc3\xb8rsta.no\0" -"srht.site\0" -"ads\0" -"dattoweb.com\0" -"bluebite.io\0" -"aeg\0" -"is-a-democrat.com\0ngrok.dev\0" -"assur.bj\0" -"funagata.yamagata.jp\0stat.no\0dynu.net\0" -"yamagata.nagano.jp\0tozawa.yamagata.jp\0church\0" -"rr.leg.br\0" -"dynamic-dns.info\0faststacks.net\0" -"servegame.org\0" -"creditunion\0" -"is-a-chef.com\0" -"omniwe.site\0" -"ino.kochi.jp\0ia.us\0" -"shingu.wakayama.jp\0" -"vb.it\0narviika.no\0" -"workers.dev\0" -"*.gateway.dev\0" -"jorpeland.no\0afl\0" -"digick.jp\0" -"rr.gov.br\0" -"audible\0" -"on.ca\0" -"independent-inquest.uk\0" -"yakumo.hokkaido.jp\0" -"uonuma.niigata.jp\0" -"kawahara.tottori.jp\0" -"tamano.okayama.jp\0""123kotisivu.fi\0" -"sar.it\0oow.gov.pl\0weber\0" -"\xe5\x8f\xb0\xe7\x81\xa3\0" -"rs.leg.br\0sc.leg.br\0" -"gloomy.jp\0" -"digital\0platterp.us\0" -"tn.it\0" -"grimstad.no\0" -"kitagata.gifu.jp\0apple\0bambina.jp\0" -"au.eu.org\0be.eu.org\0" -"alipay\0" -"mutsuzawa.chiba.jp\0" -"rs.gov.br\0sc.gov.br\0mediatech.by\0" -"oizumi.gunma.jp\0" -"edugit.io\0" -"gon.pk\0" -"cahcesuolo.no\0aig\0" -"*.cloudera.site\0" -"tottori.jp\0forsand.no\0lima-city.de\0" -"mosjoen.no\0" -"architectes.bj\0" -"base.ec\0" -"asaminami.hiroshima.jp\0love\0devices.resinstaging.io\0" -"emergency.aero\0psi.br\0horse\0" -"malatvuopmi.no\0" -"is-very-good.org\0" -"noboribetsu.hokkaido.jp\0" -"akamaiorigin-staging.net\0" -"sowa.ibaraki.jp\0" -"obama.nagasaki.jp\0lima-city.at\0" -"curv.dev\0" -"tamatsukuri.ibaraki.jp\0" -"rakkestad.no\0" -"vic.gov.au\0" -"ogawa.ibaraki.jp\0susono.shizuoka.jp\0" -"kainan.tokushima.jp\0s3.eu-west-2.amazonaws.com\0" -"taki.mie.jp\0wiih.gov.pl\0data\0" -"date\0" -"barsy.site\0" -"gs.of.no\0" -"pr.it\0bg.eu.org\0" -"lima-city.ch\0" -"koto.shiga.jp\0" -"saga.saga.jp\0" -"yoichi.hokkaido.jp\0halden.no\0" -"sarufutsu.hokkaido.jp\0" -"nic.in\0" -"lib.ca.us\0" -"webview-assets.aws-cloud9.af-south-1.amazonaws.com\0" -"wakayama.jp\0nanmoku.gunma.jp\0" -"rn.leg.br\0" -"mar.it\0stordal.no\0" -"games.hu\0" -"yoshino.nara.jp\0" -"gs.mr.no\0" -"chikugo.fukuoka.jp\0" -"matsushige.tokushima.jp\0tcp4.me\0" -"haebaru.okinawa.jp\0theshop.jp\0" -"ipifony.net\0" -"dyndns.dappnode.io\0" -"rn.gov.br\0" -"gen.in\0url.tw\0" -"filegear.me\0" -"deca.jp\0" -"soc.dz\0" -"murata.miyagi.jp\0" -"gv.ao\0" -"kawachinagano.osaka.jp\0sakura.ne.jp\0" -"kutchan.hokkaido.jp\0anz\0" -"gv.at\0" -"aol\0kasserver.com\0poivron.org\0" -"maibara.shiga.jp\0" -"\xe7\xbd\x91\xe5\xba\x97\0ro.leg.br\0pgafan.net\0" -"hiji.oita.jp\0" -"tamayu.shimane.jp\0nord-aurdal.no\0egoism.jp\0" -"chungnam.kr\0" -"ai.vn\0careers\0kyoto\0webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com\0" -"kilo.jp\0" -"smile\0zero\0" -"123hjemmeside.no\0" -"sakurai.nara.jp\0" -"taku.saga.jp\0uwu.ai\0" -"\xd8\xa7\xd9\x85\xd8\xa7\xd8\xb1\xd8\xa7\xd8\xaa\0" -"localzone.xyz\0" -"webview-assets.cloud9.ap-south-1.amazonaws.com\0" -"ro.gov.br\0app\0dattorelay.com\0de.trendhosting.cloud\0" -"williamhill\0" -"dyn.ddnss.de\0" -"miyoshi.aichi.jp\0higashikagawa.kagawa.jp\0jeju.kr\0email\0" -"barsy.shop\0" -"higashi.okinawa.jp\0" -"ngo.lk\0" -"webview-assets.aws-cloud9.eu-north-1.amazonaws.com\0router.management\0" -"mail.pl\0cc.nv.us\0" -"monza.it\0bar\0" -"bbc\0s3.dualstack.ap-south-1.amazonaws.com\0" -"orangecloud.tn\0" -"s3-us-west-2.amazonaws.com\0" -"pagefrontapp.com\0" -"nakano.nagano.jp\0*.azurecontainer.io\0it.com\0" -"skin\0" -"higashiyamato.tokyo.jp\0hr.eu.org\0" -"shijonawate.osaka.jp\0" -"sjc.br\0kr.it\0y.se\0map.fastly.net\0" -"shinagawa.tokyo.jp\0askim.no\0" -"lib.tn.us\0" -"art\0bbt\0" -"ngo.ng\0" -"notodden.no\0bcg\0members.linode.com\0" -"potenza.it\0" -"gen.ng\0" -"bcn\0\xe3\x82\xaf\xe3\x83\xa9\xe3\x82\xa6\xe3\x83\x89\0" -"trentin-sudtirol.it\0tn.us\0" -"izumiotsu.osaka.jp\0sanofi\0" -"*.in.futurecms.at\0" -"val-d-aosta.it\0hemne.no\0" -"higashiosaka.osaka.jp\0drud.io\0" -"kasamatsu.gifu.jp\0" -"e.se\0" -"kakinoki.shimane.jp\0" -"vagan.no\0s3.cn-north-1.amazonaws.com.cn\0*.customer-oci.com\0" -"gen.nz\0" -"rgr.jp\0" -"osakikamijima.hiroshima.jp\0*.firenet.ch\0" -"kameoka.kyoto.jp\0" -"ngo.ph\0" -"jambyl.su\0" -"r\xc3\xa6lingen.no\0" -"*.on-acorn.io\0cechire.com\0ghost.io\0" -"navoi.su\0lon.wafaicloud.com\0" +"gov.cx\0nyuzen.toyama.jp\0" +"gov.cy\0reserve-online.com\0" +"av.it\0akune.kagoshima.jp\0" +"info.zm\0" +"gov.dm\0" +"shingu.wakayama.jp\0wien.funkfeuer.at\0" +"gov.do\0hemsedal.no\0" +"shibetsu.hokkaido.jp\0" +"gov.ec\0" +"miasta.pl\0" +"gov.ee\0s\xc3\xb8r-aurdal.no\0cc.wa.us\0" +"wolomin.pl\0" +"gov.eg\0ringerike.no\0auth.ca-central-1.amazoncognito.com\0" +"ao.it\0" +"repbody.aero\0*.dev-builder.code.com\0" +"gov.dz\0nasu.tochigi.jp\0" +"friuli-vgiulia.it\0" +"bryne.no\0" "isa-geek.net\0" -"stcgroup\0ap-southeast-2.elasticbeanstalk.com\0" -"porsanger.no\0bet\0" -"catholic.edu.au\0forum.hu\0soc.lk\0" -"dnsupdate.info\0" -"dgca.aero\0" -"bookonline.app\0" -"\xe3\x82\xb0\xe3\x83\xbc\xe3\x82\xb0\xe3\x83\xab\0" -"\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91\0" -"xbox\0" -"miyoshi.hiroshima.jp\0" -"otsuchi.iwate.jp\0" -"aga.niigata.jp\0shiraoka.saitama.jp\0dyndns-wiki.com\0kicks-ass.net\0""2038.io\0" -"nic.tj\0" -"axa\0hyatt\0daynight.jp\0" -"vestvagoy.no\0aws\0" -"ipiranga\0" -"sor-fron.no\0" -"akabira.hokkaido.jp\0hitachi\0barsy.info\0" -"pr.us\0" -"utazu.kagawa.jp\0" -"hyuga.miyazaki.jp\0" -"nhs.uk\0" -"leadpages.co\0" -"fr.it\0bid\0try-snowplow.com\0" -"freebox-os.com\0" -"hoylandet.no\0tank.jp\0" -"musashino.tokyo.jp\0shouji\0" -"bio\0poznan.pl\0" -"\xd0\xbf\xd1\x80.\xd1\x81\xd1\x80\xd0\xb1\0" -"homeftp.org\0" -"gen.tr\0""123hjemmeside.dk\0" -"dnsupdater.de\0" -"biz\0padova.it\0nakagawa.tokushima.jp\0" -"in-vpn.de\0" -"en.it\0\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4\xe0\xb1\x8d\0" -"management\0is-an-entertainer.com\0" -"neko.am\0" -"kamikawa.hyogo.jp\0" -"ravpage.co.il\0" -"game.tw\0" -"run.app\0" -"hamaroy.no\0nj.us\0" -"se.leg.br\0" -"hapmir.no\0blogsyte.com\0" -"lenvik.no\0firmdale\0user.webaccel.jp\0" -"lv.ua\0" -"sth.ac.at\0inabe.mie.jp\0" -"cz.it\0" -"pictures\0is-a-chef.net\0" -"tuyenquang.vn\0" -"amsterdam\0" -"sor-aurdal.no\0" -"ba.leg.br\0" -"se.gov.br\0tabuse.yamaguchi.jp\0" -"minato.osaka.jp\0accenture\0" -"dyndns.info\0" -"maif\0" -"nic.za\0" -"tw.cn\0nantan.kyoto.jp\0" -"mydrobo.com\0iliadboxos.it\0eating-organic.net\0" -"slask.pl\0" -"indigena.bo\0" -"conn.uk\0" -"kr.ua\0topaz.ne.jp\0" -"andriabarlettatrani.it\0" -"ba.gov.br\0gifu.gifu.jp\0" -"bms\0" -"tc.br\0" -"ancona.it\0kawanishi.hyogo.jp\0" -"bmw\0" -"himi.toyama.jp\0" -"ngo.za\0rag-cloud.hosteur.com\0" -"co.com\0" -"riik.ee\0otama.fukushima.jp\0" -"fukuyama.hiroshima.jp\0k12.oh.us\0democrat\0" -"serveminecraft.net\0x0.com\0" -"kragero.no\0" -"bo.telemark.no\0" -"exchange.aero\0n.bg\0" -"ar.it\0" -"ryd.wafaicloud.com\0" -"adult.ht\0" -"\xe6\x96\xb0\xe9\x97\xbb\0" -"yonezawa.yamagata.jp\0bom\0" -"boo\0versus.jp\0" -"lipsy\0" -"tattoo\0" -"bajddar.no\0" -"plc.co.im\0bot\0" -"isahaya.nagasaki.jp\0" -"box\0" -"search\0" -"drud.us\0" -"westus2.azurestaticapps.net\0" -"firewall-gateway.net\0" -"apartments\0" -"athleta\0cab\0" -"repbody.aero\0" -"bukhara.su\0" -"oji.nara.jp\0georgia.su\0" -"s3-website.pl-waw.scw.cloud\0" -"massa-carrara.it\0ass.km\0cal\0" -"cam\0" -"sorum.no\0" -"cba\0" -"car\0" -"mediatech.dev\0" -"cat\0krodsherad.no\0" -"from-ga.com\0" -"toyoake.aichi.jp\0from-ut.com\0" -"sa.gov.pl\0" -"frosinone.it\0" -"cbn\0google\0" -"sicilia.it\0carbonia-iglesias.it\0" -"global.prod.fastly.net\0" -"bolzano.it\0panel.gg\0" -"cbs\0" -"rikuzentakata.iwate.jp\0\xe5\x85\xac\xe7\x9b\x8a\0" -"diskstation.org\0" -"gv.vc\0" -"andasuolo.no\0" -"handa.aichi.jp\0nakijin.okinawa.jp\0is-very-evil.org\0" -"2.bg\0" -"kaneyama.yamagata.jp\0" -"tarama.okinawa.jp\0" -"schmidt\0" -"latrobe\0" -"ns.ca\0" -"kihoku.ehime.jp\0" -"sue.fukuoka.jp\0raisa.no\0" -"is-into-games.com\0" -"dclk\0" -"isehara.kanagawa.jp\0am.leg.br\0" -"kiho.mie.jp\0binhphuoc.vn\0" -"\xe5\x85\xab\xe5\x8d\xa6\0" -"pro.typeform.com\0" -"flight.aero\0s\xc3\xb8ndre-land.no\0hu.com\0" -"ss.it\0graphics\0" -"noheji.aomori.jp\0ravendb.run\0" +"gov.et\0kumagaya.saitama.jp\0" +"vfs.cloud9.eu-north-1.amazonaws.com\0b-data.io\0" +"gov.fj\0" +"ecn.br\0" +"coffee\0" +"bib.br\0\xe6\x84\x9b\xe7\x9f\xa5.jp\0" +"s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com\0s3-accesspoint.dualstack.us-east-2.amazonaws.com\0" +"deno.dev\0" +"ong.br\0" +"gov.gd\0kihoku.ehime.jp\0" +"gov.ge\0app.lmpm.com\0townnews-staging.com\0" +"grp.lk\0" +"gov.gh\0" +"gov.gi\0" +"yasu.shiga.jp\0" +"*.builder.code.com\0" +"fl.us\0" +"gov.gn\0miho.ibaraki.jp\0" +"gov.gr\0wix.run\0" +"gov.gu\0dst.mi.us\0" +"yoshino.nara.jp\0" +"app.banzaicloud.io\0" +"seven\0" +"gov.gy\0" +"isen.kagoshima.jp\0" +"gov.hk\0r\xc3\xb8ros.no\0" +"5g.in\0oyama.tochigi.jp\0" +"chillout.jp\0" +"ehime.jp\0tourism.pl\0" +"leka.no\0" +"serveminecraft.net\0" +"gov.ie\0" +"midori.gunma.jp\0blog.gt\0" +"k12.wa.us\0emrstudio-prod.us-west-1.amazonaws.com\0" +"kuwana.mie.jp\0*.gateway.dev\0" +"s3-accesspoint.eu-north-1.amazonaws.com\0s3.eu-west-2.amazonaws.com\0" +"build\0walmart\0" +"cc.tn.us\0mk.eu.org\0" +"gov.il\0" +"12hp.de\0" +"gov.in\0" +"xihuan\0" +"gov.iq\0surnadal.no\0is-very-sweet.org\0" +"gov.ir\0" +"gov.is\0dp.ua\0store.ve\0isteingeek.de\0" +"gov.it\0anz\0" +"journal.aero\0k12.vt.us\0feedback\0" +"aol\0" +"s3-eu-west-2.amazonaws.com\0" +"minamiashigara.kanagawa.jp\0orangecloud.tn\0" +"storj.farm\0" +"kyonan.chiba.jp\0" +"kerrylogistics\0" +"yoshioka.gunma.jp\0fujiyoshida.yamanashi.jp\0" +"\xd9\x85\xd8\xb5\xd8\xb1\0" +"gov.jo\0" +"tourism.bj\0" +"ah.no\0" +"kamaishi.iwate.jp\0reisen\0support\0" +"citic\0staging.onred.one\0" +"pilot.aero\0gov.kg\0" "elblag.pl\0" -"ureshino.mie.jp\0" -"forde.no\0is-not-certified.com\0" -"ceo\0" -"am.gov.br\0cfa\0" -"cfd\0" -"secure\0" -"murayama.yamagata.jp\0ro.im\0" -"buy\0" -"fr\xc3\xa6na.no\0ooguy.com\0" -"ugim.gov.pl\0" -"il.eu.org\0" -"mo.cn\0adobeaemcloud.com\0but.jp\0" -"ro.it\0k12.il.us\0nikita.jp\0nyaa.am\0" -"chuo.osaka.jp\0" -"hinode.tokyo.jp\0" -"abbvie\0" -"rio.br\0sec.ps\0" -"exnet.su\0" -"sand\xc3\xb8y.no\0s3-website.eu-west-3.amazonaws.com\0" -"tsumagoi.gunma.jp\0eu-west-3.elasticbeanstalk.com\0ynh.fr\0" -"gucci\0" -"skydiving.aero\0" -"fhv.se\0" -"anjo.aichi.jp\0" -"inagawa.hyogo.jp\0" -"yuki.ibaraki.jp\0tatsuno.nagano.jp\0" -"lukow.pl\0" -"hu.eu.org\0ie.eu.org\0" -"mediocampidano.it\0" -"otobe.hokkaido.jp\0" -"ap-south-1.elasticbeanstalk.com\0" -"taranto.it\0" -"production.aero\0" -"nagano.nagano.jp\0" -"sandnessj\xc3\xb8""en.no\0siteleaf.net\0" -"*.magentosite.cloud\0i234.me\0" -"pg.in\0" -"hiranai.aomori.jp\0" -"skodje.no\0" -"faith\0" -"sanda.hyogo.jp\0" -"pg.it\0mino.gifu.jp\0" -"edgeapp.net\0west1-us.cloudjiffy.net\0" -"bzh\0" -"shizuoka.shizuoka.jp\0moka.tochigi.jp\0" -"nishimera.miyazaki.jp\0" -"arakawa.tokyo.jp\0" -"b\xc3\xa1id\xc3\xa1r.no\0" -"andebu.no\0" -"ap.leg.br\0" -"fvg.it\0" -"on-aptible.com\0" -"\xe5\xba\x83\xe5\xb3\xb6.jp\0ivory.ne.jp\0" -"ukiha.fukuoka.jp\0ar.us\0" -"mito.ibaraki.jp\0s3-website-ap-southeast-2.amazonaws.com\0za.com\0" -"blogdns.com\0ownip.net\0" -"maceio.br\0" -"ap.gov.br\0" -"umaji.kochi.jp\0omi.niigata.jp\0chofu.tokyo.jp\0" -"streamlitapp.com\0" -"hungry.jp\0" -"aerodrome.aero\0*.stg-builder.code.com\0small-web.org\0" -"sokndal.no\0opoczno.pl\0doesntexist.com\0encoreapi.com\0" -"cloudflare-ipfs.com\0" -"gildesk\xc3\xa5l.no\0" -"froland.no\0" -"isumi.chiba.jp\0townnews-staging.com\0" -"chuo.fukuoka.jp\0" -"sauda.no\0" -"bihar.in\0" -"emr.it\0" -"mo.it\0" -"inzai.chiba.jp\0" -"caserta.it\0supabase.net\0" -"chikuzen.fukuoka.jp\0" -"ap.gov.pl\0" -"holiday\0" -"midtre-gauldal.no\0" -"savona.it\0" -"munakata.fukuoka.jp\0" -"ozora.hokkaido.jp\0" -"dynalias.net\0" -"toei.aichi.jp\0" -"iitate.fukushima.jp\0" -"nanporo.hokkaido.jp\0br\xc3\xb8nn\xc3\xb8ysund.no\0" -"*.s5y.io\0" -"taxi.br\0\xc3\xa5""fjord.no\0" -"namegawa.saitama.jp\0" -"jevnaker.no\0" -"guovdageaidnu.no\0" -"\xe0\xa4\xb8\xe0\xa4\x82\xe0\xa4\x97\xe0\xa4\xa0\xe0\xa4\xa8\0myphotos.cc\0" -"kyotango.kyoto.jp\0" -"hirakata.osaka.jp\0\xe5\x85\xac\xe5\x8f\xb8\0" -"karatsu.saga.jp\0" -"barueri.br\0giving\0" -"ine.kyoto.jp\0" -"webview-assets.aws-cloud9.eu-west-2.amazonaws.com\0" -"com\0" -"functions.fnc.fr-par.scw.cloud\0" -"dni.us\0cpa\0*.dev.adobeaemcloud.com\0synology.me\0" -"jobs\0b\xc3\xa1hcavuotna.no\0mykolaiv.ua\0" -"lund.no\0" -"rennebu.no\0n.se\0" -"takinoue.hokkaido.jp\0makurazaki.kagoshima.jp\0xnbay.com\0" -"plurinacional.bo\0yamato.kanagawa.jp\0" -"rade.no\0" -"co.ae\0" -"co.ag\0" -"s3.isk01.sakurastorage.jp\0" -"gosen.niigata.jp\0" -"co.am\0dad\0" -"co.ao\0kawagoe.mie.jp\0ngrok.io\0" -"id.repl.co\0basicserver.io\0" -"co.bb\0kiwa.mie.jp\0valer.ostfold.no\0abogado\0" +"gov.ki\0" +"kamitsue.oita.jp\0app\0" +"fresenius\0" +"12hp.at\0" +"gov.km\0vfs.cloud9.us-west-1.amazonaws.com\0" +"gov.kn\0" +"aa.no\0cr.ua\0dyndns.dappnode.io\0" +"gov.kp\0ca.reclaim.cloud\0" +"blog.bo\0gov.la\0" +"gov.lb\0" +"gov.lc\0" +"blog.br\0" +"tjome.no\0codespot.com\0" +"hitachiota.ibaraki.jp\0" +"gov.kw\0" +"kamagaya.chiba.jp\0gov.kz\0" +"gov.lk\0" +"minami.fukuoka.jp\0miyada.nagano.jp\0bar\0" +"ck.ua\0bbc\0" +"army\0" +"12hp.ch\0" +"gov.ma\0attorney\0from-mn.com\0" +"torino.it\0kamisato.saitama.jp\0gov.lr\0" +"gov.ls\0politie\0" +"gov.lt\0" +"gov.me\0arna.no\0\xe4\xbf\xa1\xe6\x81\xaf\0fr.eu.org\0" +"gov.lv\0" +"gov.mg\0" +"gov.ly\0eu-west-1.elasticbeanstalk.com\0" +"gov.mk\0ruovat.no\0*.advisor.ws\0lu.eu.org\0me.eu.org\0" +"gov.ml\0deta.dev\0" +"rost.no\0" +"gov.mn\0art\0bbt\0base.shop\0" +"gov.mo\0""2038.io\0" +"beiarn.no\0bcg\0" +"nishiokoppe.hokkaido.jp\0kanuma.tochigi.jp\0gov.mr\0" +"gov.ms\0" +"futbol\0solar\0is-a-geek.net\0" +"gov.mu\0rsc.cdn77.org\0" +"gov.mv\0koeln\0" +"arpa\0gov.mw\0gov.ng\0" +"bcn\0cloudjiffy.net\0" +"gov.my\0skaun.no\0s3.dualstack.ap-northeast-3.amazonaws.com\0" +"gov.mz\0" +"audio\0" +"*.ex.ortsinfo.at\0gov.nl\0" +"store.ro\0" +"matsushige.tokushima.jp\0" +"gov.nr\0" +"monzaedellabrianza.it\0" +"notaires.km\0\xe9\xa4\x90\xe5\x8e\x85\0servequake.com\0" +"sekikawa.niigata.jp\0" +"avoues.fr\0av.tr\0" +"s3-accesspoint-fips.us-gov-east-1.amazonaws.com\0" +"hsbc\0icbc\0lv.eu.org\0" +"thuathienhue.vn\0" +"gov.om\0vm.bytemark.co.uk\0" +"togakushi.nagano.jp\0" +"brumunddal.no\0bjerkreim.no\0" +"myphotos.cc\0" +"store.st\0" +"m\xc4\x81ori.nz\0" +"hofu.yamaguchi.jp\0gov.ph\0" +"asn.au\0" +"gs.nl.no\0gov.pk\0" +"gov.pl\0" +"gov.pn\0bet\0" +"s3.dualstack.eu-south-2.amazonaws.com\0""4u.com\0" +"gov.qa\0pccw\0" +"gov.pr\0*.in.futurecms.at\0" +"oster\xc3\xb8y.no\0gov.ps\0nagoya\0" +"sakawa.kochi.jp\0gov.pt\0" "evenes.no\0" -"co.at\0" -"hk.com\0" -"is.it\0" -"ip6.arpa\0framercanvas.com\0" -"co.bi\0" -"co.bj\0" -"ehime.jp\0limited\0" -"katashina.gunma.jp\0kg.kr\0ralingen.no\0" -"shichikashuku.miyagi.jp\0" -"cc.ks.us\0co.bn\0" -"servequake.com\0" -"ae.org\0co.ca\0" -"witd.gov.pl\0day\0" -"cloudcontrolled.com\0" -"res.in\0oirm.gov.pl\0gr.eu.org\0sites.static.land\0" -"kvam.no\0" -"co.bw\0" -"co.ci\0vega.no\0" -"nankoku.kochi.jp\0" -"co.cl\0crs\0" -"co.cm\0" -"catanzaro.it\0" -"group\0" -"co.cr\0gyokuto.kumamoto.jp\0" -"koya.wakayama.jp\0" -"kicks-ass.org\0" -"kibichuo.okayama.jp\0co.cz\0" -"review\0co.dk\0" -"aizubange.fukushima.jp\0" -"tsurugi.ishikawa.jp\0yahaba.iwate.jp\0ohira.tochigi.jp\0" -"vfs.cloud9.us-west-2.amazonaws.com\0" -"shibetsu.hokkaido.jp\0googleapis.com\0" -"\xc3\xa5krehamn.no\0" -"suita.osaka.jp\0travinh.vn\0" -"ishigaki.okinawa.jp\0v-info.info\0" -"motegi.tochigi.jp\0brussels\0sakuratan.com\0" -"baby\0\xe5\x98\x89\xe9\x87\x8c\xe5\xa4\xa7\xe9\x85\x92\xe5\xba\x97\0" -"pmn.it\0pleskns.com\0" +"vall\xc3\xa9""edaoste.it\0turek.pl\0" +"gov.py\0try-snowplow.com\0" +"hosting\0pdns.page\0" +"ardal.no\0" +"pub.instances.scw.cloud\0" +"\xc3\xb8ygarden.no\0k12.sc.us\0" +"go.leg.br\0" +"us-east-2.elasticbeanstalk.com\0codeberg.page\0utwente.io\0" +"bulsan.it\0" +"asda\0eu-4.evennode.com\0" +"\xe5\xb2\xa1\xe5\xb1\xb1.jp\0" +"arte\0axa\0" +"aws\0studio-fips.us-gov-west-1.sagemaker.aws\0" +"gov.sa\0s3.dualstack.eu-west-1.amazonaws.com\0" +"friuliv-giulia.it\0oarai.ibaraki.jp\0gov.sb\0" +"trysil.no\0gov.rs\0gov.sc\0" +"gov.sd\0allfinanz\0" +"tjeldsund.no\0cc.pa.us\0gov.ru\0" +"gov.rw\0gov.sg\0" +"gov.sh\0" +"emrnotebooks-prod.ap-southeast-2.amazonaws.com\0s3.us-west-2.amazonaws.com\0" +"gov.sl\0" +"x.bg\0\xd0\xb1\xd0\xb8\xd0\xb7.\xd1\x80\xd1\x83\xd1\x81\0" +"bid\0upaas.kazteleport.kz\0" +"orkdal.no\0gov.so\0taobao\0" +"journalist.aero\0radoy.no\0\xd9\x87\xd9\x85\xd8\xb1\xd8\xa7\xd9\x87\0" +"gov.ss\0fastly-edge.com\0" +"maori.nz\0" +"2000.hu\0" +"bbva\0" +"shizuoka.shizuoka.jp\0is.gov.pl\0sosnowiec.pl\0gov.sx\0" +"gov.sy\0bio\0" +"gov.tj\0" +"q.bg\0s3-website-us-gov-west-1.amazonaws.com\0" +"gov.tl\0" +"gov.tm\0s3.dualstack.ap-east-1.amazonaws.com\0" +"gov.tn\0" +"gov.to\0" +"shikama.miyagi.jp\0" +"gov.ua\0" +"yanaizu.fukushima.jp\0gov.tr\0" +"biz\0marche.it\0gov.tt\0" +"auth.ap-northeast-2.amazoncognito.com\0vfs.cloud9.ap-northeast-2.amazonaws.com\0" +"gov.tw\0" +"bip.sh\0" +"j.bg\0" +"itako.ibaraki.jp\0" +"gov.uk\0" +"aibetsu.hokkaido.jp\0*.firenet.ch\0" +"ovre-eiker.no\0" +"nagasaki.jp\0" +"nyanta.jp\0" +"s3.amazonaws.com\0webview-assets.aws-cloud9.me-south-1.amazonaws.com\0" +"umig.gov.pl\0" +"gov.vc\0" +"chino.nagano.jp\0*.northflank.app\0" +"gov.ve\0execute-api.il-central-1.amazonaws.com\0s3-object-lambda.eu-north-1.amazonaws.com\0s3-website.eu-south-1.amazonaws.com\0" +"c.bg\0stathelle.no\0eu-3.evennode.com\0" +"holt\xc3\xa5len.no\0k12.pr.us\0sekd1.beebyteapp.io\0j.layershift.co.uk\0" +"akiruno.tokyo.jp\0s3.fr-par.scw.cloud\0" +"kharkov.ua\0cc.ne.us\0orsites.com\0" +"gov.vn\0mattel\0" +"khmelnytskyi.ua\0" +"toray\0temp-dns.com\0" +"asia\0sand\xc3\xb8y.no\0k12.pa.us\0" +"cc.mn.us\0kr.eu.org\0app.os.stg.fedoraproject.org\0" +"tsuru.yamanashi.jp\0" +"\xe4\xb8\xad\xe5\x9b\xbd\0" +"mazury.pl\0" +"emrnotebooks-prod.me-south-1.amazonaws.com\0" +"vallee-d-aoste.it\0hakodate.hokkaido.jp\0izumo.shimane.jp\0" +"gov.ws\0" +"saroma.hokkaido.jp\0" +"nord-fron.no\0\xe5\x85\xac\xe5\x8f\xb8.\xe9\xa6\x99\xe6\xb8\xaf\0" +"blog.vu\0" +"kashiwa.chiba.jp\0" +"capetown\0" +"\xe4\xb8\xad\xe5\x9c\x8b\0" +"bms\0" +"matsue.shimane.jp\0" +"bmw\0" +"gov.ye\0" +"osaka\0" +"simplesite.com.br\0" +"chambagri.fr\0" +"jgora.pl\0" +"bib.ve\0gov.za\0demo.datadetect.com\0fuettertdasnetz.de\0" +"ravenna.it\0" +"sa.edu.au\0*.otap.co\0nfshost.com\0" +"hiroshima.jp\0" +"cc.ky.us\0" +"bom\0eu-2.evennode.com\0" +"\xd9\xbe\xd8\xa7\xd9\x83\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0rich\0" +"boo\0latrobe\0freeboxos.com\0" +"square7.net\0" +"\xe0\xb9\x80\xe0\xb8\x99\xe0\xb9\x87\xe0\xb8\x95.\xe0\xb9\x84\xe0\xb8\x97\xe0\xb8\xa2\0" +"gov.zm\0" +"bot\0" +"sko.gov.pl\0box\0" +"budejju.no\0" +"gov.zw\0" +"kawakita.ishikawa.jp\0" +"kokonoe.oita.jp\0asn.lv\0" +"9.bg\0" +"kosei.shiga.jp\0cab\0" +"onred.one\0" +"hobby-site.org\0x0.com\0" +"from-la.net\0" +"nishiizu.shizuoka.jp\0" +"gaular.no\0" +"huissier-justice.fr\0minano.saitama.jp\0cal\0nyc.mn\0" +"tozsde.hu\0cam\0" +"yenbai.vn\0" +"2.bg\0gj\xc3\xb8vik.no\0" +"mond.jp\0" +"aremark.no\0cba\0taifun-dns.de\0" +"biratori.hokkaido.jp\0car\0" +"cat\0kawamata.fukushima.jp\0" +"grondar.za\0" +"kids\0" +"ashiya.hyogo.jp\0gobo.wakayama.jp\0" +"hole.no\0" +"webhop.org\0" +"hasama.oita.jp\0opal.ne.jp\0" +"execute-api.eu-south-2.amazonaws.com\0" +"ogliastra.it\0shiroishi.saga.jp\0cbn\0" +"k12.nj.us\0s3-accesspoint.ap-south-1.amazonaws.com\0" +"salon\0" +"\xe7\xbd\x91\xe7\xab\x99\0" +"sardegna.it\0" +"marker.no\0properties\0" +"store.bb\0kawai.iwate.jp\0tokushima.tokushima.jp\0" +"sogndal.no\0" +"t3l3p0rt.net\0" +"stufftoread.com\0" +"shintoku.hokkaido.jp\0" +"emrappui-prod.ca-central-1.amazonaws.com\0" +"k12.mi.us\0eu-1.evennode.com\0" +"carraramassa.it\0tohma.hokkaido.jp\0" +"camera\0" +"lolipop.io\0" +"gen.in\0" +"imb.br\0diet\0" +"j\xc3\xb8rpeland.no\0" +"cuneo.it\0hioki.kagoshima.jp\0*.sensiosite.cloud\0" +"\xd7\x9e\xd7\x9e\xd7\xa9\xd7\x9c.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0\xe8\x81\x94\xe9\x80\x9a\0" +"deporte.bo\0" +"myspreadshop.net\0" +"auth.ap-southeast-2.amazoncognito.com\0is-a-cpa.com\0" +"is-a-libertarian.com\0" +"porsgrunn.no\0" +"c.la\0" +"architectes.bj\0red.sv\0gov.nc.tr\0" +"k12.ks.us\0" +"bahccavuotna.no\0\xe0\xb0\xad\xe0\xb0\xbe\xe0\xb0\xb0\xe0\xb0\xa4\xe0\xb1\x8d\0" +"londrina.br\0ynh.fr\0" +"ceo\0store.dk\0blogspot.com\0js.wpenginepowered.com\0" +"cfa\0beta.bounty-full.com\0" +"takehara.hiroshima.jp\0shikaoi.hokkaido.jp\0" +"ryukyu\0" +"cfd\0" +"buy\0miami\0" +"cc.ia.us\0" +"gorlice.pl\0" +"s3-accesspoint.us-gov-west-1.amazonaws.com\0" +"*.owo.codes\0" +"chichibu.saitama.jp\0" +"urn.arpa\0""123miweb.es\0basicserver.io\0" +"buzen.fukuoka.jp\0wakkanai.hokkaido.jp\0" +"instance.datadetect.com\0" +"doesntexist.org\0" +"foz.br\0ogasawara.tokyo.jp\0" +"tynset.no\0" +"*.eu-west-1.airflow.amazonaws.com\0" +"teo.br\0kusatsu.shiga.jp\0" +"!city.sendai.jp\0" +"gen.ng\0" +"merckmsd\0" +"akrehamn.no\0lib.wi.us\0" +"hiraya.nagano.jp\0" +"namdinh.vn\0" +"vfs.cloud9.us-east-2.amazonaws.com\0" +"ono.hyogo.jp\0" +"os\xc3\xb8yro.no\0" +"copro.uk\0" +"blog.kg\0" +"yn.cn\0gen.nz\0" +"tolga.no\0x.se\0" +"\xe5\xa4\xa7\xe9\x98\xaa.jp\0" +"mobi\0" +"sarpsborg.no\0" +"nakatsugawa.gifu.jp\0bzh\0" +"\xe6\xb8\xb8\xe6\x88\x8f\0ras.ru\0" +"k12.ia.us\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.cn\0verm\xc3\xb6gensberater\0" +"lifestyle\0" +"*.kobe.jp\0" +"s3-deprecated.us-east-2.amazonaws.com\0from-mi.com\0" +"\xe5\xa4\xa7\xe6\x8b\xbf\0s3-website.ap-south-1.amazonaws.com\0" +"tsuiki.fukuoka.jp\0aridagawa.wakayama.jp\0""5.azurestaticapps.net\0" +"analytics-gateway.us-east-1.amazonaws.com\0" +"jeonnam.kr\0" +"imizu.toyama.jp\0" +"k12.id.us\0moda\0" +"bergamo.it\0yabuki.fukushima.jp\0" +"\xc3\xa5snes.no\0" +"oita.jp\0" +"karasjohka.no\0" +"quangbinh.vn\0" +"uppo.gov.pl\0" +"yahoo\0" +"c.se\0" +"toyokawa.aichi.jp\0komono.mie.jp\0" +"ballooning.aero\0ap-southeast-1.elasticbeanstalk.com\0is-very-evil.org\0" +"bar0.net\0" +"freedesktop.org\0" +"kamo.niigata.jp\0" +"\xe9\xa3\x9e\xe5\x88\xa9\xe6\xb5\xa6\0user.srcf.net\0" +"student.aero\0*.on-acorn.io\0" +"noticeable.news\0" +"iobb.net\0" +"cloudns.info\0" +"nissan\0" +"uk.oxa.cloud\0" +"penza.su\0" +"cyou\0" +"\xe5\x8d\x83\xe8\x91\x89.jp\0" +"nissay\0" +"sandoy.no\0ing.pa\0" +"pubtls.org\0" +"toyosato.shiga.jp\0" +"notebook.eu-central-1.sagemaker.aws\0" +"ustka.pl\0" +"poniatowa.pl\0" +"spdns.eu\0" +"*.kitakyushu.jp\0*.ex.futurecms.at\0" +"minamifurano.hokkaido.jp\0gen.tr\0" +"auth-fips.us-east-2.amazoncognito.com\0us-east-1.amazonaws.com\0" +"bounceme.net\0" +"\xe7\xb6\xb2\xe7\xb5\xa1.hk\0" +"coach\0" +"com\0bodo.no\0" +"yuasa.wakayama.jp\0" +"from-ga.com\0" +"notaires.fr\0" +"cpa\0" +"onojo.fukuoka.jp\0" +"cc.ct.us\0" +"trentino-s\xc3\xbc""dtirol.it\0\xe7\xa6\x8f\xe5\xb3\xb6.jp\0financial\0" +"news.hu\0emrappui-prod.eu-north-1.amazonaws.com\0" +"campania.it\0zushi.kanagawa.jp\0" +"brindisi.it\0secret.jp\0" +"ascolipiceno.it\0lon-1.paas.massivegrid.net\0" +"sellsyourhome.org\0" +"katori.chiba.jp\0" +"\xe9\xb9\xbf\xe5\x85\x90\xe5\xb3\xb6.jp\0dad\0" +"\xe6\xbe\xb3\xe9\x96\x80\0" +"dish\0" +"bungoono.oita.jp\0" +"\xd0\xba\xd0\xb0\xd1\x82\xd0\xbe\xd0\xbb\xd0\xb8\xd0\xba\0" +"waw.pl\0" +"xen.prgmr.com\0" +"mutsu.aomori.jp\0imabari.ehime.jp\0shirakawa.gifu.jp\0" +"day\0" +"coz.br\0co.education\0" +"k12.fl.us\0" +"my-router.de\0" +"buyshop.jp\0noop.app\0" +"avianca\0weibo\0" +"tatebayashi.gunma.jp\0" +"crs\0" +"andriatranibarletta.it\0toyohashi.aichi.jp\0" +"betainabox.com\0" +"medio-campidano.it\0vibovalentia.it\0" +"natal.br\0himeji.hyogo.jp\0" +"kibichuo.okayama.jp\0" +"commune.am\0r\xc3\xb8mskog.no\0game.tw\0discourse.team\0" +"hizen.saga.jp\0" +"lib.pr.us\0s3-accesspoint.dualstack.eu-south-1.amazonaws.com\0s3.us-gov-east-1.amazonaws.com\0" +"lodi.it\0gotsu.shimane.jp\0" +"pvt.ge\0eu.pythonanywhere.com\0" +"tj.cn\0higashikawa.hokkaido.jp\0tagami.niigata.jp\0komatsushima.tokushima.jp\0klodzko.pl\0" +"tc.br\0ouchi.saga.jp\0" +"webview-assets.aws-cloud9.af-south-1.amazonaws.com\0es.eu.org\0" +"nesseby.no\0gifts\0kiwi\0" +"schaeffler\0" +"dds\0myshopblocks.com\0" +"hanggliding.aero\0spdns.de\0" +"kakogawa.hyogo.jp\0" +"friulivgiulia.it\0vt.it\0" +"laz.it\0massacarrara.it\0" +"hvaler.no\0" +"iyo.ehime.jp\0nowtv\0" +"dev\0" +"fukusaki.hyogo.jp\0sanjo.niigata.jp\0" +"koriyama.fukushima.jp\0s3-accesspoint.dualstack.cn-northwest-1.amazonaws.com.cn\0" +"\xd8\xaa\xd9\x88\xd9\x86\xd8\xb3\0" +"taku.saga.jp\0ina.saitama.jp\0" +"cng.br\0airtel\0" +"tydal.no\0de.com\0" +"mcdir.me\0" +"toyone.aichi.jp\0" +"nagaokakyo.kyoto.jp\0narusawa.yamanashi.jp\0lamer\0" +"ivano-frankivsk.ua\0\xd0\xbe\xd0\xbd\xd0\xbb\xd0\xb0\xd0\xb9\xd0\xbd\0" +"bjark\xc3\xb8y.no\0" +"rankoshi.hokkaido.jp\0food\0" +"sortland.no\0" +"\xe6\xbe\xb3\xe9\x97\xa8\0" +"roan.no\0" +"tonami.toyama.jp\0" +"ieee\0cloudns.pro\0" +"audi\0" +"kumamoto.kumamoto.jp\0*.cloud.metacentrum.cz\0" +"asahi.chiba.jp\0" +"steigen.no\0" +"val-d-aosta.it\0nghean.vn\0dhl\0" +"slz.br\0now.sh\0" +"transporte.bo\0lea\xc5\x8bgaviika.no\0" +"is-an-engineer.com\0" +"s3-accesspoint.dualstack.ap-south-1.amazonaws.com\0" +"miura.kanagawa.jp\0" +"\xe5\xbe\xb3\xe5\xb3\xb6.jp\0" +"bielawa.pl\0" +"daa.jp\0" +"ip.linodeusercontent.com\0" +"\xe9\x9b\xbb\xe8\xa8\x8a\xe7\x9b\x88\xe7\xa7\x91\0" +"\xe0\xae\x87\xe0\xae\xa8\xe0\xaf\x8d\xe0\xae\xa4\xe0\xae\xbf\xe0\xae\xaf\xe0\xae\xbe\0beer\0" +"grosseto.it\0" +"hangout\0lplfinancial\0" +"tunk.org\0" +"kumamoto.jp\0" +"lib.ne.us\0studio.eu-north-1.sagemaker.aws\0home-webserver.de\0" +"fukagawa.hokkaido.jp\0" +"diy\0" +"v\xc3\xa5gan.no\0" +"ford\0" +"alstom\0dynserv.org\0" +"weir\0" +"lib.nj.us\0*.r.appspot.com\0" +"shiojiri.nagano.jp\0imari.saga.jp\0user.webaccel.jp\0" +"morimachi.shizuoka.jp\0" +"omniwe.site\0" +"ss.it\0hs.run\0" +"skodje.no\0" +"total\0" +"vinhlong.vn\0fra1-de.cloudjiffy.net\0" +"vf.no\0north-kazakhstan.su\0" +"production.aero\0" +"datsun\0" +"\xe6\x89\x8b\xe6\x9c\xba\0" +"idf.il\0" +"moto\0emrappui-prod.sa-east-1.amazonaws.com\0" +"\xe5\xae\xae\xe5\x9f\x8e.jp\0forex\0" +"reservd.testing.thingdust.io\0" +"seto.aichi.jp\0travel\0" +"*.futurecms.at\0" +"tonkotsu.jp\0" +"digital\0" +"odda.no\0" +"trentinoaltoadige.it\0yugawara.kanagawa.jp\0" +"mysecuritycamera.com\0" +"senasa.ar\0narita.chiba.jp\0" +"froya.no\0s3-website.ap-southeast-1.amazonaws.com\0" +"fitness\0" +"yonezawa.yamagata.jp\0" +"katagami.akita.jp\0" +"lib.la.us\0" +"tatar\0" +"fr-1.paas.massivegrid.net\0" +"execute-api.eu-north-1.amazonaws.com\0" +"hirono.iwate.jp\0" +"rn.it\0run.app\0" +"navoi.su\0" +"kamishihoro.hokkaido.jp\0town\0" +"of.by\0" +"ichiba.tokushima.jp\0" +"reklam.hu\0wy.us\0" +"dnp\0parallel.jp\0" +"forum.hu\0" +"ujiie.tochigi.jp\0" +"consulting.aero\0is-into-cars.com\0" +"rg.it\0\xe7\xbd\x91\xe5\x9d\x80\0platter-app.dev\0" +"otsuki.kochi.jp\0storage.yandexcloud.net\0" +"dog\0" +"arita.saga.jp\0" +"insurance\0" +"*.cn-north-1.airflow.amazonaws.com.cn\0" +"col.ng\0" +"thick.jp\0" +"gildeskal.no\0" +"is-a-lawyer.com\0webredirect.org\0" +"brother\0" +"s3.dualstack.eu-central-2.amazonaws.com\0" +"agrigento.it\0moroyama.saitama.jp\0" +"latino\0" +"pa.gov.br\0dot\0" +"webview-assets.cloud9.eu-south-1.amazonaws.com\0webview-assets.cloud9.us-east-1.amazonaws.com\0" +"ozu.kumamoto.jp\0asakuchi.okayama.jp\0" +"chase\0" +"daegu.kr\0*.rss.my.id\0" +"murata.miyagi.jp\0credit\0" +"fi.eu.org\0" +"easypanel.app\0" +"b\xc3\xa1hcavuotna.no\0beauty\0toys\0" +"shishikui.tokushima.jp\0" +"mcdir.ru\0" +"s3-accesspoint.dualstack.ap-northeast-2.amazonaws.com\0" +"ginoza.okinawa.jp\0urasoe.okinawa.jp\0" +"kmpsp.gov.pl\0" +"vt.us\0" +"s3-accesspoint.me-south-1.amazonaws.com\0" +"campobasso.it\0pr.it\0" +"vik.no\0cable-modem.org\0byen.site\0" +"matsuda.kanagawa.jp\0mc.ax\0" +"pictures\0" +"hirakata.osaka.jp\0restaurant\0" +"pb.gov.br\0kawaminami.miyazaki.jp\0eat\0" +"cruise\0" +"\xe5\x95\x86\xe5\x9f\x8e\0" +"nakagawa.tokushima.jp\0kamitonda.wakayama.jp\0cistron.nl\0" +"*.on-rancher.cloud\0" +"fhs.no\0*.oci.customer-oci.com\0" +"\xe7\xbb\x84\xe7\xb9\x94.hk\0lyngdal.no\0ua.rs\0" +"tomobe.ibaraki.jp\0" +"lacaixa\0" +"hayashima.okayama.jp\0de.cool\0" +"boehringer\0" +"smile\0togliatti.su\0" +"iveland.no\0" +"ot.it\0pd.it\0" +"filegear-au.me\0" +"cantho.vn\0" +"eco\0" +"sicilia.it\0" +"oyer.no\0" +"muni.il\0" +"nishihara.kumamoto.jp\0tsubame.niigata.jp\0" +"webview-assets.aws-cloud9.us-west-2.amazonaws.com\0" +"namegata.ibaraki.jp\0" +"gamo.shiga.jp\0" +"hermes\0" +"izena.okinawa.jp\0" +"modelling.aero\0tx.us\0cn.com\0" +"ushiku.ibaraki.jp\0shimizu.shizuoka.jp\0" +"edu\0" +"dtv\0myeffect.net\0" +"sandvik\0of.je\0" +"curitiba.br\0aichi.jp\0numata.hokkaido.jp\0eastasia.azurestaticapps.net\0" +"execute-api.eu-west-1.amazonaws.com\0s3-accesspoint.dualstack.us-west-1.amazonaws.com\0" +"floripa.br\0ninhbinh.vn\0" +"ringsaker.no\0s3.dualstack.me-central-1.amazonaws.com\0is-a-techie.com\0" +"bulsan-sudtirol.it\0szczecin.pl\0girly.jp\0" +"chanel\0" +"capitalone\0" +"lima-city.rocks\0" +"kiyose.tokyo.jp\0tiengiang.vn\0" +"*.uberspace.de\0" +"no.it\0" +"cesenaforli.it\0health.nz\0" +"logistics.aero\0s3-website.eu-north-1.amazonaws.com\0" +"hadano.kanagawa.jp\0webhop.net\0" +"aver\xc3\xb8y.no\0" +"lukow.pl\0" +"vision\0" +"rahkkeravju.no\0temasek\0" +"kurogi.fukuoka.jp\0chiyoda.gunma.jp\0embetsu.hokkaido.jp\0gyeongbuk.kr\0" +"hikone.shiga.jp\0oguni.yamagata.jp\0" +"gucci\0fldrv.com\0" +"mitsue.nara.jp\0dvr\0" +"oyamazaki.kyoto.jp\0" +"press.cy\0s3-website.dualstack.ap-northeast-3.amazonaws.com\0" +"s3-accesspoint.cn-north-1.amazonaws.com.cn\0" +"cloudns.org\0" +"kawanehon.shizuoka.jp\0" +"oppegard.no\0emrappui-prod.ap-southeast-1.amazonaws.com\0s3-accesspoint.dualstack.us-gov-west-1.amazonaws.com\0" +"na.it\0best\0" +"from-de.com\0" +"shoparena.pl\0edu.scot\0" +"jorpeland.no\0songdalen.no\0barrell-of-knowledge.info\0" +"milan.it\0nogata.fukuoka.jp\0" +"rimini.it\0" +"shoes\0" +"auto\0" +"broke-it.net\0" +"compare\0hlx.live\0" +"omachi.saga.jp\0" +"jp.eu.org\0" +"editorx.io\0" +"oki.fukuoka.jp\0" +"insure\0" +"id.au\0" +"mc.it\0" +"of.no\0" +"knx-server.net\0" +"minamitane.kagoshima.jp\0" +"ventures\0s3-object-lambda.ap-south-1.amazonaws.com\0" +"minamiyamashiro.kyoto.jp\0" +"sorum.no\0" +"aeroport.fr\0" +"g\xc3\xbcnstigliefern.de\0" +"mx.na\0from-ri.com\0" +"gv.ao\0" +"krym.ua\0cleverapps.io\0" +"gv.at\0trento.it\0" +"aircraft.aero\0" +"le.it\0shikatsu.aichi.jp\0hanamaki.iwate.jp\0" +"dyndns-work.com\0" +"auth-fips.us-west-1.amazoncognito.com\0" +"forum\0" +"bozen.it\0kaminoyama.yamagata.jp\0" +"ddnslive.com\0" +"lexus\0na4u.ru\0" +"nango.fukushima.jp\0" +"ambulance.aero\0" +"for-more.biz\0" +"physio\0" +"instances.spawn.cc\0" +"s3-fips.dualstack.us-gov-west-1.amazonaws.com\0phx.enscaled.us\0" +"babymilk.jp\0" +"point2this.com\0" +"go.ci\0" +"hamada.shimane.jp\0health.vn\0" +"lib.co.us\0readmyblog.org\0" +"aogaki.hyogo.jp\0" +"pr.us\0" +"berlin\0" +"qoto.io\0" +"trafficplex.cloud\0" +"co.business\0" +"go.cr\0" +"company\0events\0s3-accesspoint-fips.us-gov-west-1.amazonaws.com\0" +"\xd0\xba\xd0\xbe\xd0\xbc\0" +"s3-object-lambda.il-central-1.amazonaws.com\0" +"builders\0" +"lib.ct.us\0" +"s\xc3\xb8rfold.no\0" +"hokuto.hokkaido.jp\0onion\0" +"s3-accesspoint-fips.dualstack.us-gov-east-1.amazonaws.com\0" +"kg.kr\0" +"mikasa.hokkaido.jp\0" +"sci.eg\0jp.kg\0" +"quangtri.vn\0ciao.jp\0" +"sandefjord.no\0" +"milano.it\0es.leg.br\0" +"s3-website.eu-central-1.amazonaws.com\0s3-accesspoint.dualstack.eu-west-1.amazonaws.com\0" +"boutique\0" +"boutir.com\0" +"es.ax\0" +"niki.hokkaido.jp\0ando.nara.jp\0" +"bardu.no\0" +"pi.gov.br\0bologna.it\0yawata.kyoto.jp\0" +"fj.cn\0" +"moscow\0" +"space-to-rent.com\0" +"no-ip.org\0" +"\xe6\x94\xbf\xe5\xba\x9c\0serveftp.net\0" +"s3.eu-central-2.amazonaws.com\0servehttp.com\0" +"zuerich\0" +"n\xc3\xa6r\xc3\xb8y.no\0scholarships\0" +"iwanuma.miyagi.jp\0immobilien\0jp.md\0" +"dyndns.tv\0khplay.nl\0" +"ingatlan.hu\0nv.us\0" +"kanonji.kagawa.jp\0" +"s3-website.eu-west-1.amazonaws.com\0" +"id.ir\0auto.pl\0" +"neko.am\0" +"lyngen.no\0filegear-ie.me\0dynvpn.de\0" +"fed.us\0glug.org.uk\0" +"miyako.fukuoka.jp\0oketo.hokkaido.jp\0fan\0versus.jp\0" +"alessandria.it\0" +"sa.ngrok.io\0" +"yokkaichi.mie.jp\0" +"auth.eu-west-2.amazoncognito.com\0est-a-la-maison.com\0" +"natori.miyagi.jp\0" +"rennebu.no\0nh.us\0" +"siena.it\0" +"go.id\0" +"s3-us-gov-west-1.amazonaws.com\0" +"nishihara.okinawa.jp\0" +"hamaroy.no\0*.sa-east-1.airflow.amazonaws.com\0notebook.eu-west-1.sagemaker.aws\0" +"k8s.pl-waw.scw.cloud\0" +"trentinsudtirol.it\0execute-api.cn-northwest-1.amazonaws.com.cn\0" +"faststacks.net\0" +"\xd0\xb1\xd0\xb3\0" +"\xe9\x95\xb7\xe9\x87\x8e.jp\0kaga.ishikawa.jp\0kawagoe.mie.jp\0\xd9\xbe\xd8\xa7\xda\xa9\xd8\xb3\xd8\xaa\xd8\xa7\xd9\x86\0" +"esq\0dyndns.ws\0" +"dedyn.io\0" +"go.it\0" +"tselinograd.su\0" +"sel.no\0sells-for-u.com\0" +"agro.bj\0" +"fusa.no\0" +"sumoto.hyogo.jp\0id.lv\0parasite.jp\0" +"agro.bo\0" +"id.ly\0name\0aure.no\0family\0" +"go.jp\0" +"br\xc3\xb8nn\xc3\xb8ysund.no\0" +"shirahama.wakayama.jp\0" +"go.ke\0tuxfamily.org\0" +"koshu.yamanashi.jp\0" +"lib.al.us\0is-a-democrat.com\0" +"forsand.no\0game\0" +"trentino-stirol.it\0kanegasaki.iwate.jp\0" +"go.kr\0seoul.kr\0\xe9\x9b\x86\xe5\x9b\xa2\0" +"eus\0" +"edgesuite.net\0" +"cremona.it\0" +"musashimurayama.tokyo.jp\0" +"sakahogi.gifu.jp\0undo.jp\0" +"utazas.hu\0" +"dr\xc3\xb8""bak.no\0s\xc3\xb8mna.no\0" +"kusatsu.gunma.jp\0" +"madrid\0" +"hm.no\0g\xc3\xa1\xc5\x8bgaviika.no\0redumbrella\0is-a-patsfan.org\0" +"showa.yamanashi.jp\0rybnik.pl\0\xe0\xa6\xac\xe0\xa6\xbe\xe0\xa6\x82\xe0\xa6\xb2\xe0\xa6\xbe\0" +"*.nagoya.jp\0\xe5\x8f\xb0\xe6\xb9\xbe\0web.app\0" +"cal.it\0fukushima.jp\0" +"priv.hu\0" +"muika.niigata.jp\0" +"nesna.no\0" +"fc.it\0" +"marine.ru\0" +"gru.br\0lolipopmc.jp\0" +"nahari.kochi.jp\0niyodogawa.kochi.jp\0tamayu.shimane.jp\0" +"drangedal.no\0holmestrand.no\0" +"pe.gov.br\0" +"execute-api.us-east-2.amazonaws.com\0" +"tahara.aichi.jp\0kepno.pl\0" +"averoy.no\0s3.dualstack.eu-west-2.amazonaws.com\0" +"qa2.com\0" +"ino.kochi.jp\0" +"\xc4\x8d\xc3\xa1hcesuolo.no\0" +"from-sd.com\0" +"wakayama.wakayama.jp\0" +"*.devcdnaccesso.com\0" +"sveio.no\0herokussl.com\0" +"am.br\0" +"ddns5.com\0" +"iide.yamagata.jp\0\xd0\xb5\xd1\x8e\0""123paginaweb.pt\0" +"es.kr\0" +"pantheonsite.io\0" +"e4.cz\0" +"hattfjelldal.no\0" +"\xe4\xbd\x90\xe8\xb3\x80.jp\0" +"press.se\0" +"fit\0podzone.net\0gloomy.jp\0" +"tomakomai.hokkaido.jp\0*.migration.run\0" +"fedorainfracloud.org\0" +"ishinomaki.miyagi.jp\0" +"hostyhosting.io\0" +"nl-ams-1.baremetal.scw.cloud\0" +"s3.dualstack.ap-south-1.amazonaws.com\0notebook.ca-central-1.sagemaker.aws\0" +"grue.no\0" +"torahime.shiga.jp\0" +"haram.no\0" +"\xd8\xa8\xda\xbe\xd8\xa7\xd8\xb1\xd8\xaa\0" +"dattolocal.net\0alp1.ae.flow.ch\0o0o0.jp\0" +"go.pw\0service.one\0devices.resinstaging.io\0" +"versicherung\0" +"forde.no\0mcpre.ru\0" +"monzabrianza.it\0" +"edugit.io\0" +"abbott\0" +"kitchen\0" +"creditunion\0" +"rennesoy.no\0" +"sannohe.aomori.jp\0nakanojo.gunma.jp\0" +"eaton.mi.us\0eero.online\0customer.mythic-beasts.com\0" +"priv.at\0" +"s3-object-lambda.sa-east-1.amazonaws.com\0" +"miyazaki.miyazaki.jp\0" +"lakas.hu\0" +"gs.va.no\0" +"porsangu.no\0s3.ca-central-1.amazonaws.com\0" +"ci.it\0azurewebsites.net\0" +"obira.hokkaido.jp\0" +"bindal.no\0tours\0community-pro.de\0" +"id.us\0fly\0" +"nishiwaki.hyogo.jp\0" +"tsuga.tochigi.jp\0turystyka.pl\0" +"free\0" +"palmas.br\0br.it\0cb.it\0pa.gov.pl\0" +"gifu.gifu.jp\0" +"id.vn\0servers.run\0" +"narvik.no\0" +"kimino.wakayama.jp\0go.th\0" +"orland.no\0tickets\0execute-api.ap-northeast-2.amazonaws.com\0emrstudio-prod.us-east-1.amazonaws.com\0bnr.la\0" +"yamato.kumamoto.jp\0go.tj\0" +"s3-accesspoint-fips.us-east-1.amazonaws.com\0" +"mutsuzawa.chiba.jp\0kakinoki.shimane.jp\0" +"nome.cv\0" +"is.eu.org\0" +"psse.gov.pl\0" +"navy\0" +"gv.vc\0" +"maizuru.kyoto.jp\0" +"go.ug\0" +"asaminami.hiroshima.jp\0" +"*.dev.adobeaemcloud.com\0" +"at.it\0go.tz\0" +"\xe6\x84\x9b\xe5\xaa\x9b.jp\0kamakura.kanagawa.jp\0landrover\0" +"webview-assets.aws-cloud9.eu-west-3.amazonaws.com\0" +"shingu.fukuoka.jp\0hirata.fukushima.jp\0" +"press.ma\0foo\0" +"am.in\0" +"rio.br\0taki.mie.jp\0" +"matsuyama.ehime.jp\0williamhill\0" +"b\xc3\xa6rum.no\0" +"fox\0" +"poivron.org\0" +"authgear-staging.com\0" +"venice.it\0" +"bahcavuotna.no\0s3-website-us-west-2.amazonaws.com\0" +"perspecta.cloud\0onporter.run\0" +"it.eu.org\0" +"incheon.kr\0" +"framer.photos\0" +"sumomo.ne.jp\0" +"!city.kawasaki.jp\0saikai.nagasaki.jp\0" +"dealer\0" +"gal\0" +"ga.us\0vfs.cloud9.ap-south-1.amazonaws.com\0" +"gap\0" +"cc.va.us\0" +"kawagoe.saitama.jp\0" +"grane.no\0donetsk.ua\0af-south-1.elasticbeanstalk.com\0" +"pr.gov.br\0" +"codes\0" +"gay\0" +"fujisato.akita.jp\0squares.net\0at.md\0" +"frl\0" +"execute-api.me-south-1.amazonaws.com\0" +"avocats.bj\0avellino.it\0" +"beardu.no\0s3-accesspoint.ap-south-2.amazonaws.com\0cechire.com\0" +"lecco.it\0tsuruta.aomori.jp\0\xe4\xbc\x81\xe4\xb8\x9a\0" +"shimoda.shizuoka.jp\0gbiz\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd9\x87\0" +"misato.saitama.jp\0" +"juniper\0\xe7\xbd\x91\xe7\xbb\x9c\0pages.dev\0" +"from-ut.com\0" +"execute-api.eu-south-1.amazonaws.com\0" +"\xd1\x80\xd1\x84\0" +"protection\0" +"tashkent.su\0wixsite.com\0" +"\xe8\xb0\xb7\xe6\xad\x8c\0" +"linkyard.cloud\0" +"bashkiria.ru\0" +"kashima.ibaraki.jp\0kitamoto.saitama.jp\0" +"space\0tele.amune.org\0" +"mat.br\0traniandriabarletta.it\0gdn\0co.financial\0" +"gea\0in.eu.org\0" +"olbiatempio.it\0asahi.mie.jp\0ftr\0" +"dn.ua\0" +"ikata.ehime.jp\0miyako.iwate.jp\0" +"\xd8\xa7\xd9\x84\xd8\xb3\xd8\xb9\xd9\x88\xd8\xaf\xd9\x8a\xd8\xa9\0" +"bashkiria.su\0" +"kharkiv.ua\0notebook-fips.us-west-2.sagemaker.aws\0studio.eu-south-1.sagemaker.aws\0" +"hasami.nagasaki.jp\0kitadaito.okinawa.jp\0goldpoint\0" +"fun\0" +"k12.va.us\0" +"yuzawa.niigata.jp\0" +"s3-object-lambda.ap-southeast-4.amazonaws.com\0jelastic.regruhosting.ru\0" +"pors\xc3\xa1\xc5\x8bgu.no\0" +"\xd7\xa6\xd7\x94\xd7\x9c.\xd7\x99\xd7\xa9\xd7\xa8\xd7\x90\xd7\x9c\0assabu.hokkaido.jp\0" +"musician.io\0" +"lucca.it\0" +"notebook.sa-east-1.sagemaker.aws\0" +"maintenance.aero\0" +"k12.ut.us\0" +"wroc.pl\0" +"eu-north-1.elasticbeanstalk.com\0" +"monza-e-della-brianza.it\0" +"lahppi.no\0is-an-entertainer.com\0" +"malbork.pl\0" +"gr.com\0" +"rep.br\0numata.gunma.jp\0" +"s3-website.us-east-2.amazonaws.com\0" +"smola.no\0" +"s3-accesspoint.ap-southeast-1.amazonaws.com\0" +"shimotsuke.tochigi.jp\0" +"hockey\0georgia.su\0" +"bd.se\0" +"k12.tn.us\0""611.to\0" +"kanoya.kagoshima.jp\0" +"hokksund.no\0cc.ri.us\0" +"s3.eu-north-1.amazonaws.com\0" +"ikeda.gifu.jp\0" +"suginami.tokyo.jp\0shopselect.net\0s3.pl-waw.scw.cloud\0" +"fyi\0" +"rzgw.gov.pl\0" +"vegas\0" +"\xd0\xbc\xd0\xba\xd0\xb4\0" +"memset.net\0" +"b\xc3\xb8mlo.no\0villas\0" +"carbonia-iglesias.it\0" +"keymachine.de\0" +"sande.more-og-romsdal.no\0sykkylven.no\0" +"vfs.cloud9.us-east-1.amazonaws.com\0" +"agro.pl\0" +"academia.bo\0" +"joso.ibaraki.jp\0" +"contagem.br\0miyashiro.saitama.jp\0" +"stor-elvdal.no\0" +"fr\xc3\xa6na.no\0" +"uchinomi.kagawa.jp\0" +"balat.no\0" +"taira.toyama.jp\0" +"s3-ap-northeast-3.amazonaws.com\0misconfused.org\0at.vg\0" +"adobeio-static.net\0" +"my-vigor.de\0" +"fukui.jp\0" +"*.compute-1.amazonaws.com\0" +"bluebite.io\0" +"gle\0" +"\xe5\xaf\x8c\xe5\xb1\xb1.jp\0haiphong.vn\0" +"kamogawa.chiba.jp\0mashiki.kumamoto.jp\0kamikitayama.nara.jp\0" +"no-ip.net\0" +"studio-fips.us-gov-east-1.sagemaker.aws\0" +"career\0" +"aukra.no\0" +"naganohara.gunma.jp\0" +"s3-website.ap-east-1.amazonaws.com\0pyatigorsk.ru\0" +"notebook.eu-central-2.sagemaker.aws\0" +"holiday\0" +"mihama.wakayama.jp\0" +"s3-object-lambda.ap-northeast-1.amazonaws.com\0" +"is-a-student.com\0kalmykia.su\0" +"la-spezia.it\0" +"s3-object-lambda.ap-east-1.amazonaws.com\0from-nm.com\0hk.org\0" +"gmo\0" +"ebiz.tw\0" +"tra.kp\0" +"\xd0\xbc\xd0\xbe\xd0\xbd\0" +"kopervik.no\0" +"toyama.jp\0kiryu.gunma.jp\0minamiawaji.hyogo.jp\0gmx\0" +"adobeaemcloud.com\0myfast.space\0" +"v.bg\0" +"priv.pl\0" +"haga.tochigi.jp\0cheap\0group\0" +"cc.oh.us\0yodobashi\0" +"international\0" +"lindas.no\0" +"mitou.yamaguchi.jp\0" +"hungyen.vn\0whitesnow.jp\0" +"o.bg\0" +"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x81\xd1\x80\xd0\xb1\0goo\0s3-object-lambda.eu-west-1.amazonaws.com\0" +"gop\0" +"vadso.no\0" +"co.krd\0" +"homegoods\0" +"got\0" +"emrnotebooks-prod.eu-central-1.amazonaws.com\0" +"gov\0kawatana.nagasaki.jp\0hachijo.tokyo.jp\0s3.isk02.sakurastorage.jp\0" +"ui.nabu.casa\0" +"repl.run\0" +"h.bg\0kalmykia.ru\0" +"yame.fukuoka.jp\0" +"rdy.jp\0" +"cc.nj.us\0" +"kamikawa.hokkaido.jp\0rep.kp\0execute-api.cn-north-1.amazonaws.com.cn\0" +"priv.no\0" +"alta.no\0" +"date.hokkaido.jp\0" +"a.bg\0fitjar.no\0movie\0c.cdn77.org\0" +"nikon\0" +"matsumoto.nagano.jp\0instantcloud.cn\0" +"toon.ehime.jp\0" +"cc.ms.us\0cc.nc.us\0" +"shirosato.ibaraki.jp\0po.gov.pl\0" +"barcelona\0" +"g.vbrplsbx.io\0" +"yukuhashi.fukuoka.jp\0kameoka.kyoto.jp\0kyotamba.kyoto.jp\0" +"s3-object-lambda.ca-central-1.amazonaws.com\0" +"tromso.no\0" +"aquila.it\0" +"birkenes.no\0" +"isernia.it\0tamakawa.fukushima.jp\0kitahata.saga.jp\0" +"hbo\0" +"trentinoalto-adige.it\0" +"agric.za\0secure\0" +"higashisumiyoshi.osaka.jp\0travel.pl\0" +"yoro.gifu.jp\0" +"chernigov.ua\0k12.or.us\0" +"musashino.tokyo.jp\0" +"notebook.ap-south-1.sagemaker.aws\0" +"notebook.cn-northwest-1.sagemaker.com.cn\0" +"priv.me\0cc.me.us\0dreamhosters.com\0" +"okegawa.saitama.jp\0lubin.pl\0\xe6\x85\x88\xe5\x96\x84\0" +"chikujo.fukuoka.jp\0nome.pt\0" +"orskog.no\0" +"\xd8\xa7\xd9\x8a\xd8\xb1\xd8\xa7\xd9\x86.ir\0" +"hasvik.no\0s3-accesspoint.ap-northeast-1.amazonaws.com\0" +"osakikamijima.hiroshima.jp\0" +"ass.km\0" +"saloon.jp\0" +"tranby.no\0" +"nakayama.yamagata.jp\0" +"ntr.br\0sondrio.it\0tsuyama.okayama.jp\0" +"eidsberg.no\0edeka\0" +"sport.hu\0serveftp.org\0" +"ecommerce-shop.pl\0" +"hirokawa.fukuoka.jp\0" +"akamaiorigin-staging.net\0" +"\xe5\x8f\xb0\xe7\x81\xa3\0" +"nisshin.aichi.jp\0" +"k12.ok.us\0" +"biella.it\0" +"pics\0tlon.network\0" +"tarama.okinawa.jp\0fujimi.saitama.jp\0" +"bounty-full.com\0" +"lazio.it\0\xd8\xb3\xd9\x88\xd8\xaf\xd8\xa7\xd9\x86\0" +"otsuka\0podzone.org\0" +"yashiro.hyogo.jp\0kurobe.toyama.jp\0" +"kiso.nagano.jp\0" +"7.bg\0" +"akabira.hokkaido.jp\0psp.gov.pl\0" +"k12.mn.us\0s3-website.dualstack.ap-southeast-2.amazonaws.com\0" +"*.stolos.io\0" +"wien\0deci.jp\0" +"cloud\0" +"directory\0ddnss.de\0" +"kamigori.hyogo.jp\0seika.kyoto.jp\0" +"s3-website.dualstack.cn-north-1.amazonaws.com.cn\0" +"nagai.yamagata.jp\0noho.st\0" +"0.bg\0s3-ap-southeast-1.amazonaws.com\0" +"kita.kyoto.jp\0travel.tt\0senseering.net\0" +"k12.nm.us\0" +"hamatonbetsu.hokkaido.jp\0" +"s3-accesspoint.dualstack.sa-east-1.amazonaws.com\0" +"assur.bj\0asahi.yamagata.jp\0" +"r\xc3\xb8yrvik.no\0s3-deprecated.eu-west-1.amazonaws.com\0" +"draydns.de\0" +"algard.no\0caracal.mythic-beasts.com\0" +"wedding\0forgot.her.name\0" +"git-pages.rit.edu\0" +"emrstudio-prod.us-gov-west-1.amazonaws.com\0dnsdojo.com\0" +"it.com\0" +"xerox\0" +"fortal.br\0jelastic.tsukaeru.net\0" +"synology-ds.de\0" +"sakura\0" +"tokai.ibaraki.jp\0taito.tokyo.jp\0" +"pueblo.bo\0" +"namerikawa.toyama.jp\0" +"poltava.ua\0dd-dns.de\0" +"trentinoa-adige.it\0otsu.shiga.jp\0" +"satsumasendai.kagoshima.jp\0" +"s3-object-lambda.ap-southeast-3.amazonaws.com\0s3-accesspoint-fips.dualstack.us-west-2.amazonaws.com\0" +"hiv\0" +"execute-api.ap-southeast-4.amazonaws.com\0paas.datacenter.fi\0" +"rygge.no\0" +"babia-gora.pl\0" +"\xe0\xa4\xa8\xe0\xa5\x87\xe0\xa4\x9f\0" +"shimosuwa.nagano.jp\0" +"engerdal.no\0" +"k12.ky.us\0\xe5\x81\xa5\xe5\xba\xb7\0" +"ssl.origin.cdn77-secure.org\0" +"royal-commission.uk\0" +"heroy.nordland.no\0from-nh.com\0" +"diskussionsbereich.de\0" +"pr.gov.pl\0r.cdn77.net\0" +"is-a-therapist.com\0" +"tokashiki.okinawa.jp\0yoshida.shizuoka.jp\0westus2.azurestaticapps.net\0" +"konsulat.gov.pl\0" +"m\xc3\xa5s\xc3\xb8y.no\0" +"hashikami.aomori.jp\0hkt\0" +"dscloud.me\0" +"sue.fukuoka.jp\0tsubata.ishikawa.jp\0" +"skierva.no\0notebook.ap-southeast-2.sagemaker.aws\0" +"oita.oita.jp\0dontexist.net\0" +"wiki\0" +"des.br\0" +"blackfriday\0" +"ar.com\0fentiger.mythic-beasts.com\0dsmynas.com\0" +"onna.okinawa.jp\0" +"nysa.pl\0" +"s3-accesspoint-fips.ca-central-1.amazonaws.com\0" +"aarborte.no\0" +"matsumoto.kagoshima.jp\0tonaki.okinawa.jp\0" +"barrel-of-knowledge.info\0" +"cs.keliweb.cloud\0" +"zj.cn\0zentsuji.kagawa.jp\0" +"equipment\0" +"fjaler.no\0lynx.mythic-beasts.com\0" +"emrnotebooks-prod.sa-east-1.amazonaws.com\0" +"okayama.jp\0" +"\xe6\x94\xbf\xe5\xba\x9c.hk\0b\xc3\xa1id\xc3\xa1r.no\0" +"adult\0flop.jp\0" +"krager\xc3\xb8.no\0official.ec\0" +"trentin-sudtirol.it\0jinsekikogen.hiroshima.jp\0" +"bike\0" +"yugawa.fukushima.jp\0" +"tado.mie.jp\0" +"romskog.no\0valle.no\0wine\0za.com\0" +"iwate.jp\0\xd8\xa7\xd9\x84\xd8\xa8\xd8\xad\xd8\xb1\xd9\x8a\xd9\x86\0" +"hazu.aichi.jp\0" +"koganei.tokyo.jp\0kicks-ass.net\0hippy.jp\0" +"valledaosta.it\0" +"school.na\0" +"yoshikawa.saitama.jp\0hot\0" +"lib.vi.us\0s3-fips.us-gov-west-1.amazonaws.com\0" +"santamaria.br\0showa.fukushima.jp\0" +"how\0ping\0" +"o.se\0cuisinella\0" +"shiwa.iwate.jp\0" +"cc.fl.us\0catholic\0pink\0" +"1.azurestaticapps.net\0" +"cloud66.ws\0" +"flap.id\0" +"pt.eu.org\0" +"lib.tn.us\0" +"oristano.it\0" +"karlsoy.no\0" +"h.se\0v.ua\0" +"school.nz\0" +"apple\0" +"trentino-a-adige.it\0" +"mw.gov.pl\0" +"hara.nagano.jp\0" +"ddns.me\0" +"pinb.gov.pl\0" +"bing\0s3.ap-southeast-1.amazonaws.com\0in-berlin.de\0" +"uki.kumamoto.jp\0joetsu.niigata.jp\0" +"plurinacional.bo\0a.se\0docs\0" +"bari.it\0" +"bronnoysund.no\0" +"ohira.tochigi.jp\0" +"yoga\0" +"abogado\0" +"ibm\0emrappui-prod.ap-east-1.amazonaws.com\0" +"yokawa.hyogo.jp\0" +"trentino-altoadige.it\0" +"ice\0" +"shimizu.hokkaido.jp\0" +"*.database.run\0" +"\xe8\x8c\xa8\xe5\x9f\x8e.jp\0" +"\xd0\xbe\xd1\x80\xd0\xb3.\xd1\x80\xd1\x83\xd1\x81\0" +"london.cloudapps.digital\0" +"ibxos.it\0" +"ms.gov.br\0anjo.aichi.jp\0hagi.yamaguchi.jp\0" +"asker.no\0icu\0my-firewall.org\0" +"nishinomiya.hyogo.jp\0website.yandexcloud.net\0" +"mo\xc3\xa5reke.no\0" +"sekigahara.gifu.jp\0" +"barum.no\0homesecuritymac.com\0" +"\xe7\xb5\x84\xe7\xb9\x94.tw\0" +"kyotanabe.kyoto.jp\0\xe6\x9c\xba\xe6\x9e\x84\0at-band-camp.net\0" +"oksnes.no\0" +"leasing.aero\0" +"zamami.okinawa.jp\0" +"kitagata.gifu.jp\0mizunami.gifu.jp\0manno.kagawa.jp\0mitoyo.kagawa.jp\0" +"lib.sc.us\0crd.co\0" +"tsuchiura.ibaraki.jp\0" +"fukuyama.hiroshima.jp\0" +"gs.ah.no\0" +"is-a-bruinsfan.org\0" +"mycd.eu\0" +"mt.gov.br\0gliwice.pl\0" +"woodside\0from-tx.com\0" +"yamagata.nagano.jp\0" +"leitungsen.de\0" +"soeda.fukuoka.jp\0" +"tv.bb\0" +"niigata.niigata.jp\0" +"gs.aa.no\0ifm\0" +"luxury\0" +"utsunomiya.tochigi.jp\0" +"fastly-terrarium.com\0" +"sn\xc3\xa5""ase.no\0webview-assets.cloud9.eu-west-1.amazonaws.com\0ddnsking.com\0" +"tv.bo\0" +"tv.br\0hakui.ishikawa.jp\0" +"maceio.br\0" +"trentin-s\xc3\xbc""dtirol.it\0tsukuba.ibaraki.jp\0" +"*.spectrum.myjino.ru\0" +"uzhhorod.ua\0ca-central-1.elasticbeanstalk.com\0myforum.community\0" +"adult.ht\0" +"soccer\0" +"vfs.cloud9.me-south-1.amazonaws.com\0" +"kitami.hokkaido.jp\0walter\0" +"obanazawa.yamagata.jp\0" +"platter-app.com\0" +"niigata.jp\0iwaki.fukushima.jp\0" +"tube\0" +"urausu.hokkaido.jp\0" +"lk3.ru\0" +"press.aero\0" +"nishiazai.shiga.jp\0abu.yamaguchi.jp\0" +"leirvik.no\0" +"greta.fr\0" +"emrstudio-prod.ap-southeast-1.amazonaws.com\0from-ok.com\0" +"potenza.it\0" +"mochizuki.nagano.jp\0nieruchomosci.pl\0search\0" +"webview-assets.cloud9.ap-southeast-1.amazonaws.com\0" +"kai.yamanashi.jp\0" +"uzhgorod.ua\0" +"sx.cn\0iitate.fukushima.jp\0yachiyo.ibaraki.jp\0suzaka.nagano.jp\0" +"vang.no\0" +"africa\0catering\0protonet.io\0" +"bci.dnstrace.pro\0" +"wzmiuw.gov.pl\0" +"from-hi.com\0" +"shiiba.miyazaki.jp\0" }; -static constexpr quint32 tldChunks[tldChunkCount] = {65525, 108674}; +static constexpr quint32 tldChunks[tldChunkCount] = {65516, 127046}; QT_END_NAMESPACE diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index 916774db04e..73057d656dc 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -615,10 +615,7 @@ void QSslConfiguration::setCiphers(const QList &ciphers) Sets the cryptographic cipher suite for this configuration to \a ciphers, which is a colon-separated list of cipher suite names. The ciphers are listed - in order of preference, starting with the most preferred cipher. For example: - - \snippet code/src_network_ssl_qsslconfiguration.cpp 1 - + in order of preference, starting with the most preferred cipher. Each cipher name in \a ciphers must be the name of a cipher in the list returned by supportedCiphers(). Restricting the cipher suite must be done before the handshake phase, where the session cipher diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp index 2fdf269566d..ead3251b8ce 100644 --- a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp +++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include +#include #include "qandroidplatformfontdatabase.h" @@ -76,6 +77,38 @@ QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &fami QChar::Script script) const { QStringList result; + + // Prepend CJK fonts by the locale. + QLocale locale = QLocale::system(); + switch (locale.language()) { + case QLocale::Chinese: { + switch (locale.territory()) { + case QLocale::China: + case QLocale::Singapore: + result.append(QStringLiteral("Noto Sans Mono CJK SC")); + break; + case QLocale::Taiwan: + case QLocale::HongKong: + case QLocale::Macao: + result.append(QStringLiteral("Noto Sans Mono CJK TC")); + break; + default: + // no modifications. + break; + } + break; + } + case QLocale::Japanese: + result.append(QStringLiteral("Noto Sans Mono CJK JP")); + break; + case QLocale::Korean: + result.append(QStringLiteral("Noto Sans Mono CJK KR")); + break; + default: + // no modifications. + break; + } + if (styleHint == QFont::Monospace || styleHint == QFont::Courier) result.append(QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(QLatin1Char(';'))); else if (styleHint == QFont::Serif) diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h index ad61c2d5840..3108319620c 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.h @@ -74,6 +74,7 @@ public: public: // for QNSOpenSavePanelDelegate void panelClosed(NSInteger result); + void panelDirectoryDidChange(NSString *path); private: void createNSOpenSavePanelDelegate(); diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm index 358fba50c7a..afb280388e0 100644 --- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm +++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm @@ -87,8 +87,6 @@ typedef QSharedPointer SharedPointerFileDialogOptions; NSPopUpButton *m_popupButton; NSTextField *m_textField; QCocoaFileDialogHelper *m_helper; - NSString *m_currentDirectory; - SharedPointerFileDialogOptions m_options; QString *m_currentSelection; QStringList *m_nameFilterDropDownList; @@ -116,12 +114,34 @@ typedef QSharedPointer SharedPointerFileDialogOptions; QString selectedVisualNameFilter = m_options->initiallySelectedNameFilter(); m_selectedNameFilter = new QStringList([self findStrippedFilterWithVisualFilterName:selectedVisualNameFilter]); + // Explicitly show extensions if we detect a filter + // that has a multi-part extension. This prevents + // confusing situations where the user clicks e.g. + // 'foo.tar.gz' and 'foo.tar' is populated in the + // file name box, but when then clicking save macOS + // will warn that the file needs to end in .gz, + // due to thinking the user tried to save the file + // as a 'tar' file instead. Unfortunately this + // property can only be set before the panel is + // shown, so we can't toggle it on and off based + // on the active filter. + m_panel.extensionHidden = [&]{ + for (const auto &nameFilter : *m_nameFilterDropDownList) { + const auto extensions = QPlatformFileDialogHelper::cleanFilterList(nameFilter); + for (const auto &extension : extensions) { + if (extension.count('.') > 1) + return false; + } + } + return true; + }(); + QFileInfo sel(selectFile); if (sel.isDir() && !sel.isBundle()){ - m_currentDirectory = [sel.absoluteFilePath().toNSString() retain]; + m_panel.directoryURL = [NSURL fileURLWithPath:sel.absoluteFilePath().toNSString()]; m_currentSelection = new QString; } else { - m_currentDirectory = [sel.absolutePath().toNSString() retain]; + m_panel.directoryURL = [NSURL fileURLWithPath:sel.absolutePath().toNSString()]; m_currentSelection = new QString(sel.absoluteFilePath()); } @@ -131,7 +151,7 @@ typedef QSharedPointer SharedPointerFileDialogOptions; m_panel.accessoryView = m_nameFilterDropDownList->size() > 1 ? m_accessoryView : nil; // -setAccessoryView: can result in -panel:directoryDidChange: - // resetting our m_currentDirectory, set the delegate + // resetting our current directory. Set the delegate // here to make sure it gets the correct value. m_panel.delegate = self; @@ -156,7 +176,6 @@ typedef QSharedPointer SharedPointerFileDialogOptions; [m_accessoryView release]; m_panel.delegate = nil; [m_panel release]; - [m_currentDirectory release]; [super dealloc]; } @@ -168,7 +187,6 @@ typedef QSharedPointer SharedPointerFileDialogOptions; bool selectable = (m_options->acceptMode() == QFileDialogOptions::AcceptSave) || [self panel:m_panel shouldEnableURL:url]; - m_panel.directoryURL = [NSURL fileURLWithPath:m_currentDirectory]; m_panel.nameFieldStringValue = selectable ? info.fileName().toNSString() : @""; [self updateProperties]; @@ -380,20 +398,6 @@ typedef QSharedPointer SharedPointerFileDialogOptions; m_panel.allowedFileTypes = [self computeAllowedFileTypes]; - // Explicitly show extensions if we detect a filter - // that has a multi-part extension. This prevents - // confusing situations where the user clicks e.g. - // 'foo.tar.gz' and 'foo.tar' is populated in the - // file name box, but when then clicking save macOS - // will warn that the file needs to end in .gz, - // due to thinking the user tried to save the file - // as a 'tar' file instead. Unfortunately this - // property can only be set before the panel is - // shown, so it will not have any effect when - // switching filters in an already opened dialog. - if (m_panel.allowedFileTypes.count > 2) - m_panel.extensionHidden = NO; - if (m_panel.visible) [m_panel validateVisibleColumns]; } @@ -414,14 +418,10 @@ typedef QSharedPointer SharedPointerFileDialogOptions; { Q_UNUSED(sender); - if (!(path && path.length) || [path isEqualToString:m_currentDirectory]) + if (!m_helper) return; - [m_currentDirectory release]; - m_currentDirectory = [path retain]; - - // ### fixme: priv->setLastVisitedDirectory(newDir); - emit m_helper->directoryEntered(QUrl::fromLocalFile(QString::fromNSString(m_currentDirectory))); + m_helper->panelDirectoryDidChange(path); } /* @@ -548,21 +548,32 @@ void QCocoaFileDialogHelper::panelClosed(NSInteger result) void QCocoaFileDialogHelper::setDirectory(const QUrl &directory) { + m_directory = directory; + if (m_delegate) m_delegate->m_panel.directoryURL = [NSURL fileURLWithPath:directory.toLocalFile().toNSString()]; - else - m_directory = directory; } QUrl QCocoaFileDialogHelper::directory() const { - if (m_delegate) { - QString path = QString::fromNSString(m_delegate->m_panel.directoryURL.path).normalized(QString::NormalizationForm_C); - return QUrl::fromLocalFile(path); - } return m_directory; } +void QCocoaFileDialogHelper::panelDirectoryDidChange(NSString *path) +{ + if (!path || [path isEqual:NSNull.null] || !path.length) + return; + + const auto oldDirectory = m_directory; + m_directory = QUrl::fromLocalFile( + QString::fromNSString(path).normalized(QString::NormalizationForm_C)); + + if (m_directory != oldDirectory) { + // FIXME: Plumb old directory back to QFileDialog's lastVisitedDir? + emit directoryEntered(m_directory); + } +} + void QCocoaFileDialogHelper::selectFile(const QUrl &filename) { QString filePath = filename.toLocalFile(); diff --git a/src/plugins/platforms/cocoa/qnsview_complextext.mm b/src/plugins/platforms/cocoa/qnsview_complextext.mm index e84aa88bf6a..0534e984590 100644 --- a/src/plugins/platforms/cocoa/qnsview_complextext.mm +++ b/src/plugins/platforms/cocoa/qnsview_complextext.mm @@ -529,6 +529,32 @@ return NSNotFound; } +/* + Returns the window level of the text input. + + This allows the input method to place its input panel + above the text input. +*/ +- (NSInteger)windowLevel +{ + // The default level assumed by input methods is NSFloatingWindowLevel, + // but our NSWindow level could be higher than that for many reasons, + // including being set via QWindow::setFlags() or directly on the + // NSWindow, or because we're embedded into a native view hierarchy. + // Return the actual window level to account for this. + auto level = m_platformWindow ? m_platformWindow->nativeWindow().level + : NSNormalWindowLevel; + + // The logic above only covers our own window though. In some cases, + // such as when a completer is active, the text input has a lower + // window level than another window that's also visible, and we don't + // want the input panel to be sandwiched between these two windows. + // Account for this by explicitly using NSPopUpMenuWindowLevel as + // the minimum window level, which corresponds to the highest level + // one can get via QWindow::setFlags(), except for Qt::ToolTip. + return qMax(level, NSPopUpMenuWindowLevel); +} + // ------------- Helper functions ------------- /* diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp index b47ded766f5..57dae83d35d 100644 --- a/src/plugins/platforms/windows/qwindowsdrag.cpp +++ b/src/plugins/platforms/windows/qwindowsdrag.cpp @@ -685,7 +685,8 @@ IDropTargetHelper* QWindowsDrag::dropHelper() { static HRESULT startDoDragDrop(LPDATAOBJECT pDataObj, LPDROPSOURCE pDropSource, DWORD dwOKEffects, LPDWORD pdwEffect) { QWindow *underMouse = QWindowsContext::instance()->windowUnderMouse(); - const HWND hwnd = underMouse ? reinterpret_cast(underMouse->winId()) : ::GetFocus(); + const bool hasMouseCapture = underMouse && static_cast(underMouse->handle())->hasMouseCapture(); + const HWND hwnd = hasMouseCapture ? reinterpret_cast(underMouse->winId()) : ::GetFocus(); bool starting = false; for (;;) { diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp index 14bd1526212..5ce20420a9c 100644 --- a/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp +++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.cpp @@ -208,8 +208,6 @@ void QWindowsSystemTrayIcon::cleanup() void QWindowsSystemTrayIcon::updateIcon(const QIcon &icon) { qCDebug(lcQpaTrayIcon) << __FUNCTION__ << '(' << icon << ')' << this; - if (icon.cacheKey() == m_icon.cacheKey()) - return; m_icon = icon; const HICON hIconToDestroy = createIcon(icon); if (ensureInstalled()) @@ -273,6 +271,10 @@ void QWindowsSystemTrayIcon::showMessage(const QString &title, const QString &me size = largeIcon; } QPixmap pm = icon.pixmap(size); + if (m_hMessageIcon) { + DestroyIcon(m_hMessageIcon); + m_hMessageIcon = nullptr; + } if (pm.isNull()) { tnd.dwInfoFlags = NIIF_INFO; } else { @@ -281,7 +283,8 @@ void QWindowsSystemTrayIcon::showMessage(const QString &title, const QString &me pm.size().width(), pm.size().height(), size.width(), size.height()); pm = pm.scaled(size, Qt::IgnoreAspectRatio); } - tnd.hBalloonIcon = qt_pixmapToWinHICON(pm); + m_hMessageIcon = qt_pixmapToWinHICON(pm); + tnd.hBalloonIcon = m_hMessageIcon; } tnd.hWnd = m_hwnd; tnd.uTimeout = msecsIn <= 0 ? UINT(10000) : UINT(msecsIn); // 10s default @@ -339,7 +342,10 @@ void QWindowsSystemTrayIcon::ensureCleanup() } if (m_hIcon != nullptr) DestroyIcon(m_hIcon); + if (m_hMessageIcon != nullptr) + DestroyIcon(m_hMessageIcon); m_hIcon = nullptr; + m_hMessageIcon = nullptr; m_menu = nullptr; // externally owned m_toolTip.clear(); } diff --git a/src/plugins/platforms/windows/qwindowssystemtrayicon.h b/src/plugins/platforms/windows/qwindowssystemtrayicon.h index 44e1bcc7611..8e70d443639 100644 --- a/src/plugins/platforms/windows/qwindowssystemtrayicon.h +++ b/src/plugins/platforms/windows/qwindowssystemtrayicon.h @@ -91,6 +91,7 @@ private: QString m_toolTip; HWND m_hwnd = nullptr; HICON m_hIcon = nullptr; + HICON m_hMessageIcon = nullptr; mutable QPointer m_menu; bool m_ignoreNextMouseRelease = false; bool m_visible = false; diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp index 3465c55bc49..4f069926cdb 100644 --- a/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp +++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiatextrangeprovider.cpp @@ -343,14 +343,14 @@ HRESULT QWindowsUiaTextRangeProvider::Move(TextUnit unit, int count, int *pRetVa int len = textInterface->characterCount(); - if (len < 1) + if (len < 1 || count == 0) // MSDN: "Zero has no effect." return S_OK; if (unit == TextUnit_Character) { // Moves the start point, ensuring it lies within the bounds. - int start = qBound(0, m_startOffset + count, len - 1); + int start = qBound(0, m_startOffset + count, len); // If range was initially empty, leaves it as is; otherwise, normalizes it to one char. - m_endOffset = (m_endOffset > m_startOffset) ? start + 1 : start; + m_endOffset = (m_endOffset > m_startOffset) ? qMin(start + 1, len) : start; *pRetVal = start - m_startOffset; // Returns the actually moved distance. m_startOffset = start; } else { @@ -421,7 +421,7 @@ HRESULT QWindowsUiaTextRangeProvider::MoveEndpointByUnit(TextPatternRangeEndpoin if (unit == TextUnit_Character) { if (endpoint == TextPatternRangeEndpoint_Start) { - int boundedValue = qBound(0, m_startOffset + count, len - 1); + int boundedValue = qBound(0, m_startOffset + count, len); *pRetVal = boundedValue - m_startOffset; m_startOffset = boundedValue; m_endOffset = qBound(m_startOffset, m_endOffset, len); diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 91afa458af8..1b827927860 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -1464,7 +1464,8 @@ void QXcbWindow::propagateSizeHints() qMin(XCOORD_MAX, maximumSize.height())); if (sizeIncrement.width() > 0 || sizeIncrement.height() > 0) { - xcb_icccm_size_hints_set_base_size(&hints, baseSize.width(), baseSize.height()); + if (!baseSize.isNull() && baseSize.isValid()) + xcb_icccm_size_hints_set_base_size(&hints, baseSize.width(), baseSize.height()); xcb_icccm_size_hints_set_resize_inc(&hints, sizeIncrement.width(), sizeIncrement.height()); } @@ -1994,10 +1995,15 @@ static inline bool doCheckUnGrabAncestor(QXcbConnection *conn) return true; } -static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn = nullptr) +static bool windowContainsGlobalPoint(QXcbWindow *window, int x, int y) +{ + return window ? window->geometry().contains(window->mapFromGlobal(QPoint(x, y))) : false; +} + +static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn) { return ((doCheckUnGrabAncestor(conn) - && mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) + && mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) || (mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_INFERIOR) || detail == XCB_NOTIFY_DETAIL_VIRTUAL || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); @@ -2017,14 +2023,13 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in { connection()->setTime(timestamp); - const QPoint global = QPoint(root_x, root_y); - if (ignoreEnterEvent(mode, detail, connection()) || connection()->mousePressWindow()) return; // Updates scroll valuators, as user might have done some scrolling outside our X client. connection()->xi2UpdateScrollingDevices(); + const QPoint global = QPoint(root_x, root_y); const QPoint local(event_x, event_y); QWindowSystemInterface::handleEnterEvent(window(), local, global); } @@ -2034,8 +2039,11 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, { connection()->setTime(timestamp); - if (ignoreLeaveEvent(mode, detail, connection()) || connection()->mousePressWindow()) + QXcbWindow *mousePressWindow = connection()->mousePressWindow(); + if (ignoreLeaveEvent(mode, detail, connection()) + || (mousePressWindow && windowContainsGlobalPoint(mousePressWindow, root_x, root_y))) { return; + } // check if enter event is buffered auto event = connection()->eventQueue()->peek([](xcb_generic_event_t *event, int type) { @@ -2053,6 +2061,8 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); } else { QWindowSystemInterface::handleLeaveEvent(window()); + if (!windowContainsGlobalPoint(this, root_x, root_y)) + connection()->setMousePressWindow(nullptr); } free(enter); diff --git a/src/plugins/sqldrivers/.cmake.conf b/src/plugins/sqldrivers/.cmake.conf index d9966ddcd05..897ec4a3db6 100644 --- a/src/plugins/sqldrivers/.cmake.conf +++ b/src/plugins/sqldrivers/.cmake.conf @@ -1 +1 @@ -set(QT_REPO_MODULE_VERSION "6.2.11") +set(QT_REPO_MODULE_VERSION "6.2.12") diff --git a/src/plugins/tls/schannel/qtls_schannel.cpp b/src/plugins/tls/schannel/qtls_schannel.cpp index 93804ca57b4..371b119549b 100644 --- a/src/plugins/tls/schannel/qtls_schannel.cpp +++ b/src/plugins/tls/schannel/qtls_schannel.cpp @@ -1654,8 +1654,12 @@ void TlsCryptographSchannel::transmit() qCWarning(lcTlsBackendSchannel, "The internal SSPI handle is invalid!"); Q_UNREACHABLE(); } else if (status == SEC_E_INVALID_TOKEN) { - qCWarning(lcTlsBackendSchannel, "Got SEC_E_INVALID_TOKEN!"); - Q_UNREACHABLE(); // Happened once due to a bug, but shouldn't generally happen(?) + // Supposedly we have an invalid token, it's under-documented what + // this means, so to be safe we disconnect. + shutdown = true; + disconnectFromHost(); + setErrorAndEmit(d, QAbstractSocket::SslInternalError, schannelErrorToString(status)); + break; } else if (status == SEC_E_MESSAGE_ALTERED) { // The message has been altered, disconnect now. shutdown = true; // skips sending the shutdown alert diff --git a/src/testlib/qtestcase.qdoc b/src/testlib/qtestcase.qdoc index 8e4d58a6f73..52d6e0d4476 100644 --- a/src/testlib/qtestcase.qdoc +++ b/src/testlib/qtestcase.qdoc @@ -247,7 +247,7 @@ Example: \code - QTRY_VERIFY2_WITH_TIMEOUT(list.size() > 2, QByteArray::number(list.size()).constData()); + QTRY_VERIFY2(list.size() > 2, QByteArray::number(list.size()).constData()); \endcode \note This macro can only be used in a test function that is invoked diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index f5f70e3447a..e62c4ed59a7 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -2519,8 +2519,9 @@ void checkAndWarnGradleLongPaths(const QString &outputDirectory) QDirIterator it(outputDirectory, QStringList(QStringLiteral("*.java")), QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { - if (it.next().size() >= MAX_PATH) - longFileNames.append(it.next()); + const QString &filePath = it.next(); + if (filePath.size() >= MAX_PATH) + longFileNames.append(filePath); } if (!longFileNames.isEmpty()) { diff --git a/src/tools/bootstrap/CMakeLists.txt b/src/tools/bootstrap/CMakeLists.txt index cd78609d9ab..5026393736e 100644 --- a/src/tools/bootstrap/CMakeLists.txt +++ b/src/tools/bootstrap/CMakeLists.txt @@ -83,7 +83,6 @@ qt_internal_extend_target(Bootstrap ../../corelib/time/qgregoriancalendar.cpp ../../corelib/time/qromancalendar.cpp ../../corelib/tools/qarraydata.cpp - ../../corelib/tools/qbitarray.cpp ../../corelib/tools/qcommandlineoption.cpp ../../corelib/tools/qcommandlineparser.cpp ../../corelib/tools/qcryptographichash.cpp @@ -190,6 +189,7 @@ qt_internal_extend_target(Bootstrap CONDITION CMAKE_CROSSCOMPILING OR NOT QT_FEA ../../3rdparty/pcre2/src/pcre2.h ../../3rdparty/pcre2/src/pcre2_auto_possess.c ../../3rdparty/pcre2/src/pcre2_chartables.c + ../../3rdparty/pcre2/src/pcre2_chkdint.c ../../3rdparty/pcre2/src/pcre2_compile.c ../../3rdparty/pcre2/src/pcre2_config.c ../../3rdparty/pcre2/src/pcre2_context.c diff --git a/src/widgets/kernel/qwidgetsvariant.cpp b/src/widgets/kernel/qwidgetsvariant.cpp index e27c26cd059..e8301a3bec2 100644 --- a/src/widgets/kernel/qwidgetsvariant.cpp +++ b/src/widgets/kernel/qwidgetsvariant.cpp @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE namespace { +// NOLINTNEXTLINE(cppcoreguidelines-virtual-class-destructor): this is not a base class static const struct : QMetaTypeModuleHelper { const QtPrivate::QMetaTypeInterface *interfaceForType(int type) const override { diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index 710aa831ab8..e84f8bfdb8d 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -319,9 +319,9 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const returns the visual geometry of a single tab. \table 100% - \row \li \inlineimage fusion-tabbar.png Screenshot of a Fusion style tab bar + \row \li \inlineimage {fusion-tabbar.png} {Screenshot of a Fusion style tab bar} \li A tab bar shown in the \l{Qt Widget Gallery}{Fusion widget style}. - \row \li \inlineimage fusion-tabbar-truncated.png Screenshot of a truncated Fusion tab bar + \row \li \inlineimage {fusion-tabbar-truncated.png} {Screenshot of a truncated Fusion tab bar} \li A truncated tab bar shown in the Fusion widget style. \endtable diff --git a/tests/auto/cmake/mockplugins/.cmake.conf b/tests/auto/cmake/mockplugins/.cmake.conf index d9966ddcd05..897ec4a3db6 100644 --- a/tests/auto/cmake/mockplugins/.cmake.conf +++ b/tests/auto/cmake/mockplugins/.cmake.conf @@ -1 +1 @@ -set(QT_REPO_MODULE_VERSION "6.2.11") +set(QT_REPO_MODULE_VERSION "6.2.12") diff --git a/tests/auto/cmake/test_static_resources/.cmake.conf b/tests/auto/cmake/test_static_resources/.cmake.conf index d9966ddcd05..897ec4a3db6 100644 --- a/tests/auto/cmake/test_static_resources/.cmake.conf +++ b/tests/auto/cmake/test_static_resources/.cmake.conf @@ -1 +1 @@ -set(QT_REPO_MODULE_VERSION "6.2.11") +set(QT_REPO_MODULE_VERSION "6.2.12") diff --git a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp index aed72fab1bf..6b1ed21bc2c 100644 --- a/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/concurrent/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -209,6 +209,17 @@ void tst_QtConcurrentMap::map() QCOMPARE(list, NonTemplateSequence({ 2, 4, 6 })); } + // custom pool with invalid number of threads + { + QList list; + list << 1 << 2 << 3; + QThreadPool pool; + pool.setMaxThreadCount(0); // explicitly set incorrect value + // This should not crash + QtConcurrent::map(&pool, list, MultiplyBy2InPlace()).waitForFinished(); + QCOMPARE(list, QList() << 2 << 4 << 6); + } + #if 0 // not allowed: map() with immutable sequences makes no sense { @@ -1046,6 +1057,17 @@ void tst_QtConcurrentMap::mappedReducedThreadPool() intCube, intSumReduce); QCOMPARE(result, sumOfCubes); } + + { + // pool with invalid number of threads + QThreadPool pool; + pool.setMaxThreadCount(0); // explicitly set incorrect value + + // This should not crash + NonTemplateSequence list { 1, 2, 3 }; + auto future = QtConcurrent::mappedReduced(&pool, list, multiplyBy2, intSumReduce); + QCOMPARE(future.result(), 12); + } } void tst_QtConcurrentMap::mappedReducedWithMoveOnlyCallable() diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index f7e9ff375d5..a1567d72abd 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -104,6 +104,7 @@ private slots: void blockingQueuedConnection(); void childEvents(); void installEventFilter(); + void installEventFilterOrder(); void deleteSelfInSlot(); void disconnectSelfInSlotAndDeleteAfterEmit(); void dumpObjectInfo(); @@ -3095,9 +3096,11 @@ public: bool eventFilter(QObject *object, QEvent *event) override { events.append(qMakePair(object, event->type())); + timeStamp = std::chrono::steady_clock::now(); return false; } + std::chrono::steady_clock::time_point timeStamp; private: EventList events; }; @@ -3227,6 +3230,78 @@ void tst_QObject::installEventFilter() QVERIFY(spy.eventList().isEmpty()); } +void tst_QObject::installEventFilterOrder() +{ + // installEventFilter() adds new objects to d_func()->extraData->eventFilters, which + // affects the order of calling each object's eventFilter() when processing the events. + + QObject object; + EventSpy spy1; + object.installEventFilter(&spy1); + EventSpy spy2; + object.installEventFilter(&spy2); + EventSpy spy3; + object.installEventFilter(&spy3); + + const EventSpy::EventList expected = { {&object, QEvent::Type(QEvent::User + 1)} }; + auto checkExpected = [&] { + QCOMPARE(spy1.eventList(), expected); + QCOMPARE(spy2.eventList(), expected); + QCOMPARE(spy3.eventList(), expected); + }; + + auto clearSignalSpies = [&] { + for (auto *s : {&spy1, &spy2, &spy3}) + s->clear(); + }; + + auto checkCallOrder = [](EventSpy &a, EventSpy &b, EventSpy &c) { + QVERIFY(a.timeStamp > b.timeStamp); + QVERIFY(b.timeStamp > c.timeStamp); + }; + + QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1))); + QCoreApplication::processEvents(); + + checkExpected(); + if (QTest::currentTestFailed()) + return; + + checkCallOrder(spy1, spy2, spy3); + if (QTest::currentTestFailed()) + return; + + clearSignalSpies(); + + // Install event filter for `spy1` again, which reorders spy1 in `eventFilters` + // (the list doesn't have duplicates). + object.installEventFilter(&spy1); + + QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1))); + QCoreApplication::processEvents(); + + checkExpected(); + if (QTest::currentTestFailed()) + return; + + checkCallOrder(spy2, spy3, spy1); + if (QTest::currentTestFailed()) + return; + + clearSignalSpies(); + + object.removeEventFilter(&spy3); + + QCoreApplication::postEvent(&object, new QEvent(QEvent::Type(QEvent::User + 1))); + QCoreApplication::processEvents(); + + QVERIFY(spy3.eventList().isEmpty()); + QCOMPARE(spy1.eventList(), expected); + QCOMPARE(spy2.eventList(), expected); + + QVERIFY(spy2.timeStamp > spy1.timeStamp); +} + class EmitThread : public QThread { Q_OBJECT public: diff --git a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp index a2fbd9d54d6..3e9d3e2a156 100644 --- a/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/corelib/serialization/qdatastream/tst_qdatastream.cpp @@ -2998,6 +2998,8 @@ void tst_QDataStream::status_QBitArray_data() QTest::newRow("badsize 16") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x10\xff", 5) << (int) QDataStream::ReadPastEnd << QBitArray(); QTest::newRow("badsize 17") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x11\xff\xff", 6) << (int) QDataStream::ReadPastEnd << QBitArray(); QTest::newRow("badsize 32") << QDataStream::Qt_5_15 << QByteArray("\x00\x00\x00\x20\xff\xff\xff", 7) << (int) QDataStream::ReadPastEnd << QBitArray(); + QTest::newRow("badsize INT_MAX") << QDataStream::Qt_5_15 << QByteArray("\x7f\xff\xff\xff\xff\xff\xff", 7) << int(QDataStream::ReadPastEnd) << QBitArray(); // size accepted + QTest::addRow("badsize INT_MAX + 1") << QDataStream::Qt_5_15 << QByteArray("\x80\x00\x00\x01" "\xff\xff\xff", 7) << int(QDataStream::ReadCorruptData) << QBitArray(); // size rejected QTest::newRow("new badsize 0") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x00", 4) << (int) QDataStream::ReadPastEnd << QBitArray(); QTest::newRow("new badsize 9") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x00\x00\x00\x00\x09\xff", 9) << (int) QDataStream::ReadPastEnd << QBitArray(); QTest::newRow("new badsize 0x10000") << QDataStream::Qt_6_0 << QByteArray("\x00\x00\x00\x01\x00\x00\x00\x00\x00", 9) << (int) QDataStream::ReadPastEnd << QBitArray(); diff --git a/tests/auto/corelib/text/qstring/tst_qstring.cpp b/tests/auto/corelib/text/qstring/tst_qstring.cpp index 7ea7c4ba0aa..5e153641f93 100644 --- a/tests/auto/corelib/text/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/text/qstring/tst_qstring.cpp @@ -334,7 +334,8 @@ private: class TransientDefaultLocale { - const QLocale prior; // Records what *was* the default before we set it. + // This default-constructed QLocale records what *was* the default before we changed it: + const QLocale prior = {}; public: TransientDefaultLocale(const QLocale &transient) { revise(transient); } void revise(const QLocale &transient) { QLocale::setDefault(transient); } diff --git a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp index 79943a99eb6..927bf618123 100644 --- a/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp +++ b/tests/auto/corelib/tools/qbitarray/tst_qbitarray.cpp @@ -32,6 +32,9 @@ #include "qbitarray.h" +#include +#include + /** * Helper function to initialize a bitarray from a string */ @@ -55,6 +58,7 @@ class tst_QBitArray : public QObject { Q_OBJECT private slots: + void canHandleIntMaxBits(); void size_data(); void size(); void countBits_data(); @@ -91,6 +95,54 @@ private slots: void toUInt32(); }; +void tst_QBitArray::canHandleIntMaxBits() +{ + QElapsedTimer timer; + timer.start(); + const auto print = qScopeGuard([&] { + qDebug("Function took %lldms", qlonglong(timer.elapsed())); + }); + + try { + constexpr qsizetype Size1 = sizeof(void*) > sizeof(int) ? qsizetype(INT_MAX) + 2 : + INT_MAX - 2; + constexpr qsizetype Size2 = Size1 + 2; + + QBitArray ba(Size1, true); + QCOMPARE(ba.size(), Size1); + QCOMPARE(ba.at(Size1 - 1), true); + + ba.resize(Size2); + QCOMPARE(ba.size(), Size2); + QCOMPARE(ba.at(Size1 - 1), true); + QCOMPARE(ba.at(Size1), false); + QCOMPARE(ba.at(Size2 - 1), false); + + QByteArray serialized; + if constexpr (sizeof(void*) > sizeof(int)) { + QDataStream ds(&serialized, QIODevice::WriteOnly); + ds.setVersion(QDataStream::Qt_5_15); + ds << ba; + QCOMPARE(ds.status(), QDataStream::Status::WriteFailed); // ### SizeLimitExceeded + serialized.clear(); + } + { + QDataStream ds(&serialized, QIODevice::WriteOnly); + ds << ba; + QCOMPARE(ds.status(), QDataStream::Status::Ok); + } + { + QDataStream ds(serialized); + QBitArray ba2; + ds >> ba2; + QCOMPARE(ds.status(), QDataStream::Status::Ok); + QCOMPARE(ba, ba2); + } + } catch (const std::bad_alloc &) { + QSKIP("Failed to allocate sufficient memory"); + } +} + void tst_QBitArray::size_data() { //create the testtable instance and define the elements diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp index 5abc164e1ad..35619d1bd8e 100644 --- a/tests/auto/gui/image/qimage/tst_qimage.cpp +++ b/tests/auto/gui/image/qimage/tst_qimage.cpp @@ -130,6 +130,8 @@ private slots: void smoothScaleAlpha(); void smoothScaleFormats_data(); void smoothScaleFormats(); + void smoothScaleNoConversion_data(); + void smoothScaleNoConversion(); void transformed_data(); void transformed(); @@ -2062,6 +2064,24 @@ void tst_QImage::smoothScaleFormats() QVERIFY(rotated.hasAlphaChannel()); } +void tst_QImage::smoothScaleNoConversion_data() +{ + QTest::addColumn("format"); + QTest::addRow("Mono") << QImage::Format_Mono; + QTest::addRow("MonoLSB") << QImage::Format_MonoLSB; + QTest::addRow("Indexed8") << QImage::Format_Indexed8; +} + +void tst_QImage::smoothScaleNoConversion() +{ + QFETCH(QImage::Format, format); + QImage img(128, 128, format); + img.fill(1); + img.setColorTable(QList() << qRgba(255,0,0,255) << qRgba(0,0,0,0)); + img = img.scaled(QSize(48, 48), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + QVERIFY(img.hasAlphaChannel()); +} + static int count(const QImage &img, int x, int y, int dx, int dy, QRgb pixel) { int i = 0; diff --git a/tests/auto/gui/kernel/qbackingstore/tst_qbackingstore.cpp b/tests/auto/gui/kernel/qbackingstore/tst_qbackingstore.cpp index de35943c6c2..f10bfac64e4 100644 --- a/tests/auto/gui/kernel/qbackingstore/tst_qbackingstore.cpp +++ b/tests/auto/gui/kernel/qbackingstore/tst_qbackingstore.cpp @@ -55,6 +55,8 @@ private slots: void scroll(); void flush(); + + void staticContents(); }; void tst_QBackingStore::initTestCase_data() @@ -292,5 +294,79 @@ void tst_QBackingStore::flush() QTRY_VERIFY(window.isExposed()); } +void tst_QBackingStore::staticContents() +{ +#if !defined(Q_OS_WIN) + QSKIP("Platform does not support static backingstore content"); +#endif + + QWindow window; + window.create(); + + const auto dpr = window.devicePixelRatio(); + + QBackingStore backingStore(&window); + + QRect initialRect(0, 0, 100, 100); + + // Static contents without paint first should not crash + backingStore.setStaticContents(initialRect); + backingStore.resize(initialRect.size()); + QCOMPARE(backingStore.size(), initialRect.size()); + backingStore.beginPaint(QRect(0, 0, 50, 50)); + backingStore.endPaint(); + backingStore.handle()->toImage(); + + { + backingStore.setStaticContents(QRect()); + backingStore.beginPaint(initialRect); + QPainter p(backingStore.paintDevice()); + p.fillRect(initialRect, Qt::green); + p.end(); + backingStore.endPaint(); + + QImage image = backingStore.handle()->toImage(); + if (image.isNull()) + QSKIP("Platform backingstore does not implement toImage"); + + QCOMPARE(image.pixelColor(initialRect.topLeft() * dpr), Qt::green); + QCOMPARE(image.pixelColor(initialRect.bottomLeft() * dpr), Qt::green); + QCOMPARE(image.pixelColor(initialRect.topRight() * dpr), Qt::green); + QCOMPARE(image.pixelColor(initialRect.bottomRight() * dpr), Qt::green); + } + + { + backingStore.setStaticContents(initialRect); + + QRect resizedRect(0, 0, 200, 200); + backingStore.resize(resizedRect.size()); + + QRegion repaintRegion = QRegion(resizedRect) - QRegion(initialRect); + + backingStore.beginPaint(repaintRegion); + QPainter p(backingStore.paintDevice()); + for (auto repaintRect : repaintRegion) + p.fillRect(repaintRect, Qt::red); + p.end(); + backingStore.endPaint(); + + QImage image = backingStore.handle()->toImage(); + if (image.isNull()) + QSKIP("Platform backingstore does not implement toImage"); + + QCOMPARE(image.pixelColor(initialRect.topLeft() * dpr), Qt::green); + QCOMPARE(image.pixelColor(initialRect.bottomLeft() * dpr), Qt::green); + QCOMPARE(image.pixelColor(initialRect.topRight() * dpr), Qt::green); + QCOMPARE(image.pixelColor(initialRect.bottomRight() * dpr), Qt::green); + + for (auto repaintRect : repaintRegion) { + QCOMPARE(image.pixelColor(repaintRect.topLeft() * dpr), Qt::red); + QCOMPARE(image.pixelColor(repaintRect.bottomLeft() * dpr), Qt::red); + QCOMPARE(image.pixelColor(repaintRect.topRight() * dpr), Qt::red); + QCOMPARE(image.pixelColor(repaintRect.bottomRight() * dpr), Qt::red); + } + } +} + #include QTEST_MAIN(tst_QBackingStore); diff --git a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp index 03d97470c13..f6129e264cb 100644 --- a/tests/auto/gui/painting/qpainter/tst_qpainter.cpp +++ b/tests/auto/gui/painting/qpainter/tst_qpainter.cpp @@ -87,6 +87,7 @@ private slots: #endif void drawPixmapFragments(); void drawPixmapNegativeScale(); + void drawPixmapRounding(); void drawLine_data(); void drawLine(); @@ -769,6 +770,16 @@ void tst_QPainter::drawPixmapNegativeScale() QVERIFY(resultImage.pixel(12, 8) == qRgba(0, 0, 0, 255)); // and right strip is now black } +void tst_QPainter::drawPixmapRounding() +{ + // Just test that we don't assert + QBitmap bm(8, 8); + QImage out(64, 64, QImage::Format_RGB32); + QPainter p(&out); + qreal y = 26.499999999999996; + p.drawPixmap(QPointF(0, y), bm); +} + void tst_QPainter::drawLine_data() { QTest::addColumn("line"); diff --git a/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md b/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md index 7a0d5388adf..e784879326f 100644 --- a/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md +++ b/tests/auto/gui/text/qtextmarkdownimporter/data/thematicBreaks.md @@ -11,6 +11,7 @@ stars stars with tabs between *** stars with whitespace after + --- hyphens with whitespace after _____ diff --git a/tests/auto/gui/util/qtexturefilereader/CMakeLists.txt b/tests/auto/gui/util/qtexturefilereader/CMakeLists.txt index de809f577d6..9d764dd4369 100644 --- a/tests/auto/gui/util/qtexturefilereader/CMakeLists.txt +++ b/tests/auto/gui/util/qtexturefilereader/CMakeLists.txt @@ -18,6 +18,7 @@ set(qtexturefilereader_resource_files "texturefiles/car_mips.ktx" "texturefiles/cubemap_float32_rgba.ktx" "texturefiles/cubemap_metadata.ktx" + "texturefiles/invalid.ktx" "texturefiles/newlogo.astc" "texturefiles/newlogo_srgb.astc" "texturefiles/pattern.pkm" diff --git a/tests/auto/gui/util/qtexturefilereader/texturefiles/invalid.ktx b/tests/auto/gui/util/qtexturefilereader/texturefiles/invalid.ktx new file mode 100644 index 00000000000..68a92221db3 Binary files /dev/null and b/tests/auto/gui/util/qtexturefilereader/texturefiles/invalid.ktx differ diff --git a/tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp b/tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp index 89144eb245e..00673ab0de8 100644 --- a/tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp +++ b/tests/auto/gui/util/qtexturefilereader/tst_qtexturefilereader.cpp @@ -36,6 +36,7 @@ class tst_qtexturefilereader : public QObject private slots: void checkHandlers_data(); void checkHandlers(); + void checkInvalid(); void checkMetadata(); }; @@ -165,6 +166,18 @@ void tst_qtexturefilereader::checkMetadata() QCOMPARE(kvs.value("test C"), QByteArrayLiteral("3\x0000")); } +void tst_qtexturefilereader::checkInvalid() +{ + QFile f(":/texturefiles/invalid.ktx"); + QVERIFY(f.open(QIODevice::ReadOnly)); + QTextureFileReader r(&f); + QTextureFileData d = r.read(); + auto kvs = d.keyValueMetadata(); + + // Basically just checking that we don't crash on and invalid file + QVERIFY(kvs.empty()); +} + QTEST_MAIN(tst_qtexturefilereader) #include "tst_qtexturefilereader.moc" diff --git a/tests/auto/network/access/http2/http2srv.cpp b/tests/auto/network/access/http2/http2srv.cpp index 9e19b76a9dc..2280a8633ac 100644 --- a/tests/auto/network/access/http2/http2srv.cpp +++ b/tests/auto/network/access/http2/http2srv.cpp @@ -130,6 +130,12 @@ void Http2Server::setAuthenticationHeader(const QByteArray &authentication) authenticationHeader = authentication; } +void Http2Server::setAuthenticationRequired(bool enable) +{ + Q_ASSERT(!enable || authenticationHeader.isEmpty()); + authenticationRequired = enable; +} + void Http2Server::setRedirect(const QByteArray &url, int count) { redirectUrl = url; @@ -889,7 +895,8 @@ void Http2Server::sendResponse(quint32 streamID, bool emptyBody) } else if (!authenticationHeader.isEmpty() && !hasAuth) { header.push_back({ ":status", "401" }); header.push_back(HPack::HeaderField("www-authenticate", authenticationHeader)); - authenticationHeader.clear(); + } else if (authenticationRequired) { + header.push_back({ ":status", "401" }); } else { header.push_back({":status", "200"}); } diff --git a/tests/auto/network/access/http2/http2srv.h b/tests/auto/network/access/http2/http2srv.h index 7c8810003c0..5da82a0217c 100644 --- a/tests/auto/network/access/http2/http2srv.h +++ b/tests/auto/network/access/http2/http2srv.h @@ -90,6 +90,8 @@ public: void setContentEncoding(const QByteArray &contentEncoding); // No authentication data is generated for the method, the full header value must be set void setAuthenticationHeader(const QByteArray &authentication); + // Authentication always required, no challenge provided + void setAuthenticationRequired(bool enable); // Set the redirect URL and count. The server will return a redirect response with the url // 'count' amount of times void setRedirect(const QByteArray &redirectUrl, int count); @@ -227,6 +229,7 @@ private: QByteArray contentEncoding; QByteArray authenticationHeader; + bool authenticationRequired = false; QByteArray redirectUrl; int redirectCount = 0; diff --git a/tests/auto/network/access/http2/tst_http2.cpp b/tests/auto/network/access/http2/tst_http2.cpp index 36a89c1059b..f7ab3ea7e0c 100644 --- a/tests/auto/network/access/http2/tst_http2.cpp +++ b/tests/auto/network/access/http2/tst_http2.cpp @@ -1001,13 +1001,18 @@ void tst_Http2::authenticationRequired_data() { QTest::addColumn("success"); QTest::addColumn("responseHEADOnly"); + QTest::addColumn("withChallenge"); - QTest::addRow("failed-auth") << false << true; - QTest::addRow("successful-auth") << true << true; + QTest::addRow("failed-auth") << false << true << true; + QTest::addRow("successful-auth") << true << true << true; // Include a DATA frame in the response from the remote server. An example would be receiving a // JSON response on a request along with the 401 error. - QTest::addRow("failed-auth-with-response") << false << false; - QTest::addRow("successful-auth-with-response") << true << false; + QTest::addRow("failed-auth-with-response") << false << false << true; + QTest::addRow("successful-auth-with-response") << true << false << true; + + // Don't provide a challenge header. This is valid if you are actually just + // denied access for whatever reason. + QTest::addRow("no-challenge") << false << false << false; } void tst_Http2::authenticationRequired() @@ -1018,10 +1023,15 @@ void tst_Http2::authenticationRequired() POSTResponseHEADOnly = responseHEADOnly; QFETCH(const bool, success); + QFETCH(const bool, withChallenge); ServerPtr targetServer(newServer(defaultServerSettings, defaultConnectionType())); - targetServer->setResponseBody("Hello"); - targetServer->setAuthenticationHeader("Basic realm=\"Shadow\""); + QByteArray responseBody = "Hello"; + targetServer->setResponseBody(responseBody); + if (withChallenge) + targetServer->setAuthenticationHeader("Basic realm=\"Shadow\""); + else + targetServer->setAuthenticationRequired(true); QMetaObject::invokeMethod(targetServer.data(), "startServer", Qt::QueuedConnection); runEventLoop(); @@ -1056,24 +1066,30 @@ void tst_Http2::authenticationRequired() receivedBody += body; }); - if (success) + if (success) { connect(reply.get(), &QNetworkReply::finished, this, &tst_Http2::replyFinished); - else - connect(reply.get(), &QNetworkReply::errorOccurred, this, &tst_Http2::replyFinishedWithError); + } else { + // Use queued connection so that the finished signal can be emitted and the isFinished + // property can be set. + connect(reply.get(), &QNetworkReply::errorOccurred, this, + &tst_Http2::replyFinishedWithError, Qt::QueuedConnection); + } // Since we're using self-signed certificates, // ignore SSL errors: reply->ignoreSslErrors(); runEventLoop(); STOP_ON_FAILURE + QVERIFY2(reply->isFinished(), + "The reply should error out if authentication fails, or finish if it succeeds"); if (!success) QCOMPARE(reply->error(), QNetworkReply::AuthenticationRequiredError); // else: no error (is checked in tst_Http2::replyFinished) - QVERIFY(authenticationRequested); + QVERIFY(authenticationRequested || !withChallenge); - const auto isAuthenticated = [](QByteArray bv) { + const auto isAuthenticated = [](const QByteArray &bv) { return bv == "Basic YWRtaW46YWRtaW4="; // admin:admin }; // Get the "authorization" header out from the server and make sure it's as expected: @@ -1081,6 +1097,16 @@ void tst_Http2::authenticationRequired() QCOMPARE(isAuthenticated(reqAuthHeader), success); if (success) QCOMPARE(receivedBody, expectedBody); + if (responseHEADOnly) { + const QVariant contentLenHeader = reply->header(QNetworkRequest::ContentLengthHeader); + QVERIFY2(!contentLenHeader.isValid(), "We expect no DATA frames to be received"); + QCOMPARE(reply->readAll(), QByteArray()); + } else { + const qint32 contentLen = reply->header(QNetworkRequest::ContentLengthHeader).toInt(); + QCOMPARE(contentLen, responseBody.length()); + QCOMPARE(reply->bytesAvailable(), responseBody.length()); + QCOMPARE(reply->readAll(), QByteArray("Hello")); + } // In the `!success` case we need to wait for the server to emit this or it might cause issues // in the next test running after this. In the `success` case we anyway expect it to have been // received. diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 6f6bbb8ae13..96c6eac9da8 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -3795,6 +3795,7 @@ void tst_QAccessibility::bridgeTest() // For now this is a simple test to see if the bridge is working at all. // Ideally it should be extended to test all aspects of the bridge. #if defined(Q_OS_WIN) + auto guard = qScopeGuard([]() { QTestAccessibility::clearEvents(); }); QWidget window; QVBoxLayout *lay = new QVBoxLayout(&window); @@ -3932,10 +3933,105 @@ void tst_QAccessibility::bridgeTest() QCOMPARE(controlTypeId, UIA_ButtonControlTypeId); // Edit - hr = nodeList.at(2)->get_CurrentControlType(&controlTypeId); + IUIAutomationElement *uiaElement = nodeList.at(2); + hr = uiaElement->get_CurrentControlType(&controlTypeId); QVERIFY(SUCCEEDED(hr)); QCOMPARE(controlTypeId, UIA_EditControlTypeId); + // "hello world\nhow are you today?\n" + IUIAutomationTextPattern *textPattern = nullptr; + hr = uiaElement->GetCurrentPattern(UIA_TextPattern2Id, reinterpret_cast(&textPattern)); + QVERIFY(SUCCEEDED(hr)); + QVERIFY(textPattern); + + IUIAutomationTextRange *docRange = nullptr; + hr = textPattern->get_DocumentRange(&docRange); + QVERIFY(SUCCEEDED(hr)); + QVERIFY(docRange); + + IUIAutomationTextRange *textRange = nullptr; + hr = docRange->Clone(&textRange); + QVERIFY(SUCCEEDED(hr)); + QVERIFY(textRange); + int moved; + + auto rangeText = [](IUIAutomationTextRange *textRange) { + BSTR str; + QString res = "IUIAutomationTextRange::GetText() failed"; + HRESULT hr = textRange->GetText(-1, &str); + if (SUCCEEDED(hr)) { + res = QString::fromWCharArray(str); + ::SysFreeString(str); + } + return res; + }; + + // Move start endpoint past "hello " to "world" + hr = textRange->Move(TextUnit_Character, 6, &moved); + QVERIFY(SUCCEEDED(hr)); + QCOMPARE(moved, 6); + // If the range was not empty, it should be collapsed to contain a single text unit + QCOMPARE(rangeText(textRange), QString("w")); + + // Move end endpoint to end of "world" + hr = textRange->MoveEndpointByUnit(TextPatternRangeEndpoint_End, TextUnit_Character, 4, &moved); + QVERIFY(SUCCEEDED(hr)); + QCOMPARE(moved, 4); + QCOMPARE(rangeText(textRange), QString("world")); + + // MSDN: "Zero has no effect". This behavior was also verified with native controls. + hr = textRange->Move(TextUnit_Character, 0, &moved); + QVERIFY(SUCCEEDED(hr)); + QCOMPARE(moved, 0); + QCOMPARE(rangeText(textRange), QString("world")); + + hr = textRange->Move(TextUnit_Character, 1, &moved); + QVERIFY(SUCCEEDED(hr)); + QCOMPARE(rangeText(textRange), QString("o")); + + // move as far towards the end as possible + hr = textRange->Move(TextUnit_Character, 999, &moved); + QVERIFY(SUCCEEDED(hr)); + QCOMPARE(rangeText(textRange), QString("")); + + hr = textRange->MoveEndpointByUnit(TextPatternRangeEndpoint_Start, TextUnit_Character, -1, &moved); + QVERIFY(SUCCEEDED(hr)); + QCOMPARE(rangeText(textRange), QString("\n")); + + // move one forward (last possible position again) + hr = textRange->Move(TextUnit_Character, 1, &moved); + QVERIFY(SUCCEEDED(hr)); + QCOMPARE(rangeText(textRange), QString("")); + + hr = textRange->Move(TextUnit_Character, -7, &moved); + QVERIFY(SUCCEEDED(hr)); + QCOMPARE(moved, -7); + QCOMPARE(rangeText(textRange), QString("")); + // simulate moving cursor (empty range) towards (and past) the end + QString today(" today?\n"); + for (int i = 1; i < 9; ++i) { // 9 is deliberately too much + // peek one character back + hr = textRange->MoveEndpointByUnit(TextPatternRangeEndpoint_Start, TextUnit_Character, -1, &moved); + QVERIFY(SUCCEEDED(hr)); + QCOMPARE(rangeText(textRange), today.mid(i - 1, 1)); + + hr = textRange->Move(TextUnit_Character, 1, &moved); + QVERIFY(SUCCEEDED(hr)); + QCOMPARE(rangeText(textRange), today.mid(i, moved)); // when we cannot move further, moved will be 0 + + // Make the range empty again + hr = textRange->MoveEndpointByUnit(TextPatternRangeEndpoint_End, TextUnit_Character, -moved, &moved); + QVERIFY(SUCCEEDED(hr)); + + // advance the empty range + hr = textRange->Move(TextUnit_Character, 1, &moved); + QVERIFY(SUCCEEDED(hr)); + } + docRange->Release(); + textRange->Release(); + textPattern->Release(); + + // Table hr = nodeList.at(3)->get_CurrentControlType(&controlTypeId); QVERIFY(SUCCEEDED(hr)); @@ -3954,8 +4050,6 @@ void tst_QAccessibility::bridgeTest() windowElement->Release(); automation->Release(); CoUninitialize(); - - QTestAccessibility::clearEvents(); #endif } diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp index 9227cc26d38..2706a3e3c4a 100644 --- a/tests/auto/tools/moc/tst_moc.cpp +++ b/tests/auto/tools/moc/tst_moc.cpp @@ -789,6 +789,14 @@ private: }; +#define VERIFY_NO_ERRORS(proc) do { \ + auto &&p = proc; \ + const QByteArray stderr = p.readAllStandardError(); \ + QVERIFY2(stderr.isEmpty(), stderr.data()); \ + QCOMPARE(p.exitCode(), 0); \ + } while (false) + + void tst_Moc::initTestCase() { QString binpath = QLibraryInfo::path(QLibraryInfo::BinariesPath); @@ -803,10 +811,9 @@ void tst_Moc::initTestCase() QProcess proc; proc.start(qtpaths, QStringList() << "-query" << "QT_INSTALL_HEADERS"); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QByteArray output = proc.readAllStandardOutput(); QVERIFY(!output.isEmpty()); - QCOMPARE(proc.readAllStandardError(), QByteArray()); qtIncludePath = QString::fromLocal8Bit(output).trimmed(); QFileInfo fi(qtIncludePath); QVERIFY(fi.exists()); @@ -841,10 +848,9 @@ void tst_Moc::oldStyleCasts() QProcess proc; proc.start(m_moc, QStringList(m_sourceDirectory + QStringLiteral("/oldstyle-casts.h"))); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); - QCOMPARE(proc.readAllStandardError(), QByteArray()); QStringList args; args << "-c" << "-x" << "c++" << "-Wold-style-cast" << "-I" << "." @@ -855,8 +861,7 @@ void tst_Moc::oldStyleCasts() proc.closeWriteChannel(); QVERIFY(proc.waitForFinished()); - QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); #else QSKIP("Only tested on linux/gcc"); #endif @@ -913,10 +918,9 @@ void tst_Moc::inputFileNameWithDotsButNoExtension() proc.setWorkingDirectory(m_sourceDirectory + QStringLiteral("/task71021")); proc.start(m_moc, QStringList("../Header")); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); - QCOMPARE(proc.readAllStandardError(), QByteArray()); QStringList args; args << "-c" << "-x" << "c++" << "-I" << ".." @@ -927,8 +931,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension() proc.closeWriteChannel(); QVERIFY(proc.waitForFinished()); - QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); #else QSKIP("Only tested on linux/gcc"); #endif @@ -1196,11 +1199,7 @@ void tst_Moc::ignoreOptionClashes() if (!finished) qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error()); QVERIFY(finished); - if (proc.exitCode() != 0) { - qDebug() << proc.readAllStandardError(); - } - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); // If -pthread wasn't ignored, it was parsed as a prefix of "thread/", which breaks compilation. @@ -1214,7 +1213,7 @@ void tst_Moc::ignoreOptionClashes() proc.closeWriteChannel(); QVERIFY(proc.waitForFinished()); - QCOMPARE(QString::fromLocal8Bit(proc.readAllStandardError()), QString()); + VERIFY_NO_ERRORS(proc); #else QSKIP("Only tested on linux/gcc"); #endif @@ -1319,11 +1318,7 @@ void tst_Moc::frameworkSearchPath() if (!finished) qWarning("waitForFinished failed. QProcess error: %d", (int)proc.error()); QVERIFY(finished); - if (proc.exitCode() != 0) { - qDebug() << proc.readAllStandardError(); - } - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); #else QSKIP("Only tested/relevant on unixy platforms"); #endif @@ -1355,11 +1350,9 @@ void tst_Moc::templateGtGt() QProcess proc; proc.start(m_moc, QStringList(m_sourceDirectory + QStringLiteral("/template-gtgt.h"))); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); - QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError()); - QVERIFY(mocWarning.isEmpty()); #else QSKIP("Only tested on unix/gcc"); #endif @@ -1376,8 +1369,7 @@ void tst_Moc::defineMacroViaCmdline() proc.start(m_moc, args); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); #else @@ -1396,8 +1388,7 @@ void tst_Moc::defineMacroViaForcedInclude() proc.start(m_moc, args); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); #else @@ -1416,8 +1407,7 @@ void tst_Moc::defineMacroViaForcedIncludeRelative() proc.start(m_moc, args); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); #else @@ -1462,8 +1452,7 @@ void tst_Moc::environmentIncludePaths() proc.setProcessEnvironment(env); proc.start(m_moc, args); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); - QCOMPARE(proc.readAllStandardError(), QByteArray()); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); #else @@ -1870,11 +1859,10 @@ void tst_Moc::notifyError() const QString header = m_sourceDirectory + QStringLiteral("/error-on-wrong-notify.h"); proc.start(m_moc, QStringList(header)); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QCOMPARE(proc.exitStatus(), QProcess::NormalExit); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); - QCOMPARE(proc.readAllStandardError(), QByteArray()); QStringList args; args << "-c" << "-x" << "c++" << "-I" << "." @@ -3591,10 +3579,9 @@ void tst_Moc::preprocessorOnly() QProcess proc; proc.start(m_moc, QStringList() << "-E" << m_sourceDirectory + QStringLiteral("/pp-dollar-signs.h")); QVERIFY(proc.waitForFinished()); - QCOMPARE(proc.exitCode(), 0); + VERIFY_NO_ERRORS(proc); QByteArray mocOut = proc.readAllStandardOutput(); QVERIFY(!mocOut.isEmpty()); - QCOMPARE(proc.readAllStandardError(), QByteArray()); QVERIFY(mocOut.contains("$$ = parser->createFoo()")); #else @@ -4087,6 +4074,8 @@ void tst_Moc::mocJsonOutput() return "Error waiting for diff process to finish."; return diffProc.readAllStandardOutput(); #else + Q_UNUSED(actual); + Q_UNUSED(expected); return "Cannot launch diff. Please check allmocs.json and allmocs_baseline.json on disk."; #endif }; diff --git a/tests/baseline/painting/tst_baseline_painting.cpp b/tests/baseline/painting/tst_baseline_painting.cpp index 9d3ae9cdd2f..208d252a918 100644 --- a/tests/baseline/painting/tst_baseline_painting.cpp +++ b/tests/baseline/painting/tst_baseline_painting.cpp @@ -77,7 +77,7 @@ private: private slots: void initTestCase(); - void cleanupTestCase() {} + void init(); void testRasterARGB32PM_data(); void testRasterARGB32PM(); @@ -156,6 +156,11 @@ void tst_Lancelot::initTestCase() #endif } +void tst_Lancelot::init() +{ + // This gets called for every row. QSKIP if current item is blacklisted on the baseline server: + QBASELINE_SKIP_IF_BLACKLISTED; +} void tst_Lancelot::testRasterARGB32PM_data() { diff --git a/tests/baseline/shared/qbaselinetest.cpp b/tests/baseline/shared/qbaselinetest.cpp index 0af6dae95b5..d3bf5c29513 100644 --- a/tests/baseline/shared/qbaselinetest.cpp +++ b/tests/baseline/shared/qbaselinetest.cpp @@ -397,22 +397,21 @@ QTestData &newRow(const char *dataTag, quint16 checksum) return QTest::newRow(dataTag); } - -bool testImage(const QImage& img, QByteArray *msg, bool *error) +const ImageItem *findCurrentItem(QByteArray *msg, bool *error) { if (!connected && !connect(msg, error)) - return true; + return nullptr; if (QTest::currentTestFunction() != curFunction || itemList.isEmpty()) { - qWarning() << "Usage error: QBASELINE_TEST used without corresponding QBaselineTest::newRow()"; - return true; + qWarning() << "Usage error: QBASELINE_ macro used without corresponding QBaselineTest::newRow()"; + return nullptr; } if (!gotBaselines) { if (!proto.requestBaselineChecksums(QString::fromLatin1(QTest::currentTestFunction()), &itemList) || itemList.isEmpty()) { *msg = "Communication with baseline server failed: " + proto.errorMessage().toLatin1(); *error = true; - return true; + return nullptr; } gotBaselines = true; } @@ -422,10 +421,24 @@ bool testImage(const QImage& img, QByteArray *msg, bool *error) while (it != itemList.constEnd() && it->itemName != curTag) ++it; if (it == itemList.constEnd()) { - qWarning() << "Usage error: QBASELINE_TEST used without corresponding QBaselineTest::newRow() for row" << curTag; - return true; + qWarning() << "Usage error: QBASELINE_ macro used without corresponding QBaselineTest::newRow() for row" << curTag; + return nullptr; } - return compareItem(*it, img, msg, error); + return &(*it); +} + +bool testImage(const QImage &img, QByteArray *msg, bool *error) +{ + const ImageItem *item = findCurrentItem(msg, error); + return item ? compareItem(*item, img, msg, error) : true; +} + +bool isCurrentItemBlacklisted() +{ + QByteArray msg; + bool error = false; + const ImageItem *item = findCurrentItem(&msg, &error); + return item ? (item->status == ImageItem::IgnoreItem) : false; } } diff --git a/tests/baseline/shared/qbaselinetest.h b/tests/baseline/shared/qbaselinetest.h index cc9a6f53ee3..4d9c2d19b19 100644 --- a/tests/baseline/shared/qbaselinetest.h +++ b/tests/baseline/shared/qbaselinetest.h @@ -43,6 +43,7 @@ bool connectToBaselineServer(QByteArray *msg = nullptr); bool checkImage(const QImage& img, const char *name, quint16 checksum, QByteArray *msg, bool *error, int manualdatatag = 0); bool testImage(const QImage& img, QByteArray *msg, bool *error); QTestData &newRow(const char *dataTag, quint16 checksum = 0); +bool isCurrentItemBlacklisted(); bool disconnectFromBaselineServer(); bool shouldAbortIfUnstable(); } @@ -71,4 +72,10 @@ do {\ }\ } while (0) +#define QBASELINE_SKIP_IF_BLACKLISTED \ +do {\ + if (QBaselineTest::isCurrentItemBlacklisted())\ + QSKIP("Blacklisted on baseline server.");\ +} while (0) + #endif // BASELINETEST_H diff --git a/tests/benchmarks/corelib/serialization/qcborvalue/tst_bench_qcborvalue.cpp b/tests/benchmarks/corelib/serialization/qcborvalue/tst_bench_qcborvalue.cpp index 292817fcb8a..3905d7ec52a 100644 --- a/tests/benchmarks/corelib/serialization/qcborvalue/tst_bench_qcborvalue.cpp +++ b/tests/benchmarks/corelib/serialization/qcborvalue/tst_bench_qcborvalue.cpp @@ -39,10 +39,18 @@ private: template void doKeyLookup(); + template + void doConstruct(); + private slots: void keyLookupLatin1() { doKeyLookup(); } void keyLookupString() { doKeyLookup(); } void keyLookupConstCharPtr() { doKeyLookup(); }; + + void constructLatin1() { doConstruct(); } + void constructString() { doConstruct(); } + void constructStringView() { doConstruct(); } + void constructConstCharPtr() { doConstruct(); } }; template @@ -56,13 +64,28 @@ void tst_QCborValue::doKeyLookup() using Strings = SampleStrings; const Type s(Strings::key); QBENCHMARK { - const QCborValue r = v[s]; - Q_UNUSED(r); + [[maybe_unused]] const QCborValue r = v[s]; } } else { QBENCHMARK { - const QCborValue r = v[SampleStrings::key]; - Q_UNUSED(r); + [[maybe_unused]] const QCborValue r = v[SampleStrings::key]; + } + } +} + +template +void tst_QCborValue::doConstruct() +{ + if constexpr (hasValueType) { + using Char = std::remove_cv_t; + using Strings = SampleStrings; + const Type s(Strings::key); + QBENCHMARK { + [[maybe_unused]] const auto v = QCborValue{s}; + } + } else { + QBENCHMARK { + [[maybe_unused]] const auto v = QCborValue{SampleStrings::key}; } } } diff --git a/tests/benchmarks/gui/image/qimagereader/CMakeLists.txt b/tests/benchmarks/gui/image/qimagereader/CMakeLists.txt index d5084a70184..29d40d9a5ca 100644 --- a/tests/benchmarks/gui/image/qimagereader/CMakeLists.txt +++ b/tests/benchmarks/gui/image/qimagereader/CMakeLists.txt @@ -8,6 +8,7 @@ qt_internal_add_benchmark(tst_bench_qimagereader SOURCES tst_bench_qimagereader.cpp PUBLIC_LIBRARIES + Qt::CorePrivate Qt::Gui Qt::Test ) diff --git a/tests/benchmarks/gui/image/qimagereader/tst_bench_qimagereader.cpp b/tests/benchmarks/gui/image/qimagereader/tst_bench_qimagereader.cpp index 2903d5d9edb..7cdc0a2d3e8 100644 --- a/tests/benchmarks/gui/image/qimagereader/tst_bench_qimagereader.cpp +++ b/tests/benchmarks/gui/image/qimagereader/tst_bench_qimagereader.cpp @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -55,6 +56,9 @@ public slots: void initTestCase(); private slots: + void rawFactoryLoader_keyMap(); + void rawFactoryLoader_instance(); + void readImage_data(); void readImage(); @@ -70,6 +74,7 @@ private slots: private: QList< QPair > images; // filename, format QString prefix; + QFactoryLoader m_loader{QImageIOHandlerFactoryInterface_iid, "/imageformats"}; }; tst_bench_QImageReader::tst_bench_QImageReader() @@ -106,6 +111,30 @@ void tst_bench_QImageReader::initTestCase() QFAIL("Can't find images directory!"); } +void tst_bench_QImageReader::rawFactoryLoader_keyMap() +{ + if (m_loader.keyMap().isEmpty()) + QSKIP("No image plugins found."); + + QBENCHMARK { + [[maybe_unused]] auto r = m_loader.keyMap(); + } +} + +void tst_bench_QImageReader::rawFactoryLoader_instance() +{ + if (m_loader.keyMap().isEmpty()) + QSKIP("No image plugins found."); + + const auto numInstances = m_loader.keyMap().uniqueKeys().size(); + + QBENCHMARK { + for (int i = 0; i < numInstances; ++i) + delete m_loader.instance(i); + } +} + + void tst_bench_QImageReader::readImage_data() { QTest::addColumn("fileName"); diff --git a/util/cmake/pro2cmake.py b/util/cmake/pro2cmake.py index 553c569144c..7abe9d79fdb 100755 --- a/util/cmake/pro2cmake.py +++ b/util/cmake/pro2cmake.py @@ -4423,7 +4423,7 @@ def create_top_level_cmake_conf(): conf_file_name = ".cmake.conf" try: with open(conf_file_name, "x") as file: - file.write('set(QT_REPO_MODULE_VERSION "6.2.11")\n') + file.write('set(QT_REPO_MODULE_VERSION "6.2.12")\n') except FileExistsError: pass diff --git a/util/update_public_suffix_list.sh b/util/update_public_suffix_list.sh index 9f3074fa28c..6ad479363cd 100755 --- a/util/update_public_suffix_list.sh +++ b/util/update_public_suffix_list.sh @@ -1,31 +1,31 @@ #!/bin/bash -/**************************************************************************** -** -** Copyright (C) 2023 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the utils of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:COMM$ -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** $QT_END_LICENSE$ -** -** -** -** -** -** -** -** -******************************************************************************/ +#/**************************************************************************** +#** +#** Copyright (C) 2023 The Qt Company Ltd. +#** Contact: https://www.qt.io/licensing/ +#** +#** This file is part of the utils of the Qt Toolkit. +#** +#** $QT_BEGIN_LICENSE:COMM$ +#** +#** Commercial License Usage +#** Licensees holding valid commercial Qt licenses may use this file in +#** accordance with the commercial license agreement provided with the +#** Software or, alternatively, in accordance with the terms contained in +#** a written agreement between you and The Qt Company. For licensing terms +#** and conditions see https://www.qt.io/terms-conditions. For further +#** information use the contact form at https://www.qt.io/contact-us. +#** +#** $QT_END_LICENSE$ +#** +#** +#** +#** +#** +#** +#** +#** +#******************************************************************************/ # This is the Qt 6.2 version of the script. The way to update the # publicsuffix-list is very different from Qt 6.5+, but this script is @@ -115,6 +115,10 @@ run_or_die git commit -m "Update public suffix list Version $GITSHA1, fetched on $TODAY. + + +[ChangeLog][Third-Party Code] Updated the public suffix list to upstream +SHA $GITSHA1. " --edit msg "Please use topic:publicsuffix-list-$GITSHA1 when pushing."