New upstream version 10.44
authorMatthew Vernon <matthew@debian.org>
Fri, 8 Nov 2024 16:26:58 +0000 (16:26 +0000)
committerMatthew Vernon <matthew@debian.org>
Fri, 8 Nov 2024 16:26:58 +0000 (16:26 +0000)
95 files changed:
CMakeLists.txt
ChangeLog
Makefile.am
Makefile.in
NEWS
NON-AUTOTOOLS-BUILD
README
cmake/pcre2-config.cmake.in
config-cmake.h.in
configure
configure.ac
doc/html/NON-AUTOTOOLS-BUILD.txt
doc/html/README.txt
doc/html/index.html
doc/html/pcre2_set_max_pattern_compiled_length.html [new file with mode: 0644]
doc/html/pcre2api.html
doc/html/pcre2build.html
doc/html/pcre2jit.html
doc/html/pcre2pattern.html
doc/html/pcre2test.html
doc/index.html.src
doc/pcre2.txt
doc/pcre2_set_max_pattern_compiled_length.3 [new file with mode: 0644]
doc/pcre2api.3
doc/pcre2build.3
doc/pcre2demo.3
doc/pcre2jit.3
doc/pcre2pattern.3
doc/pcre2test.1
doc/pcre2test.txt
ltmain.sh
m4/libtool.m4
m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
m4/pcre2_visibility.m4
src/config.h.generic
src/pcre2.h.generic
src/pcre2.h.in
src/pcre2_compile.c
src/pcre2_context.c
src/pcre2_error.c
src/pcre2_extuni.c
src/pcre2_fuzzsupport.c
src/pcre2_intmodedep.h
src/pcre2_jit_compile.c
src/pcre2_jit_misc.c
src/pcre2_jit_simd_inc.h
src/pcre2_jit_test.c
src/pcre2_match.c
src/pcre2_tables.c
src/pcre2test.c
src/sljit/allocator_src/sljitExecAllocatorApple.c
src/sljit/allocator_src/sljitExecAllocatorCore.c
src/sljit/sljitConfigInternal.h
src/sljit/sljitLir.c
src/sljit/sljitLir.h
src/sljit/sljitNativeARM_32.c
src/sljit/sljitNativeARM_64.c
src/sljit/sljitNativeARM_T2_32.c
src/sljit/sljitNativeLOONGARCH_64.c
src/sljit/sljitNativeMIPS_32.c
src/sljit/sljitNativeMIPS_64.c
src/sljit/sljitNativeMIPS_common.c
src/sljit/sljitNativePPC_common.c
src/sljit/sljitNativeRISCV_common.c
src/sljit/sljitNativeS390X.c
src/sljit/sljitNativeX86_32.c
src/sljit/sljitNativeX86_64.c
src/sljit/sljitNativeX86_common.c
src/sljit/sljitSerialize.c [new file with mode: 0644]
testdata/testinput10
testdata/testinput2
testdata/testinput4
testdata/testinput5
testdata/testoutput10
testdata/testoutput16
testdata/testoutput17
testdata/testoutput2
testdata/testoutput4
testdata/testoutput5
testdata/testoutput8-16-2
testdata/testoutput8-16-3
testdata/testoutput8-16-4
testdata/testoutput8-32-2
testdata/testoutput8-32-3
testdata/testoutput8-32-4
testdata/testoutput8-8-2
testdata/testoutput8-8-3
testdata/testoutput8-8-4
vms/configure.com [new file with mode: 0644]
vms/openvms_readme.txt [new file with mode: 0644]
vms/pcre2.h_patch [new file with mode: 0644]
vms/stdint.h [new file with mode: 0644]

index a17a26162e3e69688dfbeb907db4233ace1d1dc4..b73ed73282aabc1586a3af2e6cfe09df94ad3c45 100644 (file)
@@ -1130,8 +1130,8 @@ FILE(GLOB html ${PROJECT_SOURCE_DIR}/doc/html/*.html)
 FILE(GLOB man1 ${PROJECT_SOURCE_DIR}/doc/*.1)
 FILE(GLOB man3 ${PROJECT_SOURCE_DIR}/doc/*.3)
 
-INSTALL(FILES ${man1} DESTINATION man/man1)
-INSTALL(FILES ${man3} DESTINATION man/man3)
+INSTALL(FILES ${man1} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
+INSTALL(FILES ${man3} DESTINATION ${CMAKE_INSTALL_MANDIR}/man3)
 INSTALL(FILES ${html} DESTINATION share/doc/pcre2/html)
 
 IF(MSVC AND INSTALL_MSVC_PDB)
index 99001da69c311268bd4e2bb58fc8d09249bf00ff..ea228c193f7566580e8be5236ef7f475328015cc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,60 @@ Change Log for PCRE2
 --------------------
 
 Before the move to GitHub, this was the only record of changes to PCRE2. Now
-there is often more detail in the pull requests.
+there is also the log of commit messages.
+
+Version 10.44 07-June-2024
+--------------------------
+
+1. If a pattern contained a variable-length lookbehind in which the first
+branch was not the one with the shortest minimum length, and the lookbehind
+contained a capturing group, and elsewhere in the pattern there was another
+lookbehind that referenced that group, the pattern was incorrectly compiled,
+leading to unpredictable results, including crashes in JIT compiling. An
+example pattern is: /(((?<=123?456456|ABC)))(?<=\2)/
+
+2. Further updates to the oss-fuzz support:
+
+   (a) Limit quantifiers for groups and classes to be no more than 10. This
+       avoids very long JIT compile times that happen in some cases when groups
+       are replicated for quantification, and very long match times when
+       classes contain a lot of non-ascii characters.
+
+   (b) Added PCRE2_EXTENDED_MORE to the list of allowed options.
+
+   (c) Arranged for text error messages to be shown in 16-bit and 32-bit modes.
+
+   (d) Made the output in standalone mode more readable.
+
+   (e) General code tidies.
+
+   (f) Limit the size of compiled patterns to 10MB (see 6 below).
+
+   (g) Do not run JIT on patterns whose compiled length is greater than 200K
+       bytes because this takes a long time, causing oss-fuzz to time out.
+
+   (h) Avoid compiling or matching twice with the same options (this could
+       happen if the input didn't set any options).
+
+3. Increase the maximum length of a name for a group from 32 to 128 because
+there is a user for whom 32 is too small.
+
+4. Cause pcre2test to output a message when pcre2_jit_compile() gives an error
+return if either jitverify or info is specified.
+
+5. Some auxiliary files for building under OpenVMS that were contributed by
+Alexey Chupahin have been installed.
+
+6. Added pcre2_set_max_pattern_compiled_length() to limit the size of compiled
+patterns.
+
+7. There was a bug in the implementation of \X caused by my (PH) misreading or
+misunderstanding one of the grapheme sequence breaking rules in Unicode Annex
+#29. A break should occur between two characters with the Extended Pictographic
+break property unless a zero-width joiner intervenes. PCRE2 was not insisting
+on the ZWJ, causing \X to match more than it should. See GitHub issue #410.
+
+8. Avoid compilation issues with proprietary compilers in UNIX since 10.43.
 
 
 Version 10.43 16-February-2024
@@ -124,7 +177,7 @@ pcre2_match() was not fully resetting all captures that had been set within a
 
 32. Changed the meaning of \w (and its synonyms) in UCP mode to match Perl. It
 now matches characters whose general categories are L or N or whose particular
-categories are Mn (non-spacing mark) or Pc (combining puntuation). The latter
+categories are Mn (non-spacing mark) or Pc (combining punctuation). The latter
 includes underscore.
 
 33. Changed the meaning of [:xdigit:] in UCP mode to match Perl. It now also
@@ -297,7 +350,7 @@ elsewhere that can never be obeyed in normal testing has been excluded from
 coverage.
 
 15. Fixed a bug in pcre2grep that could cause an extra newline to be written
-after output generaed by --output.
+after output generated by --output.
 
 16. If a file has a .bz2 extension but is not in fact compressed, pcre2grep
 should process it as a plain text file. A bug stopped this happening; now fixed
@@ -452,7 +505,7 @@ Version 10.39 29-October-2021
   that an appropriate width is chosen if pointers are 64bit wide and
   long is not (ex: Windows 64bit).
 
-  IMHO removing the cast (and therefore the possibilty of truncation)
+  IMHO removing the cast (and therefore the possibility of truncation)
   make the code cleaner and the fallback is likely portable enough
   with all 64-bit POSIX systems doing LP64 except for Windows.
 
@@ -587,7 +640,7 @@ now the same as Perl.
   quantifier was nevertheless complaining that a quantifier number was too big.
 
 5. A run of autoconf suggested that configure.ac was out-of-date with respect
-to the lastest autoconf. Running autoupdate made some valid changes, some valid
+to the latest autoconf. Running autoupdate made some valid changes, some valid
 suggestions, and also some invalid changes, which were fixed by hand. Autoconf
 now runs clean and the resulting "configure" seems to work, so I hope nothing
 is broken. Later: the requirement for autoconf 2.70 broke some automatic test
@@ -619,7 +672,7 @@ compiler. This fixes https://bugs.exim.org/show_bug.cgi?id=2578. Patch for
 Makefile.am and configure.ac by H.J. Lu. Equivalent patch for CMakeLists.txt
 invented by PH.
 
-2. Fix inifinite loop when a single byte newline is searched in JIT when
+2. Fix infinite loop when a single byte newline is searched in JIT when
 invalid utf8 mode is enabled.
 
 3. Updated CMakeLists.txt with patch from Wolfgang Stöggl (Bugzilla #2584):
@@ -732,7 +785,7 @@ after the end a repeated group, the captured substrings had their values from
 the final repetition, not from an earlier repetition that might be the
 destination of a backtrack. This feature was documented, and was carried over
 into PCRE2. However, it has now been realized that the major refactoring that
-was done for 10.30 has made this atomicizing unnecessary, and it is confusing
+was done for 10.30 has made this atomizing unnecessary, and it is confusing
 when users are unaware of it, making some patterns appear not to be working as
 expected. Capture values of recursive back references in repeated groups are
 now correctly backtracked, so this unnecessary restriction has been removed.
@@ -1895,7 +1948,7 @@ not recognize this syntax.
 7. Automatic callouts are no longer generated before and after callouts in the
 pattern.
 
-8. When pcre2test was outputing information from a callout, the caret indicator
+8. When pcre2test was outputting information from a callout, the caret indicator
 for the current position in the subject line was incorrect if it was after an
 escape sequence for a character whose code point was greater than \x{ff}.
 
@@ -2276,7 +2329,7 @@ if it fails when running the interpreter with a 16MiB stack (and if changing
 the stack size via pcre2test is possible). This avoids having to manually set a
 large stack size when testing with clang.
 
-42. Fix register overwite in JIT when SSE2 acceleration is enabled.
+42. Fix register overwrite in JIT when SSE2 acceleration is enabled.
 
 43. Detect integer overflow in pcre2test pattern and data repetition counts.
 
@@ -3029,7 +3082,7 @@ characters, for example: /(?:(?=.)|(?<!x))a/.
 7. When an (*ACCEPT) is triggered inside capturing parentheses, it arranges for
 those parentheses to be closed with whatever has been captured so far. However,
 it was failing to mark any other groups between the highest capture so far and
-the currrent group as "unset". Thus, the ovector for those groups contained
+the current group as "unset". Thus, the ovector for those groups contained
 whatever was previously there. An example is the pattern /(x)|((*ACCEPT))/ when
 matched against "abcd".
 
index ca078a6d5a1670d2d637c696ab252faab8244150..ca6a63839eb84bee18a00afd09c3ab30fb2f703d 100644 (file)
@@ -82,6 +82,7 @@ dist_html_DATA = \
   doc/html/pcre2_set_glob_separator.html \
   doc/html/pcre2_set_heap_limit.html \
   doc/html/pcre2_set_match_limit.html \
+  doc/html/pcre2_set_max_pattern_compiled_length.html \
   doc/html/pcre2_set_max_pattern_length.html \
   doc/html/pcre2_set_max_varlookbehind.html \
   doc/html/pcre2_set_offset_limit.html \
@@ -180,6 +181,7 @@ dist_man_MANS = \
   doc/pcre2_set_glob_separator.3 \
   doc/pcre2_set_heap_limit.3 \
   doc/pcre2_set_match_limit.3 \
+  doc/pcre2_set_max_pattern_compiled_length.3 \
   doc/pcre2_set_max_pattern_length.3 \
   doc/pcre2_set_max_varlookbehind.3 \
   doc/pcre2_set_offset_limit.3 \
@@ -238,9 +240,19 @@ bin_PROGRAMS =
 noinst_PROGRAMS =
 
 # Additional files to delete on 'make clean', 'make distclean',
-# and 'make maintainer-clean'.
+# and 'make maintainer-clean'. It turns out that the default is to delete only
+# those binaries that *this* configuration has created. If the configuration
+# has been changed, some binaries may not get automatically deleted. Therefore
+# we list them here.
+
+CLEANFILES = \
+  pcre2_dftables \
+  pcre2_jit_test \
+  pcre2fuzzcheck-8 \
+  pcre2fuzzcheck-16 \
+  pcre2fuzzcheck-32 \
+  pcre2demo
 
-CLEANFILES =
 DISTCLEANFILES = src/config.h.in~
 MAINTAINERCLEANFILES =
 
@@ -260,6 +272,14 @@ EXTRA_DIST += \
   NON-AUTOTOOLS-BUILD \
   HACKING
 
+# These are support files for building under VMS
+
+EXTRA_DIST += \
+  vms/configure.com \
+  vms/openvms_readme.txt \
+  vms/pcre2.h_patch \
+  vms/stdint.h
+
 # These files are used in the preparation of a release
 
 EXTRA_DIST += \
@@ -462,6 +482,7 @@ EXTRA_DIST += \
   src/sljit/sljitNativeX86_32.c \
   src/sljit/sljitNativeX86_64.c \
   src/sljit/sljitNativeX86_common.c \
+  src/sljit/sljitSerialize.c \
   src/sljit/sljitUtils.c \
   src/sljit/allocator_src/sljitExecAllocatorApple.c \
   src/sljit/allocator_src/sljitExecAllocatorCore.c \
index bfc2e8ea0948305d2366423030d92449456d5ec4..5fb3982a88c84ea767e6b2c90071d68f8f99f1cf 100644 (file)
@@ -1108,6 +1108,7 @@ dist_html_DATA = \
   doc/html/pcre2_set_glob_separator.html \
   doc/html/pcre2_set_heap_limit.html \
   doc/html/pcre2_set_match_limit.html \
+  doc/html/pcre2_set_max_pattern_compiled_length.html \
   doc/html/pcre2_set_max_pattern_length.html \
   doc/html/pcre2_set_max_varlookbehind.html \
   doc/html/pcre2_set_offset_limit.html \
@@ -1206,6 +1207,7 @@ dist_man_MANS = \
   doc/pcre2_set_glob_separator.3 \
   doc/pcre2_set_heap_limit.3 \
   doc/pcre2_set_match_limit.3 \
+  doc/pcre2_set_max_pattern_compiled_length.3 \
   doc/pcre2_set_max_pattern_length.3 \
   doc/pcre2_set_max_varlookbehind.3 \
   doc/pcre2_set_offset_limit.3 \
@@ -1254,11 +1256,16 @@ check_SCRIPTS =
 dist_noinst_SCRIPTS = RunTest $(am__append_45)
 
 # Additional files to delete on 'make clean', 'make distclean',
-# and 'make maintainer-clean'.
+# and 'make maintainer-clean'. It turns out that the default is to delete only
+# those binaries that *this* configuration has created. If the configuration
+# has been changed, some binaries may not get automatically deleted. Therefore
+# we list them here.
 
 # RunTest and RunGrepTest should clean up after themselves, but just in case
 # they don't, add their working files to CLEANFILES.
-CLEANFILES = src/pcre2_chartables.c testSinput test3input test3output \
+CLEANFILES = pcre2_dftables pcre2_jit_test pcre2fuzzcheck-8 \
+       pcre2fuzzcheck-16 pcre2fuzzcheck-32 pcre2demo \
+       src/pcre2_chartables.c testSinput test3input test3output \
        test3outputA test3outputB testtry teststdout teststderr \
        teststderrgrep testtemp1grep testtemp2grep testtrygrep \
        testNinputgrep
@@ -1272,6 +1279,8 @@ MAINTAINERCLEANFILES = src/pcre2.h.generic src/config.h.generic
 
 # These files contain maintenance information
 
+# These are support files for building under VMS
+
 # These files are used in the preparation of a release
 
 # These files are usable versions of pcre2.h and config.h that are distributed
@@ -1291,14 +1300,15 @@ MAINTAINERCLEANFILES = src/pcre2.h.generic src/config.h.generic
 # PCRE2 demonstration program. Not built automatically. The point is that the
 # users should build it themselves. So just distribute the source.
 EXTRA_DIST = m4/ax_pthread.m4 m4/pcre2_visibility.m4 \
-       NON-AUTOTOOLS-BUILD HACKING PrepareRelease CheckMan CleanTxt \
-       Detrail 132html doc/index.html.src src/pcre2.h.generic \
-       src/config.h.generic src/pcre2_ucptables.c \
-       src/pcre2_chartables.c.dist src/sljit/sljitConfig.h \
-       src/sljit/sljitConfigCPU.h src/sljit/sljitConfigInternal.h \
-       src/sljit/sljitLir.c src/sljit/sljitLir.h \
-       src/sljit/sljitNativeARM_32.c src/sljit/sljitNativeARM_64.c \
-       src/sljit/sljitNativeARM_T2_32.c \
+       NON-AUTOTOOLS-BUILD HACKING vms/configure.com \
+       vms/openvms_readme.txt vms/pcre2.h_patch vms/stdint.h \
+       PrepareRelease CheckMan CleanTxt Detrail 132html \
+       doc/index.html.src src/pcre2.h.generic src/config.h.generic \
+       src/pcre2_ucptables.c src/pcre2_chartables.c.dist \
+       src/sljit/sljitConfig.h src/sljit/sljitConfigCPU.h \
+       src/sljit/sljitConfigInternal.h src/sljit/sljitLir.c \
+       src/sljit/sljitLir.h src/sljit/sljitNativeARM_32.c \
+       src/sljit/sljitNativeARM_64.c src/sljit/sljitNativeARM_T2_32.c \
        src/sljit/sljitNativeLOONGARCH_64.c \
        src/sljit/sljitNativeMIPS_32.c src/sljit/sljitNativeMIPS_64.c \
        src/sljit/sljitNativeMIPS_common.c \
@@ -1309,7 +1319,8 @@ EXTRA_DIST = m4/ax_pthread.m4 m4/pcre2_visibility.m4 \
        src/sljit/sljitNativeRISCV_common.c \
        src/sljit/sljitNativeS390X.c src/sljit/sljitNativeX86_32.c \
        src/sljit/sljitNativeX86_64.c \
-       src/sljit/sljitNativeX86_common.c src/sljit/sljitUtils.c \
+       src/sljit/sljitNativeX86_common.c src/sljit/sljitSerialize.c \
+       src/sljit/sljitUtils.c \
        src/sljit/allocator_src/sljitExecAllocatorApple.c \
        src/sljit/allocator_src/sljitExecAllocatorCore.c \
        src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c \
diff --git a/NEWS b/NEWS
index 6129546073944f9e6a19bfb22f308a0fc9a65849..5f8dde35406358b0ef052f3ba07e686c36848d27 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,14 @@ News about PCRE2 releases
 -------------------------
 
 
+Version 10.44 07-June-2024
+--------------------------
+
+This is mostly a bug-fix and tidying release. There is one new function, to set
+a maximum size for a compiled pattern. The maximum name length for groups is
+increased to 128. Some auxiliary files for building under VMS are added.
+
+
 Version 10.43 16-February-2024
 ------------------------------
 
index c0b9eed9bbd6c121075877adda726c1b47bd6df5..851976ae23850024346195b0d8d9d9b024d62c2c 100644 (file)
@@ -13,6 +13,7 @@ This document contains the following sections:
   Building PCRE2 on Windows with Visual Studio
   Testing with RunTest.bat
   Building PCRE2 on native z/OS and z/VM
+  Building PCRE2 under VMS
 
 
 GENERAL
@@ -416,6 +417,14 @@ Everything in that location, source and executable, is in EBCDIC and native
 z/OS file formats. The port provides an API for LE languages such as COBOL and
 for the z/OS and z/VM versions of the Rexx languages.
 
+
+BUILDING PCRE2 UNDER VMS
+
+Alexey Chuphin has contributed some auxiliary files for building PCRE2 under
+OpenVMS. They are in the "vms" directory in the distribution tarball. Please
+read the file called vms/openvms_readme.txt. The pcre2test and pcre2grep
+programs contain some VMS-specific code.
+
 ===========================
-Last Updated: 15 April 2023
+Last Updated: 16 April 2024
 ===========================
diff --git a/README b/README
index 8ef6262d5f535354f77bedd17be30768540243b1..dab5e94210be04540ea6f18fcfdaceb529be1ca2 100644 (file)
--- a/README
+++ b/README
@@ -24,7 +24,6 @@ contents of this README file are:
 
   The PCRE2 APIs
   Documentation for PCRE2
-  Contributions by users of PCRE2
   Building PCRE2 on non-Unix-like systems
   Building PCRE2 without using autotools
   Building PCRE2 using autotools
@@ -944,7 +943,14 @@ The distribution should contain the files listed below.
   src/config.h.generic    ) a version of config.h for use in non-"configure"
                           )   environments
 
+(F) Auxiliary files for building PCRE2 under OpenVMS
+
+  vms/configure.com       )
+  vms/openvms_readme.txt  ) These files were contributed by a PCRE2 user.
+  vms/pcre2.h_patch       )
+  vms/stdint.h            )
+
 Philip Hazel
 Email local part: Philip.Hazel
 Email domain: gmail.com
-Last updated: 24 November 2023
+Last updated: 15 April 2024
index 12f3a35add6c7e80b148af70ab6b006863cd9141..84eebad7507ad1d7b9073fd2d049d3b692faf592 100644 (file)
@@ -49,6 +49,8 @@ else ()
   set(PCRE2_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
   if (MINGW AND PCRE2_NON_STANDARD_LIB_SUFFIX)
     set(PCRE2_SUFFIX "-0.dll")
+  elseif(MSVC)
+    set(PCRE2_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
   endif ()
 endif ()
 find_library(PCRE2_8BIT_LIBRARY NAMES ${PCRE2_PREFIX}${PCRE2_8BIT_NAME}${PCRE2_SUFFIX} ${PCRE2_PREFIX}${PCRE2_8BIT_NAME}d${PCRE2_SUFFIX} DOC "8 bit PCRE2 library")
index 48d87d57aaec337c89c9fd70e843d2086fb601db..6539d77353c1e8f7a61adba5a3748a824b4236a8 100644 (file)
@@ -50,7 +50,7 @@
 #define PCRE2GREP_BUFSIZE       @PCRE2GREP_BUFSIZE@
 #define PCRE2GREP_MAX_BUFSIZE   @PCRE2GREP_MAX_BUFSIZE@
 
-#define MAX_NAME_SIZE  32
+#define MAX_NAME_SIZE  128
 #define MAX_NAME_COUNT 10000
 
 /* end config.h for CMake builds */
index 45e873662aae5551838dd9198cb5fb801cd1ad90..fa7e664559ccad164c91c5a149d179d388e71d71 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.72 for PCRE2 10.43.
+# Generated by GNU Autoconf 2.72 for PCRE2 10.44.
 #
 #
 # Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation,
@@ -611,8 +611,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='PCRE2'
 PACKAGE_TARNAME='pcre2'
-PACKAGE_VERSION='10.43'
-PACKAGE_STRING='PCRE2 10.43'
+PACKAGE_VERSION='10.44'
+PACKAGE_STRING='PCRE2 10.44'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1454,7 +1454,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-'configure' configures PCRE2 10.43 to adapt to many kinds of systems.
+'configure' configures PCRE2 10.44 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1525,7 +1525,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of PCRE2 10.43:";;
+     short | recursive ) echo "Configuration of PCRE2 10.44:";;
    esac
   cat <<\_ACEOF
 
@@ -1711,7 +1711,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-PCRE2 configure 10.43
+PCRE2 configure 10.44
 generated by GNU Autoconf 2.72
 
 Copyright (C) 2023 Free Software Foundation, Inc.
@@ -2077,7 +2077,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by PCRE2 $as_me 10.43, which was
+It was created by PCRE2 $as_me 10.44, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -3372,7 +3372,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='pcre2'
- VERSION='10.43'
+ VERSION='10.44'
 
 
 printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -5214,8 +5214,8 @@ esac
 
 
 
-macro_version='2.4.7.4-1ec8f-dirty'
-macro_revision='2.4.7.4'
+macro_version='2.5.0.1-38c1-dirty'
+macro_revision='2.5.0.1'
 
 
 
@@ -5726,7 +5726,7 @@ if test yes = "$GCC"; then
   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
 printf %s "checking for ld used by $CC... " >&6; }
   case $host in
-  *-*-mingw*)
+  *-*-mingw* | *-*-windows*)
     # gcc leaves a trailing carriage return, which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
@@ -5855,7 +5855,7 @@ else
        # Tru64's nm complains that /dev/null is an invalid object file
        # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
        case $build_os in
-       mingw*) lt_bad_file=conftest.nm/nofile ;;
+       mingw* | windows*) lt_bad_file=conftest.nm/nofile ;;
        *) lt_bad_file=/dev/null ;;
        esac
        case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in
@@ -6088,7 +6088,7 @@ else case e in #(
     lt_cv_sys_max_cmd_len=-1;
     ;;
 
-  cygwin* | mingw* | cegcc*)
+  cygwin* | mingw* | windows* | cegcc*)
     # On Win9x/ME, this test blows up -- it succeeds, but takes
     # about 5 minutes as the teststring grows exponentially.
     # Worse, since 9x/ME are not pre-emptively multitasking,
@@ -6110,7 +6110,7 @@ else case e in #(
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
-  bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*)
+  darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*)
     # This has been around since 386BSD, at least.  Likely further.
     if test -x /sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -6253,7 +6253,7 @@ else case e in #(
   e) case $host in
   *-*-mingw* )
     case $build in
-      *-*-mingw* ) # actually msys
+      *-*-mingw* | *-*-windows* ) # actually msys
         lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
         ;;
       *-*-cygwin* )
@@ -6266,7 +6266,7 @@ else case e in #(
     ;;
   *-*-cygwin* )
     case $build in
-      *-*-mingw* ) # actually msys
+      *-*-mingw* | *-*-windows* ) # actually msys
         lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
         ;;
       *-*-cygwin* )
@@ -6302,9 +6302,9 @@ else case e in #(
   e) #assume ordinary cross tools, or native build.
 lt_cv_to_tool_file_cmd=func_convert_file_noop
 case $host in
-  *-*-mingw* )
+  *-*-mingw* | *-*-windows* )
     case $build in
-      *-*-mingw* ) # actually msys
+      *-*-mingw* | *-*-windows* ) # actually msys
         lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
         ;;
     esac
@@ -6340,7 +6340,7 @@ case $reload_flag in
 esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
-  cygwin* | mingw* | pw32* | cegcc*)
+  cygwin* | mingw* | windows* | pw32* | cegcc*)
     if test yes != "$GCC"; then
       reload_cmds=false
     fi
@@ -6362,9 +6362,8 @@ esac
 
 
 
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}file", so it can be a program name with args.
-set dummy ${ac_tool_prefix}file; ac_word=$2
+# Extract the first word of "file", so it can be a program name with args.
+set dummy file; ac_word=$2
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 printf %s "checking for $ac_word... " >&6; }
 if test ${ac_cv_prog_FILECMD+y}
@@ -6385,7 +6384,7 @@ do
   esac
     for ac_exec_ext in '' $ac_executable_extensions; do
   if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
-    ac_cv_prog_FILECMD="${ac_tool_prefix}file"
+    ac_cv_prog_FILECMD=":"
     printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -6406,66 +6405,6 @@ printf "%s\n" "no" >&6; }
 fi
 
 
-fi
-if test -z "$ac_cv_prog_FILECMD"; then
-  ac_ct_FILECMD=$FILECMD
-  # Extract the first word of "file", so it can be a program name with args.
-set dummy file; ac_word=$2
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-printf %s "checking for $ac_word... " >&6; }
-if test ${ac_cv_prog_ac_ct_FILECMD+y}
-then :
-  printf %s "(cached) " >&6
-else case e in #(
-  e) if test -n "$ac_ct_FILECMD"; then
-  ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  case $as_dir in #(((
-    '') as_dir=./ ;;
-    */) ;;
-    *) as_dir=$as_dir/ ;;
-  esac
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_FILECMD="file"
-    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi ;;
-esac
-fi
-ac_ct_FILECMD=$ac_cv_prog_ac_ct_FILECMD
-if test -n "$ac_ct_FILECMD"; then
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5
-printf "%s\n" "$ac_ct_FILECMD" >&6; }
-else
-  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
-fi
-
-  if test "x$ac_ct_FILECMD" = x; then
-    FILECMD=":"
-  else
-    case $cross_compiling:$ac_tool_warned in
-yes:)
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
-ac_tool_warned=yes ;;
-esac
-    FILECMD=$ac_ct_FILECMD
-  fi
-else
-  FILECMD="$ac_cv_prog_FILECMD"
-fi
-
 
 
 
@@ -6597,7 +6536,6 @@ lt_cv_deplibs_check_method='unknown'
 # 'none' -- dependencies not supported.
 # 'unknown' -- same as none, but documents that we really don't know.
 # 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
 # 'file_magic [[regex]]' -- check by looking for files in library path
 # that responds to the $file_magic_cmd with a given extended regex.
 # If you have 'file' or equivalent on your system and you're not sure
@@ -6624,7 +6562,7 @@ cygwin*)
   lt_cv_file_magic_cmd='func_win32_libid'
   ;;
 
-mingw* | pw32*)
+mingw* | windows* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
@@ -6724,7 +6662,7 @@ newos6*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
     lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
   else
@@ -6792,7 +6730,7 @@ file_magic_glob=
 want_nocaseglob=no
 if test "$build" = "$host"; then
   case $host_os in
-  mingw* | pw32*)
+  mingw* | windows* | pw32*)
     if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
       want_nocaseglob=yes
     else
@@ -6948,7 +6886,7 @@ else case e in #(
   e) lt_cv_sharedlib_from_linklib_cmd='unknown'
 
 case $host_os in
-cygwin* | mingw* | pw32* | cegcc*)
+cygwin* | mingw* | windows* | pw32* | cegcc*)
   # two different shell functions defined in ltmain.sh;
   # decide which one to use based on capabilities of $DLLTOOL
   case `$DLLTOOL --help 2>&1` in
@@ -7100,7 +7038,7 @@ fi
 
 # Use ARFLAGS variable as AR's operation code to sync the variable naming with
 # Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
-# higher priority because thats what people were doing historically (setting
+# higher priority because that's what people were doing historically (setting
 # ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS
 # variable obsoleted/removed.
 
@@ -7409,15 +7347,8 @@ old_postinstall_cmds='chmod 644 $oldlib'
 old_postuninstall_cmds=
 
 if test -n "$RANLIB"; then
-  case $host_os in
-  bitrig* | openbsd*)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
-    ;;
-  *)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
-    ;;
-  esac
   old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+  old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
 fi
 
 case $host_os in
@@ -7497,7 +7428,7 @@ case $host_os in
 aix*)
   symcode='[BCDT]'
   ;;
-cygwin* | mingw* | pw32* | cegcc*)
+cygwin* | mingw* | windows* | pw32* | cegcc*)
   symcode='[ABCDGISTW]'
   ;;
 hpux*)
@@ -7512,7 +7443,7 @@ osf*)
   symcode='[BCDEGQRST]'
   ;;
 solaris*)
-  symcode='[BDRT]'
+  symcode='[BCDRT]'
   ;;
 sco3.2v5*)
   symcode='[DT]'
@@ -7576,7 +7507,7 @@ $lt_c_name_lib_hook\
 # Handle CRLF in mingw tool chain
 opt_cr=
 case $build_os in
-mingw*)
+mingw* | windows*)
   opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
   ;;
 esac
@@ -7812,7 +7743,9 @@ lt_sysroot=
 case $with_sysroot in #(
  yes)
    if test yes = "$GCC"; then
-     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+     # Trim trailing / since we'll always append absolute paths and we want
+     # to avoid //, if only for less confusing output for the user.
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null | $SED 's:/\+$::'`
    fi
    ;; #(
  /*)
@@ -8029,7 +7962,7 @@ mips64*-*linux*)
   ;;
 
 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
-s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*)
   # Find out what ABI is being produced by ac_compile, and set linker
   # options accordingly.  Note that the listed cases only cover the
   # situations where additional linker options are needed (such as when
@@ -8048,7 +7981,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
          x86_64-*kfreebsd*-gnu)
            LD="${LD-ld} -m elf_i386_fbsd"
            ;;
-         x86_64-*linux*)
+         x86_64-*linux*|x86_64-gnu*)
            case `$FILECMD conftest.o` in
              *x86-64*)
                LD="${LD-ld} -m elf32_x86_64"
@@ -8077,7 +8010,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
          x86_64-*kfreebsd*-gnu)
            LD="${LD-ld} -m elf_x86_64_fbsd"
            ;;
-         x86_64-*linux*)
+         x86_64-*linux*|x86_64-gnu*)
            LD="${LD-ld} -m elf_x86_64"
            ;;
          powerpcle-*linux*)
@@ -8298,23 +8231,23 @@ fi
 test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
-if test ${lt_cv_path_mainfest_tool+y}
+if test ${lt_cv_path_manifest_tool+y}
 then :
   printf %s "(cached) " >&6
 else case e in #(
-  e) lt_cv_path_mainfest_tool=no
+  e) lt_cv_path_manifest_tool=no
   echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
   $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
   cat conftest.err >&5
   if $GREP 'Manifest Tool' conftest.out > /dev/null; then
-    lt_cv_path_mainfest_tool=yes
+    lt_cv_path_manifest_tool=yes
   fi
   rm -f conftest* ;;
 esac
 fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
-printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; }
-if test yes != "$lt_cv_path_mainfest_tool"; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_manifest_tool" >&5
+printf "%s\n" "$lt_cv_path_manifest_tool" >&6; }
+if test yes != "$lt_cv_path_manifest_tool"; then
   MANIFEST_TOOL=:
 fi
 
@@ -9063,7 +8996,7 @@ fi
 enable_win32_dll=yes
 
 case $host in
-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-cegcc*)
   if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
 set dummy ${ac_tool_prefix}as; ac_word=$2
@@ -10020,7 +9953,7 @@ lt_prog_compiler_static=
       # PIC is the default for these OSes.
       ;;
 
-    mingw* | cygwin* | pw32* | os2* | cegcc*)
+    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
@@ -10123,7 +10056,7 @@ lt_prog_compiler_static=
       esac
       ;;
 
-    mingw* | cygwin* | pw32* | os2* | cegcc*)
+    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       lt_prog_compiler_pic='-DDLL_EXPORT'
@@ -10164,6 +10097,12 @@ lt_prog_compiler_static=
        lt_prog_compiler_pic='-KPIC'
        lt_prog_compiler_static='-static'
         ;;
+      *flang)
+        # Flang compiler.
+       lt_prog_compiler_wl='-Wl,'
+       lt_prog_compiler_pic='-fPIC'
+       lt_prog_compiler_static='-static'
+        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -10635,7 +10574,7 @@ printf %s "checking whether the $compiler linker ($LD) supports shared libraries
   extract_expsyms_cmds=
 
   case $host_os in
-  cygwin* | mingw* | pw32* | cegcc*)
+  cygwin* | mingw* | windows* | pw32* | cegcc*)
     # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # Microsoft Visual C++ or Intel C++ Compiler.
@@ -10647,7 +10586,7 @@ printf %s "checking whether the $compiler linker ($LD) supports shared libraries
     # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
     with_gnu_ld=yes
     ;;
-  openbsd* | bitrig*)
+  openbsd*)
     with_gnu_ld=no
     ;;
   esac
@@ -10750,7 +10689,7 @@ _LT_EOF
       fi
       ;;
 
-    cygwin* | mingw* | pw32* | cegcc*)
+    cygwin* | mingw* | windows* | pw32* | cegcc*)
       # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
       # as there is no search path for DLLs.
       hardcode_libdir_flag_spec='-L$libdir'
@@ -10806,7 +10745,7 @@ _LT_EOF
        cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
        $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
        emximp -o $lib $output_objdir/$libname.def'
-      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       enable_shared_with_static_runtimes=yes
       file_list_spec='@'
       ;;
@@ -11297,7 +11236,7 @@ fi
       export_dynamic_flag_spec=-rdynamic
       ;;
 
-    cygwin* | mingw* | pw32* | cegcc*)
+    cygwin* | mingw* | windows* | pw32* | cegcc*)
       # When not using gcc, we currently assume that we are using
       # Microsoft Visual C++ or Intel C++ Compiler.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
        # Tell ltmain to make .dll files, not .so files.
        shrext_cmds=.dll
        # FIXME: Setting linknames here is a bad hack.
-       archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+       archive_cmds='$CC -Fe $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
        archive_expsym_cmds='if   test DEF = "`$SED -n     -e '\''s/^[   ]*//'\''     -e '\''/^\(;.*\)*$/d'\''     -e '\''s/^\(EXPORTS\|LIBRARY\)\([     ].*\)*$/DEF/p'\''     -e q     $export_symbols`" ; then
             cp "$export_symbols" "$output_objdir/$soname.def";
             echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
           else
             $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
           fi~
-          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+          $CC -Fe $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
           linknames='
        # The linker will not automatically build a static lib if we build a DLL.
        # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
@@ -11630,7 +11569,7 @@ printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; }
     *nto* | *qnx*)
       ;;
 
-    openbsd* | bitrig*)
+    openbsd*)
       if test -f /usr/libexec/ld.so; then
        hardcode_direct=yes
        hardcode_shlibpath_var=no
@@ -11673,7 +11612,7 @@ printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; }
        cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
        $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
        emximp -o $lib $output_objdir/$libname.def'
-      old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       enable_shared_with_static_runtimes=yes
       file_list_spec='@'
       ;;
@@ -12115,7 +12054,7 @@ if test yes = "$GCC"; then
     *) lt_awk_arg='/^libraries:/' ;;
   esac
   case $host_os in
-    mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
+    mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;;
     *) lt_sed_strip_eq='s|=/|/|g' ;;
   esac
   lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
@@ -12173,7 +12112,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
   # AWK program above erroneously prepends '/' to C:/dos/paths
   # for these hosts.
   case $host_os in
-    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+    mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
       $SED 's|/\([A-Za-z]:\)|\1|g'` ;;
   esac
   sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
@@ -12341,7 +12280,7 @@ bsdi[45]*)
   # libtool to hard-code these into programs
   ;;
 
-cygwin* | mingw* | pw32* | cegcc*)
+cygwin* | mingw* | windows* | pw32* | cegcc*)
   version_type=windows
   shrext_cmds=.dll
   need_version=no
@@ -12373,7 +12312,7 @@ cygwin* | mingw* | pw32* | cegcc*)
 
       sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
       ;;
-    mingw* | cegcc*)
+    mingw* | windows* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
       soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext'
       ;;
@@ -12392,7 +12331,7 @@ cygwin* | mingw* | pw32* | cegcc*)
     library_names_spec='$libname.dll.lib'
 
     case $build_os in
-    mingw*)
+    mingw* | windows*)
       sys_lib_search_path_spec=
       lt_save_ifs=$IFS
       IFS=';'
@@ -12640,7 +12579,7 @@ linux*android*)
   version_type=none # Android doesn't support versioned libraries.
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext'
+  library_names_spec='$libname$release$shared_ext $libname$shared_ext'
   soname_spec='$libname$release$shared_ext'
   finish_cmds=
   shlibpath_var=LD_LIBRARY_PATH
@@ -12652,8 +12591,9 @@ linux*android*)
   hardcode_into_libs=yes
 
   dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  hardcode_libdir_flag_spec='-L$libdir'
+  # -rpath works at least for libraries that are not overridden by
+  # libraries installed in system locations.
+  hardcode_libdir_flag_spec='$wl-rpath $wl$libdir'
   ;;
 
 # This must be glibc/ELF.
@@ -12710,7 +12650,7 @@ fi
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
+  # Ideally, we could use ldconfig to report *all* directories which are
   # searched for libraries, however this is still not possible.  Aside from not
   # being certain /sbin/ldconfig is available, command
   # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
@@ -12767,7 +12707,7 @@ newsos6)
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
   sys_lib_dlsearch_path_spec=/usr/lib
   need_lib_prefix=no
@@ -13108,7 +13048,7 @@ else
     lt_cv_dlopen_self=yes
     ;;
 
-  mingw* | pw32* | cegcc*)
+  mingw* | windows* | pw32* | cegcc*)
     lt_cv_dlopen=LoadLibrary
     lt_cv_dlopen_libs=
     ;;
@@ -14084,6 +14024,10 @@ printf "%s\n" "#define PCRE2_EXPORT __attribute__ ((visibility (\"default\")))"
 printf "%s\n" "#define PCRE2_EXPORT /**/" >>confdefs.h
 
     fi
+  else
+
+printf "%s\n" "#define PCRE2_EXPORT /**/" >>confdefs.h
+
   fi
 
 
@@ -14194,9 +14138,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 # Versioning
 
 PCRE2_MAJOR="10"
-PCRE2_MINOR="43"
+PCRE2_MINOR="44"
 PCRE2_PRERELEASE=""
-PCRE2_DATE="2024-02-16"
+PCRE2_DATE="2024-06-07"
 
 if test "$PCRE2_MINOR" = "08" -o "$PCRE2_MINOR" = "09"
 then
@@ -14325,7 +14269,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 /* end confdefs.h.  */
 
   #define SLJIT_CONFIG_AUTO 1
-  #include "src/sljit/sljitConfigInternal.h"
+  #include "src/sljit/sljitConfigCPU.h"
   #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
   #error unsupported
   #endif
@@ -16281,7 +16225,7 @@ printf "%s\n" "#define HEAP_LIMIT $with_heap_limit" >>confdefs.h
 
 
 
-printf "%s\n" "#define MAX_NAME_SIZE 32" >>confdefs.h
+printf "%s\n" "#define MAX_NAME_SIZE 128" >>confdefs.h
 
 
 
@@ -16324,13 +16268,13 @@ esac
 # are m4 variables, assigned above.
 
 EXTRA_LIBPCRE2_8_LDFLAGS="$EXTRA_LIBPCRE2_8_LDFLAGS \
-  $NO_UNDEFINED -version-info 12:0:12"
+  $NO_UNDEFINED -version-info 13:0:13"
 
 EXTRA_LIBPCRE2_16_LDFLAGS="$EXTRA_LIBPCRE2_16_LDFLAGS \
-  $NO_UNDEFINED -version-info 12:0:12"
+  $NO_UNDEFINED -version-info 13:0:13"
 
 EXTRA_LIBPCRE2_32_LDFLAGS="$EXTRA_LIBPCRE2_32_LDFLAGS \
-  $NO_UNDEFINED -version-info 12:0:12"
+  $NO_UNDEFINED -version-info 13:0:13"
 
 EXTRA_LIBPCRE2_POSIX_LDFLAGS="$EXTRA_LIBPCRE2_POSIX_LDFLAGS \
   $NO_UNDEFINED -version-info 3:5:0"
@@ -17458,7 +17402,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by PCRE2 $as_me 10.43, which was
+This file was extended by PCRE2 $as_me 10.44, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -17526,7 +17470,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-PCRE2 config.status 10.43
+PCRE2 config.status 10.44
 configured by $0, generated by GNU Autoconf 2.72,
   with options \\"\$ac_cs_config\\"
 
@@ -18665,13 +18609,13 @@ See 'config.log' for more details" "$LINENO" 5; }
 # Provide generalized library-building support services.
 # Written by Gordon Matzigkeit, 1996
 
-# Copyright (C) 2014 Free Software Foundation, Inc.
+# Copyright (C) 2024 Free Software Foundation, Inc.
 # This is free software; see the source for copying conditions.  There is NO
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 # GNU Libtool is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of of the License, or
+# the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
 #
 # As a special exception to the GNU General Public License, if you
@@ -19055,7 +18999,7 @@ hardcode_direct=$hardcode_direct
 
 # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes
 # DIR into the resulting binary and the resulting library dependency is
-# "absolute",i.e impossible to change by setting \$shlibpath_var if the
+# "absolute",i.e. impossible to change by setting \$shlibpath_var if the
 # library is relocated.
 hardcode_direct_absolute=$hardcode_direct_absolute
 
index 77b77f3b3fcb9ec0a4a0d977d1fbe5e042b85feb..6091ea4ca48a1ef24db4f47cc260660d15042076 100644 (file)
@@ -9,14 +9,14 @@ dnl The PCRE2_PRERELEASE feature is for identifying release candidates. It might
 dnl be defined as -RC2, for example. For real releases, it should be empty.
 
 m4_define(pcre2_major, [10])
-m4_define(pcre2_minor, [43])
+m4_define(pcre2_minor, [44])
 m4_define(pcre2_prerelease, [])
-m4_define(pcre2_date, [2024-02-16])
+m4_define(pcre2_date, [2024-06-07])
 
 # Libtool shared library interface versions (current:revision:age)
-m4_define(libpcre2_8_version,     [12:0:12])
-m4_define(libpcre2_16_version,    [12:0:12])
-m4_define(libpcre2_32_version,    [12:0:12])
+m4_define(libpcre2_8_version,     [13:0:13])
+m4_define(libpcre2_16_version,    [13:0:13])
+m4_define(libpcre2_32_version,    [13:0:13])
 m4_define(libpcre2_posix_version, [3:5:0])
 
 # NOTE: The CMakeLists.txt file searches for the above variables in the first
@@ -191,7 +191,7 @@ if test "$enable_jit" = "auto"; then
   CPPFLAGS=-I$srcdir
   AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
   #define SLJIT_CONFIG_AUTO 1
-  #include "src/sljit/sljitConfigInternal.h"
+  #include "src/sljit/sljitConfigCPU.h"
   #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
   #error unsupported
   #endif]])], enable_jit=yes, enable_jit=no)
@@ -883,7 +883,7 @@ AC_DEFINE_UNQUOTED([HEAP_LIMIT], [$with_heap_limit], [
   a pattern. It applies to both pcre2_match() and pcre2_dfa_match(). It does
   not apply to JIT matching. The value is in kibibytes (units of 1024 bytes).])
 
-AC_DEFINE([MAX_NAME_SIZE], [32], [
+AC_DEFINE([MAX_NAME_SIZE], [128], [
   This limit is parameterized just in case anybody ever wants to
   change it. Care must be taken if it is increased, because it guards
   against integer overflow caused by enormously large patterns.])
index c0b9eed9bbd6c121075877adda726c1b47bd6df5..851976ae23850024346195b0d8d9d9b024d62c2c 100644 (file)
@@ -13,6 +13,7 @@ This document contains the following sections:
   Building PCRE2 on Windows with Visual Studio
   Testing with RunTest.bat
   Building PCRE2 on native z/OS and z/VM
+  Building PCRE2 under VMS
 
 
 GENERAL
@@ -416,6 +417,14 @@ Everything in that location, source and executable, is in EBCDIC and native
 z/OS file formats. The port provides an API for LE languages such as COBOL and
 for the z/OS and z/VM versions of the Rexx languages.
 
+
+BUILDING PCRE2 UNDER VMS
+
+Alexey Chuphin has contributed some auxiliary files for building PCRE2 under
+OpenVMS. They are in the "vms" directory in the distribution tarball. Please
+read the file called vms/openvms_readme.txt. The pcre2test and pcre2grep
+programs contain some VMS-specific code.
+
 ===========================
-Last Updated: 15 April 2023
+Last Updated: 16 April 2024
 ===========================
index 8ef6262d5f535354f77bedd17be30768540243b1..dab5e94210be04540ea6f18fcfdaceb529be1ca2 100644 (file)
@@ -24,7 +24,6 @@ contents of this README file are:
 
   The PCRE2 APIs
   Documentation for PCRE2
-  Contributions by users of PCRE2
   Building PCRE2 on non-Unix-like systems
   Building PCRE2 without using autotools
   Building PCRE2 using autotools
@@ -944,7 +943,14 @@ The distribution should contain the files listed below.
   src/config.h.generic    ) a version of config.h for use in non-"configure"
                           )   environments
 
+(F) Auxiliary files for building PCRE2 under OpenVMS
+
+  vms/configure.com       )
+  vms/openvms_readme.txt  ) These files were contributed by a PCRE2 user.
+  vms/pcre2.h_patch       )
+  vms/stdint.h            )
+
 Philip Hazel
 Email local part: Philip.Hazel
 Email domain: gmail.com
-Last updated: 24 November 2023
+Last updated: 15 April 2024
index f056fed9e276d079f9f060a0aff72daaca21a381..e4dc78620fdb9f49cf8f7c196071abcf9ab8e76e 100644 (file)
@@ -252,8 +252,11 @@ in the library.
 <tr><td><a href="pcre2_set_match_limit.html">pcre2_set_match_limit</a></td>
     <td>&nbsp;&nbsp;Set the match limit</td></tr>
 
+<tr><td><a href="pcre2_set_max_pattern_compiled_length.html">pcre2_set_max_pattern_compiled_length</a></td>
+    <td>&nbsp;&nbsp;Set the maximum length of a compiled pattern</td></tr>
+
 <tr><td><a href="pcre2_set_max_pattern_length.html">pcre2_set_max_pattern_length</a></td>
-    <td>&nbsp;&nbsp;Set the maximum length of pattern</td></tr>
+    <td>&nbsp;&nbsp;Set the maximum length of pattern</td></tr>
 
 <tr><td><a href="pcre2_set_max_varlookbehind.html">pcre2_set_max_varlookbehind</a></td>
     <td>&nbsp;&nbsp;Set the maximum match length for a variable-length lookbehind</td></tr>
diff --git a/doc/html/pcre2_set_max_pattern_compiled_length.html b/doc/html/pcre2_set_max_pattern_compiled_length.html
new file mode 100644 (file)
index 0000000..ab570cf
--- /dev/null
@@ -0,0 +1,44 @@
+<html>
+<head>
+<title>pcre2_set_max_pattern_compiled_length specification</title>
+</head>
+<body bgcolor="#FFFFFF" text="#00005A" link="#0066FF" alink="#3399FF" vlink="#2222BB">
+<h1>pcre2_set_max_pattern_compiled_length man page</h1>
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
+<p>
+This page is part of the PCRE2 HTML documentation. It was generated
+automatically from the original man page. If there is any nonsense in it,
+please consult the man page, in case the conversion went wrong.
+<br>
+<br><b>
+SYNOPSIS
+</b><br>
+<P>
+<b>#include &#60;pcre2.h&#62;</b>
+</P>
+<P>
+<b>int pcre2_set_max_pattern_compiled_length(</b>
+<b>  pcre2_compile_context *<i>ccontext</i>, PCRE2_SIZE <i>value</i>);</b>
+</P>
+<br><b>
+DESCRIPTION
+</b><br>
+<P>
+This function sets, in a compile context, the maximum size (in bytes) for the
+memory needed to hold the compiled version of a pattern that is compiled with
+this context. The result is always zero. If a pattern that is passed to
+<b>pcre2_compile()</b> with this context needs more memory, an error is
+generated. The default is the largest number that a PCRE2_SIZE variable can
+hold, which is effectively unlimited.
+</P>
+<P>
+There is a complete description of the PCRE2 native API in the
+<a href="pcre2api.html"><b>pcre2api</b></a>
+page and a description of the POSIX API in the
+<a href="pcre2posix.html"><b>pcre2posix</b></a>
+page.
+<p>
+Return to the <a href="index.html">PCRE2 index page</a>.
+</p>
index 23997d7269a68155d86ea430455674ac7c55031e..6b60ee9fa7af415ad04b61c85c83feaeb75f9e28 100644 (file)
@@ -161,6 +161,10 @@ document for an overview of all the PCRE2 documentation.
 <b>  PCRE2_SIZE <i>value</i>);</b>
 <br>
 <br>
+<b>int pcre2_set_max_pattern_compiled_length(</b>
+<b>  pcre2_compile_context *<i>ccontext</i>, PCRE2_SIZE <i>value</i>);</b>
+<br>
+<br>
 <b>int pcre2_set_max_varlookbehind(pcre2_compile_contest *<i>ccontext</i>,</b>
 <b>"  uint32_t <i>value</i>);</b>
 <br>
@@ -874,6 +878,18 @@ external sources can limit their size. The default is the largest number that a
 PCRE2_SIZE variable can hold, which is effectively unlimited.
 <br>
 <br>
+<b>int pcre2_set_max_pattern_compiled_length(</b>
+<b>  pcre2_compile_context *<i>ccontext</i>, PCRE2_SIZE <i>value</i>);</b>
+<br>
+<br>
+This sets a maximum size, in bytes, for the memory needed to hold the compiled
+version of a pattern that is compiled with this context. If the pattern needs
+more memory, an error is generated. This facility is provided so that
+applications that accept patterns from external sources can limit the amount of
+memory they use. The default is the largest number that a PCRE2_SIZE variable
+can hold, which is effectively unlimited.
+<br>
+<br>
 <b>int pcre2_set_max_varlookbehind(pcre2_compile_contest *<i>ccontext</i>,</b>
 <b>"  uint32_t <i>value</i>);</b>
 <br>
@@ -4161,7 +4177,7 @@ Cambridge, England.
 </P>
 <br><a name="SEC43" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 27 January 2024
+Last updated: 24 April 2024
 <br>
 Copyright &copy; 1997-2024 University of Cambridge.
 <br>
index 3276a6648a1c37ee02af5122515895f7a55e3e8d..d4b0d336b08047f17b8f4c8566eba7f59860031d 100644 (file)
@@ -50,7 +50,8 @@ Autotools. Also in the distribution are files to support building using
 <a href="README.txt"><b>README</b></a>
 contains general information about building with Autotools (some of which is
 repeated below), and also has some comments about building on various operating
-systems. There is a lot more information about building PCRE2 without using
+systems. The files in the <b>vms</b> directory support building under OpenVMS.
+There is a lot more information about building PCRE2 without using
 Autotools (including information about using <b>CMake</b> and building "by
 hand") in the text file called
 <a href="NON-AUTOTOOLS-BUILD.txt"><b>NON-AUTOTOOLS-BUILD</b>.</a>
@@ -642,9 +643,9 @@ Cambridge, England.
 </P>
 <br><a name="SEC27" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 24 November 2023
+Last updated: 15 April 2024
 <br>
-Copyright &copy; 1997-2023 University of Cambridge.
+Copyright &copy; 1997-2024 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
index 8eb86f282da25285be83d4a08a937354370882a2..d97d8003ccb104fc815dd2cf3498f2c3bdb5608e 100644 (file)
@@ -52,7 +52,7 @@ JIT support is an optional feature of PCRE2. The "configure" option
 you want to use JIT. The support is limited to the following hardware
 platforms:
 <pre>
-  ARM 32-bit (v5, v7, and Thumb2)
+  ARM 32-bit (v7, and Thumb2)
   ARM 64-bit
   IBM s390x 64 bit
   Intel x86 32-bit and 64-bit
@@ -487,9 +487,9 @@ Cambridge, England.
 </P>
 <br><a name="SEC14" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 23 January 2023
+Last updated: 21 February 2024
 <br>
-Copyright &copy; 1997-2023 University of Cambridge.
+Copyright &copy; 1997-2024 University of Cambridge.
 <br>
 <p>
 Return to the <a href="index.html">PCRE2 index page</a>.
index debce8d44dd51ce8daf3270d7b39cf242fb5af2c..cf50c1a109541a06fa1d32cc71252b62ca9749ae 100644 (file)
@@ -1034,17 +1034,19 @@ L, V, LV, or LVT character; an LV or V character may be followed by a V or T
 character; an LVT or T character may be followed only by a T character.
 </P>
 <P>
-4. Do not end before extending characters or spacing marks or the "zero-width
-joiner" character. Characters with the "mark" property always have the
+4. Do not end before extending characters or spacing marks or the zero-width
+joiner (ZWJ) character. Characters with the "mark" property always have the
 "extend" grapheme breaking property.
 </P>
 <P>
 5. Do not end after prepend characters.
 </P>
 <P>
-6. Do not break within emoji modifier sequences or emoji zwj sequences. That
-is, do not break between characters with the Extended_Pictographic property.
-Extend and ZWJ characters are allowed between the characters.
+6. Do not end within emoji modifier sequences or emoji ZWJ (zero-width
+joiner) sequences. An emoji ZWJ sequence consists of a character with the
+Extended_Pictographic property, optionally followed by one or more characters
+with the Extend property, followed by the ZWJ character, followed by another
+Extended_Pictographic character.
 </P>
 <P>
 7. Do not break within emoji flag sequences. That is, do not break between
@@ -1843,7 +1845,7 @@ using the Python syntax. PCRE2 supports both the Perl and the Python syntax.
 </P>
 <P>
 In PCRE2, a capture group can be named in one of three ways: (?&#60;name&#62;...) or
-(?'name'...) as in Perl, or (?P&#60;name&#62;...) as in Python. Names may be up to 32
+(?'name'...) as in Perl, or (?P&#60;name&#62;...) as in Python. Names may be up to 128
 code units long. When PCRE2_UTF is not set, they may contain only ASCII
 alphanumeric characters and underscores, but must start with a non-digit. When
 PCRE2_UTF is set, the syntax of group names is extended to allow any Unicode
@@ -3844,7 +3846,7 @@ Cambridge, England.
 </P>
 <br><a name="SEC32" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 19 January 2024
+Last updated: 04 June 2024
 <br>
 Copyright &copy; 1997-2024 University of Cambridge.
 <br>
index fdeed5fbd829a41359bdb9e486d3d037e8ae7caa..6cc3cc317ffb1674ebaf532c844ebd3bc5b8f8cf 100644 (file)
@@ -696,7 +696,9 @@ heavily used in the test files.
       jitfast                   use JIT fast path
       jitverify                 verify JIT use
       locale=&#60;name&#62;             use this locale
-      max_pattern_length=&#60;n&#62;    set maximum pattern length
+      max_pattern_compiled      ) set maximum compiled pattern
+                 _length=&#60;n&#62;    )   length (bytes)
+      max_pattern_length=&#60;n&#62;    set maximum pattern length (code units)
       max_varlookbehind=&#60;n&#62;     set maximum variable lookbehind length
       memory                    show memory used
       newline=&#60;type&#62;            set newline type
@@ -1019,6 +1021,15 @@ The <b>max_pattern_length</b> modifier sets a limit, in code units, to the
 length of pattern that <b>pcre2_compile()</b> will accept. Breaching the limit
 causes a compilation error. The default is the largest number a PCRE2_SIZE
 variable can hold (essentially unlimited).
+</P>
+<br><b>
+Limiting the size of a compiled pattern
+</b><br>
+<P>
+The <b>max_pattern_compiled_length</b> modifier sets a limit, in bytes, to the
+amount of memory used by a compiled pattern. Breaching the limit causes a
+compilation error. The default is the largest number a PCRE2_SIZE variable can
+hold (essentially unlimited).
 <a name="posixwrapper"></a></P>
 <br><b>
 Using the POSIX wrapper API
@@ -2193,7 +2204,7 @@ Cambridge, England.
 </P>
 <br><a name="SEC21" href="#TOC1">REVISION</a><br>
 <P>
-Last updated: 27 January 2024
+Last updated: 24 April 2024
 <br>
 Copyright &copy; 1997-2024 University of Cambridge.
 <br>
index f056fed9e276d079f9f060a0aff72daaca21a381..e4dc78620fdb9f49cf8f7c196071abcf9ab8e76e 100644 (file)
@@ -252,8 +252,11 @@ in the library.
 <tr><td><a href="pcre2_set_match_limit.html">pcre2_set_match_limit</a></td>
     <td>&nbsp;&nbsp;Set the match limit</td></tr>
 
+<tr><td><a href="pcre2_set_max_pattern_compiled_length.html">pcre2_set_max_pattern_compiled_length</a></td>
+    <td>&nbsp;&nbsp;Set the maximum length of a compiled pattern</td></tr>
+
 <tr><td><a href="pcre2_set_max_pattern_length.html">pcre2_set_max_pattern_length</a></td>
-    <td>&nbsp;&nbsp;Set the maximum length of pattern</td></tr>
+    <td>&nbsp;&nbsp;Set the maximum length of pattern</td></tr>
 
 <tr><td><a href="pcre2_set_max_varlookbehind.html">pcre2_set_max_varlookbehind</a></td>
     <td>&nbsp;&nbsp;Set the maximum match length for a variable-length lookbehind</td></tr>
index e1606471f12138672dbb42c3b927b571b47448ca..85eead6e61f838ca8c8a25716863485dd23b0440 100644 (file)
@@ -283,6 +283,9 @@ PCRE2 NATIVE API COMPILE CONTEXT FUNCTIONS
        int pcre2_set_max_pattern_length(pcre2_compile_context *ccontext,
          PCRE2_SIZE value);
 
+       int pcre2_set_max_pattern_compiled_length(
+         pcre2_compile_context *ccontext, PCRE2_SIZE value);
+
        int pcre2_set_max_varlookbehind(pcre2_compile_contest *ccontext,
          uint32_t value);
 
@@ -912,6 +915,17 @@ PCRE2 CONTEXTS
        largest number that a PCRE2_SIZE variable can  hold,  which  is  effec-
        tively unlimited.
 
+       int pcre2_set_max_pattern_compiled_length(
+         pcre2_compile_context *ccontext, PCRE2_SIZE value);
+
+       This  sets  a maximum size, in bytes, for the memory needed to hold the
+       compiled version of a pattern that is compiled with  this  context.  If
+       the  pattern needs more memory, an error is generated. This facility is
+       provided so  that  applications  that  accept  patterns  from  external
+       sources  can  limit  the  amount of memory they use. The default is the
+       largest number that a PCRE2_SIZE variable can  hold,  which  is  effec-
+       tively unlimited.
+
        int pcre2_set_max_varlookbehind(pcre2_compile_contest *ccontext,
          uint32_t value);
 
@@ -3998,11 +4012,11 @@ AUTHOR
 
 REVISION
 
-       Last updated: 27 January 2024
+       Last updated: 24 April 2024
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.43                     27 January 2024                    PCRE2API(3)
+PCRE2 10.44                      24 April 2024                     PCRE2API(3)
 ------------------------------------------------------------------------------
 
 
@@ -4022,11 +4036,12 @@ BUILDING PCRE2
        CMake  instead  of configure. The text file README contains general in-
        formation about building with Autotools (some of which is repeated  be-
        low),  and  also  has some comments about building on various operating
-       systems. There is a lot more information about building  PCRE2  without
-       using  Autotools  (including information about using CMake and building
-       "by hand") in the text file  called  NON-AUTOTOOLS-BUILD.   You  should
-       consult  this  file as well as the README file if you are building in a
-       non-Unix-like environment.
+       systems. The files in the vms directory support building under OpenVMS.
+       There is a lot more information about building PCRE2 without using  Au-
+       totools  (including  information  about  using  CMake  and building "by
+       hand") in the text file called NON-AUTOTOOLS-BUILD.  You should consult
+       this file as well as the README file if you are building in a non-Unix-
+       like environment.
 
 
 PCRE2 BUILD-TIME OPTIONS
@@ -4624,11 +4639,11 @@ AUTHOR
 
 REVISION
 
-       Last updated: 24 November 2023
-       Copyright (c) 1997-2023 University of Cambridge.
+       Last updated: 15 April 2024
+       Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.43                       24 November                    PCRE2BUILD(3)
+PCRE2 10.44                      15 April 2024                   PCRE2BUILD(3)
 ------------------------------------------------------------------------------
 
 
@@ -5333,7 +5348,7 @@ AVAILABILITY OF JIT SUPPORT
        built  if  you want to use JIT. The support is limited to the following
        hardware platforms:
 
-         ARM 32-bit (v5, v7, and Thumb2)
+         ARM 32-bit (v7, and Thumb2)
          ARM 64-bit
          IBM s390x 64 bit
          Intel x86 32-bit and 64-bit
@@ -5739,11 +5754,11 @@ AUTHOR
 
 REVISION
 
-       Last updated: 23 January 2023
-       Copyright (c) 1997-2023 University of Cambridge.
+       Last updated: 21 February 2024
+       Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.43                     23 January 2023                    PCRE2JIT(3)
+PCRE2 10.43                    21 February 2024                    PCRE2JIT(3)
 ------------------------------------------------------------------------------
 
 
@@ -7355,16 +7370,17 @@ BACKSLASH
        be  followed  by  a V or T character; an LVT or T character may be fol-
        lowed only by a T character.
 
-       4. Do not end before extending  characters  or  spacing  marks  or  the
-       "zero-width  joiner" character. Characters with the "mark" property al-
+       4. Do not end before extending characters or spacing marks or the zero-
+       width joiner (ZWJ) character. Characters with the "mark"  property  al-
        ways have the "extend" grapheme breaking property.
 
        5. Do not end after prepend characters.
 
-       6. Do not break within emoji modifier sequences or emoji zwj sequences.
-       That is, do not break between characters with the Extended_Pictographic
-       property.  Extend and ZWJ characters are allowed  between  the  charac-
-       ters.
+       6.  Do not end within emoji modifier sequences or emoji ZWJ (zero-width
+       joiner) sequences. An emoji ZWJ sequence consists of a  character  with
+       the  Extended_Pictographic property, optionally followed by one or more
+       characters with the Extend property, followed  by  the  ZWJ  character,
+       followed by another Extended_Pictographic character.
 
        7.  Do not break within emoji flag sequences. That is, do not break be-
        tween regional indicator (RI) characters if there are an odd number  of
@@ -8120,8 +8136,8 @@ NAMED CAPTURE GROUPS
 
        In  PCRE2,  a  capture  group  can  be  named  in  one  of  three ways:
        (?<name>...) or (?'name'...) as in Perl, or (?P<name>...) as in Python.
-       Names may be up to 32 code units long. When PCRE2_UTF is not set,  they
-       may  contain  only  ASCII  alphanumeric characters and underscores, but
+       Names may be up to 128 code units long. When PCRE2_UTF is not set, they
+       may contain only ASCII alphanumeric  characters  and  underscores,  but
        must start with a non-digit. When PCRE2_UTF is set, the syntax of group
        names is extended to allow any Unicode letter or Unicode decimal digit.
        In other words, group names must match one of these patterns:
@@ -8129,42 +8145,42 @@ NAMED CAPTURE GROUPS
          ^[_A-Za-z][_A-Za-z0-9]*\z   when PCRE2_UTF is not set
          ^[_\p{L}][_\p{L}\p{Nd}]*\z  when PCRE2_UTF is set
 
-       References to capture groups from other parts of the pattern,  such  as
-       backreferences,  recursion,  and conditions, can all be made by name as
+       References  to  capture groups from other parts of the pattern, such as
+       backreferences, recursion, and conditions, can all be made by  name  as
        well as by number.
 
        Named capture groups are allocated numbers as well as names, exactly as
-       if the names were not present. In both PCRE2 and Perl,  capture  groups
-       are  primarily  identified  by  numbers; any names are just aliases for
+       if  the  names were not present. In both PCRE2 and Perl, capture groups
+       are primarily identified by numbers; any names  are  just  aliases  for
        these numbers. The PCRE2 API provides function calls for extracting the
-       complete name-to-number translation table from a compiled  pattern,  as
-       well  as  convenience  functions  for extracting captured substrings by
+       complete  name-to-number  translation table from a compiled pattern, as
+       well as convenience functions for  extracting  captured  substrings  by
        name.
 
-       Warning: When more than one capture group has the same number,  as  de-
+       Warning:  When  more than one capture group has the same number, as de-
        scribed in the previous section, a name given to one of them applies to
-       all  of them. Perl allows identically numbered groups to have different
+       all of them. Perl allows identically numbered groups to have  different
        names.  Consider this pattern, where there are two capture groups, both
        numbered 1:
 
          (?|(?<AA>aa)|(?<BB>bb))
 
-       Perl allows this, with both names AA and BB  as  aliases  of  group  1.
+       Perl  allows  this,  with  both  names AA and BB as aliases of group 1.
        Thus, after a successful match, both names yield the same value (either
        "aa" or "bb").
 
-       In  an attempt to reduce confusion, PCRE2 does not allow the same group
+       In an attempt to reduce confusion, PCRE2 does not allow the same  group
        number to be associated with more than one name. The example above pro-
-       vokes a compile-time error. However, there is still  scope  for  confu-
+       vokes  a  compile-time  error. However, there is still scope for confu-
        sion. Consider this pattern:
 
          (?|(?<AA>aa)|(bb))
 
        Although the second group number 1 is not explicitly named, the name AA
-       is  still an alias for any group 1. Whether the pattern matches "aa" or
+       is still an alias for any group 1. Whether the pattern matches "aa"  or
        "bb", a reference by name to group AA yields the matched string.
 
-       By default, a name must be unique within a pattern, except that  dupli-
+       By  default, a name must be unique within a pattern, except that dupli-
        cate names are permitted for groups with the same number, for example:
 
          (?|(?<AA>aa)|(?<AA>bb))
@@ -8173,10 +8189,10 @@ NAMED CAPTURE GROUPS
        NAMES option at compile time, or by the use of (?J) within the pattern,
        as described in the section entitled "Internal Option Setting" above.
 
-       Duplicate  names  can be useful for patterns where only one instance of
-       the named capture group can match. Suppose you want to match  the  name
-       of  a  weekday,  either as a 3-letter abbreviation or as the full name,
-       and in both cases you want to extract the  abbreviation.  This  pattern
+       Duplicate names can be useful for patterns where only one  instance  of
+       the  named  capture group can match. Suppose you want to match the name
+       of a weekday, either as a 3-letter abbreviation or as  the  full  name,
+       and  in  both  cases you want to extract the abbreviation. This pattern
        (ignoring the line breaks) does the job:
 
          (?J)
@@ -8186,17 +8202,17 @@ NAMED CAPTURE GROUPS
          (?<DN>Thu)(?:rsday)?|
          (?<DN>Sat)(?:urday)?
 
-       There  are five capture groups, but only one is ever set after a match.
-       The convenience functions for extracting the data by name  returns  the
-       substring  for  the first (and in this example, the only) group of that
+       There are five capture groups, but only one is ever set after a  match.
+       The  convenience  functions for extracting the data by name returns the
+       substring for the first (and in this example, the only) group  of  that
        name that matched. This saves searching to find which numbered group it
-       was. (An alternative way of solving this problem is to  use  a  "branch
+       was.  (An  alternative  way of solving this problem is to use a "branch
        reset" group, as described in the previous section.)
 
-       If  you make a backreference to a non-unique named group from elsewhere
-       in the pattern, the groups to which the name refers are checked in  the
-       order  in  which they appear in the overall pattern. The first one that
-       is set is used for the reference. For  example,  this  pattern  matches
+       If you make a backreference to a non-unique named group from  elsewhere
+       in  the pattern, the groups to which the name refers are checked in the
+       order in which they appear in the overall pattern. The first  one  that
+       is  set  is  used  for the reference. For example, this pattern matches
        both "foofoo" and "barbar" but not "foobar" or "barfoo":
 
          (?J)(?:(?<n>foo)|(?<n>bar))\k<n>
@@ -8209,15 +8225,15 @@ NAMED CAPTURE GROUPS
        If you use a named reference in a condition test (see the section about
        conditions below), either to check whether a capture group has matched,
        or to check for recursion, all groups with the same name are tested. If
-       the  condition  is  true  for any one of them, the overall condition is
-       true. This is the same behaviour as testing by number. For further  de-
-       tails  of  the  interfaces  for  handling named capture groups, see the
+       the condition is true for any one of them,  the  overall  condition  is
+       true.  This is the same behaviour as testing by number. For further de-
+       tails of the interfaces for handling  named  capture  groups,  see  the
        pcre2api documentation.
 
 
 REPETITION
 
-       Repetition is specified by quantifiers, which may  follow  any  one  of
+       Repetition  is  specified  by  quantifiers, which may follow any one of
        these items:
 
          a literal data character
@@ -8233,16 +8249,16 @@ REPETITION
 
        If a quantifier does not follow a repeatable item, an error occurs. The
        general repetition quantifier specifies a minimum and maximum number of
-       permitted  matches  by  giving  two numbers in curly brackets (braces),
-       separated by a comma. The numbers must be  less  than  65536,  and  the
+       permitted matches by giving two numbers  in  curly  brackets  (braces),
+       separated  by  a  comma.  The  numbers must be less than 65536, and the
        first must be less than or equal to the second. For example,
 
          z{2,4}
 
-       matches  "zz",  "zzz",  or  "zzzz". A closing brace on its own is not a
-       special character. If the second number is omitted, but  the  comma  is
-       present,  there  is  no upper limit; if the second number and the comma
-       are both omitted, the quantifier specifies an exact number of  required
+       matches "zz", "zzz", or "zzzz". A closing brace on its  own  is  not  a
+       special  character.  If  the second number is omitted, but the comma is
+       present, there is no upper limit; if the second number  and  the  comma
+       are  both omitted, the quantifier specifies an exact number of required
        matches. Thus
 
          [aeiou]{3,}
@@ -8251,65 +8267,65 @@ REPETITION
 
          \d{8}
 
-       matches  exactly  8  digits.  If the first number is omitted, the lower
+       matches exactly 8 digits. If the first number  is  omitted,  the  lower
        limit is taken as zero; in this case the upper limit must be present.
 
          X{,4} is interpreted as X{0,4}
 
-       This is a change in behaviour that happened in Perl  5.34.0  and  PCRE2
-       10.43.  In  earlier  versions  such a sequence was not interpreted as a
+       This  is  a  change in behaviour that happened in Perl 5.34.0 and PCRE2
+       10.43. In earlier versions such a sequence was  not  interpreted  as  a
        quantifier. Other regular expression engines may behave either way.
 
-       If the characters that follow an opening brace do not match the  syntax
+       If  the characters that follow an opening brace do not match the syntax
        of a quantifier, the brace is taken as a literal character. In particu-
        lar, this means that {,} is a literal string of three characters.
 
        Note that not every opening brace is potentially the start of a quanti-
-       fier  because  braces  are  used  in  other  items such as \N{U+345} or
+       fier because braces are used  in  other  items  such  as  \N{U+345}  or
        \k{name}.
 
        In UTF modes, quantifiers apply to characters rather than to individual
-       code units. Thus, for example, \x{100}{2} matches two characters,  each
+       code  units. Thus, for example, \x{100}{2} matches two characters, each
        of which is represented by a two-byte sequence in a UTF-8 string. Simi-
-       larly,  \X{3} matches three Unicode extended grapheme clusters, each of
-       which may be several code units long (and  they  may  be  of  different
+       larly, \X{3} matches three Unicode extended grapheme clusters, each  of
+       which  may  be  several  code  units long (and they may be of different
        lengths).
 
        The quantifier {0} is permitted, causing the expression to behave as if
        the previous item and the quantifier were not present. This may be use-
-       ful  for  capture  groups that are referenced as subroutines from else-
-       where in the pattern (but see also the section entitled "Defining  cap-
+       ful for capture groups that are referenced as  subroutines  from  else-
+       where  in the pattern (but see also the section entitled "Defining cap-
        ture groups for use by reference only" below). Except for parenthesized
-       groups,  items that have a {0} quantifier are omitted from the compiled
+       groups, items that have a {0} quantifier are omitted from the  compiled
        pattern.
 
-       For convenience, the three most common quantifiers have  single-charac-
+       For  convenience, the three most common quantifiers have single-charac-
        ter abbreviations:
 
          *    is equivalent to {0,}
          +    is equivalent to {1,}
          ?    is equivalent to {0,1}
 
-       It  is  possible  to construct infinite loops by following a group that
-       can match no characters with a quantifier that has no upper limit,  for
+       It is possible to construct infinite loops by following  a  group  that
+       can  match no characters with a quantifier that has no upper limit, for
        example:
 
          (a?)*
 
-       Earlier  versions  of  Perl  and PCRE1 used to give an error at compile
+       Earlier versions of Perl and PCRE1 used to give  an  error  at  compile
        time for such patterns. However, because there are cases where this can
        be useful, such patterns are now accepted, but whenever an iteration of
-       such a group matches no characters, matching moves on to the next  item
-       in  the  pattern  instead  of repeatedly matching an empty string. This
-       does not prevent backtracking into any of the iterations  if  a  subse-
+       such  a group matches no characters, matching moves on to the next item
+       in the pattern instead of repeatedly matching  an  empty  string.  This
+       does  not  prevent  backtracking into any of the iterations if a subse-
        quent item fails to match.
 
-       By  default,  quantifiers  are "greedy", that is, they match as much as
-       possible (up to the maximum number of permitted  repetitions),  without
-       causing  the  rest of the pattern to fail. The classic example of where
+       By default, quantifiers are "greedy", that is, they match  as  much  as
+       possible  (up  to the maximum number of permitted repetitions), without
+       causing the rest of the pattern to fail. The classic example  of  where
        this gives problems is in trying to match comments in C programs. These
-       appear between /* and */ and within the comment,  individual  *  and  /
-       characters  may  appear. An attempt to match C comments by applying the
+       appear  between  /*  and  */ and within the comment, individual * and /
+       characters may appear. An attempt to match C comments by  applying  the
        pattern
 
          /\*.*\*/
@@ -8318,17 +8334,17 @@ REPETITION
 
          /* first comment */  not comment  /* second comment */
 
-       fails, because it matches the entire string owing to the greediness  of
-       the  .*  item. However, if a quantifier is followed by a question mark,
+       fails,  because it matches the entire string owing to the greediness of
+       the .*  item. However, if a quantifier is followed by a question  mark,
        it ceases to be greedy, and instead matches the minimum number of times
        possible, so the pattern
 
          /\*.*?\*/
 
-       does the right thing with C comments. The meaning of the various  quan-
+       does  the right thing with C comments. The meaning of the various quan-
        tifiers is not otherwise changed, just the preferred number of matches.
-       Do  not  confuse this use of question mark with its use as a quantifier
-       in its own right.  Because it has two uses,  it  can  sometimes  appear
+       Do not confuse this use of question mark with its use as  a  quantifier
+       in  its  own  right.   Because it has two uses, it can sometimes appear
        doubled, as in
 
          \d??\d
@@ -8337,55 +8353,55 @@ REPETITION
        only way the rest of the pattern matches.
 
        If the PCRE2_UNGREEDY option is set (an option that is not available in
-       Perl),  the  quantifiers are not greedy by default, but individual ones
-       can be made greedy by following them with a  question  mark.  In  other
+       Perl), the quantifiers are not greedy by default, but  individual  ones
+       can  be  made  greedy  by following them with a question mark. In other
        words, it inverts the default behaviour.
 
-       When  a  parenthesized  group is quantified with a minimum repeat count
-       that is greater than 1 or with a limited maximum, more  memory  is  re-
+       When a parenthesized group is quantified with a  minimum  repeat  count
+       that  is  greater  than 1 or with a limited maximum, more memory is re-
        quired for the compiled pattern, in proportion to the size of the mini-
        mum or maximum.
 
-       If  a  pattern  starts  with  .*  or  .{0,} and the PCRE2_DOTALL option
-       (equivalent to Perl's /s) is set, thus allowing the dot to  match  new-
-       lines,  the  pattern  is  implicitly anchored, because whatever follows
-       will be tried against every character position in the  subject  string,
-       so  there is no point in retrying the overall match at any position af-
-       ter the first. PCRE2 normally treats such a pattern as though  it  were
+       If a pattern starts with  .*  or  .{0,}  and  the  PCRE2_DOTALL  option
+       (equivalent  to  Perl's /s) is set, thus allowing the dot to match new-
+       lines, the pattern is implicitly  anchored,  because  whatever  follows
+       will  be  tried against every character position in the subject string,
+       so there is no point in retrying the overall match at any position  af-
+       ter  the  first. PCRE2 normally treats such a pattern as though it were
        preceded by \A.
 
-       In  cases  where  it  is known that the subject string contains no new-
-       lines, it is worth setting PCRE2_DOTALL in order to obtain  this  opti-
+       In cases where it is known that the subject  string  contains  no  new-
+       lines,  it  is worth setting PCRE2_DOTALL in order to obtain this opti-
        mization, or alternatively, using ^ to indicate anchoring explicitly.
 
-       However,  there  are  some cases where the optimization cannot be used.
-       When .*  is inside capturing parentheses that  are  the  subject  of  a
-       backreference  elsewhere  in the pattern, a match at the start may fail
+       However, there are some cases where the optimization  cannot  be  used.
+       When  .*   is  inside  capturing  parentheses that are the subject of a
+       backreference elsewhere in the pattern, a match at the start  may  fail
        where a later one succeeds. Consider, for example:
 
          (.*)abc\1
 
-       If the subject is "xyz123abc123" the match point is the fourth  charac-
+       If  the subject is "xyz123abc123" the match point is the fourth charac-
        ter. For this reason, such a pattern is not implicitly anchored.
 
-       Another  case where implicit anchoring is not applied is when the lead-
-       ing .* is inside an atomic group. Once again, a match at the start  may
+       Another case where implicit anchoring is not applied is when the  lead-
+       ing  .* is inside an atomic group. Once again, a match at the start may
        fail where a later one succeeds. Consider this pattern:
 
          (?>.*?a)b
 
-       It  matches "ab" in the subject "aab". The use of the backtracking con-
-       trol verbs (*PRUNE) and (*SKIP) also  disable  this  optimization,  and
+       It matches "ab" in the subject "aab". The use of the backtracking  con-
+       trol  verbs  (*PRUNE)  and  (*SKIP) also disable this optimization, and
        there is an option, PCRE2_NO_DOTSTAR_ANCHOR, to do so explicitly.
 
-       When  a  capture group is repeated, the value captured is the substring
+       When a capture group is repeated, the value captured is  the  substring
        that matched the final iteration. For example, after
 
          (tweedle[dume]{3}\s*)+
 
        has matched "tweedledum tweedledee" the value of the captured substring
-       is "tweedledee". However, if there are nested capture groups, the  cor-
-       responding  captured  values  may have been set in previous iterations.
+       is  "tweedledee". However, if there are nested capture groups, the cor-
+       responding captured values may have been set  in  previous  iterations.
        For example, after
 
          (a|(b))+
@@ -8395,57 +8411,57 @@ REPETITION
 
 ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
 
-       With both maximizing ("greedy") and minimizing ("ungreedy"  or  "lazy")
-       repetition,  failure  of what follows normally causes the repeated item
-       to be re-evaluated to see if a different number of repeats  allows  the
-       rest  of  the pattern to match. Sometimes it is useful to prevent this,
-       either to change the nature of the match, or to cause it  fail  earlier
-       than  it otherwise might, when the author of the pattern knows there is
+       With  both  maximizing ("greedy") and minimizing ("ungreedy" or "lazy")
+       repetition, failure of what follows normally causes the  repeated  item
+       to  be  re-evaluated to see if a different number of repeats allows the
+       rest of the pattern to match. Sometimes it is useful to  prevent  this,
+       either  to  change the nature of the match, or to cause it fail earlier
+       than it otherwise might, when the author of the pattern knows there  is
        no point in carrying on.
 
-       Consider, for example, the pattern \d+foo when applied to  the  subject
+       Consider,  for  example, the pattern \d+foo when applied to the subject
        line
 
          123456bar
 
        After matching all 6 digits and then failing to match "foo", the normal
-       action  of  the matcher is to try again with only 5 digits matching the
-       \d+ item, and then with  4,  and  so  on,  before  ultimately  failing.
-       "Atomic  grouping"  (a  term taken from Jeffrey Friedl's book) provides
+       action of the matcher is to try again with only 5 digits  matching  the
+       \d+  item,  and  then  with  4,  and  so on, before ultimately failing.
+       "Atomic grouping" (a term taken from Jeffrey  Friedl's  book)  provides
        the means for specifying that once a group has matched, it is not to be
        re-evaluated in this way.
 
-       If we use atomic grouping for the previous example, the  matcher  gives
-       up  immediately  on failing to match "foo" the first time. The notation
+       If  we  use atomic grouping for the previous example, the matcher gives
+       up immediately on failing to match "foo" the first time.  The  notation
        is a kind of special parenthesis, starting with (?> as in this example:
 
          (?>\d+)foo
 
-       Perl 5.28 introduced an experimental alphabetic form starting  with  (*
+       Perl  5.28  introduced an experimental alphabetic form starting with (*
        which may be easier to remember:
 
          (*atomic:\d+)foo
 
-       This  kind of parenthesized group "locks up" the part of the pattern it
+       This kind of parenthesized group "locks up" the part of the pattern  it
        contains once it has matched, and a failure further into the pattern is
-       prevented from backtracking into it. Backtracking past it  to  previous
+       prevented  from  backtracking into it. Backtracking past it to previous
        items, however, works as normal.
 
        An alternative description is that a group of this type matches exactly
-       the  string  of  characters  that an identical standalone pattern would
+       the string of characters that an  identical  standalone  pattern  would
        match, if anchored at the current point in the subject string.
 
-       Atomic groups are not capture groups. Simple cases such  as  the  above
-       example  can  be  thought  of  as a maximizing repeat that must swallow
-       everything it can.  So, while both \d+ and \d+? are prepared to  adjust
-       the  number  of digits they match in order to make the rest of the pat-
+       Atomic  groups  are  not capture groups. Simple cases such as the above
+       example can be thought of as a  maximizing  repeat  that  must  swallow
+       everything  it can.  So, while both \d+ and \d+? are prepared to adjust
+       the number of digits they match in order to make the rest of  the  pat-
        tern match, (?>\d+) can only match an entire sequence of digits.
 
-       Atomic groups in general can of course contain arbitrarily  complicated
+       Atomic  groups in general can of course contain arbitrarily complicated
        expressions, and can be nested. However, when the contents of an atomic
-       group  is  just a single repeated item, as in the example above, a sim-
-       pler notation, called a "possessive quantifier" can be used. This  con-
-       sists  of  an additional + character following a quantifier. Using this
+       group is just a single repeated item, as in the example above,  a  sim-
+       pler  notation, called a "possessive quantifier" can be used. This con-
+       sists of an additional + character following a quantifier.  Using  this
        notation, the previous example can be rewritten as
 
          \d++foo
@@ -8455,46 +8471,46 @@ ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
 
          (abc|xyz){2,3}+
 
-       Possessive quantifiers are always greedy; the setting of the  PCRE2_UN-
-       GREEDY  option  is ignored. They are a convenient notation for the sim-
-       pler forms of atomic group. However, there  is  no  difference  in  the
-       meaning  of  a  possessive  quantifier and the equivalent atomic group,
-       though there may be a performance  difference;  possessive  quantifiers
+       Possessive  quantifiers are always greedy; the setting of the PCRE2_UN-
+       GREEDY option is ignored. They are a convenient notation for  the  sim-
+       pler  forms  of  atomic  group.  However, there is no difference in the
+       meaning of a possessive quantifier and  the  equivalent  atomic  group,
+       though  there  may  be a performance difference; possessive quantifiers
        should be slightly faster.
 
-       The  possessive  quantifier syntax is an extension to the Perl 5.8 syn-
-       tax.  Jeffrey Friedl originated the idea (and the name)  in  the  first
+       The possessive quantifier syntax is an extension to the Perl  5.8  syn-
+       tax.   Jeffrey  Friedl  originated the idea (and the name) in the first
        edition of his book. Mike McCloskey liked it, so implemented it when he
-       built  Sun's Java package, and PCRE1 copied it from there. It found its
+       built Sun's Java package, and PCRE1 copied it from there. It found  its
        way into Perl at release 5.10.
 
-       PCRE2 has an optimization  that  automatically  "possessifies"  certain
-       simple  pattern constructs. For example, the sequence A+B is treated as
-       A++B because there is no point in backtracking into a sequence  of  A's
+       PCRE2  has  an  optimization  that automatically "possessifies" certain
+       simple pattern constructs. For example, the sequence A+B is treated  as
+       A++B  because  there is no point in backtracking into a sequence of A's
        when B must follow.  This feature can be disabled by the PCRE2_NO_AUTO-
        POSSESS option, or starting the pattern with (*NO_AUTO_POSSESS).
 
        When a pattern contains an unlimited repeat inside a group that can it-
-       self  be  repeated  an  unlimited number of times, the use of an atomic
-       group is the only way to avoid some failing matches taking a very  long
+       self be repeated an unlimited number of times, the  use  of  an  atomic
+       group  is the only way to avoid some failing matches taking a very long
        time indeed. The pattern
 
          (\D+|<\d+>)*[!?]
 
-       matches  an  unlimited number of substrings that either consist of non-
-       digits, or digits enclosed in <>, followed by either ! or  ?.  When  it
+       matches an unlimited number of substrings that either consist  of  non-
+       digits,  or  digits  enclosed in <>, followed by either ! or ?. When it
        matches, it runs quickly. However, if it is applied to
 
          aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 
-       it  takes  a  long  time  before reporting failure. This is because the
-       string can be divided between the internal \D+ repeat and the  external
-       *  repeat in a large number of ways, and all have to be tried. (The ex-
+       it takes a long time before reporting  failure.  This  is  because  the
+       string  can be divided between the internal \D+ repeat and the external
+       * repeat in a large number of ways, and all have to be tried. (The  ex-
        ample uses [!?] rather than a single character at the end, because both
        PCRE2 and Perl have an optimization that allows for fast failure when a
-       single character is used. They remember the last single character  that
-       is  required  for  a  match, and fail early if it is not present in the
-       string.) If the pattern is changed so that it  uses  an  atomic  group,
+       single  character is used. They remember the last single character that
+       is required for a match, and fail early if it is  not  present  in  the
+       string.)  If  the  pattern  is changed so that it uses an atomic group,
        like this:
 
          ((?>\D+)|<\d+>)*[!?]
@@ -8505,28 +8521,28 @@ ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
 BACKREFERENCES
 
        Outside a character class, a backslash followed by a digit greater than
-       0  (and  possibly further digits) is a backreference to a capture group
+       0 (and possibly further digits) is a backreference to a  capture  group
        earlier (that is, to its left) in the pattern, provided there have been
        that many previous capture groups.
 
-       However, if the decimal number following the backslash is less than  8,
-       it  is  always  taken  as  a backreference, and causes an error only if
-       there are not that many capture groups in the entire pattern. In  other
+       However,  if the decimal number following the backslash is less than 8,
+       it is always taken as a backreference, and  causes  an  error  only  if
+       there  are not that many capture groups in the entire pattern. In other
        words, the group that is referenced need not be to the left of the ref-
-       erence  for numbers less than 8. A "forward backreference" of this type
+       erence for numbers less than 8. A "forward backreference" of this  type
        can make sense when a repetition is involved and the group to the right
        has participated in an earlier iteration.
 
-       It is not possible to have a numerical  "forward  backreference"  to  a
-       group  whose  number  is 8 or more using this syntax because a sequence
-       such as \50 is interpreted as a character defined  in  octal.  See  the
+       It  is  not  possible  to have a numerical "forward backreference" to a
+       group whose number is 8 or more using this syntax  because  a  sequence
+       such  as  \50  is  interpreted as a character defined in octal. See the
        subsection entitled "Non-printing characters" above for further details
-       of  the  handling of digits following a backslash. Other forms of back-
-       referencing do not suffer from this restriction. In  particular,  there
+       of the handling of digits following a backslash. Other forms  of  back-
+       referencing  do  not suffer from this restriction. In particular, there
        is no problem when named capture groups are used (see below).
 
-       Another  way  of  avoiding  the ambiguity inherent in the use of digits
-       following a backslash is to use the \g  escape  sequence.  This  escape
+       Another way of avoiding the ambiguity inherent in  the  use  of  digits
+       following  a  backslash  is  to use the \g escape sequence. This escape
        must be followed by a signed or unsigned number, optionally enclosed in
        braces. These examples are all identical:
 
@@ -8534,54 +8550,54 @@ BACKREFERENCES
          (ring), \g1
          (ring), \g{1}
 
-       An  unsigned number specifies an absolute reference without the ambigu-
+       An unsigned number specifies an absolute reference without the  ambigu-
        ity that is present in the older syntax. It is also useful when literal
-       digits follow the reference. A signed number is a  relative  reference.
+       digits  follow  the reference. A signed number is a relative reference.
        Consider this example:
 
          (abc(def)ghi)\g{-1}
 
        The sequence \g{-1} is a reference to the capture group whose number is
-       one  less  than  the number of the next group to be started, so in this
-       example (where the next group would be numbered 3) is it equivalent  to
-       \2,  and  \g{-2} would be equivalent to \1. Note that if this construct
-       is inside a capture group, that group is included in the count,  so  in
+       one less than the number of the next group to be started,  so  in  this
+       example  (where the next group would be numbered 3) is it equivalent to
+       \2, and \g{-2} would be equivalent to \1. Note that if  this  construct
+       is  inside  a capture group, that group is included in the count, so in
        this example \g{-2} also refers to group 1:
 
          (A)(\g{-2}B)
 
-       The  use  of  relative  references can be helpful in long patterns, and
-       also in patterns that are created by joining  together  fragments  that
+       The use of relative references can be helpful  in  long  patterns,  and
+       also  in  patterns  that are created by joining together fragments that
        contain references within themselves.
 
-       The  sequence  \g{+1}  is a reference to the next capture group that is
-       started after this item, and \g{+2} refers to the one after  that,  and
-       so  on.  This  kind of forward reference can be useful in patterns that
+       The sequence \g{+1} is a reference to the next capture  group  that  is
+       started  after  this item, and \g{+2} refers to the one after that, and
+       so on. This kind of forward reference can be useful  in  patterns  that
        repeat. Perl does not support the use of + in this way.
 
-       A backreference matches whatever actually  most  recently  matched  the
-       capture  group  in  the current subject string, rather than anything at
+       A  backreference  matches  whatever  actually most recently matched the
+       capture group in the current subject string, rather  than  anything  at
        all that matches the group (see "Groups as subroutines" below for a way
        of doing that). So the pattern
 
          (sens|respons)e and \1ibility
 
-       matches "sense and sensibility" and "response and responsibility",  but
-       not  "sense and responsibility". If caseful matching is in force at the
-       time of the backreference, the case of letters is relevant.  For  exam-
+       matches  "sense and sensibility" and "response and responsibility", but
+       not "sense and responsibility". If caseful matching is in force at  the
+       time  of  the backreference, the case of letters is relevant. For exam-
        ple,
 
          ((?i)rah)\s+\1
 
-       matches  "rah  rah"  and  "RAH RAH", but not "RAH rah", even though the
+       matches "rah rah" and "RAH RAH", but not "RAH  rah",  even  though  the
        original capture group is matched caselessly.
 
-       There are several different ways of  writing  backreferences  to  named
-       capture  groups.  The  .NET  syntax  is  \k{name}, the Python syntax is
-       (?=name), and the original Perl syntax is \k<name> or \k'name'. All  of
-       these  are  now  supported  by both Perl and PCRE2. Perl 5.10's unified
-       backreference syntax, in which \g can be  used  for  both  numeric  and
-       named  references,  is  also  supported by PCRE2.  We could rewrite the
+       There  are  several  different  ways of writing backreferences to named
+       capture groups. The .NET syntax  is  \k{name},  the  Python  syntax  is
+       (?=name),  and the original Perl syntax is \k<name> or \k'name'. All of
+       these are now supported by both Perl and  PCRE2.  Perl  5.10's  unified
+       backreference  syntax,  in  which  \g  can be used for both numeric and
+       named references, is also supported by PCRE2.   We  could  rewrite  the
        above example in any of the following ways:
 
          (?<p1>(?i)rah)\s+\k<p1>
@@ -8589,114 +8605,114 @@ BACKREFERENCES
          (?P<p1>(?i)rah)\s+(?P=p1)
          (?<p1>(?i)rah)\s+\g{p1}
 
-       A capture group that is referenced by name may appear  in  the  pattern
+       A  capture  group  that is referenced by name may appear in the pattern
        before or after the reference.
 
-       There  may be more than one backreference to the same group. If a group
-       has not actually been used in a particular match, backreferences to  it
+       There may be more than one backreference to the same group. If a  group
+       has  not actually been used in a particular match, backreferences to it
        always fail by default. For example, the pattern
 
          (a|(bc))\2
 
-       always  fails  if  it starts to match "a" rather than "bc". However, if
+       always fails if it starts to match "a" rather than  "bc".  However,  if
        the PCRE2_MATCH_UNSET_BACKREF option is set at compile time, a backref-
        erence to an unset value matches an empty string.
 
-       Because there may be many capture groups in a pattern, all digits  fol-
-       lowing  a backslash are taken as part of a potential backreference num-
-       ber. If the pattern continues with a digit  character,  some  delimiter
-       must  be  used to terminate the backreference. If the PCRE2_EXTENDED or
-       PCRE2_EXTENDED_MORE option is set, this can be white space.  Otherwise,
+       Because  there may be many capture groups in a pattern, all digits fol-
+       lowing a backslash are taken as part of a potential backreference  num-
+       ber.  If  the  pattern continues with a digit character, some delimiter
+       must be used to terminate the backreference. If the  PCRE2_EXTENDED  or
+       PCRE2_EXTENDED_MORE  option is set, this can be white space. Otherwise,
        the \g{} syntax or an empty comment (see "Comments" below) can be used.
 
    Recursive backreferences
 
-       A  backreference  that occurs inside the group to which it refers fails
-       when the group is first used, so, for  example,  (a\1)  never  matches.
-       However,  such references can be useful inside repeated groups. For ex-
+       A backreference that occurs inside the group to which it  refers  fails
+       when  the  group  is  first used, so, for example, (a\1) never matches.
+       However, such references can be useful inside repeated groups. For  ex-
        ample, the pattern
 
          (a|b\1)+
 
        matches any number of "a"s and also "aba", "ababbaa" etc. At each iter-
        ation of the group, the backreference matches the character string cor-
-       responding to the previous iteration. In order for this  to  work,  the
-       pattern  must  be  such that the first iteration does not need to match
-       the backreference. This can be done using alternation, as in the  exam-
+       responding  to  the  previous iteration. In order for this to work, the
+       pattern must be such that the first iteration does not  need  to  match
+       the  backreference. This can be done using alternation, as in the exam-
        ple above, or by a quantifier with a minimum of zero.
 
        For versions of PCRE2 less than 10.25, backreferences of this type used
-       to  cause  the  group  that  they  reference to be treated as an atomic
-       group.  This restriction no longer applies, and backtracking into  such
+       to cause the group that they reference  to  be  treated  as  an  atomic
+       group.   This restriction no longer applies, and backtracking into such
        groups can occur as normal.
 
 
 ASSERTIONS
 
-       An  assertion  is  a  test on the characters following or preceding the
+       An assertion is a test on the characters  following  or  preceding  the
        current matching point that does not consume any characters. The simple
-       assertions coded as \b, \B, \A, \G, \Z,  \z,  ^  and  $  are  described
+       assertions  coded  as  \b,  \B,  \A,  \G, \Z, \z, ^ and $ are described
        above.
 
-       More  complicated  assertions  are coded as parenthesized groups. There
-       are two kinds: those that look ahead of the  current  position  in  the
-       subject  string, and those that look behind it, and in each case an as-
-       sertion may be positive (must match for the assertion to  be  true)  or
-       negative  (must  not  match for the assertion to be true). An assertion
+       More complicated assertions are coded as  parenthesized  groups.  There
+       are  two  kinds:  those  that look ahead of the current position in the
+       subject string, and those that look behind it, and in each case an  as-
+       sertion  may  be  positive (must match for the assertion to be true) or
+       negative (must not match for the assertion to be  true).  An  assertion
        group is matched in the normal way, and if it is true, matching contin-
-       ues after it, but with the matching position in the subject string  re-
+       ues  after it, but with the matching position in the subject string re-
        set to what it was before the assertion was processed.
 
-       The  Perl-compatible  lookaround assertions are atomic. If an assertion
-       is true, but there is a subsequent matching failure, there is no  back-
-       tracking  into  the assertion. However, there are some cases where non-
-       atomic assertions can be useful. PCRE2 has some support for these,  de-
+       The Perl-compatible lookaround assertions are atomic. If  an  assertion
+       is  true, but there is a subsequent matching failure, there is no back-
+       tracking into the assertion. However, there are some cases  where  non-
+       atomic  assertions can be useful. PCRE2 has some support for these, de-
        scribed in the section entitled "Non-atomic assertions" below, but they
        are not Perl-compatible.
 
-       A  lookaround  assertion  may  appear as the condition in a conditional
-       group (see below). In this case, the result of matching  the  assertion
+       A lookaround assertion may appear as the  condition  in  a  conditional
+       group  (see  below). In this case, the result of matching the assertion
        determines which branch of the condition is followed.
 
-       Assertion  groups are not capture groups. If an assertion contains cap-
-       ture groups within it, these are counted for the purposes of  numbering
-       the  capture  groups in the whole pattern. Within each branch of an as-
-       sertion, locally captured substrings may be  referenced  in  the  usual
-       way.  For  example,  a  sequence such as (.)\g{-1} can be used to check
+       Assertion groups are not capture groups. If an assertion contains  cap-
+       ture  groups within it, these are counted for the purposes of numbering
+       the capture groups in the whole pattern. Within each branch of  an  as-
+       sertion,  locally  captured  substrings  may be referenced in the usual
+       way. For example, a sequence such as (.)\g{-1} can  be  used  to  check
        that two adjacent characters are the same.
 
-       When a branch within an assertion fails to match, any  substrings  that
-       were  captured  are  discarded (as happens with any pattern branch that
-       fails to match). A  negative  assertion  is  true  only  when  all  its
+       When  a  branch within an assertion fails to match, any substrings that
+       were captured are discarded (as happens with any  pattern  branch  that
+       fails  to  match).  A  negative  assertion  is  true  only when all its
        branches fail to match; this means that no captured substrings are ever
-       retained  after a successful negative assertion. When an assertion con-
+       retained after a successful negative assertion. When an assertion  con-
        tains a matching branch, what happens depends on the type of assertion.
 
-       For a positive assertion, internally captured substrings  in  the  suc-
-       cessful  branch are retained, and matching continues with the next pat-
-       tern item after the assertion. For a  negative  assertion,  a  matching
-       branch  means  that  the assertion is not true. If such an assertion is
-       being used as a condition in a conditional group (see below),  captured
-       substrings  are  retained,  because  matching  continues  with the "no"
+       For  a  positive  assertion, internally captured substrings in the suc-
+       cessful branch are retained, and matching continues with the next  pat-
+       tern  item  after  the  assertion. For a negative assertion, a matching
+       branch means that the assertion is not true. If such  an  assertion  is
+       being  used as a condition in a conditional group (see below), captured
+       substrings are retained,  because  matching  continues  with  the  "no"
        branch of the condition. For other failing negative assertions, control
        passes to the previous backtracking point, thus discarding any captured
        strings within the assertion.
 
-       Most assertion groups may be repeated; though it makes no sense to  as-
+       Most  assertion groups may be repeated; though it makes no sense to as-
        sert the same thing several times, the side effect of capturing in pos-
        itive assertions may occasionally be useful. However, an assertion that
-       forms  the  condition  for  a  conditional group may not be quantified.
-       PCRE2 used to restrict the repetition of assertions, but  from  release
-       10.35  the  only restriction is that an unlimited maximum repetition is
-       changed to be one more than the minimum. For example, {3,}  is  treated
+       forms the condition for a conditional  group  may  not  be  quantified.
+       PCRE2  used  to restrict the repetition of assertions, but from release
+       10.35 the only restriction is that an unlimited maximum  repetition  is
+       changed  to  be one more than the minimum. For example, {3,} is treated
        as {3,4}.
 
    Alphabetic assertion names
 
-       Traditionally,  symbolic  sequences such as (?= and (?<= have been used
-       to specify lookaround assertions. Perl 5.28 introduced some  experimen-
+       Traditionally, symbolic sequences such as (?= and (?<= have  been  used
+       to  specify lookaround assertions. Perl 5.28 introduced some experimen-
        tal alphabetic alternatives which might be easier to remember. They all
-       start  with  (* instead of (? and must be written using lower case let-
+       start with (* instead of (? and must be written using lower  case  let-
        ters. PCRE2 supports the following synonyms:
 
          (*positive_lookahead:  or (*pla: is the same as (?=
@@ -8704,8 +8720,8 @@ ASSERTIONS
          (*positive_lookbehind: or (*plb: is the same as (?<=
          (*negative_lookbehind: or (*nlb: is the same as (?<!
 
-       For example, (*pla:foo) is the same assertion as (?=foo). In  the  fol-
-       lowing  sections, the various assertions are described using the origi-
+       For  example,  (*pla:foo) is the same assertion as (?=foo). In the fol-
+       lowing sections, the various assertions are described using the  origi-
        nal symbolic forms.
 
    Lookahead assertions
@@ -8715,107 +8731,107 @@ ASSERTIONS
 
          \w+(?=;)
 
-       matches a word followed by a semicolon, but does not include the  semi-
+       matches  a word followed by a semicolon, but does not include the semi-
        colon in the match, and
 
          foo(?!bar)
 
-       matches  any  occurrence  of  "foo" that is not followed by "bar". Note
+       matches any occurrence of "foo" that is not  followed  by  "bar".  Note
        that the apparently similar pattern
 
          (?!foo)bar
 
-       does not find an occurrence of "bar"  that  is  preceded  by  something
-       other  than "foo"; it finds any occurrence of "bar" whatsoever, because
+       does  not  find  an  occurrence  of "bar" that is preceded by something
+       other than "foo"; it finds any occurrence of "bar" whatsoever,  because
        the assertion (?!foo) is always true when the next three characters are
        "bar". A lookbehind assertion is needed to achieve the other effect.
 
        If you want to force a matching failure at some point in a pattern, the
-       most convenient way to do it is with (?!) because an empty  string  al-
-       ways  matches,  so  an assertion that requires there not to be an empty
+       most  convenient  way to do it is with (?!) because an empty string al-
+       ways matches, so an assertion that requires there not to  be  an  empty
        string must always fail.  The backtracking control verb (*FAIL) or (*F)
        is a synonym for (?!).
 
    Lookbehind assertions
 
-       Lookbehind assertions start with (?<= for positive assertions and  (?<!
+       Lookbehind  assertions start with (?<= for positive assertions and (?<!
        for negative assertions. For example,
 
          (?<!foo)bar
 
-       does  find  an  occurrence  of "bar" that is not preceded by "foo". The
-       contents of a lookbehind assertion are restricted such that there  must
-       be  a known maximum to the lengths of all the strings it matches. There
+       does find an occurrence of "bar" that is not  preceded  by  "foo".  The
+       contents  of a lookbehind assertion are restricted such that there must
+       be a known maximum to the lengths of all the strings it matches.  There
        are two cases:
 
        If every top-level alternative matches a fixed length, for example
 
          (?<=colour|color)
 
-       there is a limit of 65535 characters to the lengths, which do not  have
-       to  be the same, as this example demonstrates. This is the only kind of
-       lookbehind supported by PCRE2 versions earlier than 10.43  and  by  the
+       there  is a limit of 65535 characters to the lengths, which do not have
+       to be the same, as this example demonstrates. This is the only kind  of
+       lookbehind  supported  by  PCRE2 versions earlier than 10.43 and by the
        alternative matching function pcre2_dfa_match().
 
-       In  PCRE2 10.43 and later, pcre2_match() supports lookbehind assertions
-       in which one or more top-level alternatives can  match  more  than  one
+       In PCRE2 10.43 and later, pcre2_match() supports lookbehind  assertions
+       in  which  one  or  more top-level alternatives can match more than one
        string length, for example
 
          (?<=colou?r)
 
        The maximum matching length for any branch of the lookbehind is limited
-       to  a value set by the calling program (default 255 characters). Unlim-
-       ited repetition (for example \d*) is not supported. In some cases,  the
-       escape  sequence \K (see above) can be used instead of a lookbehind as-
-       sertion at the start of a pattern to get round  the  length  limit  re-
+       to a value set by the calling program (default 255 characters).  Unlim-
+       ited  repetition (for example \d*) is not supported. In some cases, the
+       escape sequence \K (see above) can be used instead of a lookbehind  as-
+       sertion  at  the  start  of a pattern to get round the length limit re-
        striction.
 
-       In  UTF-8  and  UTF-16 modes, PCRE2 does not allow the \C escape (which
-       matches a single code unit even in a UTF mode) to appear in  lookbehind
-       assertions,  because  it makes it impossible to calculate the length of
-       the lookbehind. The \X and \R escapes, which can match  different  num-
+       In UTF-8 and UTF-16 modes, PCRE2 does not allow the  \C  escape  (which
+       matches  a single code unit even in a UTF mode) to appear in lookbehind
+       assertions, because it makes it impossible to calculate the  length  of
+       the  lookbehind.  The \X and \R escapes, which can match different num-
        bers of code units, are never permitted in lookbehinds.
 
-       "Subroutine"  calls  (see below) such as (?2) or (?&X) are permitted in
-       lookbehinds, as long as the called capture  group  matches  a  limited-
-       length  string. However, recursion, that is, a "subroutine" call into a
+       "Subroutine" calls (see below) such as (?2) or (?&X) are  permitted  in
+       lookbehinds,  as  long  as  the called capture group matches a limited-
+       length string. However, recursion, that is, a "subroutine" call into  a
        group that is already active, is not supported.
 
-       PCRE2 supports backreferences in lookbehinds, but only if certain  con-
-       ditions  are met. The PCRE2_MATCH_UNSET_BACKREF option must not be set,
-       there must be no use of (?| in the pattern (it creates duplicate  group
+       PCRE2  supports backreferences in lookbehinds, but only if certain con-
+       ditions are met. The PCRE2_MATCH_UNSET_BACKREF option must not be  set,
+       there  must be no use of (?| in the pattern (it creates duplicate group
        numbers), and if the backreference is by name, the name must be unique.
        Of course, the referenced group must itself match a limited length sub-
-       string.  The  following  pattern  matches words containing at least two
+       string. The following pattern matches words  containing  at  least  two
        characters that begin and end with the same character:
 
           \b(\w)\w++(?<=\1)
 
-       Possessive quantifiers can be used in conjunction with  lookbehind  as-
-       sertions  to  specify efficient matching at the end of subject strings.
+       Possessive  quantifiers  can be used in conjunction with lookbehind as-
+       sertions to specify efficient matching at the end of  subject  strings.
        Consider a simple pattern such as
 
          abcd$
 
-       when applied to a long string that does  not  match.  Because  matching
-       proceeds  from  left to right, PCRE2 will look for each "a" in the sub-
-       ject and then see if what follows matches the rest of the  pattern.  If
+       when  applied  to  a  long string that does not match. Because matching
+       proceeds from left to right, PCRE2 will look for each "a" in  the  sub-
+       ject  and  then see if what follows matches the rest of the pattern. If
        the pattern is specified as
 
          ^.*abcd$
 
-       the  initial .* matches the entire string at first, but when this fails
+       the initial .* matches the entire string at first, but when this  fails
        (because there is no following "a"), it backtracks to match all but the
-       last character, then all but the last two characters, and so  on.  Once
-       again  the search for "a" covers the entire string, from right to left,
+       last  character,  then all but the last two characters, and so on. Once
+       again the search for "a" covers the entire string, from right to  left,
        so we are no better off. However, if the pattern is written as
 
          ^.*+(?<=abcd)
 
        there can be no backtracking for the .*+ item because of the possessive
        quantifier; it can match only the entire string. The subsequent lookbe-
-       hind assertion does a single test on the last four  characters.  If  it
-       fails,  the  match  fails  immediately. For long strings, this approach
+       hind  assertion  does  a single test on the last four characters. If it
+       fails, the match fails immediately. For  long  strings,  this  approach
        makes a significant difference to the processing time.
 
    Using multiple assertions
@@ -8824,18 +8840,18 @@ ASSERTIONS
 
          (?<=\d{3})(?<!999)foo
 
-       matches "foo" preceded by three digits that are not "999". Notice  that
-       each  of  the  assertions is applied independently at the same point in
-       the subject string. First there is a  check  that  the  previous  three
-       characters  are  all  digits,  and  then there is a check that the same
+       matches  "foo" preceded by three digits that are not "999". Notice that
+       each of the assertions is applied independently at the  same  point  in
+       the  subject  string.  First  there  is a check that the previous three
+       characters are all digits, and then there is  a  check  that  the  same
        three characters are not "999".  This pattern does not match "foo" pre-
-       ceded by six characters, the first of which are  digits  and  the  last
-       three  of  which  are not "999". For example, it doesn't match "123abc-
+       ceded  by  six  characters,  the first of which are digits and the last
+       three of which are not "999". For example, it  doesn't  match  "123abc-
        foo". A pattern to do that is
 
          (?<=\d{3}...)(?<!999)foo
 
-       This time the first assertion looks at the  preceding  six  characters,
+       This  time  the  first assertion looks at the preceding six characters,
        checking that the first three are digits, and then the second assertion
        checks that the preceding three characters are not "999".
 
@@ -8843,69 +8859,69 @@ ASSERTIONS
 
          (?<=(?<!foo)bar)baz
 
-       matches  an occurrence of "baz" that is preceded by "bar" which in turn
+       matches an occurrence of "baz" that is preceded by "bar" which in  turn
        is not preceded by "foo", while
 
          (?<=\d{3}(?!999)...)foo
 
-       is another pattern that matches "foo" preceded by three digits and  any
+       is  another pattern that matches "foo" preceded by three digits and any
        three characters that are not "999".
 
 
 NON-ATOMIC ASSERTIONS
 
-       Traditional  lookaround assertions are atomic. That is, if an assertion
-       is true, but there is a subsequent matching failure, there is no  back-
-       tracking  into  the assertion. However, there are some cases where non-
-       atomic positive assertions can be useful. PCRE2  provides  these  using
+       Traditional lookaround assertions are atomic. That is, if an  assertion
+       is  true, but there is a subsequent matching failure, there is no back-
+       tracking into the assertion. However, there are some cases  where  non-
+       atomic  positive  assertions  can be useful. PCRE2 provides these using
        the following syntax:
 
          (*non_atomic_positive_lookahead:  or (*napla: or (?*
          (*non_atomic_positive_lookbehind: or (*naplb: or (?<*
 
-       Consider  the  problem  of finding the right-most word in a string that
-       also appears earlier in the string, that is, it must  appear  at  least
-       twice  in  total.  This pattern returns the required result as captured
+       Consider the problem of finding the right-most word in  a  string  that
+       also  appears  earlier  in the string, that is, it must appear at least
+       twice in total.  This pattern returns the required result  as  captured
        substring 1:
 
          ^(?x)(*napla: .* \b(\w++)) (?> .*? \b\1\b ){2}
 
-       For a subject such as "word1 word2 word3 word2 word3 word4" the  result
-       is  "word3".  How does it work? At the start, ^(?x) anchors the pattern
+       For  a subject such as "word1 word2 word3 word2 word3 word4" the result
+       is "word3". How does it work? At the start, ^(?x) anchors  the  pattern
        and sets the "x" option, which causes white space (introduced for read-
-       ability) to be ignored. Inside the assertion, the greedy  .*  at  first
+       ability)  to  be  ignored. Inside the assertion, the greedy .* at first
        consumes the entire string, but then has to backtrack until the rest of
-       the  assertion can match a word, which is captured by group 1. In other
-       words, when the assertion first succeeds, it  captures  the  right-most
+       the assertion can match a word, which is captured by group 1. In  other
+       words,  when  the  assertion first succeeds, it captures the right-most
        word in the string.
 
-       The  current  matching point is then reset to the start of the subject,
-       and the rest of the pattern match checks for  two  occurrences  of  the
-       captured  word,  using  an  ungreedy .*? to scan from the left. If this
-       succeeds, we are done, but if the last word in the string does not  oc-
-       cur  twice,  this  part  of  the pattern fails. If a traditional atomic
-       lookahead (?= or (*pla: had been used, the assertion could not  be  re-
+       The current matching point is then reset to the start of  the  subject,
+       and  the  rest  of  the pattern match checks for two occurrences of the
+       captured word, using an ungreedy .*? to scan from  the  left.  If  this
+       succeeds,  we are done, but if the last word in the string does not oc-
+       cur twice, this part of the pattern  fails.  If  a  traditional  atomic
+       lookahead  (?=  or (*pla: had been used, the assertion could not be re-
        entered, and the whole match would fail. The pattern would succeed only
        if the very last word in the subject was found twice.
 
-       Using  a  non-atomic  lookahead, however, means that when the last word
-       does not occur twice in the string, the  lookahead  can  backtrack  and
-       find  the second-last word, and so on, until either the match succeeds,
+       Using a non-atomic lookahead, however, means that when  the  last  word
+       does  not  occur  twice  in the string, the lookahead can backtrack and
+       find the second-last word, and so on, until either the match  succeeds,
        or all words have been tested.
 
        Two conditions must be met for a non-atomic assertion to be useful: the
-       contents of one or more capturing groups must change after a  backtrack
-       into  the  assertion,  and  there  must be a backreference to a changed
-       group later in the pattern. If this is not the case, the  rest  of  the
-       pattern  match  fails exactly as before because nothing has changed, so
+       contents  of one or more capturing groups must change after a backtrack
+       into the assertion, and there must be  a  backreference  to  a  changed
+       group  later  in  the pattern. If this is not the case, the rest of the
+       pattern match fails exactly as before because nothing has  changed,  so
        using a non-atomic assertion just wastes resources.
 
-       There is one exception to backtracking into a non-atomic assertion.  If
-       an  (*ACCEPT)  control verb is triggered, the assertion succeeds atomi-
-       cally. That is, a subsequent match failure cannot  backtrack  into  the
+       There  is one exception to backtracking into a non-atomic assertion. If
+       an (*ACCEPT) control verb is triggered, the assertion  succeeds  atomi-
+       cally.  That  is,  a subsequent match failure cannot backtrack into the
        assertion.
 
-       Non-atomic  assertions  are  not  supported by the alternative matching
+       Non-atomic assertions are not supported  by  the  alternative  matching
        function pcre2_dfa_match(). They are supported by JIT, but only if they
        do not contain any control verbs such as (*ACCEPT). (This may change in
        future). Note that assertions that appear as conditions for conditional
@@ -8914,42 +8930,42 @@ NON-ATOMIC ASSERTIONS
 
 SCRIPT RUNS
 
-       In concept, a script run is a sequence of characters that are all  from
-       the  same  Unicode script such as Latin or Greek. However, because some
-       scripts are commonly used together, and because  some  diacritical  and
-       other  marks  are  used  with  multiple scripts, it is not that simple.
+       In  concept, a script run is a sequence of characters that are all from
+       the same Unicode script such as Latin or Greek. However,  because  some
+       scripts  are  commonly  used together, and because some diacritical and
+       other marks are used with multiple scripts,  it  is  not  that  simple.
        There is a full description of the rules that PCRE2 uses in the section
        entitled "Script Runs" in the pcre2unicode documentation.
 
-       If part of a pattern is enclosed between (*script_run: or (*sr:  and  a
-       closing  parenthesis,  it  fails  if the sequence of characters that it
-       matches are not a script run. After a failure, normal backtracking  oc-
-       curs.  Script runs can be used to detect spoofing attacks using charac-
-       ters that look the same, but are from  different  scripts.  The  string
-       "paypal.com"  is an infamous example, where the letters could be a mix-
+       If  part  of a pattern is enclosed between (*script_run: or (*sr: and a
+       closing parenthesis, it fails if the sequence  of  characters  that  it
+       matches  are not a script run. After a failure, normal backtracking oc-
+       curs. Script runs can be used to detect spoofing attacks using  charac-
+       ters  that  look  the  same, but are from different scripts. The string
+       "paypal.com" is an infamous example, where the letters could be a  mix-
        ture of Latin and Cyrillic. This pattern ensures that the matched char-
        acters in a sequence of non-spaces that follow white space are a script
        run:
 
          \s+(*sr:\S+)
 
-       To be sure that they are all from the Latin  script  (for  example),  a
+       To  be  sure  that  they are all from the Latin script (for example), a
        lookahead can be used:
 
          \s+(?=\p{Latin})(*sr:\S+)
 
        This works as long as the first character is expected to be a character
-       in  that  script,  and  not (for example) punctuation, which is allowed
-       with any script. If this is not the case, a more creative lookahead  is
-       needed.  For  example, if digits, underscore, and dots are permitted at
+       in that script, and not (for example)  punctuation,  which  is  allowed
+       with  any script. If this is not the case, a more creative lookahead is
+       needed. For example, if digits, underscore, and dots are  permitted  at
        the start:
 
          \s+(?=[0-9_.]*\p{Latin})(*sr:\S+)
 
 
-       In many cases, backtracking into a script run pattern fragment  is  not
-       desirable.  The  script run can employ an atomic group to prevent this.
-       Because this is a common requirement, a shorthand notation is  provided
+       In  many  cases, backtracking into a script run pattern fragment is not
+       desirable. The script run can employ an atomic group to  prevent  this.
+       Because  this is a common requirement, a shorthand notation is provided
        by (*atomic_script_run: or (*asr:
 
          (*asr:...) is the same as (*sr:(?>...))
@@ -8957,13 +8973,13 @@ SCRIPT RUNS
        Note that the atomic group is inside the script run. Putting it outside
        would not prevent backtracking into the script run pattern.
 
-       Support  for  script runs is not available if PCRE2 is compiled without
+       Support for script runs is not available if PCRE2 is  compiled  without
        Unicode support. A compile-time error is given if any of the above con-
-       structs is encountered. Script runs are not supported by the  alternate
-       matching  function,  pcre2_dfa_match() because they use the same mecha-
+       structs  is encountered. Script runs are not supported by the alternate
+       matching function, pcre2_dfa_match() because they use the  same  mecha-
        nism as capturing parentheses.
 
-       Warning: The (*ACCEPT) control verb (see  below)  should  not  be  used
+       Warning:  The  (*ACCEPT)  control  verb  (see below) should not be used
        within a script run group, because it causes an immediate exit from the
        group, bypassing the script run checking.
 
@@ -8972,117 +8988,117 @@ CONDITIONAL GROUPS
 
        It is possible to cause the matching process to obey a pattern fragment
        conditionally or to choose between two alternative fragments, depending
-       on  the result of an assertion, or whether a specific capture group has
+       on the result of an assertion, or whether a specific capture group  has
        already been matched. The two possible forms of conditional group are:
 
          (?(condition)yes-pattern)
          (?(condition)yes-pattern|no-pattern)
 
-       If the condition is satisfied, the yes-pattern is used;  otherwise  the
-       no-pattern  (if present) is used. An absent no-pattern is equivalent to
-       an empty string (it always matches). If there are more than two  alter-
-       natives  in the group, a compile-time error occurs. Each of the two al-
+       If  the  condition is satisfied, the yes-pattern is used; otherwise the
+       no-pattern (if present) is used. An absent no-pattern is equivalent  to
+       an  empty string (it always matches). If there are more than two alter-
+       natives in the group, a compile-time error occurs. Each of the two  al-
        ternatives may itself contain nested groups of any form, including con-
-       ditional groups; the restriction to two alternatives  applies  only  at
-       the  level of the condition itself. This pattern fragment is an example
+       ditional  groups;  the  restriction to two alternatives applies only at
+       the level of the condition itself. This pattern fragment is an  example
        where the alternatives are complex:
 
          (?(1) (A|B|C) | (D | (?(2)E|F) | E) )
 
 
        There are five kinds of condition: references to capture groups, refer-
-       ences to recursion, two pseudo-conditions called  DEFINE  and  VERSION,
+       ences  to  recursion,  two pseudo-conditions called DEFINE and VERSION,
        and assertions.
 
    Checking for a used capture group by number
 
-       If  the  text between the parentheses consists of a sequence of digits,
-       the condition is true if a capture group of that number has  previously
-       matched.  If  there is more than one capture group with the same number
-       (see the earlier section about duplicate group numbers), the  condition
-       is  true if any of them have matched. An alternative notation, which is
+       If the text between the parentheses consists of a sequence  of  digits,
+       the  condition is true if a capture group of that number has previously
+       matched. If there is more than one capture group with the  same  number
+       (see  the earlier section about duplicate group numbers), the condition
+       is true if any of them have matched. An alternative notation, which  is
        a PCRE2 extension, not supported by Perl, is to precede the digits with
        a plus or minus sign. In this case, the group number is relative rather
-       than absolute. The most recently opened capture group (which  could  be
-       enclosing  this  condition)  can be referenced by (?(-1), the next most
+       than  absolute.  The most recently opened capture group (which could be
+       enclosing this condition) can be referenced by (?(-1),  the  next  most
        recent by (?(-2), and so on. Inside loops it can also make sense to re-
-       fer to subsequent groups.  The next capture group to be opened  can  be
-       referenced  as  (?(+1), and so on. The value zero in any of these forms
+       fer  to  subsequent groups.  The next capture group to be opened can be
+       referenced as (?(+1), and so on. The value zero in any of  these  forms
        is not used; it provokes a compile-time error.
 
-       Consider the following pattern, which  contains  non-significant  white
-       space  to  make it more readable (assume the PCRE2_EXTENDED option) and
+       Consider  the  following  pattern, which contains non-significant white
+       space to make it more readable (assume the PCRE2_EXTENDED  option)  and
        to divide it into three parts for ease of discussion:
 
          ( \( )?    [^()]+    (?(1) \) )
 
-       The first part matches an optional opening  parenthesis,  and  if  that
+       The  first  part  matches  an optional opening parenthesis, and if that
        character is present, sets it as the first captured substring. The sec-
-       ond  part  matches one or more characters that are not parentheses. The
-       third part is a conditional group that tests whether or not  the  first
-       capture  group  matched. If it did, that is, if subject started with an
-       opening parenthesis, the condition is true, and so the  yes-pattern  is
-       executed  and  a  closing parenthesis is required. Otherwise, since no-
+       ond part matches one or more characters that are not  parentheses.  The
+       third  part  is a conditional group that tests whether or not the first
+       capture group matched. If it did, that is, if subject started  with  an
+       opening  parenthesis,  the condition is true, and so the yes-pattern is
+       executed and a closing parenthesis is required.  Otherwise,  since  no-
        pattern is not present, the conditional group matches nothing. In other
-       words, this pattern matches a sequence of  non-parentheses,  optionally
+       words,  this  pattern matches a sequence of non-parentheses, optionally
        enclosed in parentheses.
 
-       If  you  were  embedding  this pattern in a larger one, you could use a
+       If you were embedding this pattern in a larger one,  you  could  use  a
        relative reference:
 
          ...other stuff... ( \( )?    [^()]+    (?(-1) \) ) ...
 
-       This makes the fragment independent of the parentheses  in  the  larger
+       This  makes  the  fragment independent of the parentheses in the larger
        pattern.
 
    Checking for a used capture group by name
 
-       Perl  uses  the  syntax  (?(<name>)...) or (?('name')...) to test for a
-       used capture group by name. For compatibility with earlier versions  of
-       PCRE1,  which had this facility before Perl, the syntax (?(name)...) is
-       also recognized.  Note, however, that undelimited names  consisting  of
-       the  letter  R followed by digits are ambiguous (see the following sec-
+       Perl uses the syntax (?(<name>)...) or (?('name')...)  to  test  for  a
+       used  capture group by name. For compatibility with earlier versions of
+       PCRE1, which had this facility before Perl, the syntax (?(name)...)  is
+       also  recognized.   Note, however, that undelimited names consisting of
+       the letter R followed by digits are ambiguous (see the  following  sec-
        tion). Rewriting the above example to use a named group gives this:
 
          (?<OPEN> \( )?    [^()]+    (?(<OPEN>) \) )
 
-       If the name used in a condition of this kind is a duplicate,  the  test
-       is  applied  to  all groups of the same name, and is true if any one of
+       If  the  name used in a condition of this kind is a duplicate, the test
+       is applied to all groups of the same name, and is true if  any  one  of
        them has matched.
 
    Checking for pattern recursion
 
-       "Recursion" in this sense refers to any subroutine-like call  from  one
-       part  of  the  pattern to another, whether or not it is actually recur-
-       sive. See the sections entitled "Recursive  patterns"  and  "Groups  as
+       "Recursion"  in  this sense refers to any subroutine-like call from one
+       part of the pattern to another, whether or not it  is  actually  recur-
+       sive.  See  the  sections  entitled "Recursive patterns" and "Groups as
        subroutines" below for details of recursion and subroutine calls.
 
-       If  a  condition  is the string (R), and there is no capture group with
-       the name R, the condition is true if matching is currently in a  recur-
-       sion  or  subroutine call to the whole pattern or any capture group. If
-       digits follow the letter R, and there is no group with that  name,  the
-       condition  is  true  if  the  most recent call is into a group with the
-       given number, which must exist somewhere in the overall  pattern.  This
+       If a condition is the string (R), and there is no  capture  group  with
+       the  name R, the condition is true if matching is currently in a recur-
+       sion or subroutine call to the whole pattern or any capture  group.  If
+       digits  follow  the letter R, and there is no group with that name, the
+       condition is true if the most recent call is  into  a  group  with  the
+       given  number,  which must exist somewhere in the overall pattern. This
        is a contrived example that is equivalent to a+b:
 
          ((?(R1)a+|(?1)b))
 
-       However,  in  both  cases,  if there is a capture group with a matching
-       name, the condition tests for its being set, as described in  the  sec-
-       tion  above,  instead of testing for recursion. For example, creating a
-       group with the name R1 by adding (?<R1>)  to  the  above  pattern  com-
+       However, in both cases, if there is a capture  group  with  a  matching
+       name,  the  condition tests for its being set, as described in the sec-
+       tion above, instead of testing for recursion. For example,  creating  a
+       group  with  the  name  R1  by adding (?<R1>) to the above pattern com-
        pletely changes its meaning.
 
        If a name preceded by ampersand follows the letter R, for example:
 
          (?(R&name)...)
 
-       the  condition  is true if the most recent recursion is into a group of
+       the condition is true if the most recent recursion is into a  group  of
        that name (which must exist within the pattern).
 
        This condition does not check the entire recursion stack. It tests only
-       the current level. If the name used in a condition of this  kind  is  a
-       duplicate,  the  test is applied to all groups of the same name, and is
+       the  current  level.  If the name used in a condition of this kind is a
+       duplicate, the test is applied to all groups of the same name,  and  is
        true if any one of them is the most recent recursion.
 
        At "top level", all these recursion test conditions are false.
@@ -9090,111 +9106,111 @@ CONDITIONAL GROUPS
    Defining capture groups for use by reference only
 
        If the condition is the string (DEFINE), the condition is always false,
-       even if there is a group with the name DEFINE. In this case, there  may
+       even  if there is a group with the name DEFINE. In this case, there may
        be only one alternative in the rest of the conditional group. It is al-
-       ways  skipped if control reaches this point in the pattern; the idea of
-       DEFINE is that it can be used to define subroutines that can be  refer-
-       enced  from elsewhere. (The use of subroutines is described below.) For
-       example, a pattern to match an IPv4 address  such  as  "192.168.23.245"
+       ways skipped if control reaches this point in the pattern; the idea  of
+       DEFINE  is that it can be used to define subroutines that can be refer-
+       enced from elsewhere. (The use of subroutines is described below.)  For
+       example,  a  pattern  to match an IPv4 address such as "192.168.23.245"
        could be written like this (ignore white space and line breaks):
 
          (?(DEFINE) (?<byte> 2[0-4]\d | 25[0-5] | 1\d\d | [1-9]?\d) )
          \b (?&byte) (\.(?&byte)){3} \b
 
-       The  first  part  of the pattern is a DEFINE group inside which another
-       group named "byte" is defined. This matches an individual component  of
-       an  IPv4  address  (a number less than 256). When matching takes place,
-       this part of the pattern is skipped because DEFINE acts  like  a  false
-       condition.  The  rest of the pattern uses references to the named group
-       to match the four dot-separated components of an IPv4 address,  insist-
+       The first part of the pattern is a DEFINE group  inside  which  another
+       group  named "byte" is defined. This matches an individual component of
+       an IPv4 address (a number less than 256). When  matching  takes  place,
+       this  part  of  the pattern is skipped because DEFINE acts like a false
+       condition. The rest of the pattern uses references to the  named  group
+       to  match the four dot-separated components of an IPv4 address, insist-
        ing on a word boundary at each end.
 
    Checking the PCRE2 version
 
-       Programs  that link with a PCRE2 library can check the version by call-
-       ing pcre2_config() with appropriate arguments.  Users  of  applications
-       that  do  not have access to the underlying code cannot do this. A spe-
-       cial "condition" called VERSION exists to allow such users to  discover
+       Programs that link with a PCRE2 library can check the version by  call-
+       ing  pcre2_config()  with  appropriate arguments. Users of applications
+       that do not have access to the underlying code cannot do this.  A  spe-
+       cial  "condition" called VERSION exists to allow such users to discover
        which version of PCRE2 they are dealing with by using this condition to
-       match  a string such as "yesno". VERSION must be followed either by "="
+       match a string such as "yesno". VERSION must be followed either by  "="
        or ">=" and a version number.  For example:
 
          (?(VERSION>=10.4)yes|no)
 
-       This pattern matches "yes" if the PCRE2 version is greater or equal  to
-       10.4,  or "no" otherwise. The fractional part of the version number may
+       This  pattern matches "yes" if the PCRE2 version is greater or equal to
+       10.4, or "no" otherwise. The fractional part of the version number  may
        not contain more than two digits.
 
    Assertion conditions
 
-       If the condition is not in any of the  above  formats,  it  must  be  a
-       parenthesized  assertion.  This may be a positive or negative lookahead
-       or lookbehind assertion. However, it must be a traditional  atomic  as-
+       If  the  condition  is  not  in  any of the above formats, it must be a
+       parenthesized assertion. This may be a positive or  negative  lookahead
+       or  lookbehind  assertion. However, it must be a traditional atomic as-
        sertion, not one of the non-atomic assertions.
 
-       Consider  this  pattern,  again containing non-significant white space,
+       Consider this pattern, again containing  non-significant  white  space,
        and with the two alternatives on the second line:
 
          (?(?=[^a-z]*[a-z])
          \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} )
 
-       The condition is a positive lookahead assertion  that  matches  an  op-
+       The  condition  is  a  positive lookahead assertion that matches an op-
        tional sequence of non-letters followed by a letter. In other words, it
        tests for the presence of at least one letter in the subject. If a let-
-       ter  is  found,  the  subject is matched against the first alternative;
-       otherwise it is  matched  against  the  second.  This  pattern  matches
-       strings  in  one  of the two forms dd-aaa-dd or dd-dd-dd, where aaa are
+       ter is found, the subject is matched  against  the  first  alternative;
+       otherwise  it  is  matched  against  the  second.  This pattern matches
+       strings in one of the two forms dd-aaa-dd or dd-dd-dd,  where  aaa  are
        letters and dd are digits.
 
        When an assertion that is a condition contains capture groups, any cap-
-       turing that occurs in a matching branch  is  retained  afterwards,  for
-       both  positive and negative assertions, because matching always contin-
-       ues after the assertion, whether it succeeds or  fails.  (Compare  non-
-       conditional  assertions, for which captures are retained only for posi-
+       turing  that  occurs  in  a matching branch is retained afterwards, for
+       both positive and negative assertions, because matching always  contin-
+       ues  after  the  assertion, whether it succeeds or fails. (Compare non-
+       conditional assertions, for which captures are retained only for  posi-
        tive assertions that succeed.)
 
 
 COMMENTS
 
        There are two ways of including comments in patterns that are processed
-       by PCRE2. In both cases, the start of the comment  must  not  be  in  a
-       character  class,  nor  in  the middle of any other sequence of related
-       characters such as (?: or a group name or number. The  characters  that
+       by  PCRE2.  In  both  cases,  the start of the comment must not be in a
+       character class, nor in the middle of any  other  sequence  of  related
+       characters  such  as (?: or a group name or number. The characters that
        make up a comment play no part in the pattern matching.
 
-       The  sequence (?# marks the start of a comment that continues up to the
-       next closing parenthesis. Nested parentheses are not permitted. If  the
-       PCRE2_EXTENDED  or  PCRE2_EXTENDED_MORE  option  is set, an unescaped #
-       character also introduces a comment, which in this  case  continues  to
-       immediately  after  the next newline character or character sequence in
+       The sequence (?# marks the start of a comment that continues up to  the
+       next  closing parenthesis. Nested parentheses are not permitted. If the
+       PCRE2_EXTENDED or PCRE2_EXTENDED_MORE option is  set,  an  unescaped  #
+       character  also  introduces  a comment, which in this case continues to
+       immediately after the next newline character or character  sequence  in
        the pattern. Which characters are interpreted as newlines is controlled
-       by an option passed to the compiling function or by a special  sequence
+       by  an option passed to the compiling function or by a special sequence
        at the start of the pattern, as described in the section entitled "New-
        line conventions" above. Note that the end of this type of comment is a
-       literal  newline  sequence in the pattern; escape sequences that happen
+       literal newline sequence in the pattern; escape sequences  that  happen
        to represent a newline do not count. For example, consider this pattern
-       when PCRE2_EXTENDED is set, and the default newline convention (a  sin-
+       when  PCRE2_EXTENDED is set, and the default newline convention (a sin-
        gle linefeed character) is in force:
 
          abc #comment \n still comment
 
-       On  encountering  the # character, pcre2_compile() skips along, looking
-       for a newline in the pattern. The sequence \n is still literal at  this
-       stage,  so  it does not terminate the comment. Only an actual character
+       On encountering the # character, pcre2_compile() skips  along,  looking
+       for  a newline in the pattern. The sequence \n is still literal at this
+       stage, so it does not terminate the comment. Only an  actual  character
        with the code value 0x0a (the default newline) does so.
 
 
 RECURSIVE PATTERNS
 
-       Consider the problem of matching a string in parentheses, allowing  for
-       unlimited  nested  parentheses.  Without the use of recursion, the best
-       that can be done is to use a pattern that  matches  up  to  some  fixed
-       depth  of  nesting.  It  is not possible to handle an arbitrary nesting
+       Consider  the problem of matching a string in parentheses, allowing for
+       unlimited nested parentheses. Without the use of  recursion,  the  best
+       that  can  be  done  is  to use a pattern that matches up to some fixed
+       depth of nesting. It is not possible to  handle  an  arbitrary  nesting
        depth.
 
        For some time, Perl has provided a facility that allows regular expres-
-       sions to recurse (amongst other things). It does this by  interpolating
-       Perl  code in the expression at run time, and the code can refer to the
+       sions  to recurse (amongst other things). It does this by interpolating
+       Perl code in the expression at run time, and the code can refer to  the
        expression itself. A Perl pattern using code interpolation to solve the
        parentheses problem can be created like this:
 
@@ -9203,67 +9219,67 @@ RECURSIVE PATTERNS
        The (?p{...}) item interpolates Perl code at run time, and in this case
        refers recursively to the pattern in which it appears.
 
-       Obviously, PCRE2 cannot support the interpolation  of  Perl  code.  In-
-       stead,  it supports special syntax for recursion of the entire pattern,
+       Obviously,  PCRE2  cannot  support  the interpolation of Perl code. In-
+       stead, it supports special syntax for recursion of the entire  pattern,
        and also for individual capture group recursion. After its introduction
        in PCRE1 and Python, this kind of recursion was subsequently introduced
        into Perl at release 5.10.
 
-       A special item that consists of (? followed by a  number  greater  than
-       zero  and  a  closing parenthesis is a recursive subroutine call of the
-       capture group of the given number, provided that it occurs inside  that
-       group.  (If  not,  it  is a non-recursive subroutine call, which is de-
+       A  special  item  that consists of (? followed by a number greater than
+       zero and a closing parenthesis is a recursive subroutine  call  of  the
+       capture  group of the given number, provided that it occurs inside that
+       group. (If not, it is a non-recursive subroutine  call,  which  is  de-
        scribed in the next section.) The special item (?R) or (?0) is a recur-
        sive call of the entire regular expression.
 
-       This PCRE2 pattern solves the nested parentheses  problem  (assume  the
+       This  PCRE2  pattern  solves the nested parentheses problem (assume the
        PCRE2_EXTENDED option is set so that white space is ignored):
 
          \( ( [^()]++ | (?R) )* \)
 
-       First  it matches an opening parenthesis. Then it matches any number of
-       substrings which can either be a sequence of non-parentheses, or a  re-
+       First it matches an opening parenthesis. Then it matches any number  of
+       substrings  which can either be a sequence of non-parentheses, or a re-
        cursive match of the pattern itself (that is, a correctly parenthesized
-       substring).   Finally there is a closing parenthesis. Note the use of a
-       possessive quantifier to avoid  backtracking  into  sequences  of  non-
+       substring).  Finally there is a closing parenthesis. Note the use of  a
+       possessive  quantifier  to  avoid  backtracking  into sequences of non-
        parentheses.
 
-       If  this  were  part of a larger pattern, you would not want to recurse
+       If this were part of a larger pattern, you would not  want  to  recurse
        the entire pattern, so instead you could use this:
 
          ( \( ( [^()]++ | (?1) )* \) )
 
-       We have put the pattern into parentheses, and caused the  recursion  to
+       We  have  put the pattern into parentheses, and caused the recursion to
        refer to them instead of the whole pattern.
 
-       In  a  larger  pattern,  keeping  track  of  parenthesis numbers can be
-       tricky. This is made easier by the use of relative references.  Instead
+       In a larger pattern,  keeping  track  of  parenthesis  numbers  can  be
+       tricky.  This is made easier by the use of relative references. Instead
        of (?1) in the pattern above you can write (?-2) to refer to the second
-       most  recently  opened  parentheses  preceding  the recursion. In other
-       words, a negative number counts capturing  parentheses  leftwards  from
+       most recently opened parentheses  preceding  the  recursion.  In  other
+       words,  a  negative  number counts capturing parentheses leftwards from
        the point at which it is encountered.
 
-       Be  aware  however, that if duplicate capture group numbers are in use,
-       relative references refer to the earliest group  with  the  appropriate
+       Be aware however, that if duplicate capture group numbers are  in  use,
+       relative  references  refer  to the earliest group with the appropriate
        number. Consider, for example:
 
          (?|(a)|(b)) (c) (?-2)
 
        The first two capture groups (a) and (b) are both numbered 1, and group
-       (c)  is  number  2. When the reference (?-2) is encountered, the second
-       most recently opened parentheses has the number 1, but it is the  first
+       (c) is number 2. When the reference (?-2) is  encountered,  the  second
+       most  recently opened parentheses has the number 1, but it is the first
        such group (the (a) group) to which the recursion refers. This would be
-       the  same if an absolute reference (?1) was used. In other words, rela-
+       the same if an absolute reference (?1) was used. In other words,  rela-
        tive references are just a shorthand for computing a group number.
 
-       It is also possible to refer to subsequent capture groups,  by  writing
-       references  such  as  (?+2). However, these cannot be recursive because
-       the reference is not inside the parentheses that are  referenced.  They
-       are  always  non-recursive  subroutine  calls, as described in the next
+       It  is  also possible to refer to subsequent capture groups, by writing
+       references such as (?+2). However, these cannot  be  recursive  because
+       the  reference  is not inside the parentheses that are referenced. They
+       are always non-recursive subroutine calls, as  described  in  the  next
        section.
 
-       An alternative approach is to use named parentheses.  The  Perl  syntax
-       for  this  is  (?&name);  PCRE1's earlier syntax (?P>name) is also sup-
+       An  alternative  approach  is to use named parentheses. The Perl syntax
+       for this is (?&name); PCRE1's earlier syntax  (?P>name)  is  also  sup-
        ported. We could rewrite the above example as follows:
 
          (?<pn> \( ( [^()]++ | (?&pn) )* \) )
@@ -9272,57 +9288,57 @@ RECURSIVE PATTERNS
        used.
 
        The example pattern that we have been looking at contains nested unlim-
-       ited repeats, and so the use of a possessive  quantifier  for  matching
-       strings  of  non-parentheses  is important when applying the pattern to
+       ited  repeats,  and  so the use of a possessive quantifier for matching
+       strings of non-parentheses is important when applying  the  pattern  to
        strings that do not match. For example, when this pattern is applied to
 
          (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
 
-       it yields "no match" quickly. However, if a  possessive  quantifier  is
-       not  used, the match runs for a very long time indeed because there are
-       so many different ways the + and * repeats can carve  up  the  subject,
+       it  yields  "no  match" quickly. However, if a possessive quantifier is
+       not used, the match runs for a very long time indeed because there  are
+       so  many  different  ways the + and * repeats can carve up the subject,
        and all have to be tested before failure can be reported.
 
-       At  the  end  of a match, the values of capturing parentheses are those
-       from the outermost level. If you want to obtain intermediate values,  a
+       At the end of a match, the values of capturing  parentheses  are  those
+       from  the outermost level. If you want to obtain intermediate values, a
        callout function can be used (see below and the pcre2callout documenta-
        tion). If the pattern above is matched against
 
          (ab(cd)ef)
 
-       the  value  for  the  inner capturing parentheses (numbered 2) is "ef",
-       which is the last value taken on at the top level. If a  capture  group
-       is  not  matched  at  the top level, its final captured value is unset,
-       even if it was (temporarily) set at a deeper level during the  matching
+       the value for the inner capturing parentheses  (numbered  2)  is  "ef",
+       which  is  the last value taken on at the top level. If a capture group
+       is not matched at the top level, its final  captured  value  is  unset,
+       even  if it was (temporarily) set at a deeper level during the matching
        process.
 
-       Do  not  confuse  the (?R) item with the condition (R), which tests for
-       recursion.  Consider this pattern, which matches text in  angle  brack-
-       ets,  allowing for arbitrary nesting. Only digits are allowed in nested
-       brackets (that is, when recursing), whereas any characters are  permit-
+       Do not confuse the (?R) item with the condition (R),  which  tests  for
+       recursion.   Consider  this pattern, which matches text in angle brack-
+       ets, allowing for arbitrary nesting. Only digits are allowed in  nested
+       brackets  (that is, when recursing), whereas any characters are permit-
        ted at the outer level.
 
          < (?: (?(R) \d++  | [^<>]*+) | (?R)) * >
 
-       In  this  pattern,  (?(R) is the start of a conditional group, with two
-       different alternatives for the recursive and non-recursive  cases.  The
+       In this pattern, (?(R) is the start of a conditional  group,  with  two
+       different  alternatives  for the recursive and non-recursive cases. The
        (?R) item is the actual recursive call.
 
    Differences in recursion processing between PCRE2 and Perl
 
        Some former differences between PCRE2 and Perl no longer exist.
 
-       Before  release 10.30, recursion processing in PCRE2 differed from Perl
-       in that a recursive subroutine call was always  treated  as  an  atomic
-       group.  That is, once it had matched some of the subject string, it was
-       never re-entered, even if it contained untried alternatives  and  there
-       was  a  subsequent matching failure. (Historical note: PCRE implemented
+       Before release 10.30, recursion processing in PCRE2 differed from  Perl
+       in  that  a  recursive  subroutine call was always treated as an atomic
+       group. That is, once it had matched some of the subject string, it  was
+       never  re-entered,  even if it contained untried alternatives and there
+       was a subsequent matching failure. (Historical note:  PCRE  implemented
        recursion before Perl did.)
 
-       Starting with release 10.30, recursive subroutine calls are  no  longer
+       Starting  with  release 10.30, recursive subroutine calls are no longer
        treated as atomic. That is, they can be re-entered to try unused alter-
-       natives  if  there  is a matching failure later in the pattern. This is
-       now compatible with the way Perl works. If you want a  subroutine  call
+       natives if there is a matching failure later in the  pattern.  This  is
+       now  compatible  with the way Perl works. If you want a subroutine call
        to be atomic, you must explicitly enclose it in an atomic group.
 
        Supporting backtracking into recursions simplifies certain types of re-
@@ -9330,47 +9346,47 @@ RECURSIVE PATTERNS
 
          ^((.)(?1)\2|.?)$
 
-       The  second  branch  in the group matches a single central character in
-       the palindrome when there are an odd number of characters,  or  nothing
-       when  there  are  an even number of characters, but in order to work it
-       has to be able to try the second case when  the  rest  of  the  pattern
+       The second branch in the group matches a single  central  character  in
+       the  palindrome  when there are an odd number of characters, or nothing
+       when there are an even number of characters, but in order  to  work  it
+       has  to  be  able  to  try the second case when the rest of the pattern
        match fails. If you want to match typical palindromic phrases, the pat-
-       tern  has  to  ignore  all  non-word characters, which can be done like
+       tern has to ignore all non-word characters,  which  can  be  done  like
        this:
 
          ^\W*+((.)\W*+(?1)\W*+\2|\W*+.?)\W*+$
 
-       If run with the PCRE2_CASELESS option,  this  pattern  matches  phrases
-       such  as "A man, a plan, a canal: Panama!". Note the use of the posses-
-       sive quantifier *+ to avoid backtracking  into  sequences  of  non-word
+       If  run  with  the  PCRE2_CASELESS option, this pattern matches phrases
+       such as "A man, a plan, a canal: Panama!". Note the use of the  posses-
+       sive  quantifier  *+  to  avoid backtracking into sequences of non-word
        characters. Without this, PCRE2 takes a great deal longer (ten times or
-       more)  to  match typical phrases, and Perl takes so long that you think
+       more) to match typical phrases, and Perl takes so long that  you  think
        it has gone into a loop.
 
-       Another way in which PCRE2 and Perl used to differ in  their  recursion
-       processing  is  in  the  handling of captured values. Formerly in Perl,
-       when a group was called recursively or as a subroutine  (see  the  next
+       Another  way  in which PCRE2 and Perl used to differ in their recursion
+       processing is in the handling of captured  values.  Formerly  in  Perl,
+       when  a  group  was called recursively or as a subroutine (see the next
        section), it had no access to any values that were captured outside the
-       recursion,  whereas  in  PCRE2 these values can be referenced. Consider
+       recursion, whereas in PCRE2 these values can  be  referenced.  Consider
        this pattern:
 
          ^(.)(\1|a(?2))
 
-       This pattern matches "bab". The first capturing parentheses match  "b",
+       This  pattern matches "bab". The first capturing parentheses match "b",
        then in the second group, when the backreference \1 fails to match "b",
        the second alternative matches "a" and then recurses. In the recursion,
-       \1  does now match "b" and so the whole match succeeds. This match used
+       \1 does now match "b" and so the whole match succeeds. This match  used
        to fail in Perl, but in later versions (I tried 5.024) it now works.
 
 
 GROUPS AS SUBROUTINES
 
-       If the syntax for a recursive group call (either by number or by  name)
-       is  used  outside the parentheses to which it refers, it operates a bit
-       like a subroutine in a programming  language.  More  accurately,  PCRE2
+       If  the syntax for a recursive group call (either by number or by name)
+       is used outside the parentheses to which it refers, it operates  a  bit
+       like  a  subroutine  in  a programming language. More accurately, PCRE2
        treats the referenced group as an independent subpattern which it tries
-       to  match at the current matching position. The called group may be de-
-       fined before or after the reference. A numbered reference  can  be  ab-
+       to match at the current matching position. The called group may be  de-
+       fined  before  or  after the reference. A numbered reference can be ab-
        solute or relative, as in these examples:
 
          (...(absolute)...)...(?2)...
@@ -9381,106 +9397,106 @@ GROUPS AS SUBROUTINES
 
          (sens|respons)e and \1ibility
 
-       matches  "sense and sensibility" and "response and responsibility", but
+       matches "sense and sensibility" and "response and responsibility",  but
        not "sense and responsibility". If instead the pattern
 
          (sens|respons)e and (?1)ibility
 
-       is used, it does match "sense and responsibility" as well as the  other
-       two  strings.  Another  example  is  given  in the discussion of DEFINE
+       is  used, it does match "sense and responsibility" as well as the other
+       two strings. Another example is  given  in  the  discussion  of  DEFINE
        above.
 
-       Like recursions, subroutine calls used to be  treated  as  atomic,  but
-       this  changed  at  PCRE2 release 10.30, so backtracking into subroutine
-       calls can now occur. However, any capturing parentheses  that  are  set
+       Like  recursions,  subroutine  calls  used to be treated as atomic, but
+       this changed at PCRE2 release 10.30, so  backtracking  into  subroutine
+       calls  can  now  occur. However, any capturing parentheses that are set
        during the subroutine call revert to their previous values afterwards.
 
-       Processing  options such as case-independence are fixed when a group is
-       defined, so if it is used as  a  subroutine,  such  options  cannot  be
+       Processing options such as case-independence are fixed when a group  is
+       defined,  so  if  it  is  used  as a subroutine, such options cannot be
        changed for different calls. For example, consider this pattern:
 
          (abc)(?i:(?-1))
 
-       It  matches  "abcabc". It does not match "abcABC" because the change of
+       It matches "abcabc". It does not match "abcABC" because the  change  of
        processing option does not affect the called group.
 
-       The behaviour of backtracking control verbs in groups  when  called  as
+       The  behaviour  of  backtracking control verbs in groups when called as
        subroutines is described in the section entitled "Backtracking verbs in
        subroutines" below.
 
 
 ONIGURUMA SUBROUTINE SYNTAX
 
-       For  compatibility with Oniguruma, the non-Perl syntax \g followed by a
+       For compatibility with Oniguruma, the non-Perl syntax \g followed by  a
        name or a number enclosed either in angle brackets or single quotes, is
        an alternative syntax for calling a group as a subroutine, possibly re-
-       cursively. Here are two of the examples  used  above,  rewritten  using
+       cursively.  Here  are  two  of the examples used above, rewritten using
        this syntax:
 
          (?<pn> \( ( (?>[^()]+) | \g<pn> )* \) )
          (sens|respons)e and \g'1'ibility
 
-       PCRE2  supports an extension to Oniguruma: if a number is preceded by a
+       PCRE2 supports an extension to Oniguruma: if a number is preceded by  a
        plus or a minus sign it is taken as a relative reference. For example:
 
          (abc)(?i:\g<-1>)
 
-       Note that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are  not
-       synonymous.  The  former is a backreference; the latter is a subroutine
+       Note  that \g{...} (Perl syntax) and \g<...> (Oniguruma syntax) are not
+       synonymous. The former is a backreference; the latter is  a  subroutine
        call.
 
 
 CALLOUTS
 
        Perl has a feature whereby using the sequence (?{...}) causes arbitrary
-       Perl code to be obeyed in the middle of matching a regular  expression.
+       Perl  code to be obeyed in the middle of matching a regular expression.
        This makes it possible, amongst other things, to extract different sub-
        strings that match the same pair of parentheses when there is a repeti-
        tion.
 
-       PCRE2  provides  a  similar feature, but of course it cannot obey arbi-
-       trary Perl code. The feature is called "callout". The caller  of  PCRE2
-       provides  an  external  function  by putting its entry point in a match
-       context using the function pcre2_set_callout(), and then  passing  that
-       context  to  pcre2_match() or pcre2_dfa_match(). If no match context is
+       PCRE2 provides a similar feature, but of course it  cannot  obey  arbi-
+       trary  Perl  code. The feature is called "callout". The caller of PCRE2
+       provides an external function by putting its entry  point  in  a  match
+       context  using  the function pcre2_set_callout(), and then passing that
+       context to pcre2_match() or pcre2_dfa_match(). If no match  context  is
        passed, or if the callout entry point is set to NULL, callouts are dis-
        abled.
 
-       Within a regular expression, (?C<arg>) indicates a point at  which  the
-       external  function  is  to  be  called. There are two kinds of callout:
-       those with a numerical argument and those with a string argument.  (?C)
-       on  its  own with no argument is treated as (?C0). A numerical argument
-       allows the  application  to  distinguish  between  different  callouts.
-       String  arguments  were added for release 10.20 to make it possible for
-       script languages that use PCRE2 to embed short scripts within  patterns
+       Within  a  regular expression, (?C<arg>) indicates a point at which the
+       external function is to be called. There  are  two  kinds  of  callout:
+       those  with a numerical argument and those with a string argument. (?C)
+       on its own with no argument is treated as (?C0). A  numerical  argument
+       allows  the  application  to  distinguish  between  different callouts.
+       String arguments were added for release 10.20 to make it  possible  for
+       script  languages that use PCRE2 to embed short scripts within patterns
        in a similar way to Perl.
 
        During matching, when PCRE2 reaches a callout point, the external func-
-       tion  is  called.  It is provided with the number or string argument of
-       the callout, the position in the pattern, and one item of data that  is
+       tion is called. It is provided with the number or  string  argument  of
+       the  callout, the position in the pattern, and one item of data that is
        also set in the match block. The callout function may cause matching to
        proceed, to backtrack, or to fail.
 
-       By  default,  PCRE2  implements  a  number of optimizations at matching
-       time, and one side-effect is that sometimes callouts  are  skipped.  If
-       you  need all possible callouts to happen, you need to set options that
-       disable the relevant optimizations. More details, including a  complete
-       description  of  the programming interface to the callout function, are
+       By default, PCRE2 implements a  number  of  optimizations  at  matching
+       time,  and  one  side-effect is that sometimes callouts are skipped. If
+       you need all possible callouts to happen, you need to set options  that
+       disable  the relevant optimizations. More details, including a complete
+       description of the programming interface to the callout  function,  are
        given in the pcre2callout documentation.
 
    Callouts with numerical arguments
 
-       If you just want to have  a  means  of  identifying  different  callout
-       points,  put  a  number  less than 256 after the letter C. For example,
+       If  you  just  want  to  have  a means of identifying different callout
+       points, put a number less than 256 after the  letter  C.  For  example,
        this pattern has two callout points:
 
          (?C1)abc(?C2)def
 
-       If the PCRE2_AUTO_CALLOUT flag is passed to pcre2_compile(),  numerical
-       callouts  are  automatically installed before each item in the pattern.
-       They are all numbered 255. If there is a conditional group in the  pat-
+       If  the PCRE2_AUTO_CALLOUT flag is passed to pcre2_compile(), numerical
+       callouts are automatically installed before each item in  the  pattern.
+       They  are all numbered 255. If there is a conditional group in the pat-
        tern whose condition is an assertion, an additional callout is inserted
-       just  before the condition. An explicit callout may also be set at this
+       just before the condition. An explicit callout may also be set at  this
        position, as in this example:
 
          (?(?C9)(?=a)abc|def)
@@ -9490,78 +9506,78 @@ CALLOUTS
 
    Callouts with string arguments
 
-       A delimited string may be used instead of a number as a  callout  argu-
-       ment.  The  starting  delimiter  must be one of ` ' " ^ % # $ { and the
+       A  delimited  string may be used instead of a number as a callout argu-
+       ment. The starting delimiter must be one of ` ' " ^ % #  $  {  and  the
        ending delimiter is the same as the start, except for {, where the end-
-       ing delimiter is }. If  the  ending  delimiter  is  needed  within  the
+       ing  delimiter  is  }.  If  the  ending  delimiter is needed within the
        string, it must be doubled. For example:
 
          (?C'ab ''c'' d')xyz(?C{any text})pqr
 
-       The  doubling  is  removed  before  the string is passed to the callout
+       The doubling is removed before the string  is  passed  to  the  callout
        function.
 
 
 BACKTRACKING CONTROL
 
-       There are a number of special  "Backtracking  Control  Verbs"  (to  use
-       Perl's  terminology)  that  modify the behaviour of backtracking during
-       matching. They are generally of the form (*VERB) or (*VERB:NAME).  Some
+       There  are  a  number  of  special "Backtracking Control Verbs" (to use
+       Perl's terminology) that modify the behaviour  of  backtracking  during
+       matching.  They are generally of the form (*VERB) or (*VERB:NAME). Some
        verbs take either form, and may behave differently depending on whether
-       or  not  a  name  argument is present. The names are not required to be
+       or not a name argument is present. The names are  not  required  to  be
        unique within the pattern.
 
-       By default, for compatibility with Perl, a  name  is  any  sequence  of
+       By  default,  for  compatibility  with  Perl, a name is any sequence of
        characters that does not include a closing parenthesis. The name is not
-       processed  in  any  way,  and  it  is not possible to include a closing
-       parenthesis  in  the  name.   This  can  be  changed  by  setting   the
-       PCRE2_ALT_VERBNAMES  option,  but the result is no longer Perl-compati-
+       processed in any way, and it is  not  possible  to  include  a  closing
+       parenthesis   in  the  name.   This  can  be  changed  by  setting  the
+       PCRE2_ALT_VERBNAMES option, but the result is no  longer  Perl-compati-
        ble.
 
-       When PCRE2_ALT_VERBNAMES is set, backslash  processing  is  applied  to
-       verb  names  and  only  an unescaped closing parenthesis terminates the
-       name. However, the only backslash items that are permitted are \Q,  \E,
-       and  sequences such as \x{100} that define character code points. Char-
+       When  PCRE2_ALT_VERBNAMES  is  set,  backslash processing is applied to
+       verb names and only an unescaped  closing  parenthesis  terminates  the
+       name.  However, the only backslash items that are permitted are \Q, \E,
+       and sequences such as \x{100} that define character code points.  Char-
        acter type escapes such as \d are faulted.
 
        A closing parenthesis can be included in a name either as \) or between
-       \Q and \E. In addition to backslash processing, if  the  PCRE2_EXTENDED
+       \Q  and  \E. In addition to backslash processing, if the PCRE2_EXTENDED
        or PCRE2_EXTENDED_MORE option is also set, unescaped whitespace in verb
        names is skipped, and #-comments are recognized, exactly as in the rest
-       of  the  pattern.  PCRE2_EXTENDED and PCRE2_EXTENDED_MORE do not affect
+       of the pattern.  PCRE2_EXTENDED and PCRE2_EXTENDED_MORE do  not  affect
        verb names unless PCRE2_ALT_VERBNAMES is also set.
 
-       The maximum length of a name is 255 in the 8-bit library and  65535  in
-       the  16-bit and 32-bit libraries. If the name is empty, that is, if the
-       closing parenthesis immediately follows the colon, the effect is as  if
+       The  maximum  length of a name is 255 in the 8-bit library and 65535 in
+       the 16-bit and 32-bit libraries. If the name is empty, that is, if  the
+       closing  parenthesis immediately follows the colon, the effect is as if
        the colon were not there. Any number of these verbs may occur in a pat-
        tern. Except for (*ACCEPT), they may not be quantified.
 
-       Since  these  verbs  are  specifically related to backtracking, most of
-       them can be used only when the pattern is to be matched using the  tra-
+       Since these verbs are specifically related  to  backtracking,  most  of
+       them  can be used only when the pattern is to be matched using the tra-
        ditional matching function, because that uses a backtracking algorithm.
-       With  the  exception  of (*FAIL), which behaves like a failing negative
+       With the exception of (*FAIL), which behaves like  a  failing  negative
        assertion, the backtracking control verbs cause an error if encountered
        by the DFA matching function.
 
-       The behaviour of these verbs in repeated  groups,  assertions,  and  in
-       capture  groups  called  as subroutines (whether or not recursively) is
+       The  behaviour  of  these  verbs in repeated groups, assertions, and in
+       capture groups called as subroutines (whether or  not  recursively)  is
        documented below.
 
    Optimizations that affect backtracking verbs
 
        PCRE2 contains some optimizations that are used to speed up matching by
        running some checks at the start of each match attempt. For example, it
-       may know the minimum length of matching subject, or that  a  particular
+       may  know  the minimum length of matching subject, or that a particular
        character must be present. When one of these optimizations bypasses the
-       running  of  a  match,  any  included  backtracking  verbs will not, of
+       running of a match,  any  included  backtracking  verbs  will  not,  of
        course, be processed. You can suppress the start-of-match optimizations
-       by setting the PCRE2_NO_START_OPTIMIZE option when  calling  pcre2_com-
-       pile(),  or by starting the pattern with (*NO_START_OPT). There is more
+       by  setting  the PCRE2_NO_START_OPTIMIZE option when calling pcre2_com-
+       pile(), or by starting the pattern with (*NO_START_OPT). There is  more
        discussion of this option in the section entitled "Compiling a pattern"
        in the pcre2api documentation.
 
-       Experiments with Perl suggest that it too  has  similar  optimizations,
+       Experiments  with  Perl  suggest that it too has similar optimizations,
        and like PCRE2, turning them off can change the result of a match.
 
    Verbs that act immediately
@@ -9570,77 +9586,77 @@ BACKTRACKING CONTROL
 
           (*ACCEPT) or (*ACCEPT:NAME)
 
-       This  verb causes the match to end successfully, skipping the remainder
-       of the pattern. However, when it is inside  a  capture  group  that  is
+       This verb causes the match to end successfully, skipping the  remainder
+       of  the  pattern.  However,  when  it is inside a capture group that is
        called as a subroutine, only that group is ended successfully. Matching
        then continues at the outer level. If (*ACCEPT) in triggered in a posi-
-       tive  assertion,  the  assertion succeeds; in a negative assertion, the
+       tive assertion, the assertion succeeds; in a  negative  assertion,  the
        assertion fails.
 
-       If (*ACCEPT) is inside capturing parentheses, the data so far  is  cap-
+       If  (*ACCEPT)  is inside capturing parentheses, the data so far is cap-
        tured. For example:
 
          A((?:A|B(*ACCEPT)|C)D)
 
-       This  matches  "AB", "AAD", or "ACD"; when it matches "AB", "B" is cap-
+       This matches "AB", "AAD", or "ACD"; when it matches "AB", "B"  is  cap-
        tured by the outer parentheses.
 
-       (*ACCEPT) is the only backtracking verb that is allowed to  be  quanti-
-       fied  because  an  ungreedy  quantification with a minimum of zero acts
+       (*ACCEPT)  is  the only backtracking verb that is allowed to be quanti-
+       fied because an ungreedy quantification with a  minimum  of  zero  acts
        only when a backtrack happens. Consider, for example,
 
          (A(*ACCEPT)??B)C
 
-       where A, B, and C may be complex expressions. After matching  "A",  the
-       matcher  processes  "BC"; if that fails, causing a backtrack, (*ACCEPT)
-       is triggered and the match succeeds. In both cases, all but C  is  cap-
-       tured.  Whereas  (*COMMIT) (see below) means "fail on backtrack", a re-
+       where  A,  B, and C may be complex expressions. After matching "A", the
+       matcher processes "BC"; if that fails, causing a  backtrack,  (*ACCEPT)
+       is  triggered  and the match succeeds. In both cases, all but C is cap-
+       tured. Whereas (*COMMIT) (see below) means "fail on backtrack",  a  re-
        peated (*ACCEPT) of this type means "succeed on backtrack".
 
-       Warning: (*ACCEPT) should not be used within a script  run  group,  be-
-       cause  it causes an immediate exit from the group, bypassing the script
+       Warning:  (*ACCEPT)  should  not be used within a script run group, be-
+       cause it causes an immediate exit from the group, bypassing the  script
        run checking.
 
          (*FAIL) or (*FAIL:NAME)
 
-       This verb causes a matching failure, forcing backtracking to occur.  It
-       may  be  abbreviated  to  (*F).  It is equivalent to (?!) but easier to
+       This  verb causes a matching failure, forcing backtracking to occur. It
+       may be abbreviated to (*F). It is equivalent  to  (?!)  but  easier  to
        read. The Perl documentation notes that it is probably useful only when
        combined with (?{}) or (??{}). Those are, of course, Perl features that
-       are not present in PCRE2. The nearest equivalent is  the  callout  fea-
+       are  not  present  in PCRE2. The nearest equivalent is the callout fea-
        ture, as for example in this pattern:
 
          a+(?C)(*FAIL)
 
-       A  match  with the string "aaaa" always fails, but the callout is taken
+       A match with the string "aaaa" always fails, but the callout  is  taken
        before each backtrack happens (in this example, 10 times).
 
-       (*ACCEPT:NAME) and (*FAIL:NAME) behave the  same  as  (*MARK:NAME)(*AC-
-       CEPT)  and  (*MARK:NAME)(*FAIL),  respectively,  that  is, a (*MARK) is
+       (*ACCEPT:NAME)  and  (*FAIL:NAME)  behave the same as (*MARK:NAME)(*AC-
+       CEPT) and (*MARK:NAME)(*FAIL), respectively,  that  is,  a  (*MARK)  is
        recorded just before the verb acts.
 
    Recording which path was taken
 
-       There is one verb whose main purpose is to track how a  match  was  ar-
-       rived  at,  though  it also has a secondary use in conjunction with ad-
+       There  is  one  verb whose main purpose is to track how a match was ar-
+       rived at, though it also has a secondary use in  conjunction  with  ad-
        vancing the match starting point (see (*SKIP) below).
 
          (*MARK:NAME) or (*:NAME)
 
-       A name is always required with this verb. For all the other  backtrack-
+       A  name is always required with this verb. For all the other backtrack-
        ing control verbs, a NAME argument is optional.
 
-       When  a  match  succeeds, the name of the last-encountered mark name on
+       When a match succeeds, the name of the last-encountered  mark  name  on
        the matching path is passed back to the caller as described in the sec-
        tion entitled "Other information about the match" in the pcre2api docu-
-       mentation. This applies to all instances of (*MARK)  and  other  verbs,
+       mentation.  This  applies  to all instances of (*MARK) and other verbs,
        including those inside assertions and atomic groups. However, there are
-       differences  in  those  cases  when (*MARK) is used in conjunction with
+       differences in those cases when (*MARK) is  used  in  conjunction  with
        (*SKIP) as described below.
 
-       The mark name that was last encountered on the matching path is  passed
-       back.  A verb without a NAME argument is ignored for this purpose. Here
-       is an example of pcre2test output, where the "mark"  modifier  requests
+       The  mark name that was last encountered on the matching path is passed
+       back. A verb without a NAME argument is ignored for this purpose.  Here
+       is  an  example of pcre2test output, where the "mark" modifier requests
        the retrieval and outputting of (*MARK) data:
 
            re> /X(*MARK:A)Y|X(*MARK:B)Z/mark
@@ -9652,76 +9668,76 @@ BACKTRACKING CONTROL
          MK: B
 
        The (*MARK) name is tagged with "MK:" in this output, and in this exam-
-       ple  it indicates which of the two alternatives matched. This is a more
-       efficient way of obtaining this information than putting each  alterna-
+       ple it indicates which of the two alternatives matched. This is a  more
+       efficient  way of obtaining this information than putting each alterna-
        tive in its own capturing parentheses.
 
-       If  a  verb  with a name is encountered in a positive assertion that is
-       true, the name is recorded and passed back if it  is  the  last-encoun-
+       If a verb with a name is encountered in a positive  assertion  that  is
+       true,  the  name  is recorded and passed back if it is the last-encoun-
        tered. This does not happen for negative assertions or failing positive
        assertions.
 
-       After  a  partial match or a failed match, the last encountered name in
+       After a partial match or a failed match, the last encountered  name  in
        the entire match process is returned. For example:
 
            re> /X(*MARK:A)Y|X(*MARK:B)Z/mark
          data> XP
          No match, mark = B
 
-       Note that in this unanchored example the  mark  is  retained  from  the
+       Note  that  in  this  unanchored  example the mark is retained from the
        match attempt that started at the letter "X" in the subject. Subsequent
        match attempts starting at "P" and then with an empty string do not get
        as far as the (*MARK) item, but nevertheless do not reset it.
 
-       If  you  are  interested  in  (*MARK)  values after failed matches, you
-       should probably set the PCRE2_NO_START_OPTIMIZE option (see  above)  to
+       If you are interested in  (*MARK)  values  after  failed  matches,  you
+       should  probably  set the PCRE2_NO_START_OPTIMIZE option (see above) to
        ensure that the match is always attempted.
 
    Verbs that act after backtracking
 
        The following verbs do nothing when they are encountered. Matching con-
-       tinues  with  what follows, but if there is a subsequent match failure,
-       causing a backtrack to the verb, a failure is forced.  That  is,  back-
-       tracking  cannot  pass  to  the  left of the verb. However, when one of
+       tinues with what follows, but if there is a subsequent  match  failure,
+       causing  a  backtrack  to the verb, a failure is forced. That is, back-
+       tracking cannot pass to the left of the  verb.  However,  when  one  of
        these verbs appears inside an atomic group or in a lookaround assertion
-       that is true, its effect is confined to that group,  because  once  the
-       group  has been matched, there is never any backtracking into it. Back-
+       that  is  true,  its effect is confined to that group, because once the
+       group has been matched, there is never any backtracking into it.  Back-
        tracking from beyond an assertion or an atomic group ignores the entire
        group, and seeks a preceding backtracking point.
 
-       These verbs differ in exactly what kind of failure  occurs  when  back-
-       tracking  reaches  them.  The behaviour described below is what happens
-       when the verb is not in a subroutine or an assertion.  Subsequent  sec-
+       These  verbs  differ  in exactly what kind of failure occurs when back-
+       tracking reaches them. The behaviour described below  is  what  happens
+       when  the  verb is not in a subroutine or an assertion. Subsequent sec-
        tions cover these special cases.
 
          (*COMMIT) or (*COMMIT:NAME)
 
-       This  verb  causes the whole match to fail outright if there is a later
+       This verb causes the whole match to fail outright if there is  a  later
        matching failure that causes backtracking to reach it. Even if the pat-
-       tern is unanchored, no further attempts to find a  match  by  advancing
-       the  starting  point  take place. If (*COMMIT) is the only backtracking
+       tern  is  unanchored,  no further attempts to find a match by advancing
+       the starting point take place. If (*COMMIT) is  the  only  backtracking
        verb that is encountered, once it has been passed pcre2_match() is com-
        mitted to finding a match at the current starting point, or not at all.
        For example:
 
          a+(*COMMIT)b
 
-       This matches "xxaab" but not "aacaab". It can be thought of as  a  kind
+       This  matches  "xxaab" but not "aacaab". It can be thought of as a kind
        of dynamic anchor, or "I've started, so I must finish."
 
-       The  behaviour  of (*COMMIT:NAME) is not the same as (*MARK:NAME)(*COM-
-       MIT). It is like (*MARK:NAME) in that the name is remembered for  pass-
-       ing  back  to the caller. However, (*SKIP:NAME) searches only for names
+       The behaviour of (*COMMIT:NAME) is not the same  as  (*MARK:NAME)(*COM-
+       MIT).  It is like (*MARK:NAME) in that the name is remembered for pass-
+       ing back to the caller. However, (*SKIP:NAME) searches only  for  names
        that are set with (*MARK), ignoring those set by any of the other back-
        tracking verbs.
 
-       If there is more than one backtracking verb in a pattern,  a  different
-       one  that  follows  (*COMMIT) may be triggered first, so merely passing
+       If  there  is more than one backtracking verb in a pattern, a different
+       one that follows (*COMMIT) may be triggered first,  so  merely  passing
        (*COMMIT) during a match does not always guarantee that a match must be
        at this starting point.
 
        Note that (*COMMIT) at the start of a pattern is not the same as an an-
-       chor, unless PCRE2's start-of-match optimizations are  turned  off,  as
+       chor,  unless  PCRE2's  start-of-match optimizations are turned off, as
        shown in this output from pcre2test:
 
            re> /(*COMMIT)abc/
@@ -9732,68 +9748,68 @@ BACKTRACKING CONTROL
          data> xyzabc
          No match
 
-       For  the first pattern, PCRE2 knows that any match must start with "a",
-       so the optimization skips along the subject to "a" before applying  the
-       pattern  to the first set of data. The match attempt then succeeds. The
-       second pattern disables the optimization that skips along to the  first
-       character.  The  pattern  is  now  applied  starting at "x", and so the
-       (*COMMIT) causes the match to fail without trying  any  other  starting
+       For the first pattern, PCRE2 knows that any match must start with  "a",
+       so  the optimization skips along the subject to "a" before applying the
+       pattern to the first set of data. The match attempt then succeeds.  The
+       second  pattern disables the optimization that skips along to the first
+       character. The pattern is now applied  starting  at  "x",  and  so  the
+       (*COMMIT)  causes  the  match to fail without trying any other starting
        points.
 
          (*PRUNE) or (*PRUNE:NAME)
 
-       This  verb causes the match to fail at the current starting position in
+       This verb causes the match to fail at the current starting position  in
        the subject if there is a later matching failure that causes backtrack-
-       ing to reach it. If the pattern is unanchored, the  normal  "bumpalong"
-       advance  to  the next starting character then happens. Backtracking can
-       occur as usual to the left of (*PRUNE), before it is reached,  or  when
-       matching  to  the  right  of  (*PRUNE), but if there is no match to the
-       right, backtracking cannot cross (*PRUNE). In simple cases, the use  of
-       (*PRUNE)  is just an alternative to an atomic group or possessive quan-
+       ing  to  reach it. If the pattern is unanchored, the normal "bumpalong"
+       advance to the next starting character then happens.  Backtracking  can
+       occur  as  usual to the left of (*PRUNE), before it is reached, or when
+       matching to the right of (*PRUNE), but if there  is  no  match  to  the
+       right,  backtracking cannot cross (*PRUNE). In simple cases, the use of
+       (*PRUNE) is just an alternative to an atomic group or possessive  quan-
        tifier, but there are some uses of (*PRUNE) that cannot be expressed in
-       any other way. In an anchored pattern (*PRUNE) has the same  effect  as
+       any  other  way. In an anchored pattern (*PRUNE) has the same effect as
        (*COMMIT).
 
        The behaviour of (*PRUNE:NAME) is not the same as (*MARK:NAME)(*PRUNE).
        It is like (*MARK:NAME) in that the name is remembered for passing back
-       to  the  caller. However, (*SKIP:NAME) searches only for names set with
+       to the caller. However, (*SKIP:NAME) searches only for names  set  with
        (*MARK), ignoring those set by other backtracking verbs.
 
          (*SKIP)
 
-       This verb, when given without a name, is like (*PRUNE), except that  if
-       the  pattern  is unanchored, the "bumpalong" advance is not to the next
+       This  verb, when given without a name, is like (*PRUNE), except that if
+       the pattern is unanchored, the "bumpalong" advance is not to  the  next
        character, but to the position in the subject where (*SKIP) was encoun-
-       tered. (*SKIP) signifies that whatever text was matched leading  up  to
-       it  cannot  be part of a successful match if there is a later mismatch.
+       tered.  (*SKIP)  signifies that whatever text was matched leading up to
+       it cannot be part of a successful match if there is a  later  mismatch.
        Consider:
 
          a+(*SKIP)b
 
-       If the subject is "aaaac...",  after  the  first  match  attempt  fails
-       (starting  at  the  first  character in the string), the starting point
+       If  the  subject  is  "aaaac...",  after  the first match attempt fails
+       (starting at the first character in the  string),  the  starting  point
        skips on to start the next attempt at "c". Note that a possessive quan-
        tifier does not have the same effect as this example; although it would
-       suppress backtracking during the first match attempt,  the  second  at-
-       tempt  would  start  at  the second character instead of skipping on to
+       suppress  backtracking  during  the first match attempt, the second at-
+       tempt would start at the second character instead  of  skipping  on  to
        "c".
 
-       If (*SKIP) is used to specify a new starting position that is the  same
-       as  the  starting  position of the current match, or (by being inside a
-       lookbehind) earlier, the position specified by (*SKIP) is ignored,  and
+       If  (*SKIP) is used to specify a new starting position that is the same
+       as the starting position of the current match, or (by  being  inside  a
+       lookbehind)  earlier, the position specified by (*SKIP) is ignored, and
        instead the normal "bumpalong" occurs.
 
          (*SKIP:NAME)
 
-       When  (*SKIP)  has  an associated name, its behaviour is modified. When
-       such a (*SKIP) is triggered, the previous path through the  pattern  is
-       searched  for the most recent (*MARK) that has the same name. If one is
-       found, the "bumpalong" advance is to the subject position  that  corre-
-       sponds  to that (*MARK) instead of to where (*SKIP) was encountered. If
+       When (*SKIP) has an associated name, its behaviour  is  modified.  When
+       such  a  (*SKIP) is triggered, the previous path through the pattern is
+       searched for the most recent (*MARK) that has the same name. If one  is
+       found,  the  "bumpalong" advance is to the subject position that corre-
+       sponds to that (*MARK) instead of to where (*SKIP) was encountered.  If
        no (*MARK) with a matching name is found, the (*SKIP) is ignored.
 
-       The search for a (*MARK) name uses the normal  backtracking  mechanism,
-       which  means  that  it  does  not  see (*MARK) settings that are inside
+       The  search  for a (*MARK) name uses the normal backtracking mechanism,
+       which means that it does not  see  (*MARK)  settings  that  are  inside
        atomic groups or assertions, because they are never re-entered by back-
        tracking. Compare the following pcre2test examples:
 
@@ -9807,105 +9823,105 @@ BACKTRACKING CONTROL
           0: b
           1: b
 
-       In the first example, the (*MARK) setting is in an atomic group, so  it
+       In  the first example, the (*MARK) setting is in an atomic group, so it
        is not seen when (*SKIP:X) triggers, causing the (*SKIP) to be ignored.
-       This  allows  the second branch of the pattern to be tried at the first
-       character position.  In the second example, the (*MARK) setting is  not
-       in  an  atomic group. This allows (*SKIP:X) to find the (*MARK) when it
+       This allows the second branch of the pattern to be tried at  the  first
+       character  position.  In the second example, the (*MARK) setting is not
+       in an atomic group. This allows (*SKIP:X) to find the (*MARK)  when  it
        backtracks, and this causes a new matching attempt to start at the sec-
-       ond character. This time, the (*MARK) is never seen  because  "a"  does
+       ond  character.  This  time, the (*MARK) is never seen because "a" does
        not match "b", so the matcher immediately jumps to the second branch of
        the pattern.
 
-       Note  that (*SKIP:NAME) searches only for names set by (*MARK:NAME). It
+       Note that (*SKIP:NAME) searches only for names set by (*MARK:NAME).  It
        ignores names that are set by other backtracking verbs.
 
          (*THEN) or (*THEN:NAME)
 
-       This verb causes a skip to the next innermost  alternative  when  back-
-       tracking  reaches  it.  That  is,  it  cancels any further backtracking
-       within the current alternative. Its name  comes  from  the  observation
+       This  verb  causes  a skip to the next innermost alternative when back-
+       tracking reaches it. That  is,  it  cancels  any  further  backtracking
+       within  the  current  alternative.  Its name comes from the observation
        that it can be used for a pattern-based if-then-else block:
 
          ( COND1 (*THEN) FOO | COND2 (*THEN) BAR | COND3 (*THEN) BAZ ) ...
 
-       If  the COND1 pattern matches, FOO is tried (and possibly further items
-       after the end of the group if FOO succeeds); on  failure,  the  matcher
-       skips  to  the second alternative and tries COND2, without backtracking
-       into COND1. If that succeeds and BAR fails, COND3 is tried.  If  subse-
-       quently  BAZ fails, there are no more alternatives, so there is a back-
-       track to whatever came before the entire group. If (*THEN) is  not  in-
+       If the COND1 pattern matches, FOO is tried (and possibly further  items
+       after  the  end  of the group if FOO succeeds); on failure, the matcher
+       skips to the second alternative and tries COND2,  without  backtracking
+       into  COND1.  If that succeeds and BAR fails, COND3 is tried. If subse-
+       quently BAZ fails, there are no more alternatives, so there is a  back-
+       track  to  whatever came before the entire group. If (*THEN) is not in-
        side an alternation, it acts like (*PRUNE).
 
-       The  behaviour  of (*THEN:NAME) is not the same as (*MARK:NAME)(*THEN).
+       The behaviour of (*THEN:NAME) is not the same  as  (*MARK:NAME)(*THEN).
        It is like (*MARK:NAME) in that the name is remembered for passing back
-       to the caller. However, (*SKIP:NAME) searches only for names  set  with
+       to  the  caller. However, (*SKIP:NAME) searches only for names set with
        (*MARK), ignoring those set by other backtracking verbs.
 
-       A  group  that does not contain a | character is just a part of the en-
-       closing alternative; it is not a nested alternation with only  one  al-
+       A group that does not contain a | character is just a part of  the  en-
+       closing  alternative;  it is not a nested alternation with only one al-
        ternative. The effect of (*THEN) extends beyond such a group to the en-
-       closing  alternative.  Consider this pattern, where A, B, etc. are com-
-       plex pattern fragments that do not contain any  |  characters  at  this
+       closing alternative.  Consider this pattern, where A, B, etc. are  com-
+       plex  pattern  fragments  that  do not contain any | characters at this
        level:
 
          A (B(*THEN)C) | D
 
-       If  A and B are matched, but there is a failure in C, matching does not
+       If A and B are matched, but there is a failure in C, matching does  not
        backtrack into A; instead it moves to the next alternative, that is, D.
-       However, if the group containing (*THEN) is given  an  alternative,  it
+       However,  if  the  group containing (*THEN) is given an alternative, it
        behaves differently:
 
          A (B(*THEN)C | (*FAIL)) | D
 
        The effect of (*THEN) is now confined to the inner group. After a fail-
-       ure  in  C,  matching moves to (*FAIL), which causes the whole group to
-       fail because there are no more  alternatives  to  try.  In  this  case,
+       ure in C, matching moves to (*FAIL), which causes the  whole  group  to
+       fail  because  there  are  no  more  alternatives to try. In this case,
        matching does backtrack into A.
 
-       Note  that a conditional group is not considered as having two alterna-
-       tives, because only one is ever used. In other words, the  |  character
-       in  a  conditional group has a different meaning. Ignoring white space,
+       Note that a conditional group is not considered as having two  alterna-
+       tives,  because  only one is ever used. In other words, the | character
+       in a conditional group has a different meaning. Ignoring  white  space,
        consider:
 
          ^.*? (?(?=a) a | b(*THEN)c )
 
        If the subject is "ba", this pattern does not match. Because .*? is un-
-       greedy, it initially matches zero characters. The condition (?=a)  then
-       fails,  the  character  "b"  is matched, but "c" is not. At this point,
-       matching does not backtrack to .*? as might perhaps  be  expected  from
-       the  presence  of the | character. The conditional group is part of the
-       single alternative that comprises the whole pattern, and so  the  match
-       fails.  (If  there  was a backtrack into .*?, allowing it to match "b",
+       greedy,  it initially matches zero characters. The condition (?=a) then
+       fails, the character "b" is matched, but "c" is  not.  At  this  point,
+       matching  does  not  backtrack to .*? as might perhaps be expected from
+       the presence of the | character. The conditional group is part  of  the
+       single  alternative  that comprises the whole pattern, and so the match
+       fails. (If there was a backtrack into .*?, allowing it  to  match  "b",
        the match would succeed.)
 
-       The verbs just described provide four different "strengths" of  control
+       The  verbs just described provide four different "strengths" of control
        when subsequent matching fails. (*THEN) is the weakest, carrying on the
-       match  at  the next alternative. (*PRUNE) comes next, failing the match
-       at the current starting position, but allowing an advance to  the  next
-       character  (for an unanchored pattern). (*SKIP) is similar, except that
+       match at the next alternative. (*PRUNE) comes next, failing  the  match
+       at  the  current starting position, but allowing an advance to the next
+       character (for an unanchored pattern). (*SKIP) is similar, except  that
        the advance may be more than one character. (*COMMIT) is the strongest,
        causing the entire match to fail.
 
    More than one backtracking verb
 
-       If more than one backtracking verb is present in  a  pattern,  the  one
-       that  is  backtracked  onto first acts. For example, consider this pat-
+       If  more  than  one  backtracking verb is present in a pattern, the one
+       that is backtracked onto first acts. For example,  consider  this  pat-
        tern, where A, B, etc. are complex pattern fragments:
 
          (A(*COMMIT)B(*THEN)C|ABD)
 
-       If A matches but B fails, the backtrack to (*COMMIT) causes the  entire
+       If  A matches but B fails, the backtrack to (*COMMIT) causes the entire
        match to fail. However, if A and B match, but C fails, the backtrack to
-       (*THEN)  causes  the next alternative (ABD) to be tried. This behaviour
-       is consistent, but is not always the same as Perl's. It means  that  if
-       two  or  more backtracking verbs appear in succession, all but the last
+       (*THEN) causes the next alternative (ABD) to be tried.  This  behaviour
+       is  consistent,  but is not always the same as Perl's. It means that if
+       two or more backtracking verbs appear in succession, all but  the  last
        of them has no effect. Consider this example:
 
          ...(*COMMIT)(*PRUNE)...
 
        If there is a matching failure to the right, backtracking onto (*PRUNE)
-       causes it to be triggered, and its action is taken. There can never  be
+       causes  it to be triggered, and its action is taken. There can never be
        a backtrack onto (*COMMIT).
 
    Backtracking verbs in repeated groups
@@ -9915,50 +9931,50 @@ BACKTRACKING CONTROL
 
          /(a(*COMMIT)b)+ac/
 
-       If  the  subject  is  "abac", Perl matches unless its optimizations are
-       disabled, but PCRE2 always fails because the (*COMMIT)  in  the  second
+       If the subject is "abac", Perl matches  unless  its  optimizations  are
+       disabled,  but  PCRE2  always fails because the (*COMMIT) in the second
        repeat of the group acts.
 
    Backtracking verbs in assertions
 
-       (*FAIL)  in any assertion has its normal effect: it forces an immediate
-       backtrack. The behaviour of the other  backtracking  verbs  depends  on
-       whether  or  not the assertion is standalone or acting as the condition
+       (*FAIL) in any assertion has its normal effect: it forces an  immediate
+       backtrack.  The  behaviour  of  the other backtracking verbs depends on
+       whether or not the assertion is standalone or acting as  the  condition
        in a conditional group.
 
-       (*ACCEPT) in a standalone positive assertion causes  the  assertion  to
-       succeed  without  any  further  processing; captured strings and a mark
-       name (if set) are retained. In a standalone negative  assertion,  (*AC-
+       (*ACCEPT)  in  a  standalone positive assertion causes the assertion to
+       succeed without any further processing; captured  strings  and  a  mark
+       name  (if  set) are retained. In a standalone negative assertion, (*AC-
        CEPT) causes the assertion to fail without any further processing; cap-
        tured substrings and any mark name are discarded.
 
-       If  the  assertion is a condition, (*ACCEPT) causes the condition to be
-       true for a positive assertion and false for a  negative  one;  captured
+       If the assertion is a condition, (*ACCEPT) causes the condition  to  be
+       true  for  a  positive assertion and false for a negative one; captured
        substrings are retained in both cases.
 
        The remaining verbs act only when a later failure causes a backtrack to
-       reach  them. This means that, for the Perl-compatible assertions, their
+       reach them. This means that, for the Perl-compatible assertions,  their
        effect is confined to the assertion, because Perl lookaround assertions
        are atomic. A backtrack that occurs after such an assertion is complete
-       does not jump back into  the  assertion.  Note  in  particular  that  a
-       (*MARK)  name  that is set in an assertion is not "seen" by an instance
+       does  not  jump  back  into  the  assertion.  Note in particular that a
+       (*MARK) name that is set in an assertion is not "seen" by  an  instance
        of (*SKIP:NAME) later in the pattern.
 
-       PCRE2 now supports non-atomic positive assertions, as described in  the
-       section  entitled  "Non-atomic assertions" above. These assertions must
-       be standalone (not used as conditions). They are  not  Perl-compatible.
-       For  these assertions, a later backtrack does jump back into the asser-
-       tion, and therefore verbs such as (*COMMIT) can be triggered  by  back-
+       PCRE2  now supports non-atomic positive assertions, as described in the
+       section entitled "Non-atomic assertions" above. These  assertions  must
+       be  standalone  (not used as conditions). They are not Perl-compatible.
+       For these assertions, a later backtrack does jump back into the  asser-
+       tion,  and  therefore verbs such as (*COMMIT) can be triggered by back-
        tracks from later in the pattern.
 
-       The  effect of (*THEN) is not allowed to escape beyond an assertion. If
-       there are no more branches to try, (*THEN) causes a positive  assertion
+       The effect of (*THEN) is not allowed to escape beyond an assertion.  If
+       there  are no more branches to try, (*THEN) causes a positive assertion
        to be false, and a negative assertion to be true.
 
-       The  other  backtracking verbs are not treated specially if they appear
-       in a standalone positive assertion. In a  conditional  positive  asser-
+       The other backtracking verbs are not treated specially if  they  appear
+       in  a  standalone  positive assertion. In a conditional positive asser-
        tion, backtracking (from within the assertion) into (*COMMIT), (*SKIP),
-       or  (*PRUNE) causes the condition to be false. However, for both stand-
+       or (*PRUNE) causes the condition to be false. However, for both  stand-
        alone and conditional negative assertions, backtracking into (*COMMIT),
        (*SKIP), or (*PRUNE) causes the assertion to be true, without consider-
        ing any further alternative branches.
@@ -9968,26 +9984,26 @@ BACKTRACKING CONTROL
        These behaviours occur whether or not the group is called recursively.
 
        (*ACCEPT) in a group called as a subroutine causes the subroutine match
-       to succeed without any further processing. Matching then continues  af-
-       ter  the  subroutine call. Perl documents this behaviour. Perl's treat-
+       to  succeed without any further processing. Matching then continues af-
+       ter the subroutine call. Perl documents this behaviour.  Perl's  treat-
        ment of the other verbs in subroutines is different in some cases.
 
-       (*FAIL) in a group called as a subroutine has  its  normal  effect:  it
+       (*FAIL)  in  a  group  called as a subroutine has its normal effect: it
        forces an immediate backtrack.
 
-       (*COMMIT),  (*SKIP),  and  (*PRUNE)  cause the subroutine match to fail
-       when triggered by being backtracked to in a group called as  a  subrou-
+       (*COMMIT), (*SKIP), and (*PRUNE) cause the  subroutine  match  to  fail
+       when  triggered  by being backtracked to in a group called as a subrou-
        tine. There is then a backtrack at the outer level.
 
        (*THEN), when triggered, skips to the next alternative in the innermost
-       enclosing  group that has alternatives (its normal behaviour). However,
+       enclosing group that has alternatives (its normal behaviour).  However,
        if there is no such group within the subroutine's group, the subroutine
        match fails and there is a backtrack at the outer level.
 
 
 SEE ALSO
 
-       pcre2api(3),   pcre2callout(3),    pcre2matching(3),    pcre2syntax(3),
+       pcre2api(3),    pcre2callout(3),    pcre2matching(3),   pcre2syntax(3),
        pcre2(3).
 
 
@@ -10000,11 +10016,11 @@ AUTHOR
 
 REVISION
 
-       Last updated: 19 January 2024
+       Last updated: 04 June 2024
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE2 10.43                     19 January 2024                PCRE2PATTERN(3)
+PCRE2 10.44                      04 June 2024                  PCRE2PATTERN(3)
 ------------------------------------------------------------------------------
 
 
diff --git a/doc/pcre2_set_max_pattern_compiled_length.3 b/doc/pcre2_set_max_pattern_compiled_length.3
new file mode 100644 (file)
index 0000000..472a7bb
--- /dev/null
@@ -0,0 +1,32 @@
+.TH PCRE2_SET_MAX_PATTERN_COMPILED_LENGTH 3 "24 April 2024" "PCRE2 10.44"
+.SH NAME
+PCRE2 - Perl-compatible regular expressions (revised API)
+.SH SYNOPSIS
+.rs
+.sp
+.B #include <pcre2.h>
+.PP
+.nf
+.B int pcre2_set_max_pattern_compiled_length(
+.B "  pcre2_compile_context *\fIccontext\fP, PCRE2_SIZE \fIvalue\fP);"
+.fi
+.
+.SH DESCRIPTION
+.rs
+.sp
+This function sets, in a compile context, the maximum size (in bytes) for the
+memory needed to hold the compiled version of a pattern that is compiled with
+this context. The result is always zero. If a pattern that is passed to
+\fBpcre2_compile()\fP with this context needs more memory, an error is
+generated. The default is the largest number that a PCRE2_SIZE variable can
+hold, which is effectively unlimited.
+.P
+There is a complete description of the PCRE2 native API in the
+.\" HREF
+\fBpcre2api\fP
+.\"
+page and a description of the POSIX API in the
+.\" HREF
+\fBpcre2posix\fP
+.\"
+page.
index 47990052fb9db38bf86f445ed50be1170d9c1ee3..6028d626778021b40d0fd077d6be2cc9d2033abe 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2API 3 "27 January 2024" "PCRE2 10.43"
+.TH PCRE2API 3 "24 April 2024" "PCRE2 10.44"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .sp
@@ -101,6 +101,9 @@ document for an overview of all the PCRE2 documentation.
 .B int pcre2_set_max_pattern_length(pcre2_compile_context *\fIccontext\fP,
 .B "  PCRE2_SIZE \fIvalue\fP);"
 .sp
+.B int pcre2_set_max_pattern_compiled_length(
+.B "  pcre2_compile_context *\fIccontext\fP, PCRE2_SIZE \fIvalue\fP);"
+.sp
 .B int pcre2_set_max_varlookbehind(pcre2_compile_contest *\fIccontext\fP,
 .B "  uint32_t \fIvalue\fP);
 .sp
@@ -805,6 +808,18 @@ external sources can limit their size. The default is the largest number that a
 PCRE2_SIZE variable can hold, which is effectively unlimited.
 .sp
 .nf
+.B int pcre2_set_max_pattern_compiled_length(
+.B "  pcre2_compile_context *\fIccontext\fP, PCRE2_SIZE \fIvalue\fP);"
+.fi
+.sp
+This sets a maximum size, in bytes, for the memory needed to hold the compiled
+version of a pattern that is compiled with this context. If the pattern needs
+more memory, an error is generated. This facility is provided so that
+applications that accept patterns from external sources can limit the amount of
+memory they use. The default is the largest number that a PCRE2_SIZE variable
+can hold, which is effectively unlimited.
+.sp
+.nf
 .B int pcre2_set_max_varlookbehind(pcre2_compile_contest *\fIccontext\fP,
 .B "  uint32_t \fIvalue\fP);
 .fi
@@ -4167,6 +4182,6 @@ Cambridge, England.
 .rs
 .sp
 .nf
-Last updated: 27 January 2024
+Last updated: 24 April 2024
 Copyright (c) 1997-2024 University of Cambridge.
 .fi
index 72316126543cee0900a6cabff3e2dbb6d1c50211..1df4ebd234e01dd29c78e8803f307fcecfc1905e 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2BUILD 3 "24 November" "PCRE2 10.43"
+.TH PCRE2BUILD 3 "15 April 2024" "PCRE2 10.44"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .
@@ -16,7 +16,8 @@ Autotools. Also in the distribution are files to support building using
 .\"
 contains general information about building with Autotools (some of which is
 repeated below), and also has some comments about building on various operating
-systems. There is a lot more information about building PCRE2 without using
+systems. The files in the \fBvms\fP directory support building under OpenVMS.
+There is a lot more information about building PCRE2 without using
 Autotools (including information about using \fBCMake\fP and building "by
 hand") in the text file called
 .\" HTML <a href="NON-AUTOTOOLS-BUILD.txt">
@@ -659,6 +660,6 @@ Cambridge, England.
 .rs
 .sp
 .nf
-Last updated: 24 November 2023
-Copyright (c) 1997-2023 University of Cambridge.
+Last updated: 15 April 2024
+Copyright (c) 1997-2024 University of Cambridge.
 .fi
index 73f26e7d21ed71deca4b5611e4a7914064be9a8e..0453a94900b8093e482d6f00cf3294db4e45d637 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2DEMO 3 "16 February 2024" "PCRE2 10.43-RC1"
+.TH PCRE2DEMO 3 " 7 June 2024" "PCRE2 10.44"
 .\"AUTOMATICALLY GENERATED BY PrepareRelease - do not EDIT!
 .SH NAME
 PCRE2DEMO - A demonstration C program for PCRE2
index 9b40ef519f081fcfccc8455fb27af1d138083b13..8798089f459f9122d2b1efd9d7eb39558c03888a 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2JIT 3 "23 January 2023" "PCRE2 10.43"
+.TH PCRE2JIT 3 "21 February 2024" "PCRE2 10.43"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 JUST-IN-TIME COMPILER SUPPORT"
@@ -27,7 +27,7 @@ JIT support is an optional feature of PCRE2. The "configure" option
 you want to use JIT. The support is limited to the following hardware
 platforms:
 .sp
-  ARM 32-bit (v5, v7, and Thumb2)
+  ARM 32-bit (v7, and Thumb2)
   ARM 64-bit
   IBM s390x 64 bit
   Intel x86 32-bit and 64-bit
@@ -476,6 +476,6 @@ Cambridge, England.
 .rs
 .sp
 .nf
-Last updated: 23 January 2023
-Copyright (c) 1997-2023 University of Cambridge.
+Last updated: 21 February 2024
+Copyright (c) 1997-2024 University of Cambridge.
 .fi
index af107b46a65dd121876ff333fb01698d9487daf6..c3ccb0b61f32de9e8263c9b792eafa4b7d22afb7 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2PATTERN 3 "19 January 2024" "PCRE2 10.43"
+.TH PCRE2PATTERN 3 "04 June 2024" "PCRE2 10.44"
 .SH NAME
 PCRE2 - Perl-compatible regular expressions (revised API)
 .SH "PCRE2 REGULAR EXPRESSION DETAILS"
@@ -1027,15 +1027,17 @@ are of five types: L, V, T, LV, and LVT. An L character may be followed by an
 L, V, LV, or LVT character; an LV or V character may be followed by a V or T
 character; an LVT or T character may be followed only by a T character.
 .P
-4. Do not end before extending characters or spacing marks or the "zero-width
-joiner" character. Characters with the "mark" property always have the
+4. Do not end before extending characters or spacing marks or the zero-width
+joiner (ZWJ) character. Characters with the "mark" property always have the
 "extend" grapheme breaking property.
 .P
 5. Do not end after prepend characters.
 .P
-6. Do not break within emoji modifier sequences or emoji zwj sequences. That
-is, do not break between characters with the Extended_Pictographic property.
-Extend and ZWJ characters are allowed between the characters.
+6. Do not end within emoji modifier sequences or emoji ZWJ (zero-width
+joiner) sequences. An emoji ZWJ sequence consists of a character with the
+Extended_Pictographic property, optionally followed by one or more characters
+with the Extend property, followed by the ZWJ character, followed by another
+Extended_Pictographic character.
 .P
 7. Do not break within emoji flag sequences. That is, do not break between
 regional indicator (RI) characters if there are an odd number of RI characters
@@ -1844,7 +1846,7 @@ the naming of capture groups. This feature was not added to Perl until release
 using the Python syntax. PCRE2 supports both the Perl and the Python syntax.
 .P
 In PCRE2, a capture group can be named in one of three ways: (?<name>...) or
-(?'name'...) as in Perl, or (?P<name>...) as in Python. Names may be up to 32
+(?'name'...) as in Perl, or (?P<name>...) as in Python. Names may be up to 128
 code units long. When PCRE2_UTF is not set, they may contain only ASCII
 alphanumeric characters and underscores, but must start with a non-digit. When
 PCRE2_UTF is set, the syntax of group names is extended to allow any Unicode
@@ -3889,6 +3891,6 @@ Cambridge, England.
 .rs
 .sp
 .nf
-Last updated: 19 January 2024
+Last updated: 04 June 2024
 Copyright (c) 1997-2024 University of Cambridge.
 .fi
index 5e6f36a63896b8113af260f0cbee68169092b499..c7df4183464e0d3e32a1c5326955190e3946f61b 100644 (file)
@@ -1,4 +1,4 @@
-.TH PCRE2TEST 1 "27 January 2024" "PCRE 10.43"
+.TH PCRE2TEST 1 "24 April 2024" "PCRE 10.44"
 .SH NAME
 pcre2test - a program for testing Perl-compatible regular expressions.
 .SH SYNOPSIS
@@ -652,7 +652,9 @@ heavily used in the test files.
       jitfast                   use JIT fast path
       jitverify                 verify JIT use
       locale=<name>             use this locale
-      max_pattern_length=<n>    set maximum pattern length
+      max_pattern_compiled      ) set maximum compiled pattern
+                 _length=<n>    )   length (bytes)
+      max_pattern_length=<n>    set maximum pattern length (code units)
       max_varlookbehind=<n>     set maximum variable lookbehind length
       memory                    show memory used
       newline=<type>            set newline type
@@ -976,6 +978,15 @@ causes a compilation error. The default is the largest number a PCRE2_SIZE
 variable can hold (essentially unlimited).
 .
 .
+.SS "Limiting the size of a compiled pattern"
+.rs
+.sp
+The \fBmax_pattern_compiled_length\fP modifier sets a limit, in bytes, to the
+amount of memory used by a compiled pattern. Breaching the limit causes a
+compilation error. The default is the largest number a PCRE2_SIZE variable can
+hold (essentially unlimited).
+.
+.
 .\" HTML <a name="posixwrapper"></a>
 .SS "Using the POSIX wrapper API"
 .rs
@@ -2170,6 +2181,6 @@ Cambridge, England.
 .rs
 .sp
 .nf
-Last updated: 27 January 2024
+Last updated: 24 April 2024
 Copyright (c) 1997-2024 University of Cambridge.
 .fi
index d5750b487085e4a9d62cb89520fca799c941ecfe..ddb491d7e7c18aeb5d898bc858db9f22cdd4b517 100644 (file)
@@ -630,7 +630,9 @@ PATTERN MODIFIERS
              jitfast                   use JIT fast path
              jitverify                 verify JIT use
              locale=<name>             use this locale
-             max_pattern_length=<n>    set maximum pattern length
+             max_pattern_compiled      ) set maximum compiled pattern
+                        _length=<n>    )   length (bytes)
+             max_pattern_length=<n>    set maximum pattern length (code units)
              max_varlookbehind=<n>     set maximum variable lookbehind length
              memory                    show memory used
              newline=<type>            set newline type
@@ -913,14 +915,21 @@ PATTERN MODIFIERS
        causes a compilation  error.  The  default  is  the  largest  number  a
        PCRE2_SIZE variable can hold (essentially unlimited).
 
+   Limiting the size of a compiled pattern
+
+       The max_pattern_compiled_length modifier sets a limit, in bytes, to the
+       amount of memory used by a compiled pattern. Breaching the limit causes
+       a  compilation  error.  The  default is the largest number a PCRE2_SIZE
+       variable can hold (essentially unlimited).
+
    Using the POSIX wrapper API
 
-       The  posix  and posix_nosub modifiers cause pcre2test to call PCRE2 via
-       the POSIX wrapper API rather than its native API. When  posix_nosub  is
-       used,  the  POSIX  option  REG_NOSUB  is passed to regcomp(). The POSIX
-       wrapper supports only the 8-bit library. Note that it  does  not  imply
+       The posix and posix_nosub modifiers cause pcre2test to call  PCRE2  via
+       the  POSIX  wrapper API rather than its native API. When posix_nosub is
+       used, the POSIX option REG_NOSUB is  passed  to  regcomp().  The  POSIX
+       wrapper  supports  only  the 8-bit library. Note that it does not imply
        POSIX matching semantics; for more detail see the pcre2posix documenta-
-       tion.  The  following  pattern  modifiers set options for the regcomp()
+       tion. The following pattern modifiers set  options  for  the  regcomp()
        function:
 
          caseless           REG_ICASE
@@ -930,42 +939,42 @@ PATTERN MODIFIERS
          ucp                REG_UCP        )   the POSIX standard
          utf                REG_UTF8       )
 
-       The regerror_buffsize modifier specifies a size for  the  error  buffer
-       that  is  passed to regerror() in the event of a compilation error. For
+       The  regerror_buffsize  modifier  specifies a size for the error buffer
+       that is passed to regerror() in the event of a compilation  error.  For
        example:
 
          /abc/posix,regerror_buffsize=20
 
-       This provides a means of testing the behaviour of regerror()  when  the
-       buffer  is  too  small  for the error message. If this modifier has not
+       This  provides  a means of testing the behaviour of regerror() when the
+       buffer is too small for the error message. If  this  modifier  has  not
        been set, a large buffer is used.
 
-       The aftertext and allaftertext subject modifiers work as described  be-
+       The  aftertext and allaftertext subject modifiers work as described be-
        low. All other modifiers are either ignored, with a warning message, or
        cause an error.
 
-       The  pattern  is passed to regcomp() as a zero-terminated string by de-
+       The pattern is passed to regcomp() as a zero-terminated string  by  de-
        fault, but if the use_length or hex modifiers are set, the REG_PEND ex-
        tension is used to pass it by length.
 
    Testing the stack guard feature
 
-       The stackguard modifier is used  to  test  the  use  of  pcre2_set_com-
-       pile_recursion_guard(),  a  function  that  is provided to enable stack
-       availability to be checked during compilation (see the  pcre2api  docu-
-       mentation  for  details).  If  the  number specified by the modifier is
+       The  stackguard  modifier  is  used  to  test the use of pcre2_set_com-
+       pile_recursion_guard(), a function that is  provided  to  enable  stack
+       availability  to  be checked during compilation (see the pcre2api docu-
+       mentation for details). If the number  specified  by  the  modifier  is
        greater than zero, pcre2_set_compile_recursion_guard() is called to set
-       up callback from pcre2_compile() to a local function. The  argument  it
-       receives  is  the current nesting parenthesis depth; if this is greater
+       up  callback  from pcre2_compile() to a local function. The argument it
+       receives is the current nesting parenthesis depth; if this  is  greater
        than the value given by the modifier, non-zero is returned, causing the
        compilation to be aborted.
 
    Using alternative character tables
 
-       The value specified for the tables modifier must be one of  the  digits
+       The  value  specified for the tables modifier must be one of the digits
        0, 1, 2, or 3. It causes a specific set of built-in character tables to
-       be  passed to pcre2_compile(). This is used in the PCRE2 tests to check
-       behaviour with different character tables. The digit specifies the  ta-
+       be passed to pcre2_compile(). This is used in the PCRE2 tests to  check
+       behaviour  with different character tables. The digit specifies the ta-
        bles as follows:
 
          0   do not pass any special character tables
@@ -976,15 +985,15 @@ PATTERN MODIFIERS
 
        In tables 2, some characters whose codes are greater than 128 are iden-
        tified as letters, digits, spaces, etc. Tables 3 can be used only after
-       a  #loadtables  command has loaded them from a binary file. Setting al-
+       a #loadtables command has loaded them from a binary file.  Setting  al-
        ternate character tables and a locale are mutually exclusive.
 
    Setting certain match controls
 
        The following modifiers are really subject modifiers, and are described
-       under "Subject Modifiers" below. However, they may  be  included  in  a
-       pattern's  modifier  list, in which case they are applied to every sub-
-       ject line that is processed with that pattern. These modifiers  do  not
+       under  "Subject  Modifiers"  below.  However, they may be included in a
+       pattern's modifier list, in which case they are applied to  every  sub-
+       ject  line  that is processed with that pattern. These modifiers do not
        affect the compilation process.
 
              aftertext                   show text after match
@@ -1010,39 +1019,39 @@ PATTERN MODIFIERS
              substitute_unknown_unset    use PCRE2_SUBSTITUTE_UNKNOWN_UNSET
              substitute_unset_empty      use PCRE2_SUBSTITUTE_UNSET_EMPTY
 
-       These  modifiers may not appear in a #pattern command. If you want them
+       These modifiers may not appear in a #pattern command. If you want  them
        as defaults, set them in a #subject command.
 
    Specifying literal subject lines
 
-       If the subject_literal modifier is present on a pattern, all  the  sub-
+       If  the  subject_literal modifier is present on a pattern, all the sub-
        ject lines that it matches are taken as literal strings, with no inter-
-       pretation  of  backslashes. It is not possible to set subject modifiers
-       on such lines, but any that are set as defaults by a  #subject  command
+       pretation of backslashes. It is not possible to set  subject  modifiers
+       on  such  lines, but any that are set as defaults by a #subject command
        are recognized.
 
    Saving a compiled pattern
 
-       When  a  pattern with the push modifier is successfully compiled, it is
-       pushed onto a stack of compiled patterns,  and  pcre2test  expects  the
-       next  line to contain a new pattern (or a command) instead of a subject
+       When a pattern with the push modifier is successfully compiled,  it  is
+       pushed  onto  a  stack  of compiled patterns, and pcre2test expects the
+       next line to contain a new pattern (or a command) instead of a  subject
        line. This facility is used when saving compiled patterns to a file, as
-       described in the section entitled "Saving and restoring  compiled  pat-
-       terns"  below.  If pushcopy is used instead of push, a copy of the com-
-       piled pattern is stacked, leaving the original  as  current,  ready  to
-       match  the  following  input  lines. This provides a way of testing the
-       pcre2_code_copy() function.  The push and pushcopy  modifiers  are  in-
-       compatible  with compilation modifiers such as global that act at match
+       described  in  the section entitled "Saving and restoring compiled pat-
+       terns" below.  If pushcopy is used instead of push, a copy of the  com-
+       piled  pattern  is  stacked,  leaving the original as current, ready to
+       match the following input lines. This provides a  way  of  testing  the
+       pcre2_code_copy()  function.   The push and pushcopy  modifiers are in-
+       compatible with compilation modifiers such as global that act at  match
        time. Any that are specified are ignored (for the stacked copy), with a
-       warning message, except for replace, which causes an error.  Note  that
-       jitverify,  which  is allowed, does not carry through to any subsequent
+       warning  message,  except for replace, which causes an error. Note that
+       jitverify, which is allowed, does not carry through to  any  subsequent
        matching that uses a stacked pattern.
 
    Testing foreign pattern conversion
 
-       The experimental foreign pattern conversion functions in PCRE2  can  be
-       tested  by  setting the convert modifier. Its argument is a colon-sepa-
-       rated list  of  options,  which  set  the  equivalent  option  for  the
+       The  experimental  foreign pattern conversion functions in PCRE2 can be
+       tested by setting the convert modifier. Its argument is  a  colon-sepa-
+       rated  list  of  options,  which  set  the  equivalent  option  for the
        pcre2_pattern_convert() function:
 
          glob                    PCRE2_CONVERT_GLOB
@@ -1054,19 +1063,19 @@ PATTERN MODIFIERS
 
        The "unset" value is useful for turning off a default that has been set
        by a #pattern command. When one of these options is set, the input pat-
-       tern  is  passed  to pcre2_pattern_convert(). If the conversion is suc-
-       cessful, the result is reflected in  the  output  and  then  passed  to
+       tern is passed to pcre2_pattern_convert(). If the  conversion  is  suc-
+       cessful,  the  result  is  reflected  in  the output and then passed to
        pcre2_compile(). The normal utf and no_utf_check options, if set, cause
-       the  PCRE2_CONVERT_UTF  and  PCRE2_CONVERT_NO_UTF_CHECK  options  to be
+       the PCRE2_CONVERT_UTF  and  PCRE2_CONVERT_NO_UTF_CHECK  options  to  be
        passed to pcre2_pattern_convert().
 
        By default, the conversion function is allowed to allocate a buffer for
-       its output. However, if the convert_length modifier is set to  a  value
-       greater  than zero, pcre2test passes a buffer of the given length. This
+       its  output.  However, if the convert_length modifier is set to a value
+       greater than zero, pcre2test passes a buffer of the given length.  This
        makes it possible to test the length check.
 
-       The convert_glob_escape and  convert_glob_separator  modifiers  can  be
-       used  to  specify the escape and separator characters for glob process-
+       The  convert_glob_escape  and  convert_glob_separator  modifiers can be
+       used to specify the escape and separator characters for  glob  process-
        ing, overriding the defaults, which are operating-system dependent.
 
 
@@ -1077,7 +1086,7 @@ SUBJECT MODIFIERS
 
    Setting match options
 
-       The   following   modifiers   set   options   for   pcre2_match()    or
+       The    following   modifiers   set   options   for   pcre2_match()   or
        pcre2_dfa_match(). See pcreapi for a description of their effects.
 
              anchored                   set PCRE2_ANCHORED
@@ -1094,35 +1103,35 @@ SUBJECT MODIFIERS
              partial_hard (or ph)       set PCRE2_PARTIAL_HARD
              partial_soft (or ps)       set PCRE2_PARTIAL_SOFT
 
-       The  partial matching modifiers are provided with abbreviations because
+       The partial matching modifiers are provided with abbreviations  because
        they appear frequently in tests.
 
-       If the posix or posix_nosub modifier was present on the pattern,  caus-
+       If  the posix or posix_nosub modifier was present on the pattern, caus-
        ing the POSIX wrapper API to be used, the only option-setting modifiers
        that have any effect are notbol, notempty, and noteol, causing REG_NOT-
-       BOL,  REG_NOTEMPTY,  and  REG_NOTEOL,  respectively,  to  be  passed to
+       BOL, REG_NOTEMPTY,  and  REG_NOTEOL,  respectively,  to  be  passed  to
        regexec(). The other modifiers are ignored, with a warning message.
 
-       There is one additional modifier that can be used with the POSIX  wrap-
+       There  is one additional modifier that can be used with the POSIX wrap-
        per. It is ignored (with a warning) if used for non-POSIX matching.
 
              posix_startend=<n>[:<m>]
 
-       This  causes  the  subject  string  to be passed to regexec() using the
-       REG_STARTEND option, which uses offsets to specify which  part  of  the
-       string  is  searched.  If  only  one number is given, the end offset is
-       passed as the end of the subject string. For more detail  of  REG_STAR-
-       TEND,  see the pcre2posix documentation. If the subject string contains
-       binary zeros (coded as escapes such as \x{00}  because  pcre2test  does
+       This causes the subject string to be  passed  to  regexec()  using  the
+       REG_STARTEND  option,  which  uses offsets to specify which part of the
+       string is searched. If only one number is  given,  the  end  offset  is
+       passed  as  the end of the subject string. For more detail of REG_STAR-
+       TEND, see the pcre2posix documentation. If the subject string  contains
+       binary  zeros  (coded  as escapes such as \x{00} because pcre2test does
        not support actual binary zeros in its input), you must use posix_star-
        tend to specify its length.
 
    Setting match controls
 
-       The  following  modifiers  affect the matching process or request addi-
-       tional information. Some of them may also be  specified  on  a  pattern
-       line  (see  above), in which case they apply to every subject line that
-       is matched against that pattern, but can be overridden by modifiers  on
+       The following modifiers affect the matching process  or  request  addi-
+       tional  information.  Some  of  them may also be specified on a pattern
+       line (see above), in which case they apply to every subject  line  that
+       is  matched against that pattern, but can be overridden by modifiers on
        the subject.
 
              aftertext                  show text after match
@@ -1175,29 +1184,29 @@ SUBJECT MODIFIERS
              zero_terminate             pass the subject as zero-terminated
 
        The effects of these modifiers are described in the following sections.
-       When  matching  via the POSIX wrapper API, the aftertext, allaftertext,
-       and ovector subject modifiers work as described below. All other  modi-
+       When matching via the POSIX wrapper API, the  aftertext,  allaftertext,
+       and  ovector subject modifiers work as described below. All other modi-
        fiers are either ignored, with a warning message, or cause an error.
 
    Showing more text
 
-       The  aftertext modifier requests that as well as outputting the part of
+       The aftertext modifier requests that as well as outputting the part  of
        the subject string that matched the entire pattern, pcre2test should in
        addition output the remainder of the subject string. This is useful for
        tests where the subject contains multiple copies of the same substring.
-       The allaftertext modifier requests the same action  for  captured  sub-
+       The  allaftertext  modifier  requests the same action for captured sub-
        strings as well as the main matched substring. In each case the remain-
        der is output on the following line with a plus character following the
        capture number.
 
-       The  allusedtext modifier requests that all the text that was consulted
-       during a successful pattern match by the interpreter should  be  shown,
-       for  both  full  and partial matches. This feature is not supported for
-       JIT matching, and if requested with JIT it is ignored (with  a  warning
-       message).  Setting this modifier affects the output if there is a look-
-       behind at the start of a match, or, for a complete match,  a  lookahead
+       The allusedtext modifier requests that all the text that was  consulted
+       during  a  successful pattern match by the interpreter should be shown,
+       for both full and partial matches. This feature is  not  supported  for
+       JIT  matching,  and if requested with JIT it is ignored (with a warning
+       message). Setting this modifier affects the output if there is a  look-
+       behind  at  the start of a match, or, for a complete match, a lookahead
        at the end, or if \K is used in the pattern. Characters that precede or
-       follow  the start and end of the actual match are indicated in the out-
+       follow the start and end of the actual match are indicated in the  out-
        put by '<' or '>' characters underneath them.  Here is an example:
 
            re> /(?<=pqr)abc(?=xyz)/
@@ -1208,16 +1217,16 @@ SUBJECT MODIFIERS
          Partial match: pqrabcxy
                         <<<
 
-       The first, complete match shows that the matched string is "abc",  with
-       the  preceding  and  following strings "pqr" and "xyz" having been con-
-       sulted during the match (when processing the assertions).  The  partial
+       The  first, complete match shows that the matched string is "abc", with
+       the preceding and following strings "pqr" and "xyz"  having  been  con-
+       sulted  during  the match (when processing the assertions). The partial
        match can indicate only the preceding string.
 
-       The  startchar  modifier  requests  that the starting character for the
-       match be indicated, if it is different to  the  start  of  the  matched
+       The startchar modifier requests that the  starting  character  for  the
+       match  be  indicated,  if  it  is different to the start of the matched
        string. The only time when this occurs is when \K has been processed as
        part of the match. In this situation, the output for the matched string
-       is  displayed  from  the  starting  character instead of from the match
+       is displayed from the starting character  instead  of  from  the  match
        point, with circumflex characters under the earlier characters. For ex-
        ample:
 
@@ -1226,7 +1235,7 @@ SUBJECT MODIFIERS
           0: abcxyz
              ^^^
 
-       Unlike allusedtext, the startchar modifier can be used with JIT.   How-
+       Unlike  allusedtext, the startchar modifier can be used with JIT.  How-
        ever, these two modifiers are mutually exclusive.
 
    Showing the value of all capture groups
@@ -1234,104 +1243,104 @@ SUBJECT MODIFIERS
        The allcaptures modifier requests that the values of all potential cap-
        tured parentheses be output after a match. By default, only those up to
        the highest one actually used in the match are output (corresponding to
-       the  return  code from pcre2_match()). Groups that did not take part in
-       the match are output as "<unset>". This modifier is  not  relevant  for
-       DFA  matching (which does no capturing) and does not apply when replace
+       the return code from pcre2_match()). Groups that did not take  part  in
+       the  match  are  output as "<unset>". This modifier is not relevant for
+       DFA matching (which does no capturing) and does not apply when  replace
        is specified; it is ignored, with a warning message, if present.
 
    Showing the entire ovector, for all outcomes
 
        The allvector modifier requests that the entire ovector be shown, what-
        ever the outcome of the match. Compare allcaptures, which shows only up
-       to the maximum number of capture groups for the pattern, and then  only
-       for  a successful complete non-DFA match. This modifier, which acts af-
-       ter any match result, and also for DFA matching, provides  a  means  of
-       checking  that there are no unexpected modifications to ovector fields.
-       Before each match attempt, the ovector is filled with a special  value,
-       and  if  this  is  found  in  both  elements of a capturing pair, "<un-
-       changed>" is output. After a successful  match,  this  applies  to  all
-       groups  after the maximum capture group for the pattern. In other cases
-       it applies to the entire ovector. After a partial match, the first  two
-       elements  are  the only ones that should be set. After a DFA match, the
-       amount of ovector that is used depends on the number  of  matches  that
+       to  the maximum number of capture groups for the pattern, and then only
+       for a successful complete non-DFA match. This modifier, which acts  af-
+       ter  any  match  result, and also for DFA matching, provides a means of
+       checking that there are no unexpected modifications to ovector  fields.
+       Before  each match attempt, the ovector is filled with a special value,
+       and if this is found in  both  elements  of  a  capturing  pair,  "<un-
+       changed>"  is  output.  After  a  successful match, this applies to all
+       groups after the maximum capture group for the pattern. In other  cases
+       it  applies to the entire ovector. After a partial match, the first two
+       elements are the only ones that should be set. After a DFA  match,  the
+       amount  of  ovector  that is used depends on the number of matches that
        were found.
 
    Testing pattern callouts
 
-       A  callout function is supplied when pcre2test calls the library match-
-       ing functions, unless callout_none is specified. Its behaviour  can  be
-       controlled  by  various  modifiers  listed above whose names begin with
-       callout_. Details are given in the section entitled  "Callouts"  below.
-       Testing  callouts  from  pcre2_substitute()  is described separately in
+       A callout function is supplied when pcre2test calls the library  match-
+       ing  functions,  unless callout_none is specified. Its behaviour can be
+       controlled by various modifiers listed above  whose  names  begin  with
+       callout_.  Details  are given in the section entitled "Callouts" below.
+       Testing callouts from pcre2_substitute()  is  described  separately  in
        "Testing the substitution function" below.
 
    Finding all matches in a string
 
        Searching for all possible matches within a subject can be requested by
-       the global or altglobal modifier. After finding a match,  the  matching
-       function  is  called  again to search the remainder of the subject. The
-       difference between global and altglobal is that  the  former  uses  the
-       start_offset  argument  to  pcre2_match() or pcre2_dfa_match() to start
-       searching at a new point within the entire string (which is  what  Perl
+       the  global  or altglobal modifier. After finding a match, the matching
+       function is called again to search the remainder of  the  subject.  The
+       difference  between  global  and  altglobal is that the former uses the
+       start_offset argument to pcre2_match() or  pcre2_dfa_match()  to  start
+       searching  at  a new point within the entire string (which is what Perl
        does), whereas the latter passes over a shortened subject. This makes a
        difference to the matching process if the pattern begins with a lookbe-
        hind assertion (including \b or \B).
 
-       If  an  empty  string  is  matched,  the  next  match  is done with the
+       If an empty string  is  matched,  the  next  match  is  done  with  the
        PCRE2_NOTEMPTY_ATSTART and PCRE2_ANCHORED flags set, in order to search
        for another, non-empty, match at the same point in the subject. If this
-       match fails, the start offset is advanced, and the normal match is  re-
-       tried.  This imitates the way Perl handles such cases when using the /g
-       modifier or the split() function. Normally, the  start  offset  is  ad-
-       vanced  by one character, but if the newline convention recognizes CRLF
-       as a newline, and the current character is CR followed by  LF,  an  ad-
+       match  fails, the start offset is advanced, and the normal match is re-
+       tried. This imitates the way Perl handles such cases when using the  /g
+       modifier  or  the  split()  function. Normally, the start offset is ad-
+       vanced by one character, but if the newline convention recognizes  CRLF
+       as  a  newline,  and the current character is CR followed by LF, an ad-
        vance of two characters occurs.
 
    Testing substring extraction functions
 
-       The  copy  and  get  modifiers  can  be  used  to  test  the pcre2_sub-
+       The copy  and  get  modifiers  can  be  used  to  test  the  pcre2_sub-
        string_copy_xxx() and pcre2_substring_get_xxx() functions.  They can be
        given more than once, and each can specify a capture group name or num-
        ber, for example:
 
           abcd\=copy=1,copy=3,get=G1
 
-       If the #subject command is used to set default copy and/or  get  lists,
-       these  can  be unset by specifying a negative number to cancel all num-
+       If  the  #subject command is used to set default copy and/or get lists,
+       these can be unset by specifying a negative number to cancel  all  num-
        bered groups and an empty name to cancel all named groups.
 
-       The getall modifier tests  pcre2_substring_list_get(),  which  extracts
+       The  getall  modifier  tests pcre2_substring_list_get(), which extracts
        all captured substrings.
 
-       If  the  subject line is successfully matched, the substrings extracted
-       by the convenience functions are output with  C,  G,  or  L  after  the
-       string  number  instead  of  a colon. This is in addition to the normal
-       full list. The string length (that is, the return from  the  extraction
+       If the subject line is successfully matched, the  substrings  extracted
+       by  the  convenience  functions  are  output  with C, G, or L after the
+       string number instead of a colon. This is in  addition  to  the  normal
+       full  list.  The string length (that is, the return from the extraction
        function) is given in parentheses after each substring, followed by the
        name when the extraction was by name.
 
    Testing the substitution function
 
-       If  the  replace  modifier  is  set, the pcre2_substitute() function is
-       called instead of one of the matching functions (or after one  call  of
-       pcre2_match()  in  the case of PCRE2_SUBSTITUTE_MATCHED). Note that re-
-       placement strings cannot contain commas, because a comma signifies  the
-       end  of  a  modifier. This is not thought to be an issue in a test pro-
+       If the replace modifier is  set,  the  pcre2_substitute()  function  is
+       called  instead  of one of the matching functions (or after one call of
+       pcre2_match() in the case of PCRE2_SUBSTITUTE_MATCHED). Note  that  re-
+       placement  strings cannot contain commas, because a comma signifies the
+       end of a modifier. This is not thought to be an issue in  a  test  pro-
        gram.
 
-       Specifying a completely empty replacement string  disables  this  modi-
-       fier.   However, it is possible to specify an empty replacement by pro-
-       viding a buffer length, as described below, for an otherwise empty  re-
+       Specifying  a  completely  empty replacement string disables this modi-
+       fier.  However, it is possible to specify an empty replacement by  pro-
+       viding  a buffer length, as described below, for an otherwise empty re-
        placement.
 
-       Unlike  subject strings, pcre2test does not process replacement strings
-       for escape sequences. In UTF mode, a replacement string is  checked  to
-       see  if it is a valid UTF-8 string. If so, it is correctly converted to
-       a UTF string of the appropriate code unit width. If it is not  a  valid
-       UTF-8  string, the individual code units are copied directly. This pro-
+       Unlike subject strings, pcre2test does not process replacement  strings
+       for  escape  sequences. In UTF mode, a replacement string is checked to
+       see if it is a valid UTF-8 string. If so, it is correctly converted  to
+       a  UTF  string of the appropriate code unit width. If it is not a valid
+       UTF-8 string, the individual code units are copied directly. This  pro-
        vides a means of passing an invalid UTF-8 string for testing purposes.
 
-       The following modifiers set options (in additional to the normal  match
+       The  following modifiers set options (in additional to the normal match
        options) for pcre2_substitute():
 
          global                      PCRE2_SUBSTITUTE_GLOBAL
@@ -1345,8 +1354,8 @@ SUBJECT MODIFIERS
 
        See the pcre2api documentation for details of these options.
 
-       After  a  successful  substitution, the modified string is output, pre-
-       ceded by the number of replacements. This may be zero if there were  no
+       After a successful substitution, the modified string  is  output,  pre-
+       ceded  by the number of replacements. This may be zero if there were no
        matches. Here is a simple example of a substitution test:
 
          /abc/replace=xxx
@@ -1355,12 +1364,12 @@ SUBJECT MODIFIERS
              =abc=abc=\=global
           2: =xxx=xxx=
 
-       Subject  and replacement strings should be kept relatively short (fewer
-       than 256 characters) for substitution tests, as fixed-size buffers  are
-       used.  To  make it easy to test for buffer overflow, if the replacement
-       string starts with a number in square brackets, that number  is  passed
-       to  pcre2_substitute()  as  the size of the output buffer, with the re-
-       placement string starting at the next character.  Here  is  an  example
+       Subject and replacement strings should be kept relatively short  (fewer
+       than  256 characters) for substitution tests, as fixed-size buffers are
+       used. To make it easy to test for buffer overflow, if  the  replacement
+       string  starts  with a number in square brackets, that number is passed
+       to pcre2_substitute() as the size of the output buffer,  with  the  re-
+       placement  string  starting  at  the next character. Here is an example
        that tests the edge case:
 
          /abc/
@@ -1370,12 +1379,12 @@ SUBJECT MODIFIERS
          Failed: error -47: no more memory
 
        The  default  action  of  pcre2_substitute()  is  to  return  PCRE2_ER-
-       ROR_NOMEMORY when the output buffer  is  too  small.  However,  if  the
-       PCRE2_SUBSTITUTE_OVERFLOW_LENGTH  option  is  set (by using the substi-
+       ROR_NOMEMORY  when  the  output  buffer  is  too small. However, if the
+       PCRE2_SUBSTITUTE_OVERFLOW_LENGTH option is set (by  using  the  substi-
        tute_overflow_length  modifier),  pcre2_substitute()  continues  to  go
-       through  the  motions  of  matching and substituting (but not doing any
-       callouts), in order to compute the size of  buffer  that  is  required.
-       When  this  happens,  pcre2test shows the required buffer length (which
+       through the motions of matching and substituting  (but  not  doing  any
+       callouts),  in  order  to  compute the size of buffer that is required.
+       When this happens, pcre2test shows the required  buffer  length  (which
        includes space for the trailing zero) as part of the error message. For
        example:
 
@@ -1384,15 +1393,15 @@ SUBJECT MODIFIERS
          Failed: error -47: no more memory: 10 code units are needed
 
        A replacement string is ignored with POSIX and DFA matching. Specifying
-       partial matching provokes an error return  ("bad  option  value")  from
+       partial  matching  provokes  an  error return ("bad option value") from
        pcre2_substitute().
 
    Testing substitute callouts
 
        If the substitute_callout modifier is set, a substitution callout func-
-       tion  is set up. The null_context modifier must not be set, because the
-       address of the callout function is passed in a match context. When  the
-       callout  function  is  called (after each substitution), details of the
+       tion is set up. The null_context modifier must not be set, because  the
+       address  of the callout function is passed in a match context. When the
+       callout function is called (after each substitution),  details  of  the
        input and output strings are output. For example:
 
          /abc/g,replace=<$0>,substitute_callout
@@ -1401,19 +1410,19 @@ SUBJECT MODIFIERS
           2(1) Old 6 9 "abc" New 8 13 "<abc>"
           2: <abc>def<abc>pqr
 
-       The first number on each callout line is  the  count  of  matches.  The
+       The  first  number  on  each  callout line is the count of matches. The
        parenthesized number is the number of pairs that are set in the ovector
-       (that  is, one more than the number of capturing groups that were set).
+       (that is, one more than the number of capturing groups that were  set).
        Then are listed the offsets of the old substring, its contents, and the
        same for the replacement.
 
-       By default, the substitution callout function returns zero,  which  ac-
-       cepts  the  replacement and causes matching to continue if /g was used.
-       Two further modifiers can be used to test other return values. If  sub-
-       stitute_skip  is  set to a value greater than zero the callout function
-       returns +1 for the match of that number, and similarly  substitute_stop
-       returns  -1.  These cause the replacement to be rejected, and -1 causes
-       no further matching to take place. If either of them are  set,  substi-
+       By  default,  the substitution callout function returns zero, which ac-
+       cepts the replacement and causes matching to continue if /g  was  used.
+       Two  further modifiers can be used to test other return values. If sub-
+       stitute_skip is set to a value greater than zero the  callout  function
+       returns  +1 for the match of that number, and similarly substitute_stop
+       returns -1. These cause the replacement to be rejected, and  -1  causes
+       no  further  matching to take place. If either of them are set, substi-
        tute_callout is assumed. For example:
 
          /abc/g,replace=<$0>,substitute_skip=1
@@ -1431,181 +1440,181 @@ SUBJECT MODIFIERS
 
    Setting the JIT stack size
 
-       The  jitstack modifier provides a way of setting the maximum stack size
-       that is used by the just-in-time optimization code. It  is  ignored  if
-       JIT  optimization is not being used. The value is a number of kibibytes
-       (units of 1024 bytes). Setting zero reverts to the  default  of  32KiB.
+       The jitstack modifier provides a way of setting the maximum stack  size
+       that  is  used  by the just-in-time optimization code. It is ignored if
+       JIT optimization is not being used. The value is a number of  kibibytes
+       (units  of  1024  bytes). Setting zero reverts to the default of 32KiB.
        Providing a stack that is larger than the default is necessary only for
-       very  complicated  patterns.  If  jitstack is set non-zero on a subject
+       very complicated patterns. If jitstack is set  non-zero  on  a  subject
        line it overrides any value that was set on the pattern.
 
    Setting heap, match, and depth limits
 
-       The heap_limit, match_limit, and depth_limit modifiers set  the  appro-
-       priate  limits  in the match context. These values are ignored when the
+       The  heap_limit,  match_limit, and depth_limit modifiers set the appro-
+       priate limits in the match context. These values are ignored  when  the
        find_limits or find_limits_noheap modifier is specified.
 
    Finding minimum limits
 
-       If the find_limits modifier is present on  a  subject  line,  pcre2test
-       calls  the  relevant matching function several times, setting different
-       values   in   the    match    context    via    pcre2_set_heap_limit(),
-       pcre2_set_match_limit(),  or pcre2_set_depth_limit() until it finds the
-       smallest value for each parameter that allows  the  match  to  complete
+       If  the  find_limits  modifier  is present on a subject line, pcre2test
+       calls the relevant matching function several times,  setting  different
+       values    in    the    match    context   via   pcre2_set_heap_limit(),
+       pcre2_set_match_limit(), or pcre2_set_depth_limit() until it finds  the
+       smallest  value  for  each  parameter that allows the match to complete
        without a "limit exceeded" error. The match itself may succeed or fail.
        An alternative modifier, find_limits_noheap, omits the heap limit. This
-       is  used  in  the standard tests, because the minimum heap limit varies
-       between systems. If JIT is being used, only the match  limit  is  rele-
+       is used in the standard tests, because the minimum  heap  limit  varies
+       between  systems.  If  JIT is being used, only the match limit is rele-
        vant, and the other two are automatically omitted.
 
        When using this modifier, the pattern should not contain any limit set-
-       tings  such  as  (*LIMIT_MATCH=...)  within  it.  If  such a setting is
+       tings such as (*LIMIT_MATCH=...)  within  it.  If  such  a  setting  is
        present and is lower than the minimum matching value, the minimum value
-       cannot be found because pcre2_set_match_limit() etc. are only  able  to
+       cannot  be  found because pcre2_set_match_limit() etc. are only able to
        reduce the value of an in-pattern limit; they cannot increase it.
 
-       For  non-DFA  matching,  the minimum depth_limit number is a measure of
+       For non-DFA matching, the minimum depth_limit number is  a  measure  of
        how much nested backtracking happens (that is, how deeply the pattern's
-       tree is searched). In the case of DFA  matching,  depth_limit  controls
-       the  depth of recursive calls of the internal function that is used for
+       tree  is  searched).  In the case of DFA matching, depth_limit controls
+       the depth of recursive calls of the internal function that is used  for
        handling pattern recursion, lookaround assertions, and atomic groups.
 
        For non-DFA matching, the match_limit number is a measure of the amount
        of backtracking that takes place, and learning the minimum value can be
-       instructive. For most simple matches, the number is  quite  small,  but
-       for  patterns with very large numbers of matching possibilities, it can
-       become large very quickly with increasing length of subject string.  In
-       the  case  of  DFA  matching,  match_limit controls the total number of
+       instructive.  For  most  simple matches, the number is quite small, but
+       for patterns with very large numbers of matching possibilities, it  can
+       become  large very quickly with increasing length of subject string. In
+       the case of DFA matching, match_limit  controls  the  total  number  of
        calls, both recursive and non-recursive, to the internal matching func-
        tion, thus controlling the overall amount of computing resource that is
        used.
 
-       For both  kinds  of  matching,  the  heap_limit  number,  which  is  in
-       kibibytes  (units of 1024 bytes), limits the amount of heap memory used
+       For  both  kinds  of  matching,  the  heap_limit  number,  which  is in
+       kibibytes (units of 1024 bytes), limits the amount of heap memory  used
        for matching.
 
    Showing MARK names
 
 
        The mark modifier causes the names from backtracking control verbs that
-       are returned from calls to pcre2_match() to be displayed. If a mark  is
-       returned  for a match, non-match, or partial match, pcre2test shows it.
-       For a match, it is on a line by itself, tagged with  "MK:".  Otherwise,
+       are  returned from calls to pcre2_match() to be displayed. If a mark is
+       returned for a match, non-match, or partial match, pcre2test shows  it.
+       For  a  match, it is on a line by itself, tagged with "MK:". Otherwise,
        it is added to the non-match message.
 
    Showing memory usage
 
-       The  memory modifier causes pcre2test to log the sizes of all heap mem-
-       ory  allocation  and  freeing  calls  that  occur  during  a  call   to
-       pcre2_match()  or pcre2_dfa_match(). In the latter case, heap memory is
-       used only when a match requires more internal workspace  that  the  de-
-       fault  allocation  on the stack, so in many cases there will be no out-
-       put. No heap memory is allocated during matching  with  JIT.  For  this
+       The memory modifier causes pcre2test to log the sizes of all heap  mem-
+       ory   allocation  and  freeing  calls  that  occur  during  a  call  to
+       pcre2_match() or pcre2_dfa_match(). In the latter case, heap memory  is
+       used  only  when  a match requires more internal workspace that the de-
+       fault allocation on the stack, so in many cases there will be  no  out-
+       put.  No  heap  memory  is allocated during matching with JIT. For this
        modifier to work, the null_context modifier must not be set on both the
        pattern and the subject, though it can be set on one or the other.
 
    Showing the heap frame overall vector size
 
-       The   heapframes_size   modifier   is   relevant   for   matches  using
+       The  heapframes_size   modifier   is   relevant   for   matches   using
        pcre2_match() without JIT. After a match has run (whether successful or
-       not) the size, in bytes, of the allocated heap frames  vector  that  is
-       left  attached to the match data block is shown. If the matching action
-       involved several calls to pcre2_match() (for example,  global  matching
+       not)  the  size,  in bytes, of the allocated heap frames vector that is
+       left attached to the match data block is shown. If the matching  action
+       involved  several  calls to pcre2_match() (for example, global matching
        or for timing) only the final value is shown.
 
-       This  modifier  is  ignored, with a warning, for POSIX or DFA matching.
+       This modifier is ignored, with a warning, for POSIX  or  DFA  matching.
        JIT matching does not use the heap frames vector, so the size is always
-       zero, unless there was a previous non-JIT match. Note that specifing  a
+       zero,  unless there was a previous non-JIT match. Note that specifing a
        size of zero for the output vector (see below) causes pcre2test to free
        its match data block (and associated heap frames vector) and allocate a
        new one.
 
    Setting a starting offset
 
-       The  offset  modifier  sets  an  offset  in the subject string at which
+       The offset modifier sets an offset  in  the  subject  string  at  which
        matching starts. Its value is a number of code units, not characters.
 
    Setting an offset limit
 
-       The offset_limit modifier sets a limit for  unanchored  matches.  If  a
+       The  offset_limit  modifier  sets  a limit for unanchored matches. If a
        match cannot be found starting at or before this offset in the subject,
        a "no match" return is given. The data value is a number of code units,
-       not  characters. When this modifier is used, the use_offset_limit modi-
+       not characters. When this modifier is used, the use_offset_limit  modi-
        fier must have been set for the pattern; if not, an error is generated.
 
    Setting the size of the output vector
 
-       The ovector modifier applies only to the subject line in which  it  ap-
+       The  ovector  modifier applies only to the subject line in which it ap-
        pears, though of course it can also be used to set a default in a #sub-
-       ject  command.  It  specifies  the  number of pairs of offsets that are
+       ject command. It specifies the number of  pairs  of  offsets  that  are
        available for storing matching information. The default is 15.
 
-       A value of zero is useful when testing the POSIX API because it  causes
+       A  value of zero is useful when testing the POSIX API because it causes
        regexec() to be called with a NULL capture vector. When not testing the
-       POSIX  API,  a  value  of  zero  is used to cause pcre2_match_data_cre-
-       ate_from_pattern() to be called, in order to create a new  match  block
-       of  exactly the right size for the pattern. (It is not possible to cre-
-       ate a match block with a zero-length ovector; there is always at  least
+       POSIX API, a value of  zero  is  used  to  cause  pcre2_match_data_cre-
+       ate_from_pattern()  to  be called, in order to create a new match block
+       of exactly the right size for the pattern. (It is not possible to  cre-
+       ate  a match block with a zero-length ovector; there is always at least
        one pair of offsets.) The old match data block is freed.
 
    Passing the subject as zero-terminated
 
        By default, the subject string is passed to a native API matching func-
        tion with its correct length. In order to test the facility for passing
-       a  zero-terminated  string, the zero_terminate modifier is provided. It
-       causes the length to be passed as PCRE2_ZERO_TERMINATED. When  matching
+       a zero-terminated string, the zero_terminate modifier is  provided.  It
+       causes  the length to be passed as PCRE2_ZERO_TERMINATED. When matching
        via the POSIX interface, this modifier is ignored, with a warning.
 
-       When  testing  pcre2_substitute(), this modifier also has the effect of
+       When testing pcre2_substitute(), this modifier also has the  effect  of
        passing the replacement string as zero-terminated.
 
    Passing a NULL context, subject, or replacement
 
-       Normally,  pcre2test  passes  a   context   block   to   pcre2_match(),
-       pcre2_dfa_match(),  pcre2_jit_match()  or  pcre2_substitute().   If the
-       null_context modifier is set, however, NULL  is  passed.  This  is  for
-       testing  that  the matching and substitution functions behave correctly
-       in this case (they use default values). This modifier  cannot  be  used
-       with  the  find_limits, find_limits_noheap, or substitute_callout modi-
+       Normally,   pcre2test   passes   a   context  block  to  pcre2_match(),
+       pcre2_dfa_match(), pcre2_jit_match()  or  pcre2_substitute().   If  the
+       null_context  modifier  is  set,  however,  NULL is passed. This is for
+       testing that the matching and substitution functions  behave  correctly
+       in  this  case  (they use default values). This modifier cannot be used
+       with the find_limits, find_limits_noheap, or  substitute_callout  modi-
        fiers.
 
-       Similarly, for testing purposes, if the null_subject  or  null_replace-
-       ment  modifier  is  set, the subject or replacement string pointers are
+       Similarly,  for  testing purposes, if the null_subject or null_replace-
+       ment modifier is set, the subject or replacement  string  pointers  are
        passed as NULL, respectively, to the relevant functions.
 
 
 THE ALTERNATIVE MATCHING FUNCTION
 
-       By default,  pcre2test  uses  the  standard  PCRE2  matching  function,
+       By  default,  pcre2test  uses  the  standard  PCRE2  matching function,
        pcre2_match() to match each subject line. PCRE2 also supports an alter-
-       native  matching  function, pcre2_dfa_match(), which operates in a dif-
-       ferent way, and has some restrictions. The differences between the  two
+       native matching function, pcre2_dfa_match(), which operates in  a  dif-
+       ferent  way, and has some restrictions. The differences between the two
        functions are described in the pcre2matching documentation.
 
-       If  the dfa modifier is set, the alternative matching function is used.
-       This function finds all possible matches at a given point in  the  sub-
-       ject.  If,  however, the dfa_shortest modifier is set, processing stops
-       after the first match is found. This is always  the  shortest  possible
+       If the dfa modifier is set, the alternative matching function is  used.
+       This  function  finds all possible matches at a given point in the sub-
+       ject. If, however, the dfa_shortest modifier is set,  processing  stops
+       after  the  first  match is found. This is always the shortest possible
        match.
 
 
 DEFAULT OUTPUT FROM pcre2test
 
-       This  section  describes  the output when the normal matching function,
+       This section describes the output when the  normal  matching  function,
        pcre2_match(), is being used.
 
-       When a match succeeds, pcre2test outputs  the  list  of  captured  sub-
-       strings,  starting  with number 0 for the string that matched the whole
+       When  a  match  succeeds,  pcre2test  outputs the list of captured sub-
+       strings, starting with number 0 for the string that matched  the  whole
        pattern.  Otherwise, it outputs "No match" when the return is PCRE2_ER-
-       ROR_NOMATCH, or "Partial match:" followed  by  the  partially  matching
-       substring  when  the  return is PCRE2_ERROR_PARTIAL. (Note that this is
-       the entire substring that was inspected during the  partial  match;  it
-       may  include  characters  before the actual match start if a lookbehind
+       ROR_NOMATCH,  or  "Partial  match:"  followed by the partially matching
+       substring when the return is PCRE2_ERROR_PARTIAL. (Note  that  this  is
+       the  entire  substring  that was inspected during the partial match; it
+       may include characters before the actual match start  if  a  lookbehind
        assertion, \K, \b, or \B was involved.)
 
        For any other return, pcre2test outputs the PCRE2 negative error number
-       and a short descriptive phrase. If the error is  a  failed  UTF  string
-       check,  the  code  unit offset of the start of the failing character is
+       and  a  short  descriptive  phrase. If the error is a failed UTF string
+       check, the code unit offset of the start of the  failing  character  is
        also output. Here is an example of an interactive pcre2test run.
 
          $ pcre2test
@@ -1621,8 +1630,8 @@ DEFAULT OUTPUT FROM pcre2test
        Unset capturing substrings that are not followed by one that is set are
        not shown by pcre2test unless the allcaptures modifier is specified. In
        the following example, there are two capturing substrings, but when the
-       first data line is matched, the second, unset substring is  not  shown.
-       An  "internal" unset substring is shown as "<unset>", as for the second
+       first  data  line is matched, the second, unset substring is not shown.
+       An "internal" unset substring is shown as "<unset>", as for the  second
        data line.
 
            re> /(a)|(b)/
@@ -1634,11 +1643,11 @@ DEFAULT OUTPUT FROM pcre2test
           1: <unset>
           2: b
 
-       If the strings contain any non-printing characters, they are output  as
-       \xhh  escapes  if  the  value is less than 256 and UTF mode is not set.
+       If  the strings contain any non-printing characters, they are output as
+       \xhh escapes if the value is less than 256 and UTF  mode  is  not  set.
        Otherwise they are output as \x{hh...} escapes. See below for the defi-
-       nition of non-printing characters. If the aftertext  modifier  is  set,
-       the  output  for  substring  0  is  followed by the rest of the subject
+       nition  of  non-printing  characters. If the aftertext modifier is set,
+       the output for substring 0 is followed  by  the  rest  of  the  subject
        string, identified by "0+" like this:
 
            re> /cat/aftertext
@@ -1658,8 +1667,8 @@ DEFAULT OUTPUT FROM pcre2test
           0: ipp
           1: pp
 
-       "No match" is output only if the first match attempt fails. Here is  an
-       example  of  a  failure  message (the offset 4 that is specified by the
+       "No  match" is output only if the first match attempt fails. Here is an
+       example of a failure message (the offset 4 that  is  specified  by  the
        offset modifier is past the end of the subject string):
 
            re> /xyz/
@@ -1667,7 +1676,7 @@ DEFAULT OUTPUT FROM pcre2test
          Error -24 (bad offset value)
 
        Note that whereas patterns can be continued over several lines (a plain
-       ">" prompt is used for continuations), subject lines may  not.  However
+       ">"  prompt  is used for continuations), subject lines may not. However
        newlines can be included in a subject by means of the \n escape (or \r,
        \r\n, etc., depending on the newline sequence setting).
 
@@ -1675,7 +1684,7 @@ DEFAULT OUTPUT FROM pcre2test
 OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
 
        When the alternative matching function, pcre2_dfa_match(), is used, the
-       output  consists  of  a list of all the matches that start at the first
+       output consists of a list of all the matches that start  at  the  first
        point in the subject where there is at least one match. For example:
 
            re> /(tang|tangerine|tan)/
@@ -1684,11 +1693,11 @@ OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
           1: tang
           2: tan
 
-       Using the normal matching function on this data finds only "tang".  The
-       longest  matching string is always given first (and numbered zero). Af-
-       ter a PCRE2_ERROR_PARTIAL return, the output is "Partial match:",  fol-
+       Using  the normal matching function on this data finds only "tang". The
+       longest matching string is always given first (and numbered zero).  Af-
+       ter  a PCRE2_ERROR_PARTIAL return, the output is "Partial match:", fol-
        lowed by the partially matching substring. Note that this is the entire
-       substring  that  was inspected during the partial match; it may include
+       substring that was inspected during the partial match; it  may  include
        characters before the actual match start if a lookbehind assertion, \b,
        or \B was involved. (\K is not supported for DFA matching.)
 
@@ -1704,16 +1713,16 @@ OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
           1: tan
           0: tan
 
-       The alternative matching function does not support  substring  capture,
-       so  the  modifiers  that are concerned with captured substrings are not
+       The  alternative  matching function does not support substring capture,
+       so the modifiers that are concerned with captured  substrings  are  not
        relevant.
 
 
 RESTARTING AFTER A PARTIAL MATCH
 
-       When the alternative matching function has given  the  PCRE2_ERROR_PAR-
+       When  the  alternative matching function has given the PCRE2_ERROR_PAR-
        TIAL return, indicating that the subject partially matched the pattern,
-       you  can restart the match with additional subject data by means of the
+       you can restart the match with additional subject data by means of  the
        dfa_restart modifier. For example:
 
            re> /^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$/
@@ -1722,37 +1731,37 @@ RESTARTING AFTER A PARTIAL MATCH
          data> n05\=dfa,dfa_restart
           0: n05
 
-       For further information about partial matching,  see  the  pcre2partial
+       For  further  information  about partial matching, see the pcre2partial
        documentation.
 
 
 CALLOUTS
 
        If the pattern contains any callout requests, pcre2test's callout func-
-       tion  is  called during matching unless callout_none is specified. This
+       tion is called during matching unless callout_none is  specified.  This
        works with both matching functions, and with JIT, though there are some
-       differences in behaviour. The output for callouts with numerical  argu-
+       differences  in behaviour. The output for callouts with numerical argu-
        ments and those with string arguments is slightly different.
 
    Callouts with numerical arguments
 
        By default, the callout function displays the callout number, the start
-       and  current positions in the subject text at the callout time, and the
+       and current positions in the subject text at the callout time, and  the
        next pattern item to be tested. For example:
 
          --->pqrabcdef
            0    ^  ^     \d
 
-       This output indicates that callout number 0 occurred for  a  match  at-
-       tempt  starting at the fourth character of the subject string, when the
-       pointer was at the seventh character, and when the  next  pattern  item
-       was  \d.  Just  one circumflex is output if the start and current posi-
+       This  output  indicates  that callout number 0 occurred for a match at-
+       tempt starting at the fourth character of the subject string, when  the
+       pointer  was  at  the seventh character, and when the next pattern item
+       was \d. Just one circumflex is output if the start  and  current  posi-
        tions are the same, or if the current position precedes the start posi-
        tion, which can happen if the callout is in a lookbehind assertion.
 
        Callouts numbered 255 are assumed to be automatic callouts, inserted as
        a result of the auto_callout pattern modifier. In this case, instead of
-       showing the callout number, the offset in the pattern,  preceded  by  a
+       showing  the  callout  number, the offset in the pattern, preceded by a
        plus, is output. For example:
 
            re> /\d?[A-E]\*/auto_callout
@@ -1779,17 +1788,17 @@ CALLOUTS
          +12 ^  ^
           0: abc
 
-       The  mark  changes between matching "a" and "b", but stays the same for
-       the rest of the match, so nothing more is output. If, as  a  result  of
-       backtracking,  the  mark  reverts to being unset, the text "<unset>" is
+       The mark changes between matching "a" and "b", but stays the  same  for
+       the  rest  of  the match, so nothing more is output. If, as a result of
+       backtracking, the mark reverts to being unset, the  text  "<unset>"  is
        output.
 
    Callouts with string arguments
 
        The output for a callout with a string argument is similar, except that
-       instead of outputting a callout number before the position  indicators,
-       the  callout string and its offset in the pattern string are output be-
-       fore the reflection of the subject string, and the  subject  string  is
+       instead  of outputting a callout number before the position indicators,
+       the callout string and its offset in the pattern string are output  be-
+       fore  the  reflection  of the subject string, and the subject string is
        reflected for each callout. For example:
 
            re> /^ab(?C'first')cd(?C"second")ef/
@@ -1805,26 +1814,26 @@ CALLOUTS
 
    Callout modifiers
 
-       The  callout  function in pcre2test returns zero (carry on matching) by
-       default, but you can use a callout_fail modifier in a subject  line  to
+       The callout function in pcre2test returns zero (carry on  matching)  by
+       default,  but  you can use a callout_fail modifier in a subject line to
        change this and other parameters of the callout (see below).
 
        If the callout_capture modifier is set, the current captured groups are
        output when a callout occurs. This is useful only for non-DFA matching,
-       as  pcre2_dfa_match()  does  not  support capturing, so no captures are
+       as pcre2_dfa_match() does not support capturing,  so  no  captures  are
        ever shown.
 
        The normal callout output, showing the callout number or pattern offset
-       (as described above) is suppressed if the callout_no_where modifier  is
+       (as  described above) is suppressed if the callout_no_where modifier is
        set.
 
-       When  using  the  interpretive  matching function pcre2_match() without
-       JIT, setting the callout_extra modifier causes additional  output  from
-       pcre2test's  callout function to be generated. For the first callout in
-       a match attempt at a new starting position in the subject,  "New  match
-       attempt"  is output. If there has been a backtrack since the last call-
+       When using the interpretive  matching  function  pcre2_match()  without
+       JIT,  setting  the callout_extra modifier causes additional output from
+       pcre2test's callout function to be generated. For the first callout  in
+       a  match  attempt at a new starting position in the subject, "New match
+       attempt" is output. If there has been a backtrack since the last  call-
        out (or start of matching if this is the first callout), "Backtrack" is
-       output, followed by "No other matching paths" if  the  backtrack  ended
+       output,  followed  by  "No other matching paths" if the backtrack ended
        the previous match attempt. For example:
 
           re> /(a+)b/auto_callout,no_start_optimize,no_auto_possess
@@ -1861,86 +1870,86 @@ CALLOUTS
           +1    ^    a+
          No match
 
-       Notice  that  various  optimizations must be turned off if you want all
-       possible matching paths to be  scanned.  If  no_start_optimize  is  not
-       used,  there  is an immediate "no match", without any callouts, because
-       the starting optimization fails to find "b" in the  subject,  which  it
-       knows  must  be  present for any match. If no_auto_possess is not used,
-       the "a+" item is turned into "a++", which reduces the number  of  back-
+       Notice that various optimizations must be turned off if  you  want  all
+       possible  matching  paths  to  be  scanned. If no_start_optimize is not
+       used, there is an immediate "no match", without any  callouts,  because
+       the  starting  optimization  fails to find "b" in the subject, which it
+       knows must be present for any match. If no_auto_possess  is  not  used,
+       the  "a+"  item is turned into "a++", which reduces the number of back-
        tracks.
 
-       The  callout_extra modifier has no effect if used with the DFA matching
+       The callout_extra modifier has no effect if used with the DFA  matching
        function, or with JIT.
 
    Return values from callouts
 
-       The default return from the callout  function  is  zero,  which  allows
+       The  default  return  from  the  callout function is zero, which allows
        matching to continue. The callout_fail modifier can be given one or two
        numbers. If there is only one number, 1 is returned instead of 0 (caus-
        ing matching to backtrack) when a callout of that number is reached. If
-       two  numbers  (<n>:<m>)  are  given,  1 is returned when callout <n> is
-       reached and there have been at least <m>  callouts.  The  callout_error
+       two numbers (<n>:<m>) are given, 1 is  returned  when  callout  <n>  is
+       reached  and  there  have been at least <m> callouts. The callout_error
        modifier is similar, except that PCRE2_ERROR_CALLOUT is returned, caus-
-       ing  the entire matching process to be aborted. If both these modifiers
-       are set for the same callout number,  callout_error  takes  precedence.
-       Note  that  callouts  with string arguments are always given the number
+       ing the entire matching process to be aborted. If both these  modifiers
+       are  set  for  the same callout number, callout_error takes precedence.
+       Note that callouts with string arguments are always  given  the  number
        zero.
 
-       The callout_data modifier can be given an unsigned or a  negative  num-
-       ber.   This  is  set  as the "user data" that is passed to the matching
-       function, and passed back when the callout  function  is  invoked.  Any
-       value  other  than  zero  is  used as a return from pcre2test's callout
+       The  callout_data  modifier can be given an unsigned or a negative num-
+       ber.  This is set as the "user data" that is  passed  to  the  matching
+       function,  and  passed  back  when the callout function is invoked. Any
+       value other than zero is used as  a  return  from  pcre2test's  callout
        function.
 
        Inserting callouts can be helpful when using pcre2test to check compli-
-       cated regular expressions. For further information about callouts,  see
+       cated  regular expressions. For further information about callouts, see
        the pcre2callout documentation.
 
 
 NON-PRINTING CHARACTERS
 
        When pcre2test is outputting text in the compiled version of a pattern,
-       bytes  other  than 32-126 are always treated as non-printing characters
+       bytes other than 32-126 are always treated as  non-printing  characters
        and are therefore shown as hex escapes.
 
-       When pcre2test is outputting text that is a matched part of  a  subject
-       string,  it behaves in the same way, unless a different locale has been
-       set for the pattern (using the locale modifier). In this case, the  is-
+       When  pcre2test  is outputting text that is a matched part of a subject
+       string, it behaves in the same way, unless a different locale has  been
+       set  for the pattern (using the locale modifier). In this case, the is-
        print() function is used to distinguish printing and non-printing char-
        acters.
 
 
 SAVING AND RESTORING COMPILED PATTERNS
 
-       It  is possible to save compiled patterns on disc or elsewhere, and re-
-       load them later, subject to a number of restrictions. JIT  data  cannot
-       be  saved.  The host on which the patterns are reloaded must be running
+       It is possible to save compiled patterns on disc or elsewhere, and  re-
+       load  them  later, subject to a number of restrictions. JIT data cannot
+       be saved. The host on which the patterns are reloaded must  be  running
        the same version of PCRE2, with the same code unit width, and must also
-       have the same endianness, pointer width  and  PCRE2_SIZE  type.  Before
-       compiled  patterns  can be saved they must be serialized, that is, con-
-       verted to a stream of bytes. A single byte stream may contain any  num-
-       ber  of compiled patterns, but they must all use the same character ta-
-       bles. A single copy of the tables is included in the byte  stream  (its
+       have  the  same  endianness,  pointer width and PCRE2_SIZE type. Before
+       compiled patterns can be saved they must be serialized, that  is,  con-
+       verted  to a stream of bytes. A single byte stream may contain any num-
+       ber of compiled patterns, but they must all use the same character  ta-
+       bles.  A  single copy of the tables is included in the byte stream (its
        size is 1088 bytes).
 
-       The  functions whose names begin with pcre2_serialize_ are used for se-
-       rializing and de-serializing. They are described in the  pcre2serialize
-       documentation.  In  this  section we describe the features of pcre2test
+       The functions whose names begin with pcre2_serialize_ are used for  se-
+       rializing  and de-serializing. They are described in the pcre2serialize
+       documentation. In this section we describe the  features  of  pcre2test
        that can be used to test these functions.
 
-       Note that "serialization" in PCRE2 does not convert  compiled  patterns
-       to  an  abstract  format  like Java or .NET. It just makes a reloadable
+       Note  that  "serialization" in PCRE2 does not convert compiled patterns
+       to an abstract format like Java or .NET. It  just  makes  a  reloadable
        byte code stream.  Hence the restrictions on reloading mentioned above.
 
-       In pcre2test, when a pattern with push modifier  is  successfully  com-
-       piled,  it  is  pushed onto a stack of compiled patterns, and pcre2test
-       expects the next line to contain a new pattern (or command) instead  of
+       In  pcre2test,  when  a pattern with push modifier is successfully com-
+       piled, it is pushed onto a stack of compiled  patterns,  and  pcre2test
+       expects  the next line to contain a new pattern (or command) instead of
        a subject line. By contrast, the pushcopy modifier causes a copy of the
-       compiled  pattern to be stacked, leaving the original available for im-
-       mediate matching. By using push and/or pushcopy, a number  of  patterns
-       can  be  compiled  and  retained. These modifiers are incompatible with
+       compiled pattern to be stacked, leaving the original available for  im-
+       mediate  matching.  By using push and/or pushcopy, a number of patterns
+       can be compiled and retained. These  modifiers  are  incompatible  with
        posix, and control modifiers that act at match time are ignored (with a
-       message) for the stacked patterns. The jitverify modifier applies  only
+       message)  for the stacked patterns. The jitverify modifier applies only
        at compile time.
 
        The command
@@ -1948,21 +1957,21 @@ SAVING AND RESTORING COMPILED PATTERNS
          #save <filename>
 
        causes all the stacked patterns to be serialized and the result written
-       to  the named file. Afterwards, all the stacked patterns are freed. The
+       to the named file. Afterwards, all the stacked patterns are freed.  The
        command
 
          #load <filename>
 
-       reads the data in the file, and then arranges for it to  be  de-serial-
-       ized,  with the resulting compiled patterns added to the pattern stack.
-       The pattern on the top of the stack can be retrieved by the  #pop  com-
-       mand,  which  must  be  followed  by  lines  of subjects that are to be
-       matched with the pattern, terminated as usual by an empty line  or  end
-       of  file.  This  command  may be followed by a modifier list containing
-       only control modifiers that act after a pattern has been  compiled.  In
-       particular,  hex,  posix,  posix_nosub,  push, and pushcopy are not al-
-       lowed, nor are any option-setting modifiers.  The  JIT  modifiers  are,
-       however  permitted.  Here is an example that saves and reloads two pat-
+       reads  the  data in the file, and then arranges for it to be de-serial-
+       ized, with the resulting compiled patterns added to the pattern  stack.
+       The  pattern  on the top of the stack can be retrieved by the #pop com-
+       mand, which must be followed by  lines  of  subjects  that  are  to  be
+       matched  with  the pattern, terminated as usual by an empty line or end
+       of file. This command may be followed by  a  modifier  list  containing
+       only  control  modifiers that act after a pattern has been compiled. In
+       particular, hex, posix, posix_nosub, push, and  pushcopy  are  not  al-
+       lowed,  nor  are  any option-setting modifiers.  The JIT modifiers are,
+       however permitted. Here is an example that saves and reloads  two  pat-
        terns.
 
          /abc/push
@@ -1975,10 +1984,10 @@ SAVING AND RESTORING COMPILED PATTERNS
          #pop jit,bincode
          abc
 
-       If jitverify is used with #pop, it does not  automatically  imply  jit,
+       If  jitverify  is  used with #pop, it does not automatically imply jit,
        which is different behaviour from when it is used on a pattern.
 
-       The  #popcopy  command is analogous to the pushcopy modifier in that it
+       The #popcopy command is analogous to the pushcopy modifier in  that  it
        makes current a copy of the topmost stack pattern, leaving the original
        still on the stack.
 
@@ -1998,8 +2007,8 @@ AUTHOR
 
 REVISION
 
-       Last updated: 27 January 2024
+       Last updated: 24 April 2024
        Copyright (c) 1997-2024 University of Cambridge.
 
 
-PCRE 10.43                      27 January 2024                   PCRE2TEST(1)
+PCRE 10.44                       24 April 2024                    PCRE2TEST(1)
index 550669344c0fb09b96ae76d0d4a53aa04cb557de..51e57e31f13f943e96ab7798e0e17a4329ab79b7 100644 (file)
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -2,11 +2,11 @@
 ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in
 ##               by inline-source v2019-02-19.15
 
-# libtool (GNU libtool) 2.4.7.4-1ec8f-dirty
+# libtool (GNU libtool) 2.5.0.1-38c1-dirty
 # Provide generalized library-building support services.
 # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
 
-# Copyright (C) 1996-2019, 2021-2022 Free Software Foundation, Inc.
+# Copyright (C) 1996-2019, 2021-2024 Free Software Foundation, Inc.
 # This is free software; see the source for copying conditions.  There is NO
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
@@ -31,8 +31,8 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION=2.4.7.4-1ec8f-dirty
-package_revision=2.4.7.4
+VERSION=2.5.0.1-38c1-dirty
+package_revision=2.5.0.1
 
 
 ## ------ ##
@@ -72,11 +72,11 @@ scriptversion=2019-02-19.15; # UTC
 # This is free software.  There is NO warranty; not even for
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 #
-# Copyright (C) 2004-2019, 2021 Bootstrap Authors
+# Copyright (C) 2004-2019, 2021, 2023 Bootstrap Authors
 #
 # This file is dual licensed under the terms of the MIT license
-# <https://opensource.org/license/MIT>, and GPL version 2 or later
-# <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
+# <https://opensource.org/licenses/MIT>, and GPL version 2 or later
+# <https://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
 # these licenses when using or redistributing this software or any of
 # the files within it.  See the URLs above, or the file `LICENSE`
 # included in the Bootstrap distribution for the full license texts.
@@ -143,7 +143,7 @@ nl='
 '
 IFS="$sp       $nl"
 
-# There are apparently some retarded systems that use ';' as a PATH separator!
+# There are apparently some systems that use ';' as a PATH separator!
 if test "${PATH_SEPARATOR+set}" != set; then
   PATH_SEPARATOR=:
   (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
@@ -1536,11 +1536,11 @@ func_lt_ver ()
 # This is free software.  There is NO warranty; not even for
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 #
-# Copyright (C) 2010-2019, 2021 Bootstrap Authors
+# Copyright (C) 2010-2019, 2021, 2023 Bootstrap Authors
 #
 # This file is dual licensed under the terms of the MIT license
-# <https://opensource.org/license/MIT>, and GPL version 2 or later
-# <http://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
+# <https://opensource.org/licenses/MIT>, and GPL version 2 or later
+# <https://www.gnu.org/licenses/gpl-2.0.html>.  You must apply one of
 # these licenses when using or redistributing this software or any of
 # the files within it.  See the URLs above, or the file `LICENSE`
 # included in the Bootstrap distribution for the full license texts.
@@ -2215,7 +2215,7 @@ func_version ()
 # End:
 
 # Set a version string.
-scriptversion='(GNU libtool) 2.4.7.4-1ec8f-dirty'
+scriptversion='(GNU libtool) 2.5.0.1-38c1-dirty'
 
 
 # func_echo ARG...
@@ -2306,13 +2306,13 @@ include the following information:
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname (GNU libtool) 2.4.7.4-1ec8f-dirty
+       version:        $progname (GNU libtool) 2.5.0.1-38c1-dirty
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
 Report bugs to <bug-libtool@gnu.org>.
-GNU libtool home page: <http://www.gnu.org/s/libtool/>.
-General help using GNU software: <http://www.gnu.org/gethelp/>."
+GNU libtool home page: <https://www.gnu.org/s/libtool/>.
+General help using GNU software: <https://www.gnu.org/gethelp/>."
     exit 0
 }
 
@@ -2668,10 +2668,10 @@ libtool_validate_options ()
     # preserve --debug
     test : = "$debug_cmd" || func_append preserve_args " --debug"
 
-    case $host in
+    case $host_os in
       # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452
       # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788
-      *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*)
+      cygwin* | mingw* | windows* | pw32* | cegcc* | solaris2* | os2*)
         # don't eliminate duplications in $postdeps and $predeps
         opt_duplicate_compiler_generated_deps=:
         ;;
@@ -3003,7 +3003,7 @@ EOF
 
 # func_convert_core_file_wine_to_w32 ARG
 # Helper function used by file name conversion functions when $build is *nix,
-# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# and $host is mingw, windows, cygwin, or some other w32 environment. Relies on a
 # correctly configured wine environment available, with the winepath program
 # in $build's $PATH.
 #
@@ -3035,9 +3035,10 @@ func_convert_core_file_wine_to_w32 ()
 
 # func_convert_core_path_wine_to_w32 ARG
 # Helper function used by path conversion functions when $build is *nix, and
-# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
-# configured wine environment available, with the winepath program in $build's
-# $PATH. Assumes ARG has no leading or trailing path separator characters.
+# $host is mingw, windows, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH. Assumes ARG has no leading or trailing path separator
+# characters.
 #
 # ARG is path to be converted from $build format to win32.
 # Result is available in $func_convert_core_path_wine_to_w32_result.
@@ -3692,7 +3693,7 @@ func_mode_compile ()
 
     # On Cygwin there's no "real" PIC flag so we must build both object types
     case $host_os in
-    cygwin* | mingw* | pw32* | os2* | cegcc*)
+    cygwin* | mingw* | windows* | pw32* | os2* | cegcc*)
       pic_mode=default
       ;;
     esac
@@ -4569,7 +4570,7 @@ func_mode_install ()
              'exit $?'
          tstripme=$stripme
          case $host_os in
-         cygwin* | mingw* | pw32* | cegcc*)
+         cygwin* | mingw* | windows* | pw32* | cegcc*)
            case $realname in
            *.dll.a)
              tstripme=
@@ -4682,7 +4683,7 @@ func_mode_install ()
 
        # Do a test to see if this is really a libtool program.
        case $host in
-       *cygwin* | *mingw*)
+       *cygwin* | *mingw* | *windows*)
            if func_ltwrapper_executable_p "$file"; then
              func_ltwrapper_scriptname "$file"
              wrapper=$func_ltwrapper_scriptname_result
@@ -4910,7 +4911,7 @@ extern \"C\" {
              $RM $export_symbols
              eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
              case $host in
-             *cygwin* | *mingw* | *cegcc* )
+             *cygwin* | *mingw* | *windows* | *cegcc* )
                 eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
                 eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
                ;;
@@ -4922,7 +4923,7 @@ extern \"C\" {
              eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
              eval '$MV "$nlist"T "$nlist"'
              case $host in
-               *cygwin* | *mingw* | *cegcc* )
+               *cygwin* | *mingw* | *windows* | *cegcc* )
                  eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
                  eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
                  ;;
@@ -4936,7 +4937,7 @@ extern \"C\" {
          func_basename "$dlprefile"
          name=$func_basename_result
           case $host in
-           *cygwin* | *mingw* | *cegcc* )
+           *cygwin* | *mingw* | *windows* | *cegcc* )
              # if an import library, we need to obtain dlname
              if func_win32_import_lib_p "$dlprefile"; then
                func_tr_sh "$dlprefile"
@@ -5111,7 +5112,7 @@ static const void *lt_preloaded_setup() {
        # Transform the symbol file into the correct name.
        symfileobj=$output_objdir/${my_outputname}S.$objext
        case $host in
-       *cygwin* | *mingw* | *cegcc* )
+       *cygwin* | *mingw* | *windows* | *cegcc* )
          if test -f "$output_objdir/$my_outputname.def"; then
            compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
            finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
@@ -5454,7 +5455,7 @@ func_extract_archives ()
 #
 # Emit a libtool wrapper script on stdout.
 # Don't directly open a file because we may want to
-# incorporate the script contents within a cygwin/mingw
+# incorporate the script contents within a cygwin/mingw/windows
 # wrapper executable.  Must ONLY be called from within
 # func_mode_link because it depends on a number of variables
 # set therein.
@@ -5462,7 +5463,7 @@ func_extract_archives ()
 # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
 # variable will take.  If 'yes', then the emitted script
 # will assume that the directory where it is stored is
-# the $objdir directory.  This is a cygwin/mingw-specific
+# the $objdir directory.  This is a cygwin/mingw/windows-specific
 # behavior.
 func_emit_wrapper ()
 {
@@ -5587,7 +5588,7 @@ func_exec_program_core ()
 "
   case $host in
   # Backslashes separate directories on plain windows
-  *-*-mingw | *-*-os2* | *-cegcc*)
+  *-*-mingw* | *-*-windows* | *-*-os2* | *-cegcc*)
     $ECHO "\
       if test -n \"\$lt_option_debug\"; then
         \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2
@@ -5655,7 +5656,7 @@ func_exec_program ()
     file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
   done
 
-  # Usually 'no', except on cygwin/mingw when embedded into
+  # Usually 'no', except on cygwin/mingw/windows when embedded into
   # the cwrapper.
   WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
   if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
@@ -5787,7 +5788,7 @@ EOF
 #endif
 #include <stdio.h>
 #include <stdlib.h>
-#ifdef _MSC_VER
+#if defined _WIN32 && !defined __GNUC__
 # include <direct.h>
 # include <process.h>
 # include <io.h>
@@ -5812,7 +5813,7 @@ EOF
 /* declarations of non-ANSI functions */
 #if defined __MINGW32__
 # ifdef __STRICT_ANSI__
-int _putenv (const char *);
+_CRTIMP int __cdecl _putenv (const char *);
 # endif
 #elif defined __CYGWIN__
 # ifdef __STRICT_ANSI__
@@ -6010,7 +6011,7 @@ main (int argc, char *argv[])
        {
 EOF
            case $host in
-             *mingw* | *cygwin* )
+             *mingw* | *windows* | *cygwin* )
                # make stdout use "unix" line endings
                echo "          setmode(1,_O_BINARY);"
                ;;
@@ -6029,7 +6030,7 @@ EOF
         {
           /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
              namespace, but it is not one of the ones we know about and
-             have already dealt with, above (inluding dump-script), then
+             have already dealt with, above (including dump-script), then
              report an error. Otherwise, targets might begin to believe
              they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
              namespace. The first time any user complains about this, we'll
@@ -6113,7 +6114,7 @@ EOF
 EOF
 
            case $host_os in
-             mingw*)
+             mingw* | windows*)
            cat <<"EOF"
   {
     char* p;
@@ -6155,7 +6156,7 @@ EOF
 EOF
 
            case $host_os in
-             mingw*)
+             mingw* | windows*)
                cat <<"EOF"
   /* execv doesn't actually work on mingw as expected on unix */
   newargz = prepare_spawn (newargz);
@@ -6574,7 +6575,7 @@ lt_update_lib_path (const char *name, const char *value)
 
 EOF
            case $host_os in
-             mingw*)
+             mingw* | windows*)
                cat <<"EOF"
 
 /* Prepares an argument vector before calling spawn().
@@ -6749,7 +6750,7 @@ func_mode_link ()
     $debug_cmd
 
     case $host in
-    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+    *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*)
       # It is impossible to link a dll without this setting, and
       # we shouldn't force the makefile maintainer to figure out
       # what system we are compiling for in order to pass an extra
@@ -7255,7 +7256,7 @@ func_mode_link ()
          ;;
        esac
        case $host in
-       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+       *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*)
          testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
          case :$dllsearchpath: in
          *":$dir:"*) ;;
@@ -7275,7 +7276,7 @@ func_mode_link ()
       -l*)
        if test X-lc = "X$arg" || test X-lm = "X$arg"; then
          case $host in
-         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
+         *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
            # These systems don't actually have a C or math library (as such)
            continue
            ;;
@@ -7283,7 +7284,7 @@ func_mode_link ()
            # These systems don't actually have a C library (as such)
            test X-lc = "X$arg" && continue
            ;;
-         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*)
+         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*)
            # Do not include libc due to us having libc/libc_r.
            test X-lc = "X$arg" && continue
            ;;
@@ -7303,7 +7304,7 @@ func_mode_link ()
          esac
        elif test X-lc_r = "X$arg"; then
         case $host in
-        *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*)
+        *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*)
           # Do not include libc_r directly, use -pthread flag.
           continue
           ;;
@@ -7347,7 +7348,7 @@ func_mode_link ()
        continue
        ;;
       -mt|-mthreads|-kthread|-Kthread|-pthreads|--thread-safe \
-      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+      |-threads|-fopenmp|-fopenmp=*|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
        func_append compiler_flags " $arg"
        func_append compile_command " $arg"
        func_append finalize_command " $arg"
@@ -7370,7 +7371,7 @@ func_mode_link ()
 
       -no-install)
        case $host in
-       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+       *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
          # The PATH hackery in wrapper scripts is required on Windows
          # and Darwin in order for the loader to find any dlls it needs.
          func_warning "'-no-install' is ignored for $host"
@@ -7555,14 +7556,27 @@ func_mode_link ()
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
       # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
+      # -fdiagnostics-color* simply affects output
+      # -frecord-gcc-switches used to verify flags were respected
       # -fsanitize=*         Clang/GCC memory and address sanitizer
+      # -fno-sanitize*       Clang/GCC memory and address sanitizer
+      # -shared-libsan       Link with shared sanitizer runtimes (Clang)
+      # -static-libsan       Link with static sanitizer runtimes (Clang)
+      # -no-canonical-prefixes Do not expand any symbolic links
       # -fuse-ld=*           Linker select flags for GCC
+      # -rtlib=*             select c runtime lib with clang
+      # --unwindlib=*        select unwinder library with clang
+      # -f{file|debug|macro|profile}-prefix-map=* needed for lto linking
       # -Wa,*                Pass flags directly to the assembler
       # -Werror, -Werror=*   Report (specified) warnings as errors
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*|-fsanitize=*|-fuse-ld=*|-Wa,*|-Werror|-Werror=*)
+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-no-canonical-prefixes| \
+      -stdlib=*|-rtlib=*|--unwindlib=*| \
+      -specs=*|-fsanitize=*|-fno-sanitize*|-shared-libsan|-static-libsan| \
+      -ffile-prefix-map=*|-fdebug-prefix-map=*|-fmacro-prefix-map=*|-fprofile-prefix-map=*| \
+      -fdiagnostics-color*|-frecord-gcc-switches| \
+      -fuse-ld=*|-Wa,*|-Werror|-Werror=*)
         func_quote_arg pretty "$arg"
        arg=$func_quote_arg_result
         func_append compile_command " $arg"
@@ -7892,7 +7906,7 @@ func_mode_link ()
        found=false
        case $deplib in
        -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
-        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+        |-threads|-fopenmp|-fopenmp=*|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
          if test prog,link = "$linkmode,$pass"; then
            compile_deplibs="$deplib $compile_deplibs"
            finalize_deplibs="$deplib $finalize_deplibs"
@@ -8069,18 +8083,15 @@ func_mode_link ()
                ;;
              esac
              if $valid_a_lib; then
-               echo
-               $ECHO "*** Warning: Linking the shared library $output against the"
-               $ECHO "*** static library $deplib is not portable!"
+               func_warning "Linking the shared library $output against the static library $deplib is not portable!"
                deplibs="$deplib $deplibs"
              else
-               echo
-               $ECHO "*** Warning: Trying to link with static lib archive $deplib."
-               echo "*** I have the capability to make that library automatically link in when"
-               echo "*** you link to this library.  But I can only do this if you have a"
-               echo "*** shared version of the library, which you do not appear to have"
-               echo "*** because the file extensions .$libext of this argument makes me believe"
-               echo "*** that it is just a static archive that I should not use here."
+               func_warning "Trying to link with static lib archive $deplib."
+               func_warning "I have the capability to make that library automatically link in when"
+               func_warning "you link to this library.  But I can only do this if you have a"
+               func_warning "shared version of the library, which you do not appear to have"
+               func_warning "because the file extensions .$libext of this argument makes me believe"
+               func_warning "that it is just a static archive that I should not use here."
              fi
              ;;
            esac
@@ -8275,7 +8286,7 @@ func_mode_link ()
          fi
          case $host in
            # special handling for platforms with PE-DLLs.
-           *cygwin* | *mingw* | *cegcc* )
+           *cygwin* | *mingw* | *windows* | *cegcc* )
              # Linker will automatically link against shared library if both
              # static and shared are present.  Therefore, ensure we extract
              # symbols from the import library if a shared library is present
@@ -8418,8 +8429,8 @@ func_mode_link ()
        fi
        if test -n "$library_names" &&
           { test no = "$use_static_libs" || test -z "$old_library"; }; then
-         case $host in
-         *cygwin* | *mingw* | *cegcc* | *os2*)
+         case $host_os in
+         cygwin* | mingw* | windows* | cegcc* | os2*)
              # No point in relinking DLLs because paths are not encoded
              func_append notinst_deplibs " $lib"
              need_relink=no
@@ -8445,11 +8456,11 @@ func_mode_link ()
          if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then
            echo
            if test prog = "$linkmode"; then
-             $ECHO "*** Warning: Linking the executable $output against the loadable module"
+             func_warning "Linking the executable $output against the loadable module"
            else
-             $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+             func_warning "Linking the shared library $output against the loadable module"
            fi
-           $ECHO "*** $linklib is not portable!"
+           func_warning "$linklib is not portable!"
          fi
          if test lib = "$linkmode" &&
             test yes = "$hardcode_into_libs"; then
@@ -8488,8 +8499,8 @@ func_mode_link ()
              soname=$dlname
            elif test -n "$soname_spec"; then
              # bleh windows
-             case $host in
-             *cygwin* | mingw* | *cegcc* | *os2*)
+             case $host_os in
+             cygwin* | mingw* | windows* | cegcc* | os2*)
                func_arith $current - $age
                major=$func_arith_result
                versuffix=-$major
@@ -8544,11 +8555,10 @@ func_mode_link ()
                    if /usr/bin/file -L $add 2> /dev/null |
                         $GREP ": [^:]* bundle" >/dev/null; then
                      if test "X$dlopenmodule" != "X$lib"; then
-                       $ECHO "*** Warning: lib $linklib is a module, not a shared library"
+                       func_warning "lib $linklib is a module, not a shared library"
                        if test -z "$old_library"; then
-                         echo
-                         echo "*** And there doesn't seem to be a static archive available"
-                         echo "*** The link will probably fail, sorry"
+                         func_warning "And there doesn't seem to be a static archive available"
+                         func_warning "The link will probably fail, sorry"
                        else
                          add=$dir/$old_library
                        fi
@@ -8688,21 +8698,19 @@ func_mode_link ()
 
            # Just print a warning and add the library to dependency_libs so
            # that the program can be linked against the static library.
-           echo
-           $ECHO "*** Warning: This system cannot link to static lib archive $lib."
-           echo "*** I have the capability to make that library automatically link in when"
-           echo "*** you link to this library.  But I can only do this if you have a"
-           echo "*** shared version of the library, which you do not appear to have."
+           func_warning "This system cannot link to static lib archive $lib."
+           func_warning "I have the capability to make that library automatically link in when"
+           func_warning "you link to this library.  But I can only do this if you have a"
+           func_warning "shared version of the library, which you do not appear to have."
            if test yes = "$module"; then
-             echo "*** But as you try to build a module library, libtool will still create "
-             echo "*** a static module, that should work as long as the dlopening application"
-             echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+             func_warning "But as you try to build a module library, libtool will still create "
+             func_warning "a static module, that should work as long as the dlopening application"
+             func_warning "is linked with the -dlopen flag to resolve symbols at runtime."
              if test -z "$global_symbol_pipe"; then
-               echo
-               echo "*** However, this would only work if libtool was able to extract symbol"
-               echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
-               echo "*** not find such a program.  So, this module is probably useless."
-               echo "*** 'nm' from GNU binutils and a full rebuild may help."
+               func_warning "However, this would only work if libtool was able to extract symbol"
+               func_warning "lists from a program, using 'nm' or equivalent, but libtool could"
+               func_warning "not find such a program.  So, this module is probably useless."
+               func_warning "'nm' from GNU binutils and a full rebuild may help."
              fi
              if test no = "$build_old_libs"; then
                build_libtool_libs=module
@@ -9029,9 +9037,7 @@ func_mode_link ()
        if test pass_all != "$deplibs_check_method"; then
          func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs"
        else
-         echo
-         $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
-         $ECHO "*** objects $objs is not portable!"
+         func_warning "Linking the shared library $output against the non-libtool objects $objs is not portable!"
          func_append libobjs " $objs"
        fi
       fi
@@ -9092,13 +9098,13 @@ func_mode_link ()
          #
          case $version_type in
          # correct linux to gnu/linux during the next big refactor
-         darwin|freebsd-elf|linux|midnightbsd-elf|osf|windows|none)
+         darwin|freebsd-elf|linux|midnightbsd-elf|osf|qnx|windows|none)
            func_arith $number_major + $number_minor
            current=$func_arith_result
            age=$number_minor
            revision=$number_revision
            ;;
-         freebsd-aout|qnx|sunos)
+         freebsd-aout|sco|sunos)
            current=$number_major
            revision=$number_minor
            age=0
@@ -9245,8 +9251,9 @@ func_mode_link ()
          ;;
 
        qnx)
-         major=.$current
-         versuffix=.$current
+         func_arith $current - $age
+         major=.$func_arith_result
+         versuffix=$major.$age.$revision
          ;;
 
        sco)
@@ -9399,7 +9406,7 @@ func_mode_link ()
       if test yes = "$build_libtool_libs"; then
        if test -n "$rpath"; then
          case $host in
-         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
+         *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
            # these systems don't actually have a c library (as such)!
            ;;
          *-*-rhapsody* | *-*-darwin1.[012])
@@ -9450,108 +9457,6 @@ func_mode_link ()
          # implementing what was already the behavior.
          newdeplibs=$deplibs
          ;;
-       test_compile)
-         # This code stresses the "libraries are programs" paradigm to its
-         # limits. Maybe even breaks it.  We compile a program, linking it
-         # against the deplibs as a proxy for the library.  Then we can check
-         # whether they linked in statically or dynamically with ldd.
-         $opt_dry_run || $RM conftest.c
-         cat > conftest.c <<EOF
-         int main() { return 0; }
-EOF
-         $opt_dry_run || $RM conftest
-         if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
-           ldd_output=`ldd conftest`
-           for i in $deplibs; do
-             case $i in
-             -l*)
-               func_stripname -l '' "$i"
-               name=$func_stripname_result
-               if test yes = "$allow_libtool_libs_with_static_runtimes"; then
-                 case " $predeps $postdeps " in
-                 *" $i "*)
-                   func_append newdeplibs " $i"
-                   i=
-                   ;;
-                 esac
-               fi
-               if test -n "$i"; then
-                 libname=`eval "\\$ECHO \"$libname_spec\""`
-                 deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
-                 set dummy $deplib_matches; shift
-                 deplib_match=$1
-                 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
-                   func_append newdeplibs " $i"
-                 else
-                   droppeddeps=yes
-                   echo
-                   $ECHO "*** Warning: dynamic linker does not accept needed library $i."
-                   echo "*** I have the capability to make that library automatically link in when"
-                   echo "*** you link to this library.  But I can only do this if you have a"
-                   echo "*** shared version of the library, which I believe you do not have"
-                   echo "*** because a test_compile did reveal that the linker did not use it for"
-                   echo "*** its dynamic dependency list that programs get resolved with at runtime."
-                 fi
-               fi
-               ;;
-             *)
-               func_append newdeplibs " $i"
-               ;;
-             esac
-           done
-         else
-           # Error occurred in the first compile.  Let's try to salvage
-           # the situation: Compile a separate program for each library.
-           for i in $deplibs; do
-             case $i in
-             -l*)
-               func_stripname -l '' "$i"
-               name=$func_stripname_result
-               $opt_dry_run || $RM conftest
-               if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
-                 ldd_output=`ldd conftest`
-                 if test yes = "$allow_libtool_libs_with_static_runtimes"; then
-                   case " $predeps $postdeps " in
-                   *" $i "*)
-                     func_append newdeplibs " $i"
-                     i=
-                     ;;
-                   esac
-                 fi
-                 if test -n "$i"; then
-                   libname=`eval "\\$ECHO \"$libname_spec\""`
-                   deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
-                   set dummy $deplib_matches; shift
-                   deplib_match=$1
-                   if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then
-                     func_append newdeplibs " $i"
-                   else
-                     droppeddeps=yes
-                     echo
-                     $ECHO "*** Warning: dynamic linker does not accept needed library $i."
-                     echo "*** I have the capability to make that library automatically link in when"
-                     echo "*** you link to this library.  But I can only do this if you have a"
-                     echo "*** shared version of the library, which you do not appear to have"
-                     echo "*** because a test_compile did reveal that the linker did not use this one"
-                     echo "*** as a dynamic dependency that programs can get resolved with at runtime."
-                   fi
-                 fi
-               else
-                 droppeddeps=yes
-                 echo
-                 $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
-                 echo "*** make it link in!  You will probably need to install it or some"
-                 echo "*** library that it depends on before this library will be fully"
-                 echo "*** functional.  Installing it before continuing would be even better."
-               fi
-               ;;
-             *)
-               func_append newdeplibs " $i"
-               ;;
-             esac
-           done
-         fi
-         ;;
        file_magic*)
          set dummy $deplibs_check_method; shift
          file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
@@ -9615,17 +9520,16 @@ EOF
              fi
              if test -n "$a_deplib"; then
                droppeddeps=yes
-               echo
-               $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
-               echo "*** I have the capability to make that library automatically link in when"
-               echo "*** you link to this library.  But I can only do this if you have a"
-               echo "*** shared version of the library, which you do not appear to have"
-               echo "*** because I did check the linker path looking for a file starting"
+               func_warning "Linker path does not have real file for library $a_deplib."
+               func_warning "I have the capability to make that library automatically link in when"
+               func_warning "you link to this library.  But I can only do this if you have a"
+               func_warning "shared version of the library, which you do not appear to have"
+               func_warning "because I did check the linker path looking for a file starting"
                if test -z "$potlib"; then
-                 $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+                 func_warning "with $libname but no candidates were found. (...for file magic test)"
                else
-                 $ECHO "*** with $libname and none of the candidates passed a file format test"
-                 $ECHO "*** using a file magic. Last file checked: $potlib"
+                 func_warning "with $libname and none of the candidates passed a file format test"
+                 func_warning "using a file magic. Last file checked: $potlib"
                fi
              fi
              ;;
@@ -9669,17 +9573,16 @@ EOF
              fi
              if test -n "$a_deplib"; then
                droppeddeps=yes
-               echo
-               $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
-               echo "*** I have the capability to make that library automatically link in when"
-               echo "*** you link to this library.  But I can only do this if you have a"
-               echo "*** shared version of the library, which you do not appear to have"
-               echo "*** because I did check the linker path looking for a file starting"
+               func_warning "Linker path does not have real file for library $a_deplib."
+               func_warning "I have the capability to make that library automatically link in when"
+               func_warning "you link to this library.  But I can only do this if you have a"
+               func_warning "shared version of the library, which you do not appear to have"
+               func_warning "because I did check the linker path looking for a file starting"
                if test -z "$potlib"; then
-                 $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+                 func_warning "with $libname but no candidates were found. (...for regex pattern test)"
                else
-                 $ECHO "*** with $libname and none of the candidates passed a file format test"
-                 $ECHO "*** using a regex pattern. Last file checked: $potlib"
+                 func_warning "with $libname and none of the candidates passed a file format test"
+                 func_warning "using a regex pattern. Last file checked: $potlib"
                fi
              fi
              ;;
@@ -9703,11 +9606,11 @@ EOF
          *[!\  \ ]*)
            echo
            if test none = "$deplibs_check_method"; then
-             echo "*** Warning: inter-library dependencies are not supported in this platform."
+             func_warning "Inter-library dependencies are not supported in this platform."
            else
-             echo "*** Warning: inter-library dependencies are not known to be supported."
+             func_warning "Inter-library dependencies are not known to be supported."
            fi
-           echo "*** All declared inter-library dependencies are being dropped."
+           func_warning "All declared inter-library dependencies are being dropped."
            droppeddeps=yes
            ;;
          esac
@@ -9728,17 +9631,15 @@ EOF
 
        if test yes = "$droppeddeps"; then
          if test yes = "$module"; then
-           echo
-           echo "*** Warning: libtool could not satisfy all declared inter-library"
-           $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
-           echo "*** a static module, that should work as long as the dlopening"
-           echo "*** application is linked with the -dlopen flag."
+           func_warning "libtool could not satisfy all declared inter-library"
+           func_warning "dependencies of module $libname.  Therefore, libtool will create"
+           func_warning "a static module, that should work as long as the dlopening"
+           func_warning "application is linked with the -dlopen flag."
            if test -z "$global_symbol_pipe"; then
-             echo
-             echo "*** However, this would only work if libtool was able to extract symbol"
-             echo "*** lists from a program, using 'nm' or equivalent, but libtool could"
-             echo "*** not find such a program.  So, this module is probably useless."
-             echo "*** 'nm' from GNU binutils and a full rebuild may help."
+             func_warning "However, this would only work if libtool was able to extract symbol"
+             func_warning "lists from a program, using 'nm' or equivalent, but libtool could"
+             func_warning "not find such a program.  So, this module is probably useless."
+             func_warning "'nm' from GNU binutils and a full rebuild may help."
            fi
            if test no = "$build_old_libs"; then
              oldlibs=$output_objdir/$libname.$libext
@@ -9913,7 +9814,7 @@ EOF
 
        orig_export_symbols=
        case $host_os in
-       cygwin* | mingw* | cegcc*)
+       cygwin* | mingw* | windows* | cegcc*)
          if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
            # exporting using user supplied symfile
            func_dll_def_p "$export_symbols" || {
@@ -10583,7 +10484,7 @@ EOF
          esac
        fi
        case $host in
-       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+       *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*)
          testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'`
          case :$dllsearchpath: in
          *":$libdir:"*) ;;
@@ -10661,7 +10562,7 @@ EOF
         # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
         wrappers_required=false
         ;;
-      *cygwin* | *mingw* )
+      *cygwin* | *mingw* | *windows* )
         test yes = "$build_libtool_libs" || wrappers_required=false
         ;;
       *)
@@ -10815,7 +10716,7 @@ EOF
          *) exeext= ;;
        esac
        case $host in
-         *cygwin* | *mingw* )
+         *cygwin* | *mingw* | windows* )
            func_dirname_and_basename "$output" "" "."
            output_name=$func_basename_result
            output_path=$func_dirname_result
@@ -11149,7 +11050,7 @@ EOF
          # tests/bindir.at for full details.
          tdlname=$dlname
          case $host,$output,$installed,$module,$dlname in
-           *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+           *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *windows*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
              # If a -bindir argument was supplied, place the dll there.
              if test -n "$bindir"; then
                func_relative_path "$install_libdir" "$bindir"
index 717e76978d934d0f4ef0c15512e33e529aaf1d04..c5be64368225952bfd3ea67ee521533d0286aea4 100644 (file)
@@ -1,6 +1,6 @@
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 #
-#   Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software
+#   Copyright (C) 1996-2001, 2003-2019, 2021-2024 Free Software
 #   Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
@@ -9,13 +9,13 @@
 # modifications, as long as this notice is preserved.
 
 m4_define([_LT_COPYING], [dnl
-# Copyright (C) 2014 Free Software Foundation, Inc.
+# Copyright (C) 2024 Free Software Foundation, Inc.
 # This is free software; see the source for copying conditions.  There is NO
 # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 # GNU Libtool is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of of the License, or
+# the Free Software Foundation; either version 2 of the License, or
 # (at your option) any later version.
 #
 # As a special exception to the GNU General Public License, if you
@@ -32,7 +32,7 @@ m4_define([_LT_COPYING], [dnl
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ])
 
-# serial 59 LT_INIT
+# serial 61 LT_INIT
 
 
 # LT_PREREQ(VERSION)
@@ -616,7 +616,7 @@ m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
 # LT_OUTPUT
 # ---------
 # This macro allows early generation of the libtool script (before
-# AC_OUTPUT is called), incase it is used in configure for compilation
+# AC_OUTPUT is called), in case it is used in configure for compilation
 # tests.
 AC_DEFUN([LT_OUTPUT],
 [: ${CONFIG_LT=./config.lt}
@@ -651,9 +651,9 @@ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
 m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
 configured by $[0], generated by m4_PACKAGE_STRING.
 
-Copyright (C) 2011 Free Software Foundation, Inc.
+Copyright (C) 2024 Free Software Foundation, Inc.
 This config.lt script is free software; the Free Software Foundation
-gives unlimited permision to copy, distribute and modify it."
+gives unlimited permission to copy, distribute and modify it."
 
 while test 0 != $[#]
 do
@@ -1255,7 +1255,9 @@ lt_sysroot=
 case $with_sysroot in #(
  yes)
    if test yes = "$GCC"; then
-     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+     # Trim trailing / since we'll always append absolute paths and we want
+     # to avoid //, if only for less confusing output for the user.
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null | $SED 's:/\+$::'`
    fi
    ;; #(
  /*)
@@ -1367,7 +1369,7 @@ mips64*-*linux*)
   ;;
 
 x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
-s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*)
   # Find out what ABI is being produced by ac_compile, and set linker
   # options accordingly.  Note that the listed cases only cover the
   # situations where additional linker options are needed (such as when
@@ -1382,7 +1384,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
          x86_64-*kfreebsd*-gnu)
            LD="${LD-ld} -m elf_i386_fbsd"
            ;;
-         x86_64-*linux*)
+         x86_64-*linux*|x86_64-gnu*)
            case `$FILECMD conftest.o` in
              *x86-64*)
                LD="${LD-ld} -m elf32_x86_64"
@@ -1411,7 +1413,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
          x86_64-*kfreebsd*-gnu)
            LD="${LD-ld} -m elf_x86_64_fbsd"
            ;;
-         x86_64-*linux*)
+         x86_64-*linux*|x86_64-gnu*)
            LD="${LD-ld} -m elf_x86_64"
            ;;
          powerpcle-*linux*)
@@ -1494,7 +1496,7 @@ _LT_DECL([], [AR], [1], [The archiver])
 
 # Use ARFLAGS variable as AR's operation code to sync the variable naming with
 # Automake.  If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
-# higher priority because thats what people were doing historically (setting
+# higher priority because that's what people were doing historically (setting
 # ARFLAGS for automake and AR_FLAGS for libtool).  FIXME: Make the AR_FLAGS
 # variable obsoleted/removed.
 
@@ -1555,15 +1557,8 @@ old_postinstall_cmds='chmod 644 $oldlib'
 old_postuninstall_cmds=
 
 if test -n "$RANLIB"; then
-  case $host_os in
-  bitrig* | openbsd*)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
-    ;;
-  *)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
-    ;;
-  esac
   old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
+  old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
 fi
 
 case $host_os in
@@ -1702,7 +1697,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     lt_cv_sys_max_cmd_len=-1;
     ;;
 
-  cygwin* | mingw* | cegcc*)
+  cygwin* | mingw* | windows* | cegcc*)
     # On Win9x/ME, this test blows up -- it succeeds, but takes
     # about 5 minutes as the teststring grows exponentially.
     # Worse, since 9x/ME are not pre-emptively multitasking,
@@ -1724,7 +1719,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
-  bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*)
+  darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*)
     # This has been around since 386BSD, at least.  Likely further.
     if test -x /sbin/sysctl; then
       lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
@@ -1945,7 +1940,7 @@ else
     lt_cv_dlopen_self=yes
     ;;
 
-  mingw* | pw32* | cegcc*)
+  mingw* | windows* | pw32* | cegcc*)
     lt_cv_dlopen=LoadLibrary
     lt_cv_dlopen_libs=
     ;;
@@ -2313,7 +2308,7 @@ if test yes = "$GCC"; then
     *) lt_awk_arg='/^libraries:/' ;;
   esac
   case $host_os in
-    mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
+    mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;;
     *) lt_sed_strip_eq='s|=/|/|g' ;;
   esac
   lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
@@ -2371,7 +2366,7 @@ BEGIN {RS = " "; FS = "/|\n";} {
   # AWK program above erroneously prepends '/' to C:/dos/paths
   # for these hosts.
   case $host_os in
-    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+    mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
       $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;;
   esac
   sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
@@ -2540,7 +2535,7 @@ bsdi[[45]]*)
   # libtool to hard-code these into programs
   ;;
 
-cygwin* | mingw* | pw32* | cegcc*)
+cygwin* | mingw* | windows* | pw32* | cegcc*)
   version_type=windows
   shrext_cmds=.dll
   need_version=no
@@ -2572,7 +2567,7 @@ cygwin* | mingw* | pw32* | cegcc*)
 m4_if([$1], [],[
       sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
       ;;
-    mingw* | cegcc*)
+    mingw* | windows* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
       soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
       ;;
@@ -2591,7 +2586,7 @@ m4_if([$1], [],[
     library_names_spec='$libname.dll.lib'
 
     case $build_os in
-    mingw*)
+    mingw* | windows*)
       sys_lib_search_path_spec=
       lt_save_ifs=$IFS
       IFS=';'
@@ -2839,7 +2834,7 @@ linux*android*)
   version_type=none # Android doesn't support versioned libraries.
   need_lib_prefix=no
   need_version=no
-  library_names_spec='$libname$release$shared_ext'
+  library_names_spec='$libname$release$shared_ext $libname$shared_ext'
   soname_spec='$libname$release$shared_ext'
   finish_cmds=
   shlibpath_var=LD_LIBRARY_PATH
@@ -2851,8 +2846,9 @@ linux*android*)
   hardcode_into_libs=yes
 
   dynamic_linker='Android linker'
-  # Don't embed -rpath directories since the linker doesn't support them.
-  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+  # -rpath works at least for libraries that are not overridden by
+  # libraries installed in system locations.
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
   ;;
 
 # This must be glibc/ELF.
@@ -2886,7 +2882,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
   # before this can be enabled.
   hardcode_into_libs=yes
 
-  # Ideally, we could use ldconfig to report *all* directores which are
+  # Ideally, we could use ldconfig to report *all* directories which are
   # searched for libraries, however this is still not possible.  Aside from not
   # being certain /sbin/ldconfig is available, command
   # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64,
@@ -2943,7 +2939,7 @@ newsos6)
   dynamic_linker='ldqnx.so'
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   version_type=sunos
   sys_lib_dlsearch_path_spec=/usr/lib
   need_lib_prefix=no
@@ -3275,7 +3271,7 @@ if test yes = "$GCC"; then
   # Check if gcc -print-prog-name=ld gives a path.
   AC_MSG_CHECKING([for ld used by $CC])
   case $host in
-  *-*-mingw*)
+  *-*-mingw* | *-*-windows*)
     # gcc leaves a trailing carriage return, which upsets mingw
     ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
   *)
@@ -3384,7 +3380,7 @@ case $reload_flag in
 esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
-  cygwin* | mingw* | pw32* | cegcc*)
+  cygwin* | mingw* | windows* | pw32* | cegcc*)
     if test yes != "$GCC"; then
       reload_cmds=false
     fi
@@ -3456,7 +3452,6 @@ lt_cv_deplibs_check_method='unknown'
 # 'none' -- dependencies not supported.
 # 'unknown' -- same as none, but documents that we really don't know.
 # 'pass_all' -- all dependencies passed with no checks.
-# 'test_compile' -- check by making test program.
 # 'file_magic [[regex]]' -- check by looking for files in library path
 # that responds to the $file_magic_cmd with a given extended regex.
 # If you have 'file' or equivalent on your system and you're not sure
@@ -3483,7 +3478,7 @@ cygwin*)
   lt_cv_file_magic_cmd='func_win32_libid'
   ;;
 
-mingw* | pw32*)
+mingw* | windows* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
@@ -3583,7 +3578,7 @@ newos6*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-openbsd* | bitrig*)
+openbsd*)
   if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then
     lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
   else
@@ -3647,7 +3642,7 @@ file_magic_glob=
 want_nocaseglob=no
 if test "$build" = "$host"; then
   case $host_os in
-  mingw* | pw32*)
+  mingw* | windows* | pw32*)
     if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
       want_nocaseglob=yes
     else
@@ -3699,7 +3694,7 @@ else
        # Tru64's nm complains that /dev/null is an invalid object file
        # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty
        case $build_os in
-       mingw*) lt_bad_file=conftest.nm/nofile ;;
+       mingw* | windows*) lt_bad_file=conftest.nm/nofile ;;
        *) lt_bad_file=/dev/null ;;
        esac
        case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in
@@ -3790,7 +3785,7 @@ lt_cv_sharedlib_from_linklib_cmd,
 [lt_cv_sharedlib_from_linklib_cmd='unknown'
 
 case $host_os in
-cygwin* | mingw* | pw32* | cegcc*)
+cygwin* | mingw* | windows* | pw32* | cegcc*)
   # two different shell functions defined in ltmain.sh;
   # decide which one to use based on capabilities of $DLLTOOL
   case `$DLLTOOL --help 2>&1` in
@@ -3822,16 +3817,16 @@ _LT_DECL([], [sharedlib_from_linklib_cmd], [1],
 m4_defun([_LT_PATH_MANIFEST_TOOL],
 [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
 test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
-AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
-  [lt_cv_path_mainfest_tool=no
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_manifest_tool],
+  [lt_cv_path_manifest_tool=no
   echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
   $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
   cat conftest.err >&AS_MESSAGE_LOG_FD
   if $GREP 'Manifest Tool' conftest.out > /dev/null; then
-    lt_cv_path_mainfest_tool=yes
+    lt_cv_path_manifest_tool=yes
   fi
   rm -f conftest*])
-if test yes != "$lt_cv_path_mainfest_tool"; then
+if test yes != "$lt_cv_path_manifest_tool"; then
   MANIFEST_TOOL=:
 fi
 _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
@@ -3860,7 +3855,7 @@ AC_DEFUN([LT_LIB_M],
 [AC_REQUIRE([AC_CANONICAL_HOST])dnl
 LIBM=
 case $host in
-*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-mingw* | *-*-pw32* | *-*-darwin*)
   # These system don't have libm, or don't need it
   ;;
 *-ncr-sysv4.3*)
@@ -3935,7 +3930,7 @@ case $host_os in
 aix*)
   symcode='[[BCDT]]'
   ;;
-cygwin* | mingw* | pw32* | cegcc*)
+cygwin* | mingw* | windows* | pw32* | cegcc*)
   symcode='[[ABCDGISTW]]'
   ;;
 hpux*)
@@ -3950,7 +3945,7 @@ osf*)
   symcode='[[BCDEGQRST]]'
   ;;
 solaris*)
-  symcode='[[BDRT]]'
+  symcode='[[BCDRT]]'
   ;;
 sco3.2v5*)
   symcode='[[DT]]'
@@ -4014,7 +4009,7 @@ $lt_c_name_lib_hook\
 # Handle CRLF in mingw tool chain
 opt_cr=
 case $build_os in
-mingw*)
+mingw* | windows*)
   opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
   ;;
 esac
@@ -4241,7 +4236,7 @@ m4_if([$1], [CXX], [
     beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
       # PIC is the default for these OSes.
       ;;
-    mingw* | cygwin* | os2* | pw32* | cegcc*)
+    mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
@@ -4317,7 +4312,7 @@ m4_if([$1], [CXX], [
          ;;
        esac
        ;;
-      mingw* | cygwin* | os2* | pw32* | cegcc*)
+      mingw* | windows* | cygwin* | os2* | pw32* | cegcc*)
        # This hack is so that the source file can tell whether it is being
        # built for inclusion in a dll (and should export symbols for example).
        m4_if([$1], [GCJ], [],
@@ -4565,7 +4560,7 @@ m4_if([$1], [CXX], [
       # PIC is the default for these OSes.
       ;;
 
-    mingw* | cygwin* | pw32* | os2* | cegcc*)
+    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       # Although the cygwin gcc ignores -fPIC, still need this for old-style
@@ -4669,7 +4664,7 @@ m4_if([$1], [CXX], [
       esac
       ;;
 
-    mingw* | cygwin* | pw32* | os2* | cegcc*)
+    mingw* | windows* | cygwin* | pw32* | os2* | cegcc*)
       # This hack is so that the source file can tell whether it is being
       # built for inclusion in a dll (and should export symbols for example).
       m4_if([$1], [GCJ], [],
@@ -4711,6 +4706,12 @@ m4_if([$1], [CXX], [
        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
        _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
         ;;
+      *flang)
+        # Flang compiler.
+       _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+       _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+       _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
       # icc used to be incompatible with GCC.
       # ICC 10 doesn't accept -KPIC any more.
       icc* | ifort*)
@@ -4944,7 +4945,7 @@ m4_if([$1], [CXX], [
   pw32*)
     _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds
     ;;
-  cygwin* | mingw* | cegcc*)
+  cygwin* | mingw* | windows* | cegcc*)
     case $cc_basename in
     cl* | icl*)
       _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
@@ -5002,7 +5003,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
   extract_expsyms_cmds=
 
   case $host_os in
-  cygwin* | mingw* | pw32* | cegcc*)
+  cygwin* | mingw* | windows* | pw32* | cegcc*)
     # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
     # When not using gcc, we currently assume that we are using
     # Microsoft Visual C++ or Intel C++ Compiler.
@@ -5014,7 +5015,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
     with_gnu_ld=yes
     ;;
-  openbsd* | bitrig*)
+  openbsd*)
     with_gnu_ld=no
     ;;
   esac
@@ -5117,7 +5118,7 @@ _LT_EOF
       fi
       ;;
 
-    cygwin* | mingw* | pw32* | cegcc*)
+    cygwin* | mingw* | windows* | pw32* | cegcc*)
       # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
       # as there is no search path for DLLs.
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
@@ -5173,7 +5174,7 @@ _LT_EOF
        cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
        $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
        emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
       _LT_TAGVAR(file_list_spec, $1)='@'
       ;;
@@ -5574,7 +5575,7 @@ _LT_EOF
       _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
       ;;
 
-    cygwin* | mingw* | pw32* | cegcc*)
+    cygwin* | mingw* | windows* | pw32* | cegcc*)
       # When not using gcc, we currently assume that we are using
       # Microsoft Visual C++ or Intel C++ Compiler.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
@@ -5591,14 +5592,14 @@ _LT_EOF
        # Tell ltmain to make .dll files, not .so files.
        shrext_cmds=.dll
        # FIXME: Setting linknames here is a bad hack.
-       _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
+       _LT_TAGVAR(archive_cmds, $1)='$CC -Fe $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames='
        _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then
             cp "$export_symbols" "$output_objdir/$soname.def";
             echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp";
           else
             $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp;
           fi~
-          $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+          $CC -Fe $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
           linknames='
        # The linker will not automatically build a static lib if we build a DLL.
        # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
@@ -5836,7 +5837,7 @@ _LT_EOF
     *nto* | *qnx*)
       ;;
 
-    openbsd* | bitrig*)
+    openbsd*)
       if test -f /usr/libexec/ld.so; then
        _LT_TAGVAR(hardcode_direct, $1)=yes
        _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -5879,7 +5880,7 @@ _LT_EOF
        cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
        $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
        emximp -o $lib $output_objdir/$libname.def'
-      _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
       _LT_TAGVAR(file_list_spec, $1)='@'
       ;;
@@ -6173,7 +6174,7 @@ _LT_TAGDECL([], [hardcode_direct], [0],
 _LT_TAGDECL([], [hardcode_direct_absolute], [0],
     [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes
     DIR into the resulting binary and the resulting library dependency is
-    "absolute", i.e impossible to change by setting $shlibpath_var if the
+    "absolute", i.e. impossible to change by setting $shlibpath_var if the
     library is relocated])
 _LT_TAGDECL([], [hardcode_minus_L], [0],
     [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
@@ -6420,8 +6421,7 @@ if test yes != "$_lt_caught_CXX_error"; then
         wlarc='$wl'
 
         # ancient GNU ld didn't support --whole-archive et. al.
-        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
-         $GREP 'no-whole-archive' > /dev/null; then
+        if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
           _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive'
         else
           _LT_TAGVAR(whole_archive_flag_spec, $1)=
@@ -6441,7 +6441,7 @@ if test yes != "$_lt_caught_CXX_error"; then
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
 
     else
       GXX=no
@@ -6650,7 +6650,7 @@ if test yes != "$_lt_caught_CXX_error"; then
         esac
         ;;
 
-      cygwin* | mingw* | pw32* | cegcc*)
+      cygwin* | mingw* | windows* | pw32* | cegcc*)
        case $GXX,$cc_basename in
        ,cl* | no,cl* | ,icl* | no,icl*)
          # Native MSVC or ICC
@@ -6749,7 +6749,7 @@ if test yes != "$_lt_caught_CXX_error"; then
          cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~
          $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~
          emximp -o $lib $output_objdir/$libname.def'
-       _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
+       _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
        _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
        _LT_TAGVAR(file_list_spec, $1)='@'
        ;;
@@ -6817,7 +6817,7 @@ if test yes != "$_lt_caught_CXX_error"; then
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test yes = "$GXX"; then
@@ -6882,7 +6882,7 @@ if test yes != "$_lt_caught_CXX_error"; then
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
            ;;
           *)
            if test yes = "$GXX"; then
@@ -7130,7 +7130,7 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(ld_shlibs, $1)=yes
        ;;
 
-      openbsd* | bitrig*)
+      openbsd*)
        if test -f /usr/libexec/ld.so; then
          _LT_TAGVAR(hardcode_direct, $1)=yes
          _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -7221,7 +7221,7 @@ if test yes != "$_lt_caught_CXX_error"; then
              # Commands to make compiler produce verbose output that lists
              # what "hidden" libraries, object files and flags are used when
              # linking a shared library.
-             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
 
            else
              # FIXME: insert proper C++ library support
@@ -7305,7 +7305,7 @@ if test yes != "$_lt_caught_CXX_error"; then
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
              else
                # g++ 2.7 appears to require '-G' NOT '-shared' on this
                # platform.
@@ -7316,7 +7316,7 @@ if test yes != "$_lt_caught_CXX_error"; then
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "[[-]]L"'
              fi
 
              _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
@@ -7554,10 +7554,11 @@ if AC_TRY_EVAL(ac_compile); then
     case $prev$p in
 
     -L* | -R* | -l*)
-       # Some compilers place space between "-{L,R}" and the path.
+       # Some compilers place space between "-{L,R,l}" and the path.
        # Remove the space.
-       if test x-L = "$p" ||
-          test x-R = "$p"; then
+       if test x-L = x"$p" ||
+          test x-R = x"$p" ||
+          test x-l = x"$p"; then
         prev=$p
         continue
        fi
@@ -8215,7 +8216,7 @@ AC_SUBST([DLLTOOL])
 # ----------------
 # Check for a file(cmd) program that can be used to detect file type and magic
 m4_defun([_LT_DECL_FILECMD],
-[AC_CHECK_TOOL([FILECMD], [file], [:])
+[AC_CHECK_PROG([FILECMD], [file], [:])
 _LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types])
 ])# _LD_DECL_FILECMD
 
@@ -8231,73 +8232,6 @@ _LT_DECL([], [SED], [1], [A sed program that does not truncate output])
 _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
     [Sed that helps us avoid accidentally triggering echo(1) options like -n])
 ])# _LT_DECL_SED
-
-m4_ifndef([AC_PROG_SED], [
-############################################################
-# NOTE: This macro has been submitted for inclusion into   #
-#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
-#  a released version of Autoconf we should remove this    #
-#  macro and use it instead.                               #
-############################################################
-
-m4_defun([AC_PROG_SED],
-[AC_MSG_CHECKING([for a sed that does not truncate output])
-AC_CACHE_VAL(lt_cv_path_SED,
-[# Loop through the user's path and test for sed and gsed.
-# Then use that list of sed's as ones to test for truncation.
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for lt_ac_prog in sed gsed; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
-        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
-      fi
-    done
-  done
-done
-IFS=$as_save_IFS
-lt_ac_max=0
-lt_ac_count=0
-# Add /usr/xpg4/bin/sed as it is typically found on Solaris
-# along with /bin/sed that truncates output.
-for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
-  test ! -f "$lt_ac_sed" && continue
-  cat /dev/null > conftest.in
-  lt_ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
-  # Check for GNU sed and select it if it is found.
-  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
-    lt_cv_path_SED=$lt_ac_sed
-    break
-  fi
-  while true; do
-    cat conftest.in conftest.in >conftest.tmp
-    mv conftest.tmp conftest.in
-    cp conftest.in conftest.nl
-    echo >>conftest.nl
-    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
-    cmp -s conftest.out conftest.nl || break
-    # 10000 chars as input seems more than enough
-    test 10 -lt "$lt_ac_count" && break
-    lt_ac_count=`expr $lt_ac_count + 1`
-    if test "$lt_ac_count" -gt "$lt_ac_max"; then
-      lt_ac_max=$lt_ac_count
-      lt_cv_path_SED=$lt_ac_sed
-    fi
-  done
-done
-])
-SED=$lt_cv_path_SED
-AC_SUBST([SED])
-AC_MSG_RESULT([$SED])
-])#AC_PROG_SED
-])#m4_ifndef
-
-# Old name:
-AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
 dnl aclocal-1.4 backwards compatibility:
 dnl AC_DEFUN([LT_AC_PROG_SED], [])
 
@@ -8344,7 +8278,7 @@ AC_CACHE_VAL(lt_cv_to_host_file_cmd,
 [case $host in
   *-*-mingw* )
     case $build in
-      *-*-mingw* ) # actually msys
+      *-*-mingw* | *-*-windows* ) # actually msys
         lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
         ;;
       *-*-cygwin* )
@@ -8357,7 +8291,7 @@ AC_CACHE_VAL(lt_cv_to_host_file_cmd,
     ;;
   *-*-cygwin* )
     case $build in
-      *-*-mingw* ) # actually msys
+      *-*-mingw* | *-*-windows* ) # actually msys
         lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
         ;;
       *-*-cygwin* )
@@ -8383,9 +8317,9 @@ AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
 [#assume ordinary cross tools, or native build.
 lt_cv_to_tool_file_cmd=func_convert_file_noop
 case $host in
-  *-*-mingw* )
+  *-*-mingw* | *-*-windows* )
     case $build in
-      *-*-mingw* ) # actually msys
+      *-*-mingw* | *-*-windows* ) # actually msys
         lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
         ;;
     esac
index b0b5e9c21260626dbace09fdb80b1fddb5a90db8..6dfe99f1f200cf6de44eca450ec2b446fd185c19 100644 (file)
@@ -1,6 +1,6 @@
 # Helper functions for option handling.                    -*- Autoconf -*-
 #
-#   Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free
+#   Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2024 Free
 #   Software Foundation, Inc.
 #   Written by Gary V. Vaughan, 2004
 #
@@ -8,7 +8,7 @@
 # unlimited permission to copy and/or distribute it, with or without
 # modifications, as long as this notice is preserved.
 
-# serial 8 ltoptions.m4
+# serial 9 ltoptions.m4
 
 # This is to help aclocal find these macros, as it can't see m4_define.
 AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
@@ -128,7 +128,7 @@ LT_OPTION_DEFINE([LT_INIT], [win32-dll],
 [enable_win32_dll=yes
 
 case $host in
-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
+*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-cegcc*)
   AC_CHECK_TOOL(AS, as, false)
   AC_CHECK_TOOL(DLLTOOL, dlltool, false)
   AC_CHECK_TOOL(OBJDUMP, objdump, false)
index 902508bd93aec6b21aa65636f69eaeb7c9b67329..5b5c80a3ad78a1c33104908a40e3f3f12e920df2 100644 (file)
@@ -1,6 +1,6 @@
 # ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
 #
-# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software
+# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2024 Free Software
 # Foundation, Inc.
 # Written by Gary V. Vaughan, 2004
 #
index 0026c21cfb3d58b7a1e89f27599451019ffdc2b8..82887f7c954bbdd0b70ac0e0d73e20aa91b228f4 100644 (file)
@@ -1,6 +1,6 @@
 # ltversion.m4 -- version numbers                      -*- Autoconf -*-
 #
-#   Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation,
+#   Copyright (C) 2004, 2011-2019, 2021-2024 Free Software Foundation,
 #   Inc.
 #   Written by Scott James Remnant, 2004
 #
 
 # @configure_input@
 
-# serial 4249 ltversion.m4
+# serial 4337 ltversion.m4
 # This file is part of GNU Libtool
 
-m4_define([LT_PACKAGE_VERSION], [2.4.7.4-1ec8f-dirty])
-m4_define([LT_PACKAGE_REVISION], [2.4.7.4])
+m4_define([LT_PACKAGE_VERSION], [2.5.0.1-38c1-dirty])
+m4_define([LT_PACKAGE_REVISION], [2.5.0.1])
 
 AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.4.7.4-1ec8f-dirty'
-macro_revision='2.4.7.4'
+[macro_version='2.5.0.1-38c1-dirty'
+macro_revision='2.5.0.1'
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_revision, 0)
 ])
index 0f7a8759da8d46df4a9996141d7138ca680cce6b..22b5346973571a78d046a0ce77bae488d4e43280 100644 (file)
@@ -1,6 +1,6 @@
 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
 #
-#   Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free
+#   Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2024 Free
 #   Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004.
 #
index ae00de06ef2b0783ffa574334f85a63ae2a3be9b..c025d5fd8c3ebf8b7667deb6c9b837891f60f806 100644 (file)
@@ -77,6 +77,8 @@ AC_DEFUN([PCRE2_VISIBILITY],
     else
       AC_DEFINE(PCRE2_EXPORT, [], [to make a symbol visible])
     fi
+  else
+    AC_DEFINE(PCRE2_EXPORT, [], [to make a symbol visible])
   fi
   AC_SUBST([VISIBILITY_CFLAGS])
   AC_SUBST([VISIBILITY_CXXFLAGS])
index e8779b55cd1844e5318424b97ae881af91146760..0092948132aeba60e4aba75a386fdc12a7318993 100644 (file)
@@ -215,7 +215,7 @@ sure both macros are undefined; an emulation function will then be used. */
    Care must be taken if it is increased, because it guards against integer
    overflow caused by enormously large patterns. */
 #ifndef MAX_NAME_SIZE
-#define MAX_NAME_SIZE 32
+#define MAX_NAME_SIZE 128
 #endif
 
 /* The value of MAX_VARLOOKBEHIND specifies the default maximum length, in
@@ -245,7 +245,7 @@ sure both macros are undefined; an emulation function will then be used. */
 #define PACKAGE_NAME "PCRE2"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "PCRE2 10.43"
+#define PACKAGE_STRING "PCRE2 10.44"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "pcre2"
@@ -254,7 +254,7 @@ sure both macros are undefined; an emulation function will then be used. */
 #define PACKAGE_URL ""
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "10.43"
+#define PACKAGE_VERSION "10.44"
 
 /* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
    parentheses (of any kind) in a pattern. This limits the amount of system
@@ -458,7 +458,7 @@ sure both macros are undefined; an emulation function will then be used. */
 #endif
 
 /* Version number of package */
-#define VERSION "10.43"
+#define VERSION "10.44"
 
 /* Number of bits in a file offset, on hosts where this is settable. */
 /* #undef _FILE_OFFSET_BITS */
index d7a8ff5201e18e852436c103d6579c2ddbc33843..a322d9f2d56f939c83c42e85ed42bb923a4427c9 100644 (file)
@@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
 /* The current PCRE version information. */
 
 #define PCRE2_MAJOR           10
-#define PCRE2_MINOR           43
+#define PCRE2_MINOR           44
 #define PCRE2_PRERELEASE      
-#define PCRE2_DATE            2024-02-16
+#define PCRE2_DATE            2024-06-07
 
 /* 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
@@ -603,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_pattern_compiled_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 \
@@ -901,6 +903,7 @@ pcre2_compile are called by application code. */
 #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_max_pattern_compiled_length PCRE2_SUFFIX(pcre2_set_max_pattern_compiled_length_)
 #define pcre2_set_newline                     PCRE2_SUFFIX(pcre2_set_newline_)
 #define pcre2_set_parens_nest_limit           PCRE2_SUFFIX(pcre2_set_parens_nest_limit_)
 #define pcre2_set_offset_limit                PCRE2_SUFFIX(pcre2_set_offset_limit_)
index 1e7e5eb19ef969ec3d4862a06213919aa52ce7b4..b43534b04dc65bdc284a81576260e308f2c92874 100644 (file)
@@ -603,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_pattern_compiled_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 \
@@ -901,6 +903,7 @@ pcre2_compile are called by application code. */
 #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_max_pattern_compiled_length PCRE2_SUFFIX(pcre2_set_max_pattern_compiled_length_)
 #define pcre2_set_newline                     PCRE2_SUFFIX(pcre2_set_newline_)
 #define pcre2_set_parens_nest_limit           PCRE2_SUFFIX(pcre2_set_parens_nest_limit_)
 #define pcre2_set_offset_limit                PCRE2_SUFFIX(pcre2_set_offset_limit_)
index 8b364977c46481be1c4ac5d782c54849f6858dda..8e6787aba38ec1a977098257bf0c1e5987290591 100644 (file)
@@ -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-2023 University of Cambridge
+          New API code Copyright (c) 2016-2024 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -808,7 +808,8 @@ 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, ERR100 };
+       ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99, ERR100,
+       ERR101 };
 
 /* 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
@@ -7549,7 +7550,8 @@ for (;; pptr++)
             if (lengthptr != NULL)
               {
               PCRE2_SIZE delta;
-              if (PRIV(ckd_smul)(&delta, repeat_min - 1, length_prevgroup) ||
+              if (PRIV(ckd_smul)(&delta, repeat_min - 1,
+                                 (int)length_prevgroup) ||
                   OFLOW_MAX - *lengthptr < delta)
                 {
                 *errorcodeptr = ERR20;
@@ -7599,7 +7601,7 @@ for (;; pptr++)
             {
             PCRE2_SIZE delta;
             if (PRIV(ckd_smul)(&delta, repeat_max,
-                               length_prevgroup + 1 + 2 + 2*LINK_SIZE) ||
+                               (int)length_prevgroup + 1 + 2 + 2*LINK_SIZE) ||
                 OFLOW_MAX + (2 + 2*LINK_SIZE) - *lengthptr < delta)
               {
               *errorcodeptr = ERR20;
@@ -9908,7 +9910,7 @@ do
   *bptr |= branchlength;  /* branchlength never more than 65535 */
   bptr = *pptrptr;
   }
-while (*bptr == META_ALT);
+while (META_CODE(*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
@@ -10601,14 +10603,21 @@ if (length > MAX_PATTERN_SIZE)
   goto HAD_CB_ERROR;
   }
 
-/* Compute the size of, and then get and initialize, the data block for storing
-the compiled pattern and names table. Integer overflow should no longer be
-possible because nowadays we limit the maximum value of cb.names_found and
-cb.name_entry_size. */
+/* Compute the size of, then, if not too large, get and initialize the data
+block for storing the compiled pattern and names table. Integer overflow should
+no longer be possible because nowadays we limit the maximum value of
+cb.names_found and cb.name_entry_size. */
 
 re_blocksize = sizeof(pcre2_real_code) +
   CU2BYTES(length +
   (PCRE2_SIZE)cb.names_found * (PCRE2_SIZE)cb.name_entry_size);
+
+if (re_blocksize > ccontext->max_pattern_compiled_length)
+  {
+  errorcode = ERR101;
+  goto HAD_CB_ERROR;
+  }
+
 re = (pcre2_real_code *)
   ccontext->memctl.malloc(re_blocksize, ccontext->memctl.memory_data);
 if (re == NULL)
index 0bc2ea0b047ccac6d9bc4d89329ea2563ff80303..9edbd1b2ae8659480860af5aaa407027fb56d0dc 100644 (file)
@@ -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-2023 University of Cambridge
+          New API code Copyright (c) 2016-2024 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -136,6 +136,7 @@ const pcre2_compile_context PRIV(default_compile_context) = {
   NULL,                                      /* Stack guard data */
   PRIV(default_tables),                      /* Character tables */
   PCRE2_UNSET,                               /* Max pattern length */
+  PCRE2_UNSET,                               /* Max pattern compiled length */
   BSR_DEFAULT,                               /* Backslash R default */
   NEWLINE_DEFAULT,                           /* Newline convention */
   PARENS_NEST_LIMIT,                         /* As it says */
@@ -352,6 +353,13 @@ ccontext->max_pattern_length = length;
 return 0;
 }
 
+PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
+pcre2_set_max_pattern_compiled_length(pcre2_compile_context *ccontext, PCRE2_SIZE length)
+{
+ccontext->max_pattern_compiled_length = length;
+return 0;
+}
+
 PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
 pcre2_set_newline(pcre2_compile_context *ccontext, uint32_t newline)
 {
index 1569f6315f5cc6a42a19b7764f977e53827d4430..7fa997aa9510b4d3b363f88c4a8aaf3f9f68f5e8 100644 (file)
@@ -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-2023 University of Cambridge
+          New API code Copyright (c) 2016-2024 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -189,6 +189,7 @@ static const unsigned char compile_error_texts[] =
   "\\K is not allowed in lookarounds (but see PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK)\0"
   /* 100 */
   "branch too long in variable-length lookbehind assertion\0"
+  "compiled pattern would be longer than the limit set by the application\0"
   ;
 
 /* Match-time and UTF error texts are in the same format. */
index b23946b0d16e6485c607bc67fe8849cd36575ddd..4ed9f00c55a1c229599b1236d81cf5ef6fffb681 100644 (file)
@@ -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-2024 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -75,7 +75,11 @@ return NULL;
 *      Match an extended grapheme sequence       *
 *************************************************/
 
-/*
+/* NOTE: The logic contained in this function is replicated in three special-
+purpose functions in the pcre2_jit_compile.c module. If the logic below is
+changed, they must be kept in step so that the interpreter and the JIT have the
+same behaviour.
+
 Arguments:
   c              the first character
   eptr           pointer to next character
@@ -92,6 +96,7 @@ PCRE2_SPTR
 PRIV(extuni)(uint32_t c, PCRE2_SPTR eptr, PCRE2_SPTR start_subject,
   PCRE2_SPTR end_subject, BOOL utf, int *xcount)
 {
+BOOL was_ep_ZWJ = FALSE;
 int lgb = UCD_GRAPHBREAK(c);
 
 while (eptr < end_subject)
@@ -102,6 +107,12 @@ while (eptr < end_subject)
   rgb = UCD_GRAPHBREAK(c);
   if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
 
+  /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was
+  preceded by Extended Pictographic. */
+
+  if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ)
+    break;
+
   /* Not breaking between Regional Indicators is allowed only if there
   are an even number of preceding RIs. */
 
@@ -129,12 +140,15 @@ while (eptr < end_subject)
     if ((ricount & 1) != 0) break;  /* Grapheme break required */
     }
 
-  /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this
-  allows any number of them before a following Extended_Pictographic. */
+  /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in
+  between; see next statement). */
+
+  was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ);
+
+  /* If Extend follows Extended_Pictographic, do not update lgb; this allows
+  any number of them before a following ZWJ. */
 
-  if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||
-       lgb != ucp_gbExtended_Pictographic)
-    lgb = rgb;
+  if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic) lgb = rgb;
 
   eptr += len;
   if (xcount != NULL) *xcount += 1;
index f364832b6752b1a6a78b0b1cbd625e46a6fe6e75..cd784357a716bf95c9221f10f4704fbe0c8a6da0 100644 (file)
@@ -8,9 +8,11 @@ rather than a file name. This allows easy testing of short strings.
 
 Written by Philip Hazel, October 2016
 Updated February 2024 (Addison Crump added 16-bit/32-bit and JIT support)
+Further updates March/April/May 2024 by PH
 ***************************************************************************/
 
 #include <errno.h>
+#include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -21,6 +23,7 @@ Updated February 2024 (Addison Crump added 16-bit/32-bit and JIT support)
 #include <sys/resource.h>
 
 #define STACK_SIZE_MB 256
+#define JIT_SIZE_LIMIT (200 * 1024)
 
 #ifndef PCRE2_CODE_UNIT_WIDTH
 #define PCRE2_CODE_UNIT_WIDTH 8
@@ -28,15 +31,20 @@ Updated February 2024 (Addison Crump added 16-bit/32-bit and JIT support)
 
 #include "config.h"
 #include "pcre2.h"
+#include "pcre2_internal.h"
 
 #define MAX_MATCH_SIZE 1000
 
 #define DFA_WORKSPACE_COUNT 100
 
+/* When adding new compile or match options, remember to update the functions
+below that output them. */
+
 #define ALLOWED_COMPILE_OPTIONS \
   (PCRE2_ANCHORED|PCRE2_ALLOW_EMPTY_CLASS|PCRE2_ALT_BSUX|PCRE2_ALT_CIRCUMFLEX| \
    PCRE2_ALT_VERBNAMES|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_DOLLAR_ENDONLY| \
-   PCRE2_DOTALL|PCRE2_DUPNAMES|PCRE2_ENDANCHORED|PCRE2_EXTENDED|PCRE2_FIRSTLINE| \
+   PCRE2_DOTALL|PCRE2_DUPNAMES|PCRE2_ENDANCHORED|PCRE2_EXTENDED| \
+   PCRE2_EXTENDED_MORE|PCRE2_FIRSTLINE| \
    PCRE2_MATCH_UNSET_BACKREF|PCRE2_MULTILINE|PCRE2_NEVER_BACKSLASH_C| \
    PCRE2_NO_AUTO_CAPTURE| \
    PCRE2_NO_AUTO_POSSESS|PCRE2_NO_DOTSTAR_ANCHOR|PCRE2_NO_START_OPTIMIZE| \
@@ -48,62 +56,89 @@ Updated February 2024 (Addison Crump added 16-bit/32-bit and JIT support)
    PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_HARD| \
    PCRE2_PARTIAL_SOFT)
 
+#define BASE_MATCH_OPTIONS \
+  (PCRE2_NO_JIT|PCRE2_DISABLE_RECURSELOOP_CHECK)
+
+
 #if defined(SUPPORT_DIFF_FUZZ) || defined(STANDALONE)
 static void print_compile_options(FILE *stream, uint32_t compile_options)
 {
-fprintf(stream, "Compile options %.8x never_backslash_c", compile_options);
-fprintf(stream, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
-  ((compile_options & PCRE2_ALT_BSUX) != 0)? ",alt_bsux" : "",
-  ((compile_options & PCRE2_ALT_CIRCUMFLEX) != 0)? ",alt_circumflex" : "",
-  ((compile_options & PCRE2_ALT_VERBNAMES) != 0)? ",alt_verbnames" : "",
-  ((compile_options & PCRE2_ALLOW_EMPTY_CLASS) != 0)? ",allow_empty_class" : "",
-  ((compile_options & PCRE2_ANCHORED) != 0)? ",anchored" : "",
-  ((compile_options & PCRE2_AUTO_CALLOUT) != 0)? ",auto_callout" : "",
-  ((compile_options & PCRE2_CASELESS) != 0)? ",caseless" : "",
-  ((compile_options & PCRE2_DOLLAR_ENDONLY) != 0)? ",dollar_endonly" : "",
-  ((compile_options & PCRE2_DOTALL) != 0)? ",dotall" : "",
-  ((compile_options & PCRE2_DUPNAMES) != 0)? ",dupnames" : "",
-  ((compile_options & PCRE2_ENDANCHORED) != 0)? ",endanchored" : "",
-  ((compile_options & PCRE2_EXTENDED) != 0)? ",extended" : "",
-  ((compile_options & PCRE2_FIRSTLINE) != 0)? ",firstline" : "",
-  ((compile_options & PCRE2_MATCH_UNSET_BACKREF) != 0)? ",match_unset_backref" : "",
-  ((compile_options & PCRE2_MULTILINE) != 0)? ",multiline" : "",
-  ((compile_options & PCRE2_NEVER_UCP) != 0)? ",never_ucp" : "",
-  ((compile_options & PCRE2_NEVER_UTF) != 0)? ",never_utf" : "",
-  ((compile_options & PCRE2_NO_AUTO_CAPTURE) != 0)? ",no_auto_capture" : "",
-  ((compile_options & PCRE2_NO_AUTO_POSSESS) != 0)? ",no_auto_possess" : "",
-  ((compile_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)? ",no_dotstar_anchor" : "",
-  ((compile_options & PCRE2_NO_UTF_CHECK) != 0)? ",no_utf_check" : "",
-  ((compile_options & PCRE2_NO_START_OPTIMIZE) != 0)? ",no_start_optimize" : "",
-  ((compile_options & PCRE2_UCP) != 0)? ",ucp" : "",
-  ((compile_options & PCRE2_UNGREEDY) != 0)? ",ungreedy" : "",
-  ((compile_options & PCRE2_USE_OFFSET_LIMIT) != 0)? ",use_offset_limit" : "",
-  ((compile_options & PCRE2_UTF) != 0)? ",utf" : "");
+fprintf(stream, "Compile options %s%.8x =",
+  (compile_options == PCRE2_NEVER_BACKSLASH_C)? "(base) " : "",
+  compile_options);
+
+fprintf(stream, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
+  ((compile_options & PCRE2_ALT_BSUX) != 0)? " alt_bsux" : "",
+  ((compile_options & PCRE2_ALT_CIRCUMFLEX) != 0)? " alt_circumflex" : "",
+  ((compile_options & PCRE2_ALT_VERBNAMES) != 0)? " alt_verbnames" : "",
+  ((compile_options & PCRE2_ALLOW_EMPTY_CLASS) != 0)? " allow_empty_class" : "",
+  ((compile_options & PCRE2_ANCHORED) != 0)? " anchored" : "",
+  ((compile_options & PCRE2_AUTO_CALLOUT) != 0)? " auto_callout" : "",
+  ((compile_options & PCRE2_CASELESS) != 0)? " caseless" : "",
+  ((compile_options & PCRE2_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
+  ((compile_options & PCRE2_DOTALL) != 0)? " dotall" : "",
+  ((compile_options & PCRE2_DUPNAMES) != 0)? " dupnames" : "",
+  ((compile_options & PCRE2_ENDANCHORED) != 0)? " endanchored" : "",
+  ((compile_options & PCRE2_EXTENDED) != 0)? " extended" : "",
+  ((compile_options & PCRE2_EXTENDED_MORE) != 0)? " extended_more" : "",
+  ((compile_options & PCRE2_FIRSTLINE) != 0)? " firstline" : "",
+  ((compile_options & PCRE2_MATCH_UNSET_BACKREF) != 0)? " match_unset_backref" : "",
+  ((compile_options & PCRE2_MULTILINE) != 0)? " multiline" : "",
+  ((compile_options & PCRE2_NEVER_BACKSLASH_C) != 0)? " never_backslash_c" : "",
+  ((compile_options & PCRE2_NEVER_UCP) != 0)? " never_ucp" : "",
+  ((compile_options & PCRE2_NEVER_UTF) != 0)? " never_utf" : "",
+  ((compile_options & PCRE2_NO_AUTO_CAPTURE) != 0)? " no_auto_capture" : "",
+  ((compile_options & PCRE2_NO_AUTO_POSSESS) != 0)? " no_auto_possess" : "",
+  ((compile_options & PCRE2_NO_DOTSTAR_ANCHOR) != 0)? " no_dotstar_anchor" : "",
+  ((compile_options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "",
+  ((compile_options & PCRE2_NO_START_OPTIMIZE) != 0)? " no_start_optimize" : "",
+  ((compile_options & PCRE2_UCP) != 0)? " ucp" : "",
+  ((compile_options & PCRE2_UNGREEDY) != 0)? " ungreedy" : "",
+  ((compile_options & PCRE2_USE_OFFSET_LIMIT) != 0)? " use_offset_limit" : "",
+  ((compile_options & PCRE2_UTF) != 0)? " utf" : "");
 }
 
 static void print_match_options(FILE *stream, uint32_t match_options)
 {
-fprintf(stream, "Match options %.8x", match_options);
-fprintf(stream, "%s%s%s%s%s%s%s%s%s\n",
-  ((match_options & PCRE2_ANCHORED) != 0)? ",anchored" : "",
-  ((match_options & PCRE2_ENDANCHORED) != 0)? ",endanchored" : "",
-  ((match_options & PCRE2_NO_UTF_CHECK) != 0)? ",no_utf_check" : "",
-  ((match_options & PCRE2_NOTBOL) != 0)? ",notbol" : "",
-  ((match_options & PCRE2_NOTEMPTY) != 0)? ",notempty" : "",
-  ((match_options & PCRE2_NOTEMPTY_ATSTART) != 0)? ",notempty_atstart" : "",
-  ((match_options & PCRE2_NOTEOL) != 0)? ",noteol" : "",
-  ((match_options & PCRE2_PARTIAL_HARD) != 0)? ",partial_hard" : "",
-  ((match_options & PCRE2_PARTIAL_SOFT) != 0)? ",partial_soft" : "");
+fprintf(stream, "Match options %s%.8x =",
+  (match_options == BASE_MATCH_OPTIONS)? "(base) " : "", match_options);
+
+fprintf(stream, "%s%s%s%s%s%s%s%s%s%s%s\n",
+  ((match_options & PCRE2_ANCHORED) != 0)? " anchored" : "",
+  ((match_options & PCRE2_DISABLE_RECURSELOOP_CHECK) != 0)? " disable_recurseloop_check" : "",
+  ((match_options & PCRE2_ENDANCHORED) != 0)? " endanchored" : "",
+  ((match_options & PCRE2_NO_JIT) != 0)? " no_jit" : "",
+  ((match_options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "",
+  ((match_options & PCRE2_NOTBOL) != 0)? " notbol" : "",
+  ((match_options & PCRE2_NOTEMPTY) != 0)? " notempty" : "",
+  ((match_options & PCRE2_NOTEMPTY_ATSTART) != 0)? " notempty_atstart" : "",
+  ((match_options & PCRE2_NOTEOL) != 0)? " noteol" : "",
+  ((match_options & PCRE2_PARTIAL_HARD) != 0)? " partial_hard" : "",
+  ((match_options & PCRE2_PARTIAL_SOFT) != 0)? " partial_soft" : "");
+}
+
+
+/* This function can print an error message at all code unit widths. */
+
+static void print_error(FILE *f, int errorcode, const char *text, ...)
+{
+PCRE2_UCHAR buffer[256];
+PCRE2_UCHAR *p = buffer;
+va_list ap;
+va_start(ap, text);
+vfprintf(f, text, ap);
+va_end(ap);
+pcre2_get_error_message(errorcode, buffer, 256);
+while (*p != 0) fprintf(f, "%c", *p++);
+printf("\n");
 }
 #endif /* defined(SUPPORT_DIFF_FUZZ || defined(STANDALONE) */
 
+
 #ifdef SUPPORT_JIT
 #ifdef SUPPORT_DIFF_FUZZ
 static void dump_matches(FILE *stream, int count, pcre2_match_data *match_data)
 {
-#if PCRE2_CODE_UNIT_WIDTH == 8
-PCRE2_UCHAR error_buf[256];
-#endif
 int errorcode;
 
 for (int index = 0; index < count; index++)
@@ -111,7 +146,8 @@ for (int index = 0; index < count; index++)
   PCRE2_UCHAR *bufferptr = NULL;
   PCRE2_SIZE bufflen = 0;
 
-  errorcode = pcre2_substring_get_bynumber(match_data, index, &bufferptr, &bufflen);
+  errorcode = pcre2_substring_get_bynumber(match_data, index, &bufferptr,
+    &bufflen);
 
   if (errorcode >= 0)
     {
@@ -124,12 +160,7 @@ for (int index = 0; index < count; index++)
     }
   else
     {
-#if PCRE2_CODE_UNIT_WIDTH == 8
-    pcre2_get_error_message(errorcode, error_buf, 256);
-    fprintf(stream, "Match %d failed: %s\n", index, error_buf);
-#else
-    fprintf(stream, "Match %d failed: %d\n", index, errorcode);
-#endif
+    print_error(stream, errorcode, "Match %d failed: ", index);
     }
   }
 }
@@ -149,9 +180,6 @@ static void describe_failure(
   pcre2_match_data *match_data,
   pcre2_match_data *match_data_jit
 ) {
-#if PCRE2_CODE_UNIT_WIDTH == 8
-PCRE2_UCHAR buffer[256];
-#endif
 
 fprintf(stderr, "Encountered failure while performing %s; context:\n", task);
 
@@ -167,13 +195,9 @@ print_match_options(stderr, match_options);
 
 if (errorcode < 0)
   {
-#if PCRE2_CODE_UNIT_WIDTH == 8
-  pcre2_get_error_message(errorcode, buffer, 256);
-  fprintf(stderr, "Non-JIT'd operation emitted an error: %s (%d)\n", buffer, errorcode);
-#else
-  fprintf(stderr, "Non-JIT'd operation emitted an error: %d\n", errorcode);
-#endif
+  print_error(stderr, errorcode, "Non-JIT'd operation emitted an error: ");
   }
+
 if (matches >= 0)
   {
   fprintf(stderr, "Non-JIT'd operation did not emit an error.\n");
@@ -187,13 +211,10 @@ if (matches >= 0)
 
 if (errorcode_jit < 0)
   {
-#if PCRE2_CODE_UNIT_WIDTH == 8
-  pcre2_get_error_message(errorcode_jit, buffer, 256);
-  fprintf(stderr, "JIT'd operation emitted an error: %s (%d)\n", buffer, errorcode_jit);
-#else
-  fprintf(stderr, "JIT'd operation emitted an error: %d\n", errorcode);
-#endif
+  print_error(stderr, errorcode_jit, "JIT'd operation emitted error %d:",
+    errorcode_jit);
   }
+
 if (matches_jit >= 0)
   {
   fprintf(stderr, "JIT'd operation did not emit an error.\n");
@@ -207,7 +228,7 @@ if (matches_jit >= 0)
 
 abort();
 }
-#endif  /* SUPPORRT_DIFF_FUZZ */
+#endif  /* SUPPORT_DIFF_FUZZ */
 #endif  /* SUPPORT_JIT */
 
 /* This is the callout function. Its only purpose is to halt matching if there
@@ -226,7 +247,7 @@ return (*((uint32_t *)callout_data) > 100)? PCRE2_ERROR_CALLOUT : 0;
 
 int LLVMFuzzerInitialize(int *, char ***);
 
-int LLVMFuzzerTestOneInput(const unsigned char *, size_t);
+int LLVMFuzzerTestOneInput(unsigned char *, size_t);
 
 int LLVMFuzzerInitialize(int *argc, char ***argv)
 {
@@ -236,13 +257,13 @@ getrlimit(RLIMIT_STACK, &rlim);
 rlim.rlim_cur = STACK_SIZE_MB * 1024 * 1024;
 if (rlim.rlim_cur > rlim.rlim_max)
   {
-  fprintf(stderr, "hard stack size limit is too small (needed 8MiB)!\n");
+  fprintf(stderr, "Hard stack size limit is too small (needed 8MiB)!\n");
   _exit(1);
   }
 rc = setrlimit(RLIMIT_STACK, &rlim);
 if (rc != 0)
   {
-  fprintf(stderr, "failed to expand stack size\n");
+  fprintf(stderr, "Failed to expand stack size\n");
   _exit(1);
   }
 
@@ -253,8 +274,10 @@ return 0;
 
 /* Here's the driving function. */
 
-int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size)
+int LLVMFuzzerTestOneInput(unsigned char *data, size_t size)
 {
+PCRE2_UCHAR *wdata;
+PCRE2_UCHAR *newwdata = NULL;
 uint32_t compile_options;
 uint32_t match_options;
 uint64_t random_options;
@@ -262,34 +285,149 @@ pcre2_match_data *match_data = NULL;
 #ifdef SUPPORT_JIT
 pcre2_match_data *match_data_jit = NULL;
 #endif
+pcre2_compile_context *compile_context = NULL;
 pcre2_match_context *match_context = NULL;
 size_t match_size;
 int dfa_workspace[DFA_WORKSPACE_COUNT];
-int i;
 
 if (size < sizeof(random_options)) return -1;
 
-/* Limiting the length of the subject for matching stops fruitless searches
-in large trees taking too much time. */
-
 random_options = *(uint64_t *)(data);
 data += sizeof(random_options);
+wdata = (PCRE2_UCHAR *)data;
 size -= sizeof(random_options);
 size /= PCRE2_CODE_UNIT_WIDTH / 8;
 
+/* PCRE2 compiles quantified groups by replicating them. In certain cases of
+very large quantifiers this can lead to unacceptably long JIT compile times. To
+get around this, we scan the data string for large quantifiers that follow a
+closing parenthesis, and reduce the value of the quantifier to 10, assuming
+that this will make minimal difference to the detection of bugs.
+
+Do the same for quantifiers that follow a closing square bracket, because
+classes that contain a number of non-ascii characters can take a lot of time
+when matching.
+
+We have to make a copy of the input because oss-fuzz complains if we overwrite
+the original. Start the scan at the second character so there can be a
+lookbehind for a backslash, and end it before the end so that the next
+character can be checked for an opening brace. */
+
+if (size > 3)
+  {
+  newwdata = malloc(size * sizeof(PCRE2_UCHAR));
+  memcpy(newwdata, wdata, size * sizeof(PCRE2_UCHAR));
+  wdata = newwdata;
+
+  for (size_t i = 1; i < size - 2; i++)
+    {
+    size_t j;
+
+    if ((wdata[i] != ')' && wdata[i] != ']') || wdata[i-1] == '\\' ||
+         wdata[i+1] != '{')
+      continue;
+    i++;  /* Points to '{' */
+
+    /* Loop for two values a quantifier. Offset i points to brace or comma at the
+    start of the loop.*/
+
+    for (int ii = 0; ii < 2; ii++)
+      {
+      int q = 0;
+
+      if (i >= size - 1) goto END_QSCAN;  /* Can happen for , */
+
+      /* Ignore leading spaces */
+
+      while (wdata[i+1] == ' ' || wdata[i+1] == '\t')
+        {
+        i++;
+        if (i >= size - 1) goto END_QSCAN;
+        }
+
+      /* Scan for a number ending in brace or comma in the first iteration,
+      optionally preceded by space. */
+
+      for (j = i + 1; j < size && j < i + 7; j++)
+        {
+        if (wdata[j] == ' ' || wdata[j] == '\t')
+          {
+          j++;
+          while (j < size && (wdata[j] == ' ' || wdata[j] == '\t')) j++;
+          if (j >= size) goto OUTERLOOP;
+          if (wdata[j] != '}' && wdata[j] != ',') goto OUTERLOOP;
+          }
+        if (wdata[j] == '}' || (ii == 0 && wdata[j] == ',')) break;
+        if (wdata[j] < '0' || wdata[j] > '9')
+          {
+          j--;               /* Ensure this character is checked next. The */
+          goto OUTERLOOP;    /* string might be (e.g.) "){9){234}" */
+          }
+        q = q * 10 + wdata[j] - '0';
+        }
+
+      if (j >= size) goto END_QSCAN;  /* End of data */
+
+      /* Hit ',' or '}' or read 6 digits. Six digits is a number > 65536 which is
+      the maximum quantifier. Leave such numbers alone. */
+
+      if (j >= i + 7 || q > 65535) goto OUTERLOOP;
+
+      /* Limit the quantifier size to 10 */
+
+      if (q > 10)
+        {
+#ifdef STANDALONE
+        printf("Reduced quantifier value %d to 10.\n", q);
+#endif
+        for (size_t k = i + 1; k < j; k++) wdata[k] = '0';
+        wdata[j - 2] = '1';
+        }
+
+      /* Advance to end of number and break if reached closing brace (continue
+      after comma, which is only valid in the first time round this loop). */
+
+      i = j;
+      if (wdata[i] == '}') break;
+      }
+
+    /* Continue along the data string */
+
+    OUTERLOOP:
+    i = j;
+    continue;
+    }
+  }
+END_QSCAN:
+
+/* Limiting the length of the subject for matching stops fruitless searches
+in large trees taking too much time. */
+
 match_size = (size > MAX_MATCH_SIZE)? MAX_MATCH_SIZE : size;
 
+/* Create a compile context, and set a limit on the size of the compiled
+pattern. This stops the fuzzer using vast amounts of memory. */
+
+compile_context = pcre2_compile_context_create(NULL);
+if (compile_context == NULL)
+  {
+#ifdef STANDALONE
+  fprintf(stderr, "** Failed to create compile context block\n");
+#endif
+  abort();
+  }
+pcre2_set_max_pattern_compiled_length(compile_context, 10*1024*1024);
+
 /* Ensure that all undefined option bits are zero (waste of time trying them)
 and also that PCRE2_NO_UTF_CHECK is unset, as there is no guarantee that the
-input is UTF-8. Also unset PCRE2_NEVER_UTF and PCRE2_NEVER_UCP as there is no
-reason to disallow UTF and UCP. Force PCRE2_NEVER_BACKSLASH_C to be set because
-\C in random patterns is highly likely to cause a crash. */
+input is valid UTF. Also unset PCRE2_NEVER_UTF and PCRE2_NEVER_UCP as there is
+no reason to disallow UTF and UCP. Force PCRE2_NEVER_BACKSLASH_C to be set
+because \C in random patterns is highly likely to cause a crash. */
 
 compile_options = ((random_options >> 32) & ALLOWED_COMPILE_OPTIONS) |
   PCRE2_NEVER_BACKSLASH_C;
 match_options = (((uint32_t)random_options) & ALLOWED_MATCH_OPTIONS) |
-  PCRE2_NO_JIT |
-  PCRE2_DISABLE_RECURSELOOP_CHECK;
+  BASE_MATCH_OPTIONS;
 
 /* Discard partial matching if PCRE2_ENDANCHORED is set, because they are not
 allowed together and just give an immediate error return. */
@@ -300,13 +438,13 @@ if (((compile_options|match_options) & PCRE2_ENDANCHORED) != 0)
 /* Do the compile with and without the options, and after a successful compile,
 likewise do the match with and without the options. */
 
-for (i = 0; i < 2; i++)
+for (int i = 0; i < 2; i++)
   {
   uint32_t callout_count;
   int errorcode;
 #ifdef SUPPORT_JIT
   int errorcode_jit;
-#ifdef SUPPORT_JIT_FUZZ
+#ifdef SUPPORT_DIFF_FUZZ
   int matches = 0;
   int matches_jit = 0;
 #endif
@@ -315,11 +453,12 @@ for (i = 0; i < 2; i++)
   pcre2_code *code;
 
 #ifdef STANDALONE
+  printf("\n");
   print_compile_options(stdout, compile_options);
 #endif
 
-  code = pcre2_compile((PCRE2_SPTR)data, (PCRE2_SIZE)size, compile_options,
-    &errorcode, &erroroffset, NULL);
+  code = pcre2_compile((PCRE2_SPTR)wdata, (PCRE2_SIZE)size, compile_options,
+    &errorcode, &erroroffset, compile_context);
 
   /* Compilation succeeded */
 
@@ -328,9 +467,29 @@ for (i = 0; i < 2; i++)
     int j;
     uint32_t save_match_options = match_options;
 
+    /* Call JIT compile only if the compiled pattern is not too big. */
+
 #ifdef SUPPORT_JIT
-    int jit_ret = pcre2_jit_compile(code, PCRE2_JIT_COMPLETE);
+    int jit_ret = -1;
+    if (((struct pcre2_real_code *)code)->blocksize <= JIT_SIZE_LIMIT)
+      {
+#ifdef STANDALONE
+      printf("Compile succeeded; calling JIT compile\n");
+#endif
+      jit_ret = pcre2_jit_compile(code, PCRE2_JIT_COMPLETE);
+#ifdef STANDALONE
+      if (jit_ret < 0) printf("JIT compile error %d\n", jit_ret);
 #endif
+      }
+    else
+      {
+#ifdef STANDALONE
+      printf("Not calling JIT: compiled pattern is too long "
+        "(%ld bytes; limit=%d)\n",
+        ((struct pcre2_real_code *)code)->blocksize, JIT_SIZE_LIMIT);
+#endif
+      }
+#endif  /* SUPPORT_JIT */
 
     /* Create match data and context blocks only when we first need them. Set
     low match and depth limits to avoid wasting too much searching large
@@ -370,6 +529,9 @@ for (i = 0; i < 2; i++)
 
     /* Match twice, with and without options. */
 
+#ifdef STANDALONE
+    printf("\n");
+#endif
     for (j = 0; j < 2; j++)
       {
 #ifdef STANDALONE
@@ -377,33 +539,40 @@ for (i = 0; i < 2; i++)
 #endif
 
       callout_count = 0;
-      errorcode = pcre2_match(code, (PCRE2_SPTR)data, (PCRE2_SIZE)match_size, 0,
+      errorcode = pcre2_match(code, (PCRE2_SPTR)wdata, (PCRE2_SIZE)match_size, 0,
         match_options, match_data, match_context);
 
 #ifdef STANDALONE
       if (errorcode >= 0) printf("Match returned %d\n", errorcode); else
-        {
-#if PCRE2_CODE_UNIT_WIDTH == 8
-        unsigned char buffer[256];
-        pcre2_get_error_message(errorcode, buffer, 256);
-        printf("Match failed: error %d: %s\n", errorcode, buffer);
-#else
-        printf("Match failed: error %d\n", errorcode);
-#endif
-        }
+        print_error(stdout, errorcode, "Match failed: error %d: ", errorcode);
 #endif
 
+/* If JIT is enabled, do a JIT match and, if appropriately compiled, compare
+with the interpreter. */
+
 #ifdef SUPPORT_JIT
       if (jit_ret >= 0)
         {
+#ifdef STANDALONE
+        printf("Matching with JIT\n");
+#endif
         callout_count = 0;
-        errorcode_jit = pcre2_match(code, (PCRE2_SPTR)data, (PCRE2_SIZE)match_size, 0,
+        errorcode_jit = pcre2_match(code, (PCRE2_SPTR)wdata, (PCRE2_SIZE)match_size, 0,
           match_options & ~PCRE2_NO_JIT, match_data_jit, match_context);
 
-#ifndef SUPPORT_DIFF_FUZZ
-        (void)errorcode_jit;  /* Avoid compiler warning */
+#ifdef STANDALONE
+        if (errorcode_jit >= 0)
+          printf("Match returned %d\n", errorcode_jit);
+        else
+          print_error(stdout, errorcode_jit, "JIT match failed: error %d: ",
+            errorcode_jit);
 #else
+        (void)errorcode_jit;   /* Avoid compiler warning */
+#endif  /* STANDALONE */
+
+/* With differential matching enabled, compare with interpreter. */
 
+#ifdef SUPPORT_DIFF_FUZZ
         matches = errorcode;
         matches_jit = errorcode_jit;
 
@@ -413,7 +582,7 @@ for (i = 0; i < 2; i++)
                 errorcode != PCRE2_ERROR_MATCHLIMIT && errorcode != PCRE2_ERROR_CALLOUT &&
                 errorcode_jit != PCRE2_ERROR_MATCHLIMIT && errorcode_jit != PCRE2_ERROR_JIT_STACKLIMIT && errorcode_jit != PCRE2_ERROR_CALLOUT)
             {
-            describe_failure("match errorcode comparison", data, size, compile_options, match_options, errorcode, errorcode_jit, matches, matches_jit, match_data, match_data_jit);
+            describe_failure("match errorcode comparison", wdata, size, compile_options, match_options, errorcode, errorcode_jit, matches, matches_jit, match_data, match_data_jit);
             }
           }
         else
@@ -431,7 +600,7 @@ for (i = 0; i < 2; i++)
 
             if (errorcode != errorcode_jit)
               {
-              describe_failure("match entry errorcode comparison", data, size,
+              describe_failure("match entry errorcode comparison", wdata, size,
                 compile_options, match_options, errorcode, errorcode_jit,
                 matches, matches_jit, match_data, match_data_jit);
               }
@@ -440,14 +609,14 @@ for (i = 0; i < 2; i++)
               {
               if (bufflen != bufflen_jit)
                 {
-                describe_failure("match entry length comparison", data, size,
+                describe_failure("match entry length comparison", wdata, size,
                   compile_options, match_options, errorcode, errorcode_jit,
                   matches, matches_jit, match_data, match_data_jit);
                 }
 
               if (memcmp(bufferptr, bufferptr_jit, bufflen) != 0)
                 {
-                describe_failure("match entry content comparison", data, size,
+                describe_failure("match entry content comparison", wdata, size,
                   compile_options, match_options, errorcode, errorcode_jit,
                   matches, matches_jit, match_data, match_data_jit);
                 }
@@ -457,52 +626,53 @@ for (i = 0; i < 2; i++)
               pcre2_substring_free(bufferptr_jit);
             }
           }
-#endif  /* SUPPORT_JIT_FUZZ */
+#endif  /* SUPPORT_DIFF_FUZZ */
         }
 #endif  /* SUPPORT_JIT */
 
-      match_options = PCRE2_NO_JIT;  /* For second time */
+      if (match_options == BASE_MATCH_OPTIONS) break;  /* Don't do same twice */
+      match_options = BASE_MATCH_OPTIONS;              /* For second time */
       }
 
-    /* Match with DFA twice, with and without options. */
+    /* Match with DFA twice, with and without options, but remove options that
+    are not allowed with DFA. */
 
-    match_options = save_match_options & ~PCRE2_NO_JIT;  /* Not valid for DFA */
+    match_options = save_match_options & ~BASE_MATCH_OPTIONS;
+
+#ifdef STANDALONE
+    printf("\n");
+#endif
 
     for (j = 0; j < 2; j++)
       {
 #ifdef STANDALONE
-      printf("DFA match options %.8x", match_options);
+      printf("DFA match options %.8x =", match_options);
       printf("%s%s%s%s%s%s%s%s%s\n",
-        ((match_options & PCRE2_ANCHORED) != 0)? ",anchored" : "",
-        ((match_options & PCRE2_ENDANCHORED) != 0)? ",endanchored" : "",
-        ((match_options & PCRE2_NO_UTF_CHECK) != 0)? ",no_utf_check" : "",
-        ((match_options & PCRE2_NOTBOL) != 0)? ",notbol" : "",
-        ((match_options & PCRE2_NOTEMPTY) != 0)? ",notempty" : "",
-        ((match_options & PCRE2_NOTEMPTY_ATSTART) != 0)? ",notempty_atstart" : "",
-        ((match_options & PCRE2_NOTEOL) != 0)? ",noteol" : "",
-        ((match_options & PCRE2_PARTIAL_HARD) != 0)? ",partial_hard" : "",
-        ((match_options & PCRE2_PARTIAL_SOFT) != 0)? ",partial_soft" : "");
+        ((match_options & PCRE2_ANCHORED) != 0)? " anchored" : "",
+        ((match_options & PCRE2_ENDANCHORED) != 0)? " endanchored" : "",
+        ((match_options & PCRE2_NO_UTF_CHECK) != 0)? " no_utf_check" : "",
+        ((match_options & PCRE2_NOTBOL) != 0)? " notbol" : "",
+        ((match_options & PCRE2_NOTEMPTY) != 0)? " notempty" : "",
+        ((match_options & PCRE2_NOTEMPTY_ATSTART) != 0)? " notempty_atstart" : "",
+        ((match_options & PCRE2_NOTEOL) != 0)? " noteol" : "",
+        ((match_options & PCRE2_PARTIAL_HARD) != 0)? " partial_hard" : "",
+        ((match_options & PCRE2_PARTIAL_SOFT) != 0)? " partial_soft" : "");
 #endif
 
       callout_count = 0;
-      errorcode = pcre2_dfa_match(code, (PCRE2_SPTR)data,
-        (PCRE2_SIZE)match_size, 0, match_options, match_data, match_context,
-        dfa_workspace, DFA_WORKSPACE_COUNT);
+      errorcode = pcre2_dfa_match(code, (PCRE2_SPTR)wdata,
+        (PCRE2_SIZE)match_size, 0, match_options, match_data,
+        match_context, dfa_workspace, DFA_WORKSPACE_COUNT);
 
 #ifdef STANDALONE
-      if (errorcode >= 0) printf("Match returned %d\n", errorcode); else
-        {
-#if PCRE2_CODE_UNIT_WIDTH == 8
-        unsigned char buffer[256];
-        pcre2_get_error_message(errorcode, buffer, 256);
-        printf("Match failed: error %d: %s\n", errorcode, buffer);
-#else
-        printf("Match failed: error %d\n", errorcode);
-#endif
-        }
+      if (errorcode >= 0)
+        printf("Match returned %d\n", errorcode);
+      else
+        print_error(stdout, errorcode, "DFA match failed: error %d: ", errorcode);
 #endif
 
-      match_options = 0;  /* For second time */
+      if (match_options == 0) break;  /* No point doing same twice */
+      match_options = 0;              /* For second time */
       }
 
     match_options = save_match_options;  /* Reset for the second compile */
@@ -514,28 +684,26 @@ for (i = 0; i < 2; i++)
   else
     {
 #ifdef STANDALONE
-#if PCRE2_CODE_UNIT_WIDTH == 8
-    unsigned char buffer[256];
-    pcre2_get_error_message(errorcode, buffer, 256);
-    printf("Error %d at offset %lu: %s\n", errorcode, erroroffset, buffer);
-#else
-    printf("Error %d at offset %lu\n", errorcode, erroroffset);
-#endif
-
+    print_error(stdout, errorcode, "Error %d at offset %lu: ", errorcode,
+      erroroffset);
 #else
     if (errorcode == PCRE2_ERROR_INTERNAL) abort();
 #endif
     }
 
-  compile_options = PCRE2_NEVER_BACKSLASH_C;  /* For second time */
+  if (compile_options == PCRE2_NEVER_BACKSLASH_C) break;  /* Avoid same twice */
+  compile_options = PCRE2_NEVER_BACKSLASH_C;              /* For second time */
   }
 
+/* Tidy up before exiting */
+
 if (match_data != NULL) pcre2_match_data_free(match_data);
 #ifdef SUPPORT_JIT
 if (match_data_jit != NULL) pcre2_match_data_free(match_data_jit);
+free(newwdata);
 #endif
 if (match_context != NULL) pcre2_match_context_free(match_context);
-
+if (compile_context != NULL) pcre2_compile_context_free(compile_context);
 return 0;
 }
 
@@ -545,8 +713,6 @@ return 0;
 #ifdef STANDALONE
 int main(int argc, char **argv)
 {
-int i;
-
 LLVMFuzzerInitialize(&argc, &argv);
 
 if (argc < 2)
@@ -555,7 +721,7 @@ if (argc < 2)
   return 0;
   }
 
-for (i = 1; i < argc; i++)
+for (int i = 1; i < argc; i++)
   {
   size_t filelen;
   size_t readsize;
index 5fcddce5fe1fae2afe0f1b450e298f9ce257acac..9bd9e694a496e08c2aa952941b1c6244287de950 100644 (file)
@@ -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-2023 University of Cambridge
+          New API code Copyright (c) 2016-2024 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -568,6 +568,7 @@ typedef struct pcre2_real_compile_context {
   void *stack_guard_data;
   const uint8_t *tables;
   PCRE2_SIZE max_pattern_length;
+  PCRE2_SIZE max_pattern_compiled_length;
   uint16_t bsr_convention;
   uint16_t newline_convention;
   uint32_t parens_nest_limit;
index 050063ec6d1fd15af7f27f01e4e381cd340360a9..92f4fb858b108bd7a41f33b4d04df95355b2f9af 100644 (file)
@@ -8,7 +8,7 @@ and semantics are as close as possible to those of the Perl 5 language.
                        Written by Philip Hazel
                     This module by Zoltan Herczeg
      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-2024 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -288,7 +288,7 @@ typedef struct bracket_backtrack {
     /* For OP_ONCE. Less than 0 if not needed. */
     int framesize;
     /* For brackets with >3 alternatives. */
-    struct sljit_put_label *matching_put_label;
+    struct sljit_jump *matching_mov_addr;
   } u;
   /* Points to our private memory word on the stack. */
   int private_data_ptr;
@@ -5891,7 +5891,7 @@ while (TRUE)
               chr++;
               }
             while (byte != 0);
-            chr = (chr + 7) & ~7;
+            chr = (chr + 7) & (sljit_u32)(~7);
             }
           }
         while (chars->count != 255 && bytes < bytes_end);
@@ -5951,7 +5951,10 @@ while (TRUE)
       chr = *cc;
 #ifdef SUPPORT_UNICODE
       if (common->ucp && chr > 127)
-        othercase[0] = UCD_OTHERCASE(chr);
+        {
+        chr = UCD_OTHERCASE(chr);
+        othercase[0] = (chr == (PCRE2_UCHAR)chr) ? chr : *cc;
+        }
       else
 #endif
         othercase[0] = TABLE_GET(chr, common->fcc, chr);
@@ -6183,25 +6186,34 @@ if (max < 1)
 /* Convert last_count to priority. */
 for (i = 0; i < max; i++)
   {
-  SLJIT_ASSERT(chars[i].count > 0 && chars[i].last_count <= chars[i].count);
+  SLJIT_ASSERT(chars[i].last_count <= chars[i].count);
 
-  if (chars[i].count == 1)
+  switch (chars[i].count)
     {
+    case 0:
+    chars[i].count = 255;
+    chars[i].last_count = 0;
+    break;
+
+    case 1:
     chars[i].last_count = (chars[i].last_count == 1) ? 7 : 5;
     /* Simplifies algorithms later. */
     chars[i].chars[1] = chars[i].chars[0];
-    }
-  else if (chars[i].count == 2)
-    {
+    break;
+
+    case 2:
     SLJIT_ASSERT(chars[i].chars[0] != chars[i].chars[1]);
 
     if (is_powerof2(chars[i].chars[0] ^ chars[i].chars[1]))
       chars[i].last_count = (chars[i].last_count == 2) ? 6 : 4;
     else
       chars[i].last_count = (chars[i].last_count == 2) ? 3 : 2;
-    }
-  else
+    break;
+
+    default:
     chars[i].last_count = (chars[i].count == 255) ? 0 : 1;
+    break;
+    }
   }
 
 #ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD
@@ -6941,7 +6953,7 @@ int i, byte, length = 0;
 
 bit = bits[0] & 0x1;
 /* All bits will be zero or one (since bit is zero or one). */
-all = -bit;
+all = (sljit_u8)-bit;
 
 for (i = 0; i < 256; )
   {
@@ -6958,7 +6970,7 @@ for (i = 0; i < 256; )
       ranges[length] = i;
       length++;
       bit = cbit;
-      all = -cbit;
+      all = (sljit_u8)-cbit; /* sign extend bit into byte */
       }
     i++;
     }
@@ -7102,7 +7114,7 @@ for (i = 0; i < 32; i++)
   byte = bits[i];
 
   if (nclass)
-    byte = ~byte;
+    byte = (sljit_u8)~byte;
 
   j = 0;
   while (byte != 0)
@@ -8003,7 +8015,7 @@ if (unicode_status & XCLASS_NEEDS_UCD)
           if (cc[-1] == XCL_NOTPROP)
             invertcmp ^= 0x1;
 
-          OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_boolprop_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)1 << (cc[1] & 0x1f));
+          OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_boolprop_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f)));
           add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp));
           }
         cc += 2;
@@ -8114,7 +8126,7 @@ if (unicode_status & XCLASS_NEEDS_UCD)
             invertcmp ^= 0x1;
             }
 
-          OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_script_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)1 << (cc[1] & 0x1f));
+          OP2U(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_MEM1(TMP1), (sljit_sw)(PRIV(ucd_script_sets) + (cc[1] >> 5)), SLJIT_IMM, (sljit_sw)(1u << (cc[1] & 0x1f)));
           add_jump(compiler, compares > 0 ? list : backtracks, JUMP(SLJIT_NOT_ZERO ^ invertcmp));
 
           if (jump != NULL)
@@ -8685,6 +8697,10 @@ return cc;
 
 #if PCRE2_CODE_UNIT_WIDTH != 32
 
+/* The code in this function copies the logic of the interpreter function that
+is defined in the pcre2_extuni.c source. If that code is updated, this
+function, and those below it, must be kept in step (note by PH, June 2024). */
+
 static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc)
 {
 PCRE2_SPTR start_subject = args->begin;
@@ -8692,6 +8708,7 @@ PCRE2_SPTR end_subject = args->end;
 int lgb, rgb, ricount;
 PCRE2_SPTR prevcc, endcc, bptr;
 BOOL first = TRUE;
+BOOL was_ep_ZWJ = FALSE;
 uint32_t c;
 
 prevcc = cc;
@@ -8712,6 +8729,12 @@ do
   if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)
     break;
 
+  /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was
+  preceded by Extended Pictographic. */
+
+  if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ)
+    break;
+
   /* Not breaking between Regional Indicators is allowed only if there
   are an even number of preceding RIs. */
 
@@ -8736,11 +8759,15 @@ do
     if ((ricount & 1) != 0) break;  /* Grapheme break required */
     }
 
-  /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this
-  allows any number of them before a following Extended_Pictographic. */
+  /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in
+  between; see next statement). */
+
+  was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ);
 
-  if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||
-       lgb != ucp_gbExtended_Pictographic)
+  /* If Extend follows Extended_Pictographic, do not update lgb; this allows
+  any number of them before a following ZWJ. */
+
+  if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic)
     lgb = rgb;
 
   prevcc = endcc;
@@ -8753,6 +8780,10 @@ return endcc;
 
 #endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
 
+/* The code in this function copies the logic of the interpreter function that
+is defined in the pcre2_extuni.c source. If that code is updated, this
+function, and the one below it, must be kept in step (note by PH, June 2024). */
+
 static PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SPTR cc)
 {
 PCRE2_SPTR start_subject = args->begin;
@@ -8760,6 +8791,7 @@ PCRE2_SPTR end_subject = args->end;
 int lgb, rgb, ricount;
 PCRE2_SPTR prevcc, endcc, bptr;
 BOOL first = TRUE;
+BOOL was_ep_ZWJ = FALSE;
 uint32_t c;
 
 prevcc = cc;
@@ -8780,6 +8812,12 @@ do
   if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)
     break;
 
+  /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was
+  preceded by Extended Pictographic. */
+
+  if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ)
+    break;
+
   /* Not breaking between Regional Indicators is allowed only if there
   are an even number of preceding RIs. */
 
@@ -8803,11 +8841,15 @@ do
       break;  /* Grapheme break required */
     }
 
-  /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this
-  allows any number of them before a following Extended_Pictographic. */
+  /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in
+  between; see next statement). */
+
+  was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ);
 
-  if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||
-       lgb != ucp_gbExtended_Pictographic)
+  /* If Extend follows Extended_Pictographic, do not update lgb; this allows
+  any number of them before a following ZWJ. */
+
+  if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic)
     lgb = rgb;
 
   prevcc = endcc;
@@ -8818,6 +8860,10 @@ while (cc < end_subject);
 return endcc;
 }
 
+/* The code in this function copies the logic of the interpreter function that
+is defined in the pcre2_extuni.c source. If that code is updated, this
+function must be kept in step (note by PH, June 2024). */
+
 static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc)
 {
 PCRE2_SPTR start_subject = args->begin;
@@ -8825,6 +8871,7 @@ PCRE2_SPTR end_subject = args->end;
 int lgb, rgb, ricount;
 PCRE2_SPTR bptr;
 uint32_t c;
+BOOL was_ep_ZWJ = FALSE;
 
 /* Patch by PH */
 /* GETCHARINC(c, cc); */
@@ -8848,6 +8895,12 @@ while (cc < end_subject)
   if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0)
     break;
 
+  /* ZWJ followed by Extended Pictographic is allowed only if the ZWJ was
+  preceded by Extended Pictographic. */
+
+  if (lgb == ucp_gbZWJ && rgb == ucp_gbExtended_Pictographic && !was_ep_ZWJ)
+    break;
+
   /* Not breaking between Regional Indicators is allowed only if there
   are an even number of preceding RIs. */
 
@@ -8875,11 +8928,15 @@ while (cc < end_subject)
       break;  /* Grapheme break required */
     }
 
-  /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this
-  allows any number of them before a following Extended_Pictographic. */
+  /* Set a flag when ZWJ follows Extended Pictographic (with optional Extend in
+  between; see next statement). */
+
+  was_ep_ZWJ = (lgb == ucp_gbExtended_Pictographic && rgb == ucp_gbZWJ);
 
-  if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) ||
-       lgb != ucp_gbExtended_Pictographic)
+  /* If Extend follows Extended_Pictographic, do not update lgb; this allows
+  any number of them before a following ZWJ. */
+
+  if (rgb != ucp_gbExtend || lgb != ucp_gbExtended_Pictographic)
     lgb = rgb;
 
   cc++;
@@ -9836,7 +9893,7 @@ BACKTRACK_AS(recurse_backtrack)->matchingpath = LABEL();
 return cc + 1 + LINK_SIZE;
 }
 
-static sljit_s32 SLJIT_FUNC SLJIT_FUNC_ATTRIBUTE do_callout_jit(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector)
+static sljit_s32 SLJIT_FUNC do_callout_jit(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector)
 {
 PCRE2_SPTR begin;
 PCRE2_SIZE *ovector;
@@ -11227,7 +11284,7 @@ if (has_alternatives)
     if (i <= 3)
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
     else
-      BACKTRACK_AS(bracket_backtrack)->u.matching_put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
+      BACKTRACK_AS(bracket_backtrack)->u.matching_mov_addr = sljit_emit_mov_addr(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
     }
   if (ket != OP_KETRMAX)
     BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
@@ -11314,17 +11371,22 @@ if (bra == OP_BRAMINZERO)
   /* Continue to the normal backtrack. */
   }
 
-if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
+if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO || (has_alternatives && repeat_type != OP_EXACT))
   count_match(common);
 
 cc += 1 + LINK_SIZE;
 
 if (opcode == OP_ONCE)
   {
+  int data;
+  int framesize = BACKTRACK_AS(bracket_backtrack)->u.framesize;
+
+  SLJIT_ASSERT(SHRT_MIN <= framesize && framesize < SHRT_MAX/2);
   /* We temporarily encode the needs_control_head in the lowest bit.
-     Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns
-     the same value for small signed numbers (including negative numbers). */
-  BACKTRACK_AS(bracket_backtrack)->u.framesize = (int)((unsigned)BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
+     The real value should be short enough for this operation to work
+     without triggering Undefined Behaviour. */
+  data = (int)((short)((unsigned short)framesize << 1) | (needs_control_head ? 1 : 0));
+  BACKTRACK_AS(bracket_backtrack)->u.framesize = data;
   }
 return cc + repeat_length;
 }
@@ -13005,7 +13067,7 @@ struct sljit_jump *once = NULL;
 struct sljit_jump *cond = NULL;
 struct sljit_label *rmin_label = NULL;
 struct sljit_label *exact_label = NULL;
-struct sljit_put_label *put_label = NULL;
+struct sljit_jump *mov_addr = NULL;
 
 if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
   {
@@ -13166,8 +13228,8 @@ else if (has_alternatives)
     {
     sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0);
 
-    SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->u.matching_put_label);
-    sljit_set_put_label(CURRENT_AS(bracket_backtrack)->u.matching_put_label, LABEL());
+    SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->u.matching_mov_addr);
+    sljit_set_label(CURRENT_AS(bracket_backtrack)->u.matching_mov_addr, LABEL());
     sljit_emit_op0(compiler, SLJIT_ENDBR);
     }
   else
@@ -13320,7 +13382,7 @@ if (has_alternatives)
       if (alt_max <= 3)
         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);
       else
-        put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
+        mov_addr = sljit_emit_mov_addr(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
       }
 
     if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
@@ -13346,7 +13408,7 @@ if (has_alternatives)
         }
       else
         {
-        sljit_set_put_label(put_label, LABEL());
+        sljit_set_label(mov_addr, LABEL());
         sljit_emit_op0(compiler, SLJIT_ENDBR);
         }
       }
@@ -13878,7 +13940,7 @@ jump_list *match = NULL;
 struct sljit_jump *next_alt = NULL;
 struct sljit_jump *accept_exit = NULL;
 struct sljit_label *quit;
-struct sljit_put_label *put_label = NULL;
+struct sljit_jump *mov_addr = NULL;
 
 /* Recurse captures then. */
 common->then_trap = NULL;
@@ -13941,7 +14003,7 @@ while (1)
   if (alt_max > 1 || (recurse_flags & recurse_flag_accept_found))
     {
     if (alt_max > 3)
-      put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(1));
+      mov_addr = sljit_emit_mov_addr(compiler, SLJIT_MEM1(STACK_TOP), STACK(1));
     else
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count);
     }
@@ -13974,7 +14036,7 @@ while (1)
       if (alt_max > 3)
         {
         sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0);
-        sljit_set_put_label(put_label, LABEL());
+        sljit_set_label(mov_addr, LABEL());
         sljit_emit_op0(compiler, SLJIT_ENDBR);
         }
       else
@@ -13985,7 +14047,7 @@ while (1)
     }
   else if (alt_max > 3)
     {
-    sljit_set_put_label(put_label, LABEL());
+    sljit_set_label(mov_addr, LABEL());
     sljit_emit_op0(compiler, SLJIT_ENDBR);
     }
   else
@@ -14303,7 +14365,7 @@ if (common->has_then)
   set_then_offsets(common, common->start, NULL);
   }
 
-compiler = sljit_create_compiler(allocator_data, NULL);
+compiler = sljit_create_compiler(allocator_data);
 if (!compiler)
   {
   SLJIT_FREE(common->optimized_cbracket, allocator_data);
@@ -14718,7 +14780,7 @@ if (common->getucdtype != NULL)
 SLJIT_FREE(common->optimized_cbracket, allocator_data);
 SLJIT_FREE(common->private_data_ptrs, allocator_data);
 
-executable_func = sljit_generate_code(compiler);
+executable_func = sljit_generate_code(compiler, 0, NULL);
 executable_size = sljit_get_generated_code_size(compiler);
 sljit_free_compiler(compiler);
 
index bb6a5589cb711a91b9ef233a066da19e942edb39..c3abc0b33bd4b2de29c4533581a2e37f5ed0526a 100644 (file)
@@ -141,8 +141,8 @@ if (startsize == 0 || maxsize == 0 || maxsize > SIZE_MAX - STACK_GROWTH_RATE)
   return NULL;
 if (startsize > maxsize)
   startsize = maxsize;
-startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
-maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
+startsize = (startsize + STACK_GROWTH_RATE - 1) & (size_t)(~(STACK_GROWTH_RATE - 1));
+maxsize = (maxsize + STACK_GROWTH_RATE - 1) & (size_t)(~(STACK_GROWTH_RATE - 1));
 
 jit_stack = PRIV(memctl_malloc)(sizeof(pcre2_real_jit_stack), (pcre2_memctl *)gcontext);
 if (jit_stack == NULL) return NULL;
index 783a85f50e2a856b65e808bc5f7cfa7dbc415a7a..502977fc320452127ac7b75c5760d077e437a279 100644 (file)
@@ -2176,7 +2176,7 @@ struct sljit_label *restart;
 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()));
+SLJIT_ASSERT(diff <= (unsigned)IN_UCHARS(max_fast_forward_char_pair_offset()));
 
 /* Initialize. */
 if (common->match_end_ptr != 0)
index 54ce32f79cbad891dc5ccb2fef59d2f0a5af806a..6d95bb9eb9b7ac1b446b81d63de2d0f7ab774841 100644 (file)
@@ -148,7 +148,7 @@ int main(void)
 #define F_PROPERTY     0x200000
 
 struct regression_test_case {
-       int compile_options;
+       uint32_t compile_options;
        int newline;
        int match_options;
        int start_offset;
@@ -276,6 +276,7 @@ static struct regression_test_case regression_test_cases[] = {
        { CM, A, 0, 0, "a1277|a1377|bX487", "bx487" },
        { CM, A, 0, 0, "a1277|a1377|bx487", "bX487" },
        { 0, A, 0, 0, "(a|)b*+a", "a" },
+       { 0, A, 0, 0 | F_NOMATCH, "(.|.|.|.|.)(|.|.|.|.)(.||.|.|.)(.|.||.|.)(.|.|.||.)(.|.|.|.|)(A|.|.|.|.)(.|A|.|.|.)(.|.|A|.|.)(.|.|.|A|.)(.|.|.|.|A)(B|.|.|.|.)(.|B|.|.|.)(.|.|B|.|.)(.|.|.|B|.)(.|.|.|.|B)xa", "1234567890123456ax" },
 
        /* Greedy and non-greedy ? operators. */
        { MU, A, 0, 0, "(?:a)?a", "laab" },
@@ -395,6 +396,7 @@ static struct regression_test_case regression_test_cases[] = {
        { MU, A, 0, 0, "[\\x{10001}-\\x{10fffe}]+", "#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf0\x90\x80\x81\xf4\x8f\xbf\xbe\xf4\x8f\xbf\xbf" },
        { MU, A, 0, 0, "[^\\x{10001}-\\x{10fffe}]+", "\xf0\x90\x80\x81#\xc3\xa9\xe2\xb1\xa5\xf0\x90\x80\x80\xf4\x8f\xbf\xbf\xf4\x8f\xbf\xbe" },
        { CMU, A, 0, 0 | F_NOMATCH | F_PROPERTY, "^[\\x{100}-\\x{17f}]", " " },
+       { M, A, 0, 0 | F_NOMATCH, "[^\\S\\W]{6}", "abcdefghijk" },
 
        /* Unicode properties. */
        { MUP, A, 0, 0, "[1-5\xc3\xa9\\w]", "\xc3\xa1_" },
@@ -1172,7 +1174,7 @@ static int regression_tests(void)
        int counter = 0;
        int jit_compile_mode;
        int utf = 0;
-       int disabled_options = 0;
+       uint32_t disabled_options = 0;
        int i;
 #ifdef SUPPORT_PCRE2_8
        pcre2_code_8 *re8;
@@ -1377,9 +1379,9 @@ static int regression_tests(void)
                        ovector8_1 = pcre2_get_ovector_pointer_8(mdata8_1);
                        ovector8_2 = pcre2_get_ovector_pointer_8(mdata8_2);
                        for (i = 0; i < OVECTOR_SIZE * 2; ++i)
-                               ovector8_1[i] = -2;
+                               ovector8_1[i] = (PCRE2_SIZE)(-2);
                        for (i = 0; i < OVECTOR_SIZE * 2; ++i)
-                               ovector8_2[i] = -2;
+                               ovector8_2[i] = (PCRE2_SIZE)(-2);
                        pcre2_set_match_limit_8(mcontext8, 10000000);
                }
                if (re8) {
@@ -1417,9 +1419,9 @@ static int regression_tests(void)
                        ovector16_1 = pcre2_get_ovector_pointer_16(mdata16_1);
                        ovector16_2 = pcre2_get_ovector_pointer_16(mdata16_2);
                        for (i = 0; i < OVECTOR_SIZE * 2; ++i)
-                               ovector16_1[i] = -2;
+                               ovector16_1[i] = (PCRE2_SIZE)(-2);
                        for (i = 0; i < OVECTOR_SIZE * 2; ++i)
-                               ovector16_2[i] = -2;
+                               ovector16_2[i] = (PCRE2_SIZE)(-2);
                        pcre2_set_match_limit_16(mcontext16, 10000000);
                }
                if (re16) {
@@ -1462,9 +1464,9 @@ static int regression_tests(void)
                        ovector32_1 = pcre2_get_ovector_pointer_32(mdata32_1);
                        ovector32_2 = pcre2_get_ovector_pointer_32(mdata32_2);
                        for (i = 0; i < OVECTOR_SIZE * 2; ++i)
-                               ovector32_1[i] = -2;
+                               ovector32_1[i] = (PCRE2_SIZE)(-2);
                        for (i = 0; i < OVECTOR_SIZE * 2; ++i)
-                               ovector32_2[i] = -2;
+                               ovector32_2[i] = (PCRE2_SIZE)(-2);
                        pcre2_set_match_limit_32(mcontext32, 10000000);
                }
                if (re32) {
@@ -1844,7 +1846,7 @@ static int check_invalid_utf_result(int pattern_index, const char *type, int res
 #define CPI (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_INVALID_UTF)
 
 struct invalid_utf8_regression_test_case {
-       int compile_options;
+       uint32_t compile_options;
        int jit_compile_options;
        int start_offset;
        int skip_left;
@@ -2135,7 +2137,7 @@ static int invalid_utf8_regression_tests(void)
 #define CPI (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_INVALID_UTF)
 
 struct invalid_utf16_regression_test_case {
-       int compile_options;
+       uint32_t compile_options;
        int jit_compile_options;
        int start_offset;
        int skip_left;
@@ -2343,7 +2345,7 @@ static int invalid_utf16_regression_tests(void)
 #define CPI (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_INVALID_UTF)
 
 struct invalid_utf32_regression_test_case {
-       int compile_options;
+       uint32_t compile_options;
        int jit_compile_options;
        int start_offset;
        int skip_left;
index b4a970313d72bb922121e4f2635e472da990d904..6c422c2e5ef9e92cd8adae2622997ea23e6177d6 100644 (file)
@@ -5862,7 +5862,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
 
       {
       ptrdiff_t diff = Feptr - mb->start_subject;
-      uint32_t available = (diff > 65535)? 65535 : ((diff > 0)? diff : 0);
+      uint32_t available = (diff > 65535)? 65535 : ((diff > 0)? (int)diff : 0);
       if (Lmin > available) RRETURN(MATCH_NOMATCH);
       if (Lmax > available) Lmax = available;
       Feptr -= Lmax;
index e00252f1ebc0eeae7672a8cceeb79e846b36ce6d..097a1acca871cfaf4701be76cb9f734723b854f4 100644 (file)
@@ -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-2024 University of Cambridge
 
 -----------------------------------------------------------------------------
 Redistribution and use in source and binary forms, with or without
@@ -171,9 +171,9 @@ are implementing).
 6. Do not break after Prepend characters.
 
 7. Do not break within emoji modifier sequences or emoji zwj sequences. That
-   is, do not break between characters with the Extended_Pictographic property.
-   Extend and ZWJ characters are allowed between the characters; this cannot be
-   represented in this table, the code has to deal with it.
+   is, do not break between characters with the Extended_Pictographic property
+   if a ZWJ intervenes. Extend characters are allowed between the characters;
+   this cannot be represented in this table, the code has to deal with it.
 
 8. Do not break within emoji flag sequences. That is, do not break between
    regional indicator (RI) symbols if there are an odd number of RI characters
@@ -203,8 +203,8 @@ const uint32_t PRIV(ucp_gbtable)[] = {
    ESZ|(1u<<ucp_gbT),                                   /* 10 LVT */
    (1u<<ucp_gbRegional_Indicator),                      /* 11 Regional Indicator */
    ESZ,                                                 /* 12 Other */
-   ESZ,                                                 /* 13 ZWJ */
-   ESZ|(1u<<ucp_gbExtended_Pictographic)                /* 14 Extended Pictographic */
+   ESZ|(1u<<ucp_gbExtended_Pictographic),               /* 13 ZWJ */
+   ESZ                                                  /* 14 Extended Pictographic */
 };
 
 #undef ESZ
index 8066d962d0ae88df2619ff021cef3076a0cb1209..3790345186706308e2f111f9a81e0c6d64a90844 100644 (file)
@@ -719,6 +719,7 @@ static modstruct modlist[] = {
   { "match_line",                  MOD_CTC,  MOD_OPT, PCRE2_EXTRA_MATCH_LINE,     CO(extra_options) },
   { "match_unset_backref",         MOD_PAT,  MOD_OPT, PCRE2_MATCH_UNSET_BACKREF,  PO(options) },
   { "match_word",                  MOD_CTC,  MOD_OPT, PCRE2_EXTRA_MATCH_WORD,     CO(extra_options) },
+  { "max_pattern_compiled_length", MOD_CTC,  MOD_SIZ, 0,                          CO(max_pattern_compiled_length) },
   { "max_pattern_length",          MOD_CTC,  MOD_SIZ, 0,                          CO(max_pattern_length) },
   { "max_varlookbehind",           MOD_CTC,  MOD_INT, 0,                          CO(max_varlookbehind) },
   { "memory",                      MOD_PD,   MOD_CTL, CTL_MEMORY,                 PD(control) },
@@ -1428,6 +1429,14 @@ are supported. */
   else \
     pcre2_set_match_limit_32(G(a,32),b)
 
+#define PCRE2_SET_MAX_PATTERN_COMPILED_LENGTH(a,b) \
+  if (test_mode == PCRE8_MODE) \
+    pcre2_set_max_pattern_compiled_length_8(G(a,8),b); \
+  else if (test_mode == PCRE16_MODE) \
+    pcre2_set_max_pattern_compiled_length_16(G(a,16),b); \
+  else \
+    pcre2_set_max_pattern_compiled_length_32(G(a,32),b)
+
 #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) \
   if (test_mode == PCRE8_MODE) \
     pcre2_set_max_pattern_length_8(G(a,8),b); \
@@ -1934,6 +1943,12 @@ the three different cases. */
   else \
     G(pcre2_set_match_limit_,BITTWO)(G(a,BITTWO),b)
 
+#define PCRE2_SET_MAX_PATTERN_COMPILED_LENGTH(a,b) \
+  if (test_mode == G(G(PCRE,BITONE),_MODE)) \
+    G(pcre2_set_max_pattern_compiled_length_,BITONE)(G(a,BITONE),b); \
+  else \
+    G(pcre2_set_max_pattern_compiled_length_,BITTWO)(G(a,BITTWO),b)
+
 #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) \
   if (test_mode == G(G(PCRE,BITONE),_MODE)) \
     G(pcre2_set_max_pattern_length_,BITONE)(G(a,BITONE),b); \
@@ -2166,6 +2181,7 @@ the three different cases. */
 #define PCRE2_SET_GLOB_SEPARATOR(r,a,b) r = pcre2_set_glob_separator_8(G(a,8),b)
 #define PCRE2_SET_HEAP_LIMIT(a,b) pcre2_set_heap_limit_8(G(a,8),b)
 #define PCRE2_SET_MATCH_LIMIT(a,b) pcre2_set_match_limit_8(G(a,8),b)
+#define PCRE2_SET_MAX_PATTERN_COMPILED_LENGTH(a,b) pcre2_set_max_pattern_compiled_length_8(G(a,8),b)
 #define PCRE2_SET_MAX_PATTERN_LENGTH(a,b) pcre2_set_max_pattern_length_8(G(a,8),b)
 #define PCRE2_SET_MAX_VARLOOKBEHIND(a,b) pcre2_set_max_varlookbehind_8(G(a,8),b)
 #define PCRE2_SET_OFFSET_LIMIT(a,b) pcre2_set_offset_limit_8(G(a,8),b)
@@ -4404,14 +4420,15 @@ if (test_mode == PCRE32_MODE) cblock_size = sizeof(pcre2_real_code_32);
 /* The uint32_t variables are cast before multiplying to stop code analyzers
 grumbling about potential overflow. */
 
-fprintf(outfile, "Memory allocation (code space): %" SIZ_FORM "\n", size -
+fprintf(outfile, "Memory allocation - compiled block : %" SIZ_FORM "\n", size);
+fprintf(outfile, "Memory allocation - code portion   : %" SIZ_FORM "\n", size -
   (PCRE2_SIZE)name_count * (PCRE2_SIZE)name_entry_size * (PCRE2_SIZE)code_unit_size -
   cblock_size);
 
 if (pat_patctl.jit != 0)
   {
   (void)pattern_info(PCRE2_INFO_JITSIZE, &size, FALSE);
-  fprintf(outfile, "Memory allocation (JIT code): %" SIZ_FORM "\n", size);
+  fprintf(outfile, "Memory allocation - JIT code       : %" SIZ_FORM "\n", size);
   }
 }
 
@@ -5644,6 +5661,8 @@ if ((pat_patctl.control & CTL_POSIX) != 0)
   if (local_newline_default != 0) prmsg(&msg, "#newline_default");
   if (FLD(pat_context, max_pattern_length) != PCRE2_UNSET)
     prmsg(&msg, "max_pattern_length");
+  if (FLD(pat_context, max_pattern_compiled_length) != PCRE2_UNSET)
+    prmsg(&msg, "max_pattern_compiled_length");
   if (FLD(pat_context, parens_nest_limit) != PARENS_NEST_DEFAULT)
     prmsg(&msg, "parens_nest_limit");
 
@@ -5991,6 +6010,33 @@ if (timeit > 0)
 PCRE2_COMPILE(compiled_code, use_pbuffer, patlen,
   pat_patctl.options|use_forbid_utf, &errorcode, &erroroffset, use_pat_context);
 
+/* If valgrind is supported, mark the pbuffer as accessible again. The 16-bit
+and 32-bit buffers can be marked completely undefined, but we must leave the
+pattern in the 8-bit buffer defined because it may be read from a callout
+during matching. */
+
+#ifdef SUPPORT_VALGRIND
+#ifdef SUPPORT_PCRE2_8
+if (test_mode == PCRE8_MODE)
+  {
+  VALGRIND_MAKE_MEM_UNDEFINED(pbuffer8 + valgrind_access_length,
+    pbuffer8_size - valgrind_access_length);
+  }
+#endif
+#ifdef SUPPORT_PCRE2_16
+if (test_mode == PCRE16_MODE)
+  {
+  VALGRIND_MAKE_MEM_UNDEFINED(pbuffer16, pbuffer16_size);
+  }
+#endif
+#ifdef SUPPORT_PCRE2_32
+if (test_mode == PCRE32_MODE)
+  {
+  VALGRIND_MAKE_MEM_UNDEFINED(pbuffer32, pbuffer32_size);
+  }
+#endif
+#endif
+
 /* Call the JIT compiler if requested. When timing, we must free and recompile
 the pattern each time because that is the only way to free the JIT compiled
 code. We know that compilation will always succeed. */
@@ -6012,44 +6058,29 @@ if (TEST(compiled_code, !=, NULL) && pat_patctl.jit != 0)
       start_time = clock();
       PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
       time_taken += clock() - start_time;
+      if (jitrc != 0)
+        {
+        fprintf(outfile, "JIT compilation was not successful");
+        if (!print_error_message(jitrc, " (", ")\n")) return PR_ABEND;
+        break;
+        }
       }
     total_jit_compile_time += time_taken;
-    fprintf(outfile, "JIT compile  %8.4f microseconds\n",
-      ((1000000 / CLOCKS_PER_SEC) * (double)time_taken) / timeit);
+    if (jitrc == 0)
+      fprintf(outfile, "JIT compile  %8.4f microseconds\n",
+        ((1000000 / CLOCKS_PER_SEC) * (double)time_taken) / timeit);
     }
   else
     {
     PCRE2_JIT_COMPILE(jitrc, compiled_code, pat_patctl.jit);
+    if (jitrc != 0 && (pat_patctl.control & CTL_JITVERIFY) != 0)
+      {
+      fprintf(outfile, "JIT compilation was not successful");
+      if (!print_error_message(jitrc, " (", ")\n")) return PR_ABEND;
+      }
     }
   }
 
-/* If valgrind is supported, mark the pbuffer as accessible again. The 16-bit
-and 32-bit buffers can be marked completely undefined, but we must leave the
-pattern in the 8-bit buffer defined because it may be read from a callout
-during matching. */
-
-#ifdef SUPPORT_VALGRIND
-#ifdef SUPPORT_PCRE2_8
-if (test_mode == PCRE8_MODE)
-  {
-  VALGRIND_MAKE_MEM_UNDEFINED(pbuffer8 + valgrind_access_length,
-    pbuffer8_size - valgrind_access_length);
-  }
-#endif
-#ifdef SUPPORT_PCRE2_16
-if (test_mode == PCRE16_MODE)
-  {
-  VALGRIND_MAKE_MEM_UNDEFINED(pbuffer16, pbuffer16_size);
-  }
-#endif
-#ifdef SUPPORT_PCRE2_32
-if (test_mode == PCRE32_MODE)
-  {
-  VALGRIND_MAKE_MEM_UNDEFINED(pbuffer32, pbuffer32_size);
-  }
-#endif
-#endif
-
 /* Compilation failed; go back for another re, skipping to blank line
 if non-interactive. */
 
@@ -9397,11 +9428,11 @@ max_oveccount = DEFAULT_OVECCOUNT;
 #define CONTEXTTESTS \
   (void)G(pcre2_set_compile_extra_options_,BITS)(G(pat_context,BITS), 0); \
   (void)G(pcre2_set_max_pattern_length_,BITS)(G(pat_context,BITS), 0); \
+  (void)G(pcre2_set_max_pattern_compiled_length_,BITS)(G(pat_context,BITS), 0); \
   (void)G(pcre2_set_max_varlookbehind_,BITS)(G(pat_context,BITS), 0); \
   (void)G(pcre2_set_offset_limit_,BITS)(G(dat_context,BITS), 0); \
   (void)G(pcre2_get_match_data_size_,BITS)(G(match_data,BITS))
 
-
 /* Call the appropriate functions for the current mode, and exercise some
 functions that are not otherwise called. */
 
index 95b9842fa97e6dd08550c0902a8cd107a176eebf..9bd2094f46b93a9627d4e5172f59acdf1015ec9e 100644 (file)
 #include <sys/utsname.h>
 #include <stdlib.h>
 
-#define SLJIT_MAP_JIT  (get_map_jit_flag())
 #define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
 
+#ifdef MAP_JIT
+#define SLJIT_MAP_JIT  (get_map_jit_flag())
 static SLJIT_INLINE int get_map_jit_flag(void)
 {
        size_t page_size;
@@ -70,6 +71,9 @@ static SLJIT_INLINE int get_map_jit_flag(void)
        }
        return map_jit_flag;
 }
+#else /* !defined(MAP_JIT) */
+#define SLJIT_MAP_JIT  (0)
+#endif
 
 #elif defined(SLJIT_CONFIG_ARM) && SLJIT_CONFIG_ARM
 
index 6cd391104c22f400f1d1753dfb0955bab214954c..4e1119bc40c99ba049548989e884d7ae90bbe157 100644 (file)
@@ -181,8 +181,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
                                header->executable_offset = free_block->header.executable_offset;
 #endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
                                AS_BLOCK_HEADER(header, size)->prev_size = size;
-                       }
-                       else {
+                       } else {
                                sljit_remove_free_block(free_block);
                                header = (struct block_header*)free_block;
                                size = chunk_size;
@@ -230,26 +229,25 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
 #endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
                sljit_insert_free_block(free_block, chunk_size);
                next_header = AS_BLOCK_HEADER(free_block, chunk_size);
-       }
-       else {
+       } 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 */
+       SLJIT_ALLOCATOR_UNLOCK();
        return MEM_START(header);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(voidptr)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void *ptr)
 {
        struct block_header *header;
-       struct free_blockfree_block;
+       struct free_block *free_block;
 
        SLJIT_ALLOCATOR_LOCK();
        header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
@@ -269,8 +267,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
                free_block->size += header->size;
                header = AS_BLOCK_HEADER(free_block, free_block->size);
                header->prev_size = free_block->size;
-       }
-       else {
+       } else {
                free_block = (struct free_block*)header;
                sljit_insert_free_block(free_block, header->size);
        }
@@ -308,7 +305,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
        free_block = free_blocks;
        while (free_block) {
                next_free_block = free_block->next;
-               if (!free_block->header.prev_size && 
+               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);
@@ -317,14 +314,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
                free_block = next_free_block;
        }
 
-       SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
+       SLJIT_ASSERT(total_size || (!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)
+SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code)
 {
-       return ((struct block_header *)(ptr))[-1].executable_offset;
+       return ((struct block_header*)SLJIT_CODE_TO_PTR(code))[-1].executable_offset;
 }
 #endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
index ce4e7b04ec42adb6990649e548db89c821fba2ae..de06dd8e0c0213db9dc21358b98356cdb9e78190 100644 (file)
@@ -49,8 +49,8 @@ extern "C" {
      sljit_s16, sljit_u16 : signed and unsigned 16 bit integer type
      sljit_s32, sljit_u32 : signed and unsigned 32 bit integer type
      sljit_sw, sljit_uw   : signed and unsigned machine word, enough to store a pointer
-     sljit_p              : unsgined pointer value (usually the same as sljit_uw, but
-                            some 64 bit ABIs may use 32 bit pointers)
+     sljit_sp, sljit_up   : signed and unsigned pointer value (usually the same as
+                            sljit_uw, but some 64 bit ABIs may use 32 bit pointers)
      sljit_f32            : 32 bit single precision floating point value
      sljit_f64            : 64 bit double precision floating point value
 
@@ -98,6 +98,10 @@ extern "C" {
      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_TMP_DEST_REG : a temporary register for results
+     SLJIT_TMP_MEM_REG : a temporary base register for accessing memory
+                         (can be the same as SLJIT_TMP_DEST_REG)
+     SLJIT_TMP_DEST_FREG : a temporary register for float results
      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
@@ -132,23 +136,23 @@ extern "C" {
 */
 
 #ifndef SLJIT_MALLOC
-#define SLJIT_MALLOC(size, allocator_data) malloc(size)
+#define SLJIT_MALLOC(size, allocator_data) (malloc(size))
 #endif
 
 #ifndef SLJIT_FREE
-#define SLJIT_FREE(ptr, allocator_data) free(ptr)
+#define SLJIT_FREE(ptr, allocator_data) (free(ptr))
 #endif
 
 #ifndef SLJIT_MEMCPY
-#define SLJIT_MEMCPY(dest, src, len) memcpy(dest, src, len)
+#define SLJIT_MEMCPY(dest, src, len) (memcpy(dest, src, len))
 #endif
 
 #ifndef SLJIT_MEMMOVE
-#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len)
+#define SLJIT_MEMMOVE(dest, src, len) (memmove(dest, src, len))
 #endif
 
 #ifndef SLJIT_ZEROMEM
-#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len)
+#define SLJIT_ZEROMEM(dest, len) (memset(dest, 0, len))
 #endif
 
 /***************************/
@@ -198,7 +202,7 @@ extern "C" {
 /* Type of public API functions. */
 /*********************************/
 
-#ifndef SLJIT_API_FUNC_ATTRIBUTE 
+#ifndef SLJIT_API_FUNC_ATTRIBUTE
 #if (defined SLJIT_CONFIG_STATIC && SLJIT_CONFIG_STATIC)
 /* Static ABI functions. For all-in-one programs. */
 
@@ -358,7 +362,8 @@ typedef long int sljit_sw;
 #endif /* _WIN32 */
 #endif
 
-typedef sljit_uw sljit_p;
+typedef sljit_sw sljit_sp;
+typedef sljit_uw sljit_up;
 
 /* Floating point types. */
 typedef float sljit_f32;
@@ -399,6 +404,10 @@ typedef double sljit_f64;
 #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_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
+#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
 #else
 #error "Result for float to integer conversion is not defined"
 #endif
@@ -522,19 +531,6 @@ 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)
@@ -570,9 +566,9 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
 #endif /* SLJIT_FREE_EXEC */
 
 #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)
-#endif
+SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
+#define SLJIT_EXEC_OFFSET(code) sljit_exec_offset(code)
+#endif /* SLJIT_PROT_EXECUTABLE_ALLOCATOR */
 
 #endif /* SLJIT_EXECUTABLE_ALLOCATOR */
 
@@ -592,6 +588,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
 #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_TMP_DEST_REG SLJIT_TMP_R0
+#define SLJIT_TMP_MEM_REG SLJIT_TMP_R0
+#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
 #define SLJIT_LOCALS_OFFSET_BASE (8 * SSIZE_OF(sw))
 #define SLJIT_PREF_SHIFT_REG SLJIT_R2
 #define SLJIT_MASKED_SHIFT 1
@@ -612,6 +611,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 10
 #define SLJIT_LOCALS_OFFSET_BASE (4 * SSIZE_OF(sw))
 #endif /* !_WIN64 */
+#define SLJIT_TMP_DEST_REG SLJIT_TMP_R0
+#define SLJIT_TMP_MEM_REG SLJIT_TMP_R0
+#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
 #define SLJIT_PREF_SHIFT_REG SLJIT_R3
 #define SLJIT_MASKED_SHIFT 1
 #define SLJIT_MASKED_SHIFT32 1
@@ -624,6 +626,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
 #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_TMP_DEST_REG SLJIT_TMP_R1
+#define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
+#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
 #define SLJIT_LOCALS_OFFSET_BASE 0
 
 #elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
@@ -634,6 +639,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
 #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_TMP_DEST_REG SLJIT_TMP_R0
+#define SLJIT_TMP_MEM_REG SLJIT_TMP_R0
+#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
 #define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof(sljit_sw))
 #define SLJIT_MASKED_SHIFT 1
 #define SLJIT_MASKED_SHIFT32 1
@@ -646,6 +654,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
 #define SLJIT_NUMBER_OF_FLOAT_REGISTERS 30
 #define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 18
 #define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
+#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
+#define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
+#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
 #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)
@@ -670,6 +681,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
 #endif
 #define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5
 #define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 3
+#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
+#define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
+#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
 #define SLJIT_MASKED_SHIFT 1
 #define SLJIT_MASKED_SHIFT32 1
 
@@ -681,6 +695,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
 #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_TMP_DEST_REG SLJIT_TMP_R1
+#define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
+#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
 #define SLJIT_LOCALS_OFFSET_BASE 0
 #define SLJIT_MASKED_SHIFT 1
 #define SLJIT_MASKED_SHIFT32 1
@@ -714,6 +731,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
 #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_TMP_DEST_REG SLJIT_TMP_R0
+#define SLJIT_TMP_MEM_REG SLJIT_TMP_R2
+#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
 #define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE
 #define SLJIT_MASKED_SHIFT 1
 
@@ -725,6 +745,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
 #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_TMP_DEST_REG SLJIT_TMP_R1
+#define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
+#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
 #define SLJIT_LOCALS_OFFSET_BASE 0
 #define SLJIT_MASKED_SHIFT 1
 #define SLJIT_MASKED_SHIFT32 1
@@ -738,6 +761,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
 #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_TMP_DEST_REG 0
+#define SLJIT_TMP_MEM_REG 0
+#define SLJIT_TMP_DEST_FREG 0
 #define SLJIT_LOCALS_OFFSET_BASE 0
 
 #endif
index 6f19300081a1ba1a8a1327a859081f4b8697d19b..2dca17cd6f0786a33349fe950c84a73cf77e0910 100644 (file)
 #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
+#define JUMP_ADDR      0x1
+#define JUMP_MOV_ADDR  0x2
 /* SLJIT_REWRITABLE_JUMP is 0x1000. */
 
 #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
-#      define PATCH_MB         0x4
-#      define PATCH_MW         0x8
+#      define PATCH_MB         0x04
+#      define PATCH_MW         0x08
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
 #      define PATCH_MD         0x10
-#endif
+#      define MOV_ADDR_HI      0x20
+#      define JUMP_MAX_SIZE    ((sljit_uw)(10 + 3))
+#      define CJUMP_MAX_SIZE   ((sljit_uw)(2 + 10 + 3))
+#else /* !SLJIT_CONFIG_X86_64 */
+#      define JUMP_MAX_SIZE    ((sljit_uw)5)
+#      define CJUMP_MAX_SIZE   ((sljit_uw)6)
+#endif /* SLJIT_CONFIG_X86_64 */
 #      define TYPE_SHIFT       13
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+/* Bits 7..12 is for debug jump size, SLJIT_REWRITABLE_JUMP is 0x1000 */
+#      define JUMP_SIZE_SHIFT  7
+#endif /* SLJIT_DEBUG */
 #endif /* SLJIT_CONFIG_X86 */
 
 #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_V6 || SLJIT_CONFIG_ARM_V6 */
+#      define IS_BL            0x04
+#      define PATCH_B          0x08
+#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V7 */
 
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
 #      define CPOOL_SIZE       512
 #endif /* SLJIT_CONFIG_ARM_V6 */
 
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+#      define JUMP_SIZE_SHIFT  26
+#      define JUMP_MAX_SIZE    ((sljit_uw)3)
+#endif /* SLJIT_CONFIG_ARM_V7 */
+
 #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
 #      define IS_COND          0x04
 #      define IS_BL            0x08
 #      define PATCH_TYPE1      0x10
        /* conditional + imm20 */
 #      define PATCH_TYPE2      0x20
-       /* IT + imm24 */
-#      define PATCH_TYPE3      0x30
        /* imm11 */
-#      define PATCH_TYPE4      0x40
+#      define PATCH_TYPE3      0x30
        /* imm24 */
-#      define PATCH_TYPE5      0x50
+#      define PATCH_TYPE4      0x40
        /* BL + imm24 */
-#      define PATCH_BL         0x60
+#      define PATCH_TYPE5      0x50
+       /* addwi/subwi */
+#      define PATCH_TYPE6      0x60
        /* 0xf00 cc code for branches */
+#      define JUMP_SIZE_SHIFT  26
+#      define JUMP_MAX_SIZE    ((sljit_uw)5)
 #endif /* SLJIT_CONFIG_ARM_THUMB2 */
 
 #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
 #      define IS_COND          0x004
 #      define IS_CBZ           0x008
 #      define IS_BL            0x010
-#      define PATCH_B          0x020
-#      define PATCH_COND       0x040
-#      define PATCH_ABS48      0x080
-#      define PATCH_ABS64      0x100
+#      define PATCH_COND       0x020
+#      define PATCH_B          0x040
+#      define PATCH_B32        0x080
+#      define PATCH_ABS48      0x100
+#      define PATCH_ABS64      0x200
+#      define JUMP_SIZE_SHIFT  58
+#      define JUMP_MAX_SIZE    ((sljit_uw)5)
 #endif /* SLJIT_CONFIG_ARM_64 */
 
 #if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 #      define PATCH_ABS32      0x040
 #      define PATCH_ABS48      0x080
+#      define JUMP_SIZE_SHIFT  58
+#      define JUMP_MAX_SIZE    ((sljit_uw)7)
+#else /* !SLJIT_CONFIG_PPC_64 */
+#      define JUMP_SIZE_SHIFT  26
+#      define JUMP_MAX_SIZE    ((sljit_uw)4)
 #endif /* SLJIT_CONFIG_PPC_64 */
-#      define REMOVE_COND      0x100
 #endif /* SLJIT_CONFIG_PPC */
 
 #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
 #      define PATCH_ABS32      0x080
 #      define PATCH_ABS44      0x100
 #      define PATCH_ABS52      0x200
+#      define JUMP_SIZE_SHIFT  58
+#      define JUMP_MAX_SIZE    ((sljit_uw)6)
 #else /* !SLJIT_CONFIG_RISCV_64 */
-#      define PATCH_REL32      0x0
+#      define JUMP_SIZE_SHIFT  26
+#      define JUMP_MAX_SIZE    ((sljit_uw)2)
 #endif /* SLJIT_CONFIG_RISCV_64 */
 #endif /* SLJIT_CONFIG_RISCV */
 
 #      define PATCH_REL32      0x040
 #      define PATCH_ABS32      0x080
 #      define PATCH_ABS52      0x100
+#      define JUMP_SIZE_SHIFT  58
+#      define JUMP_MAX_SIZE    ((sljit_uw)4)
 
 #endif /* SLJIT_CONFIG_LOONGARCH */
 /* Stack management. */
 /* Utils can still be used even if SLJIT_CONFIG_UNSUPPORTED is set. */
 #include "sljitUtils.c"
 
+#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+#define SLJIT_CODE_TO_PTR(code) ((void*)((sljit_up)(code) & ~(sljit_up)0x1))
+#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+#define SLJIT_CODE_TO_PTR(code) ((void*)(*(sljit_up*)code))
+#else /* !SLJIT_CONFIG_ARM_THUMB2 && !SLJIT_INDIRECT_CALL */
+#define SLJIT_CODE_TO_PTR(code) ((void*)(code))
+#endif /* SLJIT_CONFIG_ARM_THUMB2 || SLJIT_INDIRECT_CALL */
+
 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
 
 #if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
@@ -417,7 +454,7 @@ static sljit_s32 compiler_initialized = 0;
 static void init_compiler(void);
 #endif
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
 {
        struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);
        if (!compiler)
@@ -428,10 +465,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo
                sizeof(sljit_s8) == 1 && sizeof(sljit_u8) == 1
                && sizeof(sljit_s16) == 2 && sizeof(sljit_u16) == 2
                && sizeof(sljit_s32) == 4 && sizeof(sljit_u32) == 4
-               && (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8)
-               && sizeof(sljit_p) <= sizeof(sljit_sw)
+               && (sizeof(sljit_up) == 4 || sizeof(sljit_up) == 8)
+               && sizeof(sljit_up) <= sizeof(sljit_sw)
+               && sizeof(sljit_up) == sizeof(sljit_sp)
                && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)
-               && (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8),
+               && (sizeof(sljit_uw) == sizeof(sljit_sw)),
                invalid_integer_types);
        SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_32,
                rewritable_jump_and_single_op_must_not_be_the_same);
@@ -442,7 +480,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo
        compiler->error = SLJIT_SUCCESS;
 
        compiler->allocator_data = allocator_data;
-       compiler->exec_allocator_data = exec_allocator_data;
        compiler->buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);
        compiler->abuf = (struct sljit_memory_fragment*)SLJIT_MALLOC(ABUF_SIZE, allocator_data);
 
@@ -537,37 +574,17 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi
                compiler->error = SLJIT_ERR_ALLOC_FAILED;
 }
 
-#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
 {
        SLJIT_UNUSED_ARG(exec_allocator_data);
 
-       /* Remove thumb mode flag. */
-       SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~(sljit_uw)0x1), exec_allocator_data);
+       SLJIT_FREE_EXEC(SLJIT_CODE_TO_PTR(code), exec_allocator_data);
 }
-#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
-{
-       SLJIT_UNUSED_ARG(exec_allocator_data);
-
-       /* Resolve indirection. */
-       code = (void*)(*(sljit_uw*)code);
-       SLJIT_FREE_EXEC(code, exec_allocator_data);
-}
-#else
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
-{
-       SLJIT_UNUSED_ARG(exec_allocator_data);
-
-       SLJIT_FREE_EXEC(code, exec_allocator_data);
-}
-#endif
 
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label)
 {
        if (SLJIT_LIKELY(!!jump) && SLJIT_LIKELY(!!label)) {
                jump->flags &= (sljit_uw)~JUMP_ADDR;
-               jump->flags |= JUMP_LABEL;
                jump->u.label = label;
        }
 }
@@ -575,18 +592,11 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sl
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
 {
        if (SLJIT_LIKELY(!!jump)) {
-               jump->flags &= (sljit_uw)~JUMP_LABEL;
                jump->flags |= JUMP_ADDR;
                jump->u.target = target;
        }
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label)
-{
-       if (SLJIT_LIKELY(!!put_label))
-               put_label->label = label;
-}
-
 #define SLJIT_CURRENT_FLAGS_ALL \
        (SLJIT_CURRENT_FLAGS_32 | SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE)
 
@@ -681,31 +691,66 @@ static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
        compiler->buf = prev;
 }
 
-/* Only used in RISC architectures where the instruction size is constant */
-#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
-       && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-
-static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct sljit_jump *jump,
-       struct sljit_const *const_, struct sljit_put_label *put_label)
+static SLJIT_INLINE void* allocate_executable_memory(sljit_uw size, sljit_s32 options,
+       void *exec_allocator_data, sljit_sw *executable_offset)
 {
-       sljit_uw result = ~(sljit_uw)0;
+       void *code;
+       struct sljit_generate_code_buffer *buffer;
+
+       if (SLJIT_LIKELY(!(options & SLJIT_GENERATE_CODE_BUFFER))) {
+               code = SLJIT_MALLOC_EXEC(size, exec_allocator_data);
+               *executable_offset = SLJIT_EXEC_OFFSET(code);
+               return code;
+       }
+
+       buffer = (struct sljit_generate_code_buffer*)exec_allocator_data;
+
+       if (size <= buffer->size) {
+               *executable_offset = buffer->executable_offset;
+               return buffer->buffer;
+       }
+
+       return NULL;
+}
+
+#define SLJIT_MAX_ADDRESS ~(sljit_uw)0
+
+#define SLJIT_GET_NEXT_SIZE(ptr) (ptr != NULL) ? ((ptr)->size) : SLJIT_MAX_ADDRESS
+#define SLJIT_GET_NEXT_ADDRESS(ptr) (ptr != NULL) ? ((ptr)->addr) : SLJIT_MAX_ADDRESS
+
+#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+
+#define SLJIT_NEXT_DEFINE_TYPES \
+       sljit_uw next_label_size; \
+       sljit_uw next_jump_addr; \
+       sljit_uw next_const_addr; \
+       sljit_uw next_min_addr
+
+#define SLJIT_NEXT_INIT_TYPES() \
+       next_label_size = SLJIT_GET_NEXT_SIZE(label); \
+       next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump); \
+       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
 
-       if (label)
-               result = label->size;
+#define SLJIT_GET_NEXT_MIN() \
+       next_min_addr = sljit_get_next_min(next_label_size, next_jump_addr, next_const_addr);
 
-       if (jump && jump->addr < result)
-               result = jump->addr;
+static SLJIT_INLINE sljit_uw sljit_get_next_min(sljit_uw next_label_size,
+       sljit_uw next_jump_addr, sljit_uw next_const_addr)
+{
+       sljit_uw result = next_jump_addr;
+
+       SLJIT_ASSERT(result == SLJIT_MAX_ADDRESS || result != next_const_addr);
 
-       if (const_ && const_->addr < result)
-               result = const_->addr;
+       if (next_const_addr < result)
+               result = next_const_addr;
 
-       if (put_label && put_label->addr < result)
-               result = put_label->addr;
+       if (next_label_size < result)
+               result = next_label_size;
 
        return result;
 }
 
-#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X */
+#endif /* !SLJIT_CONFIG_X86 */
 
 static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
        sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
@@ -746,8 +791,9 @@ static SLJIT_INLINE void set_set_context(struct sljit_compiler *compiler,
 static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compiler *compiler)
 {
        label->next = NULL;
+       label->u.index = compiler->label_count++;
        label->size = compiler->size;
-       if (compiler->last_label)
+       if (compiler->last_label != NULL)
                compiler->last_label->next = label;
        else
                compiler->labels = label;
@@ -758,7 +804,21 @@ static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler
 {
        jump->next = NULL;
        jump->flags = flags;
-       if (compiler->last_jump)
+       jump->u.label = NULL;
+       if (compiler->last_jump != NULL)
+               compiler->last_jump->next = jump;
+       else
+               compiler->jumps = jump;
+       compiler->last_jump = jump;
+}
+
+static SLJIT_INLINE void set_mov_addr(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_uw offset)
+{
+       jump->next = NULL;
+       jump->addr = compiler->size - offset;
+       jump->flags = JUMP_MOV_ADDR;
+       jump->u.label = NULL;
+       if (compiler->last_jump != NULL)
                compiler->last_jump->next = jump;
        else
                compiler->jumps = jump;
@@ -769,26 +829,13 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp
 {
        const_->next = NULL;
        const_->addr = compiler->size;
-       if (compiler->last_const)
+       if (compiler->last_const != NULL)
                compiler->last_const->next = const_;
        else
                compiler->consts = const_;
        compiler->last_const = const_;
 }
 
-static SLJIT_INLINE void set_put_label(struct sljit_put_label *put_label, struct sljit_compiler *compiler, sljit_uw offset)
-{
-       put_label->next = NULL;
-       put_label->label = NULL;
-       put_label->addr = compiler->size - offset;
-       put_label->flags = 0;
-       if (compiler->last_put_label)
-               compiler->last_put_label->next = put_label;
-       else
-               compiler->put_labels = put_label;
-       compiler->last_put_label = put_label;
-}
-
 #define ADDRESSING_DEPENDS_ON(exp, reg) \
        (((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))
 
@@ -1106,6 +1153,10 @@ static const char* op2_names[] = {
        "ashr", "mashr", "rotl", "rotr"
 };
 
+static const char* op2r_names[] = {
+       "muladd"
+};
+
 static const char* op_src_dst_names[] = {
        "fast_return", "skip_frames_before_fast_return",
        "prefetch_l1", "prefetch_l2",
@@ -1187,13 +1238,19 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_com
        jump = compiler->jumps;
        while (jump) {
                /* All jumps have target. */
-               CHECK_ARGUMENT(jump->flags & (JUMP_LABEL | JUMP_ADDR));
+               CHECK_ARGUMENT((jump->flags & JUMP_ADDR) || jump->u.label != NULL);
                jump = jump->next;
        }
 #endif
        CHECK_RETURN_OK;
 }
 
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+#define SLJIT_ENTER_CPU_SPECIFIC_OPTIONS (SLJIT_ENTER_USE_VEX)
+#else /* !SLJIT_CONFIG_X86 */
+#define SLJIT_ENTER_CPU_SPECIFIC_OPTIONS (0)
+#endif /* !SLJIT_CONFIG_X86 */
+
 static SLJIT_INLINE CHECK_RETURN_TYPE check_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)
@@ -1202,9 +1259,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compil
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
        if (options & SLJIT_ENTER_REG_ARG) {
-               CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG)));
+               CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG | SLJIT_ENTER_CPU_SPECIFIC_OPTIONS)));
        } else {
-               CHECK_ARGUMENT(options == 0);
+               CHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0);
        }
        CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);
        CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
@@ -1238,11 +1295,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compil
                fprintf(compiler->verbose, "],");
 
                if (options & SLJIT_ENTER_REG_ARG) {
-                       fprintf(compiler->verbose, " enter:reg_arg,");
-
                        if (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)
-                               fprintf(compiler->verbose, " keep:%d,", SLJIT_KEPT_SAVEDS_COUNT(options));
+                               fprintf(compiler->verbose, " opt:reg_arg(%d),", SLJIT_KEPT_SAVEDS_COUNT(options));
+                       else
+                               fprintf(compiler->verbose, " opt:reg_arg,");
+               }
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+               if (options & SLJIT_ENTER_USE_VEX) {
+                               fprintf(compiler->verbose, " opt:use_vex,");
                }
+#endif /* !SLJIT_CONFIG_X86 */
 
                fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
                        scratches, saveds, fscratches, fsaveds, local_size);
@@ -1259,9 +1322,9 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compi
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
        if (options & SLJIT_ENTER_REG_ARG) {
-               CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG)));
+               CHECK_ARGUMENT(!(options & ~(0x3 | SLJIT_ENTER_REG_ARG | SLJIT_ENTER_CPU_SPECIFIC_OPTIONS)));
        } else {
-               CHECK_ARGUMENT(options == 0);
+               CHECK_ARGUMENT((options & ~SLJIT_ENTER_CPU_SPECIFIC_OPTIONS) == 0);
        }
        CHECK_ARGUMENT(SLJIT_KEPT_SAVEDS_COUNT(options) <= 3 && SLJIT_KEPT_SAVEDS_COUNT(options) <= saveds);
        CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
@@ -1295,11 +1358,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compi
                fprintf(compiler->verbose, "],");
 
                if (options & SLJIT_ENTER_REG_ARG) {
-                       fprintf(compiler->verbose, " enter:reg_arg,");
-
                        if (SLJIT_KEPT_SAVEDS_COUNT(options) > 0)
-                               fprintf(compiler->verbose, " keep:%d,", SLJIT_KEPT_SAVEDS_COUNT(options));
+                               fprintf(compiler->verbose, " opt:reg_arg(%d),", SLJIT_KEPT_SAVEDS_COUNT(options));
+                       else
+                               fprintf(compiler->verbose, " opt:reg_arg,");
+               }
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+               if (options & SLJIT_ENTER_USE_VEX) {
+                               fprintf(compiler->verbose, " opt:use_vex,");
                }
+#endif /* !SLJIT_CONFIG_X86 */
 
                fprintf(compiler->verbose, " scratches:%d, saveds:%d, fscratches:%d, fsaveds:%d, local_size:%d\n",
                        scratches, saveds, fscratches, fsaveds, local_size);
@@ -1308,6 +1377,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compi
        CHECK_RETURN_OK;
 }
 
+#undef SLJIT_ENTER_CPU_SPECIFIC_OPTIONS
+
 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_return_void(struct sljit_compiler *compiler)
 {
        if (SLJIT_UNLIKELY(compiler->skip_checks)) {
@@ -1636,6 +1707,33 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler
        CHECK_RETURN_OK;
 }
 
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
+       sljit_s32 dst_reg,
+       sljit_s32 src1, sljit_sw src1w,
+       sljit_s32 src2, sljit_sw src2w)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+       CHECK_ARGUMENT((op | SLJIT_32) == SLJIT_MULADD32);
+       CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
+       FUNCTION_CHECK_SRC(src1, src1w);
+       FUNCTION_CHECK_SRC(src2, src2w);
+       compiler->last_flags = 0;
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+       if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+               fprintf(compiler->verbose, "  %s%s ", op2r_names[GET_OPCODE(op) - SLJIT_OP2R_BASE], !(op & SLJIT_32) ? "" : "32");
+
+               sljit_verbose_reg(compiler, dst_reg);
+               fprintf(compiler->verbose, ", ");
+               sljit_verbose_param(compiler, src1, src1w);
+               fprintf(compiler->verbose, ", ");
+               sljit_verbose_param(compiler, src2, src2w);
+               fprintf(compiler->verbose, "\n");
+       }
+#endif
+       CHECK_RETURN_OK;
+}
+
 static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
        sljit_s32 dst_reg,
        sljit_s32 src1_reg,
@@ -1721,11 +1819,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_register_index(sljit_s32 t
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
        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)));
+                       || (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)));
+                       || (reg >= SLJIT_TMP_FREGISTER_BASE && reg < (SLJIT_TMP_FREGISTER_BASE + SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS)));
        }
 #endif
        CHECK_RETURN_OK;
@@ -2927,14 +3025,14 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil
        CHECK_RETURN_OK;
 }
 
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
        FUNCTION_CHECK_DST(dst, dstw);
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
        if (SLJIT_UNLIKELY(!!compiler->verbose)) {
-               fprintf(compiler->verbose, "  put_label ");
+               fprintf(compiler->verbose, "  mov_addr ");
                sljit_verbose_param(compiler, dst, dstw);
                fprintf(compiler->verbose, "\n");
        }
@@ -3058,6 +3156,8 @@ static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, slji
 #      include "sljitNativeLOONGARCH_64.c"
 #endif
 
+#include "sljitSerialize.c"
+
 static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
 {
 #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
@@ -3288,7 +3388,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem_update(struct sljit_compiler
 
 #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_S390X && SLJIT_CONFIG_S390X) \
+       && !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,
        sljit_s32 freg,
index 2ba6683c74b8b6da3b9da2202bebb22f57336d29..8b6fa69a0a299849393c3ab2100a3f926cb6bd96 100644 (file)
@@ -427,7 +427,10 @@ struct sljit_memory_fragment {
 
 struct sljit_label {
        struct sljit_label *next;
-       sljit_uw addr;
+       union {
+               sljit_uw index;
+               sljit_uw addr;
+       } u;
        /* The maximum size difference. */
        sljit_uw size;
 };
@@ -443,36 +446,35 @@ struct sljit_jump {
        } u;
 };
 
-struct sljit_put_label {
-       struct sljit_put_label *next;
-       struct sljit_label *label;
-       sljit_uw addr;
-       sljit_uw flags;
-};
-
 struct sljit_const {
        struct sljit_const *next;
        sljit_uw addr;
 };
 
+struct sljit_generate_code_buffer {
+       void *buffer;
+       sljit_uw size;
+       sljit_sw executable_offset;
+};
+
 struct sljit_compiler {
        sljit_s32 error;
        sljit_s32 options;
 
        struct sljit_label *labels;
        struct sljit_jump *jumps;
-       struct sljit_put_label *put_labels;
        struct sljit_const *consts;
        struct sljit_label *last_label;
        struct sljit_jump *last_jump;
        struct sljit_const *last_const;
-       struct sljit_put_label *last_put_label;
 
        void *allocator_data;
-       void *exec_allocator_data;
+       void *user_data;
        struct sljit_memory_fragment *buf;
        struct sljit_memory_fragment *abuf;
 
+       /* Number of labels created by the compiler. */
+       sljit_uw label_count;
        /* Available scratch registers. */
        sljit_s32 scratches;
        /* Available saved registers. */
@@ -492,15 +494,16 @@ struct sljit_compiler {
 
 #if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
        sljit_s32 status_flags_state;
-#endif
+#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */
 
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
        sljit_s32 args_size;
-#endif
+#endif /* SLJIT_CONFIG_X86_32 */
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+       /* Temporary fields. */
        sljit_s32 mode32;
-#endif
+#endif /* SLJIT_CONFIG_X86_64 */
 
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
        /* Constant pool handling. */
@@ -511,7 +514,7 @@ struct sljit_compiler {
        /* Other members. */
        /* Contains pointer, "ldr pc, [...]" pairs. */
        sljit_uw patches;
-#endif
+#endif /* SLJIT_CONFIG_ARM_V6 */
 
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
        /* Temporary fields. */
@@ -520,40 +523,45 @@ struct sljit_compiler {
 
 #if (defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)
        sljit_uw args_size;
-#endif
+#endif /* SLJIT_CONFIG_ARM_32 && __SOFTFP__ */
 
 #if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
+       /* Temporary fields. */
        sljit_u32 imm;
-#endif
+#endif /* SLJIT_CONFIG_PPC */
 
 #if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
        sljit_s32 delay_slot;
+       /* Temporary fields. */
        sljit_s32 cache_arg;
        sljit_sw cache_argw;
-#endif
+#endif /* SLJIT_CONFIG_MIPS */
 
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
        sljit_uw args_size;
-#endif
+#endif /* SLJIT_CONFIG_MIPS_32 */
 
 #if (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
+       /* Temporary fields. */
        sljit_s32 cache_arg;
        sljit_sw cache_argw;
-#endif
+#endif /* SLJIT_CONFIG_RISCV */
 
 #if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
        /* Need to allocate register save area to make calls. */
+       /* Temporary fields. */
        sljit_s32 mode;
-#endif
+#endif /* SLJIT_CONFIG_S390X */
 
 #if (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
+       /* Temporary fields. */
        sljit_s32 cache_arg;
        sljit_sw cache_argw;
-#endif
+#endif /* SLJIT_CONFIG_LOONGARCH */
 
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
        FILE* verbose;
-#endif
+#endif /* SLJIT_VERBOSE */
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
                || (defined SLJIT_DEBUG && SLJIT_DEBUG)
@@ -564,7 +572,7 @@ struct sljit_compiler {
        sljit_s32 last_return;
        /* Local size passed to entry functions. */
        sljit_s32 logical_local_size;
-#endif
+#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */
 
 #if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
                || (defined SLJIT_DEBUG && SLJIT_DEBUG) \
@@ -572,7 +580,7 @@ struct sljit_compiler {
        /* Trust arguments when an API function is called.
           Used internally for calling API functions. */
        sljit_s32 skip_checks;
-#endif
+#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG || SLJIT_VERBOSE */
 };
 
 /* --------------------------------------------------------------------- */
@@ -583,12 +591,10 @@ struct sljit_compiler {
    custom memory managers. This pointer is passed to SLJIT_MALLOC
    and SLJIT_FREE macros. Most allocators (including the default
    one) ignores this value, and it is recommended to pass NULL
-   as a dummy value for allocator_data. The exec_allocator_data
-   has the same purpose but this one is passed to SLJIT_MALLOC_EXEC /
-   SLJIT_MALLOC_FREE functions.
+   as a dummy value for allocator_data.
 
    Returns NULL if failed. */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data);
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data);
 
 /* Frees everything except the compiled machine code. */
 SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
@@ -619,20 +625,31 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi
    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; }
+/* Returns the allocator data passed to sljit_create_compiler. */
+static SLJIT_INLINE void* sljit_compiler_get_allocator_data(struct sljit_compiler *compiler) { return compiler->allocator_data; }
+/* Sets/get the user data for a compiler. */
+static SLJIT_INLINE void sljit_compiler_set_user_data(struct sljit_compiler *compiler, void *user_data) { compiler->user_data = user_data; }
+static SLJIT_INLINE void* sljit_compiler_get_user_data(struct sljit_compiler *compiler) { return compiler->user_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
 
+/* Option bits for sljit_generate_code. */
+
+/* The exec_allocator_data points to a pre-allocated
+   buffer which type is sljit_generate_code_buffer. */
+#define SLJIT_GENERATE_CODE_BUFFER             0x1
+
 /* 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. */
+   of the code generation, and no more instructions can be emitted after this call.
+
+   options is the combination of SLJIT_GENERATE_CODE_* bits
+   exec_allocator_data is passed to SLJIT_MALLOC_EXEC and
+                       SLJIT_MALLOC_FREE functions */
 
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler);
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data);
 
 /* Free executable code. */
 
@@ -708,6 +725,11 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler
 #define SLJIT_HAS_AVX2                 101
 #endif
 
+#if (defined SLJIT_CONFIG_LOONGARCH)
+/* [Not emulated] LASX support is available on LoongArch */
+#define SLJIT_HAS_LASX        201
+#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,
@@ -777,17 +799,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type);
    global / local context pointers) across function calls. The
    value of n must be between 1 and 3. This option is only
    supported by SLJIT_ENTER_REG_ARG calling convention. */
-#define SLJIT_ENTER_KEEP(n)    (n)
+#define SLJIT_ENTER_KEEP(n)            (n)
 
 /* The compiled function uses an SLJIT specific register argument
    calling convention. This is a lightweight function call type where
    both the caller and the called functions must be compiled by
    SLJIT. The type argument of the call must be SLJIT_CALL_REG_ARG
    and all arguments must be stored in scratch registers. */
-#define SLJIT_ENTER_REG_ARG    0x00000004
+#define SLJIT_ENTER_REG_ARG            0x00000004
 
 /* The local_size must be >= 0 and <= SLJIT_MAX_LOCAL_SIZE. */
-#define SLJIT_MAX_LOCAL_SIZE   1048576
+#define SLJIT_MAX_LOCAL_SIZE           1048576
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+/* Use VEX prefix for all SIMD operations on x86. */
+#define SLJIT_ENTER_USE_VEX            0x00010000
+#endif /* !SLJIT_CONFIG_X86 */
 
 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,
@@ -855,7 +882,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c
      int    | 4 byte (physical_address & 0x3 == 0)
      word   | 4 byte if SLJIT_32BIT_ARCHITECTURE is defined and its value is 1
             | 8 byte if SLJIT_64BIT_ARCHITECTURE is defined and its value is 1
-    pointer | size of sljit_p type (4 byte on 32 bit machines, 4 or 8 byte
+    pointer | size of sljit_up type (4 byte on 32 bit machines, 4 or 8 byte
             | on 64 bit machines)
 
    Note:   Different architectures have different addressing limitations.
@@ -913,6 +940,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c
 #define SLJIT_IS_IMM(arg)      ((arg) == SLJIT_IMM)
 #define SLJIT_IS_REG_PAIR(arg) (!((arg) & SLJIT_MEM) && (arg) >= (SLJIT_MEM << 1))
 
+/* Macros for extracting registers from operands. */
+/* Support operands which contains a single register or
+   constructed using SLJIT_MEM1, SLJIT_MEM2, or SLJIT_REG_PAIR. */
+#define SLJIT_EXTRACT_REG(arg)         ((arg) & 0x7f)
+/* Support operands which constructed using SLJIT_MEM2, or SLJIT_REG_PAIR. */
+#define SLJIT_EXTRACT_SECOND_REG(arg)  ((arg) >> 8)
+
 /* 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
@@ -1084,7 +1118,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
    S16 - signed 16 bit data transfer
    U32 - unsigned int (32 bit) data transfer
    S32 - signed int (32 bit) data transfer
-   P   - pointer (sljit_p) data transfer
+   P   - pointer (sljit_up) data transfer
 */
 
 /* Flags: - (does not modify flags) */
@@ -1251,6 +1285,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil
        sljit_s32 src1, sljit_sw src1w,
        sljit_s32 src2, sljit_sw src2w);
 
+/* Starting index of opcodes for sljit_emit_op2r. */
+#define SLJIT_OP2R_BASE                        96
+
+/* Flags: - (may destroy flags) */
+#define SLJIT_MULADD                   (SLJIT_OP2R_BASE + 0)
+#define SLJIT_MULADD32                 (SLJIT_MULADD | SLJIT_32)
+
+/* Similar to sljit_emit_fop2, except the destination is always a register. */
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
+       sljit_s32 dst_reg,
+       sljit_s32 src1, sljit_sw src1w,
+       sljit_s32 src2, sljit_sw src2w);
+
 /* Emit a left or right shift operation, where the bits shifted
    in comes from a separate source operand. All operands are
    interpreted as unsigned integers.
@@ -1298,7 +1345,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
 
 /* Starting index of opcodes for sljit_emit_op_src
    and sljit_emit_op_dst. */
-#define SLJIT_OP_SRC_DST_BASE          96
+#define SLJIT_OP_SRC_DST_BASE          112
 
 /* Fast return, see SLJIT_FAST_CALL for more details.
    Note: src cannot be an immedate value
@@ -1350,7 +1397,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *comp
        sljit_s32 dst, sljit_sw dstw);
 
 /* Starting index of opcodes for sljit_emit_fop1. */
-#define SLJIT_FOP1_BASE                        128
+#define SLJIT_FOP1_BASE                        144
 
 /* Flags: - (does not modify flags) */
 #define SLJIT_MOV_F64                  (SLJIT_FOP1_BASE + 0)
@@ -1395,7 +1442,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                        160
+#define SLJIT_FOP2_BASE                        176
 
 /* Flags: - (may destroy flags) */
 #define SLJIT_ADD_F64                  (SLJIT_FOP2_BASE + 0)
@@ -1416,7 +1463,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
        sljit_s32 src2, sljit_sw src2w);
 
 /* Starting index of opcodes for sljit_emit_fop2r. */
-#define SLJIT_FOP2R_BASE               168
+#define SLJIT_FOP2R_BASE               192
 
 /* Flags: - (may destroy flags) */
 #define SLJIT_COPYSIGN_F64             (SLJIT_FOP2R_BASE + 0)
@@ -2138,17 +2185,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *c
    Flags: - (does not modify flags) */
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value);
 
-/* Store the value of a label (see: sljit_set_put_label)
+/* Store the value of a label (see: sljit_set_label / sljit_set_target)
    Flags: - (does not modify flags) */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
-
-/* Set the value stored by put_label to this label. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label);
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
 
-/* After the code generation the address for label, jump and const instructions
-   are computed. Since these structures are freed by sljit_free_compiler, the
-   addresses must be preserved by the user program elsewere. */
-static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->addr; }
+/* Provides the address of label, jump and const instructions after sljit_generate_code
+   is called. The returned value is unspecified before the sljit_generate_code call.
+   Since these structures are freed by sljit_free_compiler, the addresses must be
+   preserved by the user program elsewere. */
+static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->u.addr; }
 static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
 static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
 
@@ -2221,6 +2266,98 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler,
        sljit_s32 current_flags);
 
+/* --------------------------------------------------------------------- */
+/*  Serialization functions                                              */
+/* --------------------------------------------------------------------- */
+
+/* Label/jump/const enumeration functions. The items in each group
+   are enumerated in creation order. Serialization / deserialization
+   preserves this order for each group. For example the fifth label
+   after deserialization refers to the same machine code location as
+   the fifth label before the serialization. */
+static SLJIT_INLINE struct sljit_label *sljit_get_first_label(struct sljit_compiler *compiler) { return compiler->labels; }
+static SLJIT_INLINE struct sljit_jump *sljit_get_first_jump(struct sljit_compiler *compiler) { return compiler->jumps; }
+static SLJIT_INLINE struct sljit_const *sljit_get_first_const(struct sljit_compiler *compiler) { return compiler->consts; }
+
+static SLJIT_INLINE struct sljit_label *sljit_get_next_label(struct sljit_label *label) { return label->next; }
+static SLJIT_INLINE struct sljit_jump *sljit_get_next_jump(struct sljit_jump *jump) { return jump->next; }
+static SLJIT_INLINE struct sljit_const *sljit_get_next_const(struct sljit_const *const_) { return const_->next; }
+
+/* A number starting from 0 is assigned to each label, which
+represents its creation index. The first label created by the
+compiler has index 0, the second has index 1, the third has
+index 2, and so on. The returned value is unspecified after
+sljit_generate_code() is called. */
+static SLJIT_INLINE sljit_uw sljit_get_label_index(struct sljit_label *label) { return label->u.index; }
+
+/* The sljit_jump_has_label() and sljit_jump_has_target() functions
+returns non-zero value if a label or target is set for the jump
+respectively. Both may return with a zero value. The other two
+functions return the value assigned to the jump. */
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_label(struct sljit_jump *jump);
+static SLJIT_INLINE struct sljit_label *sljit_jump_get_label(struct sljit_jump *jump) { return jump->u.label; }
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_target(struct sljit_jump *jump);
+static SLJIT_INLINE sljit_uw sljit_jump_get_target(struct sljit_jump *jump) { return jump->u.target; }
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_is_mov_addr(struct sljit_jump *jump);
+
+/* Option bits for sljit_serialize_compiler. */
+
+/* When debugging is enabled, the serialized buffer contains
+debugging information unless this option is specified. */
+#define SLJIT_SERIALIZE_IGNORE_DEBUG           0x1
+
+/* Serialize the internal structure of the compiler into a buffer.
+If the serialization is successful, the returned value is a newly
+allocated buffer which is allocated by the memory allocator assigned
+to the compiler. Otherwise the returned value is NULL. Unlike
+sljit_generate_code(), serialization does not modify the internal
+state of the compiler, so the code generation can be continued.
+
+  options must be the combination of SLJIT_SERIALIZE_* option bits
+  size is an output argument, which is set to the byte size of
+    the result buffer if the operation is successful
+
+Notes:
+  - This function is useful for ahead-of-time compilation (AOT).
+  - The returned buffer must be freed later by the caller.
+    The SLJIT_FREE() macro is suitable for this purpose:
+    SLJIT_FREE(returned_buffer, sljit_get_allocator_data(compiler))
+  - Memory allocated by sljit_alloc_memory() is not serialized.
+  - The type of the returned buffer is sljit_uw* to emphasize that
+    the buffer is word aligned. However, the 'size' output argument
+    contains the byte size, so this value is always divisible by
+    sizeof(sljit_uw).
+*/
+SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compiler *compiler,
+       sljit_s32 options, sljit_uw *size);
+
+/* Construct a new compiler instance from a buffer produced by
+sljit_serialize_compiler(). If the operation is successful, the new
+compiler instance is returned. Otherwise the returned value is NULL.
+
+  buffer points to a word aligned memory data which was
+    created by sljit_serialize_compiler()
+  size is the byte size of the buffer
+  options must be 0
+  allocator_data specify an allocator specific data, see
+                 sljit_create_compiler() for further details
+
+Notes:
+  - Labels assigned to jumps are restored with their
+    corresponding label in the label set created by
+    the deserializer. Target addresses assigned to
+    jumps are also restored. Uninitialized jumps
+    remain uninitialized.
+  - After the deserialization, sljit_generate_code() does
+    not need to be the next operation on the returned
+    compiler, the code generation can be continued.
+    Even sljit_serialize_compiler() can be called again.
+  - When debugging is enabled, a buffers without debug
+    information cannot be deserialized.
+*/
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit_uw* buffer, sljit_uw size,
+       sljit_s32 options, void *allocator_data);
+
 /* --------------------------------------------------------------------- */
 /*  Miscellaneous utility functions                                      */
 /* --------------------------------------------------------------------- */
index d44616d800f556cf771b35f54affed5d386cc58b..a253c06f01008f43eac9609d0b96f40e5315597c 100644 (file)
@@ -120,6 +120,7 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1)
 #define LDREX          0xe1900f9f
 #define LDREXB         0xe1d00f9f
 #define LDREXH         0xe1f00f9f
+#define MLA            0xe0200090
 #define MOV            0xe1a00000
 #define MUL            0xe0000090
 #define MVN            0xe1e00000
@@ -482,11 +483,12 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
        if (jump->flags & IS_BL)
                code_ptr--;
+#endif /* SLJIT_CONFIG_ARM_V6 */
 
        if (jump->flags & JUMP_ADDR)
                diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset);
        else {
-               SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+               SLJIT_ASSERT(jump->u.label != NULL);
                diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2));
        }
 
@@ -494,6 +496,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw
        if (diff & 0x3)
                return 0;
 
+#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
        if (jump->flags & IS_BL) {
                if (diff <= 0x01ffffff && diff >= -0x02000000) {
                        *code_ptr = (BL - CONDITIONAL) | (*(code_ptr + 1) & COND_MASK);
@@ -508,20 +511,8 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw
                }
        }
 #else /* !SLJIT_CONFIG_ARM_V6 */
-       if (jump->flags & JUMP_ADDR)
-               diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr - executable_offset);
-       else {
-               SLJIT_ASSERT(jump->flags & JUMP_LABEL);
-               diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr);
-       }
-
-       /* Branch to Thumb code has not been optimized yet. */
-       if (diff & 0x3)
-               return 0;
-
        if (diff <= 0x01ffffff && diff >= -0x02000000) {
-               code_ptr -= 2;
-               *code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (code_ptr[2] & COND_MASK);
+               *code_ptr = ((jump->flags & IS_BL) ? (BL - CONDITIONAL) : (B - CONDITIONAL)) | (*code_ptr & COND_MASK);
                jump->flags |= PATCH_B;
                return 1;
        }
@@ -529,7 +520,7 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_uw
        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)
+static void set_jump_addr(sljit_uw jump_ptr, sljit_sw executable_offset, sljit_uw new_addr, sljit_s32 flush_cache)
 {
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
        sljit_ins *ptr = (sljit_ins*)jump_ptr;
@@ -628,7 +619,7 @@ static sljit_uw get_imm(sljit_uw imm);
 static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 reg, sljit_uw imm);
 static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg);
 
-static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_offset, sljit_uw new_constant, sljit_s32 flush_cache)
+static void set_const_value(sljit_uw addr, sljit_sw executable_offset, sljit_uw new_constant, sljit_s32 flush_cache)
 {
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
        sljit_ins *ptr = (sljit_ins*)addr;
@@ -720,18 +711,120 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off
 #endif /* SLJIT_CONFIG_ARM_V6 */
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
+{
+       sljit_uw addr;
+       sljit_sw diff;
+       SLJIT_UNUSED_ARG(executable_offset);
+
+       if (jump->flags & JUMP_ADDR)
+               addr = jump->u.target;
+       else
+               addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);
+
+       /* The pc+8 offset is represented by the 2 * SSIZE_OF(ins) below. */
+       diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+       if ((diff & 0x3) == 0 && diff <= (0x3fc + 2 * SSIZE_OF(ins)) && diff >= (-0x3fc + 2 * SSIZE_OF(ins))) {
+               jump->flags |= PATCH_B;
+               return 0;
+       }
+
+#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
+       return 0;
+#else /* !SLJIT_CONFIG_ARM_V6 */
+       return 1;
+#endif /* SLJIT_CONFIG_ARM_V6 */
+}
+
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+
+static void reduce_code_size(struct sljit_compiler *compiler)
+{
+       struct sljit_label *label;
+       struct sljit_jump *jump;
+       struct sljit_const *const_;
+       SLJIT_NEXT_DEFINE_TYPES;
+       sljit_uw total_size;
+       sljit_uw size_reduce = 0;
+       sljit_sw diff;
+
+       label = compiler->labels;
+       jump = compiler->jumps;
+       const_ = compiler->consts;
+       SLJIT_NEXT_INIT_TYPES();
+
+       while (1) {
+               SLJIT_GET_NEXT_MIN();
+
+               if (next_min_addr == SLJIT_MAX_ADDRESS)
+                       break;
+
+               if (next_min_addr == next_label_size) {
+                       label->size -= size_reduce;
+
+                       label = label->next;
+                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
+               }
+
+               if (next_min_addr == next_const_addr) {
+                       const_->addr -= size_reduce;
+                       const_ = const_->next;
+                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
+                       continue;
+               }
+
+               if (next_min_addr != next_jump_addr)
+                       continue;
+
+               jump->addr -= size_reduce;
+               if (!(jump->flags & JUMP_MOV_ADDR)) {
+                       total_size = JUMP_MAX_SIZE - 1;
+
+                       if (!(jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR))) {
+                               /* Unit size: instruction. */
+                               diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr - 2;
+
+                               if (diff <= (0x01ffffff / SSIZE_OF(ins)) && diff >= (-0x02000000 / SSIZE_OF(ins)))
+                                       total_size = 1 - 1;
+                       }
+
+                       size_reduce += JUMP_MAX_SIZE - 1 - total_size;
+               } else {
+                       /* Real size minus 1. Unit size: instruction. */
+                       total_size = 1;
+
+                       if (!(jump->flags & JUMP_ADDR)) {
+                               diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;
+                               if (diff <= 0xff + 2 && diff >= -0xff + 2)
+                                       total_size = 0;
+                       }
+
+                       size_reduce += 1 - total_size;
+               }
+
+               jump->flags |= total_size << JUMP_SIZE_SHIFT;
+               jump = jump->next;
+               next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+       }
+
+       compiler->size -= size_reduce;
+}
+
+#endif /* SLJIT_CONFIG_ARM_V7 */
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
 {
        struct sljit_memory_fragment *buf;
        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_NEXT_DEFINE_TYPES;
        sljit_sw executable_offset;
        sljit_uw addr;
+       sljit_sw diff;
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
        sljit_uw cpool_size;
        sljit_uw cpool_skip_alignment;
@@ -744,22 +837,22 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        struct sljit_label *label;
        struct sljit_jump *jump;
        struct sljit_const *const_;
-       struct sljit_put_label *put_label;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_generate_code(compiler));
-       reverse_buf(compiler);
 
        /* Second code generation pass. */
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
-       size = compiler->size + (compiler->patches << 1);
+       compiler->size += (compiler->patches << 1);
        if (compiler->cpool_fill > 0)
-               size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1;
+               compiler->size += compiler->cpool_fill + CONST_POOL_ALIGNMENT - 1;
 #else /* !SLJIT_CONFIG_ARM_V6 */
-       size = compiler->size;
+       reduce_code_size(compiler);
 #endif /* SLJIT_CONFIG_ARM_V6 */
-       code = (sljit_ins*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_ins), compiler->exec_allocator_data);
+       code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
        PTR_FAIL_WITH_EXEC_IF(code);
+
+       reverse_buf(compiler);
        buf = compiler->buf;
 
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
@@ -773,33 +866,24 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
 
        code_ptr = code;
        word_count = 0;
-       next_addr = 1;
-       executable_offset = SLJIT_EXEC_OFFSET(code);
-
        label = compiler->labels;
        jump = compiler->jumps;
        const_ = compiler->consts;
-       put_label = compiler->put_labels;
-
-       if (label && label->size == 0) {
-               label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
-               label = label->next;
-       }
+       SLJIT_NEXT_INIT_TYPES();
+       SLJIT_GET_NEXT_MIN();
 
        do {
                buf_ptr = (sljit_ins*)buf->memory;
                buf_end = buf_ptr + (buf->used_size >> 2);
                do {
-                       word_count++;
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
                        if (cpool_size > 0) {
                                if (cpool_skip_alignment > 0) {
                                        buf_ptr++;
                                        cpool_skip_alignment--;
-                               }
-                               else {
+                               } else {
                                        if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
-                                               SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);
+                                               SLJIT_FREE_EXEC(code, exec_allocator_data);
                                                compiler->error = SLJIT_ERR_ALLOC_FAILED;
                                                return NULL;
                                        }
@@ -807,59 +891,59 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
                                        if (++cpool_current_index >= cpool_size) {
                                                SLJIT_ASSERT(!first_patch);
                                                cpool_size = 0;
-                                               if (label && label->size == word_count) {
-                                                       /* Points after the current instruction. */
-                                                       label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
-                                                       label->size = (sljit_uw)(code_ptr - code);
-                                                       label = label->next;
-
-                                                       next_addr = compute_next_addr(label, jump, const_, put_label);
-                                               }
                                        }
                                }
-                       }
-                       else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {
+                       } else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {
 #endif /* SLJIT_CONFIG_ARM_V6 */
                                *code_ptr = *buf_ptr++;
-                               if (next_addr == word_count) {
+                               if (next_min_addr == word_count) {
                                        SLJIT_ASSERT(!label || label->size >= word_count);
                                        SLJIT_ASSERT(!jump || jump->addr >= word_count);
                                        SLJIT_ASSERT(!const_ || const_->addr >= word_count);
-                                       SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
 
-                               /* These structures are ordered by their address. */
-                                       if (jump && jump->addr == word_count) {
-#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 /* !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 /* SLJIT_CONFIG_ARM_V6 */
-                                               jump = jump->next;
-                                       }
-                                       if (label && label->size == word_count) {
-                                               /* code_ptr can be affected above. */
-                                               label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset);
-                                               label->size = (sljit_uw)((code_ptr + 1) - code);
+                                       if (next_min_addr == next_label_size) {
+                                               label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+                                               label->size = (sljit_uw)(code_ptr - code);
                                                label = label->next;
+                                               next_label_size = SLJIT_GET_NEXT_SIZE(label);
                                        }
-                                       if (const_ && const_->addr == word_count) {
+
+                                       /* These structures are ordered by their address. */
+                                       if (next_min_addr == next_jump_addr) {
+                                               if (!(jump->flags & JUMP_MOV_ADDR)) {
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
-                                               const_->addr = (sljit_uw)code_ptr;
+                                                       if (detect_jump_type(jump, code_ptr, code, executable_offset))
+                                                               code_ptr--;
+                                                       jump->addr = (sljit_uw)code_ptr;
 #else /* !SLJIT_CONFIG_ARM_V6 */
-                                               const_->addr = (sljit_uw)(code_ptr - 1);
+                                                       word_count += jump->flags >> JUMP_SIZE_SHIFT;
+                                                       jump->addr = (sljit_uw)code_ptr;
+                                                       if (!detect_jump_type(jump, code_ptr, code, executable_offset)) {
+                                                               code_ptr[2] = code_ptr[0];
+                                                               addr = ((code_ptr[0] & 0xf) << 12);
+                                                               code_ptr[0] = MOVW | addr;
+                                                               code_ptr[1] = MOVT | addr;
+                                                               code_ptr += 2;
+                                                       }
+                                                       SLJIT_ASSERT((sljit_uw)code_ptr - jump->addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins));
 #endif /* SLJIT_CONFIG_ARM_V6 */
+                                               } else {
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+                                                       word_count += jump->flags >> JUMP_SIZE_SHIFT;
+#endif /* SLJIT_CONFIG_ARM_V7 */
+                                                       addr = (sljit_uw)code_ptr;
+                                                       code_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);
+                                                       jump->addr = addr;
+                                               }
+                                               jump = jump->next;
+                                               next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+                                       } else if (next_min_addr == next_const_addr) {
+                                               const_->addr = (sljit_uw)code_ptr;
                                                const_ = const_->next;
+                                               next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
                                        }
-                                       if (put_label && put_label->addr == word_count) {
-                                               SLJIT_ASSERT(put_label->label);
-                                               put_label->addr = (sljit_uw)code_ptr;
-                                               put_label = put_label->next;
-                                       }
-                                       next_addr = compute_next_addr(label, jump, const_, put_label);
+
+                                       SLJIT_GET_NEXT_MIN();
                                }
                                code_ptr++;
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
@@ -879,14 +963,20 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
                                last_pc_patch = code_ptr;
                        }
 #endif /* SLJIT_CONFIG_ARM_V6 */
+                       word_count++;
                } while (buf_ptr < buf_end);
                buf = buf->next;
        } while (buf);
 
+       if (label && label->size == word_count) {
+               label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+               label->size = (sljit_uw)(code_ptr - code);
+               label = label->next;
+       }
+
        SLJIT_ASSERT(!label);
        SLJIT_ASSERT(!jump);
        SLJIT_ASSERT(!const_);
-       SLJIT_ASSERT(!put_label);
 
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
        SLJIT_ASSERT(cpool_size == 0);
@@ -901,7 +991,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
                cpool_current_index = 0;
                while (buf_ptr < buf_end) {
                        if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
-                               SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);
+                               SLJIT_FREE_EXEC(code, exec_allocator_data);
                                compiler->error = SLJIT_ERR_ALLOC_FAILED;
                                return NULL;
                        }
@@ -914,43 +1004,64 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
 
        jump = compiler->jumps;
        while (jump) {
+               addr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
                buf_ptr = (sljit_ins*)jump->addr;
 
-               if (jump->flags & PATCH_B) {
-                       addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);
-                       if (!(jump->flags & JUMP_ADDR)) {
-                               SLJIT_ASSERT(jump->flags & JUMP_LABEL);
-                               SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - addr) <= 0x01ffffff && (sljit_sw)(jump->u.label->addr - addr) >= -0x02000000);
-                               *buf_ptr |= ((jump->u.label->addr - addr) >> 2) & 0x00ffffff;
-                       }
-                       else {
-                               SLJIT_ASSERT((sljit_sw)(jump->u.target - addr) <= 0x01ffffff && (sljit_sw)(jump->u.target - addr) >= -0x02000000);
-                               *buf_ptr |= ((jump->u.target - addr) >> 2) & 0x00ffffff;
-                       }
-               }
-               else if (jump->flags & SLJIT_REWRITABLE_JUMP) {
+               if (jump->flags & JUMP_MOV_ADDR) {
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
-                       jump->addr = (sljit_uw)code_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;
+                       SLJIT_ASSERT((buf_ptr[0] & (sljit_ins)0xffff0000) == 0xe59f0000);
 #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);
+                       SLJIT_ASSERT((buf_ptr[0] & ~(sljit_ins)0xf000) == 0);
 #endif /* SLJIT_CONFIG_ARM_V6 */
+
+                       if (jump->flags & PATCH_B) {
+                               SLJIT_ASSERT((((sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset)) & 0x3) == 0);
+                               diff = ((sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset)) >> 2;
+
+                               SLJIT_ASSERT(diff <= 0xff && diff >= -0xff);
+
+                               addr = ADD;
+                               if (diff < 0) {
+                                       diff = -diff;
+                                       addr = SUB;
+                               }
+
+                               buf_ptr[0] = addr | (buf_ptr[0] & 0xf000) | RN(TMP_PC) | (1 << 25) | (0xf << 8) | (sljit_ins)(diff & 0xff);
+                       } else {
+#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
+                               buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr;
+#else /* !SLJIT_CONFIG_ARM_V6 */
+                               buf_ptr[1] = MOVT | buf_ptr[0] | ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff);
+                               buf_ptr[0] = MOVW | buf_ptr[0] | ((addr << 4) & 0xf0000) | (addr & 0xfff);
+#endif /* SLJIT_CONFIG_ARM_V6 */
+                       }
+               } else if (jump->flags & PATCH_B) {
+                       diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);
+                       SLJIT_ASSERT(diff <= 0x01ffffff && diff >= -0x02000000);
+                       *buf_ptr |= (diff >> 2) & 0x00ffffff;
                } else {
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
                        if (jump->flags & IS_BL)
                                buf_ptr--;
-                       if (*buf_ptr & (1 << 23))
-                               buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
-                       else
-                               buf_ptr += 1;
-                       *buf_ptr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+
+                       if (jump->flags & SLJIT_REWRITABLE_JUMP) {
+                               jump->addr = (sljit_uw)code_ptr;
+                               code_ptr[0] = (sljit_ins)buf_ptr;
+                               code_ptr[1] = *buf_ptr;
+                               set_jump_addr((sljit_uw)code_ptr, executable_offset, addr, 0);
+                               code_ptr += 2;
+                       } else {
+                               if (*buf_ptr & (1 << 23))
+                                       buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
+                               else
+                                       buf_ptr += 1;
+                               *buf_ptr = addr;
+                       }
 #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);
+                       set_jump_addr((sljit_uw)buf_ptr, executable_offset, addr, 0);
 #endif /* SLJIT_CONFIG_ARM_V6 */
                }
+
                jump = jump->next;
        }
 
@@ -967,30 +1078,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
                else
                        buf_ptr += 1;
                /* Set the value again (can be a simple constant). */
-               inline_set_const((sljit_uw)code_ptr, executable_offset, *buf_ptr, 0);
+               set_const_value((sljit_uw)code_ptr, executable_offset, *buf_ptr, 0);
                code_ptr += 2;
 
                const_ = const_->next;
        }
 #endif /* SLJIT_CONFIG_ARM_V6 */
 
-       put_label = compiler->put_labels;
-       while (put_label) {
-               addr = put_label->label->addr;
-               buf_ptr = (sljit_ins*)put_label->addr;
-
-#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 /* !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 /* SLJIT_CONFIG_ARM_V6 */
-               put_label = put_label->next;
-       }
-
-       SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size);
+       SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size);
 
        compiler->error = SLJIT_ERR_COMPILED;
        compiler->executable_offset = executable_offset;
@@ -1113,7 +1208,7 @@ static const sljit_ins data_transfer_insts[16] = {
   /* Inverted immediate. */
 #define INV_IMM                0x02
   /* Source and destination is register. */
-#define MOVE_REG_CONV  0x04
+#define REGISTER_OP    0x04
   /* Unused return value. */
 #define UNUSED_RETURN  0x08
 /* SET_FLAGS must be (1 << 20) as it is also the value of S bit (can be used for optimization). */
@@ -1498,7 +1593,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c
 static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
        sljit_uw dst, sljit_uw src1, sljit_uw src2)
 {
-       sljit_s32 is_masked;
+       sljit_s32 reg, is_masked;
        sljit_uw shift_type;
 
        switch (op) {
@@ -1515,7 +1610,7 @@ 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 (flags & REGISTER_OP)
                        return push_inst(compiler, (op == SLJIT_MOV_U8 ? UXTB : SXTB) | RD(dst) | RM(src2));
 
                if (dst != src2) {
@@ -1527,7 +1622,7 @@ 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 (flags & REGISTER_OP)
                        return push_inst(compiler, (op == SLJIT_MOV_U16 ? UXTH : SXTH) | RD(dst) | RM(src2));
 
                if (dst != src2) {
@@ -1543,11 +1638,11 @@ 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));
+               SLJIT_ASSERT(src1 == TMP_REG1 && src2 != TMP_REG2 && !(flags & ARGS_SWAPPED));
 #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, RSB | SRC2_IMM | RD(TMP_REG2) | RN(src2) | 0));
+               FAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RN(src2) | RM(TMP_REG2)));
+               FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(TMP_REG1)));
                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_V6 */
@@ -1563,9 +1658,9 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
 
        case SLJIT_REV_U16:
        case SLJIT_REV_S16:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED) && src2 != TMP_REG1 && dst != TMP_REG1);
+               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED));
                FAIL_IF(push_inst(compiler, REV16 | RD(dst) | RM(src2)));
-               if (dst == TMP_REG2 || (src2 == TMP_REG2 && op == SLJIT_REV_U16))
+               if (!(flags & REGISTER_OP))
                        return SLJIT_SUCCESS;
                return push_inst(compiler, (op == SLJIT_REV_U16 ? UXTH : SXTH) | RD(dst) | RM(dst));
        case SLJIT_ADD:
@@ -1601,10 +1696,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                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)));
+               reg = dst == TMP_REG1 ? TMP_REG2 : TMP_REG1;
+               FAIL_IF(push_inst(compiler, SMULL | RN(reg) | RD(dst) | RM8(src2) | RM(src1)));
 
                /* cmp TMP_REG1, dst asr #31. */
-               return push_inst(compiler, CMP | SET_FLAGS | RN(TMP_REG1) | RM(dst) | 0xfc0);
+               return push_inst(compiler, CMP | SET_FLAGS | RN(reg) | RM(dst) | 0xfc0);
 
        case SLJIT_AND:
                if ((flags & (UNUSED_RETURN | INV_IMM)) == UNUSED_RETURN)
@@ -1654,6 +1750,9 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                is_masked = 0;
                break;
 
+       case SLJIT_MULADD:
+               return push_inst(compiler, MLA | RN(dst) | RD(dst) | RM8(src2) | RM(src1));
+
        default:
                SLJIT_UNREACHABLE();
                return SLJIT_SUCCESS;
@@ -1973,6 +2072,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
        sljit_s32 dst_reg;
        sljit_s32 src1_reg = 0;
        sljit_s32 src2_reg = 0;
+       sljit_s32 src2_tmp_reg = 0;
        sljit_s32 flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
        sljit_s32 neg_op = 0;
        sljit_u32 imm2;
@@ -1982,7 +2082,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
        if (flags & SET_FLAGS)
                inp_flags &= ~ALLOW_DOUBLE_IMM;
 
-       if (dst == TMP_REG2)
+       if (dst == TMP_REG1)
                flags |= UNUSED_RETURN;
 
        SLJIT_ASSERT(!(inp_flags & ALLOW_INV_IMM) || (inp_flags & ALLOW_IMM));
@@ -2068,17 +2168,6 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                }
        } while(0);
 
-       /* Source 1. */
-       if (FAST_IS_REG(src1))
-               src1_reg = src1;
-       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 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;
-       }
-
        /* Destination. */
        dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
 
@@ -2088,21 +2177,44 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                                inp_flags &= ~SIGNED;
 
                        if (FAST_IS_REG(src2))
-                               return emit_op_mem(compiler, inp_flags, src2, dst, dstw, TMP_REG2);
+                               return emit_op_mem(compiler, inp_flags, src2, dst, dstw, TMP_REG1);
                }
 
                if (FAST_IS_REG(src2) && dst_reg != TMP_REG2)
-                       flags |= MOVE_REG_CONV;
+                       flags |= REGISTER_OP;
+
+               src2_tmp_reg = dst_reg;
+       } else {
+               if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) {
+                       if (!(dst & SLJIT_MEM) && (!(src2 & SLJIT_MEM) || op == SLJIT_REV_S16))
+                               flags |= REGISTER_OP;
+               }
+
+               src2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;
+       }
+
+       if (src2_reg == 0 && (src2 & SLJIT_MEM)) {
+               src2_reg = src2_tmp_reg;
+               FAIL_IF(emit_op_mem(compiler, inp_flags | LOAD_DATA, src2_reg, src2, src2w, TMP_REG1));
+       }
+
+       /* Source 1. */
+       if (FAST_IS_REG(src1))
+               src1_reg = src1;
+       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 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;
        }
 
        /* Source 2. */
        if (src2_reg == 0) {
-               src2_reg = (op <= SLJIT_MOV_P) ? dst_reg : TMP_REG2;
+               src2_reg = src2_tmp_reg;
 
                if (FAST_IS_REG(src2))
                        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 if (!(inp_flags & ALLOW_DOUBLE_IMM))
                        FAIL_IF(load_immediate(compiler, src2_reg, (sljit_uw)src2w));
                else {
@@ -2122,8 +2234,8 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                        }
 
                        if (src2_reg == 0) {
-                               FAIL_IF(load_immediate(compiler, TMP_REG2, (sljit_uw)src2w));
-                               src2_reg = TMP_REG2;
+                               FAIL_IF(load_immediate(compiler, src2_tmp_reg, (sljit_uw)src2w));
+                               src2_reg = src2_tmp_reg;
                        } 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;
@@ -2368,7 +2480,25 @@ 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, TMP_REG1, 0, src1, src1w, src2, src2w);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
+       sljit_s32 dst_reg,
+       sljit_s32 src1, sljit_sw src1w,
+       sljit_s32 src2, sljit_sw src2w)
+{
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
+       ADJUST_LOCAL_OFFSET(src1, src1w);
+       ADJUST_LOCAL_OFFSET(src2, src2w);
+
+       switch (GET_OPCODE(op)) {
+       case SLJIT_MULADD:
+               return emit_op(compiler, op, 0, dst_reg, 0, src1, src1w, src2, src2w);
+       }
+
+       return SLJIT_SUCCESS;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
@@ -2533,8 +2663,8 @@ static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags,
        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_ins)argw & 0x3) << 7)));
-               arg = TMP_REG2;
+               FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (((sljit_ins)argw & 0x3) << 7)));
+               arg = TMP_REG1;
                argw = 0;
        }
 
@@ -2547,25 +2677,25 @@ static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags,
 
                imm = get_imm((sljit_uw)argw & ~(sljit_uw)0x3fc);
                if (imm) {
-                       FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | imm));
-                       return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG2, reg, (argw & 0x3fc) >> 2));
+                       FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | imm));
+                       return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, (argw & 0x3fc) >> 2));
                }
                imm = get_imm((sljit_uw)-argw & ~(sljit_uw)0x3fc);
                if (imm) {
                        argw = -argw;
-                       FAIL_IF(push_inst(compiler, SUB | RD(TMP_REG2) | RN(arg & REG_MASK) | imm));
-                       return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG2, reg, (argw & 0x3fc) >> 2));
+                       FAIL_IF(push_inst(compiler, SUB | RD(TMP_REG1) | RN(arg & REG_MASK) | imm));
+                       return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG1, reg, (argw & 0x3fc) >> 2));
                }
        }
 
        if (arg) {
-               FAIL_IF(load_immediate(compiler, TMP_REG2, (sljit_uw)argw));
-               FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | RM(TMP_REG2)));
+               FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)argw));
+               FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(TMP_REG1)));
        }
        else
-               FAIL_IF(load_immediate(compiler, TMP_REG2, (sljit_uw)argw));
+               FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)argw));
 
-       return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG2, reg, 0));
+       return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, 0));
 }
 
 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
@@ -2675,7 +2805,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
        switch (GET_OPCODE(op)) {
        case SLJIT_MOV_F64:
                if (src != dst_r) {
-                       if (dst_r != TMP_FREG1)
+                       if (!(dst & SLJIT_MEM))
                                FAIL_IF(push_inst(compiler, EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_32, dst_r, src, 0)));
                        else
                                dst_r = src;
@@ -2745,7 +2875,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
                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)
+       if (dst_r != dst)
                FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_32), TMP_FREG1, dst, dstw));
 
        return SLJIT_SUCCESS;
@@ -2974,27 +3104,25 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
        if (type >= SLJIT_FAST_CALL)
                PTR_FAIL_IF(prepare_blx(compiler));
+
+       jump->addr = compiler->size;
        PTR_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)) & ~COND_MASK) | get_cc(compiler, type), 0));
 
-       if (jump->flags & SLJIT_REWRITABLE_JUMP) {
-               jump->addr = compiler->size;
+       if (jump->flags & SLJIT_REWRITABLE_JUMP)
                compiler->patches++;
-       }
 
        if (type >= SLJIT_FAST_CALL) {
                jump->flags |= IS_BL;
+               jump->addr = compiler->size;
                PTR_FAIL_IF(emit_blx(compiler));
        }
-
-       if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
-               jump->addr = compiler->size;
 #else /* !SLJIT_CONFIG_ARM_V6 */
+       jump->addr = compiler->size;
        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;
+       compiler->size += JUMP_MAX_SIZE - 1;
 #endif /* SLJIT_CONFIG_ARM_V6 */
        return jump;
 }
@@ -3264,14 +3392,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
        if (type >= SLJIT_FAST_CALL)
                FAIL_IF(prepare_blx(compiler));
+       jump->addr = compiler->size;
        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)
+       if (type >= SLJIT_FAST_CALL) {
+               jump->addr = compiler->size;
                FAIL_IF(emit_blx(compiler));
+       }
 #else /* !SLJIT_CONFIG_ARM_V6 */
-       FAIL_IF(emit_imm(compiler, TMP_REG1, 0));
+       jump->addr = compiler->size;
        FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)));
+       compiler->size += JUMP_MAX_SIZE - 1;
 #endif /* SLJIT_CONFIG_ARM_V6 */
-       jump->addr = compiler->size;
        return SLJIT_SUCCESS;
 }
 
@@ -3425,7 +3556,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
        }
 
        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));
+               FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, (src2_reg != dst_reg) ? dst_reg : TMP_REG1, src1, src1w, TMP_REG1));
 
                if (src2_reg != dst_reg) {
                        src1 = src2_reg;
@@ -3488,8 +3619,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com
        }
 
        if (src1 & SLJIT_MEM) {
-               FAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w));
-               src1 = TMP_FREG1;
+               FAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) | FPU_LOAD, TMP_FREG2, src1, src1w));
+               src1 = TMP_FREG2;
        }
 
        cc = get_cc(compiler, type & ~SLJIT_32);
@@ -4444,6 +4575,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
        CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
        ADJUST_LOCAL_OFFSET(dst, dstw);
 
+       const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+       PTR_FAIL_IF(!const_);
+       set_const(const_, compiler);
+
        dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
 
 #if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
@@ -4454,22 +4589,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
        PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value));
 #endif /* SLJIT_CONFIG_ARM_V6 */
 
-       const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
-       PTR_FAIL_IF(!const_);
-       set_const(const_, compiler);
-
        if (dst & SLJIT_MEM)
                PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));
        return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
-       struct sljit_put_label *put_label;
+       struct sljit_jump *jump;
        sljit_s32 dst_r;
 
        CHECK_ERROR_PTR();
-       CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+       CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
        ADJUST_LOCAL_OFFSET(dst, dstw);
 
        dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
@@ -4478,24 +4609,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
        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 /* !SLJIT_CONFIG_ARM_V6 */
-       PTR_FAIL_IF(emit_imm(compiler, dst_r, 0));
+       PTR_FAIL_IF(push_inst(compiler, RD(dst_r)));
 #endif /* SLJIT_CONFIG_ARM_V6 */
 
-       put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
-       PTR_FAIL_IF(!put_label);
-       set_put_label(put_label, compiler, 0);
+       jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+       PTR_FAIL_IF(!jump);
+       set_mov_addr(jump, compiler, 1);
+
+#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+       compiler->size += 1;
+#endif /* SLJIT_CONFIG_ARM_V7 */
 
        if (dst & SLJIT_MEM)
                PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));
-       return put_label;
+       return jump;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
 {
-       inline_set_jump_addr(addr, executable_offset, new_target, 1);
+       set_jump_addr(addr, executable_offset, new_target, 1);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
 {
-       inline_set_const(addr, executable_offset, (sljit_uw)new_constant, 1);
+       set_const_value(addr, executable_offset, (sljit_uw)new_constant, 1);
 }
index b268582f42ceded3829a59c22435df91c9fcca36..5331ebdf42962270cb21d4d3fdbaae6b6db50530 100644 (file)
@@ -71,6 +71,8 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
 #define ADD            0x8b000000
 #define ADDE           0x8b200000
 #define ADDI           0x91000000
+#define ADR            0x10000000
+#define ADRP           0x90000000
 #define AND            0x8a000000
 #define ANDI           0x92000000
 #define AND_v          0x0e201c00
@@ -202,77 +204,263 @@ static SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler,
        return push_inst(compiler, MOVK | RD(dst) | ((sljit_ins)(imm >> 48) << 5) | (3 << 21));
 }
 
-static SLJIT_INLINE sljit_sw detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
+static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
 {
        sljit_sw diff;
        sljit_uw target_addr;
 
-       if (jump->flags & SLJIT_REWRITABLE_JUMP) {
-               jump->flags |= PATCH_ABS64;
-               return 0;
-       }
+       if (jump->flags & SLJIT_REWRITABLE_JUMP)
+               goto exit;
 
        if (jump->flags & JUMP_ADDR)
                target_addr = jump->u.target;
        else {
-               SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+               SLJIT_ASSERT(jump->u.label != NULL);
                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 - executable_offset;
 
        if (jump->flags & IS_COND) {
                diff += SSIZE_OF(ins);
                if (diff <= 0xfffff && diff >= -0x100000) {
-                       code_ptr[-5] ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1;
-                       jump->addr -= sizeof(sljit_ins);
+                       *(--code_ptr) ^= (jump->flags & IS_CBZ) ? (0x1 << 24) : 0x1;
                        jump->flags |= PATCH_COND;
-                       return 5;
+                       jump->addr -= sizeof(sljit_ins);
+                       return code_ptr;
                }
                diff -= SSIZE_OF(ins);
        }
 
        if (diff <= 0x7ffffff && diff >= -0x8000000) {
+               if (jump->flags & IS_COND)
+                       code_ptr[-1] -= (4 << 5);
                jump->flags |= PATCH_B;
-               return 4;
+               return code_ptr;
        }
 
        if (target_addr < 0x100000000l) {
                if (jump->flags & IS_COND)
-                       code_ptr[-5] -= (2 << 5);
-               code_ptr[-2] = code_ptr[0];
-               return 2;
+                       code_ptr[-1] -= (2 << 5);
+               code_ptr[2] = code_ptr[0];
+               return code_ptr + 2;
+       }
+
+       if (diff <= 0xfffff000l && diff >= -0x100000000l) {
+               if (jump->flags & IS_COND)
+                       code_ptr[-1] -= (2 << 5);
+               jump->flags |= PATCH_B32;
+               code_ptr[2] = code_ptr[0];
+               return code_ptr + 2;
        }
 
        if (target_addr < 0x1000000000000l) {
                if (jump->flags & IS_COND)
-                       code_ptr[-5] -= (1 << 5);
+                       code_ptr[-1] -= (1 << 5);
                jump->flags |= PATCH_ABS48;
-               code_ptr[-1] = code_ptr[0];
-               return 1;
+               code_ptr[3] = code_ptr[0];
+               return code_ptr + 3;
        }
 
+exit:
        jump->flags |= PATCH_ABS64;
-       return 0;
+       code_ptr[4] = code_ptr[0];
+       return code_ptr + 4;
 }
 
-static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
+static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
 {
-       if (max_label < 0x100000000l) {
-               put_label->flags = 0;
-               return 2;
+       sljit_uw addr;
+       sljit_sw diff;
+       SLJIT_UNUSED_ARG(executable_offset);
+
+       SLJIT_ASSERT(jump->flags < ((sljit_uw)4 << JUMP_SIZE_SHIFT));
+       if (jump->flags & JUMP_ADDR)
+               addr = jump->u.target;
+       else
+               addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);
+
+       diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+       if (diff <= 0xfffff && diff >= -0x100000) {
+               jump->flags |= PATCH_B;
+               return 0;
        }
 
-       if (max_label < 0x1000000000000l) {
-               put_label->flags = 1;
+       if (diff <= 0xfffff000l && diff >= -0x100000000l) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));
+               jump->flags |= PATCH_B32;
                return 1;
        }
 
-       put_label->flags = 2;
-       return 0;
+       if (addr < 0x100000000l) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));
+               return 1;
+       }
+
+       if (addr < 0x1000000000000l) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)2 << JUMP_SIZE_SHIFT));
+               jump->flags |= PATCH_ABS48;
+               return 2;
+       }
+
+       SLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));
+       jump->flags |= PATCH_ABS64;
+       return 3;
+}
+
+static SLJIT_INLINE void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset)
+{
+       sljit_sw addr = (sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr);
+       sljit_ins* buf_ptr = (sljit_ins*)jump->addr;
+       sljit_u32 dst;
+       SLJIT_UNUSED_ARG(executable_offset);
+
+       if (!(jump->flags & JUMP_MOV_ADDR)) {
+               if (jump->flags & PATCH_COND) {
+                       addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
+                       SLJIT_ASSERT(addr <= 0x3ffff && addr >= -0x40000);
+                       buf_ptr[0] = (buf_ptr[0] & ~(sljit_ins)0xffffe0) | (sljit_ins)((addr & 0x7ffff) << 5);
+                       return;
+               }
+
+               if (jump->flags & PATCH_B) {
+                       addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
+                       SLJIT_ASSERT(addr <= 0x1ffffff && addr >= -0x2000000);
+                       buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (sljit_ins)(addr & 0x3ffffff);
+                       return;
+               }
+
+               dst = (buf_ptr[0] >> 5) & 0x1f;
+
+               if (jump->flags & PATCH_B32) {
+                       addr -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset) & ~(sljit_sw)0xfff;
+                       SLJIT_ASSERT(addr <= 0xfffff000l && addr >= -0x100000000l);
+                       buf_ptr[0] = ADRP | (((sljit_ins)(addr >> 12) & 0x3) << 29) | (((sljit_ins)(addr >> 14) & 0x7ffff) << 5) | dst;
+                       buf_ptr[1] = ADDI | dst | (dst << 5) | ((sljit_ins)(addr & 0xfff) << 10);
+                       return;
+               }
+       } else {
+               dst = *buf_ptr;
+
+               if (jump->flags & PATCH_B) {
+                       addr -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
+                       SLJIT_ASSERT(addr <= 0xfffff && addr >= -0x100000);
+                       buf_ptr[0] = ADR | (((sljit_ins)addr & 0x3) << 29) | (((sljit_ins)(addr >> 2) & 0x7ffff) << 5) | dst;
+                       return;
+               }
+
+               if (jump->flags & PATCH_B32) {
+                       addr -= ((sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) & ~(sljit_sw)0xfff;
+                       SLJIT_ASSERT(addr <= 0xffffffffl && addr >= -0x100000000l);
+                       buf_ptr[0] = ADRP | (((sljit_ins)(addr >> 12) & 0x3) << 29) | (((sljit_ins)(addr >> 14) & 0x7ffff) << 5) | dst;
+                       buf_ptr[1] = ADDI | dst | (dst << 5) | ((sljit_ins)(addr & 0xfff) << 10);
+                       return;
+               }
+       }
+
+       SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || (sljit_uw)addr <= (sljit_uw)0xffffffff);
+       SLJIT_ASSERT((jump->flags & PATCH_ABS64) || (sljit_uw)addr <= (sljit_uw)0xffffffffffff);
+
+       buf_ptr[0] = MOVZ | (((sljit_ins)addr & 0xffff) << 5) | dst;
+       buf_ptr[1] = MOVK | (((sljit_ins)(addr >> 16) & 0xffff) << 5) | (1 << 21) | dst;
+       if (jump->flags & (PATCH_ABS48 | PATCH_ABS64))
+               buf_ptr[2] = MOVK | (((sljit_ins)(addr >> 32) & 0xffff) << 5) | (2 << 21) | dst;
+
+       if (jump->flags & PATCH_ABS64)
+               buf_ptr[3] = MOVK | ((sljit_ins)((sljit_uw)addr >> 48) << 5) | (3 << 21) | dst;
+}
+
+static void reduce_code_size(struct sljit_compiler *compiler)
+{
+       struct sljit_label *label;
+       struct sljit_jump *jump;
+       struct sljit_const *const_;
+       SLJIT_NEXT_DEFINE_TYPES;
+       sljit_uw total_size;
+       sljit_uw size_reduce = 0;
+       sljit_sw diff;
+
+       label = compiler->labels;
+       jump = compiler->jumps;
+       const_ = compiler->consts;
+       SLJIT_NEXT_INIT_TYPES();
+
+       while (1) {
+               SLJIT_GET_NEXT_MIN();
+
+               if (next_min_addr == SLJIT_MAX_ADDRESS)
+                       break;
+
+               if (next_min_addr == next_label_size) {
+                       label->size -= size_reduce;
+
+                       label = label->next;
+                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
+               }
+
+               if (next_min_addr == next_const_addr) {
+                       const_->addr -= size_reduce;
+                       const_ = const_->next;
+                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
+                       continue;
+               }
+
+               if (next_min_addr != next_jump_addr)
+                       continue;
+
+               jump->addr -= size_reduce;
+               if (!(jump->flags & JUMP_MOV_ADDR)) {
+                       total_size = JUMP_MAX_SIZE;
+
+                       if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {
+                               if (jump->flags & JUMP_ADDR) {
+                                       if (jump->u.target < 0x100000000l)
+                                               total_size = 3;
+                                       else if (jump->u.target < 0x1000000000000l)
+                                               total_size = 4;
+                               } else {
+                                       /* Unit size: instruction. */
+                                       diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;
+
+                                       if ((jump->flags & IS_COND) && (diff + 1) <= (0xfffff / SSIZE_OF(ins)) && (diff + 1) >= (-0x100000 / SSIZE_OF(ins)))
+                                               total_size = 0;
+                                       else if (diff <= (0x7ffffff / SSIZE_OF(ins)) && diff >= (-0x8000000 / SSIZE_OF(ins)))
+                                               total_size = 1;
+                                       else if (diff <= (0xfffff000l / SSIZE_OF(ins)) && diff >= (-0x100000000l / SSIZE_OF(ins)))
+                                               total_size = 3;
+                               }
+                       }
+
+                       size_reduce += JUMP_MAX_SIZE - total_size;
+               } else {
+                       /* Real size minus 1. Unit size: instruction. */
+                       total_size = 3;
+
+                       if (!(jump->flags & JUMP_ADDR)) {
+                               diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;
+
+                               if (diff <= (0xfffff / SSIZE_OF(ins)) && diff >= (-0x100000 / SSIZE_OF(ins)))
+                                       total_size = 0;
+                               else if (diff <= (0xfffff000l / SSIZE_OF(ins)) && diff >= (-0x100000000l / SSIZE_OF(ins)))
+                                       total_size = 1;
+                       } else if (jump->u.target < 0x100000000l)
+                               total_size = 1;
+                       else if (jump->u.target < 0x1000000000000l)
+                               total_size = 2;
+
+                       size_reduce += 3 - total_size;
+               }
+
+               jump->flags |= total_size << JUMP_SIZE_SHIFT;
+               jump = jump->next;
+               next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+       }
+
+       compiler->size -= size_reduce;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
 {
        struct sljit_memory_fragment *buf;
        sljit_ins *code;
@@ -280,67 +468,73 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        sljit_ins *buf_ptr;
        sljit_ins *buf_end;
        sljit_uw word_count;
-       sljit_uw next_addr;
+       SLJIT_NEXT_DEFINE_TYPES;
        sljit_sw executable_offset;
        sljit_sw addr;
-       sljit_u32 dst;
 
        struct sljit_label *label;
        struct sljit_jump *jump;
        struct sljit_const *const_;
-       struct sljit_put_label *put_label;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_generate_code(compiler));
-       reverse_buf(compiler);
 
-       code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
+       reduce_code_size(compiler);
+
+       code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
        PTR_FAIL_WITH_EXEC_IF(code);
+
+       reverse_buf(compiler);
        buf = compiler->buf;
 
        code_ptr = code;
        word_count = 0;
-       next_addr = 0;
-       executable_offset = SLJIT_EXEC_OFFSET(code);
-
        label = compiler->labels;
        jump = compiler->jumps;
        const_ = compiler->consts;
-       put_label = compiler->put_labels;
+       SLJIT_NEXT_INIT_TYPES();
+       SLJIT_GET_NEXT_MIN();
 
        do {
                buf_ptr = (sljit_ins*)buf->memory;
                buf_end = buf_ptr + (buf->used_size >> 2);
                do {
                        *code_ptr = *buf_ptr++;
-                       if (next_addr == word_count) {
+                       if (next_min_addr == word_count) {
                                SLJIT_ASSERT(!label || label->size >= word_count);
                                SLJIT_ASSERT(!jump || jump->addr >= word_count);
                                SLJIT_ASSERT(!const_ || const_->addr >= word_count);
-                               SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
 
                                /* These structures are ordered by their address. */
-                               if (label && label->size == word_count) {
-                                       label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+                               if (next_min_addr == next_label_size) {
+                                       label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
                                        label->size = (sljit_uw)(code_ptr - code);
                                        label = label->next;
+                                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
                                }
-                               if (jump && jump->addr == word_count) {
-                                               jump->addr = (sljit_uw)(code_ptr - 4);
-                                               code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
-                                               jump = jump->next;
-                               }
-                               if (const_ && const_->addr == word_count) {
+
+                               if (next_min_addr == next_jump_addr) {
+                                       if (!(jump->flags & JUMP_MOV_ADDR)) {
+                                               word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT);
+                                               jump->addr = (sljit_uw)code_ptr;
+                                               code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
+                                               SLJIT_ASSERT((jump->flags & PATCH_COND) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins)));
+                                       } else {
+                                               word_count += jump->flags >> JUMP_SIZE_SHIFT;
+                                               addr = (sljit_sw)code_ptr;
+                                               code_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);
+                                               jump->addr = (sljit_uw)addr;
+                                       }
+
+                                       jump = jump->next;
+                                       next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+                               } else if (next_min_addr == next_const_addr) {
                                        const_->addr = (sljit_uw)code_ptr;
                                        const_ = const_->next;
+                                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
                                }
-                               if (put_label && put_label->addr == word_count) {
-                                       SLJIT_ASSERT(put_label->label);
-                                       put_label->addr = (sljit_uw)(code_ptr - 3);
-                                       code_ptr -= put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
-                                       put_label = put_label->next;
-                               }
-                               next_addr = compute_next_addr(label, jump, const_, put_label);
+
+                               SLJIT_GET_NEXT_MIN();
                        }
                        code_ptr++;
                        word_count++;
@@ -350,7 +544,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        } while (buf);
 
        if (label && label->size == word_count) {
-               label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+               label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
                label->size = (sljit_uw)(code_ptr - code);
                label = label->next;
        }
@@ -358,61 +552,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        SLJIT_ASSERT(!label);
        SLJIT_ASSERT(!jump);
        SLJIT_ASSERT(!const_);
-       SLJIT_ASSERT(!put_label);
        SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
 
        jump = compiler->jumps;
        while (jump) {
-               do {
-                       addr = (sljit_sw)((jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target);
-                       buf_ptr = (sljit_ins *)jump->addr;
-
-                       if (jump->flags & PATCH_B) {
-                               addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
-                               SLJIT_ASSERT(addr <= 0x1ffffff && addr >= -0x2000000);
-                               buf_ptr[0] = ((jump->flags & IS_BL) ? BL : B) | (sljit_ins)(addr & 0x3ffffff);
-                               if (jump->flags & IS_COND)
-                                       buf_ptr[-1] -= (4 << 5);
-                               break;
-                       }
-                       if (jump->flags & PATCH_COND) {
-                               addr = (addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset)) >> 2;
-                               SLJIT_ASSERT(addr <= 0x3ffff && addr >= -0x40000);
-                               buf_ptr[0] = (buf_ptr[0] & ~(sljit_ins)0xffffe0) | (sljit_ins)((addr & 0x7ffff) << 5);
-                               break;
-                       }
-
-                       SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || (sljit_uw)addr <= (sljit_uw)0xffffffff);
-                       SLJIT_ASSERT((jump->flags & PATCH_ABS64) || (sljit_uw)addr <= (sljit_uw)0xffffffffffff);
-
-                       dst = buf_ptr[0] & 0x1f;
-                       buf_ptr[0] = MOVZ | dst | (((sljit_ins)addr & 0xffff) << 5);
-                       buf_ptr[1] = MOVK | dst | (((sljit_ins)(addr >> 16) & 0xffff) << 5) | (1 << 21);
-                       if (jump->flags & (PATCH_ABS48 | PATCH_ABS64))
-                               buf_ptr[2] = MOVK | dst | (((sljit_ins)(addr >> 32) & 0xffff) << 5) | (2 << 21);
-                       if (jump->flags & PATCH_ABS64)
-                               buf_ptr[3] = MOVK | dst | ((sljit_ins)(addr >> 48) << 5) | (3 << 21);
-               } while (0);
+               generate_jump_or_mov_addr(jump, executable_offset);
                jump = jump->next;
        }
 
-       put_label = compiler->put_labels;
-       while (put_label) {
-               addr = (sljit_sw)put_label->label->addr;
-               buf_ptr = (sljit_ins*)put_label->addr;
-
-               buf_ptr[0] |= ((sljit_ins)addr & 0xffff) << 5;
-               buf_ptr[1] |= ((sljit_ins)(addr >> 16) & 0xffff) << 5;
-
-               if (put_label->flags >= 1)
-                       buf_ptr[2] |= ((sljit_ins)(addr >> 32) & 0xffff) << 5;
-
-               if (put_label->flags >= 2)
-                       buf_ptr[3] |= (sljit_ins)(addr >> 48) << 5;
-
-               put_label = put_label->next;
-       }
-
        compiler->error = SLJIT_ERR_COMPILED;
        compiler->executable_offset = executable_offset;
        compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
@@ -693,7 +840,6 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
                imm = (flags & ARG2_IMM) ? arg2 : arg1;
 
                switch (op) {
-               case SLJIT_MUL:
                case SLJIT_CLZ:
                case SLJIT_CTZ:
                case SLJIT_REV:
@@ -703,6 +849,8 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
                case SLJIT_REV_S32:
                case SLJIT_ADDC:
                case SLJIT_SUBC:
+               case SLJIT_MUL:
+               case SLJIT_MULADD:
                        /* No form with immediate operand (except imm 0, which
                        is represented by a ZERO register). */
                        break;
@@ -957,6 +1105,9 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
                /* fallthrough */
        case SLJIT_ROTR:
                return push_inst(compiler, (RORV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
+       case SLJIT_MULADD:
+               compiler->status_flags_state = 0;
+               return push_inst(compiler, (MADD ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2) | RT2(dst));
        default:
                SLJIT_UNREACHABLE();
                return SLJIT_SUCCESS;
@@ -1031,14 +1182,20 @@ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, s
        if (argw <= 0xff && argw >= -0x100)
                return push_inst(compiler, STURBI | type | RT(reg) | RN(arg) | (((sljit_ins)argw & 0x1ff) << 12));
 
-       if (argw >= 0) {
-               if (argw <= 0xfff0ff && ((argw + 0x100) & 0xfff) <= 0x1ff) {
+       if (((argw + 0x100) & 0xfff) <= 0x1ff && argw <= 0xfff0ff && argw >= -0xfff100) {
+               if (argw >= 0) {
+                       if (argw & 0x100)
+                               argw += 0x1000;
+
                        FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(tmp_reg) | RN(arg) | (((sljit_ins)argw >> 12) << 10)));
                        return push_inst(compiler, STURBI | type | RT(reg) | RN(tmp_reg) | (((sljit_ins)argw & 0x1ff) << 12));
+               } else {
+                       if (!(argw & 0x100))
+                               argw -= 0x1000;
+
+                       FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(tmp_reg) | RN(arg) | (((sljit_ins)-argw >> 12) << 10)));
+                       return push_inst(compiler, STURBI | type | RT(reg) | RN(tmp_reg) | (((sljit_ins)argw & 0x1ff) << 12));
                }
-       } else if (argw >= -0xfff100 && ((-argw + 0xff) & 0xfff) <= 0x1ff) {
-               FAIL_IF(push_inst(compiler, SUBI | (1 << 22) | RD(tmp_reg) | RN(arg) | (((sljit_ins)-argw >> 12) << 10)));
-               return push_inst(compiler, STURBI | type | RT(reg) | RN(tmp_reg) | (((sljit_ins)argw & 0x1ff) << 12));
        }
 
        FAIL_IF(load_immediate(compiler, tmp_reg, argw));
@@ -1422,7 +1579,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
        op = GET_OPCODE(op);
        if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
                /* Both operands are registers. */
-               if (dst_r != TMP_REG1 && FAST_IS_REG(src))
+               if (FAST_IS_REG(dst) && FAST_IS_REG(src))
                        return emit_op_imm(compiler, op | ((op_flags & SLJIT_32) ? INT_OP : 0), dst_r, TMP_REG1, src);
 
                switch (op) {
@@ -1472,7 +1629,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
                else if (!(src & SLJIT_MEM))
                        dst_r = src;
                else
-                       FAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, src, srcw, TMP_REG1));
+                       FAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, src, srcw, TMP_REG2));
 
                if (dst & SLJIT_MEM)
                        return emit_op_mem(compiler, mem_flags | STORE, dst_r, dst, dstw, TMP_REG2);
@@ -1534,7 +1691,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
                mem_flags = INT_SIZE;
        }
 
-       if (dst == TMP_REG1)
+       if (dst == TMP_REG2)
                flags |= UNUSED_RETURN;
 
        if (src1 & SLJIT_MEM) {
@@ -1572,7 +1729,24 @@ 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_REG1, 0, src1, src1w, src2, src2w);
+       return sljit_emit_op2(compiler, op, TMP_REG2, 0, src1, src1w, src2, src2w);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
+       sljit_s32 dst_reg,
+       sljit_s32 src1, sljit_sw src1w,
+       sljit_s32 src2, sljit_sw src2w)
+{
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
+
+       switch (GET_OPCODE(op)) {
+       case SLJIT_MULADD:
+               SLJIT_SKIP_CHECKS(compiler);
+               return sljit_emit_op2(compiler, op, dst_reg, 0, src1, src1w, src2, src2w);
+       }
+
+       return SLJIT_SUCCESS;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
@@ -1753,18 +1927,18 @@ static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags,
                        return push_inst(compiler, STR_FR | type | VT(reg)
                                | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | (argw ? (1 << 12) : 0));
 
-               FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG1) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_ins)argw << 10)));
-               return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG1));
+               FAIL_IF(push_inst(compiler, ADD | RD(TMP_REG2) | RN(arg & REG_MASK) | RM(OFFS_REG(arg)) | ((sljit_ins)argw << 10)));
+               return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG2));
        }
 
        arg &= REG_MASK;
 
        if (!arg) {
-               FAIL_IF(load_immediate(compiler, TMP_REG1, argw & ~(0xfff << shift)));
+               FAIL_IF(load_immediate(compiler, TMP_REG2, argw & ~(0xfff << shift)));
 
                argw = (argw >> shift) & 0xfff;
 
-               return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG1) | ((sljit_ins)argw << 10));
+               return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG2) | ((sljit_ins)argw << 10));
        }
 
        if (argw >= 0 && (argw & ((1 << shift) - 1)) == 0) {
@@ -1772,18 +1946,18 @@ static sljit_s32 emit_fop_mem(struct sljit_compiler *compiler, sljit_s32 flags,
                        return push_inst(compiler, STR_FI | type | VT(reg) | RN(arg) | ((sljit_ins)argw << (10 - shift)));
 
                if (argw <= 0xffffff) {
-                       FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(TMP_REG1) | RN(arg) | (((sljit_ins)argw >> 12) << 10)));
+                       FAIL_IF(push_inst(compiler, ADDI | (1 << 22) | RD(TMP_REG2) | RN(arg) | (((sljit_ins)argw >> 12) << 10)));
 
                        argw = ((argw & 0xfff) >> shift);
-                       return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG1) | ((sljit_ins)argw << 10));
+                       return push_inst(compiler, STR_FI | type | VT(reg) | RN(TMP_REG2) | ((sljit_ins)argw << 10));
                }
        }
 
        if (argw <= 255 && argw >= -256)
                return push_inst(compiler, STUR_FI | type | VT(reg) | RN(arg) | (((sljit_ins)argw & 0x1ff) << 12));
 
-       FAIL_IF(load_immediate(compiler, TMP_REG1, argw));
-       return push_inst(compiler, STR_FR | type | VT(reg) | RN(arg) | RM(TMP_REG1));
+       FAIL_IF(load_immediate(compiler, TMP_REG2, argw));
+       return push_inst(compiler, STR_FR | type | VT(reg) | RN(arg) | RM(TMP_REG2));
 }
 
 static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_compiler *compiler, sljit_s32 op,
@@ -1910,7 +2084,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
        switch (GET_OPCODE(op)) {
        case SLJIT_MOV_F64:
                if (src != dst_r) {
-                       if (dst_r != TMP_FREG1)
+                       if (!(dst & SLJIT_MEM))
                                FAIL_IF(push_inst(compiler, (FMOV ^ inv_bits) | VD(dst_r) | VN(src)));
                        else
                                dst_r = src;
@@ -2180,14 +2354,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
        if (type < SLJIT_JUMP) {
                jump->flags |= IS_COND;
                PTR_FAIL_IF(push_inst(compiler, B_CC | (6 << 5) | get_cc(compiler, type)));
-       }
-       else if (type >= SLJIT_FAST_CALL)
+       } else if (type >= SLJIT_FAST_CALL)
                jump->flags |= IS_BL;
 
-       PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
        jump->addr = compiler->size;
-       PTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1)));
+       PTR_FAIL_IF(push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG2)));
 
+       /* Maximum number of instructions required for generating a constant. */
+       compiler->size += JUMP_MAX_SIZE - 1;
        return jump;
 }
 
@@ -2236,9 +2410,11 @@ static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compi
                inv_bits |= 1 << 24;
 
        PTR_FAIL_IF(push_inst(compiler, (CBZ ^ inv_bits) | (6 << 5) | RT(src)));
-       PTR_FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
        jump->addr = compiler->size;
-       PTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG1)));
+       PTR_FAIL_IF(push_inst(compiler, BR | RN(TMP_REG2)));
+
+       /* Maximum number of instructions required for generating a constant. */
+       compiler->size += JUMP_MAX_SIZE - 1;
        return jump;
 }
 
@@ -2252,8 +2428,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
        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));
-                       src = TMP_REG1;
+                       FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2));
+                       src = TMP_REG2;
                }
                return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(src));
        }
@@ -2264,9 +2440,10 @@ 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;
 
-       FAIL_IF(emit_imm64_const(compiler, TMP_REG1, 0));
        jump->addr = compiler->size;
-       return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG1));
+       /* Maximum number of instructions required for generating a constant. */
+       compiler->size += JUMP_MAX_SIZE - 1;
+       return push_inst(compiler, ((type >= SLJIT_FAST_CALL) ? BLR : BR) | RN(TMP_REG2));
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
@@ -2314,7 +2491,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
        if (GET_OPCODE(op) < SLJIT_ADD) {
                FAIL_IF(push_inst(compiler, CSINC | (cc << 12) | RD(dst_r) | RN(TMP_ZERO) | RM(TMP_ZERO)));
 
-               if (dst_r == TMP_REG1) {
+               if (dst & SLJIT_MEM) {
                        mem_flags = (GET_OPCODE(op) == SLJIT_MOV ? WORD_SIZE : INT_SIZE) | STORE;
                        return emit_op_mem(compiler, mem_flags, TMP_REG1, dst, dstw, TMP_REG2);
                }
@@ -2361,11 +2538,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
        if (src1 == SLJIT_IMM) {
                if (type & SLJIT_32)
                        src1w = (sljit_s32)src1w;
-               FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
-               src1 = TMP_REG1;
+               FAIL_IF(load_immediate(compiler, TMP_REG2, src1w));
+               src1 = TMP_REG2;
        } else if (src1 & SLJIT_MEM) {
-               FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG2));
-               src1 = TMP_REG1;
+               FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src1, src1w, TMP_REG2));
+               src1 = TMP_REG2;
        }
 
        cc = get_cc(compiler, type & ~SLJIT_32);
@@ -2386,8 +2563,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com
        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;
+               FAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) ? INT_SIZE : WORD_SIZE, TMP_FREG2, src1, src1w));
+               src1 = TMP_FREG2;
        }
 
        cc = get_cc(compiler, type & ~SLJIT_32);
@@ -2554,13 +2731,13 @@ static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, slj
        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));
+               *mem_ptr = TMP_REG2;
+               return push_inst(compiler, ADD | RD(TMP_REG2) | 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_ptr = TMP_REG2;
+               return load_immediate(compiler, TMP_REG2, memw);
        }
 
        mem &= REG_MASK;
@@ -2570,11 +2747,11 @@ static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, slj
                return SLJIT_SUCCESS;
        }
 
-       *mem_ptr = TMP_REG1;
+       *mem_ptr = TMP_REG2;
 
        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));
+               FAIL_IF(load_immediate(compiler, TMP_REG2, memw));
+               return push_inst(compiler, ADD | RD(TMP_REG2) | RN(TMP_REG2) | RM(mem));
        }
 
        ins = ADDI;
@@ -2585,16 +2762,16 @@ static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, slj
        }
 
        if (memw > 0xfff) {
-               FAIL_IF(push_inst(compiler, ins | (1 << 22) | RD(TMP_REG1) | RN(mem) | ((sljit_ins)(memw >> 12) << 10)));
+               FAIL_IF(push_inst(compiler, ins | (1 << 22) | RD(TMP_REG2) | RN(mem) | ((sljit_ins)(memw >> 12) << 10)));
 
                memw &= 0xfff;
                if (memw == 0)
                        return SLJIT_SUCCESS;
 
-               mem = TMP_REG1;
+               mem = TMP_REG2;
        }
 
-       return push_inst(compiler, ins | RD(TMP_REG1) | RN(mem) | ((sljit_ins)memw << 10));
+       return push_inst(compiler, ins | RD(TMP_REG2) | RN(mem) | ((sljit_ins)memw << 10));
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *compiler, sljit_s32 type,
@@ -2802,8 +2979,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil
                        return push_inst(compiler, MOVI | imm | VD(freg));
                }
 
-               FAIL_IF(load_immediate(compiler, TMP_REG1, srcw));
-               src = TMP_REG1;
+               FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
+               src = TMP_REG2;
        }
 
        return push_inst(compiler, DUP_g | ins | VD(freg) | RN(src));
@@ -2872,8 +3049,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile
                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;
+               FAIL_IF(load_immediate(compiler, TMP_REG2, srcdstw));
+               srcdst = TMP_REG2;
        }
 
        if (type & SLJIT_SIMD_STORE) {
@@ -3030,7 +3207,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c
 
        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;
+       dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
        ins = (0x1 << 16);
 
        if (reg_size == 4 && elem_size == 0) {
@@ -3040,8 +3217,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c
 
        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);
+       if (dst_r == TMP_REG2)
+               return emit_op_mem(compiler, STORE | ((type & SLJIT_32) ? INT_SIZE : WORD_SIZE), TMP_REG2, dst, dstw, TMP_REG1);
 
        return SLJIT_SUCCESS;
 }
@@ -3264,26 +3441,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
        return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
-       struct sljit_put_label *put_label;
+       struct sljit_jump *jump;
        sljit_s32 dst_r;
 
        CHECK_ERROR_PTR();
-       CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+       CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
        ADJUST_LOCAL_OFFSET(dst, dstw);
 
        dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-       PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, 0));
+       PTR_FAIL_IF(push_inst(compiler, RD(dst_r)));
 
-       put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
-       PTR_FAIL_IF(!put_label);
-       set_put_label(put_label, compiler, 1);
+       jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+       PTR_FAIL_IF(!jump);
+       set_mov_addr(jump, compiler, 1);
+
+       compiler->size += 3;
 
        if (dst & SLJIT_MEM)
                PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
 
-       return put_label;
+       return jump;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
index c27c50ddb3a011f934bb0583285ba8e813f0f28a..799954a85996ff0fadff1254e8c93cb362fd7199 100644 (file)
@@ -157,6 +157,7 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1)
 #define LSRSI          0x0800
 #define LSR_W          0xfa20f000
 #define LSR_WI         0xea4f0010
+#define MLA            0xfb000000
 #define MOV            0x4600
 #define MOVS           0x0000
 #define MOVSI          0x2000
@@ -292,7 +293,7 @@ static sljit_s32 push_inst32(struct sljit_compiler *compiler, sljit_ins inst)
        return SLJIT_SUCCESS;
 }
 
-static SLJIT_INLINE sljit_s32 emit_imm32_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
+static sljit_s32 emit_imm32_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
 {
        FAIL_IF(push_inst32(compiler, MOVW | RD4(dst)
                | COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
@@ -300,137 +301,262 @@ static SLJIT_INLINE sljit_s32 emit_imm32_const(struct sljit_compiler *compiler,
                | COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
 }
 
-static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm)
+/* Dst must be in bits[11-8] */
+static void set_imm32_const(sljit_u16 *inst, sljit_ins dst, sljit_uw new_imm)
 {
-       sljit_ins dst = inst[1] & 0x0f00;
-       SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00));
        inst[0] = (sljit_u16)((MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1));
        inst[1] = (sljit_u16)(dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff));
        inst[2] = (sljit_u16)((MOVT >> 16) | COPY_BITS(new_imm, 12 + 16, 0, 4) | COPY_BITS(new_imm, 11 + 16, 10, 1));
        inst[3] = (sljit_u16)(dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16));
 }
 
-static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)
+static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm)
+{
+       sljit_ins dst = inst[1] & 0x0f00;
+       SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00));
+       set_imm32_const(inst, dst, new_imm);
+}
+
+static SLJIT_INLINE sljit_u16* detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)
 {
        sljit_sw diff;
 
        if (jump->flags & SLJIT_REWRITABLE_JUMP)
-               return 0;
+               goto exit;
 
        if (jump->flags & JUMP_ADDR) {
                /* Branch to ARM code is not optimized yet. */
                if (!(jump->u.target & 0x1))
-                       return 0;
-               diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset) >> 1;
-       }
-       else {
-               SLJIT_ASSERT(jump->flags & JUMP_LABEL);
-               diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)) >> 1;
+                       goto exit;
+               diff = (sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2) - executable_offset;
+       } else {
+               SLJIT_ASSERT(jump->u.label != NULL);
+               diff = (sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2);
        }
 
        if (jump->flags & IS_COND) {
                SLJIT_ASSERT(!(jump->flags & IS_BL));
-               if (diff <= 127 && diff >= -128) {
+               /* Size of the prefix IT instruction. */
+               diff += SSIZE_OF(u16);
+               if (diff <= 0xff && diff >= -0x100) {
                        jump->flags |= PATCH_TYPE1;
-                       return 5;
+                       jump->addr = (sljit_uw)(code_ptr - 1);
+                       return code_ptr - 1;
                }
-               if (diff <= 524287 && diff >= -524288) {
+               if (diff <= 0xfffff && diff >= -0x100000) {
                        jump->flags |= PATCH_TYPE2;
-                       return 4;
+                       jump->addr = (sljit_uw)(code_ptr - 1);
+                       return code_ptr;
                }
-               /* +1 comes from the prefix IT instruction. */
-               diff--;
-               if (diff <= 8388607 && diff >= -8388608) {
-                       jump->flags |= PATCH_TYPE3;
-                       return 3;
+               diff -= SSIZE_OF(u16);
+       } else if (jump->flags & IS_BL) {
+               /* Branch and link. */
+               if (diff <= 0xffffff && diff >= -0x1000000) {
+                       jump->flags |= PATCH_TYPE5;
+                       return code_ptr + 1;
                }
+               goto exit;
+       } else if (diff <= 0x7ff && diff >= -0x800) {
+               jump->flags |= PATCH_TYPE3;
+               return code_ptr;
        }
-       else if (jump->flags & IS_BL) {
-               if (diff <= 8388607 && diff >= -8388608) {
-                       jump->flags |= PATCH_BL;
-                       return 3;
-               }
+
+       if (diff <= 0xffffff && diff >= -0x1000000) {
+               jump->flags |= PATCH_TYPE4;
+               return code_ptr + 1;
        }
-       else {
-               if (diff <= 1023 && diff >= -1024) {
-                       jump->flags |= PATCH_TYPE4;
-                       return 4;
-               }
-               if (diff <= 8388607 && diff >= -8388608) {
-                       jump->flags |= PATCH_TYPE5;
-                       return 3;
-               }
+
+exit:
+       code_ptr[4] = code_ptr[0];
+
+       if (jump->flags & IS_COND) {
+               code_ptr[3] = code_ptr[-1];
+               jump->addr = (sljit_uw)(code_ptr - 1);
+       }
+
+       return code_ptr + 4;
+}
+
+static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)
+{
+       sljit_uw addr;
+       sljit_sw diff;
+       SLJIT_UNUSED_ARG(executable_offset);
+
+       if (jump->flags & JUMP_ADDR)
+               addr = jump->u.target;
+       else
+               addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);
+
+       /* The pc+4 offset is represented by the 2 * SSIZE_OF(sljit_u16) below. */
+       diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+       /* Note: ADR with imm8 does not set the last bit (Thumb2 flag). */
+
+       if (diff <= 0xffd + 2 * SSIZE_OF(u16) && diff >= -0xfff + 2 * SSIZE_OF(u16)) {
+               jump->flags |= PATCH_TYPE6;
+               return 1;
        }
 
-       return 0;
+       return 3;
 }
 
-static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump, sljit_sw executable_offset)
+static SLJIT_INLINE void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset)
 {
        sljit_s32 type = (jump->flags >> 4) & 0xf;
+       sljit_u16 *jump_inst = (sljit_u16*)jump->addr;
        sljit_sw diff;
-       sljit_u16 *jump_inst;
-       sljit_s32 s, j1, j2;
+       sljit_ins ins;
+
+       diff = (sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr);
 
        if (SLJIT_UNLIKELY(type == 0)) {
-               modify_imm32_const((sljit_u16*)jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target);
+               ins = (jump->flags & JUMP_MOV_ADDR) ? *jump_inst : RDN3(TMP_REG1);
+               set_imm32_const((sljit_u16*)jump->addr, ins, (sljit_uw)diff);
                return;
        }
 
-       if (jump->flags & JUMP_ADDR) {
-               SLJIT_ASSERT(jump->u.target & 0x1);
-               diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
-       }
-       else {
-               SLJIT_ASSERT(jump->u.label->addr & 0x1);
-               diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
+       if (SLJIT_UNLIKELY(type == 6)) {
+               SLJIT_ASSERT(jump->flags & JUMP_MOV_ADDR);
+               diff -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_inst + 2, executable_offset) & ~(sljit_sw)0x3;
+
+               SLJIT_ASSERT(diff <= 0xfff && diff >= -0xfff);
+
+               ins = ADDWI >> 16;
+               if (diff <= 0) {
+                       diff = -diff;
+                       ins = SUBWI >> 16;
+               }
+
+               jump_inst[1] = (sljit_u16)(jump_inst[0] | COPY_BITS(diff, 8, 12, 3) | (diff & 0xff));
+               jump_inst[0] = (sljit_u16)(ins | 0xf | COPY_BITS(diff, 11, 10, 1));
+               return;
        }
-       jump_inst = (sljit_u16*)jump->addr;
+
+       SLJIT_ASSERT((diff & 0x1) != 0 && !(jump->flags & JUMP_MOV_ADDR));
+       diff = (diff - (sljit_sw)(jump->addr + sizeof(sljit_u32)) - executable_offset) >> 1;
 
        switch (type) {
        case 1:
                /* Encoding T1 of 'B' instruction */
-               SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_COND));
+               SLJIT_ASSERT(diff <= 0x7f && diff >= -0x80 && (jump->flags & IS_COND));
                jump_inst[0] = (sljit_u16)(0xd000 | (jump->flags & 0xf00) | ((sljit_ins)diff & 0xff));
                return;
        case 2:
                /* Encoding T3 of 'B' instruction */
-               SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_COND));
+               SLJIT_ASSERT(diff <= 0x7ffff && diff >= -0x80000 && (jump->flags & IS_COND));
                jump_inst[0] = (sljit_u16)(0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1));
                jump_inst[1] = (sljit_u16)(0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | ((sljit_ins)diff & 0x7ff));
                return;
        case 3:
-               SLJIT_ASSERT(jump->flags & IS_COND);
-               *jump_inst++ = (sljit_u16)(IT | ((jump->flags >> 4) & 0xf0) | 0x8);
-               diff--;
-               type = 5;
-               break;
-       case 4:
                /* Encoding T2 of 'B' instruction */
-               SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_COND));
+               SLJIT_ASSERT(diff <= 0x3ff && diff >= -0x400 && !(jump->flags & IS_COND));
                jump_inst[0] = (sljit_u16)(0xe000 | (diff & 0x7ff));
                return;
        }
 
-       SLJIT_ASSERT(diff <= 8388607 && diff >= -8388608);
+       SLJIT_ASSERT(diff <= 0x7fffff && diff >= -0x800000);
+
+       /* Really complex instruction form for branches. Negate with sign bit. */
+       diff ^= ((diff >> 2) & 0x600000) ^ 0x600000;
 
-       /* Really complex instruction form for branches. */
-       s = (diff >> 23) & 0x1;
-       j1 = (~(diff >> 22) ^ s) & 0x1;
-       j2 = (~(diff >> 21) ^ s) & 0x1;
-       jump_inst[0] = (sljit_u16)(0xf000 | ((sljit_ins)s << 10) | COPY_BITS(diff, 11, 0, 10));
-       jump_inst[1] = (sljit_u16)((j1 << 13) | (j2 << 11) | (diff & 0x7ff));
+       jump_inst[0] = (sljit_u16)(0xf000 | COPY_BITS(diff, 11, 0, 10) | COPY_BITS(diff, 23, 10, 1));
+       jump_inst[1] = (sljit_u16)((diff & 0x7ff) | COPY_BITS(diff, 22, 13, 1) | COPY_BITS(diff, 21, 11, 1));
+
+       SLJIT_ASSERT(type == 4 || type == 5);
 
        /* The others have a common form. */
-       if (type == 5) /* Encoding T4 of 'B' instruction */
+       if (type == 4) /* Encoding T4 of 'B' instruction */
                jump_inst[1] |= 0x9000;
-       else if (type == 6) /* Encoding T1 of 'BL' instruction */
+       else /* Encoding T1 of 'BL' instruction */
                jump_inst[1] |= 0xd000;
-       else
-               SLJIT_UNREACHABLE();
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+static void reduce_code_size(struct sljit_compiler *compiler)
+{
+       struct sljit_label *label;
+       struct sljit_jump *jump;
+       struct sljit_const *const_;
+       SLJIT_NEXT_DEFINE_TYPES;
+       sljit_uw total_size;
+       sljit_uw size_reduce = 0;
+       sljit_sw diff;
+
+       label = compiler->labels;
+       jump = compiler->jumps;
+       const_ = compiler->consts;
+       SLJIT_NEXT_INIT_TYPES();
+
+       while (1) {
+               SLJIT_GET_NEXT_MIN();
+
+               if (next_min_addr == SLJIT_MAX_ADDRESS)
+                       break;
+
+               if (next_min_addr == next_label_size) {
+                       label->size -= size_reduce;
+
+                       label = label->next;
+                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
+               }
+
+               if (next_min_addr == next_const_addr) {
+                       const_->addr -= size_reduce;
+                       const_ = const_->next;
+                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
+                       continue;
+               }
+
+               if (next_min_addr != next_jump_addr)
+                       continue;
+
+               jump->addr -= size_reduce;
+               if (!(jump->flags & JUMP_MOV_ADDR)) {
+                       total_size = JUMP_MAX_SIZE;
+
+                       if (!(jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR))) {
+                               /* Unit size: instruction. */
+                               diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr - 2;
+
+                               if (jump->flags & IS_COND) {
+                                       diff++;
+
+                                       if (diff <= (0xff / SSIZE_OF(u16)) && diff >= (-0x100 / SSIZE_OF(u16)))
+                                               total_size = 0;
+                                       else if (diff <= (0xfffff / SSIZE_OF(u16)) && diff >= (-0x100000 / SSIZE_OF(u16)))
+                                               total_size = 1;
+                                       diff--;
+                               } else if (!(jump->flags & IS_BL) && diff <= (0x7ff / SSIZE_OF(u16)) && diff >= (-0x800 / SSIZE_OF(u16)))
+                                       total_size = 1;
+
+                               if (total_size == JUMP_MAX_SIZE && diff <= (0xffffff / SSIZE_OF(u16)) && diff >= (-0x1000000 / SSIZE_OF(u16)))
+                                       total_size = 2;
+                       }
+
+                       size_reduce += JUMP_MAX_SIZE - total_size;
+               } else {
+                       /* Real size minus 1. Unit size: instruction. */
+                       total_size = 3;
+
+                       if (!(jump->flags & JUMP_ADDR)) {
+                               diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;
+
+                               if (diff <= (0xffd / SSIZE_OF(u16)) && diff >= (-0xfff / SSIZE_OF(u16)))
+                                       total_size = 1;
+                       }
+
+                       size_reduce += 3 - total_size;
+               }
+
+               jump->flags |= total_size << JUMP_SIZE_SHIFT;
+               jump = jump->next;
+               next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+       }
+
+       compiler->size -= size_reduce;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
 {
        struct sljit_memory_fragment *buf;
        sljit_u16 *code;
@@ -438,64 +564,74 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        sljit_u16 *buf_ptr;
        sljit_u16 *buf_end;
        sljit_uw half_count;
-       sljit_uw next_addr;
+       SLJIT_NEXT_DEFINE_TYPES;
+       sljit_sw addr;
        sljit_sw executable_offset;
 
        struct sljit_label *label;
        struct sljit_jump *jump;
        struct sljit_const *const_;
-       struct sljit_put_label *put_label;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_generate_code(compiler));
-       reverse_buf(compiler);
 
-       code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16), compiler->exec_allocator_data);
+       reduce_code_size(compiler);
+
+       code = (sljit_u16*)allocate_executable_memory(compiler->size * sizeof(sljit_u16), options, exec_allocator_data, &executable_offset);
        PTR_FAIL_WITH_EXEC_IF(code);
+
+       reverse_buf(compiler);
        buf = compiler->buf;
 
        code_ptr = code;
        half_count = 0;
-       next_addr = 0;
-       executable_offset = SLJIT_EXEC_OFFSET(code);
-
        label = compiler->labels;
        jump = compiler->jumps;
        const_ = compiler->consts;
-       put_label = compiler->put_labels;
+       SLJIT_NEXT_INIT_TYPES();
+       SLJIT_GET_NEXT_MIN();
 
        do {
                buf_ptr = (sljit_u16*)buf->memory;
                buf_end = buf_ptr + (buf->used_size >> 1);
                do {
                        *code_ptr = *buf_ptr++;
-                       if (next_addr == half_count) {
+                       if (next_min_addr == half_count) {
                                SLJIT_ASSERT(!label || label->size >= half_count);
                                SLJIT_ASSERT(!jump || jump->addr >= half_count);
                                SLJIT_ASSERT(!const_ || const_->addr >= half_count);
-                               SLJIT_ASSERT(!put_label || put_label->addr >= half_count);
 
                                /* These structures are ordered by their address. */
-                               if (label && label->size == half_count) {
-                                       label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
+                               if (next_min_addr == next_label_size) {
+                                       label->u.addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
                                        label->size = (sljit_uw)(code_ptr - code);
                                        label = label->next;
+                                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
                                }
-                               if (jump && jump->addr == half_count) {
-                                               jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8);
-                                               code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
-                                               jump = jump->next;
-                               }
-                               if (const_ && const_->addr == half_count) {
+
+                               if (next_min_addr == next_jump_addr) {
+                                       if (!(jump->flags & JUMP_MOV_ADDR)) {
+                                               half_count = half_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT);
+                                               jump->addr = (sljit_uw)code_ptr;
+                                               code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
+                                               SLJIT_ASSERT((sljit_uw)code_ptr - jump->addr <
+                                                       ((jump->flags >> JUMP_SIZE_SHIFT) + ((jump->flags & 0xf0) <= PATCH_TYPE2)) * sizeof(sljit_u16));
+                                       } else {
+                                               half_count += jump->flags >> JUMP_SIZE_SHIFT;
+                                               addr = (sljit_sw)code_ptr;
+                                               code_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);
+                                               jump->addr = (sljit_uw)addr;
+                                       }
+
+                                       jump = jump->next;
+                                       next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+                               } else if (next_min_addr == next_const_addr) {
                                        const_->addr = (sljit_uw)code_ptr;
                                        const_ = const_->next;
+                                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
                                }
-                               if (put_label && put_label->addr == half_count) {
-                                       SLJIT_ASSERT(put_label->label);
-                                       put_label->addr = (sljit_uw)code_ptr;
-                                       put_label = put_label->next;
-                               }
-                               next_addr = compute_next_addr(label, jump, const_, put_label);
+
+                               SLJIT_GET_NEXT_MIN();
                        }
                        code_ptr++;
                        half_count++;
@@ -505,7 +641,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        } while (buf);
 
        if (label && label->size == half_count) {
-               label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
+               label->u.addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
                label->size = (sljit_uw)(code_ptr - code);
                label = label->next;
        }
@@ -513,21 +649,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        SLJIT_ASSERT(!label);
        SLJIT_ASSERT(!jump);
        SLJIT_ASSERT(!const_);
-       SLJIT_ASSERT(!put_label);
        SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
 
        jump = compiler->jumps;
        while (jump) {
-               set_jump_instruction(jump, executable_offset);
+               generate_jump_or_mov_addr(jump, executable_offset);
                jump = jump->next;
        }
 
-       put_label = compiler->put_labels;
-       while (put_label) {
-               modify_imm32_const((sljit_u16 *)put_label->addr, put_label->label->addr);
-               put_label = put_label->next;
-       }
-
        compiler->error = SLJIT_ERR_COMPILED;
        compiler->executable_offset = executable_offset;
        compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_u16);
@@ -657,10 +786,11 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst,
 /* SET_FLAGS must be 0x100000 as it is also the value of S bit (can be used for optimization). */
 #define SET_FLAGS      0x0100000
 #define UNUSED_RETURN  0x0200000
+#define REGISTER_OP    0x0400000
 
 static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 dst, sljit_uw arg1, sljit_uw arg2)
 {
-       /* dst must be register, TMP_REG1
+       /* dst must be register
           arg1 must be register, imm
           arg2 must be register, imm */
        sljit_s32 reg;
@@ -686,6 +816,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
                case SLJIT_REV_U32:
                case SLJIT_REV_S32:
                case SLJIT_MUL:
+               case SLJIT_MULADD:
                        /* No form with immediate operand. */
                        break;
                case SLJIT_MOV:
@@ -921,17 +1052,17 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
                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);
+               SLJIT_ASSERT(arg1 == 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))
+               if (!(flags & REGISTER_OP))
                        return SLJIT_SUCCESS;
 
+               flags &= 0xffff;
                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));
@@ -966,10 +1097,10 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
                compiler->status_flags_state = 0;
                if (!(flags & SET_FLAGS))
                        return push_inst32(compiler, MUL | RD4(dst) | RN4(arg1) | RM4(arg2));
-               SLJIT_ASSERT(dst != TMP_REG2);
-               FAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(TMP_REG2) | RN4(arg1) | RM4(arg2)));
+               reg = (dst == TMP_REG2) ? TMP_REG1 : TMP_REG2;
+               FAIL_IF(push_inst32(compiler, SMULL | RT4(dst) | RD4(reg) | RN4(arg1) | RM4(arg2)));
                /* cmp TMP_REG2, dst asr #31. */
-               return push_inst32(compiler, CMP_W | RN4(TMP_REG2) | 0x70e0 | RM4(dst));
+               return push_inst32(compiler, CMP_W | RN4(reg) | 0x70e0 | RM4(dst));
        case SLJIT_AND:
                if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
                        return push_inst16(compiler, ANDS | RD3(dst) | RN3(arg2));
@@ -985,37 +1116,44 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
                        return push_inst16(compiler, EORS | RD3(dst) | RN3(arg2));
                return push_inst32(compiler, EOR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
        case SLJIT_MSHL:
-               FAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(arg2) | 0x1f));
-               arg2 = TMP_REG2;
+               reg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;
+               FAIL_IF(push_inst32(compiler, ANDI | RD4(reg) | RN4(arg2) | 0x1f));
+               arg2 = (sljit_uw)reg;
                /* fallthrough */
        case SLJIT_SHL:
                if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
                        return push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2));
                return push_inst32(compiler, LSL_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
        case SLJIT_MLSHR:
-               FAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(arg2) | 0x1f));
-               arg2 = TMP_REG2;
+               reg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;
+               FAIL_IF(push_inst32(compiler, ANDI | RD4(reg) | RN4(arg2) | 0x1f));
+               arg2 = (sljit_uw)reg;
                /* fallthrough */
        case SLJIT_LSHR:
                if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
                        return push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2));
                return push_inst32(compiler, LSR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
        case SLJIT_MASHR:
-               FAIL_IF(push_inst32(compiler, ANDI | RD4(TMP_REG2) | RN4(arg2) | 0x1f));
-               arg2 = TMP_REG2;
+               reg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;
+               FAIL_IF(push_inst32(compiler, ANDI | RD4(reg) | RN4(arg2) | 0x1f));
+               arg2 = (sljit_uw)reg;
                /* fallthrough */
        case SLJIT_ASHR:
                if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
                        return push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2));
                return push_inst32(compiler, ASR_W | (flags & SET_FLAGS) | RD4(dst) | RN4(arg1) | RM4(arg2));
        case SLJIT_ROTL:
-               FAIL_IF(push_inst32(compiler, RSB_WI | RD4(TMP_REG2) | RN4(arg2) | 0));
-               arg2 = TMP_REG2;
+               reg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;
+               FAIL_IF(push_inst32(compiler, RSB_WI | RD4(reg) | RN4(arg2) | 0));
+               arg2 = (sljit_uw)reg;
                /* fallthrough */
        case SLJIT_ROTR:
                if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
                        return push_inst16(compiler, RORS | RD3(dst) | RN3(arg2));
                return push_inst32(compiler, ROR_W | RD4(dst) | RN4(arg1) | RM4(arg2));
+       case SLJIT_MULADD:
+               compiler->status_flags_state = 0;
+               return push_inst32(compiler, MLA | RD4(dst) | RN4(arg1) | RM4(arg2) | RT4(dst));
        }
 
        SLJIT_UNREACHABLE();
@@ -1779,14 +1917,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
        sljit_s32 src, sljit_sw srcw)
 {
        sljit_s32 dst_r, flags;
-       sljit_s32 op_flags = GET_ALL_FLAGS(op);
 
        CHECK_ERROR();
        CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
        ADJUST_LOCAL_OFFSET(dst, dstw);
        ADJUST_LOCAL_OFFSET(src, srcw);
 
-       dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+       dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
 
        op = GET_OPCODE(op);
        if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
@@ -1826,35 +1963,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
 
                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) {
+               else if (src & SLJIT_MEM)
                        FAIL_IF(emit_op_mem(compiler, flags, dst_r, src, srcw, TMP_REG1));
-               } else {
-                       if (dst_r != TMP_REG1)
-                               return emit_op_imm(compiler, op, dst_r, TMP_REG2, (sljit_uw)src);
+               else if (FAST_IS_REG(dst))
+                       return emit_op_imm(compiler, op, dst_r, TMP_REG2, (sljit_uw)src);
+               else
                        dst_r = src;
-               }
 
                if (!(dst & SLJIT_MEM))
                        return SLJIT_SUCCESS;
 
-               return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2);
+               return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG1);
        }
 
        SLJIT_COMPILE_ASSERT(WORD_SIZE == 0, word_size_must_be_0);
-       flags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0;
+       flags = WORD_SIZE;
 
-       if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16)
+       if (op == SLJIT_REV_U16 || op == SLJIT_REV_S16) {
+               if (!(dst & SLJIT_MEM) && (!(src & SLJIT_MEM) || op == SLJIT_REV_S16))
+                       op |= REGISTER_OP;
                flags |= HALF_SIZE;
+       }
 
        if (src & SLJIT_MEM) {
                FAIL_IF(emit_op_mem(compiler, flags, TMP_REG1, src, srcw, TMP_REG1));
                src = TMP_REG1;
        }
 
-       emit_op_imm(compiler, flags | op, dst_r, TMP_REG2, (sljit_uw)src);
+       emit_op_imm(compiler, op, dst_r, TMP_REG2, (sljit_uw)src);
 
        if (SLJIT_UNLIKELY(dst & SLJIT_MEM))
-               return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2);
+               return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG1);
        return SLJIT_SUCCESS;
 }
 
@@ -1863,7 +2002,7 @@ 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 dst_reg, flags, src2_reg;
+       sljit_s32 dst_reg, src2_tmp_reg, flags;
 
        CHECK_ERROR();
        CHECK(check_sljit_emit_op2(compiler, op, 0, dst, dstw, src1, src1w, src2, src2w));
@@ -1871,36 +2010,34 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
        ADJUST_LOCAL_OFFSET(src1, src1w);
        ADJUST_LOCAL_OFFSET(src2, src2w);
 
-       dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
+       dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
        flags = HAS_FLAGS(op) ? SET_FLAGS : 0;
 
        if (dst == TMP_REG1)
                flags |= UNUSED_RETURN;
 
+       if (src2 == SLJIT_IMM)
+               flags |= ARG2_IMM;
+       else if (src2 & SLJIT_MEM) {
+               src2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;
+               emit_op_mem(compiler, WORD_SIZE, src2_tmp_reg, src2, src2w, TMP_REG1);
+               src2w = src2_tmp_reg;
+       } else
+               src2w = src2;
+
        if (src1 == SLJIT_IMM)
                flags |= ARG1_IMM;
        else if (src1 & SLJIT_MEM) {
                emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1);
                src1w = TMP_REG1;
-       }
-       else
+       } else
                src1w = src1;
 
-       if (src2 == SLJIT_IMM)
-               flags |= ARG2_IMM;
-       else if (src2 & SLJIT_MEM) {
-               src2_reg = (!(flags & ARG1_IMM) && (src1w == TMP_REG1)) ? TMP_REG2 : TMP_REG1;
-               emit_op_mem(compiler, WORD_SIZE, src2_reg, src2, src2w, src2_reg);
-               src2w = src2_reg;
-       }
-       else
-               src2w = src2;
-
        emit_op_imm(compiler, flags | GET_OPCODE(op), dst_reg, (sljit_uw)src1w, (sljit_uw)src2w);
 
        if (!(dst & SLJIT_MEM))
                return SLJIT_SUCCESS;
-       return emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG2);
+       return emit_op_mem(compiler, WORD_SIZE | STORE, dst_reg, dst, dstw, TMP_REG1);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compiler, sljit_s32 op,
@@ -1914,6 +2051,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil
        return sljit_emit_op2(compiler, op, TMP_REG1, 0, src1, src1w, src2, src2w);
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
+       sljit_s32 dst_reg,
+       sljit_s32 src1, sljit_sw src1w,
+       sljit_s32 src2, sljit_sw src2w)
+{
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
+
+       switch (GET_OPCODE(op)) {
+       case SLJIT_MULADD:
+               SLJIT_SKIP_CHECKS(compiler);
+               return sljit_emit_op2(compiler, op, dst_reg, 0, src1, src1w, src2, src2w);
+       }
+
+       return SLJIT_SUCCESS;
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
        sljit_s32 dst_reg,
        sljit_s32 src1_reg,
@@ -2228,7 +2382,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
        switch (GET_OPCODE(op)) {
        case SLJIT_MOV_F64:
                if (src != dst_r) {
-                       if (dst_r != TMP_FREG1)
+                       if (!(dst & SLJIT_MEM))
                                FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_32) | VD4(dst_r) | VM4(src)));
                        else
                                dst_r = src;
@@ -2519,7 +2673,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
        set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
        type &= 0xff;
 
-       PTR_FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
        if (type < SLJIT_JUMP) {
                jump->flags |= IS_COND;
                cc = get_cc(compiler, type);
@@ -2535,6 +2688,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
                PTR_FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1)));
        }
 
+       /* Maximum number of instructions required for generating a constant. */
+       compiler->size += JUMP_MAX_SIZE - 1;
        return jump;
 }
 
@@ -2800,8 +2955,9 @@ 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;
 
-       FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
        jump->addr = compiler->size;
+       /* Maximum number of instructions required for generating a constant. */
+       compiler->size += JUMP_MAX_SIZE - 1;
        return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1));
 }
 
@@ -2968,7 +3124,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
        }
 
        if (src1 & SLJIT_MEM) {
-               FAIL_IF(emit_op_mem(compiler, WORD_SIZE, (src2_reg != dst_reg) ? dst_reg : TMP_REG1, src1, src1w, TMP_REG2));
+               FAIL_IF(emit_op_mem(compiler, WORD_SIZE, (src2_reg != dst_reg) ? dst_reg : TMP_REG1, src1, src1w, TMP_REG1));
 
                if (src2_reg != dst_reg) {
                        src1 = src2_reg;
@@ -3040,8 +3196,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com
        }
 
        if (src1 & SLJIT_MEM) {
-               FAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) | FPU_LOAD, TMP_FREG1, src1, src1w));
-               src1 = TMP_FREG1;
+               FAIL_IF(emit_fop_mem(compiler, (type & SLJIT_32) | FPU_LOAD, TMP_FREG2, src1, src1w));
+               src1 = TMP_FREG2;
        }
 
        FAIL_IF(push_inst16(compiler, IT | (get_cc(compiler, type & ~SLJIT_32) << 4) | 0x8));
@@ -4106,25 +4262,26 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
        return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
-       struct sljit_put_label *put_label;
+       struct sljit_jump *jump;
        sljit_s32 dst_r;
 
        CHECK_ERROR_PTR();
-       CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+       CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
        ADJUST_LOCAL_OFFSET(dst, dstw);
 
-       put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
-       PTR_FAIL_IF(!put_label);
-       set_put_label(put_label, compiler, 0);
+       jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+       PTR_FAIL_IF(!jump);
+       set_mov_addr(jump, compiler, 0);
 
        dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
-       PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, 0));
+       PTR_FAIL_IF(push_inst16(compiler, RDN3(dst_r)));
+       compiler->size += 3;
 
        if (dst & SLJIT_MEM)
                PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
-       return put_label;
+       return jump;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
index dbd760540fb56bc524ecda9d4ae8deede51a7e0c..2e1d742aee74a47c14ad3c773a025cabc2b64089 100644 (file)
@@ -85,10 +85,12 @@ lower parts in the instruction word, denoted by the “L” and “H” suffixes
 #define FRK(fk) ((sljit_ins)freg_map[fk] << 10)
 #define FRA(fa) ((sljit_ins)freg_map[fa] << 15)
 
+#define IMM_V(imm) ((sljit_ins)(imm) << 10)
 #define IMM_I8(imm) (((sljit_ins)(imm)&0xff) << 10)
 #define IMM_I12(imm) (((sljit_ins)(imm)&0xfff) << 10)
 #define IMM_I14(imm) (((sljit_ins)(imm)&0xfff3) << 10)
 #define IMM_I16(imm) (((sljit_ins)(imm)&0xffff) << 10)
+#define IMM_I20(imm) (((sljit_ins)(imm)&0xffffffff) >> 12 << 5)
 #define IMM_I21(imm) ((((sljit_ins)(imm)&0xffff) << 10) | (((sljit_ins)(imm) >> 16) & 0x1f))
 #define IMM_I26(imm) ((((sljit_ins)(imm)&0xffff) << 10) | (((sljit_ins)(imm) >> 16) & 0x3ff))
 
@@ -318,6 +320,36 @@ lower parts in the instruction word, denoted by the “L” and “H” suffixes
 #define FSTX_S OPC_3R(0x7070)
 #define FSTX_D OPC_3R(0x7078)
 
+/* Vector Instructions */
+
+/* Vector Arithmetic Instructions */
+#define VOR_V OPC_3R(0xe24d)
+#define VXOR_V OPC_3R(0xe24e)
+#define VAND_V OPC_3R(0xe24c)
+#define VMSKLTZ OPC_2R(0x1ca710)
+
+/* Vector Memory Access Instructions */
+#define VLD OPC_2RI12(0xb0)
+#define VST OPC_2RI12(0xb1)
+#define XVLD OPC_2RI12(0xb2)
+#define XVST OPC_2RI12(0xb3)
+#define VSTELM OPC_2RI8(0xc40)
+
+/* Vector Float Conversion Instructions */
+#define VFCVTL_D_S OPC_2R(0x1ca77c)
+
+/* Vector Bit Manipulate Instructions */
+#define VSLLWIL OPC_2R(0x1cc200)
+
+/* Vector Move And Shuffle Instructions */
+#define VLDREPL OPC_2R(0xc0000)
+#define VINSGR2VR OPC_2R(0x1cbac0)
+#define VPICKVE2GR_U OPC_2R(0x1cbce0)
+#define VREPLGR2VR OPC_2R(0x1ca7c0)
+#define VREPLVE OPC_3R(0xe244)
+#define VREPLVEI OPC_2R(0x1cbde0)
+#define XVPERMI OPC_2RI8(0x1dfa)
+
 #define I12_MAX (0x7ff)
 #define I12_MIN (-0x800)
 #define BRANCH16_MAX (0x7fff << 2)
@@ -337,16 +369,32 @@ lower parts in the instruction word, denoted by the “L” and “H” suffixes
 
 /* LoongArch CPUCFG register for feature detection */
 #define LOONGARCH_CFG2                 0x02
-#define LOONGARCH_FEATURE_LAMCAS       (1 << 28)
+#define LOONGARCH_CFG2_LAMCAS  (1 << 28)
 
-static sljit_u32 cpu_feature_list = 0;
+static sljit_u32 cfg2_feature_list = 0;
 
-static SLJIT_INLINE sljit_u32 get_cpu_features(void)
-{
-       if (cpu_feature_list == 0)
-               __asm__ ("cpucfg %0, %1" : "+&r"(cpu_feature_list) : "r"(LOONGARCH_CFG2));
-       return cpu_feature_list;
-}
+/* According to Software Development and Build Convention for LoongArch Architectures,
++   the status of LSX and LASX extension must be checked through HWCAP */
+#include <sys/auxv.h>
+
+#define LOONGARCH_HWCAP_LSX            (1 << 4)
+#define LOONGARCH_HWCAP_LASX   (1 << 5)
+
+static sljit_u32 hwcap_feature_list = 0;
+
+/* Feature type */
+#define GET_CFG2       0
+#define GET_HWCAP      1
+
+static SLJIT_INLINE sljit_u32 get_cpu_features(sljit_u32 feature_type)
+ {
+       if (cfg2_feature_list == 0)
+               __asm__ ("cpucfg %0, %1" : "+&r"(cfg2_feature_list) : "r"(LOONGARCH_CFG2));
+       if (hwcap_feature_list == 0)
+               hwcap_feature_list = (sljit_u32)getauxval(AT_HWCAP);
+
+       return feature_type ? hwcap_feature_list : cfg2_feature_list;
+ }
 
 static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
 {
@@ -371,24 +419,23 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
        if (jump->flags & JUMP_ADDR)
                target_addr = jump->u.target;
        else {
-               SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+               SLJIT_ASSERT(jump->u.label != NULL);
                target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
        }
 
        diff = (sljit_sw)target_addr - (sljit_sw)inst - executable_offset;
 
        if (jump->flags & IS_COND) {
-               inst--;
                diff += SSIZE_OF(ins);
 
                if (diff >= BRANCH16_MIN && diff <= BRANCH16_MAX) {
-                       jump->flags |= PATCH_B;
+                       inst--;
                        inst[0] = (inst[0] & 0xfc0003ff) ^ 0x4000000;
+                       jump->flags |= PATCH_B;
                        jump->addr = (sljit_uw)inst;
                        return inst;
                }
 
-               inst++;
                diff -= SSIZE_OF(ins);
        }
 
@@ -435,65 +482,179 @@ exit:
        return inst + 3;
 }
 
-static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
+static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
 {
-       if (max_label <= (sljit_uw)S32_MAX) {
-               put_label->flags = PATCH_ABS32;
+       sljit_uw addr;
+       sljit_sw diff;
+       SLJIT_UNUSED_ARG(executable_offset);
+
+       SLJIT_ASSERT(jump->flags < ((sljit_uw)6 << JUMP_SIZE_SHIFT));
+       if (jump->flags & JUMP_ADDR)
+               addr = jump->u.target;
+       else
+               addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);
+
+       diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+       if (diff >= S32_MIN && diff <= S32_MAX) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));
+               jump->flags |= PATCH_REL32;
+               return 1;
+       }
+
+       if (addr <= S32_MAX) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));
+               jump->flags |= PATCH_ABS32;
                return 1;
        }
 
-       if (max_label <= S52_MAX) {
-               put_label->flags = PATCH_ABS52;
+       if (addr <= S52_MAX) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)2 << JUMP_SIZE_SHIFT));
+               jump->flags |= PATCH_ABS52;
                return 2;
        }
 
-       put_label->flags = 0;
+       SLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));
        return 3;
 }
 
-static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg)
+static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw executable_offset)
 {
-       struct sljit_jump *jump = NULL;
-       struct sljit_put_label *put_label;
-       sljit_uw flags;
-       sljit_ins *inst;
-       sljit_uw addr;
+       sljit_uw flags = jump->flags;
+       sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
+       sljit_ins *ins = (sljit_ins*)jump->addr;
+       sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : TMP_REG1;
+       SLJIT_UNUSED_ARG(executable_offset);
 
-       if (reg != 0) {
-               jump = (struct sljit_jump*)dst;
-               flags = jump->flags;
-               inst = (sljit_ins*)jump->addr;
-               addr = (flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
-       } else {
-               put_label = (struct sljit_put_label*)dst;
-               flags = put_label->flags;
-               inst = (sljit_ins*)put_label->addr;
-               addr = put_label->label->addr;
-               reg = *inst;
+       if (flags & PATCH_REL32) {
+               addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(ins, executable_offset);
+
+               SLJIT_ASSERT((sljit_sw)addr >= S32_MIN && (sljit_sw)addr <= S32_MAX);
+
+               if ((addr & 0x800) != 0)
+                       addr += 0x1000;
+
+               ins[0] = PCADDU12I | RD(reg) | IMM_I20(addr);
+
+               if (!(flags & JUMP_MOV_ADDR)) {
+                       SLJIT_ASSERT((ins[1] & OPC_2RI16(0x3f)) == JIRL);
+                       ins[1] = (ins[1] & (OPC_2RI16(0x3f) | 0x3ff)) | IMM_I16((addr & 0xfff) >> 2);
+               } else
+                       ins[1] = ADDI_D | RD(reg) | RJ(reg) | IMM_I12(addr);
+               return;
        }
 
        if (flags & PATCH_ABS32) {
                SLJIT_ASSERT(addr <= S32_MAX);
-               inst[0] = LU12I_W | RD(reg) | (sljit_ins)(((addr & 0xffffffff) >> 12) << 5);
+               ins[0] = LU12I_W | RD(reg) | (sljit_ins)(((addr & 0xffffffff) >> 12) << 5);
        } else if (flags & PATCH_ABS52) {
-               inst[0] = LU12I_W | RD(reg) | (sljit_ins)(((addr & 0xffffffff) >> 12) << 5);
-               inst[1] = LU32I_D | RD(reg) | (sljit_ins)(((addr >> 32) & 0xfffff) << 5);
-               inst += 1;
+               ins[0] = LU12I_W | RD(reg) | (sljit_ins)(((addr & 0xffffffff) >> 12) << 5);
+               ins[1] = LU32I_D | RD(reg) | (sljit_ins)(((addr >> 32) & 0xfffff) << 5);
+               ins += 1;
        } else {
-               inst[0] = LU12I_W | RD(reg) | (sljit_ins)(((addr & 0xffffffff) >> 12) << 5);
-               inst[1] = LU32I_D | RD(reg) | (sljit_ins)(((addr >> 32) & 0xfffff) << 5);
-               inst[2] = LU52I_D | RD(reg) | RJ(reg) | IMM_I12(addr >> 52);
-               inst += 2;
+               ins[0] = LU12I_W | RD(reg) | (sljit_ins)(((addr & 0xffffffff) >> 12) << 5);
+               ins[1] = LU32I_D | RD(reg) | (sljit_ins)(((addr >> 32) & 0xfffff) << 5);
+               ins[2] = LU52I_D | RD(reg) | RJ(reg) | IMM_I12(addr >> 52);
+               ins += 2;
        }
 
-       if (jump != NULL) {
-               SLJIT_ASSERT((inst[1] & OPC_2RI16(0x3f)) == JIRL);
-               inst[1] = (inst[1] & (OPC_2RI16(0x3f) | 0x3ff)) | IMM_I16((addr & 0xfff) >> 2);
+       if (!(flags & JUMP_MOV_ADDR)) {
+               SLJIT_ASSERT((ins[1] & OPC_2RI16(0x3f)) == JIRL);
+               ins[1] = (ins[1] & (OPC_2RI16(0x3f) | 0x3ff)) | IMM_I16((addr & 0xfff) >> 2);
        } else
-               inst[1] = ORI | RD(reg) | RJ(reg) | IMM_I12(addr);
+               ins[1] = ORI | RD(reg) | RJ(reg) | IMM_I12(addr);
+}
+
+static void reduce_code_size(struct sljit_compiler *compiler)
+{
+       struct sljit_label *label;
+       struct sljit_jump *jump;
+       struct sljit_const *const_;
+       SLJIT_NEXT_DEFINE_TYPES;
+       sljit_uw total_size;
+       sljit_uw size_reduce = 0;
+       sljit_sw diff;
+
+       label = compiler->labels;
+       jump = compiler->jumps;
+       const_ = compiler->consts;
+
+       SLJIT_NEXT_INIT_TYPES();
+
+       while (1) {
+               SLJIT_GET_NEXT_MIN();
+
+               if (next_min_addr == SLJIT_MAX_ADDRESS)
+                       break;
+
+               if (next_min_addr == next_label_size) {
+                       label->size -= size_reduce;
+
+                       label = label->next;
+                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
+               }
+
+               if (next_min_addr == next_const_addr) {
+                       const_->addr -= size_reduce;
+                       const_ = const_->next;
+                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
+                       continue;
+               }
+
+               if (next_min_addr != next_jump_addr)
+                       continue;
+
+               jump->addr -= size_reduce;
+               if (!(jump->flags & JUMP_MOV_ADDR)) {
+                       total_size = JUMP_MAX_SIZE;
+
+                       if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {
+                               if (jump->flags & JUMP_ADDR) {
+                                       if (jump->u.target <= S32_MAX)
+                                                       total_size = 2;
+                                       else if (jump->u.target <= S52_MAX)
+                                                       total_size = 3;
+                               } else {
+                                       /* Unit size: instruction. */
+                                       diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;
+
+                                       if ((jump->flags & IS_COND) && (diff + 1) <= (BRANCH16_MAX / SSIZE_OF(ins)) && (diff + 1) >= (BRANCH16_MIN / SSIZE_OF(ins)))
+                                               total_size = 0;
+                                       else if (diff >= (JUMP_MIN / SSIZE_OF(ins)) && diff <= (JUMP_MAX / SSIZE_OF(ins)))
+                                               total_size = 1;
+                                       else if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins)))
+                                               total_size = 2;
+                               }
+                       }
+
+                       size_reduce += JUMP_MAX_SIZE - total_size;
+                       jump->flags |= total_size << JUMP_SIZE_SHIFT;
+               } else {
+                       total_size = 3;
+
+                       if (!(jump->flags & JUMP_ADDR)) {
+                               /* Real size minus 1. Unit size: instruction. */
+                               diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;
+
+                               if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins)))
+                                       total_size = 1;
+                       } else if (jump->u.target < S32_MAX)
+                               total_size = 1;
+                       else if (jump->u.target <= S52_MAX)
+                               total_size = 2;
+
+                       size_reduce += 3 - total_size;
+                       jump->flags |= total_size << JUMP_SIZE_SHIFT;
+               }
+
+               jump = jump->next;
+               next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+       }
+
+       compiler->size -= size_reduce;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
 {
        struct sljit_memory_fragment *buf;
        sljit_ins *code;
@@ -501,70 +662,72 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        sljit_ins *buf_ptr;
        sljit_ins *buf_end;
        sljit_uw word_count;
-       sljit_uw next_addr;
+       SLJIT_NEXT_DEFINE_TYPES;
        sljit_sw executable_offset;
        sljit_uw addr;
 
        struct sljit_label *label;
        struct sljit_jump *jump;
        struct sljit_const *const_;
-       struct sljit_put_label *put_label;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_generate_code(compiler));
-       reverse_buf(compiler);
 
-       code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
+       reduce_code_size(compiler);
+
+       code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
        PTR_FAIL_WITH_EXEC_IF(code);
+
+       reverse_buf(compiler);
        buf = compiler->buf;
 
        code_ptr = code;
        word_count = 0;
-       next_addr = 0;
-       executable_offset = SLJIT_EXEC_OFFSET(code);
-
        label = compiler->labels;
        jump = compiler->jumps;
        const_ = compiler->consts;
-       put_label = compiler->put_labels;
+       SLJIT_NEXT_INIT_TYPES();
+       SLJIT_GET_NEXT_MIN();
 
        do {
                buf_ptr = (sljit_ins*)buf->memory;
                buf_end = buf_ptr + (buf->used_size >> 2);
                do {
                        *code_ptr = *buf_ptr++;
-                       if (next_addr == word_count) {
+                       if (next_min_addr == word_count) {
                                SLJIT_ASSERT(!label || label->size >= word_count);
                                SLJIT_ASSERT(!jump || jump->addr >= word_count);
                                SLJIT_ASSERT(!const_ || const_->addr >= word_count);
-                               SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
 
                                /* These structures are ordered by their address. */
-                               if (label && label->size == word_count) {
-                                       label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+                               if (next_min_addr == next_label_size) {
+                                       label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
                                        label->size = (sljit_uw)(code_ptr - code);
                                        label = label->next;
+                                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
                                }
-                               if (jump && jump->addr == word_count) {
-                                       word_count += 3;
-                                       jump->addr = (sljit_uw)code_ptr;
-                                       code_ptr = detect_jump_type(jump, code, executable_offset);
+
+                               if (next_min_addr == next_jump_addr) {
+                                       if (!(jump->flags & JUMP_MOV_ADDR)) {
+                                               word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT);
+                                               jump->addr = (sljit_uw)code_ptr;
+                                               code_ptr = detect_jump_type(jump, code, executable_offset);
+                                               SLJIT_ASSERT((jump->flags & PATCH_B) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins)));
+                                       } else {
+                                               word_count += jump->flags >> JUMP_SIZE_SHIFT;
+                                               addr = (sljit_uw)code_ptr;
+                                               code_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);
+                                               jump->addr = addr;
+                                       }
                                        jump = jump->next;
-                               }
-                               if (const_ && const_->addr == word_count) {
+                                       next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+                               } else if (next_min_addr == next_const_addr) {
                                        const_->addr = (sljit_uw)code_ptr;
                                        const_ = const_->next;
+                                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
                                }
-                               if (put_label && put_label->addr == word_count) {
-                                       SLJIT_ASSERT(put_label->label);
-                                       put_label->addr = (sljit_uw)code_ptr;
-
-                                       code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
-                                       word_count += 3;
 
-                                       put_label = put_label->next;
-                               }
-                               next_addr = compute_next_addr(label, jump, const_, put_label);
+                               SLJIT_GET_NEXT_MIN();
                        }
                        code_ptr++;
                        word_count++;
@@ -574,7 +737,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        } while (buf);
 
        if (label && label->size == word_count) {
-               label->addr = (sljit_uw)code_ptr;
+               label->u.addr = (sljit_uw)code_ptr;
                label->size = (sljit_uw)(code_ptr - code);
                label = label->next;
        }
@@ -582,18 +745,17 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        SLJIT_ASSERT(!label);
        SLJIT_ASSERT(!jump);
        SLJIT_ASSERT(!const_);
-       SLJIT_ASSERT(!put_label);
        SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
 
        jump = compiler->jumps;
        while (jump) {
                do {
-                       if (!(jump->flags & (PATCH_B | PATCH_J | PATCH_REL32))) {
-                               load_addr_to_reg(jump, TMP_REG1);
+                       if (!(jump->flags & (PATCH_B | PATCH_J)) || (jump->flags & JUMP_MOV_ADDR)) {
+                               load_addr_to_reg(jump, executable_offset);
                                break;
                        }
 
-                       addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+                       addr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
                        buf_ptr = (sljit_ins *)jump->addr;
                        addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
 
@@ -603,15 +765,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
                                break;
                        }
 
-                       if (jump->flags & PATCH_REL32) {
-                               SLJIT_ASSERT((sljit_sw)addr >= S32_MIN && (sljit_sw)addr <= S32_MAX);
-
-                               buf_ptr[0] = PCADDU12I | RD(TMP_REG1) | (sljit_ins)((sljit_sw)addr & ~0xfff);
-                               SLJIT_ASSERT((buf_ptr[1] & OPC_2RI16(0x3f)) == JIRL);
-                               buf_ptr[1] |= IMM_I16((addr & 0xfff) >> 2);
-                               break;
-                       }
-
                        SLJIT_ASSERT((sljit_sw)addr >= JUMP_MIN && (sljit_sw)addr <= JUMP_MAX);
                        if (jump->flags & IS_CALL)
                                buf_ptr[0] = BL | (sljit_ins)IMM_I26(addr >> 2);
@@ -621,12 +774,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
                jump = jump->next;
        }
 
-       put_label = compiler->put_labels;
-       while (put_label) {
-               load_addr_to_reg(put_label, 0);
-               put_label = put_label->next;
-       }
-
        compiler->error = SLJIT_ERR_COMPILED;
        compiler->executable_offset = executable_offset;
        compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
@@ -651,8 +798,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
                return 1;
 #endif
 
+       case SLJIT_HAS_LASX:
+               return (LOONGARCH_HWCAP_LASX & get_cpu_features(GET_HWCAP));
+
+       case SLJIT_HAS_SIMD:
+               return (LOONGARCH_HWCAP_LSX & get_cpu_features(GET_HWCAP));
+
        case SLJIT_HAS_ATOMIC:
-               return (LOONGARCH_FEATURE_LAMCAS & get_cpu_features());
+               return (LOONGARCH_CFG2_LAMCAS & get_cpu_features(GET_CFG2));
 
        case SLJIT_HAS_CLZ:
        case SLJIT_HAS_CTZ:
@@ -707,6 +860,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
 #define SLOW_SRC1      0x08000
 #define SLOW_SRC2      0x10000
 #define SLOW_DEST      0x20000
+#define MEM_USE_TMP2   0x40000
 
 #define STACK_STORE    ST_D
 #define STACK_LOAD     LD_D
@@ -1039,7 +1193,7 @@ static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, slj
 static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
 {
        sljit_s32 base = arg & REG_MASK;
-       sljit_s32 tmp_r = TMP_REG1;
+       sljit_s32 tmp_r = (flags & MEM_USE_TMP2) ? TMP_REG2 : TMP_REG1;
        sljit_sw offset;
 
        SLJIT_ASSERT(arg & SLJIT_MEM);
@@ -1048,11 +1202,6 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
                next_argw = 0;
        }
 
-       /* 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))
-               tmp_r = reg;
-
        if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
                argw &= 0x3;
 
@@ -1149,8 +1298,7 @@ static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, slji
                                FAIL_IF(push_inst(compiler, op_reg | RD(dst) | RJ(src1) | RK(dst))); \
                        } \
                } \
-       } \
-       else { \
+       } else { \
                if (op & SLJIT_SET_Z) \
                        FAIL_IF(push_inst(compiler, op_reg | RD(EQUAL_FLAG) | RJ(src1) | RK(src2))); \
                if (!(flags & UNUSED_DEST)) \
@@ -1165,88 +1313,88 @@ static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, slji
 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)
 {
-       sljit_s32 is_overflow, is_carry, carry_src_r, is_handled;
+       sljit_s32 is_overflow, is_carry, carry_src_r, is_handled, reg;
        sljit_ins op_imm, op_reg;
        sljit_ins word_size = ((op & SLJIT_32) ? 32 : 64);
 
        switch (GET_OPCODE(op)) {
        case SLJIT_MOV:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if (dst != src2)
                        return push_inst(compiler, INST(ADD, op) | RD(dst) | RJ(src2) | IMM_I12(0));
                return SLJIT_SUCCESS;
 
        case SLJIT_MOV_U8:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
                        return push_inst(compiler, ANDI | RD(dst) | RJ(src2) | IMM_I12(0xff));
                SLJIT_ASSERT(dst == src2);
                return SLJIT_SUCCESS;
 
        case SLJIT_MOV_S8:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
                        return push_inst(compiler, EXT_W_B | RD(dst) | RJ(src2));
                SLJIT_ASSERT(dst == src2);
                return SLJIT_SUCCESS;
 
        case SLJIT_MOV_U16:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
                        return push_inst(compiler, INST(BSTRPICK, op) | RD(dst) | RJ(src2) | (15 << 16));
                SLJIT_ASSERT(dst == src2);
                return SLJIT_SUCCESS;
 
        case SLJIT_MOV_S16:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
                        return push_inst(compiler, EXT_W_H | RD(dst) | RJ(src2));
                SLJIT_ASSERT(dst == src2);
                return SLJIT_SUCCESS;
 
        case SLJIT_MOV_U32:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
                        return push_inst(compiler, BSTRPICK_D | RD(dst) | RJ(src2) | (31 << 16));
                SLJIT_ASSERT(dst == src2);
                return SLJIT_SUCCESS;
 
        case SLJIT_MOV_S32:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
                        return push_inst(compiler, SLLI_W | RD(dst) | RJ(src2) | IMM_I12(0));
                SLJIT_ASSERT(dst == src2);
                return SLJIT_SUCCESS;
 
        case SLJIT_CLZ:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                return push_inst(compiler, INST(CLZ, op) | RD(dst) | RJ(src2));
 
        case SLJIT_CTZ:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                return push_inst(compiler, INST(CTZ, op) | RD(dst) | RJ(src2));
 
        case SLJIT_REV:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                return push_inst(compiler, ((op & SLJIT_32) ? REVB_2W : REVB_D) | RD(dst) | RJ(src2));
 
        case SLJIT_REV_S16:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                FAIL_IF(push_inst(compiler, REVB_2H | RD(dst) | RJ(src2)));
                return push_inst(compiler, EXT_W_H | RD(dst) | RJ(dst));
 
        case SLJIT_REV_U16:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                FAIL_IF(push_inst(compiler, REVB_2H | RD(dst) | RJ(src2)));
                return push_inst(compiler, INST(BSTRPICK, op) | RD(dst) | RJ(dst) | (15 << 16));
 
        case SLJIT_REV_S32:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && dst != TMP_REG1);
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM) && dst != TMP_REG1);
                FAIL_IF(push_inst(compiler, REVB_2W | RD(dst) | RJ(src2)));
                return push_inst(compiler, SLLI_W | RD(dst) | RJ(dst) | IMM_I12(0));
 
        case SLJIT_REV_U32:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM) && dst != TMP_REG1);
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM) && dst != TMP_REG1);
                FAIL_IF(push_inst(compiler, REVB_2W | RD(dst) | RJ(src2)));
                return push_inst(compiler, BSTRPICK_D | RD(dst) | RJ(dst) | (31 << 16));
 
@@ -1263,15 +1411,13 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                                        FAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(TMP_ZERO) | IMM_I12(-1)));
                                        FAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RJ(src1) | RK(EQUAL_FLAG)));
                                }
-                       }
-                       else if (op & SLJIT_SET_Z)
+                       } else if (op & SLJIT_SET_Z)
                                FAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(src2)));
 
                        /* Only the zero flag is needed. */
                        if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
                                FAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(dst) | RJ(src1) | IMM_I12(src2)));
-               }
-               else {
+               } else {
                        if (is_overflow)
                                FAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));
                        else if (op & SLJIT_SET_Z)
@@ -1361,8 +1507,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                        if (GET_FLAG_TYPE(op) == SLJIT_LESS) {
                                FAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RJ(src1) | IMM_I12(src2)));
                                is_handled = 1;
-                       }
-                       else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) {
+                       } else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) {
                                FAIL_IF(push_inst(compiler, SLTI | RD(OTHER_FLAG) | RJ(src1) | IMM_I12(src2)));
                                is_handled = 1;
                        }
@@ -1372,8 +1517,9 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                        is_handled = 1;
 
                        if (flags & SRC2_IMM) {
-                               FAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG2) | RJ(TMP_ZERO) | IMM_I12(src2)));
-                               src2 = TMP_REG2;
+                               reg = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
+                               FAIL_IF(push_inst(compiler, ADDI_D | RD(reg) | RJ(TMP_ZERO) | IMM_I12(src2)));
+                               src2 = reg;
                                flags &= ~SRC2_IMM;
                        }
 
@@ -1399,8 +1545,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                                        FAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(-src2)));
                                if (!(flags & UNUSED_DEST))
                                        return push_inst(compiler, INST(ADDI, op) | RD(dst) | RJ(src1) | IMM_I12(-src2));
-                       }
-                       else {
+                       } else {
                                if (op & SLJIT_SET_Z)
                                        FAIL_IF(push_inst(compiler, INST(SUB, op) | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));
                                if (!(flags & UNUSED_DEST))
@@ -1420,8 +1565,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                                        FAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(-1)));
                                        FAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RJ(src1) | RK(EQUAL_FLAG)));
                                }
-                       }
-                       else if (op & SLJIT_SET_Z)
+                       } else if (op & SLJIT_SET_Z)
                                FAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(-src2)));
 
                        if (is_overflow || is_carry)
@@ -1430,8 +1574,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                        /* Only the zero flag is needed. */
                        if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
                                FAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(dst) | RJ(src1) | IMM_I12(-src2)));
-               }
-               else {
+               } else {
                        if (is_overflow)
                                FAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));
                        else if (op & SLJIT_SET_Z)
@@ -1468,8 +1611,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                                FAIL_IF(push_inst(compiler, SLTUI | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(src2)));
 
                        FAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(dst) | RJ(src1) | IMM_I12(-src2)));
-               }
-               else {
+               } else {
                        if (is_carry)
                                FAIL_IF(push_inst(compiler, SLTU | RD(EQUAL_FLAG) | RJ(src1) | RK(src2)));
 
@@ -1550,7 +1692,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                        if (GET_OPCODE(op) == SLJIT_ROTL)
                                src2 = word_size - src2;
                        return push_inst(compiler, INST(ROTRI, op) | RD(dst) | RJ(src1) | IMM_I12(src2));
-
                }
 
                if (src2 == TMP_ZERO) {
@@ -1601,7 +1742,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
        sljit_s32 dst_r = TMP_REG2;
        sljit_s32 src1_r;
        sljit_sw src2_r = 0;
-       sljit_s32 sugg_src2_r = TMP_REG2;
+       sljit_s32 src2_tmp_reg = (GET_OPCODE(op) >= SLJIT_OP2_BASE && FAST_IS_REG(src1)) ? TMP_REG1 : TMP_REG2;
 
        if (!(flags & ALT_KEEP_CACHE)) {
                compiler->cache_arg = 0;
@@ -1612,22 +1753,19 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                SLJIT_ASSERT(HAS_FLAGS(op));
                flags |= UNUSED_DEST;
                dst = TMP_REG2;
-       }
-       else if (FAST_IS_REG(dst)) {
+       } else if (FAST_IS_REG(dst)) {
                dst_r = dst;
                flags |= REG_DEST;
                if (flags & MOVE_OP)
-                       sugg_src2_r = dst_r;
-       }
-       else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
+                       src2_tmp_reg = dst_r;
+       } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
                flags |= SLOW_DEST;
 
        if (flags & IMM_OP) {
                if (src2 == SLJIT_IMM && src2w != 0 && src2w <= I12_MAX && src2w >= I12_MIN) {
                        flags |= SRC2_IMM;
                        src2_r = src2w;
-               }
-               else if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && src1w <= I12_MAX && src1w >= I12_MIN) {
+               } else if ((flags & CUMULATIVE_OP) && src1 == SLJIT_IMM && src1w != 0 && src1w <= I12_MAX && src1w >= I12_MIN) {
                        flags |= SRC2_IMM;
                        src2_r = src1w;
 
@@ -1643,16 +1781,14 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
        if (FAST_IS_REG(src1)) {
                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));
                        src1_r = TMP_REG1;
                }
                else
                        src1_r = TMP_ZERO;
-       }
-       else {
+       } else {
                if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w))
                        FAIL_IF(compiler->error);
                else
@@ -1666,14 +1802,12 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                flags |= REG2_SOURCE;
                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));
-                               src2_r = sugg_src2_r;
-                       }
-                       else {
+                               FAIL_IF(load_immediate(compiler, src2_tmp_reg, src2w));
+                               src2_r = src2_tmp_reg;
+                       } else {
                                src2_r = TMP_ZERO;
                                if (flags & MOVE_OP) {
                                        if (dst & SLJIT_MEM)
@@ -1683,31 +1817,29 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                                }
                        }
                }
-       }
-       else {
-               if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w))
+       } else {
+               if (getput_arg_fast(compiler, flags | LOAD_DATA, src2_tmp_reg, src2, src2w))
                        FAIL_IF(compiler->error);
                else
                        flags |= SLOW_SRC2;
 
-               src2_r = sugg_src2_r;
+               src2_r = src2_tmp_reg;
        }
 
        if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
                SLJIT_ASSERT(src2_r == TMP_REG2);
-               if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+               if ((flags & SLOW_DEST) && !can_cache(src2, src2w, src1, src1w) && can_cache(src2, src2w, dst, dstw)) {
+                       FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+                       FAIL_IF(getput_arg(compiler, flags | LOAD_DATA | MEM_USE_TMP2, TMP_REG2, src2, src2w, dst, dstw));
+               } else {
                        FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
                        FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
                }
-               else {
-                       FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
-                       FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
-               }
        }
        else if (flags & SLOW_SRC1)
                FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
        else if (flags & SLOW_SRC2)
-               FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
+               FAIL_IF(getput_arg(compiler, flags | LOAD_DATA | ((src1_r == TMP_REG1) ? MEM_USE_TMP2 : 0), src2_tmp_reg, src2, src2w, dst, dstw));
 
        FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
 
@@ -1778,40 +1910,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
        switch (GET_OPCODE(op)) {
        case SLJIT_MOV:
        case SLJIT_MOV_P:
-               return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);
+               return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, srcw);
 
        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_ZERO, 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_ZERO, 0, src, (src == SLJIT_IMM) ? (sljit_s32)srcw : srcw);
 
        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_ZERO, 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_ZERO, 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_ZERO, 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);
+               return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 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);
+               return emit_op(compiler, op, flags, dst, dstw, TMP_ZERO, 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);
+               return emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_ZERO, 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);
+               return emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_ZERO, 0, src, srcw);
        }
 
        SLJIT_UNREACHABLE();
@@ -1893,6 +2025,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil
        return sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w);
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
+       sljit_s32 dst_reg,
+       sljit_s32 src1, sljit_sw src1w,
+       sljit_s32 src2, sljit_sw src2w)
+{
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
+
+       switch (GET_OPCODE(op)) {
+       case SLJIT_MULADD:
+               SLJIT_SKIP_CHECKS(compiler);
+               FAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), TMP_REG2, 0, src1, src1w, src2, src2w));
+               return push_inst(compiler, ADD_D | RD(dst_reg) | RJ(dst_reg) | RK(TMP_REG2));
+       }
+
+       return SLJIT_SUCCESS;
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
        sljit_s32 dst_reg,
        sljit_s32 src1_reg,
@@ -2045,7 +2195,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 type, slji
        if (type == SLJIT_GP_REGISTER)
                return reg_map[reg];
 
-       if (type != SLJIT_FLOAT_REGISTER)
+       if (type != SLJIT_FLOAT_REGISTER && type != SLJIT_SIMD_REG_128 && type != SLJIT_SIMD_REG_256)
                return -1;
 
        return freg_map[reg];
@@ -2292,7 +2442,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
        switch (GET_OPCODE(op)) {
        case SLJIT_MOV_F64:
                if (src != dst_r) {
-                       if (dst_r != TMP_FREG1)
+                       if (!(dst & SLJIT_MEM))
                                FAIL_IF(push_inst(compiler, FINST(FMOV, op) | FRD(dst_r) | FRJ(src)));
                        else
                                dst_r = src;
@@ -2351,11 +2501,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
        }
 
        if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
-               if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+               if ((dst & SLJIT_MEM) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
-               }
-               else {
+               } else {
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
                }
@@ -2385,7 +2534,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
                break;
        }
 
-       if (dst_r == TMP_FREG2)
+       if (dst_r != dst)
                FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
        return SLJIT_SUCCESS;
 }
@@ -2573,8 +2722,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
        PTR_FAIL_IF(push_inst(compiler, inst));
 
        /* Maximum number of instructions required for generating a constant. */
-       compiler->size += 3;
-
+       compiler->size += JUMP_MAX_SIZE - 1;
        return jump;
 }
 
@@ -2601,6 +2749,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
        struct sljit_jump *jump;
        sljit_s32 flags;
        sljit_ins inst;
+       sljit_s32 src2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
@@ -2618,8 +2767,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
        }
 
        if (src2 & SLJIT_MEM) {
-               PTR_FAIL_IF(emit_op_mem2(compiler, flags, TMP_REG2, src2, src2w, 0, 0));
-               src2 = TMP_REG2;
+               PTR_FAIL_IF(emit_op_mem2(compiler, flags, src2_tmp_reg, src2, src2w, 0, 0));
+               src2 = src2_tmp_reg;
        }
 
        if (src1 == SLJIT_IMM) {
@@ -2633,8 +2782,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
 
        if (src2 == SLJIT_IMM) {
                if (src2w != 0) {
-                       PTR_FAIL_IF(load_immediate(compiler, TMP_REG2, src2w));
-                       src2 = TMP_REG2;
+                       PTR_FAIL_IF(load_immediate(compiler, src2_tmp_reg, src2w));
+                       src2 = src2_tmp_reg;
                }
                else
                        src2 = TMP_ZERO;
@@ -2687,7 +2836,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
        PTR_FAIL_IF(push_inst(compiler, JIRL | RD(TMP_ZERO) | RJ(TMP_REG1) | IMM_I12(0)));
 
        /* Maximum number of instructions required for generating a constant. */
-       compiler->size += 3;
+       compiler->size += JUMP_MAX_SIZE - 1;
 
        return jump;
 }
@@ -2718,7 +2867,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
        FAIL_IF(push_inst(compiler, JIRL | RD((type >= SLJIT_FAST_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | RJ(TMP_REG1) | IMM_I12(0)));
 
        /* Maximum number of instructions required for generating a constant. */
-       compiler->size += 3;
+       compiler->size += JUMP_MAX_SIZE - 1;
 
        return SLJIT_SUCCESS;
 }
@@ -2860,13 +3009,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
                        type ^= 0x1;
                } else {
                        if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {
-                               FAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG2) | RJ(dst_reg) | IMM_I12(0)));
+                               FAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG1) | RJ(dst_reg) | IMM_I12(0)));
 
                                if ((src1 & REG_MASK) == dst_reg)
-                                       src1 = (src1 & ~REG_MASK) | TMP_REG2;
+                                       src1 = (src1 & ~REG_MASK) | TMP_REG1;
 
                                if (OFFS_REG(src1) == dst_reg)
-                                       src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG2);
+                                       src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);
                        }
 
                        FAIL_IF(push_inst(compiler, ADDI_D | RD(dst_reg) | RJ(src2_reg) | IMM_I12(0)));
@@ -2908,15 +3057,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com
                if ((type & ~SLJIT_32) == SLJIT_EQUAL)
                        invert = 1;
                FAIL_IF(push_inst(compiler, MOVGR2CF | FCD(F_OTHER_FLAG) | RJ(EQUAL_FLAG)));
-       }
-       else
+       } else {
+               if (get_jump_instruction(type & ~SLJIT_32) == (BNE | RJ(OTHER_FLAG) | RD(TMP_ZERO)))
+                       invert = 1;
                FAIL_IF(push_inst(compiler, MOVGR2CF | FCD(F_OTHER_FLAG) | RJ(OTHER_FLAG)));
+       }
 
        if (src1 & SLJIT_MEM) {
-               FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, dst_freg, src1, src1w));
+               FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG2, src1, src1w));
                if (invert)
-                       return push_inst(compiler, FSEL | FRD(dst_freg) | FRJ(dst_freg) | FRK(src2_freg) | FCA(F_OTHER_FLAG));
-               return push_inst(compiler, FSEL | FRD(dst_freg) | FRJ(src2_freg) | FRK(dst_freg) | FCA(F_OTHER_FLAG));
+                       return push_inst(compiler, FSEL | FRD(dst_freg) | FRJ(TMP_FREG2) | FRK(src2_freg) | FCA(F_OTHER_FLAG));
+               return push_inst(compiler, FSEL | FRD(dst_freg) | FRJ(src2_freg) | FRK(TMP_FREG2) | FCA(F_OTHER_FLAG));
        } else {
                if (invert)
                        return push_inst(compiler, FSEL | FRD(dst_freg) | FRJ(src1) | FRK(src2_freg) | FCA(F_OTHER_FLAG));
@@ -2982,6 +3133,468 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
 
 #undef TO_ARGW_HI
 
+static sljit_s32 sljit_emit_simd_mem_offset(struct sljit_compiler *compiler, sljit_s32 *mem_ptr, sljit_sw memw)
+{
+       sljit_s32 mem = *mem_ptr;
+
+       if (SLJIT_UNLIKELY(mem & OFFS_REG_MASK)) {
+               *mem_ptr = TMP_REG3;
+               FAIL_IF(push_inst(compiler, SLLI_D | RD(TMP_REG3) | RJ(OFFS_REG(mem)) | IMM_I12(memw & 0x3)));
+               return push_inst(compiler, ADD_D | RD(TMP_REG3) | RJ(TMP_REG3) | RK(mem & REG_MASK));
+       }
+
+       if (!(mem & REG_MASK)) {
+               *mem_ptr = TMP_REG3;
+               return load_immediate(compiler, TMP_REG3, memw);
+       }
+
+       mem &= REG_MASK;
+
+       if (memw == 0) {
+               *mem_ptr = mem;
+               return SLJIT_SUCCESS;
+       }
+
+       *mem_ptr = TMP_REG3;
+
+       FAIL_IF(load_immediate(compiler, TMP_REG3, memw));
+       return push_inst(compiler, ADD_D | RD(TMP_REG3) | RJ(TMP_REG3) | RK(mem));
+}
+
+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_ins ins = 0;
+
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_simd_mov(compiler, type, freg, srcdst, srcdstw));
+
+       ADJUST_LOCAL_OFFSET(srcdst, srcdstw);
+
+       if (reg_size != 5 && reg_size != 4)
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (type & SLJIT_SIMD_TEST)
+               return SLJIT_SUCCESS;
+
+       if (!(srcdst & SLJIT_MEM)) {
+               if (type & SLJIT_SIMD_STORE)
+                       ins = FRD(srcdst) | FRJ(freg) | FRK(freg);
+               else
+                       ins = FRD(freg) | FRJ(srcdst) | FRK(srcdst);
+
+               if (reg_size == 5)
+                       ins |= VOR_V | (sljit_ins)1 << 26;
+               else
+                       ins |= VOR_V;
+
+               return push_inst(compiler, ins);
+       }
+
+       ins = (type & SLJIT_SIMD_STORE) ? VST : VLD;
+
+       if (reg_size == 5)
+               ins = (type & SLJIT_SIMD_STORE) ? XVST : XVLD;
+
+       if (FAST_IS_REG(srcdst) && srcdst >= 0 && (srcdstw >= I12_MIN && srcdstw <= I12_MAX))
+               return push_inst(compiler, ins | FRD(freg) | RJ((sljit_u8)srcdst) | IMM_I12(srcdstw));
+       else {
+               FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));
+               return push_inst(compiler, ins | FRD(freg) | RJ(srcdst) | IMM_I12(0));
+       }
+}
+
+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 = 0;
+
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw));
+
+       ADJUST_LOCAL_OFFSET(src, srcw);
+
+       if (reg_size != 5 && reg_size != 4)
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))
+               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 == 5)
+                       ins = (sljit_ins)1 << 25;
+
+               return push_inst(compiler, VLDREPL | ins | FRD(freg) | RJ(src) | (sljit_ins)1 << (23 - elem_size));
+       }
+
+       if (reg_size == 5)
+               ins = (sljit_ins)1 << 26;
+
+       if (type & SLJIT_SIMD_FLOAT) {
+               if (src == SLJIT_IMM)
+                       return push_inst(compiler, VREPLGR2VR | ins | FRD(freg) | RJ(TMP_ZERO) | (sljit_ins)elem_size << 10);
+
+               FAIL_IF(push_inst(compiler, VREPLVE | ins | FRD(freg) | FRJ(src) | RK(TMP_ZERO) | (sljit_ins)elem_size << 15));
+
+               if (reg_size == 5) {
+                       ins = (sljit_ins)(0x44 << 10);
+                       return push_inst(compiler, XVPERMI | ins | FRD(freg) | FRJ(freg));
+               }
+
+               return SLJIT_SUCCESS;
+       }
+
+       ins |= VREPLGR2VR | (sljit_ins)elem_size << 10;
+
+       if (src == SLJIT_IMM) {
+               FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
+               src = TMP_REG2;
+       }
+
+       return push_inst(compiler, ins | FRD(freg) | RJ(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 = 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 != 5 && reg_size != 4)
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))
+               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 == 5) ? ((sljit_ins)1 << 26) : 0;
+
+               if ((type & SLJIT_SIMD_FLOAT) && freg == srcdst) {
+                       FAIL_IF(push_inst(compiler, VOR_V | ins | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg)));
+                       srcdst = TMP_FREG1;
+                       srcdstw = 0;
+               }
+
+               FAIL_IF(push_inst(compiler, VXOR_V | ins | FRD(freg) | FRJ(freg) | FRK(freg)));
+       }
+
+       if (srcdst & SLJIT_MEM) {
+               FAIL_IF(sljit_emit_simd_mem_offset(compiler, &srcdst, srcdstw));
+
+               if (reg_size == 5)
+                       ins = (sljit_ins)1 << 25;
+
+               if (type & SLJIT_SIMD_STORE) {
+                       ins |= (sljit_ins)lane_index << 18 | (sljit_ins)(1 << (23 - elem_size));
+                       return push_inst(compiler, VSTELM | ins | FRD(freg) | RJ(srcdst));
+               } else {
+                       emit_op_mem(compiler, (elem_size == 3 ? WORD_DATA : (elem_size == 2 ? INT_DATA : (elem_size == 1 ? HALF_DATA : BYTE_DATA))) | LOAD_DATA, TMP_REG1, srcdst | SLJIT_MEM, 0);
+                       srcdst = TMP_REG1;
+                       ins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10;
+
+                       if (reg_size == 5) {
+                               if (elem_size < 2) {
+                                       FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg)));
+                                       if (lane_index >= (2 << (3 - elem_size))) {
+                                               FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(freg) | IMM_I8(1)));
+                                               FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(TMP_FREG1) | RJ(srcdst) | IMM_V(lane_index % (2 << (3 - elem_size)))));
+                                               return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(2));
+                                       } else {
+                                               FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index)));
+                                               return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(18));
+                                       }
+                               } else
+                                       ins = (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26;
+                       }
+
+                       return push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index));
+               }
+       }
+
+       if (type & SLJIT_SIMD_FLOAT) {
+               ins = (reg_size == 5) ? (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26 : (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10;
+
+               if (type & SLJIT_SIMD_STORE) {
+                       FAIL_IF(push_inst(compiler, VPICKVE2GR_U | ins | RD(TMP_REG1) | FRJ(freg) | IMM_V(lane_index)));
+                       return push_inst(compiler, VINSGR2VR | ins | FRD(srcdst) | RJ(TMP_REG1) | IMM_V(0));
+               } else {
+                       FAIL_IF(push_inst(compiler, VPICKVE2GR_U | ins | RD(TMP_REG1) | FRJ(srcdst) | IMM_V(0)));
+                       return push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(TMP_REG1) | IMM_V(lane_index));
+               }
+       }
+
+       if (srcdst == SLJIT_IMM) {
+               FAIL_IF(load_immediate(compiler, TMP_REG1, srcdstw));
+               srcdst = TMP_REG1;
+       }
+
+       if (type & SLJIT_SIMD_STORE) {
+               ins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10;
+
+               if (type & SLJIT_SIMD_LANE_SIGNED)
+                       ins |= (sljit_ins)(VPICKVE2GR_U ^ (0x7 << 18));
+               else
+                       ins |= VPICKVE2GR_U;
+
+               if (reg_size == 5) {
+                       if (elem_size < 2) {
+                               if (lane_index >= (2 << (3 - elem_size))) {
+                                       if (type & SLJIT_SIMD_LANE_SIGNED)
+                                               ins |= (sljit_ins)(VPICKVE2GR_U ^ (0x7 << 18));
+                                       else
+                                               ins |= VPICKVE2GR_U;
+
+                                       FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg)));
+                                       FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(freg) | IMM_I8(1)));
+                                       return push_inst(compiler, ins | RD(srcdst) | FRJ(TMP_FREG1) | IMM_V(lane_index % (2 << (3 - elem_size))));
+                               }
+                       } else {
+                               ins ^= (sljit_ins)1 << (15 - elem_size);
+                               ins |= (sljit_ins)1 << 26;
+                       }
+               }
+
+               return push_inst(compiler, ins | RD(srcdst) | FRJ(freg) | IMM_V(lane_index));
+       } else {
+               ins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10;
+
+               if (reg_size == 5) {
+                       if (elem_size < 2) {
+                               FAIL_IF(push_inst(compiler, VOR_V | (sljit_ins)1 << 26 | FRD(TMP_FREG1) | FRJ(freg) | FRK(freg)));
+                               if (lane_index >= (2 << (3 - elem_size))) {
+                                       FAIL_IF(push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(TMP_FREG1) | FRJ(freg) | IMM_I8(1)));
+                                       FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(TMP_FREG1) | RJ(srcdst) | IMM_V(lane_index % (2 << (3 - elem_size)))));
+                                       return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(2));
+                               } else {
+                                       FAIL_IF(push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index)));
+                                       return push_inst(compiler, XVPERMI | (sljit_ins)1 << 18 | FRD(freg) | FRJ(TMP_FREG1) | IMM_I8(18));
+                               }
+                       } else
+                               ins = (sljit_ins)(0x3f ^ (0x3f >> elem_size)) << 10 | (sljit_ins)1 << 26;
+               }
+
+               return push_inst(compiler, VINSGR2VR | ins | FRD(freg) | RJ(srcdst) | IMM_V(lane_index));
+       }
+
+       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)
+{
+       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_lane_replicate(compiler, type, freg, src, src_lane_index));
+
+       if (reg_size != 5 && reg_size != 4)
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (type & SLJIT_SIMD_TEST)
+               return SLJIT_SUCCESS;
+
+       ins = (sljit_ins)(0x3f ^ (0x1f >> elem_size)) << 10;
+
+       if (reg_size == 5) {
+               FAIL_IF(push_inst(compiler, VREPLVEI | (sljit_ins)1 << 26 | ins | FRD(freg) | FRJ(src) | IMM_V(src_lane_index % (2 << (3 - elem_size)))));
+
+               ins = (src_lane_index < (2 << (3 - elem_size))) ? (sljit_ins)(0x44 << 10) : (sljit_ins)(0xee << 10);
+
+               return push_inst(compiler, XVPERMI | ins | FRD(freg) | FRJ(freg));
+       }
+
+       return push_inst(compiler, VREPLVEI | ins | FRD(freg) | FRJ(src) | IMM_V(src_lane_index));
+}
+
+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_ins ins = 0;
+
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_simd_extend(compiler, type, freg, src, srcw));
+
+       ADJUST_LOCAL_OFFSET(src, srcw);
+
+       if (reg_size != 5 && reg_size != 4)
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (type & SLJIT_SIMD_TEST)
+               return SLJIT_SUCCESS;
+
+       if (src & SLJIT_MEM) {
+               ins = (type & SLJIT_SIMD_STORE) ? VST : VLD;
+
+               if (reg_size == 5)
+                       ins = (type & SLJIT_SIMD_STORE) ? XVST : XVLD;
+
+               if (FAST_IS_REG(src) && src >= 0 && (srcw >= I12_MIN && srcw <= I12_MAX))
+                       FAIL_IF(push_inst(compiler, ins | FRD(freg) | RJ(src) | IMM_I12(srcw)));
+               else {
+                       FAIL_IF(sljit_emit_simd_mem_offset(compiler, &src, srcw));
+                       FAIL_IF(push_inst(compiler, ins | FRD(freg) | RJ(src) | IMM_I12(0)));
+               }
+               src = freg;
+       }
+
+       if (type & SLJIT_SIMD_FLOAT) {
+               if (elem_size != 2 || elem2_size != 3)
+                       return SLJIT_ERR_UNSUPPORTED;
+
+               ins = 0;
+               if (reg_size == 5) {
+                       ins = (sljit_ins)1 << 26;
+                       FAIL_IF(push_inst(compiler, XVPERMI | FRD(src) | FRJ(src) | IMM_I8(16)));
+               }
+
+               return push_inst(compiler, VFCVTL_D_S | ins | FRD(freg) | FRJ(src));
+       }
+
+       ins = (type & SLJIT_SIMD_EXTEND_SIGNED) ? VSLLWIL : (VSLLWIL | (sljit_ins)1 << 18);
+
+       if (reg_size == 5)
+               ins |= (sljit_ins)1 << 26;
+
+       do {
+               if (reg_size == 5)
+                       FAIL_IF(push_inst(compiler, XVPERMI | FRD(src) | FRJ(src) | IMM_I8(16)));
+
+               FAIL_IF(push_inst(compiler, ins | ((sljit_ins)1 << (13 + elem_size)) | FRD(freg) | FRJ(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 = 0;
+       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 != 5 && reg_size != 4)
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (elem_size > 3 || ((type & SLJIT_SIMD_FLOAT) && elem_size < 2))
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (type & SLJIT_SIMD_TEST)
+               return SLJIT_SUCCESS;
+
+       dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+
+       if (reg_size == 5)
+               ins = (sljit_ins)1 << 26;
+
+       FAIL_IF(push_inst(compiler, VMSKLTZ | ins | (sljit_ins)(elem_size << 10) | FRD(TMP_FREG1) | FRJ(freg)));
+
+       FAIL_IF(push_inst(compiler, VPICKVE2GR_U | (sljit_ins)(0x3c << 10) | RD(dst_r) | FRJ(TMP_FREG1)));
+
+       if (reg_size == 5) {
+               FAIL_IF(push_inst(compiler, VPICKVE2GR_U | (sljit_ins)(0x38 << 10) | ins | RD(TMP_REG3) | FRJ(TMP_FREG1) | IMM_V(2)));
+               FAIL_IF(push_inst(compiler, SLLI_W | RD(TMP_REG3) | RJ(TMP_REG3) | IMM_I12(2 << (3 - elem_size))));
+               FAIL_IF(push_inst(compiler, OR | RD(dst_r) | RJ(dst_r) | RK(TMP_REG3)));
+       }
+
+       if (dst_r == TMP_REG2)
+               return emit_op_mem(compiler, ((type & SLJIT_32) ? INT_DATA : WORD_DATA), TMP_REG2, dst, dstw);
+
+       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 != 5 && reg_size != 4)
+               return SLJIT_ERR_UNSUPPORTED;
+
+       if (reg_size == 5 && !(get_cpu_features(GET_HWCAP) & LOONGARCH_HWCAP_LASX))
+               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 = VAND_V;
+               break;
+       case SLJIT_SIMD_OP2_OR:
+               ins = VOR_V;
+               break;
+       case SLJIT_SIMD_OP2_XOR:
+               ins = VXOR_V;
+               break;
+       }
+
+       if (reg_size == 5)
+               ins |= (sljit_ins)1 << 26;
+
+       return push_inst(compiler, ins | FRD(dst_freg) | FRJ(src1_freg) | FRK(src2_freg));
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler *compiler,
        sljit_s32 op,
        sljit_s32 dst_reg,
@@ -2992,9 +3605,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler
        CHECK_ERROR();
        CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));
 
-       if (!(LOONGARCH_FEATURE_LAMCAS & get_cpu_features()))
-               return SLJIT_ERR_UNSUPPORTED;
-
        switch(GET_OPCODE(op)) {
        case SLJIT_MOV_U8:
                ins = LD_BU;
@@ -3029,9 +3639,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
        CHECK_ERROR();
        CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));
 
-       if (!(LOONGARCH_FEATURE_LAMCAS & get_cpu_features()))
-               return SLJIT_ERR_UNSUPPORTED;
-
        switch (GET_OPCODE(op)) {
        case SLJIT_MOV_U8:
                ins = AMCAS_B;
@@ -3128,28 +3735,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
        return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
-       struct sljit_put_label *put_label;
+       struct sljit_jump *jump;
        sljit_s32 dst_r;
 
        CHECK_ERROR_PTR();
-       CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+       CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
        ADJUST_LOCAL_OFFSET(dst, dstw);
 
-       put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
-       PTR_FAIL_IF(!put_label);
-       set_put_label(put_label, compiler, 0);
+       jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+       PTR_FAIL_IF(!jump);
+       set_mov_addr(jump, compiler, 0);
 
        dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
        PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r));
 
-       compiler->size += 3;
+       compiler->size += JUMP_MAX_SIZE - 1;
 
        if (dst & SLJIT_MEM)
                PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
 
-       return put_label;
+       return jump;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
index 9620b945f655ae04e71052f8ebe3718ddd28a058..91153e5f25804bdda88cc8439767f770ba7cc181 100644 (file)
@@ -225,7 +225,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
        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);
+       SLJIT_ASSERT(reg_map[TMP_REG2] == 4 && freg_map[TMP_FREG1] == 12);
 
        arg_types >>= SLJIT_ARG_SHIFT;
 
@@ -370,7 +370,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compile
        } else if (type & SLJIT_CALL_RETURN)
                PTR_FAIL_IF(emit_stack_frame_release(compiler, 0, &ins));
 
-       SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+       SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25);
 
        if (ins == NOP && compiler->delay_slot != UNMOVABLE_INS)
                jump->flags |= IS_MOVABLE;
@@ -441,7 +441,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
                return sljit_emit_ijump(compiler, type, src, srcw);
        }
 
-       SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+       SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25);
 
        if (src == SLJIT_IMM)
                FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
index 52a0d3fb7adfcbd87d0915071589c346fba8c17f..b9f03a7bd24408b3e8793c5a6ee9884f611be28f 100644 (file)
@@ -225,7 +225,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
        sljit_ins prev_ins = *ins_ptr;
        sljit_ins ins = NOP;
 
-       SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12);
+       SLJIT_ASSERT(reg_map[TMP_REG2] == 4 && freg_map[TMP_FREG1] == 12);
 
        arg_types >>= SLJIT_ARG_SHIFT;
 
@@ -309,7 +309,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compile
        if ((type & 0xff) != SLJIT_CALL_REG_ARG)
                PTR_FAIL_IF(call_with_args(compiler, arg_types, &ins));
 
-       SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+       SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25);
 
        if (ins == NOP && compiler->delay_slot != UNMOVABLE_INS)
                jump->flags |= IS_MOVABLE;
@@ -366,7 +366,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
                return sljit_emit_ijump(compiler, type, src, srcw);
        }
 
-       SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
+       SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG1);
 
        if (src == SLJIT_IMM)
                FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
index 807b3474eaddcc295186c15d914340b8d7173e4c..88eb30b7f163b6b333d353abc4e2f54194674f64 100644 (file)
@@ -83,7 +83,7 @@ typedef sljit_u32 sljit_ins;
 #define TMP_REG3       (SLJIT_NUMBER_OF_REGISTERS + 4)
 
 /* For position independent code, t9 must contain the function address. */
-#define PIC_ADDR_REG   TMP_REG2
+#define PIC_ADDR_REG   TMP_REG1
 
 /* Floating point status register. */
 #define FCSR_REG       31
@@ -95,7 +95,7 @@ typedef sljit_u32 sljit_ins;
 #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
+       0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 25, 4, 31, 3, 1
 };
 
 #define TMP_FREG1      (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
@@ -504,7 +504,7 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
        if (jump->flags & JUMP_ADDR)
                target_addr = jump->u.target;
        else {
-               SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+               SLJIT_ASSERT(jump->u.label != NULL);
                target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
        }
 
@@ -635,75 +635,66 @@ static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_
 
 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
 
-static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
+static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)
 {
-       if (max_label < 0x80000000l) {
-               put_label->flags = PATCH_ABS32;
+       sljit_uw addr;
+       SLJIT_UNUSED_ARG(executable_offset);
+
+       if (jump->flags & JUMP_ADDR)
+               addr = jump->u.target;
+       else
+               addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);
+
+       if (addr < 0x80000000l) {
+               jump->flags |= PATCH_ABS32;
                return 1;
        }
 
-       if (max_label < 0x800000000000l) {
-               put_label->flags = PATCH_ABS48;
+       if (addr < 0x800000000000l) {
+               jump->flags |= PATCH_ABS48;
                return 3;
        }
 
-       put_label->flags = 0;
        return 5;
 }
 
 #endif /* SLJIT_CONFIG_MIPS_64 */
 
-static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg)
+static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump)
 {
-       struct sljit_jump *jump;
-       struct sljit_put_label *put_label;
-       sljit_uw flags;
-       sljit_ins *inst;
-       sljit_uw addr;
-
-       if (reg != 0) {
-               jump = (struct sljit_jump*)dst;
-               flags = jump->flags;
-               inst = (sljit_ins*)jump->addr;
-               addr = (flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
-       } else {
-               put_label = (struct sljit_put_label*)dst;
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
-               flags = put_label->flags;
-#endif
-               inst = (sljit_ins*)put_label->addr;
-               addr = put_label->label->addr;
-               reg = *inst;
-       }
+       sljit_uw flags = jump->flags;
+       sljit_ins *ins = (sljit_ins*)jump->addr;
+       sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
+       sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : PIC_ADDR_REG;
 
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-       inst[0] = LUI | T(reg) | IMM(addr >> 16);
+       ins[0] = LUI | T(reg) | IMM(addr >> 16);
 #else /* !SLJIT_CONFIG_MIPS_32 */
        if (flags & PATCH_ABS32) {
                SLJIT_ASSERT(addr < 0x80000000l);
-               inst[0] = LUI | T(reg) | IMM(addr >> 16);
+               ins[0] = LUI | T(reg) | IMM(addr >> 16);
        }
        else if (flags & PATCH_ABS48) {
                SLJIT_ASSERT(addr < 0x800000000000l);
-               inst[0] = LUI | T(reg) | IMM(addr >> 32);
-               inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
-               inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
-               inst += 2;
+               ins[0] = LUI | T(reg) | IMM(addr >> 32);
+               ins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
+               ins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
+               ins += 2;
        }
        else {
-               inst[0] = LUI | T(reg) | IMM(addr >> 48);
-               inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);
-               inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
-               inst[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
-               inst[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);
-               inst += 4;
+               ins[0] = LUI | T(reg) | IMM(addr >> 48);
+               ins[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);
+               ins[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
+               ins[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
+               ins[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);
+               ins += 4;
        }
 #endif /* SLJIT_CONFIG_MIPS_32 */
 
-       inst[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);
+       ins[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
 {
        struct sljit_memory_fragment *buf;
        sljit_ins *code;
@@ -711,77 +702,76 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        sljit_ins *buf_ptr;
        sljit_ins *buf_end;
        sljit_uw word_count;
-       sljit_uw next_addr;
+       SLJIT_NEXT_DEFINE_TYPES;
        sljit_sw executable_offset;
        sljit_uw addr;
-
        struct sljit_label *label;
        struct sljit_jump *jump;
        struct sljit_const *const_;
-       struct sljit_put_label *put_label;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_generate_code(compiler));
        reverse_buf(compiler);
 
-       code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
+       code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
        PTR_FAIL_WITH_EXEC_IF(code);
        buf = compiler->buf;
 
        code_ptr = code;
        word_count = 0;
-       next_addr = 0;
-       executable_offset = SLJIT_EXEC_OFFSET(code);
-
        label = compiler->labels;
        jump = compiler->jumps;
        const_ = compiler->consts;
-       put_label = compiler->put_labels;
+       SLJIT_NEXT_INIT_TYPES();
+       SLJIT_GET_NEXT_MIN();
 
        do {
                buf_ptr = (sljit_ins*)buf->memory;
                buf_end = buf_ptr + (buf->used_size >> 2);
                do {
                        *code_ptr = *buf_ptr++;
-                       if (next_addr == word_count) {
+                       if (next_min_addr == word_count) {
                                SLJIT_ASSERT(!label || label->size >= word_count);
                                SLJIT_ASSERT(!jump || jump->addr >= word_count);
                                SLJIT_ASSERT(!const_ || const_->addr >= word_count);
-                               SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
 
                                /* These structures are ordered by their address. */
-                               if (label && label->size == word_count) {
-                                       label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+                               if (next_min_addr == next_label_size) {
+                                       label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
                                        label->size = (sljit_uw)(code_ptr - code);
                                        label = label->next;
+                                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
                                }
-                               if (jump && jump->addr == word_count) {
+
+                               if (next_min_addr == next_jump_addr) {
+                                       if (!(jump->flags & JUMP_MOV_ADDR)) {
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-                                       word_count += 2;
-#else
-                                       word_count += 6;
-#endif
-                                       jump->addr = (sljit_uw)(code_ptr - 1);
-                                       code_ptr = detect_jump_type(jump, code, executable_offset);
+                                               word_count += 2;
+#else /* !SLJIT_CONFIG_MIPS_32 */
+                                               word_count += 6;
+#endif /* SLJIT_CONFIG_MIPS_32 */
+                                               jump->addr = (sljit_uw)(code_ptr - 1);
+                                               code_ptr = detect_jump_type(jump, code, executable_offset);
+                                       } else {
+                                               jump->addr = (sljit_uw)code_ptr;
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+                                               code_ptr += 1;
+                                               word_count += 1;
+#else /* !SLJIT_CONFIG_MIPS_32 */
+                                               code_ptr += mov_addr_get_length(jump, code, executable_offset);
+                                               word_count += 5;
+#endif /* SLJIT_CONFIG_MIPS_32 */
+                                       }
+
                                        jump = jump->next;
-                               }
-                               if (const_ && const_->addr == word_count) {
+                                       next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+                               } else if (next_min_addr == next_const_addr) {
                                        const_->addr = (sljit_uw)code_ptr;
                                        const_ = const_->next;
+                                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
                                }
-                               if (put_label && put_label->addr == word_count) {
-                                       SLJIT_ASSERT(put_label->label);
-                                       put_label->addr = (sljit_uw)code_ptr;
-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
-                                       code_ptr += 1;
-                                       word_count += 1;
-#else
-                                       code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
-                                       word_count += 5;
-#endif
-                                       put_label = put_label->next;
-                               }
-                               next_addr = compute_next_addr(label, jump, const_, put_label);
+
+                               SLJIT_GET_NEXT_MIN();
                        }
                        code_ptr++;
                        word_count++;
@@ -791,7 +781,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        } while (buf);
 
        if (label && label->size == word_count) {
-               label->addr = (sljit_uw)code_ptr;
+               label->u.addr = (sljit_uw)code_ptr;
                label->size = (sljit_uw)(code_ptr - code);
                label = label->next;
        }
@@ -799,13 +789,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        SLJIT_ASSERT(!label);
        SLJIT_ASSERT(!jump);
        SLJIT_ASSERT(!const_);
-       SLJIT_ASSERT(!put_label);
        SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
 
        jump = compiler->jumps;
        while (jump) {
                do {
-                       addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+                       addr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
                        buf_ptr = (sljit_ins *)jump->addr;
 
                        if (jump->flags & PATCH_B) {
@@ -821,15 +810,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
                                break;
                        }
 
-                       load_addr_to_reg(jump, PIC_ADDR_REG);
+                       load_addr_to_reg(jump);
                } while (0);
-               jump = jump->next;
-       }
 
-       put_label = compiler->put_labels;
-       while (put_label) {
-               load_addr_to_reg(put_label, 0);
-               put_label = put_label->next;
+               jump = jump->next;
        }
 
        compiler->error = SLJIT_ERR_COMPILED;
@@ -932,9 +916,9 @@ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, s
 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)
+#define SELECT_OP(d, w)        (w)
 #else
-#define SELECT_OP(a, b)        (!(op & SLJIT_32) ? a : b)
+#define SELECT_OP(d, w)        (!(op & SLJIT_32) ? (d) : (w))
 #endif
 
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
@@ -1001,9 +985,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
                offset = local_size - SSIZE_OF(sw);
        } else {
                FAIL_IF(load_immediate(compiler, OTHER_FLAG, local_size));
-               FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
+               FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
                FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | TA(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));
-               base = S(TMP_REG2);
+               base = S(TMP_REG1);
                offset = -SSIZE_OF(sw);
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
                local_size = 0;
@@ -1212,8 +1196,8 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit
                if (tmp < frame_size)
                        tmp = frame_size;
 
-               FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size - tmp));
-               FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG1) | D(SLJIT_SP), DR(SLJIT_SP)));
+               FAIL_IF(load_immediate(compiler, DR(TMP_REG2), local_size - tmp));
+               FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | T(TMP_REG2) | D(SLJIT_SP), DR(SLJIT_SP)));
                local_size = tmp;
        }
 
@@ -1711,7 +1695,7 @@ static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit
 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)
 {
-       sljit_s32 is_overflow, is_carry, carry_src_ar, is_handled;
+       sljit_s32 is_overflow, is_carry, carry_src_ar, is_handled, reg;
        sljit_ins op_imm, op_v;
 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
        sljit_ins ins, op_dimm, op_dimm32, op_dv;
@@ -1963,8 +1947,9 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                        is_handled = 1;
 
                        if (flags & SRC2_IMM) {
-                               FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
-                               src2 = TMP_REG2;
+                               reg = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
+                               FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(reg) | IMM(src2), DR(reg)));
+                               src2 = reg;
                                flags &= ~SRC2_IMM;
                        }
 
@@ -2283,7 +2268,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
        sljit_s32 dst_r = TMP_REG2;
        sljit_s32 src1_r;
        sljit_sw src2_r = 0;
-       sljit_s32 sugg_src2_r = TMP_REG2;
+       sljit_s32 src2_tmp_reg = (GET_OPCODE(op) >= SLJIT_OP2_BASE && FAST_IS_REG(src1)) ? TMP_REG1 : TMP_REG2;
 
        if (!(flags & ALT_KEEP_CACHE)) {
                compiler->cache_arg = 0;
@@ -2299,7 +2284,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                dst_r = dst;
                flags |= REG_DEST;
                if (flags & MOVE_OP)
-                       sugg_src2_r = dst_r;
+                       src2_tmp_reg = dst_r;
        }
        else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
                flags |= SLOW_DEST;
@@ -2351,8 +2336,8 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
        else if (src2 == SLJIT_IMM) {
                if (!(flags & SRC2_IMM)) {
                        if (src2w) {
-                               FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w));
-                               src2_r = sugg_src2_r;
+                               FAIL_IF(load_immediate(compiler, DR(src2_tmp_reg), src2w));
+                               src2_r = src2_tmp_reg;
                        }
                        else {
                                src2_r = 0;
@@ -2366,16 +2351,16 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                }
        }
        else {
-               if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w))
+               if (getput_arg_fast(compiler, flags | LOAD_DATA, DR(src2_tmp_reg), src2, src2w))
                        FAIL_IF(compiler->error);
                else
                        flags |= SLOW_SRC2;
-               src2_r = sugg_src2_r;
+               src2_r = src2_tmp_reg;
        }
 
        if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
                SLJIT_ASSERT(src2_r == TMP_REG2);
-               if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+               if ((flags & SLOW_DEST) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
                        FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
                        FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
                }
@@ -2387,7 +2372,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
        else if (flags & SLOW_SRC1)
                FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
        else if (flags & SLOW_SRC2)
-               FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(sugg_src2_r), src2, src2w, dst, dstw));
+               FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, DR(src2_tmp_reg), src2, src2w, dst, dstw));
 
        FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
 
@@ -2659,12 +2644,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil
 
 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
 #define SELECT_OP3(op, src2w, D, D32, W) (((op & SLJIT_32) ? (W) : ((src2w) < 32) ? (D) : (D32)) | (((sljit_ins)src2w & 0x1f) << 6))
-#define SELECT_OP2(op, D, W) ((op & SLJIT_32) ? (W) : (D))
 #else /* !SLJIT_CONFIG_MIPS_64 */
 #define SELECT_OP3(op, src2w, D, D32, W) ((W) | ((sljit_ins)(src2w) << 6))
-#define SELECT_OP2(op, D, W) (W)
 #endif /* SLJIT_CONFIG_MIPS_64 */
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
+       sljit_s32 dst_reg,
+       sljit_s32 src1, sljit_sw src1w,
+       sljit_s32 src2, sljit_sw src2w)
+{
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
+
+       switch (GET_OPCODE(op)) {
+       case SLJIT_MULADD:
+               SLJIT_SKIP_CHECKS(compiler);
+               FAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), TMP_REG2, 0, src1, src1w, src2, src2w));
+               return push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst_reg) | T(TMP_REG2) | D(dst_reg), DR(dst_reg));
+       }
+
+       return SLJIT_SUCCESS;
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
        sljit_s32 dst_reg,
        sljit_s32 src1_reg,
@@ -2718,18 +2719,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
                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)));
+               FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src3) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
                src3 = TMP_REG2;
        }
 
        if (is_left) {
-               ins1 = SELECT_OP2(op, DSRL, SRL);
-               ins2 = SELECT_OP2(op, DSLLV, SLLV);
-               ins3 = SELECT_OP2(op, DSRLV, SRLV);
+               ins1 = SELECT_OP(DSRL, SRL);
+               ins2 = SELECT_OP(DSLLV, SLLV);
+               ins3 = SELECT_OP(DSRLV, SRLV);
        } else {
-               ins1 = SELECT_OP2(op, DSLL, SLL);
-               ins2 = SELECT_OP2(op, DSRLV, SRLV);
-               ins3 = SELECT_OP2(op, DSLLV, SLLV);
+               ins1 = SELECT_OP(DSLL, SLL);
+               ins2 = SELECT_OP(DSRLV, SRLV);
+               ins3 = SELECT_OP(DSLLV, SLLV);
        }
 
        FAIL_IF(push_inst(compiler, ins2 | S(src3) | T(src1_reg) | D(dst_reg), DR(dst_reg)));
@@ -2739,14 +2740,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
                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(src3) | D(TMP_REG2), DR(TMP_REG2)));
+               FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src3) | D(TMP_REG2), DR(TMP_REG2)));
 
        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
-#undef SELECT_OP2
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
        sljit_s32 src, sljit_sw srcw)
@@ -3103,7 +3103,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
        switch (GET_OPCODE(op)) {
        case SLJIT_MOV_F64:
                if (src != dst_r) {
-                       if (dst_r != TMP_FREG1)
+                       if (!(dst & SLJIT_MEM))
                                FAIL_IF(push_inst(compiler, MOV_fmt(FMT(op)) | FS(src) | FD(dst_r), MOVABLE_INS));
                        else
                                dst_r = src;
@@ -3162,11 +3162,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
        }
 
        if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
-               if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+               if ((dst & SLJIT_MEM) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, src1, src1w));
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
-               }
-               else {
+               } else {
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
                }
@@ -3361,10 +3360,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
                PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
 
        if (type <= SLJIT_JUMP)
-               PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
+               PTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
        else {
                jump->flags |= IS_JAL;
-               PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
+               PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
        }
 
        jump->addr = compiler->size;
@@ -3392,8 +3391,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
 #define RESOLVE_IMM2() \
        if (src2 == SLJIT_IMM) { \
                if (src2w) { \
-                       PTR_FAIL_IF(load_immediate(compiler, DR(TMP_REG2), src2w)); \
-                       src2 = TMP_REG2; \
+                       PTR_FAIL_IF(load_immediate(compiler, DR(src2_tmp_reg), src2w)); \
+                       src2 = src2_tmp_reg; \
                } \
                else \
                        src2 = 0; \
@@ -3406,6 +3405,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
        struct sljit_jump *jump;
        sljit_s32 flags;
        sljit_ins inst;
+       sljit_s32 src2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
@@ -3426,8 +3426,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
        }
 
        if (src2 & SLJIT_MEM) {
-               PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0));
-               src2 = TMP_REG2;
+               PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(src2_tmp_reg), src2, src2w, 0, 0));
+               src2 = src2_tmp_reg;
        }
 
        jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
@@ -3515,7 +3515,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
                PTR_FAIL_IF(push_inst(compiler, (type == SLJIT_EQUAL ? BNE : BEQ) | S(TMP_REG1) | TA(0) | BRANCH_LENGTH, UNMOVABLE_INS));
        }
 
-       PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
+       PTR_FAIL_IF(push_inst(compiler, JR | S(PIC_ADDR_REG), UNMOVABLE_INS));
        jump->addr = compiler->size;
        PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
 
@@ -3553,11 +3553,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
                if (compiler->delay_slot != UNMOVABLE_INS)
                        jump->flags |= IS_MOVABLE;
 
-               src = TMP_REG2;
+               src = PIC_ADDR_REG;
        } else if (src & SLJIT_MEM) {
                ADJUST_LOCAL_OFFSET(src, srcw);
-               FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), src, srcw));
-               src = TMP_REG2;
+               FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
+               src = PIC_ADDR_REG;
        }
 
        if (type <= SLJIT_JUMP)
@@ -3755,8 +3755,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
 
 #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;
+               FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w));
+               src1 = TMP_REG1;
        } else if (src1 == SLJIT_IMM) {
 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
                if (type & SLJIT_32)
@@ -3784,13 +3784,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
                        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)));
+                               FAIL_IF(push_inst(compiler, ADDU_W | S(dst_reg) | TA(0) | D(TMP_REG1), DR(TMP_REG1)));
 
                                if ((src1 & REG_MASK) == dst_reg)
-                                       src1 = (src1 & ~REG_MASK) | TMP_REG2;
+                                       src1 = (src1 & ~REG_MASK) | TMP_REG1;
 
                                if (OFFS_REG(src1) == dst_reg)
-                                       src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG2);
+                                       src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);
                        }
 
                        FAIL_IF(push_inst(compiler, mov_ins | S(src2_reg) | TA(0) | D(dst_reg), DR(dst_reg)));
@@ -3847,8 +3847,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com
 
 #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;
+               FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, FR(TMP_FREG2), src1, src1w));
+               src1 = TMP_FREG2;
        }
 
        return push_inst(compiler, get_select_cc(type, 1) | FMT(type) | FS(src1) | FD(dst_freg), MOVABLE_INS);
@@ -4231,18 +4231,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
        return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
-       struct sljit_put_label *put_label;
+       struct sljit_jump *jump;
        sljit_s32 dst_r;
 
        CHECK_ERROR_PTR();
-       CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+       CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
        ADJUST_LOCAL_OFFSET(dst, dstw);
 
-       put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
-       PTR_FAIL_IF(!put_label);
-       set_put_label(put_label, compiler, 0);
+       jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+       PTR_FAIL_IF(!jump);
+       set_mov_addr(jump, compiler, 0);
 
        dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
        PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r, UNMOVABLE_INS));
@@ -4255,5 +4255,5 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
        if (dst & SLJIT_MEM)
                PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw));
 
-       return put_label;
+       return jump;
 }
index 54977f02e3e78aaf1e03fd2f7ea8f312f8d1ea5c..1f17d90423eb62e538d00b5dddb8f1bbb137fa65 100644 (file)
@@ -98,7 +98,7 @@ static void ppc_cache_flush(sljit_ins *from, sljit_ins *to)
 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
 #define TMP_CALL_REG   (SLJIT_NUMBER_OF_REGISTERS + 5)
 #else
-#define TMP_CALL_REG   TMP_REG2
+#define TMP_CALL_REG   TMP_REG1
 #endif
 
 #define TMP_FREG1      (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
@@ -310,24 +310,23 @@ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
        return SLJIT_SUCCESS;
 }
 
-static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
+static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
 {
        sljit_sw diff;
        sljit_uw target_addr;
-       sljit_uw extra_jump_flags;
 
 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL) && (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
        if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_CALL))
-               return 0;
+               goto exit;
 #else
        if (jump->flags & SLJIT_REWRITABLE_JUMP)
-               return 0;
+               goto exit;
 #endif
 
        if (jump->flags & JUMP_ADDR)
                target_addr = jump->u.target;
        else {
-               SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+               SLJIT_ASSERT(jump->u.label != NULL);
                target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
        }
 
@@ -336,101 +335,256 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in
                goto keep_address;
 #endif
 
-       diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr) - executable_offset) & ~0x3l;
+       diff = (sljit_sw)target_addr - (sljit_sw)code_ptr - executable_offset;
 
-       extra_jump_flags = 0;
        if (jump->flags & IS_COND) {
                if (diff <= 0x7fff && diff >= -0x8000) {
                        jump->flags |= PATCH_B;
-                       return 1;
+                       return code_ptr;
                }
                if (target_addr <= 0xffff) {
                        jump->flags |= PATCH_B | PATCH_ABS_B;
-                       return 1;
+                       return code_ptr;
                }
-               extra_jump_flags = REMOVE_COND;
 
                diff -= SSIZE_OF(ins);
        }
 
        if (diff <= 0x01ffffff && diff >= -0x02000000) {
-               jump->flags |= PATCH_B | extra_jump_flags;
-               return 1;
+               jump->flags |= PATCH_B;
+       } else if (target_addr <= 0x01ffffff) {
+               jump->flags |= PATCH_B | PATCH_ABS_B;
        }
 
-       if (target_addr <= 0x03ffffff) {
-               jump->flags |= PATCH_B | PATCH_ABS_B | extra_jump_flags;
-               return 1;
+       if (jump->flags & PATCH_B) {
+               if (!(jump->flags & IS_COND))
+                       return code_ptr;
+
+               code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);
+               code_ptr[1] = Bx;
+               jump->addr += sizeof(sljit_ins);
+               jump->flags -= IS_COND;
+               return code_ptr + 1;
        }
 
 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 #if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
 keep_address:
-#endif
-       if (target_addr <= 0x7fffffff) {
+#endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
+       if (target_addr < 0x80000000l) {
                jump->flags |= PATCH_ABS32;
-               return 1;
+               code_ptr[2] = MTCTR | S(TMP_CALL_REG);
+               code_ptr[3] = code_ptr[0];
+               return code_ptr + 3;
        }
 
-       if (target_addr <= 0x7fffffffffffl) {
+       if (target_addr < 0x800000000000l) {
                jump->flags |= PATCH_ABS48;
-               return 1;
+               code_ptr[4] = MTCTR | S(TMP_CALL_REG);
+               code_ptr[5] = code_ptr[0];
+               return code_ptr + 5;
        }
-#endif
+#endif /* SLJIT_CONFIG_PPC_64 */
 
-       return 0;
+exit:
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+       code_ptr[2] = MTCTR | S(TMP_CALL_REG);
+       code_ptr[3] = code_ptr[0];
+#else /* !SLJIT_CONFIG_PPC_32 */
+       code_ptr[5] = MTCTR | S(TMP_CALL_REG);
+       code_ptr[6] = code_ptr[0];
+#endif /* SLJIT_CONFIG_PPC_32 */
+       return code_ptr + JUMP_MAX_SIZE - 1;
 }
 
 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 
-static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
+static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code, sljit_sw executable_offset)
 {
-       if (max_label < 0x100000000l) {
-               put_label->flags = 0;
+       sljit_uw addr;
+       SLJIT_UNUSED_ARG(executable_offset);
+
+       SLJIT_ASSERT(jump->flags < ((sljit_uw)5 << JUMP_SIZE_SHIFT));
+       if (jump->flags & JUMP_ADDR)
+               addr = jump->u.target;
+       else
+               addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);
+
+       if (addr < 0x80000000l) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));
+               jump->flags |= PATCH_ABS32;
                return 1;
        }
 
-       if (max_label < 0x1000000000000l) {
-               put_label->flags = 1;
+       if (addr < 0x800000000000l) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));
+               jump->flags |= PATCH_ABS48;
                return 3;
        }
 
-       put_label->flags = 2;
+       SLJIT_ASSERT(jump->flags >= ((sljit_uw)4 << JUMP_SIZE_SHIFT));
        return 4;
 }
 
-static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label)
-{
-       sljit_uw addr = put_label->label->addr;
-       sljit_ins *inst = (sljit_ins *)put_label->addr;
-       sljit_u32 reg = *inst;
+#endif /* SLJIT_CONFIG_PPC_64 */
 
-       if (put_label->flags == 0) {
-               SLJIT_ASSERT(addr < 0x100000000l);
-               inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 16);
-       }
-       else {
-               if (put_label->flags == 1) {
-                       SLJIT_ASSERT(addr < 0x1000000000000l);
-                       inst[0] = ORI | S(TMP_ZERO) | A(reg) | IMM(addr >> 32);
+static void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset)
+{
+       sljit_uw flags = jump->flags;
+       sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
+       sljit_ins *ins = (sljit_ins*)jump->addr;
+       sljit_s32 reg;
+       SLJIT_UNUSED_ARG(executable_offset);
+
+       if (flags & PATCH_B) {
+               if (flags & IS_COND) {
+                       if (!(flags & PATCH_ABS_B)) {
+                               addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(ins, executable_offset);
+                               SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);
+                               ins[0] = BCx | ((sljit_ins)addr & 0xfffc) | (ins[0] & 0x03ff0001);
+                       } else {
+                               SLJIT_ASSERT(addr <= 0xffff);
+                               ins[0] = BCx | ((sljit_ins)addr & 0xfffc) | 0x2 | ((*ins) & 0x03ff0001);
+                       }
+                       return;
                }
-               else {
-                       inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 48);
-                       inst[1] = ORI | S(reg) | A(reg) | IMM((addr >> 32) & 0xffff);
-                       inst++;
+
+               if (!(flags & PATCH_ABS_B)) {
+                       addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(ins, executable_offset);
+                       SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);
+                       ins[0] = Bx | ((sljit_ins)addr & 0x03fffffc) | (ins[0] & 0x1);
+               } else {
+                       SLJIT_ASSERT(addr <= 0x03ffffff);
+                       ins[0] = Bx | ((sljit_ins)addr & 0x03fffffc) | 0x2 | (ins[0] & 0x1);
                }
+               return;
+       }
+
+       reg = (flags & JUMP_MOV_ADDR) ? (sljit_s32)ins[0] : TMP_CALL_REG;
+
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+       ins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 16);
+       ins[1] = ORI | S(reg) | A(reg) | IMM(addr);
+#else /* !SLJIT_CONFIG_PPC_32 */
+
+       /* The TMP_ZERO cannot be used because it is restored for tail calls. */
+       if (flags & PATCH_ABS32) {
+               SLJIT_ASSERT(addr < 0x80000000l);
+               ins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 16);
+               ins[1] = ORI | S(reg) | A(reg) | IMM(addr);
+               return;
+       }
 
-               inst[1] = SLDI(32) | S(reg) | A(reg);
-               inst[2] = ORIS | S(reg) | A(reg) | IMM((addr >> 16) & 0xffff);
-               inst += 2;
+       if (flags & PATCH_ABS48) {
+               SLJIT_ASSERT(addr < 0x800000000000l);
+               ins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 32);
+               ins[1] = ORI | S(reg) | A(reg) | IMM(addr >> 16);
+               ins[2] = SLDI(16) | S(reg) | A(reg);
+               ins[3] = ORI | S(reg) | A(reg) | IMM(addr);
+               return;
        }
 
-       inst[1] = ORI | S(reg) | A(reg) | IMM(addr & 0xffff);
+       ins[0] = ADDIS | D(reg) | A(0) | IMM(addr >> 48);
+       ins[1] = ORI | S(reg) | A(reg) | IMM(addr >> 32);
+       ins[2] = SLDI(32) | S(reg) | A(reg);
+       ins[3] = ORIS | S(reg) | A(reg) | IMM(addr >> 16);
+       ins[4] = ORI | S(reg) | A(reg) | IMM(addr);
+#endif /* SLJIT_CONFIG_PPC_32 */
 }
 
+static void reduce_code_size(struct sljit_compiler *compiler)
+{
+       struct sljit_label *label;
+       struct sljit_jump *jump;
+       struct sljit_const *const_;
+       SLJIT_NEXT_DEFINE_TYPES;
+       sljit_uw total_size;
+       sljit_uw size_reduce = 0;
+       sljit_sw diff;
+
+       label = compiler->labels;
+       jump = compiler->jumps;
+       const_ = compiler->consts;
+       SLJIT_NEXT_INIT_TYPES();
+
+       while (1) {
+               SLJIT_GET_NEXT_MIN();
+
+               if (next_min_addr == SLJIT_MAX_ADDRESS)
+                       break;
+
+               if (next_min_addr == next_label_size) {
+                       label->size -= size_reduce;
+
+                       label = label->next;
+                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
+               }
+
+               if (next_min_addr == next_const_addr) {
+                       const_->addr -= size_reduce;
+                       const_ = const_->next;
+                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
+                       continue;
+               }
+
+               if (next_min_addr != next_jump_addr)
+                       continue;
+
+               jump->addr -= size_reduce;
+               if (!(jump->flags & JUMP_MOV_ADDR)) {
+                       total_size = JUMP_MAX_SIZE - 1;
+
+                       if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {
+                               if (jump->flags & JUMP_ADDR) {
+                                       if (jump->u.target <= 0x01ffffff)
+                                               total_size = 1 - 1;
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+                                       else if (jump->u.target < 0x80000000l)
+                                               total_size = 4 - 1;
+                                       else if (jump->u.target < 0x800000000000l)
+                                               total_size = 6 - 1;
+#endif /* SLJIT_CONFIG_PPC_64 */
+                               } else {
+                                       /* Unit size: instruction. */
+                                       diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;
+
+                                       if (jump->flags & IS_COND) {
+                                               if (diff <= (0x7fff / SSIZE_OF(ins)) && diff >= (-0x8000 / SSIZE_OF(ins)))
+                                                       total_size = 1 - 1;
+                                               else if ((diff - 1) <= (0x01ffffff / SSIZE_OF(ins)) && (diff - 1) >= (-0x02000000 / SSIZE_OF(ins)))
+                                                       total_size = 2 - 1;
+                                       } else if (diff <= (0x01ffffff / SSIZE_OF(ins)) && diff >= (-0x02000000 / SSIZE_OF(ins)))
+                                               total_size = 1 - 1;
+                               }
+                       }
+
+                       size_reduce += (JUMP_MAX_SIZE - 1) - total_size;
+                       jump->flags |= total_size << JUMP_SIZE_SHIFT;
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+               } else {
+                       total_size = (sljit_uw)4 << JUMP_SIZE_SHIFT;
+
+                       if (jump->flags & JUMP_ADDR) {
+                               if (jump->u.target < 0x80000000l) {
+                                       total_size = (sljit_uw)1 << JUMP_SIZE_SHIFT;
+                                       size_reduce += 3;
+                               } else if (jump->u.target < 0x800000000000l) {
+                                       total_size = (sljit_uw)3 << JUMP_SIZE_SHIFT;
+                                       size_reduce += 1;
+                               }
+                       }
+                       jump->flags |= total_size;
 #endif /* SLJIT_CONFIG_PPC_64 */
+               }
 
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+               jump = jump->next;
+               next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+       }
+
+       compiler->size -= size_reduce;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
 {
        struct sljit_memory_fragment *buf;
        sljit_ins *code;
@@ -438,18 +592,17 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        sljit_ins *buf_ptr;
        sljit_ins *buf_end;
        sljit_uw word_count;
-       sljit_uw next_addr;
+       SLJIT_NEXT_DEFINE_TYPES;
        sljit_sw executable_offset;
-       sljit_uw addr;
 
        struct sljit_label *label;
        struct sljit_jump *jump;
        struct sljit_const *const_;
-       struct sljit_put_label *put_label;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_generate_code(compiler));
-       reverse_buf(compiler);
+
+       reduce_code_size(compiler);
 
 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
        /* add to compiler->size additional instruction space to hold the trampoline and padding */
@@ -459,93 +612,64 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
 #endif
 #endif
-       code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
+       code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
        PTR_FAIL_WITH_EXEC_IF(code);
+
+       reverse_buf(compiler);
        buf = compiler->buf;
 
        code_ptr = code;
        word_count = 0;
-       next_addr = 0;
-       executable_offset = SLJIT_EXEC_OFFSET(code);
-
        label = compiler->labels;
        jump = compiler->jumps;
        const_ = compiler->consts;
-       put_label = compiler->put_labels;
+       SLJIT_NEXT_INIT_TYPES();
+       SLJIT_GET_NEXT_MIN();
 
        do {
                buf_ptr = (sljit_ins*)buf->memory;
                buf_end = buf_ptr + (buf->used_size >> 2);
                do {
                        *code_ptr = *buf_ptr++;
-                       if (next_addr == word_count) {
+                       if (next_min_addr == word_count) {
                                SLJIT_ASSERT(!label || label->size >= word_count);
                                SLJIT_ASSERT(!jump || jump->addr >= word_count);
                                SLJIT_ASSERT(!const_ || const_->addr >= word_count);
-                               SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
 
                                /* These structures are ordered by their address. */
-                               if (label && label->size == word_count) {
+                               if (next_min_addr == next_label_size) {
                                        /* Just recording the address. */
-                                       label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+                                       label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
                                        label->size = (sljit_uw)(code_ptr - code);
                                        label = label->next;
+                                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
                                }
-                               if (jump && jump->addr == word_count) {
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-                                       jump->addr = (sljit_uw)(code_ptr - 3);
-#else
-                                       jump->addr = (sljit_uw)(code_ptr - 6);
-#endif
-                                       if (detect_jump_type(jump, code_ptr, code, executable_offset)) {
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-                                               code_ptr[-3] = code_ptr[0];
-                                               code_ptr -= 3;
-#else
-                                               if (jump->flags & PATCH_ABS32) {
-                                                       code_ptr -= 3;
-                                                       code_ptr[-1] = code_ptr[2];
-                                                       code_ptr[0] = code_ptr[3];
-                                               }
-                                               else if (jump->flags & PATCH_ABS48) {
-                                                       code_ptr--;
-                                                       code_ptr[-1] = code_ptr[0];
-                                                       code_ptr[0] = code_ptr[1];
-                                                       /* rldicr rX,rX,32,31 -> rX,rX,16,47 */
-                                                       SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6);
-                                                       code_ptr[-3] ^= 0x8422;
-                                                       /* oris -> ori */
-                                                       code_ptr[-2] ^= 0x4000000;
-                                               }
-                                               else {
-                                                       code_ptr[-6] = code_ptr[0];
-                                                       code_ptr -= 6;
-                                               }
-#endif
-                                               if (jump->flags & REMOVE_COND) {
-                                                       code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);
-                                                       code_ptr++;
-                                                       jump->addr += sizeof(sljit_ins);
-                                                       code_ptr[0] = Bx;
-                                                       jump->flags -= IS_COND;
-                                               }
+
+                               if (next_min_addr == next_jump_addr) {
+                                       if (!(jump->flags & JUMP_MOV_ADDR)) {
+                                               word_count += jump->flags >> JUMP_SIZE_SHIFT;
+                                               jump->addr = (sljit_uw)code_ptr;
+                                               code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
+                                               SLJIT_ASSERT(((sljit_uw)code_ptr - jump->addr <= (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins)));
+                                       } else {
+                                               jump->addr = (sljit_uw)code_ptr;
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+                                               word_count += jump->flags >> JUMP_SIZE_SHIFT;
+                                               code_ptr += mov_addr_get_length(jump, code, executable_offset);
+#else /* !SLJIT_CONFIG_PPC_64 */
+                                               word_count++;
+                                               code_ptr++;
+#endif /* SLJIT_CONFIG_PPC_64 */
                                        }
                                        jump = jump->next;
-                               }
-                               if (const_ && const_->addr == word_count) {
+                                       next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+                               } else if (next_min_addr == next_const_addr) {
                                        const_->addr = (sljit_uw)code_ptr;
                                        const_ = const_->next;
+                                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
                                }
-                               if (put_label && put_label->addr == word_count) {
-                                       SLJIT_ASSERT(put_label->label);
-                                       put_label->addr = (sljit_uw)code_ptr;
-#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
-                                       code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
-                                       word_count += 4;
-#endif
-                                       put_label = put_label->next;
-                               }
-                               next_addr = compute_next_addr(label, jump, const_, put_label);
+
+                               SLJIT_GET_NEXT_MIN();
                        }
                        code_ptr++;
                        word_count++;
@@ -555,7 +679,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        } while (buf);
 
        if (label && label->size == word_count) {
-               label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+               label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
                label->size = (sljit_uw)(code_ptr - code);
                label = label->next;
        }
@@ -563,7 +687,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        SLJIT_ASSERT(!label);
        SLJIT_ASSERT(!jump);
        SLJIT_ASSERT(!const_);
-       SLJIT_ASSERT(!put_label);
 
 #if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
        SLJIT_ASSERT(code_ptr - code <= (sljit_sw)(compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins))));
@@ -573,84 +696,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
 
        jump = compiler->jumps;
        while (jump) {
-               do {
-                       addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
-                       buf_ptr = (sljit_ins *)jump->addr;
-
-                       if (jump->flags & PATCH_B) {
-                               if (jump->flags & IS_COND) {
-                                       if (!(jump->flags & PATCH_ABS_B)) {
-                                               addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
-                                               SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000);
-                                               *buf_ptr = BCx | ((sljit_ins)addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001);
-                                       }
-                                       else {
-                                               SLJIT_ASSERT(addr <= 0xffff);
-                                               *buf_ptr = BCx | ((sljit_ins)addr & 0xfffc) | 0x2 | ((*buf_ptr) & 0x03ff0001);
-                                       }
-                               }
-                               else {
-                                       if (!(jump->flags & PATCH_ABS_B)) {
-                                               addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
-                                               SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000);
-                                               *buf_ptr = Bx | ((sljit_ins)addr & 0x03fffffc) | ((*buf_ptr) & 0x1);
-                                       }
-                                       else {
-                                               SLJIT_ASSERT(addr <= 0x03ffffff);
-                                               *buf_ptr = Bx | ((sljit_ins)addr & 0x03fffffc) | 0x2 | ((*buf_ptr) & 0x1);
-                                       }
-                               }
-                               break;
-                       }
-
-                       /* Set the fields of immediate loads. */
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-                       SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1]) & 0xffff) == 0);
-                       buf_ptr[0] |= (sljit_ins)(addr >> 16) & 0xffff;
-                       buf_ptr[1] |= (sljit_ins)addr & 0xffff;
-#else
-                       if (jump->flags & PATCH_ABS32) {
-                               SLJIT_ASSERT(addr <= 0x7fffffff);
-                               SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1]) & 0xffff) == 0);
-                               buf_ptr[0] |= (sljit_ins)(addr >> 16) & 0xffff;
-                               buf_ptr[1] |= (sljit_ins)addr & 0xffff;
-                               break;
-                       }
-
-                       if (jump->flags & PATCH_ABS48) {
-                               SLJIT_ASSERT(addr <= 0x7fffffffffff);
-                               SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1] | buf_ptr[3]) & 0xffff) == 0);
-                               buf_ptr[0] |= (sljit_ins)(addr >> 32) & 0xffff;
-                               buf_ptr[1] |= (sljit_ins)(addr >> 16) & 0xffff;
-                               buf_ptr[3] |= (sljit_ins)addr & 0xffff;
-                               break;
-                       }
-
-                       SLJIT_ASSERT(((buf_ptr[0] | buf_ptr[1] | buf_ptr[3] | buf_ptr[4]) & 0xffff) == 0);
-                       buf_ptr[0] |= (sljit_ins)(addr >> 48) & 0xffff;
-                       buf_ptr[1] |= (sljit_ins)(addr >> 32) & 0xffff;
-                       buf_ptr[3] |= (sljit_ins)(addr >> 16) & 0xffff;
-                       buf_ptr[4] |= (sljit_ins)addr & 0xffff;
-#endif
-               } while (0);
+               generate_jump_or_mov_addr(jump, executable_offset);
                jump = jump->next;
        }
 
-       put_label = compiler->put_labels;
-       while (put_label) {
-#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-               addr = put_label->label->addr;
-               buf_ptr = (sljit_ins *)put_label->addr;
-
-               SLJIT_ASSERT((buf_ptr[0] & 0xfc1f0000) == ADDIS && (buf_ptr[1] & 0xfc000000) == ORI);
-               buf_ptr[0] |= (addr >> 16) & 0xffff;
-               buf_ptr[1] |= addr & 0xffff;
-#else
-               put_label_set(put_label);
-#endif
-               put_label = put_label->next;
-       }
-
        compiler->error = SLJIT_ERR_COMPILED;
        compiler->executable_offset = executable_offset;
 
@@ -671,11 +720,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
 
 #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
 }
@@ -937,14 +984,16 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit
        sljit_s32 i, tmp, base, offset;
        sljit_s32 local_size = compiler->local_size;
 
+       SLJIT_ASSERT(TMP_CALL_REG != TMP_REG2);
+
        base = SLJIT_SP;
        if (local_size > STACK_MAX_DISTANCE) {
-               base = TMP_REG1;
+               base = TMP_REG2;
                if (local_size > 2 * STACK_MAX_DISTANCE + LR_SAVE_OFFSET) {
                        FAIL_IF(push_inst(compiler, STACK_LOAD | D(base) | A(SLJIT_SP) | IMM(0)));
                        local_size = 0;
                } else {
-                       FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG1) | A(SLJIT_SP) | IMM(local_size - STACK_MAX_DISTANCE)));
+                       FAIL_IF(push_inst(compiler, ADDI | D(TMP_REG2) | A(SLJIT_SP) | IMM(local_size - STACK_MAX_DISTANCE)));
                        local_size = STACK_MAX_DISTANCE;
                }
        }
@@ -986,7 +1035,7 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit
        if (local_size > 0)
                return push_inst(compiler, ADDI | D(SLJIT_SP) | A(base) | IMM(local_size));
 
-       SLJIT_ASSERT(base == TMP_REG1);
+       SLJIT_ASSERT(base == TMP_REG2);
        return push_inst(compiler, OR | S(base) | A(SLJIT_SP) | B(base));
 }
 
@@ -1253,7 +1302,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
        sljit_s32 dst_r = TMP_REG2;
        sljit_s32 src1_r;
        sljit_s32 src2_r;
-       sljit_s32 sugg_src2_r = TMP_REG2;
+       sljit_s32 src2_tmp_reg = (!(input_flags & ALT_SIGN_EXT) && GET_OPCODE(op) >= SLJIT_OP2_BASE && FAST_IS_REG(src1)) ? TMP_REG1 : TMP_REG2;
        sljit_s32 flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_SIGN_EXT | ALT_SET_FLAGS);
 
        /* Destination check. */
@@ -1264,24 +1313,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                flags |= REG_DEST;
 
                if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
-                       sugg_src2_r = dst_r;
-       }
-
-       /* Source 1. */
-       if (FAST_IS_REG(src1)) {
-               src1_r = src1;
-               flags |= REG1_SOURCE;
-       }
-       else if (src1 == SLJIT_IMM) {
-               src1_r = TMP_ZERO;
-               if (src1w != 0) {
-                       FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
-                       src1_r = TMP_REG1;
-               }
-       }
-       else {
-               FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
-               src1_r = TMP_REG1;
+                       src2_tmp_reg = dst_r;
        }
 
        /* Source 2. */
@@ -1291,17 +1323,30 @@ 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));
-                       src2_r = sugg_src2_r;
+                       FAIL_IF(load_immediate(compiler, src2_tmp_reg, src2w));
+                       src2_r = src2_tmp_reg;
                }
+       } else {
+               FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, src2_tmp_reg, src2, src2w, TMP_REG1));
+               src2_r = src2_tmp_reg;
        }
-       else {
-               FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, TMP_REG2));
-               src2_r = sugg_src2_r;
+
+       /* Source 1. */
+       if (FAST_IS_REG(src1)) {
+               src1_r = src1;
+               flags |= REG1_SOURCE;
+       } else if (src1 == SLJIT_IMM) {
+               src1_r = TMP_ZERO;
+               if (src1w != 0) {
+                       FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
+                       src1_r = TMP_REG1;
+               }
+       } else {
+               FAIL_IF(emit_op_mem(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
+               src1_r = TMP_REG1;
        }
 
        FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
@@ -1757,7 +1802,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
                compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB;
 
                if (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_LESS_EQUAL) {
-                       if (dst == TMP_REG2) {
+                       if (dst == TMP_REG1) {
                                if (TEST_UL_IMM(src2, src2w)) {
                                        compiler->imm = (sljit_ins)src2w & 0xffff;
                                        return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0);
@@ -1772,7 +1817,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
                        return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1 | ALT_FORM3, dst, dstw, src1, src1w, src2, src2w);
                }
 
-               if (dst == TMP_REG2 && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {
+               if (dst == TMP_REG1 && GET_FLAG_TYPE(op) <= SLJIT_SIG_LESS_EQUAL) {
                        if (TEST_SL_IMM(src2, src2w)) {
                                compiler->imm = (sljit_ins)src2w & 0xffff;
                                return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
@@ -1911,13 +1956,31 @@ 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, TMP_REG1, 0, src1, src1w, src2, src2w);
 }
 
 #undef TEST_ADD_FORM1
 #undef TEST_SUB_FORM2
 #undef TEST_SUB_FORM3
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
+       sljit_s32 dst_reg,
+       sljit_s32 src1, sljit_sw src1w,
+       sljit_s32 src2, sljit_sw src2w)
+{
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
+
+       switch (GET_OPCODE(op)) {
+       case SLJIT_MULADD:
+               SLJIT_SKIP_CHECKS(compiler);
+               FAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), TMP_REG2, 0, src1, src1w, src2, src2w));
+               return push_inst(compiler, ADD | D(dst_reg) | A(dst_reg) | B(TMP_REG2));
+       }
+
+       return SLJIT_SUCCESS;
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
        sljit_s32 dst_reg,
        sljit_s32 src1_reg,
@@ -2228,7 +2291,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
                /* Fall through. */
        case SLJIT_MOV_F64:
                if (src != dst_r) {
-                       if (dst_r != TMP_FREG1)
+                       if (!(dst & SLJIT_MEM))
                                FAIL_IF(push_inst(compiler, FMR | FD(dst_r) | FB(src)));
                        else
                                dst_r = src;
@@ -2268,7 +2331,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
        }
 
        if (src2 & SLJIT_MEM) {
-               FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG2));
+               FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, TMP_REG1));
                src2 = TMP_FREG2;
        }
 
@@ -2451,7 +2514,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
        type &= 0xff;
 
        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)));
+               PTR_FAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG2) | A(TMP_ZERO) | B(TMP_ZERO)));
 
        /* In PPC, we don't need to touch the arguments. */
        if (type < SLJIT_JUMP)
@@ -2461,10 +2524,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
                jump->flags |= IS_CALL;
 #endif
 
-       PTR_FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
-       PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_CALL_REG)));
        jump->addr = compiler->size;
        PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
+
+       /* Maximum number of instructions required for generating a constant. */
+       compiler->size += JUMP_MAX_SIZE - 1;
        return jump;
 }
 
@@ -2498,18 +2562,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 (FAST_IS_REG(src)) {
-#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
-               if (type >= SLJIT_CALL && src != TMP_CALL_REG) {
-                       FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
-                       src_r = TMP_CALL_REG;
-               }
-               else
-                       src_r = src;
-#else /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
-               src_r = src;
-#endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
-       } else if (src == SLJIT_IMM) {
+       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);
@@ -2521,8 +2574,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
                        jump->flags |= IS_CALL;
 #endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
 
-               FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
-               src_r = TMP_CALL_REG;
+               jump->addr = compiler->size;
+               FAIL_IF(push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0)));
+
+               /* Maximum number of instructions required for generating a constant. */
+               compiler->size += JUMP_MAX_SIZE - 1;
+               return SLJIT_SUCCESS;
+       }
+
+       if (FAST_IS_REG(src)) {
+#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
+               if (type >= SLJIT_CALL && src != TMP_CALL_REG) {
+                       FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
+                       src_r = TMP_CALL_REG;
+               } else
+                       src_r = src;
+#else /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
+               src_r = src;
+#endif /* SLJIT_PASS_ENTRY_ADDR_TO_CALL */
        } else {
                ADJUST_LOCAL_OFFSET(src, srcw);
                FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_CALL_REG, src, srcw, TMP_CALL_REG));
@@ -2530,8 +2599,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
        }
 
        FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
-       if (jump)
-               jump->addr = compiler->size;
        return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0));
 }
 
@@ -2748,13 +2815,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
                                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)));
+                               FAIL_IF(push_inst(compiler, OR | S(dst_reg) | A(TMP_REG1) | B(dst_reg)));
 
                                if ((src1 & REG_MASK) == dst_reg)
-                                       src1 = (src1 & ~REG_MASK) | TMP_REG2;
+                                       src1 = (src1 & ~REG_MASK) | TMP_REG1;
 
                                if (OFFS_REG(src1) == dst_reg)
-                                       src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG2);
+                                       src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);
                        }
 
                        FAIL_IF(push_inst(compiler, OR | S(src2_reg) | A(dst_reg) | B(src2_reg)));
@@ -3061,31 +3128,31 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
        return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
-       struct sljit_put_label *put_label;
+       struct sljit_jump *jump;
        sljit_s32 dst_r;
 
        CHECK_ERROR_PTR();
-       CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+       CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
        ADJUST_LOCAL_OFFSET(dst, dstw);
 
-       put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
-       PTR_FAIL_IF(!put_label);
-       set_put_label(put_label, compiler, 0);
+       jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+       PTR_FAIL_IF(!jump);
+       set_mov_addr(jump, compiler, 0);
 
        dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+       PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r));
 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
-       PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
+       compiler->size++;
 #else
-       PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r));
        compiler->size += 4;
 #endif
 
        if (dst & SLJIT_MEM)
                PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
 
-       return put_label;
+       return jump;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
index 64bd411d9d3a0f10dd4dddc75a672bd9a9d37cba..d86100a80ceffcf474e5598e1d0dcd3304c36f30 100644 (file)
@@ -181,24 +181,23 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
        if (jump->flags & JUMP_ADDR)
                target_addr = jump->u.target;
        else {
-               SLJIT_ASSERT(jump->flags & JUMP_LABEL);
+               SLJIT_ASSERT(jump->u.label != NULL);
                target_addr = (sljit_uw)(code + jump->u.label->size) + (sljit_uw)executable_offset;
        }
 
        diff = (sljit_sw)target_addr - (sljit_sw)inst - executable_offset;
 
        if (jump->flags & IS_COND) {
-               inst--;
                diff += SSIZE_OF(ins);
 
                if (diff >= BRANCH_MIN && diff <= BRANCH_MAX) {
-                       jump->flags |= PATCH_B;
+                       inst--;
                        inst[0] = (inst[0] & 0x1fff07f) ^ 0x1000;
+                       jump->flags |= PATCH_B;
                        jump->addr = (sljit_uw)inst;
                        return inst;
                }
 
-               inst++;
                diff -= SSIZE_OF(ins);
        }
 
@@ -265,83 +264,109 @@ exit:
 
 #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
 
-static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
+static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
 {
-       if (max_label <= (sljit_uw)S32_MAX) {
-               put_label->flags = PATCH_ABS32;
+       sljit_uw addr;
+       sljit_sw diff;
+       SLJIT_UNUSED_ARG(executable_offset);
+
+       SLJIT_ASSERT(jump->flags < ((sljit_uw)6 << JUMP_SIZE_SHIFT));
+       if (jump->flags & JUMP_ADDR)
+               addr = jump->u.target;
+       else
+               addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code + jump->u.label->size, executable_offset);
+
+       diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+       if (diff >= S32_MIN && diff <= S32_MAX) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));
+               jump->flags |= PATCH_REL32;
+               return 1;
+       }
+
+       if (addr <= S32_MAX) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));
+               jump->flags |= PATCH_ABS32;
                return 1;
        }
 
-       if (max_label <= S44_MAX) {
-               put_label->flags = PATCH_ABS44;
+       if (addr <= S44_MAX) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));
+               jump->flags |= PATCH_ABS44;
                return 3;
        }
 
-       if (max_label <= S52_MAX) {
-               put_label->flags = PATCH_ABS52;
+       if (addr <= S52_MAX) {
+               SLJIT_ASSERT(jump->flags >= ((sljit_uw)4 << JUMP_SIZE_SHIFT));
+               jump->flags |= PATCH_ABS52;
                return 4;
        }
 
-       put_label->flags = 0;
+       SLJIT_ASSERT(jump->flags >= ((sljit_uw)5 << JUMP_SIZE_SHIFT));
        return 5;
 }
 
 #endif /* SLJIT_CONFIG_RISCV_64 */
 
-static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg)
+static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw executable_offset)
 {
-       struct sljit_jump *jump = NULL;
-       struct sljit_put_label *put_label;
-       sljit_uw flags;
-       sljit_ins *inst;
+       sljit_uw flags = jump->flags;
+       sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
+       sljit_ins *ins = (sljit_ins*)jump->addr;
+       sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : TMP_REG1;
 #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
        sljit_sw high;
 #endif
-       sljit_uw addr;
+       SLJIT_UNUSED_ARG(executable_offset);
 
-       if (reg != 0) {
-               jump = (struct sljit_jump*)dst;
-               flags = jump->flags;
-               inst = (sljit_ins*)jump->addr;
-               addr = (flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
-       } else {
-               put_label = (struct sljit_put_label*)dst;
 #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
-               flags = put_label->flags;
-#endif
-               inst = (sljit_ins*)put_label->addr;
-               addr = put_label->label->addr;
-               reg = *inst;
+       if (flags & PATCH_REL32) {
+               addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(ins, executable_offset);
+
+               SLJIT_ASSERT((sljit_sw)addr >= S32_MIN && (sljit_sw)addr <= S32_MAX);
+
+               if ((addr & 0x800) != 0)
+                       addr += 0x1000;
+
+               ins[0] = AUIPC | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
+
+               if (!(flags & JUMP_MOV_ADDR)) {
+                       SLJIT_ASSERT((ins[1] & 0x707f) == JALR);
+                       ins[1] = (ins[1] & 0xfffff) | IMM_I(addr);
+               } else
+                       ins[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr);
+               return;
        }
+#endif
 
        if ((addr & 0x800) != 0)
                addr += 0x1000;
 
 #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-       inst[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
+       ins[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
 #else /* !SLJIT_CONFIG_RISCV_32 */
 
        if (flags & PATCH_ABS32) {
                SLJIT_ASSERT(addr <= S32_MAX);
-               inst[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
+               ins[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
        } else if (flags & PATCH_ABS44) {
                high = (sljit_sw)addr >> 12;
                SLJIT_ASSERT((sljit_uw)high <= 0x7fffffff);
 
                if (high > S32_MAX) {
                        SLJIT_ASSERT((high & 0x800) != 0);
-                       inst[0] = LUI | RD(reg) | (sljit_ins)0x80000000u;
-                       inst[1] = XORI | RD(reg) | RS1(reg) | IMM_I(high);
+                       ins[0] = LUI | RD(reg) | (sljit_ins)0x80000000u;
+                       ins[1] = XORI | RD(reg) | RS1(reg) | IMM_I(high);
                } else {
                        if ((high & 0x800) != 0)
                                high += 0x1000;
 
-                       inst[0] = LUI | RD(reg) | (sljit_ins)(high & ~0xfff);
-                       inst[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(high);
+                       ins[0] = LUI | RD(reg) | (sljit_ins)(high & ~0xfff);
+                       ins[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(high);
                }
 
-               inst[2] = SLLI | RD(reg) | RS1(reg) | IMM_I(12);
-               inst += 2;
+               ins[2] = SLLI | RD(reg) | RS1(reg) | IMM_I(12);
+               ins += 2;
        } else {
                high = (sljit_sw)addr >> 32;
 
@@ -350,30 +375,128 @@ static SLJIT_INLINE void load_addr_to_reg(void *dst, sljit_u32 reg)
 
                if (flags & PATCH_ABS52) {
                        SLJIT_ASSERT(addr <= S52_MAX);
-                       inst[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high << 12);
+                       ins[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++;
+                       ins[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff);
+                       ins[1] = ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high);
+                       ins++;
                }
 
-               inst[1] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
-               inst[2] = SLLI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I((flags & PATCH_ABS52) ? 20 : 32);
-               inst[3] = XOR | RD(reg) | RS1(reg) | RS2(TMP_REG3);
-               inst += 3;
+               ins[1] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
+               ins[2] = SLLI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I((flags & PATCH_ABS52) ? 20 : 32);
+               ins[3] = XOR | RD(reg) | RS1(reg) | RS2(TMP_REG3);
+               ins += 3;
        }
 #endif /* !SLJIT_CONFIG_RISCV_32 */
 
-       if (jump != NULL) {
-               SLJIT_ASSERT((inst[1] & 0x707f) == JALR);
-               inst[1] = (inst[1] & 0xfffff) | IMM_I(addr);
+       if (!(flags & JUMP_MOV_ADDR)) {
+               SLJIT_ASSERT((ins[1] & 0x707f) == JALR);
+               ins[1] = (ins[1] & 0xfffff) | IMM_I(addr);
        } else
-               inst[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr);
+               ins[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr);
+}
+
+static void reduce_code_size(struct sljit_compiler *compiler)
+{
+       struct sljit_label *label;
+       struct sljit_jump *jump;
+       struct sljit_const *const_;
+       SLJIT_NEXT_DEFINE_TYPES;
+       sljit_uw total_size;
+       sljit_uw size_reduce = 0;
+       sljit_sw diff;
+
+       label = compiler->labels;
+       jump = compiler->jumps;
+       const_ = compiler->consts;
+       SLJIT_NEXT_INIT_TYPES();
+
+       while (1) {
+               SLJIT_GET_NEXT_MIN();
+
+               if (next_min_addr == SLJIT_MAX_ADDRESS)
+                       break;
+
+               if (next_min_addr == next_label_size) {
+                       label->size -= size_reduce;
+
+                       label = label->next;
+                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
+               }
+
+               if (next_min_addr == next_const_addr) {
+                       const_->addr -= size_reduce;
+                       const_ = const_->next;
+                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
+                       continue;
+               }
+
+               if (next_min_addr != next_jump_addr)
+                       continue;
+
+               jump->addr -= size_reduce;
+               if (!(jump->flags & JUMP_MOV_ADDR)) {
+                       total_size = JUMP_MAX_SIZE;
+
+                       if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {
+                               if (jump->flags & JUMP_ADDR) {
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+                                       if (jump->u.target <= S32_MAX)
+                                               total_size = 2;
+                                       else if (jump->u.target <= S44_MAX)
+                                               total_size = 4;
+                                       else if (jump->u.target <= S52_MAX)
+                                               total_size = 5;
+#endif /* SLJIT_CONFIG_RISCV_64 */
+                               } else {
+                                       /* Unit size: instruction. */
+                                       diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;
+
+                                       if ((jump->flags & IS_COND) && (diff + 1) <= (BRANCH_MAX / SSIZE_OF(ins)) && (diff + 1) >= (BRANCH_MIN / SSIZE_OF(ins)))
+                                               total_size = 0;
+                                       else if (diff >= (JUMP_MIN / SSIZE_OF(ins)) && diff <= (JUMP_MAX / SSIZE_OF(ins)))
+                                               total_size = 1;
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+                                       else if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins)))
+                                               total_size = 2;
+#endif /* SLJIT_CONFIG_RISCV_64 */
+                               }
+                       }
+
+                       size_reduce += JUMP_MAX_SIZE - total_size;
+                       jump->flags |= total_size << JUMP_SIZE_SHIFT;
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+               } else {
+                       total_size = 5;
+
+                       if (!(jump->flags & JUMP_ADDR)) {
+                               /* Real size minus 1. Unit size: instruction. */
+                               diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;
+
+                               if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins)))
+                                       total_size = 1;
+                       } else if (jump->u.target < S32_MAX)
+                               total_size = 1;
+                       else if (jump->u.target < S44_MAX)
+                               total_size = 3;
+                       else if (jump->u.target <= S52_MAX)
+                               total_size = 4;
+
+                       size_reduce += 5 - total_size;
+                       jump->flags |= total_size << JUMP_SIZE_SHIFT;
+#endif /* !SLJIT_CONFIG_RISCV_64 */
+               }
+
+               jump = jump->next;
+               next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+       }
+
+       compiler->size -= size_reduce;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
 {
        struct sljit_memory_fragment *buf;
        sljit_ins *code;
@@ -381,77 +504,78 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        sljit_ins *buf_ptr;
        sljit_ins *buf_end;
        sljit_uw word_count;
-       sljit_uw next_addr;
+       SLJIT_NEXT_DEFINE_TYPES;
        sljit_sw executable_offset;
        sljit_uw addr;
 
        struct sljit_label *label;
        struct sljit_jump *jump;
        struct sljit_const *const_;
-       struct sljit_put_label *put_label;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_generate_code(compiler));
-       reverse_buf(compiler);
 
-       code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
+       reduce_code_size(compiler);
+
+       code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
        PTR_FAIL_WITH_EXEC_IF(code);
+
+       reverse_buf(compiler);
        buf = compiler->buf;
 
        code_ptr = code;
        word_count = 0;
-       next_addr = 0;
-       executable_offset = SLJIT_EXEC_OFFSET(code);
-
        label = compiler->labels;
        jump = compiler->jumps;
        const_ = compiler->consts;
-       put_label = compiler->put_labels;
+       SLJIT_NEXT_INIT_TYPES();
+       SLJIT_GET_NEXT_MIN();
 
        do {
                buf_ptr = (sljit_ins*)buf->memory;
                buf_end = buf_ptr + (buf->used_size >> 2);
                do {
                        *code_ptr = *buf_ptr++;
-                       if (next_addr == word_count) {
+                       if (next_min_addr == word_count) {
                                SLJIT_ASSERT(!label || label->size >= word_count);
                                SLJIT_ASSERT(!jump || jump->addr >= word_count);
                                SLJIT_ASSERT(!const_ || const_->addr >= word_count);
-                               SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
 
                                /* These structures are ordered by their address. */
-                               if (label && label->size == word_count) {
-                                       label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+                               if (next_min_addr == next_label_size) {
+                                       label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
                                        label->size = (sljit_uw)(code_ptr - code);
                                        label = label->next;
+                                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
                                }
-                               if (jump && jump->addr == word_count) {
+
+                               if (next_min_addr == next_jump_addr) {
+                                       if (!(jump->flags & JUMP_MOV_ADDR)) {
+                                               word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT);
+                                               jump->addr = (sljit_uw)code_ptr;
+                                               code_ptr = detect_jump_type(jump, code, executable_offset);
+                                               SLJIT_ASSERT((jump->flags & PATCH_B) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins)));
+                                       } else {
 #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-                                       word_count += 1;
-#else
-                                       word_count += 5;
-#endif
-                                       jump->addr = (sljit_uw)code_ptr;
-                                       code_ptr = detect_jump_type(jump, code, executable_offset);
+                                               word_count += 1;
+                                               jump->addr = (sljit_uw)code_ptr;
+                                               code_ptr += 1;
+#else /* !SLJIT_CONFIG_RISCV_32 */
+                                               word_count += jump->flags >> JUMP_SIZE_SHIFT;
+                                               addr = (sljit_uw)code_ptr;
+                                               code_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);
+                                               jump->addr = addr;
+#endif /* SLJIT_CONFIG_RISCV_32 */
+                                       }
                                        jump = jump->next;
-                               }
-                               if (const_ && const_->addr == word_count) {
+                                       next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+                               } else if (next_min_addr == next_const_addr) {
                                        const_->addr = (sljit_uw)code_ptr;
                                        const_ = const_->next;
+                                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
                                }
-                               if (put_label && put_label->addr == word_count) {
-                                       SLJIT_ASSERT(put_label->label);
-                                       put_label->addr = (sljit_uw)code_ptr;
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-                                       code_ptr += 1;
-                                       word_count += 1;
-#else
-                                       code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
-                                       word_count += 5;
-#endif
-                                       put_label = put_label->next;
-                               }
-                               next_addr = compute_next_addr(label, jump, const_, put_label);
+
+                               SLJIT_GET_NEXT_MIN();
                        }
                        code_ptr++;
                        word_count++;
@@ -461,7 +585,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        } while (buf);
 
        if (label && label->size == word_count) {
-               label->addr = (sljit_uw)code_ptr;
+               label->u.addr = (sljit_uw)code_ptr;
                label->size = (sljit_uw)(code_ptr - code);
                label = label->next;
        }
@@ -469,18 +593,17 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        SLJIT_ASSERT(!label);
        SLJIT_ASSERT(!jump);
        SLJIT_ASSERT(!const_);
-       SLJIT_ASSERT(!put_label);
        SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
 
        jump = compiler->jumps;
        while (jump) {
                do {
-                       if (!(jump->flags & (PATCH_B | PATCH_J | PATCH_REL32))) {
-                               load_addr_to_reg(jump, TMP_REG1);
+                       if (!(jump->flags & (PATCH_B | PATCH_J)) || (jump->flags & JUMP_MOV_ADDR)) {
+                               load_addr_to_reg(jump, executable_offset);
                                break;
                        }
 
-                       addr = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+                       addr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
                        buf_ptr = (sljit_ins *)jump->addr;
                        addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
 
@@ -491,31 +614,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
                                break;
                        }
 
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
-                       if (jump->flags & PATCH_REL32) {
-                               SLJIT_ASSERT((sljit_sw)addr >= S32_MIN && (sljit_sw)addr <= S32_MAX);
-
-                               if ((addr & 0x800) != 0)
-                                       addr += 0x1000;
-
-                               buf_ptr[0] = AUIPC | RD(TMP_REG1) | (sljit_ins)((sljit_sw)addr & ~0xfff);
-                               SLJIT_ASSERT((buf_ptr[1] & 0x707f) == JALR);
-                               buf_ptr[1] |= IMM_I(addr);
-                               break;
-                       }
-#endif
-
                        SLJIT_ASSERT((sljit_sw)addr >= JUMP_MIN && (sljit_sw)addr <= JUMP_MAX);
                        addr = (addr & 0xff000) | ((addr & 0x800) << 9) | ((addr & 0x7fe) << 20) | ((addr & 0x100000) << 11);
                        buf_ptr[0] = JAL | RD((jump->flags & IS_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | (sljit_ins)addr;
                } while (0);
-               jump = jump->next;
-       }
 
-       put_label = compiler->put_labels;
-       while (put_label) {
-               load_addr_to_reg(put_label, 0);
-               put_label = put_label->next;
+               jump = jump->next;
        }
 
        compiler->error = SLJIT_ERR_COMPILED;
@@ -599,6 +703,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
 #define SLOW_SRC1      0x08000
 #define SLOW_SRC2      0x10000
 #define SLOW_DEST      0x20000
+#define MEM_USE_TMP2   0x40000
 
 #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
 #define STACK_STORE    SW
@@ -883,7 +988,6 @@ static sljit_s32 push_mem_inst(struct sljit_compiler *compiler, sljit_s32 flags,
 /* Can perform an operation using at most 1 instruction. */
 static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
 {
-
        SLJIT_ASSERT(arg & SLJIT_MEM);
 
        if (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
@@ -928,7 +1032,7 @@ static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, slj
 static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
 {
        sljit_s32 base = arg & REG_MASK;
-       sljit_s32 tmp_r = TMP_REG1;
+       sljit_s32 tmp_r = (flags & MEM_USE_TMP2) ? TMP_REG2 : TMP_REG1;
        sljit_sw offset, argw_hi;
 
        SLJIT_ASSERT(arg & SLJIT_MEM);
@@ -937,11 +1041,6 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
                next_argw = 0;
        }
 
-       /* 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) && reg == TMP_REG2)
-               tmp_r = reg;
-
        if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
                argw &= 0x3;
 
@@ -1187,7 +1286,7 @@ static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit
 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)
 {
-       sljit_s32 is_overflow, is_carry, carry_src_r, is_handled;
+       sljit_s32 is_overflow, is_carry, carry_src_r, is_handled, reg;
        sljit_ins op_imm, op_reg;
 #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
        sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5;
@@ -1197,20 +1296,20 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
 
        switch (GET_OPCODE(op)) {
        case SLJIT_MOV:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if (dst != src2)
                        return push_inst(compiler, ADDI | RD(dst) | RS1(src2) | IMM_I(0));
                return SLJIT_SUCCESS;
 
        case SLJIT_MOV_U8:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
                        return push_inst(compiler, ANDI | RD(dst) | RS1(src2) | IMM_I(0xff));
                SLJIT_ASSERT(dst == src2);
                return SLJIT_SUCCESS;
 
        case SLJIT_MOV_S8:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
                        FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(24)));
                        return push_inst(compiler, SRAI | WORD | RD(dst) | RS1(dst) | IMM_EXTEND(24));
@@ -1219,7 +1318,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                return SLJIT_SUCCESS;
 
        case SLJIT_MOV_U16:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
                        FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16)));
                        return push_inst(compiler, SRLI | WORD | RD(dst) | RS1(dst) | IMM_EXTEND(16));
@@ -1228,7 +1327,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                return SLJIT_SUCCESS;
 
        case SLJIT_MOV_S16:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
                        FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16)));
                        return push_inst(compiler, SRAI | WORD | RD(dst) | RS1(dst) | IMM_EXTEND(16));
@@ -1238,7 +1337,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
 
 #if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
        case SLJIT_MOV_U32:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
                        FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(src2) | IMM_I(32)));
                        return push_inst(compiler, SRLI | RD(dst) | RS1(dst) | IMM_I(32));
@@ -1247,7 +1346,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                return SLJIT_SUCCESS;
 
        case SLJIT_MOV_S32:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
                        return push_inst(compiler, ADDI | 0x8 | RD(dst) | RS1(src2) | IMM_I(0));
                SLJIT_ASSERT(dst == src2);
@@ -1256,7 +1355,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
 
        case SLJIT_CLZ:
        case SLJIT_CTZ:
-               SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
                return emit_clz_ctz(compiler, op, dst, src2);
 
        case SLJIT_REV:
@@ -1264,17 +1363,17 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
 #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));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(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));
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(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);
+               SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM) && dst != TMP_REG1);
                FAIL_IF(emit_rev(compiler, op, dst, src2));
                if (dst == TMP_REG2)
                        return SLJIT_SUCCESS;
@@ -1402,8 +1501,9 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
                        is_handled = 1;
 
                        if (flags & SRC2_IMM) {
-                               FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG2) | RS1(TMP_ZERO) | IMM_I(src2)));
-                               src2 = TMP_REG2;
+                               reg = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
+                               FAIL_IF(push_inst(compiler, ADDI | RD(reg) | RS1(TMP_ZERO) | IMM_I(src2)));
+                               src2 = reg;
                                flags &= ~SRC2_IMM;
                        }
 
@@ -1631,7 +1731,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
        sljit_s32 dst_r = TMP_REG2;
        sljit_s32 src1_r;
        sljit_sw src2_r = 0;
-       sljit_s32 sugg_src2_r = TMP_REG2;
+       sljit_s32 src2_tmp_reg = (GET_OPCODE(op) >= SLJIT_OP2_BASE && FAST_IS_REG(src1)) ? TMP_REG1 : TMP_REG2;
 
        if (!(flags & ALT_KEEP_CACHE)) {
                compiler->cache_arg = 0;
@@ -1647,7 +1747,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                dst_r = dst;
                flags |= REG_DEST;
                if (flags & MOVE_OP)
-                       sugg_src2_r = dst_r;
+                       src2_tmp_reg = dst_r;
        }
        else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
                flags |= SLOW_DEST;
@@ -1673,16 +1773,14 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
        if (FAST_IS_REG(src1)) {
                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;
                }
                else
                        src1_r = TMP_ZERO;
-       }
-       else {
+       } else {
                if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w))
                        FAIL_IF(compiler->error);
                else
@@ -1696,14 +1794,12 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                flags |= REG2_SOURCE;
                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));
-                               src2_r = sugg_src2_r;
-                       }
-                       else {
+                               FAIL_IF(load_immediate(compiler, src2_tmp_reg, src2w, TMP_REG3));
+                               src2_r = src2_tmp_reg;
+                       } else {
                                src2_r = TMP_ZERO;
                                if (flags & MOVE_OP) {
                                        if (dst & SLJIT_MEM)
@@ -1713,30 +1809,28 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
                                }
                        }
                }
-       }
-       else {
-               if (getput_arg_fast(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w))
+       } else {
+               if (getput_arg_fast(compiler, flags | LOAD_DATA, src2_tmp_reg, src2, src2w))
                        FAIL_IF(compiler->error);
                else
                        flags |= SLOW_SRC2;
-               src2_r = sugg_src2_r;
+               src2_r = src2_tmp_reg;
        }
 
        if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
                SLJIT_ASSERT(src2_r == TMP_REG2);
-               if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+               if ((flags & SLOW_DEST) && !can_cache(src2, src2w, src1, src1w) && can_cache(src2, src2w, dst, dstw)) {
+                       FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
+                       FAIL_IF(getput_arg(compiler, flags | LOAD_DATA | MEM_USE_TMP2, TMP_REG2, src2, src2w, dst, dstw));
+               } else {
                        FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
                        FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
                }
-               else {
-                       FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w));
-                       FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw));
-               }
        }
        else if (flags & SLOW_SRC1)
                FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
        else if (flags & SLOW_SRC2)
-               FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw));
+               FAIL_IF(getput_arg(compiler, flags | LOAD_DATA | ((src1_r == TMP_REG1) ? MEM_USE_TMP2 : 0), src2_tmp_reg, src2, src2w, dst, dstw));
 
        FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
 
@@ -1819,42 +1913,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
        case SLJIT_MOV32:
 #endif
        case SLJIT_MOV_P:
-               return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_REG1, 0, src, srcw);
+               return emit_op(compiler, SLJIT_MOV, WORD_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 0, src, srcw);
 
 #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_ZERO, 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_ZERO, 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_ZERO, 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_ZERO, 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_ZERO, 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);
+               return emit_op(compiler, op, HALF_DATA | SIGNED_DATA | MOVE_OP, dst, dstw, TMP_ZERO, 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);
+               return emit_op(compiler, op, flags, dst, dstw, TMP_ZERO, 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);
+               return emit_op(compiler, op, HALF_DATA, dst, dstw, TMP_ZERO, 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);
+               return emit_op(compiler, op | SLJIT_32, INT_DATA, dst, dstw, TMP_ZERO, 0, src, srcw);
        }
 
        SLJIT_UNREACHABLE();
@@ -1941,6 +2035,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil
        return sljit_emit_op2(compiler, op, 0, 0, src1, src1w, src2, src2w);
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
+       sljit_s32 dst_reg,
+       sljit_s32 src1, sljit_sw src1w,
+       sljit_s32 src2, sljit_sw src2w)
+{
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+       sljit_ins word = (sljit_ins)(op & SLJIT_32) >> 5;
+#endif /* SLJIT_CONFIG_RISCV_64 */
+
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
+
+       SLJIT_ASSERT(WORD == 0 || WORD == 0x8);
+
+       switch (GET_OPCODE(op)) {
+       case SLJIT_MULADD:
+               SLJIT_SKIP_CHECKS(compiler);
+               FAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), TMP_REG2, 0, src1, src1w, src2, src2w));
+               return push_inst(compiler, ADD | WORD | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG2));
+       }
+
+       return SLJIT_SUCCESS;
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
        sljit_s32 dst_reg,
        sljit_s32 src1_reg,
@@ -2292,7 +2410,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
        switch (GET_OPCODE(op)) {
        case SLJIT_MOV_F64:
                if (src != dst_r) {
-                       if (dst_r != TMP_FREG1)
+                       if (!(dst & SLJIT_MEM))
                                FAIL_IF(push_inst(compiler, FSGNJ_S | FMT(op) | FRD(dst_r) | FRS1(src) | FRS2(src)));
                        else
                                dst_r = src;
@@ -2351,11 +2469,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
        }
 
        if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
-               if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
+               if ((dst & SLJIT_MEM) && !can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
-               }
-               else {
+               } else {
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
                        FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
                }
@@ -2391,7 +2508,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
                return push_inst(compiler, FSGNJ_S | FMT(op) | FRD(dst_r) | FRS1(src1) | FRS2(src2));
        }
 
-       if (dst_r == TMP_FREG2)
+       if (dst_r != dst)
                FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
 
        return SLJIT_SUCCESS;
@@ -2522,11 +2639,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
        PTR_FAIL_IF(push_inst(compiler, inst));
 
        /* Maximum number of instructions required for generating a constant. */
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-       compiler->size += 1;
-#else
-       compiler->size += 5;
-#endif
+       compiler->size += JUMP_MAX_SIZE - 1;
        return jump;
 }
 
@@ -2553,6 +2666,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
        struct sljit_jump *jump;
        sljit_s32 flags;
        sljit_ins inst;
+       sljit_s32 src2_tmp_reg = FAST_IS_REG(src1) ? TMP_REG1 : TMP_REG2;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w));
@@ -2573,8 +2687,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
        }
 
        if (src2 & SLJIT_MEM) {
-               PTR_FAIL_IF(emit_op_mem2(compiler, flags, TMP_REG2, src2, src2w, 0, 0));
-               src2 = TMP_REG2;
+               PTR_FAIL_IF(emit_op_mem2(compiler, flags, src2_tmp_reg, src2, src2w, 0, 0));
+               src2 = src2_tmp_reg;
        }
 
        if (src1 == SLJIT_IMM) {
@@ -2588,8 +2702,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
 
        if (src2 == SLJIT_IMM) {
                if (src2w != 0) {
-                       PTR_FAIL_IF(load_immediate(compiler, TMP_REG2, src2w, TMP_REG3));
-                       src2 = TMP_REG2;
+                       PTR_FAIL_IF(load_immediate(compiler, src2_tmp_reg, src2w, TMP_REG3));
+                       src2 = src2_tmp_reg;
                }
                else
                        src2 = TMP_ZERO;
@@ -2639,11 +2753,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
        PTR_FAIL_IF(push_inst(compiler, JALR | RD(TMP_ZERO) | RS1(TMP_REG1) | IMM_I(0)));
 
        /* Maximum number of instructions required for generating a constant. */
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-       compiler->size += 1;
-#else
-       compiler->size += 5;
-#endif
+       compiler->size += JUMP_MAX_SIZE - 1;
        return jump;
 }
 
@@ -2675,11 +2785,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
        FAIL_IF(push_inst(compiler, JALR | RD((type >= SLJIT_FAST_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | RS1(TMP_REG1) | IMM_I(0)));
 
        /* Maximum number of instructions required for generating a constant. */
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-       compiler->size += 1;
-#else
-       compiler->size += 5;
-#endif
+       compiler->size += JUMP_MAX_SIZE - 1;
        return SLJIT_SUCCESS;
 }
 
@@ -2826,13 +2932,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
                        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)));
+                               FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(dst_reg) | IMM_I(0)));
 
                                if ((src1 & REG_MASK) == dst_reg)
-                                       src1 = (src1 & ~REG_MASK) | TMP_REG2;
+                                       src1 = (src1 & ~REG_MASK) | TMP_REG1;
 
                                if (OFFS_REG(src1) == dst_reg)
-                                       src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG2);
+                                       src1 = (src1 & ~OFFS_REG_MASK) | TO_OFFS_REG(TMP_REG1);
                        }
 
                        FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst_reg) | RS1(src2_reg) | IMM_I(0)));
@@ -2856,7 +2962,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
        } 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);
+       size = compiler->size - size;
+       *ptr = get_jump_instruction(type & ~SLJIT_32) | (sljit_ins)((size & 0x7) << 9) | (sljit_ins)((size >> 3) << 25);
        return SLJIT_SUCCESS;
 }
 
@@ -2895,7 +3002,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com
        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);
+       size = compiler->size - size;
+       *ptr = get_jump_instruction(type & ~SLJIT_32) | (sljit_ins)((size & 0x7) << 9) | (sljit_ins)((size >> 3) << 25);
        return SLJIT_SUCCESS;
 }
 
@@ -2980,31 +3088,31 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
        return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
-       struct sljit_put_label *put_label;
+       struct sljit_jump *jump;
        sljit_s32 dst_r;
 
        CHECK_ERROR_PTR();
-       CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+       CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
        ADJUST_LOCAL_OFFSET(dst, dstw);
 
-       put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
-       PTR_FAIL_IF(!put_label);
-       set_put_label(put_label, compiler, 0);
+       jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+       PTR_FAIL_IF(!jump);
+       set_mov_addr(jump, compiler, 0);
 
        dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
        PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r));
 #if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
        compiler->size += 1;
-#else
+#else /* !SLJIT_CONFIG_RISCV_32 */
        compiler->size += 5;
-#endif
+#endif /* SLJIT_CONFIG_RISCV_32 */
 
        if (dst & SLJIT_MEM)
                PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
 
-       return put_label;
+       return jump;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
index 67516f9b320f02641424e3a245d28b86ed6de997..99e846350fdd64fa630ef9454862dfa5d11313dd 100644 (file)
@@ -38,12 +38,9 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
        return "s390x" SLJIT_CPUINFO;
 }
 
-/* Instructions. */
+/* Instructions are stored as 64 bit values regardless their size. */
 typedef sljit_uw sljit_ins;
 
-/* Instruction tags (most significant halfword). */
-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)
 
@@ -140,50 +137,21 @@ static SLJIT_INLINE sljit_gpr gpr(sljit_s32 r)
        return reg_map[r];
 }
 
-/* Size of instruction in bytes. Tags must already be cleared. */
-static SLJIT_INLINE sljit_uw sizeof_ins(sljit_ins ins)
-{
-       /* keep faulting instructions */
-       if (ins == 0)
-               return 2;
-
-       if ((ins & 0x00000000ffffL) == ins)
-               return 2;
-       if ((ins & 0x0000ffffffffL) == ins)
-               return 4;
-       if ((ins & 0xffffffffffffL) == ins)
-               return 6;
-
-       SLJIT_UNREACHABLE();
-       return (sljit_uw)-1;
-}
-
 static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
 {
        sljit_ins *ibuf = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
        FAIL_IF(!ibuf);
        *ibuf = ins;
+
+       SLJIT_ASSERT(ins <= 0xffffffffffffL);
+
        compiler->size++;
-       return SLJIT_SUCCESS;
-}
+       if (ins & 0xffff00000000L)
+               compiler->size++;
 
-static sljit_s32 encode_inst(void **ptr, sljit_ins ins)
-{
-       sljit_u16 *ibuf = (sljit_u16 *)*ptr;
-       sljit_uw size = sizeof_ins(ins);
+       if (ins & 0xffffffff0000L)
+               compiler->size++;
 
-       SLJIT_ASSERT((size & 6) == size);
-       switch (size) {
-       case 6:
-               *ibuf++ = (sljit_u16)(ins >> 32);
-               /* fallthrough */
-       case 4:
-               *ibuf++ = (sljit_u16)(ins >> 16);
-               /* fallthrough */
-       case 2:
-               *ibuf++ = (sljit_u16)(ins);
-       }
-       *ptr = (void*)ibuf;
        return SLJIT_SUCCESS;
 }
 
@@ -1424,97 +1392,60 @@ static sljit_s32 emit_non_commutative(struct sljit_compiler *compiler, const str
        return emit_rrf(compiler, ins, dst, src1, src1w, src2, src2w);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
 {
        struct sljit_label *label;
        struct sljit_jump *jump;
-       struct sljit_s390x_const *const_;
-       struct sljit_put_label *put_label;
+       struct sljit_const *const_;
        sljit_sw executable_offset;
-       sljit_uw ins_size = 0; /* instructions */
+       sljit_uw ins_size = compiler->size << 1;
        sljit_uw pool_size = 0; /* literal pool */
        sljit_uw pad_size;
-       sljit_uw i, j = 0;
+       sljit_uw half_count;
+       SLJIT_NEXT_DEFINE_TYPES;
        struct sljit_memory_fragment *buf;
-       void *code, *code_ptr;
+       sljit_ins *buf_ptr;
+       sljit_ins *buf_end;
+       sljit_u16 *code;
+       sljit_u16 *code_ptr;
        sljit_uw *pool, *pool_ptr;
-       sljit_sw source, offset; /* TODO(carenas): only need 32 bit */
+       sljit_ins ins;
+       sljit_sw source, offset;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_generate_code(compiler));
        reverse_buf(compiler);
 
-       /* branch handling */
-       label = compiler->labels;
        jump = compiler->jumps;
-       put_label = compiler->put_labels;
-
-       /* TODO(carenas): compiler->executable_size could be calculated
-         *                before to avoid the following loop (except for
-         *                pool_size)
-         */
-       /* calculate the size of the code */
-       for (buf = compiler->buf; buf != NULL; buf = buf->next) {
-               sljit_uw len = buf->used_size / sizeof(sljit_ins);
-               sljit_ins *ibuf = (sljit_ins *)buf->memory;
-               for (i = 0; i < len; ++i, ++j) {
-                       sljit_ins ins = ibuf[i];
-
-                       /* TODO(carenas): instruction tag vs size/addr == j
-                        * using instruction tags for const is creative
-                        * but unlike all other architectures, and is not
-                        * done consistently for all other objects.
-                        * This might need reviewing later.
-                        */
-                       if (ins & sljit_ins_const) {
-                               pool_size += sizeof(*pool);
-                               ins &= ~sljit_ins_const;
-                       }
-                       if (label && label->size == j) {
-                               label->size = ins_size;
-                               label = label->next;
-                       }
-                       if (jump && jump->addr == j) {
-                               if ((jump->flags & SLJIT_REWRITABLE_JUMP) || (jump->flags & JUMP_ADDR)) {
-                                       /* encoded: */
-                                       /*   brasl %r14, <rel_addr> (or brcl <mask>, <rel_addr>) */
-                                       /* replace with: */
-                                       /*   lgrl %r1, <pool_addr> */
-                                       /*   bras %r14, %r1 (or bcr <mask>, %r1) */
-                                       pool_size += sizeof(*pool);
-                                       ins_size += 2;
-                               }
-                               jump = jump->next;
-                       }
-                       if (put_label && put_label->addr == j) {
-                               pool_size += sizeof(*pool);
-                               put_label = put_label->next;
-                       }
-                       ins_size += sizeof_ins(ins);
+       while (jump != NULL) {
+               if (jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR | JUMP_MOV_ADDR)) {
+                       /* encoded: */
+                       /*   brasl %r14, <rel_addr> (or brcl <mask>, <rel_addr>) */
+                       /* replace with: */
+                       /*   lgrl %r1, <pool_addr> */
+                       /*   bras %r14, %r1 (or bcr <mask>, %r1) */
+                       pool_size += sizeof(*pool);
+                       if (!(jump->flags & JUMP_MOV_ADDR))
+                               ins_size += 2;
                }
+               jump = jump->next;
        }
 
-       /* emit trailing label */
-       if (label && label->size == j) {
-               label->size = ins_size;
-               label = label->next;
+       const_ = compiler->consts;
+       while (const_) {
+               pool_size += sizeof(*pool);
+               const_ = const_->next;
        }
 
-       SLJIT_ASSERT(!label);
-       SLJIT_ASSERT(!jump);
-       SLJIT_ASSERT(!put_label);
-
        /* pad code size to 8 bytes so is accessible with half word offsets */
        /* the literal pool needs to be doubleword aligned */
        pad_size = ((ins_size + 7UL) & ~7UL) - ins_size;
        SLJIT_ASSERT(pad_size < 8UL);
 
        /* allocate target buffer */
-       code = SLJIT_MALLOC_EXEC(ins_size + pad_size + pool_size,
-                                       compiler->exec_allocator_data);
+       code = (sljit_u16*)allocate_executable_memory(ins_size + pad_size + pool_size, options, exec_allocator_data, &executable_offset);
        PTR_FAIL_WITH_EXEC_IF(code);
        code_ptr = code;
-       executable_offset = SLJIT_EXEC_OFFSET(code);
 
        /* TODO(carenas): pool is optional, and the ABI recommends it to
          *                be created before the function code, instead of
@@ -1523,130 +1454,166 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
          */
        pool = (sljit_uw *)((sljit_uw)code + ins_size + pad_size);
        pool_ptr = pool;
-       const_ = (struct sljit_s390x_const *)compiler->consts;
+       buf = compiler->buf;
+       half_count = 0;
 
-       /* update label addresses */
        label = compiler->labels;
-       while (label) {
-               label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(
-                       (sljit_uw)code_ptr + label->size, executable_offset);
-               label = label->next;
-       }
-
-       /* reset jumps */
        jump = compiler->jumps;
-       put_label = compiler->put_labels;
+       const_ = compiler->consts;
+       SLJIT_NEXT_INIT_TYPES();
+       SLJIT_GET_NEXT_MIN();
 
-       /* emit the code */
-       j = 0;
-       for (buf = compiler->buf; buf != NULL; buf = buf->next) {
-               sljit_uw len = buf->used_size / sizeof(sljit_ins);
-               sljit_ins *ibuf = (sljit_ins *)buf->memory;
-               for (i = 0; i < len; ++i, ++j) {
-                       sljit_ins ins = ibuf[i];
-                       if (ins & sljit_ins_const) {
-                               /* clear the const tag */
-                               ins &= ~sljit_ins_const;
+       do {
+               buf_ptr = (sljit_ins*)buf->memory;
+               buf_end = buf_ptr + (buf->used_size >> 3);
+               do {
+                       ins = *buf_ptr++;
+
+                       if (next_min_addr == half_count) {
+                               SLJIT_ASSERT(!label || label->size >= half_count);
+                               SLJIT_ASSERT(!jump || jump->addr >= half_count);
+                               SLJIT_ASSERT(!const_ || const_->addr >= half_count);
+
+                               if (next_min_addr == next_label_size) {
+                                       label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+                                       label = label->next;
+                                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
+                               }
 
-                               /* update instruction with relative address of constant */
-                               source = (sljit_sw)code_ptr;
-                               offset = (sljit_sw)pool_ptr - source;
+                               if (next_min_addr == next_jump_addr) {
+                                       if (SLJIT_UNLIKELY(jump->flags & JUMP_MOV_ADDR)) {
+                                               source = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+                                               jump->addr = (sljit_uw)pool_ptr;
+
+                                               /* store target into pool */
+                                               offset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
+                                               pool_ptr++;
+
+                                               SLJIT_ASSERT(!(offset & 1));
+                                               offset >>= 1;
+                                               SLJIT_ASSERT(is_s32(offset));
+                                               ins |= (sljit_ins)offset & 0xffffffff;
+                                       } else if (jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR)) {
+                                               sljit_ins arg;
+
+                                               jump->addr = (sljit_uw)pool_ptr;
+
+                                               /* load address into tmp1 */
+                                               source = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+                                               offset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
+
+                                               SLJIT_ASSERT(!(offset & 1));
+                                               offset >>= 1;
+                                               SLJIT_ASSERT(is_s32(offset));
+
+                                               code_ptr[0] = (sljit_u16)(0xc408 | R4A(tmp1) /* lgrl */);
+                                               code_ptr[1] = (sljit_u16)(offset >> 16);
+                                               code_ptr[2] = (sljit_u16)offset;
+                                               code_ptr += 3;
+                                               pool_ptr++;
+
+                                               /* branch to tmp1 */
+                                               arg = (ins >> 36) & 0xf;
+                                               if (((ins >> 32) & 0xf) == 4) {
+                                                       /* brcl -> bcr */
+                                                       ins = bcr(arg, tmp1);
+                                               } else {
+                                                       SLJIT_ASSERT(((ins >> 32) & 0xf) == 5);
+                                                       /* brasl -> basr */
+                                                       ins = basr(arg, tmp1);
+                                               }
+
+                                               /* Adjust half_count. */
+                                               half_count += 2;
+                                       } else
+                                               jump->addr = (sljit_uw)code_ptr;
+
+                                       jump = jump->next;
+                                       next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+                               } else  if (next_min_addr == next_const_addr) {
+                                       /* update instruction with relative address of constant */
+                                       source = (sljit_sw)code_ptr;
+                                       offset = (sljit_sw)pool_ptr - source;
+
+                                       SLJIT_ASSERT(!(offset & 0x1));
+                                       offset >>= 1; /* halfword (not byte) offset */
+                                       SLJIT_ASSERT(is_s32(offset));
 
-                               SLJIT_ASSERT(!(offset & 1));
-                               offset >>= 1; /* halfword (not byte) offset */
-                               SLJIT_ASSERT(is_s32(offset));
+                                       ins |= (sljit_ins)offset & 0xffffffff;
 
-                               ins |= (sljit_ins)offset & 0xffffffff;
+                                       /* update address */
+                                       const_->addr = (sljit_uw)pool_ptr;
 
-                               /* update address */
-                               const_->const_.addr = (sljit_uw)pool_ptr;
+                                       /* store initial value into pool and update pool address */
+                                       *(pool_ptr++) = (sljit_uw)(((struct sljit_s390x_const*)const_)->init_value);
 
-                               /* store initial value into pool and update pool address */
-                               *(pool_ptr++) = (sljit_uw)const_->init_value;
+                                       /* move to next constant */
+                                       const_ = const_->next;
+                                       next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
+                               }
 
-                               /* move to next constant */
-                               const_ = (struct sljit_s390x_const *)const_->const_.next;
+                               SLJIT_GET_NEXT_MIN();
                        }
-                       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;
+                       if (ins & 0xffff00000000L) {
+                               *code_ptr++ = (sljit_u16)(ins >> 32);
+                               half_count++;
+                       }
 
-                                       /* load address into tmp1 */
-                                       source = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
-                                       offset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
+                       if (ins & 0xffffffff0000L) {
+                               *code_ptr++ = (sljit_u16)(ins >> 16);
+                               half_count++;
+                       }
 
-                                       SLJIT_ASSERT(!(offset & 1));
-                                       offset >>= 1;
-                                       SLJIT_ASSERT(is_s32(offset));
+                       *code_ptr++ = (sljit_u16)ins;
+                       half_count++;
+               } while (buf_ptr < buf_end);
 
-                                       encode_inst(&code_ptr, lgrl(tmp1, offset & 0xffffffff));
-
-                                       /* store jump target into pool and update pool address */
-                                       *(pool_ptr++) = (sljit_uw)target;
-
-                                       /* branch to tmp1 */
-                                       op = (ins >> 32) & 0xf;
-                                       arg = (ins >> 36) & 0xf;
-                                       switch (op) {
-                                       case 4: /* brcl -> bcr */
-                                               ins = bcr(arg, tmp1);
-                                               break;
-                                       case 5: /* brasl -> basr */
-                                               ins = basr(arg, tmp1);
-                                               break;
-                                       default:
-                                               abort();
-                                       }
-                               }
-                               else {
-                                       jump->addr = (sljit_uw)code_ptr + 2;
-                                       source = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
-                                       offset = target - source;
+               buf = buf->next;
+       } while (buf);
 
-                                       /* offset must be halfword aligned */
-                                       SLJIT_ASSERT(!(offset & 1));
-                                       offset >>= 1;
-                                       SLJIT_ASSERT(is_s32(offset)); /* TODO(mundaym): handle arbitrary offsets */
+       if (next_label_size == half_count) {
+               label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+               label = label->next;
+       }
 
-                                       /* patch jump target */
-                                       ins |= (sljit_ins)offset & 0xffffffff;
-                               }
-                               jump = jump->next;
-                       }
-                       if (put_label && put_label->addr == j) {
-                               source = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+       SLJIT_ASSERT(!label);
+       SLJIT_ASSERT(!jump);
+       SLJIT_ASSERT(!const_);
+       SLJIT_ASSERT(code + (ins_size >> 1) == code_ptr);
+       SLJIT_ASSERT((sljit_u8 *)pool + pool_size == (sljit_u8 *)pool_ptr);
 
-                               SLJIT_ASSERT(put_label->label);
-                               put_label->addr = (sljit_uw)code_ptr;
+       jump = compiler->jumps;
+       while (jump != NULL) {
+               offset = (sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr);
 
-                               /* store target into pool */
-                               *pool_ptr = put_label->label->addr;
-                               offset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
-                               pool_ptr++;
+               if (jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR | JUMP_MOV_ADDR)) {
+                       /* Store jump target into pool. */
+                       *(sljit_uw*)(jump->addr) = (sljit_uw)offset;
+               } else {
+                       code_ptr = (sljit_u16*)jump->addr;
+                       offset -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
 
-                               SLJIT_ASSERT(!(offset & 1));
-                               offset >>= 1;
-                               SLJIT_ASSERT(is_s32(offset));
-                               ins |= (sljit_ins)offset & 0xffffffff;
+                       /* offset must be halfword aligned */
+                       SLJIT_ASSERT(!(offset & 1));
+                       offset >>= 1;
+                       SLJIT_ASSERT(is_s32(offset)); /* TODO(mundaym): handle arbitrary offsets */
 
-                               put_label = put_label->next;
-                       }
-                       encode_inst(&code_ptr, ins);
+                       code_ptr[1] = (sljit_u16)(offset >> 16);
+                       code_ptr[2] = (sljit_u16)offset;
                }
+               jump = jump->next;
        }
-       SLJIT_ASSERT((sljit_u8 *)code + ins_size == code_ptr);
-       SLJIT_ASSERT((sljit_u8 *)pool + pool_size == (sljit_u8 *)pool_ptr);
 
        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);
+
+       code = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+       code_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
        SLJIT_CACHE_FLUSH(code, code_ptr);
        SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
        return code;
@@ -2497,7 +2464,7 @@ static sljit_s32 sljit_emit_sub(struct sljit_compiler *compiler, sljit_s32 op,
        const struct ins_forms *forms;
        sljit_ins ins;
 
-       if (dst == (sljit_s32)tmp0 && flag_type <= SLJIT_SIG_LESS_EQUAL) {
+       if (dst == TMP_REG2 && flag_type <= SLJIT_SIG_LESS_EQUAL) {
                int compare_signed = flag_type >= SLJIT_SIG_LESS;
 
                compiler->status_flags_state |= SLJIT_CURRENT_FLAGS_COMPARE;
@@ -2597,7 +2564,7 @@ done:
                             - the first operand is less if the sign bit of the result is not set
                           The -result operation sets the corrent sign, because the result cannot be zero.
                           The overflow is considered greater, since the result must be equal to INT_MIN so its sign bit is set. */
-                       FAIL_IF(push_inst(compiler, brc(0xe, 2 + 2)));
+                       FAIL_IF(push_inst(compiler, brc(0xe, (op & SLJIT_32) ? (2 + 1) : (2 + 2))));
                        FAIL_IF(push_inst(compiler, (op & SLJIT_32) ? lcr(tmp1, dst_r) : lcgr(tmp1, dst_r)));
                }
                else if (op & SLJIT_SET_Z)
@@ -2759,7 +2726,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 == TMP_REG2))) {
                sljit_s32 count16 = 0;
                sljit_uw imm = (sljit_uw)src2w;
 
@@ -2775,13 +2742,13 @@ static sljit_s32 sljit_emit_bitwise(struct sljit_compiler *compiler, sljit_s32 o
                if ((imm & 0xffff000000000000ull) != 0)
                        count16++;
 
-               if (type == SLJIT_AND && dst == (sljit_s32)tmp0 && count16 == 1) {
-                       sljit_gpr src_r = tmp0;
+               if (type == SLJIT_AND && dst == TMP_REG2 && count16 == 1) {
+                       sljit_gpr src_r = tmp1;
 
                        if (FAST_IS_REG(src1))
                                src_r = gpr(src1 & REG_MASK);
                        else
-                               FAIL_IF(emit_move(compiler, tmp0, src1, src1w));
+                               FAIL_IF(emit_move(compiler, tmp1, src1, src1w));
 
                        if ((imm & 0x000000000000ffffull) != 0 || imm == 0)
                                return push_inst(compiler, 0xa7010000 /* tmll */ | R20A(src_r) | imm);
@@ -3002,11 +2969,31 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil
        sljit_s32 src1, sljit_sw src1w,
        sljit_s32 src2, sljit_sw src2w)
 {
+       sljit_s32 dst_reg = (GET_OPCODE(op) == SLJIT_SUB || GET_OPCODE(op) == SLJIT_AND) ? TMP_REG2 : TMP_REG1;
+
        CHECK_ERROR();
        CHECK(check_sljit_emit_op2(compiler, op, 1, 0, 0, src1, src1w, src2, src2w));
 
        SLJIT_SKIP_CHECKS(compiler);
-       return sljit_emit_op2(compiler, op, (sljit_s32)tmp0, 0, src1, src1w, src2, src2w);
+       return sljit_emit_op2(compiler, op, dst_reg, 0, src1, src1w, src2, src2w);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
+       sljit_s32 dst_reg,
+       sljit_s32 src1, sljit_sw src1w,
+       sljit_s32 src2, sljit_sw src2w)
+{
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
+
+       switch (GET_OPCODE(op)) {
+       case SLJIT_MULADD:
+               SLJIT_SKIP_CHECKS(compiler);
+               FAIL_IF(sljit_emit_op2(compiler, SLJIT_MUL | (op & SLJIT_32), 0 /* tmp0 */, 0, src1, src1w, src2, src2w));
+               return push_inst(compiler, ((op & SLJIT_32) ? 0x1a00 /* ar */ : 0xb9080000 /* agr */) | R4A(gpr(dst_reg)) | R0A(tmp0));
+       }
+
+       return SLJIT_SUCCESS;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
@@ -3415,12 +3402,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
                FAIL_IF(push_inst(compiler, ins | F4(dst_r) | F0(src)));
        }
 
-       if (!(dst & SLJIT_MEM))
-               return SLJIT_SUCCESS;
-
-       SLJIT_ASSERT(dst_r == TMP_FREG1);
+       if (dst & SLJIT_MEM)
+               return float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), TMP_FREG1, dst, dstw);
 
-       return float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), TMP_FREG1, dst, dstw);
+       return SLJIT_SUCCESS;
 }
 
 #define FLOAT_MOV(op, dst_r, src_r) \
@@ -3491,7 +3476,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
        if (dst & SLJIT_MEM)
                return float_mem(compiler, FLOAT_STORE | (op & SLJIT_32), TMP_FREG1, dst, dstw);
 
-       SLJIT_ASSERT(dst_r != TMP_FREG1);
        return SLJIT_SUCCESS;
 }
 
@@ -3738,8 +3722,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
                FAIL_IF(push_inst(compiler,
                        WHEN2(op & SLJIT_32, lochi, locghi)));
        } else {
-               /* TODO(mundaym): no load/store-on-condition 2 facility (ipm? branch-and-set?) */
-               abort();
+               FAIL_IF(push_load_imm_inst(compiler, loc_r, 1));
+               FAIL_IF(push_inst(compiler, brc(mask, 2 + 2)));
+               FAIL_IF(push_load_imm_inst(compiler, loc_r, 0));
        }
        #undef LEVAL
 
@@ -3837,8 +3822,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
                        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;
+               FAIL_IF(push_load_imm_inst(compiler, tmp1, src1w));
+               src_r = tmp1;
        } else
                src_r = gpr(src1);
 
@@ -4474,9 +4459,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
 
        dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
        if (have_genext())
-               PTR_FAIL_IF(push_inst(compiler, sljit_ins_const | lgrl(dst_r, 0)));
+               PTR_FAIL_IF(push_inst(compiler, lgrl(dst_r, 0)));
        else {
-               PTR_FAIL_IF(push_inst(compiler, sljit_ins_const | larl(tmp1, 0)));
+               PTR_FAIL_IF(push_inst(compiler, larl(tmp1, 0)));
                PTR_FAIL_IF(push_inst(compiler, lg(dst_r, 0, r0, tmp1)));
        }
 
@@ -4503,20 +4488,18 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
        sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
 }
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label *sljit_emit_put_label(
-       struct sljit_compiler *compiler,
-       sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
-       struct sljit_put_label *put_label;
+       struct sljit_jump *jump;
        sljit_gpr dst_r;
 
        CHECK_ERROR_PTR();
-       CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+       CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
        ADJUST_LOCAL_OFFSET(dst, dstw);
 
-       put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
-       PTR_FAIL_IF(!put_label);
-       set_put_label(put_label, compiler, 0);
+       jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+       PTR_FAIL_IF(!jump);
+       set_mov_addr(jump, compiler, 0);
 
        dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
 
@@ -4530,7 +4513,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label *sljit_emit_put_label(
        if (dst & SLJIT_MEM)
                PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, 0));
 
-       return put_label;
+       return jump;
 }
 
 /* TODO(carenas): EVAL probably should move up or be refactored */
index ba4a1ebbc20f8303c1d50d9b67fafdcc61db8ee3..59ea04a5c81b13ec7338ce7c0d6ead87d797bb1f 100644 (file)
@@ -283,28 +283,25 @@ static sljit_s32 emit_vex_instruction(struct sljit_compiler *compiler, sljit_uw
 /*  Enter / return                                                       */
 /* --------------------------------------------------------------------- */
 
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset)
+static sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset)
 {
        sljit_uw type = jump->flags >> TYPE_SHIFT;
 
        if (type == SLJIT_JUMP) {
                *code_ptr++ = JMP_i32;
-               jump->addr++;
-       }
-       else if (type >= SLJIT_FAST_CALL) {
+       } else if (type >= SLJIT_FAST_CALL) {
                *code_ptr++ = CALL_i32;
-               jump->addr++;
-       }
-       else {
+       } else {
                *code_ptr++ = GROUP_0F;
                *code_ptr++ = get_jump_code(type);
-               jump->addr += 2;
        }
 
-       if (jump->flags & JUMP_LABEL)
-               jump->flags |= PATCH_MW;
-       else
+       jump->addr = (sljit_uw)code_ptr;
+
+       if (jump->flags & JUMP_ADDR)
                sljit_unaligned_store_sw(code_ptr, (sljit_sw)(jump->u.target - (jump->addr + 4) - (sljit_uw)executable_offset));
+       else
+               jump->flags |= PATCH_MW;
        code_ptr += 4;
 
        return code_ptr;
@@ -1249,6 +1246,68 @@ static sljit_s32 sljit_emit_get_return_address(struct sljit_compiler *compiler,
 /*  Other operations                                                     */
 /* --------------------------------------------------------------------- */
 
+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)
+{
+       sljit_s32 dst = dst_reg;
+       sljit_sw dstw = 0;
+       sljit_sw src2w = 0;
+
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));
+
+       ADJUST_LOCAL_OFFSET(src1, src1w);
+
+       CHECK_EXTRA_REGS(dst, dstw, (void)0);
+       CHECK_EXTRA_REGS(src1, src1w, (void)0);
+       CHECK_EXTRA_REGS(src2_reg, src2w, (void)0);
+
+       type &= ~SLJIT_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 {
+               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_has_cpu_feature(SLJIT_HAS_CMOV) && (src1 != SLJIT_IMM || dst_reg != TMP_REG1)) {
+               if (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) {
+                       EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+                       src1 = TMP_REG1;
+                       src1w = 0;
+               }
+
+               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 (dst & SLJIT_MEM)
+               return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
+       return SLJIT_SUCCESS;
+}
+
 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)
@@ -1449,10 +1508,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset32(struct sljit_compiler *comp
 
        if (u.imm == 0) {
                inst[2] = PXOR_x_xm;
-               inst[3] = U8(freg | (freg << 3) | MOD_REG);
+               inst[3] = U8(freg_map[freg] | (freg_map[freg] << 3) | MOD_REG);
        } else {
                inst[2] = MOVD_x_rm;
-               inst[3] = U8(reg_map[TMP_REG1] | (freg << 3) | MOD_REG);
+               inst[3] = U8(reg_map[TMP_REG1] | (freg_map[freg] << 3) | MOD_REG);
        }
 
        return SLJIT_SUCCESS;
@@ -1462,7 +1521,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *comp
        sljit_s32 freg, sljit_f64 value)
 {
        sljit_u8 *inst;
-       sljit_s32 tmp_freg = freg;
        union {
                sljit_s32 imm[2];
                sljit_f64 value;
@@ -1478,8 +1536,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *comp
                        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
+       } else {
+               SLJIT_ASSERT(cpu_feature_list != 0);
+
+               if (!(cpu_feature_list & CPU_FEATURE_SSE41) && u.imm[1] != 0 && u.imm[0] != u.imm[1]) {
+                       EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_IMM, u.imm[0]);
+                       EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), sizeof(sljit_sw), SLJIT_IMM, u.imm[1]);
+
+                       return emit_groupf(compiler, MOVLPD_x_m | EX86_SSE2, freg, SLJIT_MEM1(SLJIT_SP), 0);
+               }
+
                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));
 
@@ -1493,23 +1561,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *comp
 
                inst[0] = GROUP_0F;
                inst[1] = SHUFPS_x_xm;
-               inst[2] = U8(MOD_REG | (freg << 3) | freg);
+               inst[2] = U8(MOD_REG | (freg_map[freg] << 3) | freg_map[freg]);
                inst[3] = 0x51;
                return SLJIT_SUCCESS;
        }
 
        if (u.imm[0] != u.imm[1]) {
-               SLJIT_ASSERT(u.imm[1] != 0 && cpu_feature_list != 0);
-
+               SLJIT_ASSERT(cpu_feature_list & CPU_FEATURE_SSE41);
                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;
+               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);
        }
 
        inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
@@ -1518,7 +1580,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fset64(struct sljit_compiler *comp
 
        inst[0] = GROUP_0F;
        inst[1] = UNPCKLPS_x_xm;
-       inst[2] = U8(MOD_REG | (freg << 3) | tmp_freg);
+       inst[2] = U8(MOD_REG | (freg_map[freg] << 3) | freg_map[freg]);
        return SLJIT_SUCCESS;
 }
 
@@ -1581,7 +1643,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compi
                inst[0] = GROUP_66;
                inst[1] = GROUP_0F;
                inst[2] = PSHUFD_x_xm;
-               inst[3] = U8(MOD_REG | (TMP_FREG << 3) | freg);
+               inst[3] = U8(MOD_REG | (TMP_FREG << 3) | freg_map[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));
@@ -1597,7 +1659,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compi
 
                inst[0] = GROUP_0F;
                inst[1] = UNPCKLPS_x_xm;
-               inst[2] = U8(MOD_REG | (freg << 3) | (reg == 0 ? freg : TMP_FREG));
+               inst[2] = U8(MOD_REG | (freg_map[freg] << 3) | freg_map[reg == 0 ? freg : TMP_FREG]);
        } else
                FAIL_IF(emit_groupf(compiler, MOVD_rm_x | EX86_PREF_66 | EX86_SSE2_OP1, TMP_FREG, reg, regw));
 
index f313f3f038f7f1d22013bfb2a343fb4671d23e79..1ab79293c7efcaab98cf91b81d65941982037322 100644 (file)
@@ -358,26 +358,28 @@ static sljit_s32 emit_vex_instruction(struct sljit_compiler *compiler, sljit_uw
 /*  Enter / return                                                       */
 /* --------------------------------------------------------------------- */
 
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr)
+static sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr)
 {
        sljit_uw type = jump->flags >> TYPE_SHIFT;
 
-       int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && !(jump->flags & JUMP_LABEL) && (jump->u.target <= 0xffffffff);
+       int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && (jump->flags & JUMP_ADDR) && (jump->u.target <= 0xffffffff);
 
        /* The relative jump below specialized for this case. */
-       SLJIT_ASSERT(reg_map[TMP_REG2] >= 8);
+       SLJIT_ASSERT(reg_map[TMP_REG2] >= 8 && TMP_REG2 != SLJIT_TMP_DEST_REG);
 
        if (type < SLJIT_JUMP) {
                /* Invert type. */
-               *code_ptr++ = U8(get_jump_code(type ^ 0x1) - 0x10);
-               *code_ptr++ = short_addr ? (6 + 3) : (10 + 3);
+               code_ptr[0] = U8(get_jump_code(type ^ 0x1) - 0x10);
+               code_ptr[1] = short_addr ? (6 + 3) : (10 + 3);
+               code_ptr += 2;
        }
 
-       *code_ptr++ = short_addr ? REX_B : (REX_W | REX_B);
-       *code_ptr++ = MOV_r_i32 | reg_lmap[TMP_REG2];
+       code_ptr[0] = short_addr ? REX_B : (REX_W | REX_B);
+       code_ptr[1] = MOV_r_i32 | reg_lmap[TMP_REG2];
+       code_ptr += 2;
        jump->addr = (sljit_uw)code_ptr;
 
-       if (jump->flags & JUMP_LABEL)
+       if (!(jump->flags & JUMP_ADDR))
                jump->flags |= PATCH_MD;
        else if (short_addr)
                sljit_unaligned_store_s32(code_ptr, (sljit_s32)jump->u.target);
@@ -386,60 +388,62 @@ static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_
 
        code_ptr += short_addr ? sizeof(sljit_s32) : sizeof(sljit_sw);
 
-       *code_ptr++ = REX_B;
-       *code_ptr++ = GROUP_FF;
-       *code_ptr++ = U8(MOD_REG | (type >= SLJIT_FAST_CALL ? CALL_rm : JMP_rm) | reg_lmap[TMP_REG2]);
+       code_ptr[0] = REX_B;
+       code_ptr[1] = GROUP_FF;
+       code_ptr[2] = U8(MOD_REG | (type >= SLJIT_FAST_CALL ? CALL_rm : JMP_rm) | reg_lmap[TMP_REG2]);
 
-       return code_ptr;
+       return code_ptr + 3;
 }
 
-static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label)
+static sljit_u8* generate_mov_addr_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset)
 {
-       if (max_label > HALFWORD_MAX) {
-               put_label->addr -= put_label->flags;
-               put_label->flags = PATCH_MD;
-               return code_ptr;
-       }
+       sljit_uw addr;
+       sljit_sw diff;
+       SLJIT_UNUSED_ARG(executable_offset);
 
-       if (put_label->flags == 0) {
-               /* Destination is register. */
-               code_ptr = (sljit_u8*)put_label->addr - 2 - sizeof(sljit_uw);
+       SLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) <= 10);
+       if (jump->flags & JUMP_ADDR)
+               addr = jump->u.target;
+       else
+               addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + jump->u.label->size;
 
-               SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
-               SLJIT_ASSERT((code_ptr[1] & 0xf8) == MOV_r_i32);
+       if (addr > 0xffffffffl) {
+               diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
 
-               if ((code_ptr[0] & 0x07) != 0) {
-                       code_ptr[0] = U8(code_ptr[0] & ~0x08);
-                       code_ptr += 2 + sizeof(sljit_s32);
-               }
-               else {
-                       code_ptr[0] = code_ptr[1];
-                       code_ptr += 1 + sizeof(sljit_s32);
+               if (diff <= HALFWORD_MAX && diff >= HALFWORD_MIN) {
+                       SLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) >= 7);
+                       code_ptr -= SSIZE_OF(s32) - 1;
+
+                       SLJIT_ASSERT((code_ptr[-3 - SSIZE_OF(s32)] & 0xf8) == REX_W);
+                       SLJIT_ASSERT((code_ptr[-2 - SSIZE_OF(s32)] & 0xf8) == MOV_r_i32);
+
+                       code_ptr[-3 - SSIZE_OF(s32)] = U8(REX_W | ((code_ptr[-3 - SSIZE_OF(s32)] & 0x1) << 2));
+                       code_ptr[-1 - SSIZE_OF(s32)] = U8(((code_ptr[-2 - SSIZE_OF(s32)] & 0x7) << 3) | 0x5);
+                       code_ptr[-2 - SSIZE_OF(s32)] = LEA_r_m;
+
+                       jump->flags |= PATCH_MW;
+                       return code_ptr;
                }
 
-               put_label->addr = (sljit_uw)code_ptr;
+               jump->flags |= PATCH_MD;
                return code_ptr;
        }
 
-       code_ptr -= put_label->flags + (2 + sizeof(sljit_uw));
-       SLJIT_MEMMOVE(code_ptr, code_ptr + (2 + sizeof(sljit_uw)), put_label->flags);
+       code_ptr -= 2 + sizeof(sljit_uw);
 
        SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
+       SLJIT_ASSERT((code_ptr[1] & 0xf8) == MOV_r_i32);
 
-       if ((code_ptr[1] & 0xf8) == MOV_r_i32) {
-               code_ptr += 2 + sizeof(sljit_uw);
-               SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
+       if ((code_ptr[0] & 0x07) != 0) {
+               SLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) >= 6);
+               code_ptr[0] = U8(code_ptr[0] & ~0x08);
+               code_ptr += 2 + sizeof(sljit_s32);
+       } else {
+               SLJIT_ASSERT(((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f) >= 5);
+               code_ptr[0] = code_ptr[1];
+               code_ptr += 1 + sizeof(sljit_s32);
        }
 
-       SLJIT_ASSERT(code_ptr[1] == MOV_rm_r);
-
-       code_ptr[0] = U8(code_ptr[0] & ~0x4);
-       code_ptr[1] = MOV_rm_i32;
-       code_ptr[2] = U8(code_ptr[2] & ~(0x7 << 3));
-
-       code_ptr = (sljit_u8*)(put_label->addr - (2 + sizeof(sljit_uw)) + sizeof(sljit_s32));
-       put_label->addr = (sljit_uw)code_ptr;
-       put_label->flags = 0;
        return code_ptr;
 }
 
@@ -1003,6 +1007,46 @@ static sljit_s32 sljit_emit_get_return_address(struct sljit_compiler *compiler,
 /*  Other operations                                                     */
 /* --------------------------------------------------------------------- */
 
+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)
+{
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));
+
+       ADJUST_LOCAL_OFFSET(src1, src1w);
+
+       compiler->mode32 = type & SLJIT_32;
+       type &= ~SLJIT_32;
+
+       if (dst_reg != src2_reg) {
+               if (dst_reg == src1) {
+                       src1 = src2_reg;
+                       src1w = 0;
+                       type ^= 0x1;
+               } else if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {
+                       EMIT_MOV(compiler, dst_reg, 0, src1, src1w);
+                       src1 = src2_reg;
+                       src1w = 0;
+                       type ^= 0x1;
+               } else
+                       EMIT_MOV(compiler, dst_reg, 0, src2_reg, 0);
+       }
+
+       if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) {
+               if (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) {
+                       EMIT_MOV(compiler, TMP_REG2, 0, src1, src1w);
+                       src1 = TMP_REG2;
+                       src1w = 0;
+               }
+
+               return emit_groupf(compiler, U8(get_jump_code((sljit_uw)type) - 0x40), dst_reg, src1, src1w);
+       }
+
+       return emit_cmov_generic(compiler, type, dst_reg, src1, src1w);
+}
+
 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)
index c2c0421349b879eb549a863605a8169410a712d7..ecb7e9be3b0e0bde6067c96d29dd1c95223d4b38 100644 (file)
  * 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 <sanitizer/msan_interface.h>
-#endif /* __has_feature(memory_sanitizer) */
-#endif /* defined(__has_feature) */
-
 SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
 {
        return "x86" SLJIT_CPUINFO;
@@ -72,7 +66,6 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
 
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
 
-
 static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = {
        0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 5, 7, 6, 4, 3
 };
@@ -379,6 +372,11 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = {
 #define RET()                  (*inst++ = RET_near)
 #define RET_I16(n)             (*inst++ = RET_i16, *inst++ = U8(n), *inst++ = 0)
 
+#define SLJIT_INST_LABEL       255
+#define SLJIT_INST_JUMP                254
+#define SLJIT_INST_MOV_ADDR    253
+#define SLJIT_INST_CONST       252
+
 /* Multithreading does not affect these static variables, since they store
    built-in CPU features. Therefore they can be overwritten by different threads
    if they detect the CPU features in the same time. */
@@ -392,6 +390,7 @@ static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = {
 #define CPU_FEATURE_CMOV               0x020
 #define CPU_FEATURE_AVX                        0x040
 #define CPU_FEATURE_AVX2               0x080
+#define CPU_FEATURE_OSXSAVE            0x100
 
 static sljit_u32 cpu_feature_list = 0;
 
@@ -490,22 +489,50 @@ static void execute_cpu_id(sljit_u32 info[4])
        }
 
 #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 sljit_u32 execute_get_xcr0_low(void)
+{
+       sljit_u32 xcr0;
+
+#if defined(_MSC_VER) && _MSC_VER >= 1400
 
+       xcr0 = (sljit_u32)_xgetbv(0);
+
+#elif defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) || defined(__TINYC__)
+
+       /* AT&T syntax. */
+       __asm__ (
+               "xorl %%ecx, %%ecx\n"
+               "xgetbv\n"
+               : "=a" (xcr0)
+               :
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+               : "ecx", "edx"
+#else /* !SLJIT_CONFIG_X86_32 */
+               : "rcx", "rdx"
+#endif /* SLJIT_CONFIG_X86_32 */
+       );
+
+#else /* _MSC_VER < 1400 */
+
+       /* Intel syntax. */
+       __asm {
+               mov ecx, 0
+               xgetbv
+               mov xcr0, eax
+       }
+
+#endif /* _MSC_VER && _MSC_VER >= 1400 */
+       return xcr0;
 }
 
 static void get_cpu_features(void)
 {
        sljit_u32 feature_list = CPU_FEATURE_DETECTED;
-       sljit_u32 info[4];
+       sljit_u32 info[4] = {0};
        sljit_u32 max_id;
 
-       info[0] = 0;
        execute_cpu_id(info);
        max_id = info[0];
 
@@ -526,6 +553,8 @@ static void get_cpu_features(void)
 
                if (info[2] & 0x80000)
                        feature_list |= CPU_FEATURE_SSE41;
+               if (info[2] & 0x8000000)
+                       feature_list |= CPU_FEATURE_OSXSAVE;
                if (info[2] & 0x10000000)
                        feature_list |= CPU_FEATURE_AVX;
 #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
@@ -537,12 +566,14 @@ static void get_cpu_features(void)
        }
 
        info[0] = 0x80000001;
-       info[2] = 0; /* Silences an incorrect compiler warning. */
        execute_cpu_id(info);
 
        if (info[2] & 0x20)
                feature_list |= CPU_FEATURE_LZCNT;
 
+       if ((feature_list & CPU_FEATURE_OSXSAVE) && (execute_get_xcr0_low() & 0x4) == 0)
+               feature_list &= ~(sljit_u32)(CPU_FEATURE_AVX | CPU_FEATURE_AVX2);
+
        cpu_feature_list = feature_list;
 }
 
@@ -617,52 +648,47 @@ static sljit_u8 get_jump_code(sljit_uw type)
 }
 
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset);
-#else
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr);
-static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label);
-#endif
+static sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset);
+#else /* !SLJIT_CONFIG_X86_32 */
+static sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr);
+static sljit_u8* generate_mov_addr_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset);
+#endif /* SLJIT_CONFIG_X86_32 */
 
-static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset)
+static sljit_u8* detect_near_jump_type(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset)
 {
        sljit_uw type = jump->flags >> TYPE_SHIFT;
        sljit_s32 short_jump;
        sljit_uw label_addr;
 
-       if (jump->flags & JUMP_LABEL)
-               label_addr = (sljit_uw)(code + jump->u.label->size);
-       else
+       if (jump->flags & JUMP_ADDR)
                label_addr = jump->u.target - (sljit_uw)executable_offset;
+       else
+               label_addr = (sljit_uw)(code + jump->u.label->size);
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-       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
+       if ((sljit_sw)(label_addr - (sljit_uw)(code_ptr + 6)) > HALFWORD_MAX || (sljit_sw)(label_addr - (sljit_uw)(code_ptr + 5)) < HALFWORD_MIN)
+               return detect_far_jump_type(jump, code_ptr);
+#endif /* SLJIT_CONFIG_X86_64 */
 
-       short_jump = (sljit_sw)(label_addr - (jump->addr + 2)) >= -128 && (sljit_sw)(label_addr - (jump->addr + 2)) <= 127;
+       short_jump = (sljit_sw)(label_addr - (sljit_uw)(code_ptr + 2)) >= -0x80 && (sljit_sw)(label_addr - (sljit_uw)(code_ptr + 2)) <= 0x7f;
 
        if (type == SLJIT_JUMP) {
                if (short_jump)
                        *code_ptr++ = JMP_i8;
                else
                        *code_ptr++ = JMP_i32;
-               jump->addr++;
-       }
-       else if (type >= SLJIT_FAST_CALL) {
+       } else if (type > SLJIT_JUMP) {
                short_jump = 0;
                *code_ptr++ = CALL_i32;
-               jump->addr++;
-       }
-       else if (short_jump) {
+       } else if (short_jump) {
                *code_ptr++ = U8(get_jump_code(type) - 0x10);
-               jump->addr++;
-       }
-       else {
+       } else {
                *code_ptr++ = GROUP_0F;
                *code_ptr++ = get_jump_code(type);
-               jump->addr += 2;
        }
 
+       jump->addr = (sljit_uw)code_ptr;
+
        if (short_jump) {
                jump->flags |= PATCH_MB;
                code_ptr += sizeof(sljit_s8);
@@ -674,7 +700,172 @@ static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code
        return code_ptr;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+static void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executable_offset)
+{
+       sljit_uw flags = jump->flags;
+       sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
+       sljit_uw jump_addr = jump->addr;
+       SLJIT_UNUSED_ARG(executable_offset);
+
+       if (SLJIT_UNLIKELY(flags & JUMP_MOV_ADDR)) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+               sljit_unaligned_store_sw((void*)(jump_addr - sizeof(sljit_sw)), (sljit_sw)addr);
+#else /* SLJIT_CONFIG_X86_32 */
+               if (flags & PATCH_MD) {
+                       SLJIT_ASSERT(addr > HALFWORD_MAX);
+                       sljit_unaligned_store_sw((void*)(jump_addr - sizeof(sljit_sw)), (sljit_sw)addr);
+                       return;
+               }
+
+               if (flags & PATCH_MW) {
+                       addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET((sljit_u8*)jump_addr, executable_offset);
+                       SLJIT_ASSERT((sljit_sw)addr <= HALFWORD_MAX && (sljit_sw)addr >= HALFWORD_MIN);
+               } else {
+                       SLJIT_ASSERT(addr <= HALFWORD_MAX);
+               }
+               sljit_unaligned_store_s32((void*)(jump_addr - sizeof(sljit_s32)), (sljit_s32)addr);
+#endif /* !SLJIT_CONFIG_X86_32 */
+               return;
+       }
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+       if (SLJIT_UNLIKELY(flags & PATCH_MD)) {
+               SLJIT_ASSERT(!(flags & JUMP_ADDR));
+               sljit_unaligned_store_sw((void*)jump_addr, (sljit_sw)addr);
+               return;
+       }
+#endif /* SLJIT_CONFIG_X86_64 */
+
+       addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET((sljit_u8*)jump_addr, executable_offset);
+
+       if (flags & PATCH_MB) {
+               addr -= sizeof(sljit_s8);
+               SLJIT_ASSERT((sljit_sw)addr <= 0x7f && (sljit_sw)addr >= -0x80);
+               *(sljit_u8*)jump_addr = U8(addr);
+               return;
+       } else if (flags & PATCH_MW) {
+               addr -= sizeof(sljit_s32);
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+               sljit_unaligned_store_sw((void*)jump_addr, (sljit_sw)addr);
+#else /* !SLJIT_CONFIG_X86_32 */
+               SLJIT_ASSERT((sljit_sw)addr <= HALFWORD_MAX && (sljit_sw)addr >= HALFWORD_MIN);
+               sljit_unaligned_store_s32((void*)jump_addr, (sljit_s32)addr);
+#endif /* SLJIT_CONFIG_X86_32 */
+       }
+}
+
+static void reduce_code_size(struct sljit_compiler *compiler)
+{
+       struct sljit_label *label;
+       struct sljit_jump *jump;
+       sljit_uw next_label_size;
+       sljit_uw next_jump_addr;
+       sljit_uw next_min_addr;
+       sljit_uw size_reduce = 0;
+       sljit_sw diff;
+       sljit_uw type;
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+       sljit_uw size_reduce_max;
+#endif /* SLJIT_DEBUG */
+
+       label = compiler->labels;
+       jump = compiler->jumps;
+
+       next_label_size = SLJIT_GET_NEXT_SIZE(label);
+       next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+
+       while (1) {
+               next_min_addr = next_label_size;
+               if (next_jump_addr < next_min_addr)
+                       next_min_addr = next_jump_addr;
+
+               if (next_min_addr == SLJIT_MAX_ADDRESS)
+                       break;
+
+               if (next_min_addr == next_label_size) {
+                       label->size -= size_reduce;
+
+                       label = label->next;
+                       next_label_size = SLJIT_GET_NEXT_SIZE(label);
+               }
+
+               if (next_min_addr != next_jump_addr)
+                       continue;
+
+               if (!(jump->flags & JUMP_MOV_ADDR)) {
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+                       size_reduce_max = size_reduce + (((jump->flags >> TYPE_SHIFT) < SLJIT_JUMP) ? CJUMP_MAX_SIZE : JUMP_MAX_SIZE);
+#endif /* SLJIT_DEBUG */
+
+                       if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {
+                               if (jump->flags & JUMP_ADDR) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+                                       if (jump->u.target <= 0xffffffffl)
+                                               size_reduce += sizeof(sljit_s32);
+#endif /* SLJIT_CONFIG_X86_64 */
+                               } else {
+                                       /* Unit size: instruction. */
+                                       diff = (sljit_sw)jump->u.label->size - (sljit_sw)(jump->addr - size_reduce);
+                                       type = jump->flags >> TYPE_SHIFT;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+                                       if (type == SLJIT_JUMP) {
+                                               if (diff <= 0x7f + 2 && diff >= -0x80 + 2)
+                                                       size_reduce += JUMP_MAX_SIZE - 2;
+                                               else if (diff <= HALFWORD_MAX + 5 && diff >= HALFWORD_MIN + 5)
+                                                       size_reduce += JUMP_MAX_SIZE - 5;
+                                       } else if (type < SLJIT_JUMP) {
+                                               if (diff <= 0x7f + 2 && diff >= -0x80 + 2)
+                                                       size_reduce += CJUMP_MAX_SIZE - 2;
+                                               else if (diff <= HALFWORD_MAX + 6 && diff >= HALFWORD_MIN + 6)
+                                                       size_reduce += CJUMP_MAX_SIZE - 6;
+                                       } else  {
+                                               if (diff <= HALFWORD_MAX + 5 && diff >= HALFWORD_MIN + 5)
+                                                       size_reduce += JUMP_MAX_SIZE - 5;
+                                       }
+#else /* !SLJIT_CONFIG_X86_64 */
+                                       if (type == SLJIT_JUMP) {
+                                               if (diff <= 0x7f + 2 && diff >= -0x80 + 2)
+                                                       size_reduce += JUMP_MAX_SIZE - 2;
+                                       } else if (type < SLJIT_JUMP) {
+                                               if (diff <= 0x7f + 2 && diff >= -0x80 + 2)
+                                                       size_reduce += CJUMP_MAX_SIZE - 2;
+                                       }
+#endif /* SLJIT_CONFIG_X86_64 */
+                               }
+                       }
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+                       jump->flags |= (size_reduce_max - size_reduce) << JUMP_SIZE_SHIFT;
+#endif /* SLJIT_DEBUG */
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+               } else {
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+                       size_reduce_max = size_reduce + 10;
+#endif /* SLJIT_DEBUG */
+
+                       if (!(jump->flags & JUMP_ADDR)) {
+                               diff = (sljit_sw)jump->u.label->size - (sljit_sw)(jump->addr - size_reduce - 3);
+
+                               if (diff <= HALFWORD_MAX && diff >= HALFWORD_MIN)
+                                       size_reduce += 3;
+                       } else if (jump->u.target <= 0xffffffffl)
+                               size_reduce += (jump->flags & MOV_ADDR_HI) ? 4 : 5;
+
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+                       jump->flags |= (size_reduce_max - size_reduce) << JUMP_SIZE_SHIFT;
+#endif /* SLJIT_DEBUG */
+#endif /* SLJIT_CONFIG_X86_64 */
+               }
+
+               jump = jump->next;
+               next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
+       }
+
+       compiler->size -= size_reduce;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
 {
        struct sljit_memory_fragment *buf;
        sljit_u8 *code;
@@ -683,77 +874,82 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        sljit_u8 *buf_end;
        sljit_u8 len;
        sljit_sw executable_offset;
-       sljit_uw jump_addr;
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+       sljit_uw addr;
+#endif /* SLJIT_DEBUG */
 
        struct sljit_label *label;
        struct sljit_jump *jump;
        struct sljit_const *const_;
-       struct sljit_put_label *put_label;
 
        CHECK_ERROR_PTR();
        CHECK_PTR(check_sljit_generate_code(compiler));
-       reverse_buf(compiler);
+
+       reduce_code_size(compiler);
 
        /* Second code generation pass. */
-       code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size, compiler->exec_allocator_data);
+       code = (sljit_u8*)allocate_executable_memory(compiler->size, options, exec_allocator_data, &executable_offset);
        PTR_FAIL_WITH_EXEC_IF(code);
+
+       reverse_buf(compiler);
        buf = compiler->buf;
 
        code_ptr = code;
        label = compiler->labels;
        jump = compiler->jumps;
        const_ = compiler->consts;
-       put_label = compiler->put_labels;
-       executable_offset = SLJIT_EXEC_OFFSET(code);
 
        do {
                buf_ptr = buf->memory;
                buf_end = buf_ptr + buf->used_size;
                do {
                        len = *buf_ptr++;
-                       if (len > 0) {
+                       SLJIT_ASSERT(len > 0);
+                       if (len < SLJIT_INST_CONST) {
                                /* The code is already generated. */
                                SLJIT_MEMCPY(code_ptr, buf_ptr, len);
                                code_ptr += len;
                                buf_ptr += len;
-                       }
-                       else {
-                               switch (*buf_ptr) {
-                               case 0:
-                                       label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+                       } else {
+                               switch (len) {
+                               case SLJIT_INST_LABEL:
+                                       label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
                                        label->size = (sljit_uw)(code_ptr - code);
                                        label = label->next;
                                        break;
-                               case 1:
-                                       jump->addr = (sljit_uw)code_ptr;
+                               case SLJIT_INST_JUMP:
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+                                       addr = (sljit_uw)code_ptr;
+#endif /* SLJIT_DEBUG */
                                        if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
-                                               code_ptr = generate_near_jump_code(jump, code_ptr, code, executable_offset);
+                                               code_ptr = detect_near_jump_type(jump, code_ptr, code, executable_offset);
                                        else {
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-                                               code_ptr = generate_far_jump_code(jump, code_ptr, executable_offset);
-#else
-                                               code_ptr = generate_far_jump_code(jump, code_ptr);
-#endif
+                                               code_ptr = detect_far_jump_type(jump, code_ptr, executable_offset);
+#else /* !SLJIT_CONFIG_X86_32 */
+                                               code_ptr = detect_far_jump_type(jump, code_ptr);
+#endif /* SLJIT_CONFIG_X86_32 */
                                        }
+
+                                       SLJIT_ASSERT((sljit_uw)code_ptr - addr <= ((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f));
                                        jump = jump->next;
                                        break;
-                               case 2:
-                                       const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);
-                                       const_ = const_->next;
+                               case SLJIT_INST_MOV_ADDR:
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+                                       code_ptr = generate_mov_addr_code(jump, code_ptr, code, executable_offset);
+#endif /* SLJIT_CONFIG_X86_64 */
+                                       jump->addr = (sljit_uw)code_ptr;
+                                       jump = jump->next;
                                        break;
                                default:
-                                       SLJIT_ASSERT(*buf_ptr == 3);
-                                       SLJIT_ASSERT(put_label->label);
-                                       put_label->addr = (sljit_uw)code_ptr;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-                                       code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size);
-#endif
-                                       put_label = put_label->next;
+                                       SLJIT_ASSERT(len == SLJIT_INST_CONST);
+                                       const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);
+                                       const_ = const_->next;
                                        break;
                                }
-                               buf_ptr++;
                        }
                } while (buf_ptr < buf_end);
+
                SLJIT_ASSERT(buf_ptr == buf_end);
                buf = buf->next;
        } while (buf);
@@ -761,61 +957,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
        SLJIT_ASSERT(!label);
        SLJIT_ASSERT(!jump);
        SLJIT_ASSERT(!const_);
-       SLJIT_ASSERT(!put_label);
        SLJIT_ASSERT(code_ptr <= code + compiler->size);
 
        jump = compiler->jumps;
        while (jump) {
-               if (jump->flags & (PATCH_MB | PATCH_MW)) {
-                       if (jump->flags & JUMP_LABEL)
-                               jump_addr = jump->u.label->addr;
-                       else
-                               jump_addr = jump->u.target;
-
-                       jump_addr -= jump->addr + (sljit_uw)executable_offset;
-
-                       if (jump->flags & PATCH_MB) {
-                               jump_addr -= sizeof(sljit_s8);
-                               SLJIT_ASSERT((sljit_sw)jump_addr >= -128 && (sljit_sw)jump_addr <= 127);
-                               *(sljit_u8*)jump->addr = U8(jump_addr);
-                       } else {
-                               jump_addr -= sizeof(sljit_s32);
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-                               sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)jump_addr);
-#else
-                               SLJIT_ASSERT((sljit_sw)jump_addr >= HALFWORD_MIN && (sljit_sw)jump_addr <= HALFWORD_MAX);
-                               sljit_unaligned_store_s32((void*)jump->addr, (sljit_s32)jump_addr);
-#endif
-                       }
-               }
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-               else if (jump->flags & PATCH_MD) {
-                               SLJIT_ASSERT(jump->flags & JUMP_LABEL);
-                               sljit_unaligned_store_sw((void*)jump->addr, (sljit_sw)jump->u.label->addr);
-               }
-#endif
-
+               generate_jump_or_mov_addr(jump, executable_offset);
                jump = jump->next;
        }
 
-       put_label = compiler->put_labels;
-       while (put_label) {
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-               sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr);
-#else
-               if (put_label->flags & PATCH_MD) {
-                       SLJIT_ASSERT(put_label->label->addr > HALFWORD_MAX);
-                       sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr);
-               }
-               else {
-                       SLJIT_ASSERT(put_label->label->addr <= HALFWORD_MAX);
-                       sljit_unaligned_store_s32((void*)(put_label->addr - sizeof(sljit_s32)), (sljit_s32)put_label->label->addr);
-               }
-#endif
-
-               put_label = put_label->next;
-       }
-
        compiler->error = SLJIT_ERR_COMPILED;
        compiler->executable_offset = executable_offset;
        compiler->executable_size = (sljit_uw)(code_ptr - code);
@@ -921,8 +1070,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
                        BINARY_IMM32(op_imm, immw, arg, argw); \
                } \
                else { \
-                       FAIL_IF(emit_load_imm64(compiler, (arg == TMP_REG1) ? TMP_REG2 : TMP_REG1, immw)); \
-                       inst = emit_x86_instruction(compiler, 1, (arg == TMP_REG1) ? TMP_REG2 : TMP_REG1, 0, arg, argw); \
+                       FAIL_IF(emit_load_imm64(compiler, FAST_IS_REG(arg) ? TMP_REG2 : TMP_REG1, immw)); \
+                       inst = emit_x86_instruction(compiler, 1, FAST_IS_REG(arg) ? TMP_REG2 : TMP_REG1, 0, arg, argw); \
                        FAIL_IF(!inst); \
                        *inst = (op_mr); \
                } \
@@ -2248,10 +2397,9 @@ static sljit_s32 emit_test_binary(struct sljit_compiler *compiler,
                                inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, src1w);
                                FAIL_IF(!inst);
                                *inst = GROUP_F7;
-                       }
-                       else {
-                               FAIL_IF(emit_load_imm64(compiler, TMP_REG1, src2w));
-                               inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, src1, src1w);
+                       } else {
+                               FAIL_IF(emit_load_imm64(compiler, FAST_IS_REG(src1) ? TMP_REG2 : TMP_REG1, src2w));
+                               inst = emit_x86_instruction(compiler, 1, FAST_IS_REG(src1) ? TMP_REG2 : TMP_REG1, 0, src1, src1w);
                                FAIL_IF(!inst);
                                *inst = TEST_rm_r;
                        }
@@ -2488,8 +2636,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
        compiler->mode32 = op & SLJIT_32;
 #endif
 
-       SLJIT_ASSERT(dst != TMP_REG1 || HAS_FLAGS(op));
-
        switch (GET_OPCODE(op)) {
        case SLJIT_ADD:
                if (!HAS_FLAGS(op)) {
@@ -2583,12 +2729,44 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2u(struct sljit_compiler *compil
        compiler->mode32 = op & SLJIT_32;
 #endif
 
-       if (opcode == SLJIT_SUB) {
+       if (opcode == SLJIT_SUB)
                return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
-       }
+
        return emit_test_binary(compiler, src1, src1w, src2, src2w);
 }
 
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2r(struct sljit_compiler *compiler, sljit_s32 op,
+       sljit_s32 dst_reg,
+       sljit_s32 src1, sljit_sw src1w,
+       sljit_s32 src2, sljit_sw src2w)
+{
+       sljit_u8* inst;
+       sljit_sw dstw = 0;
+
+       CHECK_ERROR();
+       CHECK(check_sljit_emit_op2r(compiler, op, dst_reg, src1, src1w, src2, src2w));
+       ADJUST_LOCAL_OFFSET(src1, src1w);
+       ADJUST_LOCAL_OFFSET(src2, src2w);
+
+       CHECK_EXTRA_REGS(dst_reg, dstw, (void)0);
+       CHECK_EXTRA_REGS(src1, src1w, (void)0);
+       CHECK_EXTRA_REGS(src2, src2w, (void)0);
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+       compiler->mode32 = op & SLJIT_32;
+#endif
+
+       switch (GET_OPCODE(op)) {
+       case SLJIT_MULADD:
+               FAIL_IF(emit_mul(compiler, TMP_REG1, 0, src1, src1w, src2, src2w));
+               inst = emit_x86_instruction(compiler, 1, TMP_REG1, 0, dst_reg, dstw);
+               FAIL_IF(!inst);
+               *inst = ADD_rm_r;
+               return SLJIT_SUCCESS;
+       }
+
+       return SLJIT_SUCCESS;
+}
+
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *compiler, sljit_s32 op,
        sljit_s32 dst_reg,
        sljit_s32 src1_reg,
@@ -3117,19 +3295,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
                dst_r = dst;
                if (dst == src1)
                        ; /* Do nothing here. */
-               else if (dst == src2 && (op == SLJIT_ADD_F64 || op == SLJIT_MUL_F64)) {
+               else if (dst == src2 && (GET_OPCODE(op) == SLJIT_ADD_F64 || GET_OPCODE(op) == SLJIT_MUL_F64)) {
                        /* Swap arguments. */
                        src2 = src1;
                        src2w = src1w;
-               }
-               else if (dst != src2)
+               } else if (dst != src2)
                        FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, dst_r, src1, src1w));
                else {
                        dst_r = TMP_FREG;
                        FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));
                }
-       }
-       else {
+       } else {
                dst_r = TMP_FREG;
                FAIL_IF(emit_sse2_load(compiler, op & SLJIT_32, TMP_FREG, src1, src1w));
        }
@@ -3152,7 +3328,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
                break;
        }
 
-       if (dst_r == TMP_FREG)
+       if (dst_r != dst)
                return emit_sse2_store(compiler, op & SLJIT_32, dst, dstw, TMP_FREG);
        return SLJIT_SUCCESS;
 }
@@ -3215,10 +3391,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
        PTR_FAIL_IF(!label);
        set_label(label, compiler);
 
-       inst = (sljit_u8*)ensure_buf(compiler, 2);
+       inst = (sljit_u8*)ensure_buf(compiler, 1);
        PTR_FAIL_IF(!inst);
-       inst[0] = 0;
-       inst[1] = 0;
+       inst[0] = SLJIT_INST_LABEL;
 
        return label;
 }
@@ -3236,18 +3411,13 @@ 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) << TYPE_SHIFT)));
        type &= 0xff;
 
+       jump->addr = compiler->size;
        /* Worst case size. */
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-       compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
-#else
-       compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3);
-#endif
-
-       inst = (sljit_u8*)ensure_buf(compiler, 2);
+       compiler->size += (type >= SLJIT_JUMP) ? JUMP_MAX_SIZE : CJUMP_MAX_SIZE;
+       inst = (sljit_u8*)ensure_buf(compiler, 1);
        PTR_FAIL_IF_NULL(inst);
 
-       inst[0] = 0;
-       inst[1] = 1;
+       inst[0] = SLJIT_INST_JUMP;
        return jump;
 }
 
@@ -3268,20 +3438,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
                set_jump(jump, compiler, (sljit_u32)(JUMP_ADDR | (type << TYPE_SHIFT)));
                jump->u.target = (sljit_uw)srcw;
 
+               jump->addr = compiler->size;
                /* Worst case size. */
-#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-               compiler->size += 5;
-#else
-               compiler->size += 10 + 3;
-#endif
-
-               inst = (sljit_u8*)ensure_buf(compiler, 2);
+               compiler->size += JUMP_MAX_SIZE;
+               inst = (sljit_u8*)ensure_buf(compiler, 1);
                FAIL_IF_NULL(inst);
 
-               inst[0] = 0;
-               inst[1] = 1;
-       }
-       else {
+               inst[0] = SLJIT_INST_JUMP;
+       } else {
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
                /* REX_W is not necessary (src is not immediate). */
                compiler->mode32 = 1;
@@ -3414,82 +3578,6 @@ 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_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_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_select(compiler, type, dst_reg, src1, src1w, src2_reg));
-
-       ADJUST_LOCAL_OFFSET(src1, src1w);
-
-       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;
-
-#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,
@@ -3581,7 +3669,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co
        if (type & SLJIT_SIMD_TEST)
                return SLJIT_SUCCESS;
 
-       if (op & VEX_256)
+       if ((op & VEX_256) || ((cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX)))
                return emit_vex_instruction(compiler, op, freg, 0, srcdst, srcdstw);
 
        return emit_groupf(compiler, op, freg, srcdst, srcdstw);
@@ -3593,9 +3681,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil
 {
        sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);
        sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);
+       sljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX);
        sljit_u8 *inst;
        sljit_u8 opcode = 0;
-       sljit_uw size;
+       sljit_uw op;
 
        CHECK_ERROR();
        CHECK(check_sljit_emit_simd_replicate(compiler, type, freg, src, srcw));
@@ -3616,20 +3705,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil
                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 (reg_size != 4 && (reg_size != 5 || !(cpu_feature_list & CPU_FEATURE_AVX2)))
+               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 (type & SLJIT_SIMD_TEST)
+               return SLJIT_SUCCESS;
+
+       if (reg_size == 5)
+               use_vex = 1;
 
+       if (use_vex && src != SLJIT_IMM) {
+               op = 0;
+
+               switch (elem_size) {
+               case 0:
+                       if (cpu_feature_list & CPU_FEATURE_AVX2)
+                               op = VPBROADCASTB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;
+                       break;
+               case 1:
+                       if (cpu_feature_list & CPU_FEATURE_AVX2)
+                               op = VPBROADCASTW_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;
+                       break;
+               case 2:
+                       if (type & SLJIT_SIMD_FLOAT) {
+                               if ((cpu_feature_list & CPU_FEATURE_AVX2) || ((cpu_feature_list & CPU_FEATURE_AVX) && (src & SLJIT_MEM)))
+                                       op = VBROADCASTSS_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;
+                       } else if (cpu_feature_list & CPU_FEATURE_AVX2)
+                               op = VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;
+                       break;
+               default:
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+                       if (!(type & SLJIT_SIMD_FLOAT)) {
+                               if (cpu_feature_list & CPU_FEATURE_AVX2)
+                                       op = VPBROADCASTQ_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;
+                               break;
+                       }
+#endif /* SLJIT_CONFIG_X86_64 */
+
+                       if (reg_size == 5)
+                               op = VBROADCASTSD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;
+                       break;
+               }
+
+               if (op != 0) {
                        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));
+                               FAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, src, srcw));
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
                                compiler->mode32 = 1;
 #endif /* SLJIT_CONFIG_X86_64 */
@@ -3637,51 +3761,40 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil
                                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;
+                               op |= VEX_256;
 
-                       return emit_vex_instruction(compiler, size, freg, 0, src, srcw);
+                       return emit_vex_instruction(compiler, op, 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);
+                       if (use_vex)
+                               return emit_vex_instruction(compiler, XORPD_x_xm | (reg_size == 5 ? VEX_256 : 0) | (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);
                }
 
+               SLJIT_ASSERT(reg_size == 4);
+
+               if (use_vex) {
+                       if (elem_size == 3)
+                               return emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, 0, src, srcw);
+
+                       SLJIT_ASSERT(!(src & SLJIT_MEM));
+                       FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | EX86_SSE2 | VEX_SSE2_OPV, freg, src, src, 0));
+                       return emit_byte(compiler, 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));
+               op = (elem_size == 2 ? SHUFPS_x_xm : MOVDDUP_x_xm) | (elem_size == 2 ? 0 : EX86_PREF_F2) | EX86_SSE2;
+               FAIL_IF(emit_groupf(compiler, op, freg, src, srcw));
 
                if (elem_size == 2)
                        return emit_byte(compiler, 0);
@@ -3706,8 +3819,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil
 #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);
+                       if (use_vex)
+                               return emit_vex_instruction(compiler, (srcw == 0 ? PXOR_x_xm : PCMPEQD_x_xm) | (reg_size == 5 ? VEX_256 : 0) | 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);
                }
@@ -3721,16 +3834,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil
 
                src = TMP_REG1;
                srcw = 0;
+
        }
 
-       size = 2;
+       op = 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;
+                       op = 3;
                }
                break;
        case 1:
@@ -3747,44 +3861,66 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil
 #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[0] = GROUP_0F;
-       inst[1] = opcode;
+       if (use_vex) {
+               if (opcode != MOVD_x_rm) {
+                       op = (opcode == 0x3a) ? (PINSRB_x_rm_i8 | VEX_OP_0F3A) : opcode;
+                       FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1 | VEX_SSE2_OPV, freg, freg, src, srcw));
+               } else
+                       FAIL_IF(emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, src, srcw));
+       } else {
+               inst = emit_x86_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, src, srcw);
+               FAIL_IF(!inst);
+               inst[0] = GROUP_0F;
+               inst[1] = opcode;
 
-       if (reg_size == 5) {
-               SLJIT_ASSERT(opcode == MOVD_x_rm);
+               if (op == 3) {
+                       SLJIT_ASSERT(opcode == 0x3a);
+                       inst[2] = PINSRB_x_rm_i8;
+               }
+       }
+
+       if (use_vex && elem_size >= 2) {
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-               size = VPBROADCASTD_x_xm;
+               op = VPBROADCASTD_x_xm;
 #else /* !SLJIT_CONFIG_X86_32 */
-               size = (elem_size == 3) ? VPBROADCASTQ_x_xm : VPBROADCASTD_x_xm;
+               op = (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);
+               return emit_vex_instruction(compiler, op | ((reg_size == 5) ? VEX_256 : 0) | 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;
-       }
+       SLJIT_ASSERT(reg_size == 4);
 
        if (opcode != MOVD_x_rm)
                FAIL_IF(emit_byte(compiler, 0));
 
        switch (elem_size) {
        case 0:
+               if (use_vex) {
+                       FAIL_IF(emit_vex_instruction(compiler, PXOR_x_xm | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, TMP_FREG, 0));
+                       return emit_vex_instruction(compiler, PSHUFB_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, TMP_FREG, 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));
+               if (use_vex)
+                       FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, 0, freg, 0));
+               else
+                       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));
+               if (use_vex)
+                       FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, 0, freg, 0));
+               else
+                       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));
+               if (use_vex)
+                       FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, 0, freg, 0));
+               else
+                       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 */
        }
@@ -3796,9 +3932,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile
 {
        sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);
        sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);
+       sljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX);
        sljit_u8 *inst;
        sljit_u8 opcode = 0;
-       sljit_uw size;
+       sljit_uw op;
        sljit_s32 freg_orig = freg;
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
        sljit_s32 srcdst_is_ereg = 0;
@@ -3814,6 +3951,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile
        if (reg_size == 5) {
                if (!(cpu_feature_list & CPU_FEATURE_AVX2))
                        return SLJIT_ERR_UNSUPPORTED;
+               use_vex = 1;
        } else if (reg_size != 4)
                return SLJIT_ERR_UNSUPPORTED;
 
@@ -3865,20 +4003,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile
                                }
 
                                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);
+                                       if (use_vex)
+                                               return emit_vex_instruction(compiler, MOVD_x_rm | VEX_AUTO_W | EX86_PREF_66 | EX86_SSE2_OP1, freg, 0, srcdst, srcdstw);
+                                       return emit_groupf(compiler, MOVD_x_rm | EX86_PREF_66 | EX86_SSE2_OP1, freg, 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);
+                               if (use_vex)
+                                       return emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, freg, 0, srcdst, srcdstw);
+                               return emit_groupf(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, freg, 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 (use_vex)
+                                       return emit_vex_instruction(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, freg, 0, srcdst, 0);
+                               return emit_groupf(compiler, MOVQ_x_xm | EX86_PREF_F3 | EX86_SSE2, freg, srcdst, 0);
+                       } else if (use_vex) {
+                               FAIL_IF(emit_vex_instruction(compiler, XORPD_x_xm | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, TMP_FREG, 0));
+                               return emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F3 | EX86_SSE2 | VEX_SSE2_OPV, freg, TMP_FREG, srcdst, 0);
                        }
                }
 
@@ -3886,18 +4027,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile
                        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));
+                       if (use_vex)
+                               FAIL_IF(emit_vex_instruction(compiler, MOVSD_x_xm | (elem_size == 2 ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, TMP_FREG, srcdst, srcdstw));
+                       else
+                               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)
+               op = ((!(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));
+               if (use_vex)
+                       FAIL_IF(emit_vex_instruction(compiler, op | (reg_size == 5 ? VEX_256 : 0) | VEX_SSE2_OPV, freg, freg, freg, 0));
                else
-                       FAIL_IF(emit_groupf(compiler, size, freg, freg, 0));
+                       FAIL_IF(emit_groupf(compiler, op, 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));
@@ -3910,58 +4054,80 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile
                if (elem_size == 3) {
                        if (srcdst & SLJIT_MEM) {
                                if (type & SLJIT_SIMD_STORE)
-                                       size = lane_index == 0 ? MOVLPD_m_x : MOVHPD_m_x;
+                                       op = lane_index == 0 ? MOVLPD_m_x : MOVHPD_m_x;
                                else
-                                       size = lane_index == 0 ? MOVLPD_x_m : MOVHPD_x_m;
+                                       op = lane_index == 0 ? MOVLPD_x_m : MOVHPD_x_m;
 
-                               FAIL_IF(emit_groupf(compiler, size | EX86_PREF_66 | EX86_SSE2, freg, srcdst, srcdstw));
+                               /* VEX prefix clears upper bits of the target register. */
+                               if (use_vex && ((type & SLJIT_SIMD_STORE) || reg_size == 4 || freg == TMP_FREG))
+                                       FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | EX86_SSE2
+                                               | ((type & SLJIT_SIMD_STORE) ? 0 : VEX_SSE2_OPV), freg, (type & SLJIT_SIMD_STORE) ? 0 : freg, srcdst, srcdstw));
+                               else
+                                       FAIL_IF(emit_groupf(compiler, op | 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)
+                               if (lane_index == 1) {
+                                       if (use_vex)
+                                               return emit_vex_instruction(compiler, MOVHLPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, freg, 0);
                                        return emit_groupf(compiler, MOVHLPS_x_x | EX86_SSE2, srcdst, freg, 0);
+                               }
+                               if (use_vex)
+                                       return emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, srcdst, srcdst, freg, 0);
                                return emit_sse2_load(compiler, 0, srcdst, freg, 0);
+                       } else if (use_vex && (reg_size == 4 || freg == TMP_FREG)) {
+                               if (lane_index == 1)
+                                       FAIL_IF(emit_vex_instruction(compiler, MOVLHPS_x_x | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, srcdst, 0));
+                               else
+                                       FAIL_IF(emit_vex_instruction(compiler, MOVSD_x_xm | EX86_PREF_F2 | EX86_SSE2 | VEX_SSE2_OPV, freg, freg, srcdst, 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));
+                                       FAIL_IF(emit_sse2_load(compiler, 0, freg, srcdst, 0));
                        }
                } else if (type & SLJIT_SIMD_STORE) {
-                       if (lane_index == 0)
+                       if (lane_index == 0) {
+                               if (use_vex)
+                                       return emit_vex_instruction(compiler, ((srcdst & SLJIT_MEM) ? MOVSD_xm_x : MOVSD_x_xm) | EX86_PREF_F3 | EX86_SSE2
+                                               | ((srcdst & SLJIT_MEM) ? 0 : VEX_SSE2_OPV), freg, ((srcdst & SLJIT_MEM) ? 0 : freg), srcdst, srcdstw);
                                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));
+                               if (use_vex)
+                                       FAIL_IF(emit_vex_instruction(compiler, EXTRACTPS_x_xm | EX86_PREF_66 | VEX_OP_0F3A | EX86_SSE2, freg, 0, srcdst, srcdstw));
+                               else
+                                       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 (use_vex) {
+                               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));
                        }
 
                        if (srcdst == freg)
-                               size = SHUFPS_x_xm | EX86_SSE2;
+                               op = 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;
+                                       op = MOVSHDUP_x_xm | EX86_PREF_F3 | EX86_SSE2;
                                        break;
                                case 2:
-                                       size = MOVHLPS_x_x | EX86_SSE2;
+                                       op = MOVHLPS_x_x | EX86_SSE2;
                                        break;
                                default:
                                        SLJIT_ASSERT(lane_index == 3);
-                                       size = PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2;
+                                       op = PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2;
                                        break;
                                }
                        }
 
-                       FAIL_IF(emit_groupf(compiler, size, srcdst, freg, 0));
+                       FAIL_IF(emit_groupf(compiler, op, srcdst, freg, 0));
 
-                       size &= 0xff;
-                       if (size == SHUFPS_x_xm || size == PSHUFD_x_xm)
+                       op &= 0xff;
+                       if (op == SHUFPS_x_xm || op == PSHUFD_x_xm)
                                return emit_byte(compiler, U8(lane_index));
 
                        return SLJIT_SUCCESS;
@@ -3993,7 +4159,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile
                srcdstw = 0;
        }
 
-       size = 3;
+       op = 3;
 
        switch (elem_size) {
        case 0:
@@ -4001,7 +4167,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile
                break;
        case 1:
                if (!(type & SLJIT_SIMD_STORE)) {
-                       size = 2;
+                       op = 2;
                        opcode = PINSRW_x_rm_i8;
                } else
                        opcode = PEXTRW_rm_x_i8;
@@ -4018,15 +4184,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile
 #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 (use_vex && (type & SLJIT_SIMD_STORE)) {
+               op = opcode | ((op == 3) ? VEX_OP_0F3A : 0);
+               FAIL_IF(emit_vex_instruction(compiler, op | EX86_PREF_66 | VEX_AUTO_W | EX86_SSE2_OP1 | VEX_SSE2_OPV, freg, 0, srcdst, srcdstw));
+       } else {
+               inst = emit_x86_instruction(compiler, op | 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;
+               if (op == 3) {
+                       inst[1] = 0x3a;
+                       inst[2] = opcode;
+               } else
+                       inst[1] = opcode;
+       }
 
        FAIL_IF(emit_byte(compiler, U8(lane_index)));
 
@@ -4056,23 +4227,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile
 
        compiler->mode32 = (type & SLJIT_32);
 
-       size = 2;
+       op = 2;
 
        if (elem_size == 0)
-               size |= EX86_REX;
+               op |= EX86_REX;
 
        if (elem_size == 2) {
                if (type & SLJIT_32)
                        return SLJIT_SUCCESS;
 
                SLJIT_ASSERT(!(compiler->mode32));
-               size = 1;
+               op = 1;
        }
 
-       inst = emit_x86_instruction(compiler, size, srcdst, 0, srcdst, 0);
+       inst = emit_x86_instruction(compiler, op, srcdst, 0, srcdst, 0);
        FAIL_IF(!inst);
 
-       if (size != 1) {
+       if (op != 1) {
                inst[0] = GROUP_0F;
                inst[1] = U8((elem_size == 0) ? MOVSX_r_rm8 : MOVSX_r_rm16);
        } else
@@ -4096,6 +4267,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
 {
        sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);
        sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);
+       sljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX);
        sljit_uw pref;
        sljit_u8 byte;
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
@@ -4115,6 +4287,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
        if (reg_size == 5) {
                if (!(cpu_feature_list & CPU_FEATURE_AVX2))
                        return SLJIT_ERR_UNSUPPORTED;
+               use_vex = 1;
        } else if (reg_size != 4)
                return SLJIT_ERR_UNSUPPORTED;
 
@@ -4136,8 +4309,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
                                return emit_byte(compiler, U8(byte | (byte << 4)));
                        }
 
-                       if (src_lane_index == 0)
+                       if (src_lane_index == 0) {
+                               if (use_vex)
+                                       return emit_vex_instruction(compiler, MOVDDUP_x_xm | EX86_PREF_F2 | EX86_SSE2, freg, 0, src, 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;
@@ -4163,7 +4339,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
                        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)) {
+               } else if (use_vex) {
                        FAIL_IF(emit_vex_instruction(compiler, SHUFPS_x_xm | pref | EX86_SSE2 | VEX_SSE2_OPV, freg, src, src, 0));
                } else {
                        if (freg != src)
@@ -4192,7 +4368,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
                        src = freg;
                }
 
-               if ((freg != src && !(cpu_feature_list & CPU_FEATURE_AVX2)) || src_lane_index != 0) {
+               if (src_lane_index != 0 || (freg != src && (!(cpu_feature_list & CPU_FEATURE_AVX2) || !use_vex))) {
                        pref = 0;
 
                        if ((src_lane_index & 0x3) == 0) {
@@ -4202,7 +4378,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
                                pref = EX86_PREF_F2;
                                byte = U8(src_lane_index >> 1);
                        } else {
-                               if (freg == src || !(cpu_feature_list & CPU_FEATURE_AVX2)) {
+                               if (!use_vex) {
                                        if (freg != src)
                                                FAIL_IF(emit_groupf(compiler, MOVDQA_x_xm | EX86_PREF_66 | EX86_SSE2, freg, src, 0));
 
@@ -4214,14 +4390,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
                        }
 
                        if (pref != 0) {
-                               FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, src, 0));
+                               if (use_vex)
+                                       FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, 0, src, 0));
+                               else
+                                       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)
+               if (use_vex && (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);
@@ -4229,7 +4408,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
                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) {
+       if ((cpu_feature_list & CPU_FEATURE_AVX2) && use_vex && src_lane_index == 0 && elem_size <= 3) {
                switch (elem_size) {
                case 1:
                        pref = VPBROADCASTW_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2;
@@ -4291,11 +4470,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
                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));
+               if (use_vex)
+                       FAIL_IF(emit_vex_instruction(compiler, PSHUFLW_x_xm | pref | EX86_SSE2, freg, 0, src, 0));
+               else
+                       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)
+               if ((cpu_feature_list & CPU_FEATURE_AVX2) && use_vex && 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;
@@ -4310,7 +4492,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
                break;
        }
 
-       FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, src, 0));
+       if (use_vex)
+               FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, 0, src, 0));
+       else
+               FAIL_IF(emit_groupf(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, freg, src, 0));
        return emit_byte(compiler, U8(byte | (byte << 4)));
 }
 
@@ -4321,6 +4506,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler
        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 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX);
        sljit_u8 opcode;
 
        CHECK_ERROR();
@@ -4335,6 +4521,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler
        if (reg_size == 5) {
                if (!(cpu_feature_list & CPU_FEATURE_AVX2))
                        return SLJIT_ERR_UNSUPPORTED;
+               use_vex = 1;
        } else if (reg_size != 4)
                return SLJIT_ERR_UNSUPPORTED;
 
@@ -4345,9 +4532,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler
                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);
+               if (use_vex)
+                       return emit_vex_instruction(compiler, CVTPS2PD_x_xm | ((reg_size == 5) ? VEX_256 : 0) | EX86_SSE2, freg, 0, src, srcw);
+               return emit_groupf(compiler, CVTPS2PD_x_xm | EX86_SSE2, freg, src, srcw);
        }
 
        switch (elem_size) {
@@ -4382,9 +4569,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler
        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);
+       if (use_vex)
+               return emit_vex_instruction(compiler, opcode | ((reg_size == 5) ? VEX_256 : 0) | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, 0, src, srcw);
+       return emit_groupf_ext(compiler, opcode | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, freg, src, srcw);
 }
 
 SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *compiler, sljit_s32 type,
@@ -4393,8 +4580,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c
 {
        sljit_s32 reg_size = SLJIT_SIMD_GET_REG_SIZE(type);
        sljit_s32 elem_size = SLJIT_SIMD_GET_ELEM_SIZE(type);
+       sljit_s32 use_vex = (cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX);
        sljit_s32 dst_r;
-       sljit_uw pref;
+       sljit_uw op;
        sljit_u8 *inst;
 
        CHECK_ERROR();
@@ -4414,20 +4602,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c
                if (type & SLJIT_SIMD_TEST)
                        return SLJIT_SUCCESS;
 
-               pref = EX86_PREF_66 | EX86_SSE2_OP2;
+               op = 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));
+                       if (use_vex)
+                               FAIL_IF(emit_vex_instruction(compiler, PACKSSWB_x_xm | EX86_PREF_66 | EX86_SSE2 | VEX_SSE2_OPV, TMP_FREG, freg, freg, 0));
+                       else
+                               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;
+                       op = 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));
+               op |= (elem_size < 2) ? PMOVMSKB_r_x : MOVMSKPS_r_x;
+
+               if (use_vex)
+                       FAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, freg, 0));
+               else
+                       FAIL_IF(emit_groupf(compiler, op, dst_r, freg, 0));
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
                compiler->mode32 = type & SLJIT_32;
@@ -4459,14 +4655,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c
                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;
+               op = MOVMSKPS_r_x | VEX_256 | EX86_SSE2_OP2;
 
                if (elem_size == 0)
-                       pref = PMOVMSKB_r_x | VEX_256 | EX86_PREF_66 | EX86_SSE2_OP2;
+                       op = PMOVMSKB_r_x | VEX_256 | EX86_PREF_66 | EX86_SSE2_OP2;
                else if (elem_size == 3)
-                       pref |= EX86_PREF_66;
+                       op |= EX86_PREF_66;
 
-               FAIL_IF(emit_vex_instruction(compiler, pref, dst_r, 0, freg, 0));
+               FAIL_IF(emit_vex_instruction(compiler, op, dst_r, 0, freg, 0));
        }
 
        if (dst_r == TMP_REG1) {
@@ -4497,7 +4693,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co
 {
        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();
@@ -4540,20 +4735,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co
        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 || ((cpu_feature_list & CPU_FEATURE_AVX) && (compiler->options & SLJIT_ENTER_USE_VEX))) {
                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;
+       if (dst_freg != src1_freg) {
+               if (dst_freg == src2_freg)
+                       src2_freg = src1_freg;
+               else
+                       FAIL_IF(emit_simd_mov(compiler, type, dst_freg, src1_freg));
        }
 
        FAIL_IF(emit_groupf(compiler, op | EX86_SSE2, dst_freg, src2_freg, 0));
@@ -4727,11 +4920,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
                return NULL;
 #endif
 
-       inst = (sljit_u8*)ensure_buf(compiler, 2);
+       inst = (sljit_u8*)ensure_buf(compiler, 1);
        PTR_FAIL_IF(!inst);
 
-       inst[0] = 0;
-       inst[1] = 2;
+       inst[0] = SLJIT_INST_CONST;
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
        if (dst & SLJIT_MEM)
@@ -4742,52 +4934,48 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
        return const_;
 }
 
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
 {
-       struct sljit_put_label *put_label;
+       struct sljit_jump *jump;
        sljit_u8 *inst;
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
        sljit_s32 reg;
-       sljit_uw start_size;
-#endif
+#endif /* SLJIT_CONFIG_X86_64 */
 
        CHECK_ERROR_PTR();
-       CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+       CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
        ADJUST_LOCAL_OFFSET(dst, dstw);
 
        CHECK_EXTRA_REGS(dst, dstw, (void)0);
 
-       put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
-       PTR_FAIL_IF(!put_label);
-       set_put_label(put_label, compiler, 0);
+       jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+       PTR_FAIL_IF(!jump);
+       set_mov_addr(jump, compiler, 0);
 
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
        compiler->mode32 = 0;
        reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
 
-       if (emit_load_imm64(compiler, reg, 0))
-               return NULL;
-#else
-       if (emit_mov(compiler, dst, dstw, SLJIT_IMM, 0))
-               return NULL;
-#endif
+       PTR_FAIL_IF(emit_load_imm64(compiler, reg, 0));
+       jump->addr = compiler->size;
 
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-       if (dst & SLJIT_MEM) {
-               start_size = compiler->size;
-               if (emit_mov(compiler, dst, dstw, TMP_REG1, 0))
-                       return NULL;
-               put_label->flags = compiler->size - start_size;
-       }
-#endif
+       if (reg_map[reg] >= 8)
+               jump->flags |= MOV_ADDR_HI;
+#else /* !SLJIT_CONFIG_X86_64 */
+       PTR_FAIL_IF(emit_mov(compiler, dst, dstw, SLJIT_IMM, 0));
+#endif /* SLJIT_CONFIG_X86_64 */
 
-       inst = (sljit_u8*)ensure_buf(compiler, 2);
+       inst = (sljit_u8*)ensure_buf(compiler, 1);
        PTR_FAIL_IF(!inst);
 
-       inst[0] = 0;
-       inst[1] = 3;
+       inst[0] = SLJIT_INST_MOV_ADDR;
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+       if (dst & SLJIT_MEM)
+               PTR_FAIL_IF(emit_mov(compiler, dst, dstw, TMP_REG1, 0));
+#endif /* SLJIT_CONFIG_X86_64 */
 
-       return put_label;
+       return jump;
 }
 
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
diff --git a/src/sljit/sljitSerialize.c b/src/sljit/sljitSerialize.c
new file mode 100644 (file)
index 0000000..6ef161f
--- /dev/null
@@ -0,0 +1,516 @@
+/*
+ *    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.
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_label(struct sljit_jump *jump)
+{
+       return !(jump->flags & JUMP_ADDR) && (jump->u.label != NULL);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_target(struct sljit_jump *jump)
+{
+       return (jump->flags & JUMP_ADDR) != 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_is_mov_addr(struct sljit_jump *jump)
+{
+       return (jump->flags & JUMP_MOV_ADDR) != 0;
+}
+
+#define SLJIT_SERIALIZE_DEBUG ((sljit_u16)0x1)
+
+struct sljit_serialized_compiler {
+       sljit_u32 signature;
+       sljit_u16 version;
+       sljit_u16 cpu_type;
+
+       sljit_uw buf_segment_count;
+       sljit_uw label_count;
+       sljit_uw jump_count;
+       sljit_uw const_count;
+
+       sljit_s32 options;
+       sljit_s32 scratches;
+       sljit_s32 saveds;
+       sljit_s32 fscratches;
+       sljit_s32 fsaveds;
+       sljit_s32 local_size;
+       sljit_uw size;
+
+#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
+       sljit_s32 status_flags_state;
+#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+       sljit_s32 args_size;
+#endif /* SLJIT_CONFIG_X86_32 */
+
+#if ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \
+               || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+       sljit_uw args_size;
+#endif /* (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */
+
+#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
+       sljit_uw cpool_diff;
+       sljit_uw cpool_fill;
+       sljit_uw patches;
+#endif /* SLJIT_CONFIG_ARM_V6 */
+
+#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+       sljit_s32 delay_slot;
+#endif /* SLJIT_CONFIG_MIPS */
+
+};
+
+struct sljit_serialized_debug_info {
+       sljit_sw last_flags;
+       sljit_s32 last_return;
+       sljit_s32 logical_local_size;
+};
+
+struct sljit_serialized_label {
+       sljit_uw size;
+};
+
+struct sljit_serialized_jump {
+       sljit_uw addr;
+       sljit_uw flags;
+       sljit_uw value;
+};
+
+struct sljit_serialized_const {
+       sljit_uw addr;
+};
+
+#define SLJIT_SERIALIZE_ALIGN(v) (((v) + sizeof(sljit_uw) - 1) & ~(sljit_uw)(sizeof(sljit_uw) - 1))
+#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN)
+#define SLJIT_SERIALIZE_SIGNATURE 0x534c4a54
+#else /* !SLJIT_LITTLE_ENDIAN */
+#define SLJIT_SERIALIZE_SIGNATURE 0x544a4c53
+#endif /* SLJIT_LITTLE_ENDIAN */
+#define SLJIT_SERIALIZE_VERSION 1
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compiler *compiler,
+       sljit_s32 options, sljit_uw *size)
+{
+       sljit_uw serialized_size = sizeof(struct sljit_serialized_compiler);
+       struct sljit_memory_fragment *buf;
+       struct sljit_label *label;
+       struct sljit_jump *jump;
+       struct sljit_const *const_;
+       struct sljit_serialized_compiler *serialized_compiler;
+       struct sljit_serialized_label *serialized_label;
+       struct sljit_serialized_jump *serialized_jump;
+       struct sljit_serialized_const *serialized_const;
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
+               || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+       struct sljit_serialized_debug_info *serialized_debug_info;
+#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */
+       sljit_uw counter, used_size;
+       sljit_u8 *result;
+       sljit_u8 *ptr;
+       SLJIT_UNUSED_ARG(options);
+
+       if (size != NULL)
+               *size = 0;
+
+       PTR_FAIL_IF(compiler->error);
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
+               || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+       if (!(options & SLJIT_SERIALIZE_IGNORE_DEBUG))
+               serialized_size += sizeof(struct sljit_serialized_debug_info);
+#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */
+
+#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
+       serialized_size += SLJIT_SERIALIZE_ALIGN(compiler->cpool_fill * (sizeof(sljit_uw) + 1));
+#endif /* SLJIT_CONFIG_ARM_V6 */
+
+       /* Compute the size of the data. */
+       buf = compiler->buf;
+       while (buf != NULL) {
+               serialized_size += sizeof(sljit_uw) + SLJIT_SERIALIZE_ALIGN(buf->used_size);
+               buf = buf->next;
+       }
+
+       serialized_size += compiler->label_count * sizeof(struct sljit_serialized_label);
+
+       jump = compiler->jumps;
+       while (jump != NULL) {
+               serialized_size += sizeof(struct sljit_serialized_jump);
+               jump = jump->next;
+       }
+
+       const_ = compiler->consts;
+       while (const_ != NULL) {
+               serialized_size += sizeof(struct sljit_serialized_const);
+               const_ = const_->next;
+       }
+
+       result = (sljit_u8*)SLJIT_MALLOC(serialized_size, compiler->allocator_data);
+       PTR_FAIL_IF_NULL(result);
+
+       if (size != NULL)
+               *size = serialized_size;
+
+       ptr = result;
+       serialized_compiler = (struct sljit_serialized_compiler*)ptr;
+       ptr += sizeof(struct sljit_serialized_compiler);
+
+       serialized_compiler->signature = SLJIT_SERIALIZE_SIGNATURE;
+       serialized_compiler->version = SLJIT_SERIALIZE_VERSION;
+       serialized_compiler->cpu_type = 0;
+       serialized_compiler->label_count = compiler->label_count;
+       serialized_compiler->options = compiler->options;
+       serialized_compiler->scratches = compiler->scratches;
+       serialized_compiler->saveds = compiler->saveds;
+       serialized_compiler->fscratches = compiler->fscratches;
+       serialized_compiler->fsaveds = compiler->fsaveds;
+       serialized_compiler->local_size = compiler->local_size;
+       serialized_compiler->size = compiler->size;
+
+#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
+       serialized_compiler->status_flags_state = compiler->status_flags_state;
+#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+               || ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \
+               || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+       serialized_compiler->args_size = compiler->args_size;
+#endif /* SLJIT_CONFIG_X86_32 || (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */
+
+#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
+       serialized_compiler->cpool_diff = compiler->cpool_diff;
+       serialized_compiler->cpool_fill = compiler->cpool_fill;
+       serialized_compiler->patches = compiler->patches;
+
+       SLJIT_MEMCPY(ptr, compiler->cpool, compiler->cpool_fill * sizeof(sljit_uw));
+       SLJIT_MEMCPY(ptr + compiler->cpool_fill * sizeof(sljit_uw), compiler->cpool_unique, compiler->cpool_fill);
+       ptr += SLJIT_SERIALIZE_ALIGN(compiler->cpool_fill * (sizeof(sljit_uw) + 1));
+#endif /* SLJIT_CONFIG_ARM_V6 */
+
+#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+       serialized_compiler->delay_slot = compiler->delay_slot;
+#endif /* SLJIT_CONFIG_MIPS */
+
+       buf = compiler->buf;
+       counter = 0;
+       while (buf != NULL) {
+               used_size = buf->used_size;
+               *(sljit_uw*)ptr = used_size;
+               ptr += sizeof(sljit_uw);
+               SLJIT_MEMCPY(ptr, buf->memory, used_size);
+               ptr += SLJIT_SERIALIZE_ALIGN(used_size);
+               buf = buf->next;
+               counter++;
+       }
+       serialized_compiler->buf_segment_count = counter;
+
+       label = compiler->labels;
+       while (label != NULL) {
+               serialized_label = (struct sljit_serialized_label*)ptr;
+               serialized_label->size = label->size;
+               ptr += sizeof(struct sljit_serialized_label);
+               label = label->next;
+       }
+
+       jump = compiler->jumps;
+       counter = 0;
+       while (jump != NULL) {
+               serialized_jump = (struct sljit_serialized_jump*)ptr;
+               serialized_jump->addr = jump->addr;
+               serialized_jump->flags = jump->flags;
+
+               if (jump->flags & JUMP_ADDR)
+                       serialized_jump->value = jump->u.target;
+               else if (jump->u.label != NULL)
+                       serialized_jump->value = jump->u.label->u.index;
+               else
+                       serialized_jump->value = SLJIT_MAX_ADDRESS;
+
+               ptr += sizeof(struct sljit_serialized_jump);
+               jump = jump->next;
+               counter++;
+       }
+       serialized_compiler->jump_count = counter;
+
+       const_ = compiler->consts;
+       counter = 0;
+       while (const_ != NULL) {
+               serialized_const = (struct sljit_serialized_const*)ptr;
+               serialized_const->addr = const_->addr;
+               ptr += sizeof(struct sljit_serialized_const);
+               const_ = const_->next;
+               counter++;
+       }
+       serialized_compiler->const_count = counter;
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
+               || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+       if (!(options & SLJIT_SERIALIZE_IGNORE_DEBUG)) {
+               serialized_debug_info = (struct sljit_serialized_debug_info*)ptr;
+               serialized_debug_info->last_flags = compiler->last_flags;
+               serialized_debug_info->last_return = compiler->last_return;
+               serialized_debug_info->logical_local_size = compiler->logical_local_size;
+               serialized_compiler->cpu_type |= SLJIT_SERIALIZE_DEBUG;
+#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
+               ptr += sizeof(struct sljit_serialized_debug_info);
+#endif /* SLJIT_DEBUG */
+       }
+#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */
+
+       SLJIT_ASSERT((sljit_uw)(ptr - result) == serialized_size);
+       return (sljit_uw*)result;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit_uw* buffer, sljit_uw size,
+       sljit_s32 options, void *allocator_data)
+{
+       struct sljit_compiler *compiler;
+       struct sljit_serialized_compiler *serialized_compiler;
+       struct sljit_serialized_label *serialized_label;
+       struct sljit_serialized_jump *serialized_jump;
+       struct sljit_serialized_const *serialized_const;
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
+               || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+       struct sljit_serialized_debug_info *serialized_debug_info;
+#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */
+       struct sljit_memory_fragment *buf;
+       struct sljit_memory_fragment *last_buf;
+       struct sljit_label *label;
+       struct sljit_label *last_label;
+       struct sljit_label **label_list = NULL;
+       struct sljit_jump *jump;
+       struct sljit_jump *last_jump;
+       struct sljit_const *const_;
+       struct sljit_const *last_const;
+       sljit_u8 *ptr = (sljit_u8*)buffer;
+       sljit_u8 *end = ptr + size;
+       sljit_uw i, used_size, aligned_size, label_count;
+       SLJIT_UNUSED_ARG(options);
+
+       if (size < sizeof(struct sljit_serialized_compiler) || (size & (sizeof(sljit_uw) - 1)) != 0)
+               return NULL;
+
+       serialized_compiler = (struct sljit_serialized_compiler*)ptr;
+
+       if (serialized_compiler->signature != SLJIT_SERIALIZE_SIGNATURE || serialized_compiler->version != SLJIT_SERIALIZE_VERSION)
+               return NULL;
+
+       compiler = sljit_create_compiler(allocator_data);
+       PTR_FAIL_IF(compiler == NULL);
+
+       compiler->label_count = serialized_compiler->label_count;
+       compiler->options = serialized_compiler->options;
+       compiler->scratches = serialized_compiler->scratches;
+       compiler->saveds = serialized_compiler->saveds;
+       compiler->fscratches = serialized_compiler->fscratches;
+       compiler->fsaveds = serialized_compiler->fsaveds;
+       compiler->local_size = serialized_compiler->local_size;
+       compiler->size = serialized_compiler->size;
+
+#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
+       compiler->status_flags_state = serialized_compiler->status_flags_state;
+#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+               || ((defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) && (defined __SOFTFP__)) \
+               || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+       compiler->args_size = serialized_compiler->args_size;
+#endif /* SLJIT_CONFIG_X86_32 || (SLJIT_CONFIG_ARM_32 && __SOFTFP__) || SLJIT_CONFIG_MIPS_32 */
+
+#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
+       used_size = serialized_compiler->cpool_fill;
+       aligned_size = SLJIT_SERIALIZE_ALIGN(used_size * (sizeof(sljit_uw) + 1));
+       compiler->cpool_diff = serialized_compiler->cpool_diff;
+       compiler->cpool_fill = used_size;
+       compiler->patches = serialized_compiler->patches;
+
+       if ((sljit_uw)(end - ptr) < aligned_size)
+               goto error;
+
+       SLJIT_MEMCPY(compiler->cpool, ptr, used_size * sizeof(sljit_uw));
+       SLJIT_MEMCPY(compiler->cpool_unique, ptr + used_size * sizeof(sljit_uw), used_size);
+       ptr += aligned_size;
+#endif /* SLJIT_CONFIG_ARM_V6 */
+
+#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+       compiler->delay_slot = serialized_compiler->delay_slot;
+#endif /* SLJIT_CONFIG_MIPS */
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
+               || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+       if (!(serialized_compiler->cpu_type & SLJIT_SERIALIZE_DEBUG))
+               goto error;
+#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */
+
+       ptr += sizeof(struct sljit_serialized_compiler);
+       i = serialized_compiler->buf_segment_count;
+       last_buf = NULL;
+       while (i > 0) {
+               if ((sljit_uw)(end - ptr) < sizeof(sljit_uw))
+                       goto error;
+
+               used_size = *(sljit_uw*)ptr;
+               aligned_size = SLJIT_SERIALIZE_ALIGN(used_size);
+               ptr += sizeof(sljit_uw);
+
+               if ((sljit_uw)(end - ptr) < aligned_size)
+                       goto error;
+
+               if (last_buf == NULL) {
+                       SLJIT_ASSERT(compiler->buf != NULL && compiler->buf->next == NULL);
+                       buf = compiler->buf;
+               } else {
+                       buf = (struct sljit_memory_fragment*)SLJIT_MALLOC(BUF_SIZE, allocator_data);
+                       if (!buf)
+                               goto error;
+                       buf->next = NULL;
+               }
+
+               buf->used_size = used_size;
+               SLJIT_MEMCPY(buf->memory, ptr, used_size);
+
+               if (last_buf != NULL)
+                       last_buf->next = buf;
+               last_buf = buf;
+
+               ptr += aligned_size;
+               i--;
+       }
+
+       last_label = NULL;
+       label_count = serialized_compiler->label_count;
+       if ((sljit_uw)(end - ptr) < label_count * sizeof(struct sljit_serialized_label))
+               goto error;
+
+       label_list = (struct sljit_label **)SLJIT_MALLOC(label_count * sizeof(struct sljit_label*), allocator_data);
+       if (label_list == NULL)
+               goto error;
+
+       for (i = 0; i < label_count; i++) {
+               label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+               if (label == NULL)
+                       goto error;
+
+               serialized_label = (struct sljit_serialized_label*)ptr;
+               label->next = NULL;
+               label->u.index = i;
+               label->size = serialized_label->size;
+
+               if (last_label != NULL)
+                       last_label->next = label;
+               else
+                       compiler->labels = label;
+               last_label = label;
+
+               label_list[i] = label;
+               ptr += sizeof(struct sljit_serialized_label);
+       }
+       compiler->last_label = last_label;
+
+       last_jump = NULL;
+       i = serialized_compiler->jump_count;
+       if ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_jump))
+               goto error;
+
+       while (i > 0) {
+               jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
+               if (jump == NULL)
+                       goto error;
+
+               serialized_jump = (struct sljit_serialized_jump*)ptr;
+               jump->next = NULL;
+               jump->addr = serialized_jump->addr;
+               jump->flags = serialized_jump->flags;
+
+               if (!(serialized_jump->flags & JUMP_ADDR)) {
+                       if (serialized_jump->value != SLJIT_MAX_ADDRESS) {
+                               if (serialized_jump->value >= label_count)
+                                       goto error;
+                               jump->u.label = label_list[serialized_jump->value];
+                       } else
+                               jump->u.label = NULL;
+               } else
+                       jump->u.target = serialized_jump->value;
+
+               if (last_jump != NULL)
+                       last_jump->next = jump;
+               else
+                       compiler->jumps = jump;
+               last_jump = jump;
+
+               ptr += sizeof(struct sljit_serialized_jump);
+               i--;
+       }
+       compiler->last_jump = last_jump;
+
+       SLJIT_FREE(label_list, allocator_data);
+       label_list = NULL;
+
+       last_const = NULL;
+       i = serialized_compiler->const_count;
+       if ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_const))
+               goto error;
+
+       while (i > 0) {
+               const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
+               if (const_ == NULL)
+                       goto error;
+
+               serialized_const = (struct sljit_serialized_const*)ptr;
+               const_->next = NULL;
+               const_->addr = serialized_const->addr;
+
+               if (last_const != NULL)
+                       last_const->next = const_;
+               else
+                       compiler->consts = const_;
+               last_const = const_;
+
+               ptr += sizeof(struct sljit_serialized_const);
+               i--;
+       }
+       compiler->last_const = last_const;
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
+               || (defined SLJIT_DEBUG && SLJIT_DEBUG)
+       if ((sljit_uw)(end - ptr) < sizeof(struct sljit_serialized_debug_info))
+               goto error;
+
+       serialized_debug_info = (struct sljit_serialized_debug_info*)ptr;
+       compiler->last_flags = (sljit_s32)serialized_debug_info->last_flags;
+       compiler->last_return = serialized_debug_info->last_return;
+       compiler->logical_local_size = serialized_debug_info->logical_local_size;
+#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_DEBUG */
+
+       return compiler;
+
+error:
+       sljit_free_compiler(compiler);
+       if (label_list != NULL)
+               SLJIT_FREE(label_list, allocator_data);
+       return NULL;
+}
index e901d51d81d036315b4037d6c4ce38a4d9a3e728..3190ebcd8677dcddb6b7f5a34ea535435db1fced 100644 (file)
     
 # Check name length with non-ASCII characters 
 
-/(?'ABáC678901234567890123456789012'...)/utf
+/(?'ABáC678901234567890123456789012012345678901234567890123456789AB012345678901234567890123456789AB012345678901234567890123456789AB'...)/utf
 
-/(?'ABáC6789012345678901234567890123'...)/utf
+/(?'ABáC6789012345678901234567890123012345678901234567890123456789AB012345678901234567890123456789AB012345678901234567890123456789AB'...)/utf
 
-/(?'ABZC6789012345678901234567890123'...)/utf
+/(?'ABZC6789012345678901234567890123012345678901234567890123456789AB012345678901234567890123456789AB012345678901234567890123456789AB'...)/utf
 
 /(?(n/utf
 
index 9760854291841b4faf8e13f73478ab30adfbac07..b90489ae3c8b2ab56d14bad9af582a805305ea9e 100644 (file)
@@ -4680,9 +4680,9 @@ B)x/alt_verbnames,mark
 /(?<=\K.)/g,replace=-,allow_lookaround_bsk
     ab
 
-/(?'abcdefghijklmnopqrstuvwxyzABCDEFG'toolong)/
+/(?'abcdefghijklmnopqrstuvwxyzABCDEFGabcdefghijklmnopqrstuvwxyzABCDEabcdefghijklmnopqrstuvwxyzABCDEabcdefghijklmnopqrstuvwxyzABCDEFGH'toolong)/
 
-/(?'abcdefghijklmnopqrstuvwxyzABCDEF'justright)/
+/(?'abcdefghijklmnopqrstuvwxyzABCDEFGabcdefghijklmnopqrstuvwxyzABCDEabcdefghijklmnopqrstuvwxyzABCDEabcdefghijklmnopqrstuvwxyzABCDEFG'justright)/
 
 # These two use zero-termination
 /abcd/max_pattern_length=3
@@ -4694,6 +4694,9 @@ B)x/alt_verbnames,mark
 
 /abcdef/hex,max_pattern_length=3
 
+# Test compiled length limit
+/(abcdefg){10}/max_pattern_compiled_length=100
+
 # These patterns used to take a long time to compile
 
 "(.*)
@@ -4949,7 +4952,7 @@ a)"xI
 /{\84Í\84ÍÍ\84Í{'{22{2{{2{'{22{\12{22{2{'{22{2{{2{{222{{2{'{22{2{22{2{'{22{2{{2{'{22{2{22{2{'{'{22{2{22{2{'{22{2{{2{'{22{2{22{2{'{222{2Ä\84Í\84ÍÍ\84Í{'{22{2{{2{'{22{\12{11{2{'{22{2{{2{{'{22{2{{2{'{22{\12{22{1{'{22{2{{2{{222{{2{'{22{2{22{2{'{/auto_callout
 
 //
-\=get=i00000000000000000000000000000000
+\=get=i00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 \=get=i2345678901234567890123456789012,get=i1245678901234567890123456789012
 
 "(?(?C))"
@@ -6099,4 +6102,13 @@ a)"xI
 /(a(?1)z||(?1)++)$/
     abcd\=disable_recurseloop_check
 
+/(((?<=123?456456|ABC)))(?<=\2)../
+    ABCDEFG
+    12345645678910 
+    
+# This test is crashing Perl 5.38.2.
+
+/[^\S\W]{6}/
+    .abc def..
+
 # End of testinput2
index 34f187a9ef55d3e80a166a0000566643d327944c..2205caff2e833322e7c49ef174d4317af493b371 100644 (file)
     \x0a\x{1b04}LF, spacingmark
     \x0b\x{0711}Control, extend
     \x09\x{1b04}Control, spacingmark
+    *Test Extended Pictographic after bug fix
+    \x{261d}\x{261d}B              Extended_Pictographic Extended_Pictographic 
+    \x{261D}\x{1F3FB}\x{261d}B     Extended_Pictographic Extend E-P
+    \x{261D}\x{1F3FB}\x{200d}\x{261d}B     Extended_Pictographic Extend ZWJ E-P
+    \x{1f3f3}\x{fe0f}\x{200d}\x{1f308}\x{1f3f4}\x{200d}\x{2620}\x{fe0f}\x{1f3f3}\x{fe0f}\x{200d}\x{1f308}\x{1f3f4}\x{200d}\x{2620}\x{fe0f}
+    A\x{200d}\x{1f308}B
+    A\x{200d}B                     A ZWJ
+    \x{261D}\x{1F3FB}B             Extended_Pictographic Extend
+    \x{1F1E6}\x{1F1E7}B            RegionalIndicator RegionalIndicator 
     *There are no Prepend characters, so we can't test Prepend, CR
 
 /^(?>\X{2})X/utf,aftertext
index 855ecc4c967a132c71a06b86c799e94117cfab7e..7e04873a30eaed05bb4a7e83d471b1f3c2af5422 100644 (file)
   (\p{Medefaidrin}+)(\p{Old_Sogdian}+)(\p{Sogdian}+)/x,utf
     \x{11800}\x{11da9}\x{10d27}\x{11ee0}\x{16e48}\x{10f27}\x{10f30} 
 
-# These two are here because of differences from Perl.
-
-/^\X/utf
-    A\x{200d}B                     A ZWJ
-    \x{261d}\x{261d}B              Extended_Pictographic Extended_Pictographic 
-    \x{261D}\x{1F3FB}B             Extended_Pictographic Extend
-    \x{1F1E6}\x{1F1E7}B            RegionalIndicator RegionalIndicator 
-    \x{261D}\x{1F3FB}\x{261d}B     Extended_Pictographic Extend E-P
-    \x{261D}\x{1F3FB}\x{200d}\x{261d}B     Extended_Pictographic Extend ZWJ E-P
-
 # Regional indicators
 
 /^(\X)(\X)/utf,aftertext
index 8145891fd99975c6fe6e3f21de515be900d32843..1cf758455828a9e866893b68bfc40e45fe171891 100644 (file)
@@ -1615,12 +1615,12 @@ No match
     
 # Check name length with non-ASCII characters 
 
-/(?'ABáC678901234567890123456789012'...)/utf
+/(?'ABáC678901234567890123456789012012345678901234567890123456789AB012345678901234567890123456789AB012345678901234567890123456789AB'...)/utf
 
-/(?'ABáC6789012345678901234567890123'...)/utf
-Failed: error 148 at offset 36: subpattern name is too long (maximum 32 code units)
+/(?'ABáC6789012345678901234567890123012345678901234567890123456789AB012345678901234567890123456789AB012345678901234567890123456789AB'...)/utf
+Failed: error 148 at offset 132: subpattern name is too long (maximum 128 code units)
 
-/(?'ABZC6789012345678901234567890123'...)/utf
+/(?'ABZC6789012345678901234567890123012345678901234567890123456789AB012345678901234567890123456789AB012345678901234567890123456789AB'...)/utf
 
 /(?(n/utf
 Failed: error 142 at offset 4: syntax error in subpattern name (missing terminator?)
index 78d43bdaabfc5e2c917cd54db8893f6105f48e8e..54c9f18cad4e49ad9bc3f102d991aa3c4d787674 100644 (file)
@@ -3,6 +3,7 @@
 # are different without JIT.
 
 /abc/I,jit,jitverify
+JIT compilation was not successful (bad JIT option)
 Capture group count = 0
 First code unit = 'a'
 Last code unit = 'c'
index ff17d0616d04ad6af8966131e772df38e3b99175..00c4bd4c96ea405a9b978bb22a6f7aabfef5b07b 100644 (file)
@@ -6,6 +6,7 @@
 # JIT does not support this pattern (callout at start of condition).
 
 /(?(?C1)(?=a)a)/I
+JIT compilation was not successful (no more memory)
 Capture group count = 0
 May match empty string
 Subject length lower bound = 0
@@ -14,6 +15,7 @@ JIT compilation was not successful (no more memory)
 # The following pattern cannot be compiled by JIT.
 
 /b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*b*/I
+JIT compilation was not successful (no more memory)
 Capture group count = 0
 May match empty string
 Subject length lower bound = 0
index ee1f70b0ffa8febf8d4d4c0251a8d7ba9b4277f5..83756686a61499ed812be6be3a96f30b1a160880 100644 (file)
@@ -14935,10 +14935,10 @@ Failed: error -60: match with end before start or start moved backwards is not s
     ab
 Failed: error -60: match with end before start or start moved backwards is not supported
 
-/(?'abcdefghijklmnopqrstuvwxyzABCDEFG'toolong)/
-Failed: error 148 at offset 36: subpattern name is too long (maximum 32 code units)
+/(?'abcdefghijklmnopqrstuvwxyzABCDEFGabcdefghijklmnopqrstuvwxyzABCDEabcdefghijklmnopqrstuvwxyzABCDEabcdefghijklmnopqrstuvwxyzABCDEFGH'toolong)/
+Failed: error 148 at offset 132: subpattern name is too long (maximum 128 code units)
 
-/(?'abcdefghijklmnopqrstuvwxyzABCDEF'justright)/
+/(?'abcdefghijklmnopqrstuvwxyzABCDEFGabcdefghijklmnopqrstuvwxyzABCDEabcdefghijklmnopqrstuvwxyzABCDEabcdefghijklmnopqrstuvwxyzABCDEFG'justright)/
 
 # These two use zero-termination
 /abcd/max_pattern_length=3
@@ -14952,6 +14952,10 @@ Failed: error 188 at offset 0: pattern string is longer than the limit set by th
 
 /abcdef/hex,max_pattern_length=3
 
+# Test compiled length limit
+/(abcdefg){10}/max_pattern_compiled_length=100
+Failed: error 201 at offset 13: compiled pattern would be longer than the limit set by the application
+
 # These patterns used to take a long time to compile
 
 "(.*)
@@ -15549,7 +15553,7 @@ Failed: error 157 at offset 6: \g is not followed by a braced, angle-bracketed,
 /{\84Í\84ÍÍ\84Í{'{22{2{{2{'{22{\12{22{2{'{22{2{{2{{222{{2{'{22{2{22{2{'{22{2{{2{'{22{2{22{2{'{'{22{2{22{2{'{22{2{{2{'{22{2{22{2{'{222{2Ä\84Í\84ÍÍ\84Í{'{22{2{{2{'{22{\12{11{2{'{22{2{{2{{'{22{2{{2{'{22{\12{22{1{'{22{2{{2{{222{{2{'{22{2{22{2{'{/auto_callout
 
 //
-\=get=i00000000000000000000000000000000
+\=get=i00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 ** Group name in 'get' is too long
 \=get=i2345678901234567890123456789012,get=i1245678901234567890123456789012
 ** Too many characters in named 'get' modifiers
@@ -18038,6 +18042,22 @@ Failed: error -47: match limit exceeded
  0: 
  1: 
 
+/(((?<=123?456456|ABC)))(?<=\2)../
+    ABCDEFG
+ 0: DE
+ 1: 
+ 2: 
+    12345645678910 
+ 0: 78
+ 1: 
+ 2: 
+    
+# This test is crashing Perl 5.38.2.
+
+/[^\S\W]{6}/
+    .abc def..
+No match
+
 # End of testinput2
 Error -70: PCRE2_ERROR_BADDATA (unknown error number)
 Error -62: bad serialized data
index cb121fab77a7d0611f5c868b3637cd779325156f..5917ebbe5250dabcb13a41b12c9d97a87d8a7a57 100644 (file)
@@ -2668,6 +2668,33 @@ No match
     \x09\x{1b04}Control, spacingmark
  0: \x{09}
  0+ \x{1b04}Control, spacingmark
+    *Test Extended Pictographic after bug fix
+ 0: *
+ 0+ Test Extended Pictographic after bug fix
+    \x{261d}\x{261d}B              Extended_Pictographic Extended_Pictographic 
+ 0: \x{261d}
+ 0+ \x{261d}B              Extended_Pictographic Extended_Pictographic
+    \x{261D}\x{1F3FB}\x{261d}B     Extended_Pictographic Extend E-P
+ 0: \x{261d}\x{1f3fb}
+ 0+ \x{261d}B     Extended_Pictographic Extend E-P
+    \x{261D}\x{1F3FB}\x{200d}\x{261d}B     Extended_Pictographic Extend ZWJ E-P
+ 0: \x{261d}\x{1f3fb}\x{200d}\x{261d}
+ 0+ B     Extended_Pictographic Extend ZWJ E-P
+    \x{1f3f3}\x{fe0f}\x{200d}\x{1f308}\x{1f3f4}\x{200d}\x{2620}\x{fe0f}\x{1f3f3}\x{fe0f}\x{200d}\x{1f308}\x{1f3f4}\x{200d}\x{2620}\x{fe0f}
+ 0: \x{1f3f3}\x{fe0f}\x{200d}\x{1f308}
+ 0+ \x{1f3f4}\x{200d}\x{2620}\x{fe0f}\x{1f3f3}\x{fe0f}\x{200d}\x{1f308}\x{1f3f4}\x{200d}\x{2620}\x{fe0f}
+    A\x{200d}\x{1f308}B
+ 0: A\x{200d}
+ 0+ \x{1f308}B
+    A\x{200d}B                     A ZWJ
+ 0: A\x{200d}
+ 0+ B                     A ZWJ
+    \x{261D}\x{1F3FB}B             Extended_Pictographic Extend
+ 0: \x{261d}\x{1f3fb}
+ 0+ B             Extended_Pictographic Extend
+    \x{1F1E6}\x{1F1E7}B            RegionalIndicator RegionalIndicator 
+ 0: \x{1f1e6}\x{1f1e7}
+ 0+ B            RegionalIndicator RegionalIndicator
     *There are no Prepend characters, so we can't test Prepend, CR
  0: *
  0+ There are no Prepend characters, so we can't test Prepend, CR
index c289c5ced5f63367b0ec1b4dd8a371ff1497c087..b79959bc290a1ed962e938b8d82d0579aacd997a 100644 (file)
@@ -4708,22 +4708,6 @@ Callout 0: last capture = 1
  6: \x{10f27}
  7: \x{10f30}
 
-# These two are here because of differences from Perl.
-
-/^\X/utf
-    A\x{200d}B                     A ZWJ
- 0: A\x{200d}
-    \x{261d}\x{261d}B              Extended_Pictographic Extended_Pictographic 
- 0: \x{261d}\x{261d}
-    \x{261D}\x{1F3FB}B             Extended_Pictographic Extend
- 0: \x{261d}\x{1f3fb}
-    \x{1F1E6}\x{1F1E7}B            RegionalIndicator RegionalIndicator 
- 0: \x{1f1e6}\x{1f1e7}
-    \x{261D}\x{1F3FB}\x{261d}B     Extended_Pictographic Extend E-P
- 0: \x{261d}\x{1f3fb}\x{261d}
-    \x{261D}\x{1F3FB}\x{200d}\x{261d}B     Extended_Pictographic Extend ZWJ E-P
- 0: \x{261d}\x{1f3fb}\x{200d}\x{261d}
-
 # Regional indicators
 
 /^(\X)(\X)/utf,aftertext
index 49b1022c0ea07d2de69bf08a779404366856ae18..bcb9e17745a2a7d551cedf8f3f41ce1955e6df0c 100644 (file)
@@ -10,7 +10,8 @@
 #pattern fullbincode,memory
 
 /((?i)b)/
-Memory allocation (code space): 24
+Memory allocation - compiled block : 160
+Memory allocation - code portion   : 24
 ------------------------------------------------------------------
   0   9 Bra
   2   5 CBra 1
@@ -21,7 +22,8 @@ Memory allocation (code space): 24
 ------------------------------------------------------------------
 
 /(?s)(.*X|^B)/
-Memory allocation (code space): 38
+Memory allocation - compiled block : 174
+Memory allocation - code portion   : 38
 ------------------------------------------------------------------
   0  16 Bra
   2   7 CBra 1
@@ -36,7 +38,8 @@ Memory allocation (code space): 38
 ------------------------------------------------------------------
 
 /(?s:.*X|^B)/
-Memory allocation (code space): 36
+Memory allocation - compiled block : 172
+Memory allocation - code portion   : 36
 ------------------------------------------------------------------
   0  15 Bra
   2   6 Bra
@@ -51,7 +54,8 @@ Memory allocation (code space): 36
 ------------------------------------------------------------------
 
 /^[[:alnum:]]/
-Memory allocation (code space): 46
+Memory allocation - compiled block : 182
+Memory allocation - code portion   : 46
 ------------------------------------------------------------------
   0  20 Bra
   2     ^
@@ -61,7 +65,8 @@ Memory allocation (code space): 46
 ------------------------------------------------------------------
 
 /#/Ix
-Memory allocation (code space): 10
+Memory allocation - compiled block : 146
+Memory allocation - code portion   : 10
 ------------------------------------------------------------------
   0   2 Bra
   2   2 Ket
@@ -73,7 +78,8 @@ Options: extended
 Subject length lower bound = 0
 
 /a#/Ix
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -86,7 +92,8 @@ First code unit = 'a'
 Subject length lower bound = 1
 
 /x?+/
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     x?+
@@ -95,7 +102,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /x++/
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     x++
@@ -104,7 +112,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /x{1,3}+/
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0   7 Bra
   2     x
@@ -114,7 +123,8 @@ Memory allocation (code space): 20
 ------------------------------------------------------------------
 
 /(x)*+/
-Memory allocation (code space): 26
+Memory allocation - compiled block : 162
+Memory allocation - code portion   : 26
 ------------------------------------------------------------------
   0  10 Bra
   2     Braposzero
@@ -126,7 +136,8 @@ Memory allocation (code space): 26
 ------------------------------------------------------------------
 
 /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
-Memory allocation (code space): 142
+Memory allocation - compiled block : 278
+Memory allocation - code portion   : 142
 ------------------------------------------------------------------
   0  68 Bra
   2     ^
@@ -149,7 +160,8 @@ Memory allocation (code space): 142
 ------------------------------------------------------------------
 
 "8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 1648
+Memory allocation - compiled block : 1784
+Memory allocation - code portion   : 1648
 ------------------------------------------------------------------
   0 821 Bra
   2     8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -159,7 +171,8 @@ Memory allocation (code space): 1648
 ------------------------------------------------------------------
 
 "\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 1628
+Memory allocation - compiled block : 1764
+Memory allocation - code portion   : 1628
 ------------------------------------------------------------------
   0 811 Bra
   2     $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -169,7 +182,8 @@ Memory allocation (code space): 1628
 ------------------------------------------------------------------
 
 /(a(?1)b)/
-Memory allocation (code space): 32
+Memory allocation - compiled block : 168
+Memory allocation - code portion   : 32
 ------------------------------------------------------------------
   0  13 Bra
   2   9 CBra 1
@@ -182,7 +196,8 @@ Memory allocation (code space): 32
 ------------------------------------------------------------------
 
 /(a(?1)+b)/
-Memory allocation (code space): 40
+Memory allocation - compiled block : 176
+Memory allocation - code portion   : 40
 ------------------------------------------------------------------
   0  17 Bra
   2  13 CBra 1
@@ -197,7 +212,8 @@ Memory allocation (code space): 40
 ------------------------------------------------------------------
 
 /a(?P<name1>b|c)d(?P<longername2>e)/
-Memory allocation (code space): 54
+Memory allocation - compiled block : 242
+Memory allocation - code portion   : 54
 ------------------------------------------------------------------
   0  24 Bra
   2     a
@@ -215,7 +231,8 @@ Memory allocation (code space): 54
 ------------------------------------------------------------------
 
 /(?:a(?P<c>c(?P<d>d)))(?P<a>a)/
-Memory allocation (code space): 64
+Memory allocation - compiled block : 218
+Memory allocation - code portion   : 64
 ------------------------------------------------------------------
   0  29 Bra
   2  18 Bra
@@ -235,7 +252,8 @@ Memory allocation (code space): 64
 ------------------------------------------------------------------
 
 /(?P<a>a)...(?P=a)bbb(?P>a)d/
-Memory allocation (code space): 54
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 54
 ------------------------------------------------------------------
   0  24 Bra
   2   5 CBra 1
@@ -253,7 +271,8 @@ Memory allocation (code space): 54
 ------------------------------------------------------------------
 
 /abc(?C255)de(?C)f/
-Memory allocation (code space): 50
+Memory allocation - compiled block : 186
+Memory allocation - code portion   : 50
 ------------------------------------------------------------------
   0  22 Bra
   2     abc
@@ -266,7 +285,8 @@ Memory allocation (code space): 50
 ------------------------------------------------------------------
 
 /abcde/auto_callout
-Memory allocation (code space): 78
+Memory allocation - compiled block : 214
+Memory allocation - code portion   : 78
 ------------------------------------------------------------------
   0  36 Bra
   2     Callout 255 0 1
@@ -285,7 +305,8 @@ Memory allocation (code space): 78
 ------------------------------------------------------------------
 
 /\x{100}/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -294,7 +315,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /\x{1000}/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{1000}
@@ -303,7 +325,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /\x{10000}/utf
-Memory allocation (code space): 16
+Memory allocation - compiled block : 152
+Memory allocation - code portion   : 16
 ------------------------------------------------------------------
   0   5 Bra
   2     \x{10000}
@@ -312,7 +335,8 @@ Memory allocation (code space): 16
 ------------------------------------------------------------------
 
 /\x{100000}/utf
-Memory allocation (code space): 16
+Memory allocation - compiled block : 152
+Memory allocation - code portion   : 16
 ------------------------------------------------------------------
   0   5 Bra
   2     \x{100000}
@@ -321,7 +345,8 @@ Memory allocation (code space): 16
 ------------------------------------------------------------------
 
 /\x{10ffff}/utf
-Memory allocation (code space): 16
+Memory allocation - compiled block : 152
+Memory allocation - code portion   : 16
 ------------------------------------------------------------------
   0   5 Bra
   2     \x{10ffff}
@@ -333,7 +358,8 @@ Memory allocation (code space): 16
 Failed: error 134 at offset 9: character code point value in \x{} or \o{} is too large
 
 /[\x{ff}]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{ff}
@@ -342,7 +368,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[\x{100}]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -351,7 +378,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /\x80/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{80}
@@ -360,7 +388,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /\xff/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{ff}
@@ -369,7 +398,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /\x{0041}\x{2262}\x{0391}\x{002e}/I,utf
-Memory allocation (code space): 26
+Memory allocation - compiled block : 162
+Memory allocation - code portion   : 26
 ------------------------------------------------------------------
   0  10 Bra
   2     A\x{2262}\x{391}.
@@ -383,7 +413,8 @@ Last code unit = '.'
 Subject length lower bound = 4
 
 /\x{D55c}\x{ad6d}\x{C5B4}/I,utf
-Memory allocation (code space): 22
+Memory allocation - compiled block : 158
+Memory allocation - code portion   : 22
 ------------------------------------------------------------------
   0   8 Bra
   2     \x{d55c}\x{ad6d}\x{c5b4}
@@ -397,7 +428,8 @@ Last code unit = \x{c5b4}
 Subject length lower bound = 3
 
 /\x{65e5}\x{672c}\x{8a9e}/I,utf
-Memory allocation (code space): 22
+Memory allocation - compiled block : 158
+Memory allocation - code portion   : 22
 ------------------------------------------------------------------
   0   8 Bra
   2     \x{65e5}\x{672c}\x{8a9e}
@@ -411,7 +443,8 @@ Last code unit = \x{8a9e}
 Subject length lower bound = 3
 
 /[\x{100}]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -420,7 +453,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[Z\x{100}]/utf
-Memory allocation (code space): 54
+Memory allocation - compiled block : 190
+Memory allocation - code portion   : 54
 ------------------------------------------------------------------
   0  24 Bra
   2     [Z\x{100}]
@@ -429,7 +463,8 @@ Memory allocation (code space): 54
 ------------------------------------------------------------------
 
 /^[\x{100}\E-\Q\E\x{150}]/utf
-Memory allocation (code space): 26
+Memory allocation - compiled block : 162
+Memory allocation - code portion   : 26
 ------------------------------------------------------------------
   0  10 Bra
   2     ^
@@ -439,7 +474,8 @@ Memory allocation (code space): 26
 ------------------------------------------------------------------
 
 /^[\QĀ\E-\QŐ\E]/utf
-Memory allocation (code space): 26
+Memory allocation - compiled block : 162
+Memory allocation - code portion   : 26
 ------------------------------------------------------------------
   0  10 Bra
   2     ^
@@ -452,7 +488,8 @@ Memory allocation (code space): 26
 Failed: error 106 at offset 13: missing terminating ] for character class
 
 /[\p{L}]/
-Memory allocation (code space): 24
+Memory allocation - compiled block : 160
+Memory allocation - code portion   : 24
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{L}]
@@ -461,7 +498,8 @@ Memory allocation (code space): 24
 ------------------------------------------------------------------
 
 /[\p{^L}]/
-Memory allocation (code space): 24
+Memory allocation - compiled block : 160
+Memory allocation - code portion   : 24
 ------------------------------------------------------------------
   0   9 Bra
   2     [\P{L}]
@@ -470,7 +508,8 @@ Memory allocation (code space): 24
 ------------------------------------------------------------------
 
 /[\P{L}]/
-Memory allocation (code space): 24
+Memory allocation - compiled block : 160
+Memory allocation - code portion   : 24
 ------------------------------------------------------------------
   0   9 Bra
   2     [\P{L}]
@@ -479,7 +518,8 @@ Memory allocation (code space): 24
 ------------------------------------------------------------------
 
 /[\P{^L}]/
-Memory allocation (code space): 24
+Memory allocation - compiled block : 160
+Memory allocation - code portion   : 24
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{L}]
@@ -488,7 +528,8 @@ Memory allocation (code space): 24
 ------------------------------------------------------------------
 
 /[abc\p{L}\x{0660}]/utf
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  27 Bra
   2     [a-c\p{L}\x{660}]
@@ -497,7 +538,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /[\p{Nd}]/utf
-Memory allocation (code space): 24
+Memory allocation - compiled block : 160
+Memory allocation - code portion   : 24
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{Nd}]
@@ -506,7 +548,8 @@ Memory allocation (code space): 24
 ------------------------------------------------------------------
 
 /[\p{Nd}+-]+/utf
-Memory allocation (code space): 58
+Memory allocation - compiled block : 194
+Memory allocation - code portion   : 58
 ------------------------------------------------------------------
   0  26 Bra
   2     [+\-\p{Nd}]++
@@ -515,7 +558,8 @@ Memory allocation (code space): 58
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/i,utf
-Memory allocation (code space): 32
+Memory allocation - compiled block : 168
+Memory allocation - code portion   : 32
 ------------------------------------------------------------------
   0  13 Bra
   2  /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -524,7 +568,8 @@ Memory allocation (code space): 32
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/utf
-Memory allocation (code space): 32
+Memory allocation - compiled block : 168
+Memory allocation - code portion   : 32
 ------------------------------------------------------------------
   0  13 Bra
   2     A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -533,7 +578,8 @@ Memory allocation (code space): 32
 ------------------------------------------------------------------
 
 /[\x{105}-\x{109}]/i,utf
-Memory allocation (code space): 24
+Memory allocation - compiled block : 160
+Memory allocation - code portion   : 24
 ------------------------------------------------------------------
   0   9 Bra
   2     [\x{104}-\x{109}]
@@ -542,7 +588,8 @@ Memory allocation (code space): 24
 ------------------------------------------------------------------
 
 /( ( (?(1)0|) )*   )/x
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  23 Bra
   2  19 CBra 1
@@ -560,7 +607,8 @@ Memory allocation (code space): 52
 ------------------------------------------------------------------
 
 /(  (?(1)0|)*   )/x
-Memory allocation (code space): 42
+Memory allocation - compiled block : 178
+Memory allocation - code portion   : 42
 ------------------------------------------------------------------
   0  18 Bra
   2  14 CBra 1
@@ -576,7 +624,8 @@ Memory allocation (code space): 42
 ------------------------------------------------------------------
 
 /[a]/
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -585,7 +634,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[a]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -594,7 +644,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[\xaa]/
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{aa}
@@ -603,7 +654,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[\xaa]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{aa}
@@ -612,7 +664,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[^a]/
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     [^a]
@@ -621,7 +674,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[^a]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     [^a]
@@ -630,7 +684,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[^\xaa]/
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     [^\x{aa}]
@@ -639,7 +694,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[^\xaa]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   4 Bra
   2     [^\x{aa}]
index 80ee1c99c404ad2c88e8ad5e755e4b3f06da530c..4ec13ea9822e2dff1dd0d20df50c18113c9168bf 100644 (file)
@@ -10,7 +10,8 @@
 #pattern fullbincode,memory
 
 /((?i)b)/
-Memory allocation (code space): 32
+Memory allocation - compiled block : 168
+Memory allocation - code portion   : 32
 ------------------------------------------------------------------
   0  12 Bra
   3   6 CBra 1
@@ -21,7 +22,8 @@ Memory allocation (code space): 32
 ------------------------------------------------------------------
 
 /(?s)(.*X|^B)/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0  20 Bra
   3   8 CBra 1
@@ -36,7 +38,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /(?s:.*X|^B)/
-Memory allocation (code space): 46
+Memory allocation - compiled block : 182
+Memory allocation - code portion   : 46
 ------------------------------------------------------------------
   0  19 Bra
   3   7 Bra
@@ -51,7 +54,8 @@ Memory allocation (code space): 46
 ------------------------------------------------------------------
 
 /^[[:alnum:]]/
-Memory allocation (code space): 50
+Memory allocation - compiled block : 186
+Memory allocation - code portion   : 50
 ------------------------------------------------------------------
   0  21 Bra
   3     ^
@@ -61,7 +65,8 @@ Memory allocation (code space): 50
 ------------------------------------------------------------------
 
 /#/Ix
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   3 Bra
   3   3 Ket
@@ -73,7 +78,8 @@ Options: extended
 Subject length lower bound = 0
 
 /a#/Ix
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     a
@@ -86,7 +92,8 @@ First code unit = 'a'
 Subject length lower bound = 1
 
 /x?+/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     x?+
@@ -95,7 +102,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /x++/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     x++
@@ -104,7 +112,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /x{1,3}+/
-Memory allocation (code space): 24
+Memory allocation - compiled block : 160
+Memory allocation - code portion   : 24
 ------------------------------------------------------------------
   0   8 Bra
   3     x
@@ -114,7 +123,8 @@ Memory allocation (code space): 24
 ------------------------------------------------------------------
 
 /(x)*+/
-Memory allocation (code space): 34
+Memory allocation - compiled block : 170
+Memory allocation - code portion   : 34
 ------------------------------------------------------------------
   0  13 Bra
   3     Braposzero
@@ -126,7 +136,8 @@ Memory allocation (code space): 34
 ------------------------------------------------------------------
 
 /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
-Memory allocation (code space): 166
+Memory allocation - compiled block : 302
+Memory allocation - code portion   : 166
 ------------------------------------------------------------------
   0  79 Bra
   3     ^
@@ -149,7 +160,8 @@ Memory allocation (code space): 166
 ------------------------------------------------------------------
 
 "8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 1652
+Memory allocation - compiled block : 1788
+Memory allocation - code portion   : 1652
 ------------------------------------------------------------------
   0 822 Bra
   3     8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -159,7 +171,8 @@ Memory allocation (code space): 1652
 ------------------------------------------------------------------
 
 "\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 1632
+Memory allocation - compiled block : 1768
+Memory allocation - code portion   : 1632
 ------------------------------------------------------------------
   0 812 Bra
   3     $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -169,7 +182,8 @@ Memory allocation (code space): 1632
 ------------------------------------------------------------------
 
 /(a(?1)b)/
-Memory allocation (code space): 42
+Memory allocation - compiled block : 178
+Memory allocation - code portion   : 42
 ------------------------------------------------------------------
   0  17 Bra
   3  11 CBra 1
@@ -182,7 +196,8 @@ Memory allocation (code space): 42
 ------------------------------------------------------------------
 
 /(a(?1)+b)/
-Memory allocation (code space): 54
+Memory allocation - compiled block : 190
+Memory allocation - code portion   : 54
 ------------------------------------------------------------------
   0  23 Bra
   3  17 CBra 1
@@ -197,7 +212,8 @@ Memory allocation (code space): 54
 ------------------------------------------------------------------
 
 /a(?P<name1>b|c)d(?P<longername2>e)/
-Memory allocation (code space): 68
+Memory allocation - compiled block : 256
+Memory allocation - code portion   : 68
 ------------------------------------------------------------------
   0  30 Bra
   3     a
@@ -215,7 +231,8 @@ Memory allocation (code space): 68
 ------------------------------------------------------------------
 
 /(?:a(?P<c>c(?P<d>d)))(?P<a>a)/
-Memory allocation (code space): 84
+Memory allocation - compiled block : 238
+Memory allocation - code portion   : 84
 ------------------------------------------------------------------
   0  38 Bra
   3  23 Bra
@@ -235,7 +252,8 @@ Memory allocation (code space): 84
 ------------------------------------------------------------------
 
 /(?P<a>a)...(?P=a)bbb(?P>a)d/
-Memory allocation (code space): 64
+Memory allocation - compiled block : 206
+Memory allocation - code portion   : 64
 ------------------------------------------------------------------
   0  28 Bra
   3   6 CBra 1
@@ -253,7 +271,8 @@ Memory allocation (code space): 64
 ------------------------------------------------------------------
 
 /abc(?C255)de(?C)f/
-Memory allocation (code space): 62
+Memory allocation - compiled block : 198
+Memory allocation - code portion   : 62
 ------------------------------------------------------------------
   0  27 Bra
   3     abc
@@ -266,7 +285,8 @@ Memory allocation (code space): 62
 ------------------------------------------------------------------
 
 /abcde/auto_callout
-Memory allocation (code space): 106
+Memory allocation - compiled block : 242
+Memory allocation - code portion   : 106
 ------------------------------------------------------------------
   0  49 Bra
   3     Callout 255 0 1
@@ -285,7 +305,8 @@ Memory allocation (code space): 106
 ------------------------------------------------------------------
 
 /\x{100}/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{100}
@@ -294,7 +315,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /\x{1000}/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{1000}
@@ -303,7 +325,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /\x{10000}/utf
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{10000}
@@ -312,7 +335,8 @@ Memory allocation (code space): 20
 ------------------------------------------------------------------
 
 /\x{100000}/utf
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{100000}
@@ -321,7 +345,8 @@ Memory allocation (code space): 20
 ------------------------------------------------------------------
 
 /\x{10ffff}/utf
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{10ffff}
@@ -333,7 +358,8 @@ Memory allocation (code space): 20
 Failed: error 134 at offset 9: character code point value in \x{} or \o{} is too large
 
 /[\x{ff}]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{ff}
@@ -342,7 +368,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[\x{100}]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{100}
@@ -351,7 +378,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /\x80/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{80}
@@ -360,7 +388,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /\xff/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{ff}
@@ -369,7 +398,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /\x{0041}\x{2262}\x{0391}\x{002e}/I,utf
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     A\x{2262}\x{391}.
@@ -383,7 +413,8 @@ Last code unit = '.'
 Subject length lower bound = 4
 
 /\x{D55c}\x{ad6d}\x{C5B4}/I,utf
-Memory allocation (code space): 26
+Memory allocation - compiled block : 162
+Memory allocation - code portion   : 26
 ------------------------------------------------------------------
   0   9 Bra
   3     \x{d55c}\x{ad6d}\x{c5b4}
@@ -397,7 +428,8 @@ Last code unit = \x{c5b4}
 Subject length lower bound = 3
 
 /\x{65e5}\x{672c}\x{8a9e}/I,utf
-Memory allocation (code space): 26
+Memory allocation - compiled block : 162
+Memory allocation - code portion   : 26
 ------------------------------------------------------------------
   0   9 Bra
   3     \x{65e5}\x{672c}\x{8a9e}
@@ -411,7 +443,8 @@ Last code unit = \x{8a9e}
 Subject length lower bound = 3
 
 /[\x{100}]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{100}
@@ -420,7 +453,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[Z\x{100}]/utf
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  26 Bra
   3     [Z\x{100}]
@@ -429,7 +463,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /^[\x{100}\E-\Q\E\x{150}]/utf
-Memory allocation (code space): 32
+Memory allocation - compiled block : 168
+Memory allocation - code portion   : 32
 ------------------------------------------------------------------
   0  12 Bra
   3     ^
@@ -439,7 +474,8 @@ Memory allocation (code space): 32
 ------------------------------------------------------------------
 
 /^[\QĀ\E-\QŐ\E]/utf
-Memory allocation (code space): 32
+Memory allocation - compiled block : 168
+Memory allocation - code portion   : 32
 ------------------------------------------------------------------
   0  12 Bra
   3     ^
@@ -452,7 +488,8 @@ Memory allocation (code space): 32
 Failed: error 106 at offset 13: missing terminating ] for character class
 
 /[\p{L}]/
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\p{L}]
@@ -461,7 +498,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /[\p{^L}]/
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\P{L}]
@@ -470,7 +508,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /[\P{L}]/
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\P{L}]
@@ -479,7 +518,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /[\P{^L}]/
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\p{L}]
@@ -488,7 +528,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /[abc\p{L}\x{0660}]/utf
-Memory allocation (code space): 66
+Memory allocation - compiled block : 202
+Memory allocation - code portion   : 66
 ------------------------------------------------------------------
   0  29 Bra
   3     [a-c\p{L}\x{660}]
@@ -497,7 +538,8 @@ Memory allocation (code space): 66
 ------------------------------------------------------------------
 
 /[\p{Nd}]/utf
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\p{Nd}]
@@ -506,7 +548,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /[\p{Nd}+-]+/utf
-Memory allocation (code space): 64
+Memory allocation - compiled block : 200
+Memory allocation - code portion   : 64
 ------------------------------------------------------------------
   0  28 Bra
   3     [+\-\p{Nd}]++
@@ -515,7 +558,8 @@ Memory allocation (code space): 64
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/i,utf
-Memory allocation (code space): 36
+Memory allocation - compiled block : 172
+Memory allocation - code portion   : 36
 ------------------------------------------------------------------
   0  14 Bra
   3  /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -524,7 +568,8 @@ Memory allocation (code space): 36
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/utf
-Memory allocation (code space): 36
+Memory allocation - compiled block : 172
+Memory allocation - code portion   : 36
 ------------------------------------------------------------------
   0  14 Bra
   3     A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -533,7 +578,8 @@ Memory allocation (code space): 36
 ------------------------------------------------------------------
 
 /[\x{105}-\x{109}]/i,utf
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\x{104}-\x{109}]
@@ -542,7 +588,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /( ( (?(1)0|) )*   )/x
-Memory allocation (code space): 70
+Memory allocation - compiled block : 206
+Memory allocation - code portion   : 70
 ------------------------------------------------------------------
   0  31 Bra
   3  25 CBra 1
@@ -560,7 +607,8 @@ Memory allocation (code space): 70
 ------------------------------------------------------------------
 
 /(  (?(1)0|)*   )/x
-Memory allocation (code space): 56
+Memory allocation - compiled block : 192
+Memory allocation - code portion   : 56
 ------------------------------------------------------------------
   0  24 Bra
   3  18 CBra 1
@@ -576,7 +624,8 @@ Memory allocation (code space): 56
 ------------------------------------------------------------------
 
 /[a]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     a
@@ -585,7 +634,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[a]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     a
@@ -594,7 +644,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[\xaa]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{aa}
@@ -603,7 +654,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[\xaa]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{aa}
@@ -612,7 +664,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[^a]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     [^a]
@@ -621,7 +674,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[^a]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     [^a]
@@ -630,7 +684,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[^\xaa]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     [^\x{aa}]
@@ -639,7 +694,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[^\xaa]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     [^\x{aa}]
index 80ee1c99c404ad2c88e8ad5e755e4b3f06da530c..4ec13ea9822e2dff1dd0d20df50c18113c9168bf 100644 (file)
@@ -10,7 +10,8 @@
 #pattern fullbincode,memory
 
 /((?i)b)/
-Memory allocation (code space): 32
+Memory allocation - compiled block : 168
+Memory allocation - code portion   : 32
 ------------------------------------------------------------------
   0  12 Bra
   3   6 CBra 1
@@ -21,7 +22,8 @@ Memory allocation (code space): 32
 ------------------------------------------------------------------
 
 /(?s)(.*X|^B)/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0  20 Bra
   3   8 CBra 1
@@ -36,7 +38,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /(?s:.*X|^B)/
-Memory allocation (code space): 46
+Memory allocation - compiled block : 182
+Memory allocation - code portion   : 46
 ------------------------------------------------------------------
   0  19 Bra
   3   7 Bra
@@ -51,7 +54,8 @@ Memory allocation (code space): 46
 ------------------------------------------------------------------
 
 /^[[:alnum:]]/
-Memory allocation (code space): 50
+Memory allocation - compiled block : 186
+Memory allocation - code portion   : 50
 ------------------------------------------------------------------
   0  21 Bra
   3     ^
@@ -61,7 +65,8 @@ Memory allocation (code space): 50
 ------------------------------------------------------------------
 
 /#/Ix
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   3 Bra
   3   3 Ket
@@ -73,7 +78,8 @@ Options: extended
 Subject length lower bound = 0
 
 /a#/Ix
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     a
@@ -86,7 +92,8 @@ First code unit = 'a'
 Subject length lower bound = 1
 
 /x?+/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     x?+
@@ -95,7 +102,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /x++/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     x++
@@ -104,7 +112,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /x{1,3}+/
-Memory allocation (code space): 24
+Memory allocation - compiled block : 160
+Memory allocation - code portion   : 24
 ------------------------------------------------------------------
   0   8 Bra
   3     x
@@ -114,7 +123,8 @@ Memory allocation (code space): 24
 ------------------------------------------------------------------
 
 /(x)*+/
-Memory allocation (code space): 34
+Memory allocation - compiled block : 170
+Memory allocation - code portion   : 34
 ------------------------------------------------------------------
   0  13 Bra
   3     Braposzero
@@ -126,7 +136,8 @@ Memory allocation (code space): 34
 ------------------------------------------------------------------
 
 /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
-Memory allocation (code space): 166
+Memory allocation - compiled block : 302
+Memory allocation - code portion   : 166
 ------------------------------------------------------------------
   0  79 Bra
   3     ^
@@ -149,7 +160,8 @@ Memory allocation (code space): 166
 ------------------------------------------------------------------
 
 "8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 1652
+Memory allocation - compiled block : 1788
+Memory allocation - code portion   : 1652
 ------------------------------------------------------------------
   0 822 Bra
   3     8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -159,7 +171,8 @@ Memory allocation (code space): 1652
 ------------------------------------------------------------------
 
 "\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 1632
+Memory allocation - compiled block : 1768
+Memory allocation - code portion   : 1632
 ------------------------------------------------------------------
   0 812 Bra
   3     $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -169,7 +182,8 @@ Memory allocation (code space): 1632
 ------------------------------------------------------------------
 
 /(a(?1)b)/
-Memory allocation (code space): 42
+Memory allocation - compiled block : 178
+Memory allocation - code portion   : 42
 ------------------------------------------------------------------
   0  17 Bra
   3  11 CBra 1
@@ -182,7 +196,8 @@ Memory allocation (code space): 42
 ------------------------------------------------------------------
 
 /(a(?1)+b)/
-Memory allocation (code space): 54
+Memory allocation - compiled block : 190
+Memory allocation - code portion   : 54
 ------------------------------------------------------------------
   0  23 Bra
   3  17 CBra 1
@@ -197,7 +212,8 @@ Memory allocation (code space): 54
 ------------------------------------------------------------------
 
 /a(?P<name1>b|c)d(?P<longername2>e)/
-Memory allocation (code space): 68
+Memory allocation - compiled block : 256
+Memory allocation - code portion   : 68
 ------------------------------------------------------------------
   0  30 Bra
   3     a
@@ -215,7 +231,8 @@ Memory allocation (code space): 68
 ------------------------------------------------------------------
 
 /(?:a(?P<c>c(?P<d>d)))(?P<a>a)/
-Memory allocation (code space): 84
+Memory allocation - compiled block : 238
+Memory allocation - code portion   : 84
 ------------------------------------------------------------------
   0  38 Bra
   3  23 Bra
@@ -235,7 +252,8 @@ Memory allocation (code space): 84
 ------------------------------------------------------------------
 
 /(?P<a>a)...(?P=a)bbb(?P>a)d/
-Memory allocation (code space): 64
+Memory allocation - compiled block : 206
+Memory allocation - code portion   : 64
 ------------------------------------------------------------------
   0  28 Bra
   3   6 CBra 1
@@ -253,7 +271,8 @@ Memory allocation (code space): 64
 ------------------------------------------------------------------
 
 /abc(?C255)de(?C)f/
-Memory allocation (code space): 62
+Memory allocation - compiled block : 198
+Memory allocation - code portion   : 62
 ------------------------------------------------------------------
   0  27 Bra
   3     abc
@@ -266,7 +285,8 @@ Memory allocation (code space): 62
 ------------------------------------------------------------------
 
 /abcde/auto_callout
-Memory allocation (code space): 106
+Memory allocation - compiled block : 242
+Memory allocation - code portion   : 106
 ------------------------------------------------------------------
   0  49 Bra
   3     Callout 255 0 1
@@ -285,7 +305,8 @@ Memory allocation (code space): 106
 ------------------------------------------------------------------
 
 /\x{100}/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{100}
@@ -294,7 +315,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /\x{1000}/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{1000}
@@ -303,7 +325,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /\x{10000}/utf
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{10000}
@@ -312,7 +335,8 @@ Memory allocation (code space): 20
 ------------------------------------------------------------------
 
 /\x{100000}/utf
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{100000}
@@ -321,7 +345,8 @@ Memory allocation (code space): 20
 ------------------------------------------------------------------
 
 /\x{10ffff}/utf
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{10ffff}
@@ -333,7 +358,8 @@ Memory allocation (code space): 20
 Failed: error 134 at offset 9: character code point value in \x{} or \o{} is too large
 
 /[\x{ff}]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{ff}
@@ -342,7 +368,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[\x{100}]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{100}
@@ -351,7 +378,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /\x80/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{80}
@@ -360,7 +388,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /\xff/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{ff}
@@ -369,7 +398,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /\x{0041}\x{2262}\x{0391}\x{002e}/I,utf
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     A\x{2262}\x{391}.
@@ -383,7 +413,8 @@ Last code unit = '.'
 Subject length lower bound = 4
 
 /\x{D55c}\x{ad6d}\x{C5B4}/I,utf
-Memory allocation (code space): 26
+Memory allocation - compiled block : 162
+Memory allocation - code portion   : 26
 ------------------------------------------------------------------
   0   9 Bra
   3     \x{d55c}\x{ad6d}\x{c5b4}
@@ -397,7 +428,8 @@ Last code unit = \x{c5b4}
 Subject length lower bound = 3
 
 /\x{65e5}\x{672c}\x{8a9e}/I,utf
-Memory allocation (code space): 26
+Memory allocation - compiled block : 162
+Memory allocation - code portion   : 26
 ------------------------------------------------------------------
   0   9 Bra
   3     \x{65e5}\x{672c}\x{8a9e}
@@ -411,7 +443,8 @@ Last code unit = \x{8a9e}
 Subject length lower bound = 3
 
 /[\x{100}]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{100}
@@ -420,7 +453,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[Z\x{100}]/utf
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  26 Bra
   3     [Z\x{100}]
@@ -429,7 +463,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /^[\x{100}\E-\Q\E\x{150}]/utf
-Memory allocation (code space): 32
+Memory allocation - compiled block : 168
+Memory allocation - code portion   : 32
 ------------------------------------------------------------------
   0  12 Bra
   3     ^
@@ -439,7 +474,8 @@ Memory allocation (code space): 32
 ------------------------------------------------------------------
 
 /^[\QĀ\E-\QŐ\E]/utf
-Memory allocation (code space): 32
+Memory allocation - compiled block : 168
+Memory allocation - code portion   : 32
 ------------------------------------------------------------------
   0  12 Bra
   3     ^
@@ -452,7 +488,8 @@ Memory allocation (code space): 32
 Failed: error 106 at offset 13: missing terminating ] for character class
 
 /[\p{L}]/
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\p{L}]
@@ -461,7 +498,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /[\p{^L}]/
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\P{L}]
@@ -470,7 +508,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /[\P{L}]/
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\P{L}]
@@ -479,7 +518,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /[\P{^L}]/
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\p{L}]
@@ -488,7 +528,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /[abc\p{L}\x{0660}]/utf
-Memory allocation (code space): 66
+Memory allocation - compiled block : 202
+Memory allocation - code portion   : 66
 ------------------------------------------------------------------
   0  29 Bra
   3     [a-c\p{L}\x{660}]
@@ -497,7 +538,8 @@ Memory allocation (code space): 66
 ------------------------------------------------------------------
 
 /[\p{Nd}]/utf
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\p{Nd}]
@@ -506,7 +548,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /[\p{Nd}+-]+/utf
-Memory allocation (code space): 64
+Memory allocation - compiled block : 200
+Memory allocation - code portion   : 64
 ------------------------------------------------------------------
   0  28 Bra
   3     [+\-\p{Nd}]++
@@ -515,7 +558,8 @@ Memory allocation (code space): 64
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/i,utf
-Memory allocation (code space): 36
+Memory allocation - compiled block : 172
+Memory allocation - code portion   : 36
 ------------------------------------------------------------------
   0  14 Bra
   3  /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -524,7 +568,8 @@ Memory allocation (code space): 36
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/utf
-Memory allocation (code space): 36
+Memory allocation - compiled block : 172
+Memory allocation - code portion   : 36
 ------------------------------------------------------------------
   0  14 Bra
   3     A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -533,7 +578,8 @@ Memory allocation (code space): 36
 ------------------------------------------------------------------
 
 /[\x{105}-\x{109}]/i,utf
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  11 Bra
   3     [\x{104}-\x{109}]
@@ -542,7 +588,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /( ( (?(1)0|) )*   )/x
-Memory allocation (code space): 70
+Memory allocation - compiled block : 206
+Memory allocation - code portion   : 70
 ------------------------------------------------------------------
   0  31 Bra
   3  25 CBra 1
@@ -560,7 +607,8 @@ Memory allocation (code space): 70
 ------------------------------------------------------------------
 
 /(  (?(1)0|)*   )/x
-Memory allocation (code space): 56
+Memory allocation - compiled block : 192
+Memory allocation - code portion   : 56
 ------------------------------------------------------------------
   0  24 Bra
   3  18 CBra 1
@@ -576,7 +624,8 @@ Memory allocation (code space): 56
 ------------------------------------------------------------------
 
 /[a]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     a
@@ -585,7 +634,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[a]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     a
@@ -594,7 +644,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[\xaa]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{aa}
@@ -603,7 +654,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[\xaa]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{aa}
@@ -612,7 +664,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[^a]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     [^a]
@@ -621,7 +674,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[^a]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     [^a]
@@ -630,7 +684,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[^\xaa]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     [^\x{aa}]
@@ -639,7 +694,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[^\xaa]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0   5 Bra
   3     [^\x{aa}]
index 91d96c946748bdf0e3eb2b08bd9c8709634b0588..d76f3aaab9e117371f9899ca4b4d4aaec136d968 100644 (file)
@@ -10,7 +10,8 @@
 #pattern fullbincode,memory
 
 /((?i)b)/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2   5 CBra 1
@@ -21,7 +22,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /(?s)(.*X|^B)/
-Memory allocation (code space): 76
+Memory allocation - compiled block : 212
+Memory allocation - code portion   : 76
 ------------------------------------------------------------------
   0  16 Bra
   2   7 CBra 1
@@ -36,7 +38,8 @@ Memory allocation (code space): 76
 ------------------------------------------------------------------
 
 /(?s:.*X|^B)/
-Memory allocation (code space): 72
+Memory allocation - compiled block : 208
+Memory allocation - code portion   : 72
 ------------------------------------------------------------------
   0  15 Bra
   2   6 Bra
@@ -51,7 +54,8 @@ Memory allocation (code space): 72
 ------------------------------------------------------------------
 
 /^[[:alnum:]]/
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  12 Bra
   2     ^
@@ -61,7 +65,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /#/Ix
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0   2 Bra
   2   2 Ket
@@ -73,7 +78,8 @@ Options: extended
 Subject length lower bound = 0
 
 /a#/Ix
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -86,7 +92,8 @@ First code unit = 'a'
 Subject length lower bound = 1
 
 /x?+/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     x?+
@@ -95,7 +102,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /x++/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     x++
@@ -104,7 +112,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /x{1,3}+/
-Memory allocation (code space): 40
+Memory allocation - compiled block : 176
+Memory allocation - code portion   : 40
 ------------------------------------------------------------------
   0   7 Bra
   2     x
@@ -114,7 +123,8 @@ Memory allocation (code space): 40
 ------------------------------------------------------------------
 
 /(x)*+/
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     Braposzero
@@ -126,7 +136,8 @@ Memory allocation (code space): 52
 ------------------------------------------------------------------
 
 /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
-Memory allocation (code space): 220
+Memory allocation - compiled block : 356
+Memory allocation - code portion   : 220
 ------------------------------------------------------------------
   0  52 Bra
   2     ^
@@ -149,7 +160,8 @@ Memory allocation (code space): 220
 ------------------------------------------------------------------
 
 "8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 3296
+Memory allocation - compiled block : 3432
+Memory allocation - code portion   : 3296
 ------------------------------------------------------------------
   0 821 Bra
   2     8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -159,7 +171,8 @@ Memory allocation (code space): 3296
 ------------------------------------------------------------------
 
 "\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 3256
+Memory allocation - compiled block : 3392
+Memory allocation - code portion   : 3256
 ------------------------------------------------------------------
   0 811 Bra
   2     $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -169,7 +182,8 @@ Memory allocation (code space): 3256
 ------------------------------------------------------------------
 
 /(a(?1)b)/
-Memory allocation (code space): 64
+Memory allocation - compiled block : 200
+Memory allocation - code portion   : 64
 ------------------------------------------------------------------
   0  13 Bra
   2   9 CBra 1
@@ -182,7 +196,8 @@ Memory allocation (code space): 64
 ------------------------------------------------------------------
 
 /(a(?1)+b)/
-Memory allocation (code space): 80
+Memory allocation - compiled block : 216
+Memory allocation - code portion   : 80
 ------------------------------------------------------------------
   0  17 Bra
   2  13 CBra 1
@@ -197,7 +212,8 @@ Memory allocation (code space): 80
 ------------------------------------------------------------------
 
 /a(?P<name1>b|c)d(?P<longername2>e)/
-Memory allocation (code space): 108
+Memory allocation - compiled block : 348
+Memory allocation - code portion   : 108
 ------------------------------------------------------------------
   0  24 Bra
   2     a
@@ -215,7 +231,8 @@ Memory allocation (code space): 108
 ------------------------------------------------------------------
 
 /(?:a(?P<c>c(?P<d>d)))(?P<a>a)/
-Memory allocation (code space): 128
+Memory allocation - compiled block : 300
+Memory allocation - code portion   : 128
 ------------------------------------------------------------------
   0  29 Bra
   2  18 Bra
@@ -235,7 +252,8 @@ Memory allocation (code space): 128
 ------------------------------------------------------------------
 
 /(?P<a>a)...(?P=a)bbb(?P>a)d/
-Memory allocation (code space): 108
+Memory allocation - compiled block : 256
+Memory allocation - code portion   : 108
 ------------------------------------------------------------------
   0  24 Bra
   2   5 CBra 1
@@ -253,7 +271,8 @@ Memory allocation (code space): 108
 ------------------------------------------------------------------
 
 /abc(?C255)de(?C)f/
-Memory allocation (code space): 100
+Memory allocation - compiled block : 236
+Memory allocation - code portion   : 100
 ------------------------------------------------------------------
   0  22 Bra
   2     abc
@@ -266,7 +285,8 @@ Memory allocation (code space): 100
 ------------------------------------------------------------------
 
 /abcde/auto_callout
-Memory allocation (code space): 156
+Memory allocation - compiled block : 292
+Memory allocation - code portion   : 156
 ------------------------------------------------------------------
   0  36 Bra
   2     Callout 255 0 1
@@ -285,7 +305,8 @@ Memory allocation (code space): 156
 ------------------------------------------------------------------
 
 /\x{100}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -294,7 +315,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{1000}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{1000}
@@ -303,7 +325,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{10000}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{10000}
@@ -312,7 +335,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{100000}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100000}
@@ -321,7 +345,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{10ffff}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{10ffff}
@@ -333,7 +358,8 @@ Memory allocation (code space): 28
 Failed: error 134 at offset 9: character code point value in \x{} or \o{} is too large
 
 /[\x{ff}]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{ff}
@@ -342,7 +368,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[\x{100}]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -351,7 +378,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x80/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{80}
@@ -360,7 +388,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\xff/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{ff}
@@ -369,7 +398,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{0041}\x{2262}\x{0391}\x{002e}/I,utf
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     A\x{2262}\x{391}.
@@ -383,7 +413,8 @@ Last code unit = '.'
 Subject length lower bound = 4
 
 /\x{D55c}\x{ad6d}\x{C5B4}/I,utf
-Memory allocation (code space): 44
+Memory allocation - compiled block : 180
+Memory allocation - code portion   : 44
 ------------------------------------------------------------------
   0   8 Bra
   2     \x{d55c}\x{ad6d}\x{c5b4}
@@ -397,7 +428,8 @@ Last code unit = \x{c5b4}
 Subject length lower bound = 3
 
 /\x{65e5}\x{672c}\x{8a9e}/I,utf
-Memory allocation (code space): 44
+Memory allocation - compiled block : 180
+Memory allocation - code portion   : 44
 ------------------------------------------------------------------
   0   8 Bra
   2     \x{65e5}\x{672c}\x{8a9e}
@@ -411,7 +443,8 @@ Last code unit = \x{8a9e}
 Subject length lower bound = 3
 
 /[\x{100}]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -420,7 +453,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[Z\x{100}]/utf
-Memory allocation (code space): 76
+Memory allocation - compiled block : 212
+Memory allocation - code portion   : 76
 ------------------------------------------------------------------
   0  16 Bra
   2     [Z\x{100}]
@@ -429,7 +463,8 @@ Memory allocation (code space): 76
 ------------------------------------------------------------------
 
 /^[\x{100}\E-\Q\E\x{150}]/utf
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     ^
@@ -439,7 +474,8 @@ Memory allocation (code space): 52
 ------------------------------------------------------------------
 
 /^[\QĀ\E-\QŐ\E]/utf
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     ^
@@ -452,7 +488,8 @@ Memory allocation (code space): 52
 Failed: error 106 at offset 13: missing terminating ] for character class
 
 /[\p{L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{L}]
@@ -461,7 +498,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\p{^L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\P{L}]
@@ -470,7 +508,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\P{L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\P{L}]
@@ -479,7 +518,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\P{^L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{L}]
@@ -488,7 +528,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[abc\p{L}\x{0660}]/utf
-Memory allocation (code space): 88
+Memory allocation - compiled block : 224
+Memory allocation - code portion   : 88
 ------------------------------------------------------------------
   0  19 Bra
   2     [a-c\p{L}\x{660}]
@@ -497,7 +538,8 @@ Memory allocation (code space): 88
 ------------------------------------------------------------------
 
 /[\p{Nd}]/utf
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{Nd}]
@@ -506,7 +548,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\p{Nd}+-]+/utf
-Memory allocation (code space): 84
+Memory allocation - compiled block : 220
+Memory allocation - code portion   : 84
 ------------------------------------------------------------------
   0  18 Bra
   2     [+\-\p{Nd}]++
@@ -515,7 +558,8 @@ Memory allocation (code space): 84
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/i,utf
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  12 Bra
   2  /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -524,7 +568,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/utf
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  12 Bra
   2     A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -533,7 +578,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /[\x{105}-\x{109}]/i,utf
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\x{104}-\x{109}]
@@ -542,7 +588,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /( ( (?(1)0|) )*   )/x
-Memory allocation (code space): 104
+Memory allocation - compiled block : 240
+Memory allocation - code portion   : 104
 ------------------------------------------------------------------
   0  23 Bra
   2  19 CBra 1
@@ -560,7 +607,8 @@ Memory allocation (code space): 104
 ------------------------------------------------------------------
 
 /(  (?(1)0|)*   )/x
-Memory allocation (code space): 84
+Memory allocation - compiled block : 220
+Memory allocation - code portion   : 84
 ------------------------------------------------------------------
   0  18 Bra
   2  14 CBra 1
@@ -576,7 +624,8 @@ Memory allocation (code space): 84
 ------------------------------------------------------------------
 
 /[a]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -585,7 +634,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[a]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -594,7 +644,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[\xaa]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{aa}
@@ -603,7 +654,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[\xaa]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{aa}
@@ -612,7 +664,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^a]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^a]
@@ -621,7 +674,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^a]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^a]
@@ -630,7 +684,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^\xaa]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^\x{aa}]
@@ -639,7 +694,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^\xaa]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^\x{aa}]
index 91d96c946748bdf0e3eb2b08bd9c8709634b0588..d76f3aaab9e117371f9899ca4b4d4aaec136d968 100644 (file)
@@ -10,7 +10,8 @@
 #pattern fullbincode,memory
 
 /((?i)b)/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2   5 CBra 1
@@ -21,7 +22,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /(?s)(.*X|^B)/
-Memory allocation (code space): 76
+Memory allocation - compiled block : 212
+Memory allocation - code portion   : 76
 ------------------------------------------------------------------
   0  16 Bra
   2   7 CBra 1
@@ -36,7 +38,8 @@ Memory allocation (code space): 76
 ------------------------------------------------------------------
 
 /(?s:.*X|^B)/
-Memory allocation (code space): 72
+Memory allocation - compiled block : 208
+Memory allocation - code portion   : 72
 ------------------------------------------------------------------
   0  15 Bra
   2   6 Bra
@@ -51,7 +54,8 @@ Memory allocation (code space): 72
 ------------------------------------------------------------------
 
 /^[[:alnum:]]/
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  12 Bra
   2     ^
@@ -61,7 +65,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /#/Ix
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0   2 Bra
   2   2 Ket
@@ -73,7 +78,8 @@ Options: extended
 Subject length lower bound = 0
 
 /a#/Ix
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -86,7 +92,8 @@ First code unit = 'a'
 Subject length lower bound = 1
 
 /x?+/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     x?+
@@ -95,7 +102,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /x++/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     x++
@@ -104,7 +112,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /x{1,3}+/
-Memory allocation (code space): 40
+Memory allocation - compiled block : 176
+Memory allocation - code portion   : 40
 ------------------------------------------------------------------
   0   7 Bra
   2     x
@@ -114,7 +123,8 @@ Memory allocation (code space): 40
 ------------------------------------------------------------------
 
 /(x)*+/
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     Braposzero
@@ -126,7 +136,8 @@ Memory allocation (code space): 52
 ------------------------------------------------------------------
 
 /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
-Memory allocation (code space): 220
+Memory allocation - compiled block : 356
+Memory allocation - code portion   : 220
 ------------------------------------------------------------------
   0  52 Bra
   2     ^
@@ -149,7 +160,8 @@ Memory allocation (code space): 220
 ------------------------------------------------------------------
 
 "8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 3296
+Memory allocation - compiled block : 3432
+Memory allocation - code portion   : 3296
 ------------------------------------------------------------------
   0 821 Bra
   2     8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -159,7 +171,8 @@ Memory allocation (code space): 3296
 ------------------------------------------------------------------
 
 "\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 3256
+Memory allocation - compiled block : 3392
+Memory allocation - code portion   : 3256
 ------------------------------------------------------------------
   0 811 Bra
   2     $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -169,7 +182,8 @@ Memory allocation (code space): 3256
 ------------------------------------------------------------------
 
 /(a(?1)b)/
-Memory allocation (code space): 64
+Memory allocation - compiled block : 200
+Memory allocation - code portion   : 64
 ------------------------------------------------------------------
   0  13 Bra
   2   9 CBra 1
@@ -182,7 +196,8 @@ Memory allocation (code space): 64
 ------------------------------------------------------------------
 
 /(a(?1)+b)/
-Memory allocation (code space): 80
+Memory allocation - compiled block : 216
+Memory allocation - code portion   : 80
 ------------------------------------------------------------------
   0  17 Bra
   2  13 CBra 1
@@ -197,7 +212,8 @@ Memory allocation (code space): 80
 ------------------------------------------------------------------
 
 /a(?P<name1>b|c)d(?P<longername2>e)/
-Memory allocation (code space): 108
+Memory allocation - compiled block : 348
+Memory allocation - code portion   : 108
 ------------------------------------------------------------------
   0  24 Bra
   2     a
@@ -215,7 +231,8 @@ Memory allocation (code space): 108
 ------------------------------------------------------------------
 
 /(?:a(?P<c>c(?P<d>d)))(?P<a>a)/
-Memory allocation (code space): 128
+Memory allocation - compiled block : 300
+Memory allocation - code portion   : 128
 ------------------------------------------------------------------
   0  29 Bra
   2  18 Bra
@@ -235,7 +252,8 @@ Memory allocation (code space): 128
 ------------------------------------------------------------------
 
 /(?P<a>a)...(?P=a)bbb(?P>a)d/
-Memory allocation (code space): 108
+Memory allocation - compiled block : 256
+Memory allocation - code portion   : 108
 ------------------------------------------------------------------
   0  24 Bra
   2   5 CBra 1
@@ -253,7 +271,8 @@ Memory allocation (code space): 108
 ------------------------------------------------------------------
 
 /abc(?C255)de(?C)f/
-Memory allocation (code space): 100
+Memory allocation - compiled block : 236
+Memory allocation - code portion   : 100
 ------------------------------------------------------------------
   0  22 Bra
   2     abc
@@ -266,7 +285,8 @@ Memory allocation (code space): 100
 ------------------------------------------------------------------
 
 /abcde/auto_callout
-Memory allocation (code space): 156
+Memory allocation - compiled block : 292
+Memory allocation - code portion   : 156
 ------------------------------------------------------------------
   0  36 Bra
   2     Callout 255 0 1
@@ -285,7 +305,8 @@ Memory allocation (code space): 156
 ------------------------------------------------------------------
 
 /\x{100}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -294,7 +315,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{1000}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{1000}
@@ -303,7 +325,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{10000}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{10000}
@@ -312,7 +335,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{100000}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100000}
@@ -321,7 +345,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{10ffff}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{10ffff}
@@ -333,7 +358,8 @@ Memory allocation (code space): 28
 Failed: error 134 at offset 9: character code point value in \x{} or \o{} is too large
 
 /[\x{ff}]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{ff}
@@ -342,7 +368,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[\x{100}]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -351,7 +378,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x80/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{80}
@@ -360,7 +388,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\xff/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{ff}
@@ -369,7 +398,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{0041}\x{2262}\x{0391}\x{002e}/I,utf
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     A\x{2262}\x{391}.
@@ -383,7 +413,8 @@ Last code unit = '.'
 Subject length lower bound = 4
 
 /\x{D55c}\x{ad6d}\x{C5B4}/I,utf
-Memory allocation (code space): 44
+Memory allocation - compiled block : 180
+Memory allocation - code portion   : 44
 ------------------------------------------------------------------
   0   8 Bra
   2     \x{d55c}\x{ad6d}\x{c5b4}
@@ -397,7 +428,8 @@ Last code unit = \x{c5b4}
 Subject length lower bound = 3
 
 /\x{65e5}\x{672c}\x{8a9e}/I,utf
-Memory allocation (code space): 44
+Memory allocation - compiled block : 180
+Memory allocation - code portion   : 44
 ------------------------------------------------------------------
   0   8 Bra
   2     \x{65e5}\x{672c}\x{8a9e}
@@ -411,7 +443,8 @@ Last code unit = \x{8a9e}
 Subject length lower bound = 3
 
 /[\x{100}]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -420,7 +453,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[Z\x{100}]/utf
-Memory allocation (code space): 76
+Memory allocation - compiled block : 212
+Memory allocation - code portion   : 76
 ------------------------------------------------------------------
   0  16 Bra
   2     [Z\x{100}]
@@ -429,7 +463,8 @@ Memory allocation (code space): 76
 ------------------------------------------------------------------
 
 /^[\x{100}\E-\Q\E\x{150}]/utf
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     ^
@@ -439,7 +474,8 @@ Memory allocation (code space): 52
 ------------------------------------------------------------------
 
 /^[\QĀ\E-\QŐ\E]/utf
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     ^
@@ -452,7 +488,8 @@ Memory allocation (code space): 52
 Failed: error 106 at offset 13: missing terminating ] for character class
 
 /[\p{L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{L}]
@@ -461,7 +498,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\p{^L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\P{L}]
@@ -470,7 +508,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\P{L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\P{L}]
@@ -479,7 +518,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\P{^L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{L}]
@@ -488,7 +528,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[abc\p{L}\x{0660}]/utf
-Memory allocation (code space): 88
+Memory allocation - compiled block : 224
+Memory allocation - code portion   : 88
 ------------------------------------------------------------------
   0  19 Bra
   2     [a-c\p{L}\x{660}]
@@ -497,7 +538,8 @@ Memory allocation (code space): 88
 ------------------------------------------------------------------
 
 /[\p{Nd}]/utf
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{Nd}]
@@ -506,7 +548,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\p{Nd}+-]+/utf
-Memory allocation (code space): 84
+Memory allocation - compiled block : 220
+Memory allocation - code portion   : 84
 ------------------------------------------------------------------
   0  18 Bra
   2     [+\-\p{Nd}]++
@@ -515,7 +558,8 @@ Memory allocation (code space): 84
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/i,utf
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  12 Bra
   2  /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -524,7 +568,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/utf
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  12 Bra
   2     A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -533,7 +578,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /[\x{105}-\x{109}]/i,utf
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\x{104}-\x{109}]
@@ -542,7 +588,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /( ( (?(1)0|) )*   )/x
-Memory allocation (code space): 104
+Memory allocation - compiled block : 240
+Memory allocation - code portion   : 104
 ------------------------------------------------------------------
   0  23 Bra
   2  19 CBra 1
@@ -560,7 +607,8 @@ Memory allocation (code space): 104
 ------------------------------------------------------------------
 
 /(  (?(1)0|)*   )/x
-Memory allocation (code space): 84
+Memory allocation - compiled block : 220
+Memory allocation - code portion   : 84
 ------------------------------------------------------------------
   0  18 Bra
   2  14 CBra 1
@@ -576,7 +624,8 @@ Memory allocation (code space): 84
 ------------------------------------------------------------------
 
 /[a]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -585,7 +634,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[a]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -594,7 +644,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[\xaa]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{aa}
@@ -603,7 +654,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[\xaa]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{aa}
@@ -612,7 +664,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^a]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^a]
@@ -621,7 +674,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^a]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^a]
@@ -630,7 +684,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^\xaa]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^\x{aa}]
@@ -639,7 +694,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^\xaa]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^\x{aa}]
index 91d96c946748bdf0e3eb2b08bd9c8709634b0588..d76f3aaab9e117371f9899ca4b4d4aaec136d968 100644 (file)
@@ -10,7 +10,8 @@
 #pattern fullbincode,memory
 
 /((?i)b)/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2   5 CBra 1
@@ -21,7 +22,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /(?s)(.*X|^B)/
-Memory allocation (code space): 76
+Memory allocation - compiled block : 212
+Memory allocation - code portion   : 76
 ------------------------------------------------------------------
   0  16 Bra
   2   7 CBra 1
@@ -36,7 +38,8 @@ Memory allocation (code space): 76
 ------------------------------------------------------------------
 
 /(?s:.*X|^B)/
-Memory allocation (code space): 72
+Memory allocation - compiled block : 208
+Memory allocation - code portion   : 72
 ------------------------------------------------------------------
   0  15 Bra
   2   6 Bra
@@ -51,7 +54,8 @@ Memory allocation (code space): 72
 ------------------------------------------------------------------
 
 /^[[:alnum:]]/
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  12 Bra
   2     ^
@@ -61,7 +65,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /#/Ix
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0   2 Bra
   2   2 Ket
@@ -73,7 +78,8 @@ Options: extended
 Subject length lower bound = 0
 
 /a#/Ix
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -86,7 +92,8 @@ First code unit = 'a'
 Subject length lower bound = 1
 
 /x?+/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     x?+
@@ -95,7 +102,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /x++/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     x++
@@ -104,7 +112,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /x{1,3}+/
-Memory allocation (code space): 40
+Memory allocation - compiled block : 176
+Memory allocation - code portion   : 40
 ------------------------------------------------------------------
   0   7 Bra
   2     x
@@ -114,7 +123,8 @@ Memory allocation (code space): 40
 ------------------------------------------------------------------
 
 /(x)*+/
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     Braposzero
@@ -126,7 +136,8 @@ Memory allocation (code space): 52
 ------------------------------------------------------------------
 
 /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
-Memory allocation (code space): 220
+Memory allocation - compiled block : 356
+Memory allocation - code portion   : 220
 ------------------------------------------------------------------
   0  52 Bra
   2     ^
@@ -149,7 +160,8 @@ Memory allocation (code space): 220
 ------------------------------------------------------------------
 
 "8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 3296
+Memory allocation - compiled block : 3432
+Memory allocation - code portion   : 3296
 ------------------------------------------------------------------
   0 821 Bra
   2     8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -159,7 +171,8 @@ Memory allocation (code space): 3296
 ------------------------------------------------------------------
 
 "\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 3256
+Memory allocation - compiled block : 3392
+Memory allocation - code portion   : 3256
 ------------------------------------------------------------------
   0 811 Bra
   2     $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -169,7 +182,8 @@ Memory allocation (code space): 3256
 ------------------------------------------------------------------
 
 /(a(?1)b)/
-Memory allocation (code space): 64
+Memory allocation - compiled block : 200
+Memory allocation - code portion   : 64
 ------------------------------------------------------------------
   0  13 Bra
   2   9 CBra 1
@@ -182,7 +196,8 @@ Memory allocation (code space): 64
 ------------------------------------------------------------------
 
 /(a(?1)+b)/
-Memory allocation (code space): 80
+Memory allocation - compiled block : 216
+Memory allocation - code portion   : 80
 ------------------------------------------------------------------
   0  17 Bra
   2  13 CBra 1
@@ -197,7 +212,8 @@ Memory allocation (code space): 80
 ------------------------------------------------------------------
 
 /a(?P<name1>b|c)d(?P<longername2>e)/
-Memory allocation (code space): 108
+Memory allocation - compiled block : 348
+Memory allocation - code portion   : 108
 ------------------------------------------------------------------
   0  24 Bra
   2     a
@@ -215,7 +231,8 @@ Memory allocation (code space): 108
 ------------------------------------------------------------------
 
 /(?:a(?P<c>c(?P<d>d)))(?P<a>a)/
-Memory allocation (code space): 128
+Memory allocation - compiled block : 300
+Memory allocation - code portion   : 128
 ------------------------------------------------------------------
   0  29 Bra
   2  18 Bra
@@ -235,7 +252,8 @@ Memory allocation (code space): 128
 ------------------------------------------------------------------
 
 /(?P<a>a)...(?P=a)bbb(?P>a)d/
-Memory allocation (code space): 108
+Memory allocation - compiled block : 256
+Memory allocation - code portion   : 108
 ------------------------------------------------------------------
   0  24 Bra
   2   5 CBra 1
@@ -253,7 +271,8 @@ Memory allocation (code space): 108
 ------------------------------------------------------------------
 
 /abc(?C255)de(?C)f/
-Memory allocation (code space): 100
+Memory allocation - compiled block : 236
+Memory allocation - code portion   : 100
 ------------------------------------------------------------------
   0  22 Bra
   2     abc
@@ -266,7 +285,8 @@ Memory allocation (code space): 100
 ------------------------------------------------------------------
 
 /abcde/auto_callout
-Memory allocation (code space): 156
+Memory allocation - compiled block : 292
+Memory allocation - code portion   : 156
 ------------------------------------------------------------------
   0  36 Bra
   2     Callout 255 0 1
@@ -285,7 +305,8 @@ Memory allocation (code space): 156
 ------------------------------------------------------------------
 
 /\x{100}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -294,7 +315,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{1000}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{1000}
@@ -303,7 +325,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{10000}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{10000}
@@ -312,7 +335,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{100000}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100000}
@@ -321,7 +345,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{10ffff}/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{10ffff}
@@ -333,7 +358,8 @@ Memory allocation (code space): 28
 Failed: error 134 at offset 9: character code point value in \x{} or \o{} is too large
 
 /[\x{ff}]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{ff}
@@ -342,7 +368,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[\x{100}]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -351,7 +378,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x80/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{80}
@@ -360,7 +388,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\xff/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{ff}
@@ -369,7 +398,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /\x{0041}\x{2262}\x{0391}\x{002e}/I,utf
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     A\x{2262}\x{391}.
@@ -383,7 +413,8 @@ Last code unit = '.'
 Subject length lower bound = 4
 
 /\x{D55c}\x{ad6d}\x{C5B4}/I,utf
-Memory allocation (code space): 44
+Memory allocation - compiled block : 180
+Memory allocation - code portion   : 44
 ------------------------------------------------------------------
   0   8 Bra
   2     \x{d55c}\x{ad6d}\x{c5b4}
@@ -397,7 +428,8 @@ Last code unit = \x{c5b4}
 Subject length lower bound = 3
 
 /\x{65e5}\x{672c}\x{8a9e}/I,utf
-Memory allocation (code space): 44
+Memory allocation - compiled block : 180
+Memory allocation - code portion   : 44
 ------------------------------------------------------------------
   0   8 Bra
   2     \x{65e5}\x{672c}\x{8a9e}
@@ -411,7 +443,8 @@ Last code unit = \x{8a9e}
 Subject length lower bound = 3
 
 /[\x{100}]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{100}
@@ -420,7 +453,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[Z\x{100}]/utf
-Memory allocation (code space): 76
+Memory allocation - compiled block : 212
+Memory allocation - code portion   : 76
 ------------------------------------------------------------------
   0  16 Bra
   2     [Z\x{100}]
@@ -429,7 +463,8 @@ Memory allocation (code space): 76
 ------------------------------------------------------------------
 
 /^[\x{100}\E-\Q\E\x{150}]/utf
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     ^
@@ -439,7 +474,8 @@ Memory allocation (code space): 52
 ------------------------------------------------------------------
 
 /^[\QĀ\E-\QŐ\E]/utf
-Memory allocation (code space): 52
+Memory allocation - compiled block : 188
+Memory allocation - code portion   : 52
 ------------------------------------------------------------------
   0  10 Bra
   2     ^
@@ -452,7 +488,8 @@ Memory allocation (code space): 52
 Failed: error 106 at offset 13: missing terminating ] for character class
 
 /[\p{L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{L}]
@@ -461,7 +498,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\p{^L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\P{L}]
@@ -470,7 +508,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\P{L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\P{L}]
@@ -479,7 +518,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\P{^L}]/
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{L}]
@@ -488,7 +528,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[abc\p{L}\x{0660}]/utf
-Memory allocation (code space): 88
+Memory allocation - compiled block : 224
+Memory allocation - code portion   : 88
 ------------------------------------------------------------------
   0  19 Bra
   2     [a-c\p{L}\x{660}]
@@ -497,7 +538,8 @@ Memory allocation (code space): 88
 ------------------------------------------------------------------
 
 /[\p{Nd}]/utf
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\p{Nd}]
@@ -506,7 +548,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /[\p{Nd}+-]+/utf
-Memory allocation (code space): 84
+Memory allocation - compiled block : 220
+Memory allocation - code portion   : 84
 ------------------------------------------------------------------
   0  18 Bra
   2     [+\-\p{Nd}]++
@@ -515,7 +558,8 @@ Memory allocation (code space): 84
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/i,utf
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  12 Bra
   2  /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -524,7 +568,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/utf
-Memory allocation (code space): 60
+Memory allocation - compiled block : 196
+Memory allocation - code portion   : 60
 ------------------------------------------------------------------
   0  12 Bra
   2     A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -533,7 +578,8 @@ Memory allocation (code space): 60
 ------------------------------------------------------------------
 
 /[\x{105}-\x{109}]/i,utf
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0   9 Bra
   2     [\x{104}-\x{109}]
@@ -542,7 +588,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /( ( (?(1)0|) )*   )/x
-Memory allocation (code space): 104
+Memory allocation - compiled block : 240
+Memory allocation - code portion   : 104
 ------------------------------------------------------------------
   0  23 Bra
   2  19 CBra 1
@@ -560,7 +607,8 @@ Memory allocation (code space): 104
 ------------------------------------------------------------------
 
 /(  (?(1)0|)*   )/x
-Memory allocation (code space): 84
+Memory allocation - compiled block : 220
+Memory allocation - code portion   : 84
 ------------------------------------------------------------------
   0  18 Bra
   2  14 CBra 1
@@ -576,7 +624,8 @@ Memory allocation (code space): 84
 ------------------------------------------------------------------
 
 /[a]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -585,7 +634,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[a]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     a
@@ -594,7 +644,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[\xaa]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{aa}
@@ -603,7 +654,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[\xaa]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     \x{aa}
@@ -612,7 +664,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^a]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^a]
@@ -621,7 +674,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^a]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^a]
@@ -630,7 +684,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^\xaa]/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^\x{aa}]
@@ -639,7 +694,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /[^\xaa]/utf
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0   4 Bra
   2     [^\x{aa}]
index e9568e539eb9a0597a04b150c0c8c551f837ed81..f3811d952074435d8745c8c31e321b998035005c 100644 (file)
@@ -10,7 +10,8 @@
 #pattern fullbincode,memory
 
 /((?i)b)/
-Memory allocation (code space): 17
+Memory allocation - compiled block : 153
+Memory allocation - code portion   : 17
 ------------------------------------------------------------------
   0  13 Bra
   3   7 CBra 1
@@ -21,7 +22,8 @@ Memory allocation (code space): 17
 ------------------------------------------------------------------
 
 /(?s)(.*X|^B)/
-Memory allocation (code space): 25
+Memory allocation - compiled block : 161
+Memory allocation - code portion   : 25
 ------------------------------------------------------------------
   0  21 Bra
   3   9 CBra 1
@@ -36,7 +38,8 @@ Memory allocation (code space): 25
 ------------------------------------------------------------------
 
 /(?s:.*X|^B)/
-Memory allocation (code space): 23
+Memory allocation - compiled block : 159
+Memory allocation - code portion   : 23
 ------------------------------------------------------------------
   0  19 Bra
   3   7 Bra
@@ -51,7 +54,8 @@ Memory allocation (code space): 23
 ------------------------------------------------------------------
 
 /^[[:alnum:]]/
-Memory allocation (code space): 41
+Memory allocation - compiled block : 177
+Memory allocation - code portion   : 41
 ------------------------------------------------------------------
   0  37 Bra
   3     ^
@@ -61,7 +65,8 @@ Memory allocation (code space): 41
 ------------------------------------------------------------------
 
 /#/Ix
-Memory allocation (code space): 7
+Memory allocation - compiled block : 143
+Memory allocation - code portion   : 7
 ------------------------------------------------------------------
   0   3 Bra
   3   3 Ket
@@ -73,7 +78,8 @@ Options: extended
 Subject length lower bound = 0
 
 /a#/Ix
-Memory allocation (code space): 9
+Memory allocation - compiled block : 145
+Memory allocation - code portion   : 9
 ------------------------------------------------------------------
   0   5 Bra
   3     a
@@ -86,7 +92,8 @@ First code unit = 'a'
 Subject length lower bound = 1
 
 /x?+/
-Memory allocation (code space): 9
+Memory allocation - compiled block : 145
+Memory allocation - code portion   : 9
 ------------------------------------------------------------------
   0   5 Bra
   3     x?+
@@ -95,7 +102,8 @@ Memory allocation (code space): 9
 ------------------------------------------------------------------
 
 /x++/
-Memory allocation (code space): 9
+Memory allocation - compiled block : 145
+Memory allocation - code portion   : 9
 ------------------------------------------------------------------
   0   5 Bra
   3     x++
@@ -104,7 +112,8 @@ Memory allocation (code space): 9
 ------------------------------------------------------------------
 
 /x{1,3}+/
-Memory allocation (code space): 13
+Memory allocation - compiled block : 149
+Memory allocation - code portion   : 13
 ------------------------------------------------------------------
   0   9 Bra
   3     x
@@ -114,7 +123,8 @@ Memory allocation (code space): 13
 ------------------------------------------------------------------
 
 /(x)*+/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0  14 Bra
   3     Braposzero
@@ -126,7 +136,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
-Memory allocation (code space): 120
+Memory allocation - compiled block : 256
+Memory allocation - code portion   : 120
 ------------------------------------------------------------------
   0 116 Bra
   3     ^
@@ -149,7 +160,8 @@ Memory allocation (code space): 120
 ------------------------------------------------------------------
 
 "8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 826
+Memory allocation - compiled block : 962
+Memory allocation - code portion   : 826
 ------------------------------------------------------------------
   0 822 Bra
   3     8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -159,7 +171,8 @@ Memory allocation (code space): 826
 ------------------------------------------------------------------
 
 "\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 816
+Memory allocation - compiled block : 952
+Memory allocation - code portion   : 816
 ------------------------------------------------------------------
   0 812 Bra
   3     $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -169,7 +182,8 @@ Memory allocation (code space): 816
 ------------------------------------------------------------------
 
 /(a(?1)b)/
-Memory allocation (code space): 22
+Memory allocation - compiled block : 158
+Memory allocation - code portion   : 22
 ------------------------------------------------------------------
   0  18 Bra
   3  12 CBra 1
@@ -182,7 +196,8 @@ Memory allocation (code space): 22
 ------------------------------------------------------------------
 
 /(a(?1)+b)/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0  24 Bra
   3  18 CBra 1
@@ -197,7 +212,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /a(?P<name1>b|c)d(?P<longername2>e)/
-Memory allocation (code space): 36
+Memory allocation - compiled block : 200
+Memory allocation - code portion   : 36
 ------------------------------------------------------------------
   0  32 Bra
   3     a
@@ -215,7 +231,8 @@ Memory allocation (code space): 36
 ------------------------------------------------------------------
 
 /(?:a(?P<c>c(?P<d>d)))(?P<a>a)/
-Memory allocation (code space): 45
+Memory allocation - compiled block : 193
+Memory allocation - code portion   : 45
 ------------------------------------------------------------------
   0  41 Bra
   3  25 Bra
@@ -235,7 +252,8 @@ Memory allocation (code space): 45
 ------------------------------------------------------------------
 
 /(?P<a>a)...(?P=a)bbb(?P>a)d/
-Memory allocation (code space): 34
+Memory allocation - compiled block : 174
+Memory allocation - code portion   : 34
 ------------------------------------------------------------------
   0  30 Bra
   3   7 CBra 1
@@ -253,7 +271,8 @@ Memory allocation (code space): 34
 ------------------------------------------------------------------
 
 /abc(?C255)de(?C)f/
-Memory allocation (code space): 31
+Memory allocation - compiled block : 167
+Memory allocation - code portion   : 31
 ------------------------------------------------------------------
   0  27 Bra
   3     abc
@@ -266,7 +285,8 @@ Memory allocation (code space): 31
 ------------------------------------------------------------------
 
 /abcde/auto_callout
-Memory allocation (code space): 53
+Memory allocation - compiled block : 189
+Memory allocation - code portion   : 53
 ------------------------------------------------------------------
   0  49 Bra
   3     Callout 255 0 1
@@ -285,7 +305,8 @@ Memory allocation (code space): 53
 ------------------------------------------------------------------
 
 /\x{100}/utf
-Memory allocation (code space): 10
+Memory allocation - compiled block : 146
+Memory allocation - code portion   : 10
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{100}
@@ -294,7 +315,8 @@ Memory allocation (code space): 10
 ------------------------------------------------------------------
 
 /\x{1000}/utf
-Memory allocation (code space): 11
+Memory allocation - compiled block : 147
+Memory allocation - code portion   : 11
 ------------------------------------------------------------------
   0   7 Bra
   3     \x{1000}
@@ -303,7 +325,8 @@ Memory allocation (code space): 11
 ------------------------------------------------------------------
 
 /\x{10000}/utf
-Memory allocation (code space): 12
+Memory allocation - compiled block : 148
+Memory allocation - code portion   : 12
 ------------------------------------------------------------------
   0   8 Bra
   3     \x{10000}
@@ -312,7 +335,8 @@ Memory allocation (code space): 12
 ------------------------------------------------------------------
 
 /\x{100000}/utf
-Memory allocation (code space): 12
+Memory allocation - compiled block : 148
+Memory allocation - code portion   : 12
 ------------------------------------------------------------------
   0   8 Bra
   3     \x{100000}
@@ -321,7 +345,8 @@ Memory allocation (code space): 12
 ------------------------------------------------------------------
 
 /\x{10ffff}/utf
-Memory allocation (code space): 12
+Memory allocation - compiled block : 148
+Memory allocation - code portion   : 12
 ------------------------------------------------------------------
   0   8 Bra
   3     \x{10ffff}
@@ -333,7 +358,8 @@ Memory allocation (code space): 12
 Failed: error 134 at offset 9: character code point value in \x{} or \o{} is too large
 
 /[\x{ff}]/utf
-Memory allocation (code space): 10
+Memory allocation - compiled block : 146
+Memory allocation - code portion   : 10
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{ff}
@@ -342,7 +368,8 @@ Memory allocation (code space): 10
 ------------------------------------------------------------------
 
 /[\x{100}]/utf
-Memory allocation (code space): 10
+Memory allocation - compiled block : 146
+Memory allocation - code portion   : 10
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{100}
@@ -351,7 +378,8 @@ Memory allocation (code space): 10
 ------------------------------------------------------------------
 
 /\x80/utf
-Memory allocation (code space): 10
+Memory allocation - compiled block : 146
+Memory allocation - code portion   : 10
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{80}
@@ -360,7 +388,8 @@ Memory allocation (code space): 10
 ------------------------------------------------------------------
 
 /\xff/utf
-Memory allocation (code space): 10
+Memory allocation - compiled block : 146
+Memory allocation - code portion   : 10
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{ff}
@@ -369,7 +398,8 @@ Memory allocation (code space): 10
 ------------------------------------------------------------------
 
 /\x{0041}\x{2262}\x{0391}\x{002e}/I,utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0  14 Bra
   3     A\x{2262}\x{391}.
@@ -383,7 +413,8 @@ Last code unit = '.'
 Subject length lower bound = 4
 
 /\x{D55c}\x{ad6d}\x{C5B4}/I,utf
-Memory allocation (code space): 19
+Memory allocation - compiled block : 155
+Memory allocation - code portion   : 19
 ------------------------------------------------------------------
   0  15 Bra
   3     \x{d55c}\x{ad6d}\x{c5b4}
@@ -397,7 +428,8 @@ Last code unit = \xb4
 Subject length lower bound = 3
 
 /\x{65e5}\x{672c}\x{8a9e}/I,utf
-Memory allocation (code space): 19
+Memory allocation - compiled block : 155
+Memory allocation - code portion   : 19
 ------------------------------------------------------------------
   0  15 Bra
   3     \x{65e5}\x{672c}\x{8a9e}
@@ -411,7 +443,8 @@ Last code unit = \x9e
 Subject length lower bound = 3
 
 /[\x{100}]/utf
-Memory allocation (code space): 10
+Memory allocation - compiled block : 146
+Memory allocation - code portion   : 10
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{100}
@@ -420,7 +453,8 @@ Memory allocation (code space): 10
 ------------------------------------------------------------------
 
 /[Z\x{100}]/utf
-Memory allocation (code space): 47
+Memory allocation - compiled block : 183
+Memory allocation - code portion   : 47
 ------------------------------------------------------------------
   0  43 Bra
   3     [Z\x{100}]
@@ -429,7 +463,8 @@ Memory allocation (code space): 47
 ------------------------------------------------------------------
 
 /^[\x{100}\E-\Q\E\x{150}]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0  14 Bra
   3     ^
@@ -439,7 +474,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /^[\QĀ\E-\QŐ\E]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0  14 Bra
   3     ^
@@ -452,7 +488,8 @@ Memory allocation (code space): 18
 Failed: error 106 at offset 15: missing terminating ] for character class
 
 /[\p{L}]/
-Memory allocation (code space): 15
+Memory allocation - compiled block : 151
+Memory allocation - code portion   : 15
 ------------------------------------------------------------------
   0  11 Bra
   3     [\p{L}]
@@ -461,7 +498,8 @@ Memory allocation (code space): 15
 ------------------------------------------------------------------
 
 /[\p{^L}]/
-Memory allocation (code space): 15
+Memory allocation - compiled block : 151
+Memory allocation - code portion   : 15
 ------------------------------------------------------------------
   0  11 Bra
   3     [\P{L}]
@@ -470,7 +508,8 @@ Memory allocation (code space): 15
 ------------------------------------------------------------------
 
 /[\P{L}]/
-Memory allocation (code space): 15
+Memory allocation - compiled block : 151
+Memory allocation - code portion   : 15
 ------------------------------------------------------------------
   0  11 Bra
   3     [\P{L}]
@@ -479,7 +518,8 @@ Memory allocation (code space): 15
 ------------------------------------------------------------------
 
 /[\P{^L}]/
-Memory allocation (code space): 15
+Memory allocation - compiled block : 151
+Memory allocation - code portion   : 15
 ------------------------------------------------------------------
   0  11 Bra
   3     [\p{L}]
@@ -488,7 +528,8 @@ Memory allocation (code space): 15
 ------------------------------------------------------------------
 
 /[abc\p{L}\x{0660}]/utf
-Memory allocation (code space): 50
+Memory allocation - compiled block : 186
+Memory allocation - code portion   : 50
 ------------------------------------------------------------------
   0  46 Bra
   3     [a-c\p{L}\x{660}]
@@ -497,7 +538,8 @@ Memory allocation (code space): 50
 ------------------------------------------------------------------
 
 /[\p{Nd}]/utf
-Memory allocation (code space): 15
+Memory allocation - compiled block : 151
+Memory allocation - code portion   : 15
 ------------------------------------------------------------------
   0  11 Bra
   3     [\p{Nd}]
@@ -506,7 +548,8 @@ Memory allocation (code space): 15
 ------------------------------------------------------------------
 
 /[\p{Nd}+-]+/utf
-Memory allocation (code space): 48
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 48
 ------------------------------------------------------------------
   0  44 Bra
   3     [+\-\p{Nd}]++
@@ -515,7 +558,8 @@ Memory allocation (code space): 48
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/i,utf
-Memory allocation (code space): 25
+Memory allocation - compiled block : 161
+Memory allocation - code portion   : 25
 ------------------------------------------------------------------
   0  21 Bra
   3  /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -524,7 +568,8 @@ Memory allocation (code space): 25
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/utf
-Memory allocation (code space): 25
+Memory allocation - compiled block : 161
+Memory allocation - code portion   : 25
 ------------------------------------------------------------------
   0  21 Bra
   3     A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -533,7 +578,8 @@ Memory allocation (code space): 25
 ------------------------------------------------------------------
 
 /[\x{105}-\x{109}]/i,utf
-Memory allocation (code space): 17
+Memory allocation - compiled block : 153
+Memory allocation - code portion   : 17
 ------------------------------------------------------------------
   0  13 Bra
   3     [\x{104}-\x{109}]
@@ -542,7 +588,8 @@ Memory allocation (code space): 17
 ------------------------------------------------------------------
 
 /( ( (?(1)0|) )*   )/x
-Memory allocation (code space): 38
+Memory allocation - compiled block : 174
+Memory allocation - code portion   : 38
 ------------------------------------------------------------------
   0  34 Bra
   3  28 CBra 1
@@ -560,7 +607,8 @@ Memory allocation (code space): 38
 ------------------------------------------------------------------
 
 /(  (?(1)0|)*   )/x
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  26 Bra
   3  20 CBra 1
@@ -576,7 +624,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /[a]/
-Memory allocation (code space): 9
+Memory allocation - compiled block : 145
+Memory allocation - code portion   : 9
 ------------------------------------------------------------------
   0   5 Bra
   3     a
@@ -585,7 +634,8 @@ Memory allocation (code space): 9
 ------------------------------------------------------------------
 
 /[a]/utf
-Memory allocation (code space): 9
+Memory allocation - compiled block : 145
+Memory allocation - code portion   : 9
 ------------------------------------------------------------------
   0   5 Bra
   3     a
@@ -594,7 +644,8 @@ Memory allocation (code space): 9
 ------------------------------------------------------------------
 
 /[\xaa]/
-Memory allocation (code space): 9
+Memory allocation - compiled block : 145
+Memory allocation - code portion   : 9
 ------------------------------------------------------------------
   0   5 Bra
   3     \x{aa}
@@ -603,7 +654,8 @@ Memory allocation (code space): 9
 ------------------------------------------------------------------
 
 /[\xaa]/utf
-Memory allocation (code space): 10
+Memory allocation - compiled block : 146
+Memory allocation - code portion   : 10
 ------------------------------------------------------------------
   0   6 Bra
   3     \x{aa}
@@ -612,7 +664,8 @@ Memory allocation (code space): 10
 ------------------------------------------------------------------
 
 /[^a]/
-Memory allocation (code space): 9
+Memory allocation - compiled block : 145
+Memory allocation - code portion   : 9
 ------------------------------------------------------------------
   0   5 Bra
   3     [^a]
@@ -621,7 +674,8 @@ Memory allocation (code space): 9
 ------------------------------------------------------------------
 
 /[^a]/utf
-Memory allocation (code space): 9
+Memory allocation - compiled block : 145
+Memory allocation - code portion   : 9
 ------------------------------------------------------------------
   0   5 Bra
   3     [^a]
@@ -630,7 +684,8 @@ Memory allocation (code space): 9
 ------------------------------------------------------------------
 
 /[^\xaa]/
-Memory allocation (code space): 9
+Memory allocation - compiled block : 145
+Memory allocation - code portion   : 9
 ------------------------------------------------------------------
   0   5 Bra
   3     [^\x{aa}]
@@ -639,7 +694,8 @@ Memory allocation (code space): 9
 ------------------------------------------------------------------
 
 /[^\xaa]/utf
-Memory allocation (code space): 10
+Memory allocation - compiled block : 146
+Memory allocation - code portion   : 10
 ------------------------------------------------------------------
   0   6 Bra
   3     [^\x{aa}]
index 963700a3c277bc14b25839d45247a6f0ef89d22f..48e0b8aab1b870131a16d605affc799b70e0b6c4 100644 (file)
@@ -10,7 +10,8 @@
 #pattern fullbincode,memory
 
 /((?i)b)/
-Memory allocation (code space): 21
+Memory allocation - compiled block : 157
+Memory allocation - code portion   : 21
 ------------------------------------------------------------------
   0  16 Bra
   4   8 CBra 1
@@ -21,7 +22,8 @@ Memory allocation (code space): 21
 ------------------------------------------------------------------
 
 /(?s)(.*X|^B)/
-Memory allocation (code space): 30
+Memory allocation - compiled block : 166
+Memory allocation - code portion   : 30
 ------------------------------------------------------------------
   0  25 Bra
   4  10 CBra 1
@@ -36,7 +38,8 @@ Memory allocation (code space): 30
 ------------------------------------------------------------------
 
 /(?s:.*X|^B)/
-Memory allocation (code space): 28
+Memory allocation - compiled block : 164
+Memory allocation - code portion   : 28
 ------------------------------------------------------------------
   0  23 Bra
   4   8 Bra
@@ -51,7 +54,8 @@ Memory allocation (code space): 28
 ------------------------------------------------------------------
 
 /^[[:alnum:]]/
-Memory allocation (code space): 43
+Memory allocation - compiled block : 179
+Memory allocation - code portion   : 43
 ------------------------------------------------------------------
   0  38 Bra
   4     ^
@@ -61,7 +65,8 @@ Memory allocation (code space): 43
 ------------------------------------------------------------------
 
 /#/Ix
-Memory allocation (code space): 9
+Memory allocation - compiled block : 145
+Memory allocation - code portion   : 9
 ------------------------------------------------------------------
   0   4 Bra
   4   4 Ket
@@ -73,7 +78,8 @@ Options: extended
 Subject length lower bound = 0
 
 /a#/Ix
-Memory allocation (code space): 11
+Memory allocation - compiled block : 147
+Memory allocation - code portion   : 11
 ------------------------------------------------------------------
   0   6 Bra
   4     a
@@ -86,7 +92,8 @@ First code unit = 'a'
 Subject length lower bound = 1
 
 /x?+/
-Memory allocation (code space): 11
+Memory allocation - compiled block : 147
+Memory allocation - code portion   : 11
 ------------------------------------------------------------------
   0   6 Bra
   4     x?+
@@ -95,7 +102,8 @@ Memory allocation (code space): 11
 ------------------------------------------------------------------
 
 /x++/
-Memory allocation (code space): 11
+Memory allocation - compiled block : 147
+Memory allocation - code portion   : 11
 ------------------------------------------------------------------
   0   6 Bra
   4     x++
@@ -104,7 +112,8 @@ Memory allocation (code space): 11
 ------------------------------------------------------------------
 
 /x{1,3}+/
-Memory allocation (code space): 15
+Memory allocation - compiled block : 151
+Memory allocation - code portion   : 15
 ------------------------------------------------------------------
   0  10 Bra
   4     x
@@ -114,7 +123,8 @@ Memory allocation (code space): 15
 ------------------------------------------------------------------
 
 /(x)*+/
-Memory allocation (code space): 22
+Memory allocation - compiled block : 158
+Memory allocation - code portion   : 22
 ------------------------------------------------------------------
   0  17 Bra
   4     Braposzero
@@ -126,7 +136,8 @@ Memory allocation (code space): 22
 ------------------------------------------------------------------
 
 /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
-Memory allocation (code space): 132
+Memory allocation - compiled block : 268
+Memory allocation - code portion   : 132
 ------------------------------------------------------------------
   0 127 Bra
   4     ^
@@ -149,7 +160,8 @@ Memory allocation (code space): 132
 ------------------------------------------------------------------
 
 "8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 828
+Memory allocation - compiled block : 964
+Memory allocation - code portion   : 828
 ------------------------------------------------------------------
   0 823 Bra
   4     8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -159,7 +171,8 @@ Memory allocation (code space): 828
 ------------------------------------------------------------------
 
 "\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 818
+Memory allocation - compiled block : 954
+Memory allocation - code portion   : 818
 ------------------------------------------------------------------
   0 813 Bra
   4     $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -169,7 +182,8 @@ Memory allocation (code space): 818
 ------------------------------------------------------------------
 
 /(a(?1)b)/
-Memory allocation (code space): 27
+Memory allocation - compiled block : 163
+Memory allocation - code portion   : 27
 ------------------------------------------------------------------
   0  22 Bra
   4  14 CBra 1
@@ -182,7 +196,8 @@ Memory allocation (code space): 27
 ------------------------------------------------------------------
 
 /(a(?1)+b)/
-Memory allocation (code space): 35
+Memory allocation - compiled block : 171
+Memory allocation - code portion   : 35
 ------------------------------------------------------------------
   0  30 Bra
   4  22 CBra 1
@@ -197,7 +212,8 @@ Memory allocation (code space): 35
 ------------------------------------------------------------------
 
 /a(?P<name1>b|c)d(?P<longername2>e)/
-Memory allocation (code space): 43
+Memory allocation - compiled block : 207
+Memory allocation - code portion   : 43
 ------------------------------------------------------------------
   0  38 Bra
   4     a
@@ -215,7 +231,8 @@ Memory allocation (code space): 43
 ------------------------------------------------------------------
 
 /(?:a(?P<c>c(?P<d>d)))(?P<a>a)/
-Memory allocation (code space): 55
+Memory allocation - compiled block : 203
+Memory allocation - code portion   : 55
 ------------------------------------------------------------------
   0  50 Bra
   4  30 Bra
@@ -235,7 +252,8 @@ Memory allocation (code space): 55
 ------------------------------------------------------------------
 
 /(?P<a>a)...(?P=a)bbb(?P>a)d/
-Memory allocation (code space): 39
+Memory allocation - compiled block : 179
+Memory allocation - code portion   : 39
 ------------------------------------------------------------------
   0  34 Bra
   4   8 CBra 1
@@ -253,7 +271,8 @@ Memory allocation (code space): 39
 ------------------------------------------------------------------
 
 /abc(?C255)de(?C)f/
-Memory allocation (code space): 37
+Memory allocation - compiled block : 173
+Memory allocation - code portion   : 37
 ------------------------------------------------------------------
   0  32 Bra
   4     abc
@@ -266,7 +285,8 @@ Memory allocation (code space): 37
 ------------------------------------------------------------------
 
 /abcde/auto_callout
-Memory allocation (code space): 67
+Memory allocation - compiled block : 203
+Memory allocation - code portion   : 67
 ------------------------------------------------------------------
   0  62 Bra
   4     Callout 255 0 1
@@ -285,7 +305,8 @@ Memory allocation (code space): 67
 ------------------------------------------------------------------
 
 /\x{100}/utf
-Memory allocation (code space): 12
+Memory allocation - compiled block : 148
+Memory allocation - code portion   : 12
 ------------------------------------------------------------------
   0   7 Bra
   4     \x{100}
@@ -294,7 +315,8 @@ Memory allocation (code space): 12
 ------------------------------------------------------------------
 
 /\x{1000}/utf
-Memory allocation (code space): 13
+Memory allocation - compiled block : 149
+Memory allocation - code portion   : 13
 ------------------------------------------------------------------
   0   8 Bra
   4     \x{1000}
@@ -303,7 +325,8 @@ Memory allocation (code space): 13
 ------------------------------------------------------------------
 
 /\x{10000}/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   9 Bra
   4     \x{10000}
@@ -312,7 +335,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /\x{100000}/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   9 Bra
   4     \x{100000}
@@ -321,7 +345,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /\x{10ffff}/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   9 Bra
   4     \x{10ffff}
@@ -333,7 +358,8 @@ Memory allocation (code space): 14
 Failed: error 134 at offset 9: character code point value in \x{} or \o{} is too large
 
 /[\x{ff}]/utf
-Memory allocation (code space): 12
+Memory allocation - compiled block : 148
+Memory allocation - code portion   : 12
 ------------------------------------------------------------------
   0   7 Bra
   4     \x{ff}
@@ -342,7 +368,8 @@ Memory allocation (code space): 12
 ------------------------------------------------------------------
 
 /[\x{100}]/utf
-Memory allocation (code space): 12
+Memory allocation - compiled block : 148
+Memory allocation - code portion   : 12
 ------------------------------------------------------------------
   0   7 Bra
   4     \x{100}
@@ -351,7 +378,8 @@ Memory allocation (code space): 12
 ------------------------------------------------------------------
 
 /\x80/utf
-Memory allocation (code space): 12
+Memory allocation - compiled block : 148
+Memory allocation - code portion   : 12
 ------------------------------------------------------------------
   0   7 Bra
   4     \x{80}
@@ -360,7 +388,8 @@ Memory allocation (code space): 12
 ------------------------------------------------------------------
 
 /\xff/utf
-Memory allocation (code space): 12
+Memory allocation - compiled block : 148
+Memory allocation - code portion   : 12
 ------------------------------------------------------------------
   0   7 Bra
   4     \x{ff}
@@ -369,7 +398,8 @@ Memory allocation (code space): 12
 ------------------------------------------------------------------
 
 /\x{0041}\x{2262}\x{0391}\x{002e}/I,utf
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0  15 Bra
   4     A\x{2262}\x{391}.
@@ -383,7 +413,8 @@ Last code unit = '.'
 Subject length lower bound = 4
 
 /\x{D55c}\x{ad6d}\x{C5B4}/I,utf
-Memory allocation (code space): 21
+Memory allocation - compiled block : 157
+Memory allocation - code portion   : 21
 ------------------------------------------------------------------
   0  16 Bra
   4     \x{d55c}\x{ad6d}\x{c5b4}
@@ -397,7 +428,8 @@ Last code unit = \xb4
 Subject length lower bound = 3
 
 /\x{65e5}\x{672c}\x{8a9e}/I,utf
-Memory allocation (code space): 21
+Memory allocation - compiled block : 157
+Memory allocation - code portion   : 21
 ------------------------------------------------------------------
   0  16 Bra
   4     \x{65e5}\x{672c}\x{8a9e}
@@ -411,7 +443,8 @@ Last code unit = \x9e
 Subject length lower bound = 3
 
 /[\x{100}]/utf
-Memory allocation (code space): 12
+Memory allocation - compiled block : 148
+Memory allocation - code portion   : 12
 ------------------------------------------------------------------
   0   7 Bra
   4     \x{100}
@@ -420,7 +453,8 @@ Memory allocation (code space): 12
 ------------------------------------------------------------------
 
 /[Z\x{100}]/utf
-Memory allocation (code space): 50
+Memory allocation - compiled block : 186
+Memory allocation - code portion   : 50
 ------------------------------------------------------------------
   0  45 Bra
   4     [Z\x{100}]
@@ -429,7 +463,8 @@ Memory allocation (code space): 50
 ------------------------------------------------------------------
 
 /^[\x{100}\E-\Q\E\x{150}]/utf
-Memory allocation (code space): 21
+Memory allocation - compiled block : 157
+Memory allocation - code portion   : 21
 ------------------------------------------------------------------
   0  16 Bra
   4     ^
@@ -439,7 +474,8 @@ Memory allocation (code space): 21
 ------------------------------------------------------------------
 
 /^[\QĀ\E-\QŐ\E]/utf
-Memory allocation (code space): 21
+Memory allocation - compiled block : 157
+Memory allocation - code portion   : 21
 ------------------------------------------------------------------
   0  16 Bra
   4     ^
@@ -452,7 +488,8 @@ Memory allocation (code space): 21
 Failed: error 106 at offset 15: missing terminating ] for character class
 
 /[\p{L}]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0  13 Bra
   4     [\p{L}]
@@ -461,7 +498,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[\p{^L}]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0  13 Bra
   4     [\P{L}]
@@ -470,7 +508,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[\P{L}]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0  13 Bra
   4     [\P{L}]
@@ -479,7 +518,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[\P{^L}]/
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0  13 Bra
   4     [\p{L}]
@@ -488,7 +528,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[abc\p{L}\x{0660}]/utf
-Memory allocation (code space): 53
+Memory allocation - compiled block : 189
+Memory allocation - code portion   : 53
 ------------------------------------------------------------------
   0  48 Bra
   4     [a-c\p{L}\x{660}]
@@ -497,7 +538,8 @@ Memory allocation (code space): 53
 ------------------------------------------------------------------
 
 /[\p{Nd}]/utf
-Memory allocation (code space): 18
+Memory allocation - compiled block : 154
+Memory allocation - code portion   : 18
 ------------------------------------------------------------------
   0  13 Bra
   4     [\p{Nd}]
@@ -506,7 +548,8 @@ Memory allocation (code space): 18
 ------------------------------------------------------------------
 
 /[\p{Nd}+-]+/utf
-Memory allocation (code space): 51
+Memory allocation - compiled block : 187
+Memory allocation - code portion   : 51
 ------------------------------------------------------------------
   0  46 Bra
   4     [+\-\p{Nd}]++
@@ -515,7 +558,8 @@ Memory allocation (code space): 51
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/i,utf
-Memory allocation (code space): 27
+Memory allocation - compiled block : 163
+Memory allocation - code portion   : 27
 ------------------------------------------------------------------
   0  22 Bra
   4  /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -524,7 +568,8 @@ Memory allocation (code space): 27
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/utf
-Memory allocation (code space): 27
+Memory allocation - compiled block : 163
+Memory allocation - code portion   : 27
 ------------------------------------------------------------------
   0  22 Bra
   4     A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -533,7 +578,8 @@ Memory allocation (code space): 27
 ------------------------------------------------------------------
 
 /[\x{105}-\x{109}]/i,utf
-Memory allocation (code space): 20
+Memory allocation - compiled block : 156
+Memory allocation - code portion   : 20
 ------------------------------------------------------------------
   0  15 Bra
   4     [\x{104}-\x{109}]
@@ -542,7 +588,8 @@ Memory allocation (code space): 20
 ------------------------------------------------------------------
 
 /( ( (?(1)0|) )*   )/x
-Memory allocation (code space): 47
+Memory allocation - compiled block : 183
+Memory allocation - code portion   : 47
 ------------------------------------------------------------------
   0  42 Bra
   4  34 CBra 1
@@ -560,7 +607,8 @@ Memory allocation (code space): 47
 ------------------------------------------------------------------
 
 /(  (?(1)0|)*   )/x
-Memory allocation (code space): 37
+Memory allocation - compiled block : 173
+Memory allocation - code portion   : 37
 ------------------------------------------------------------------
   0  32 Bra
   4  24 CBra 1
@@ -576,7 +624,8 @@ Memory allocation (code space): 37
 ------------------------------------------------------------------
 
 /[a]/
-Memory allocation (code space): 11
+Memory allocation - compiled block : 147
+Memory allocation - code portion   : 11
 ------------------------------------------------------------------
   0   6 Bra
   4     a
@@ -585,7 +634,8 @@ Memory allocation (code space): 11
 ------------------------------------------------------------------
 
 /[a]/utf
-Memory allocation (code space): 11
+Memory allocation - compiled block : 147
+Memory allocation - code portion   : 11
 ------------------------------------------------------------------
   0   6 Bra
   4     a
@@ -594,7 +644,8 @@ Memory allocation (code space): 11
 ------------------------------------------------------------------
 
 /[\xaa]/
-Memory allocation (code space): 11
+Memory allocation - compiled block : 147
+Memory allocation - code portion   : 11
 ------------------------------------------------------------------
   0   6 Bra
   4     \x{aa}
@@ -603,7 +654,8 @@ Memory allocation (code space): 11
 ------------------------------------------------------------------
 
 /[\xaa]/utf
-Memory allocation (code space): 12
+Memory allocation - compiled block : 148
+Memory allocation - code portion   : 12
 ------------------------------------------------------------------
   0   7 Bra
   4     \x{aa}
@@ -612,7 +664,8 @@ Memory allocation (code space): 12
 ------------------------------------------------------------------
 
 /[^a]/
-Memory allocation (code space): 11
+Memory allocation - compiled block : 147
+Memory allocation - code portion   : 11
 ------------------------------------------------------------------
   0   6 Bra
   4     [^a]
@@ -621,7 +674,8 @@ Memory allocation (code space): 11
 ------------------------------------------------------------------
 
 /[^a]/utf
-Memory allocation (code space): 11
+Memory allocation - compiled block : 147
+Memory allocation - code portion   : 11
 ------------------------------------------------------------------
   0   6 Bra
   4     [^a]
@@ -630,7 +684,8 @@ Memory allocation (code space): 11
 ------------------------------------------------------------------
 
 /[^\xaa]/
-Memory allocation (code space): 11
+Memory allocation - compiled block : 147
+Memory allocation - code portion   : 11
 ------------------------------------------------------------------
   0   6 Bra
   4     [^\x{aa}]
@@ -639,7 +694,8 @@ Memory allocation (code space): 11
 ------------------------------------------------------------------
 
 /[^\xaa]/utf
-Memory allocation (code space): 12
+Memory allocation - compiled block : 148
+Memory allocation - code portion   : 12
 ------------------------------------------------------------------
   0   7 Bra
   4     [^\x{aa}]
index 8e19908e8b0c0753d635af423c698a6b5e726a16..81cf0f7632012f96526318f0397dc5e0774157ee 100644 (file)
@@ -10,7 +10,8 @@
 #pattern fullbincode,memory
 
 /((?i)b)/
-Memory allocation (code space): 25
+Memory allocation - compiled block : 161
+Memory allocation - code portion   : 25
 ------------------------------------------------------------------
   0  19 Bra
   5   9 CBra 1
@@ -21,7 +22,8 @@ Memory allocation (code space): 25
 ------------------------------------------------------------------
 
 /(?s)(.*X|^B)/
-Memory allocation (code space): 35
+Memory allocation - compiled block : 171
+Memory allocation - code portion   : 35
 ------------------------------------------------------------------
   0  29 Bra
   5  11 CBra 1
@@ -36,7 +38,8 @@ Memory allocation (code space): 35
 ------------------------------------------------------------------
 
 /(?s:.*X|^B)/
-Memory allocation (code space): 33
+Memory allocation - compiled block : 169
+Memory allocation - code portion   : 33
 ------------------------------------------------------------------
   0  27 Bra
   5   9 Bra
@@ -51,7 +54,8 @@ Memory allocation (code space): 33
 ------------------------------------------------------------------
 
 /^[[:alnum:]]/
-Memory allocation (code space): 45
+Memory allocation - compiled block : 181
+Memory allocation - code portion   : 45
 ------------------------------------------------------------------
   0  39 Bra
   5     ^
@@ -61,7 +65,8 @@ Memory allocation (code space): 45
 ------------------------------------------------------------------
 
 /#/Ix
-Memory allocation (code space): 11
+Memory allocation - compiled block : 147
+Memory allocation - code portion   : 11
 ------------------------------------------------------------------
   0   5 Bra
   5   5 Ket
@@ -73,7 +78,8 @@ Options: extended
 Subject length lower bound = 0
 
 /a#/Ix
-Memory allocation (code space): 13
+Memory allocation - compiled block : 149
+Memory allocation - code portion   : 13
 ------------------------------------------------------------------
   0   7 Bra
   5     a
@@ -86,7 +92,8 @@ First code unit = 'a'
 Subject length lower bound = 1
 
 /x?+/
-Memory allocation (code space): 13
+Memory allocation - compiled block : 149
+Memory allocation - code portion   : 13
 ------------------------------------------------------------------
   0   7 Bra
   5     x?+
@@ -95,7 +102,8 @@ Memory allocation (code space): 13
 ------------------------------------------------------------------
 
 /x++/
-Memory allocation (code space): 13
+Memory allocation - compiled block : 149
+Memory allocation - code portion   : 13
 ------------------------------------------------------------------
   0   7 Bra
   5     x++
@@ -104,7 +112,8 @@ Memory allocation (code space): 13
 ------------------------------------------------------------------
 
 /x{1,3}+/
-Memory allocation (code space): 17
+Memory allocation - compiled block : 153
+Memory allocation - code portion   : 17
 ------------------------------------------------------------------
   0  11 Bra
   5     x
@@ -114,7 +123,8 @@ Memory allocation (code space): 17
 ------------------------------------------------------------------
 
 /(x)*+/
-Memory allocation (code space): 26
+Memory allocation - compiled block : 162
+Memory allocation - code portion   : 26
 ------------------------------------------------------------------
   0  20 Bra
   5     Braposzero
@@ -126,7 +136,8 @@ Memory allocation (code space): 26
 ------------------------------------------------------------------
 
 /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
-Memory allocation (code space): 144
+Memory allocation - compiled block : 280
+Memory allocation - code portion   : 144
 ------------------------------------------------------------------
   0 138 Bra
   5     ^
@@ -149,7 +160,8 @@ Memory allocation (code space): 144
 ------------------------------------------------------------------
 
 "8J\$WE\<\.rX\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 830
+Memory allocation - compiled block : 966
+Memory allocation - code portion   : 830
 ------------------------------------------------------------------
   0 824 Bra
   5     8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -159,7 +171,8 @@ Memory allocation (code space): 830
 ------------------------------------------------------------------
 
 "\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\<EjmhUZ\?\.akp2dF\>qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b"
-Memory allocation (code space): 820
+Memory allocation - compiled block : 956
+Memory allocation - code portion   : 820
 ------------------------------------------------------------------
   0 814 Bra
   5     $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDD<EjmhUZ?.akp2dF>qmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X
@@ -169,7 +182,8 @@ Memory allocation (code space): 820
 ------------------------------------------------------------------
 
 /(a(?1)b)/
-Memory allocation (code space): 32
+Memory allocation - compiled block : 168
+Memory allocation - code portion   : 32
 ------------------------------------------------------------------
   0  26 Bra
   5  16 CBra 1
@@ -182,7 +196,8 @@ Memory allocation (code space): 32
 ------------------------------------------------------------------
 
 /(a(?1)+b)/
-Memory allocation (code space): 42
+Memory allocation - compiled block : 178
+Memory allocation - code portion   : 42
 ------------------------------------------------------------------
   0  36 Bra
   5  26 CBra 1
@@ -197,7 +212,8 @@ Memory allocation (code space): 42
 ------------------------------------------------------------------
 
 /a(?P<name1>b|c)d(?P<longername2>e)/
-Memory allocation (code space): 50
+Memory allocation - compiled block : 214
+Memory allocation - code portion   : 50
 ------------------------------------------------------------------
   0  44 Bra
   5     a
@@ -215,7 +231,8 @@ Memory allocation (code space): 50
 ------------------------------------------------------------------
 
 /(?:a(?P<c>c(?P<d>d)))(?P<a>a)/
-Memory allocation (code space): 65
+Memory allocation - compiled block : 213
+Memory allocation - code portion   : 65
 ------------------------------------------------------------------
   0  59 Bra
   5  35 Bra
@@ -235,7 +252,8 @@ Memory allocation (code space): 65
 ------------------------------------------------------------------
 
 /(?P<a>a)...(?P=a)bbb(?P>a)d/
-Memory allocation (code space): 44
+Memory allocation - compiled block : 184
+Memory allocation - code portion   : 44
 ------------------------------------------------------------------
   0  38 Bra
   5   9 CBra 1
@@ -253,7 +271,8 @@ Memory allocation (code space): 44
 ------------------------------------------------------------------
 
 /abc(?C255)de(?C)f/
-Memory allocation (code space): 43
+Memory allocation - compiled block : 179
+Memory allocation - code portion   : 43
 ------------------------------------------------------------------
   0  37 Bra
   5     abc
@@ -266,7 +285,8 @@ Memory allocation (code space): 43
 ------------------------------------------------------------------
 
 /abcde/auto_callout
-Memory allocation (code space): 81
+Memory allocation - compiled block : 217
+Memory allocation - code portion   : 81
 ------------------------------------------------------------------
   0  75 Bra
   5     Callout 255 0 1
@@ -285,7 +305,8 @@ Memory allocation (code space): 81
 ------------------------------------------------------------------
 
 /\x{100}/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   8 Bra
   5     \x{100}
@@ -294,7 +315,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /\x{1000}/utf
-Memory allocation (code space): 15
+Memory allocation - compiled block : 151
+Memory allocation - code portion   : 15
 ------------------------------------------------------------------
   0   9 Bra
   5     \x{1000}
@@ -303,7 +325,8 @@ Memory allocation (code space): 15
 ------------------------------------------------------------------
 
 /\x{10000}/utf
-Memory allocation (code space): 16
+Memory allocation - compiled block : 152
+Memory allocation - code portion   : 16
 ------------------------------------------------------------------
   0  10 Bra
   5     \x{10000}
@@ -312,7 +335,8 @@ Memory allocation (code space): 16
 ------------------------------------------------------------------
 
 /\x{100000}/utf
-Memory allocation (code space): 16
+Memory allocation - compiled block : 152
+Memory allocation - code portion   : 16
 ------------------------------------------------------------------
   0  10 Bra
   5     \x{100000}
@@ -321,7 +345,8 @@ Memory allocation (code space): 16
 ------------------------------------------------------------------
 
 /\x{10ffff}/utf
-Memory allocation (code space): 16
+Memory allocation - compiled block : 152
+Memory allocation - code portion   : 16
 ------------------------------------------------------------------
   0  10 Bra
   5     \x{10ffff}
@@ -333,7 +358,8 @@ Memory allocation (code space): 16
 Failed: error 134 at offset 9: character code point value in \x{} or \o{} is too large
 
 /[\x{ff}]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   8 Bra
   5     \x{ff}
@@ -342,7 +368,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[\x{100}]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   8 Bra
   5     \x{100}
@@ -351,7 +378,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /\x80/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   8 Bra
   5     \x{80}
@@ -360,7 +388,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /\xff/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   8 Bra
   5     \x{ff}
@@ -369,7 +398,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /\x{0041}\x{2262}\x{0391}\x{002e}/I,utf
-Memory allocation (code space): 22
+Memory allocation - compiled block : 158
+Memory allocation - code portion   : 22
 ------------------------------------------------------------------
   0  16 Bra
   5     A\x{2262}\x{391}.
@@ -383,7 +413,8 @@ Last code unit = '.'
 Subject length lower bound = 4
 
 /\x{D55c}\x{ad6d}\x{C5B4}/I,utf
-Memory allocation (code space): 23
+Memory allocation - compiled block : 159
+Memory allocation - code portion   : 23
 ------------------------------------------------------------------
   0  17 Bra
   5     \x{d55c}\x{ad6d}\x{c5b4}
@@ -397,7 +428,8 @@ Last code unit = \xb4
 Subject length lower bound = 3
 
 /\x{65e5}\x{672c}\x{8a9e}/I,utf
-Memory allocation (code space): 23
+Memory allocation - compiled block : 159
+Memory allocation - code portion   : 23
 ------------------------------------------------------------------
   0  17 Bra
   5     \x{65e5}\x{672c}\x{8a9e}
@@ -411,7 +443,8 @@ Last code unit = \x9e
 Subject length lower bound = 3
 
 /[\x{100}]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   8 Bra
   5     \x{100}
@@ -420,7 +453,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[Z\x{100}]/utf
-Memory allocation (code space): 53
+Memory allocation - compiled block : 189
+Memory allocation - code portion   : 53
 ------------------------------------------------------------------
   0  47 Bra
   5     [Z\x{100}]
@@ -429,7 +463,8 @@ Memory allocation (code space): 53
 ------------------------------------------------------------------
 
 /^[\x{100}\E-\Q\E\x{150}]/utf
-Memory allocation (code space): 24
+Memory allocation - compiled block : 160
+Memory allocation - code portion   : 24
 ------------------------------------------------------------------
   0  18 Bra
   5     ^
@@ -439,7 +474,8 @@ Memory allocation (code space): 24
 ------------------------------------------------------------------
 
 /^[\QĀ\E-\QŐ\E]/utf
-Memory allocation (code space): 24
+Memory allocation - compiled block : 160
+Memory allocation - code portion   : 24
 ------------------------------------------------------------------
   0  18 Bra
   5     ^
@@ -452,7 +488,8 @@ Memory allocation (code space): 24
 Failed: error 106 at offset 15: missing terminating ] for character class
 
 /[\p{L}]/
-Memory allocation (code space): 21
+Memory allocation - compiled block : 157
+Memory allocation - code portion   : 21
 ------------------------------------------------------------------
   0  15 Bra
   5     [\p{L}]
@@ -461,7 +498,8 @@ Memory allocation (code space): 21
 ------------------------------------------------------------------
 
 /[\p{^L}]/
-Memory allocation (code space): 21
+Memory allocation - compiled block : 157
+Memory allocation - code portion   : 21
 ------------------------------------------------------------------
   0  15 Bra
   5     [\P{L}]
@@ -470,7 +508,8 @@ Memory allocation (code space): 21
 ------------------------------------------------------------------
 
 /[\P{L}]/
-Memory allocation (code space): 21
+Memory allocation - compiled block : 157
+Memory allocation - code portion   : 21
 ------------------------------------------------------------------
   0  15 Bra
   5     [\P{L}]
@@ -479,7 +518,8 @@ Memory allocation (code space): 21
 ------------------------------------------------------------------
 
 /[\P{^L}]/
-Memory allocation (code space): 21
+Memory allocation - compiled block : 157
+Memory allocation - code portion   : 21
 ------------------------------------------------------------------
   0  15 Bra
   5     [\p{L}]
@@ -488,7 +528,8 @@ Memory allocation (code space): 21
 ------------------------------------------------------------------
 
 /[abc\p{L}\x{0660}]/utf
-Memory allocation (code space): 56
+Memory allocation - compiled block : 192
+Memory allocation - code portion   : 56
 ------------------------------------------------------------------
   0  50 Bra
   5     [a-c\p{L}\x{660}]
@@ -497,7 +538,8 @@ Memory allocation (code space): 56
 ------------------------------------------------------------------
 
 /[\p{Nd}]/utf
-Memory allocation (code space): 21
+Memory allocation - compiled block : 157
+Memory allocation - code portion   : 21
 ------------------------------------------------------------------
   0  15 Bra
   5     [\p{Nd}]
@@ -506,7 +548,8 @@ Memory allocation (code space): 21
 ------------------------------------------------------------------
 
 /[\p{Nd}+-]+/utf
-Memory allocation (code space): 54
+Memory allocation - compiled block : 190
+Memory allocation - code portion   : 54
 ------------------------------------------------------------------
   0  48 Bra
   5     [+\-\p{Nd}]++
@@ -515,7 +558,8 @@ Memory allocation (code space): 54
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/i,utf
-Memory allocation (code space): 29
+Memory allocation - compiled block : 165
+Memory allocation - code portion   : 29
 ------------------------------------------------------------------
   0  23 Bra
   5  /i A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -524,7 +568,8 @@ Memory allocation (code space): 29
 ------------------------------------------------------------------
 
 /A\x{391}\x{10427}\x{ff3a}\x{1fb0}/utf
-Memory allocation (code space): 29
+Memory allocation - compiled block : 165
+Memory allocation - code portion   : 29
 ------------------------------------------------------------------
   0  23 Bra
   5     A\x{391}\x{10427}\x{ff3a}\x{1fb0}
@@ -533,7 +578,8 @@ Memory allocation (code space): 29
 ------------------------------------------------------------------
 
 /[\x{105}-\x{109}]/i,utf
-Memory allocation (code space): 23
+Memory allocation - compiled block : 159
+Memory allocation - code portion   : 23
 ------------------------------------------------------------------
   0  17 Bra
   5     [\x{104}-\x{109}]
@@ -542,7 +588,8 @@ Memory allocation (code space): 23
 ------------------------------------------------------------------
 
 /( ( (?(1)0|) )*   )/x
-Memory allocation (code space): 56
+Memory allocation - compiled block : 192
+Memory allocation - code portion   : 56
 ------------------------------------------------------------------
   0  50 Bra
   5  40 CBra 1
@@ -560,7 +607,8 @@ Memory allocation (code space): 56
 ------------------------------------------------------------------
 
 /(  (?(1)0|)*   )/x
-Memory allocation (code space): 44
+Memory allocation - compiled block : 180
+Memory allocation - code portion   : 44
 ------------------------------------------------------------------
   0  38 Bra
   5  28 CBra 1
@@ -576,7 +624,8 @@ Memory allocation (code space): 44
 ------------------------------------------------------------------
 
 /[a]/
-Memory allocation (code space): 13
+Memory allocation - compiled block : 149
+Memory allocation - code portion   : 13
 ------------------------------------------------------------------
   0   7 Bra
   5     a
@@ -585,7 +634,8 @@ Memory allocation (code space): 13
 ------------------------------------------------------------------
 
 /[a]/utf
-Memory allocation (code space): 13
+Memory allocation - compiled block : 149
+Memory allocation - code portion   : 13
 ------------------------------------------------------------------
   0   7 Bra
   5     a
@@ -594,7 +644,8 @@ Memory allocation (code space): 13
 ------------------------------------------------------------------
 
 /[\xaa]/
-Memory allocation (code space): 13
+Memory allocation - compiled block : 149
+Memory allocation - code portion   : 13
 ------------------------------------------------------------------
   0   7 Bra
   5     \x{aa}
@@ -603,7 +654,8 @@ Memory allocation (code space): 13
 ------------------------------------------------------------------
 
 /[\xaa]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   8 Bra
   5     \x{aa}
@@ -612,7 +664,8 @@ Memory allocation (code space): 14
 ------------------------------------------------------------------
 
 /[^a]/
-Memory allocation (code space): 13
+Memory allocation - compiled block : 149
+Memory allocation - code portion   : 13
 ------------------------------------------------------------------
   0   7 Bra
   5     [^a]
@@ -621,7 +674,8 @@ Memory allocation (code space): 13
 ------------------------------------------------------------------
 
 /[^a]/utf
-Memory allocation (code space): 13
+Memory allocation - compiled block : 149
+Memory allocation - code portion   : 13
 ------------------------------------------------------------------
   0   7 Bra
   5     [^a]
@@ -630,7 +684,8 @@ Memory allocation (code space): 13
 ------------------------------------------------------------------
 
 /[^\xaa]/
-Memory allocation (code space): 13
+Memory allocation - compiled block : 149
+Memory allocation - code portion   : 13
 ------------------------------------------------------------------
   0   7 Bra
   5     [^\x{aa}]
@@ -639,7 +694,8 @@ Memory allocation (code space): 13
 ------------------------------------------------------------------
 
 /[^\xaa]/utf
-Memory allocation (code space): 14
+Memory allocation - compiled block : 150
+Memory allocation - code portion   : 14
 ------------------------------------------------------------------
   0   8 Bra
   5     [^\x{aa}]
diff --git a/vms/configure.com b/vms/configure.com
new file mode 100644 (file)
index 0000000..b50365d
--- /dev/null
@@ -0,0 +1,1144 @@
+$! Configure procedure 
+$! (c) Alexey Chupahin  11-APR-2024
+$! alexey@vaxman.de, alexey_chupahin@mail.ru
+$!
+$!
+$ SET NOON
+$SET NOVER
+$WRITE SYS$OUTPUT " "
+$WRITE SYS$OUTPUT "Configuring PCRE2 library for OpenVMS  "
+$WRITE SYS$OUTPUT "(c) Alexey Chupahin   CHAPG"
+$WRITE SYS$OUTPUT " "
+$! Checking architecture
+$DECC = F$SEARCH("SYS$SYSTEM:DECC$COMPILER.EXE") .NES. ""
+$    IF F$GETSYI("ARCH_TYPE").EQ.1 THEN CPU = "VAX"
+$    IF F$GETSYI("ARCH_TYPE").EQ.2 THEN CPU = "Alpha"
+$    IF F$GETSYI("ARCH_TYPE").EQ.3 THEN CPU = "I64"
+$    IF F$GETSYI("ARCH_TYPE").EQ.4 THEN CPU = "x86"
+$WRITE SYS$OUTPUT "Checking architecture       ...  ", CPU
+$IF ( (CPU.EQS."Alpha").OR.(CPU.EQS."I64").OR(CPU.EQS."x86") )
+$  THEN
+$       SHARED=64
+$  ELSE
+$       SHARED=32
+$ENDIF
+$!
+$IF (DECC) THEN $WRITE SYS$OUTPUT  "Compiler           ...  DEC C"
+$IF (.NOT. DECC) THEN $WRITE SYS$OUTPUT  "BAD compiler" GOTO EXIT
+$MMS = F$SEARCH("SYS$SYSTEM:MMS.EXE") .NES. ""
+$MMK = F$TYPE(MMK) 
+$IF (MMS .OR. MMK.NES."") THEN GOTO TEST_LIBRARIES
+$! I cant find any make tool
+$ WRITE SYS$OUTPUT "Install MMS or MMK"
+$GOTO EXIT
+$!PERL = F$TYPE(MMK) 
+$!IF (PERL.NES."") THEN GOTO TEST_LIBRARIES
+$!WRITE SYS$OUTPUT "Install PERL"
+$!GOTO EXIT
+$!
+$!
+$! Is it package root directory? If no, go to [-]
+$ IF (F$SEARCH("[]VMS.DIR").EQS."") .AND. (F$SEARCH("[]vms.dir").EQS."")
+$  THEN
+$       SET DEF [-]
+$ ENDIF
+$!
+$TEST_LIBRARIES:
+$!   Setting as MAKE utility one of MMS or MMK. I prefer MMS.
+$IF (MMK.NES."") THEN MAKE="MMK"
+$IF (MMS) THEN MAKE="MMS"
+$WRITE SYS$OUTPUT "Checking build utility      ...  ''MAKE'"
+$!WRITE SYS$OUTPUT "Checking PERL              ...  found"
+$WRITE SYS$OUTPUT " "
+$!
+$!
+$! Check files and ODS-2. unzip makes files FILE.H.GENERIC like FILE_H.GENERIC.  Should rename to FILE.H_GENERIC
+$IF F$SEARCH("[.SRC]PCRE2_H.GENERIC") .NES. ""
+$ THEN
+$      REN [.SRC]PCRE2_H.GENERIC [.SRC]PCRE2.H_GENERIC
+$ ELSE
+$      IF F$SEARCH("[.SRC]PCRE2.H_GENERIC") .EQS. ""
+$       THEN
+$              WRITE SYS$OUTPUT "Not ODS-2 volume, or PCRE2_H.GENERIC not found"
+$              EXIT
+$      ENDIF
+$ENDIF
+$IF F$SEARCH("[.SRC]PCRE2_CHARTABLES_C.DIST") .NES. ""
+$ THEN
+$      REN [.SRC]PCRE2_CHARTABLES_C.DIST [.SRC]PCRE2_CHARTABLES.C_DIST
+$ ELSE
+$      IF F$SEARCH("[.SRC]PCRE2_CHARTABLES.C_DIST") .EQS. ""
+$       THEN
+$              WRITE SYS$OUTPUT "Not ODS-2 volume, or PCRE2_CHARTABLES_C.DIST not found"
+$              EXIT
+$      ENDIF
+$ENDIF
+$WRITE SYS$OUTPUT "Source Files OK"
+$!
+$!
+$I18 = F$SEARCH("SYS$I18N_ICONV:ISO8859-1_UTF-8.ICONV") .NES. ""
+$IF (I18)
+$  THEN
+$      WRITE SYS$OUTPUT "Found I18 extension ICONV codes"
+$!"Checking for iconv    "
+$ DEFINE SYS$ERROR _NLA0:
+$ DEFINE SYS$OUTPUT _NLA0:
+$ CC/OBJECT=TEST.OBJ SYS$INPUT
+#include <stdio.h>
+#include <iconv.h>
+#include <errno.h>
+#include  <stdlib.h>
+
+int main ()
+{
+    /*                                                                   */
+    /* Declare variables to be used                                      */
+    /*                                                                   */
+    char fromcodeset[30];
+    char tocodeset[30];
+    int  iconv_opened;
+    iconv_t iconv_struct;                   /* Iconv descriptor      */
+
+    /*                                                                   */
+    /* Initialize variables                                              */
+    /*                                                                   */
+    sprintf(fromcodeset,"UTF-8");
+    sprintf(tocodeset,"ISO8859-1");
+    iconv_opened = FALSE;
+
+    /*                                                                   */
+    /* Attempt to create a conversion descriptor for the codesets        */
+    /* specified. If the return value from iconv_open is -1 then         */
+    /* an error has occurred. Check value of errno.                      */
+    /*                                                                   */
+    if ((iconv_struct = iconv_open (tocodeset, fromcodeset)) == (iconv_t)-1)
+    {
+        /*                                                               */
+        /* Check the value of errno                                      */
+        /*                                                               */
+        switch (errno)
+        {
+        case EMFILE:
+        case ENFILE:
+          printf("Too many iconv conversion files open\n");
+          exit(2);
+          break;
+
+        case ENOMEM:
+          printf("Not enough memory\n");
+          printf("Checking iconv .....  no\n");
+          exit(2);
+         break;
+
+        case EINVAL:
+          printf("Unsupported conversion\n");
+         exit(2);
+          break;
+
+        default:
+          printf("Unexpected error from iconv_open\n");
+         exit(2);
+          break;
+        }
+    }
+    else
+        /*                                                               */
+ /* Successfully allocated a conversion descriptor   */
+ /*         */
+ iconv_opened = TRUE;
+
+    /*                                                                   */
+    /*  Was a conversion descriptor allocated                            */
+    /*                                                                   */
+    if (iconv_opened)
+    {
+        /*                                                               */
+        /* Attempt to deallocate the conversion descriptor. If           */
+        /* iconv_close returns -1 then an error has occurred.            */
+        /*                                                               */
+        if (iconv_close (iconv_struct) == -1)
+        {
+            /*                                                           */
+            /* An error occurred. Check the value of errno               */
+            /*                                                           */
+            switch (errno)
+            {
+            case EBADF:
+                printf("Conversion descriptor is invalid\n");
+                exit(2);
+               break;
+            default:
+                break;
+            }
+        }
+        else
+            printf("Checking iconv .....  yes\n");
+    }
+    return(1);
+}
+$!
+$TMP = $STATUS
+$DEASS SYS$ERROR
+$DEAS  SYS$OUTPUT
+$!WRITE SYS$OUTPUT TMP
+$IF (TMP .NE. %X10B90001)
+$  THEN
+$       HAVE_ICONV=0
+$       GOTO NEXT0
+$ENDIF
+$DEFINE SYS$ERROR _NLA0:
+$DEFINE SYS$OUTPUT _NLA0:
+$LINK/EXE=TEST TEST
+$TMP = $STATUS
+$DEAS  SYS$ERROR
+$DEAS  SYS$OUTPUT
+$!WRITE SYS$OUTPUT TMP
+$IF (TMP .NE. %X10000001)
+$  THEN
+$       HAVE_ICONV=0
+$       GOTO NEXT0
+$  ELSE
+$       HAVE_ICONV=1
+$ENDIF
+$NEXT0:
+$IF (HAVE_ICONV.EQ.1)
+$  THEN
+$       WRITE SYS$OUTPUT "Checking for iconv ...   Yes"
+$  ELSE
+$       WRITE SYS$OUTPUT "Checking for iconv ...   No"
+$ENDIF
+$!
+$!
+$! Checking for BZIP2 library
+$!
+$ DEFINE SYS$ERROR _NLA0:
+$ DEFINE SYS$OUTPUT _NLA0:
+$ CC/OBJECT=TEST.OBJ/INCLUDE=(BZ2LIB) SYS$INPUT
+      #include <stdlib.h>
+      #include <stdio.h>
+      #include <bzlib.h>
+   int main()
+     {
+        printf("checking version bzip2 library:  %s\n",BZ2_bzlibVersion());
+     }
+$TMP = $STATUS
+$DEASS SYS$ERROR
+$DEAS  SYS$OUTPUT
+$!WRITE SYS$OUTPUT TMP
+$IF (TMP .NE. %X10B90001)
+$  THEN
+$       HAVE_BZIP2=0
+$       GOTO ERR0
+$ENDIF
+$DEFINE SYS$ERROR _NLA0:
+$DEFINE SYS$OUTPUT _NLA0:
+$!Testing for CHAPG BZIP2
+$!
+$LINK/EXE=TEST TEST,BZ2LIB:BZIP2/OPT
+$TMP = $STATUS
+$DEAS SYS$ERROR
+$DEAS SYS$OUTPUT
+$IF (TMP .NE. %X10000001)
+$  THEN
+$       HAVE_BZIP2=0
+$       GOTO ERR0
+$  ELSE
+$       HAVE_BZIP2=1
+$ENDIF
+$ERR0:
+$IF (HAVE_BZIP2.EQ.1)
+$  THEN
+$       WRITE SYS$OUTPUT "Checking for CHAPG bzip2 library ...   Yes"
+$       RUN TEST
+$       GOTO NEXT4
+$  ELSE
+$       WRITE SYS$OUTPUT "Checking for correct bzip2 library ...   No"
+$       WRITE SYS$OUTPUT "To get bzip2 archives support, please download"
+$       WRITE SYS$OUTPUT "and install good library ported by Alexey Chupahin"
+$       WRITE SYS$OUTPUT "from openvms clamav site http://vaxvms.org/clamav/"
+$       WRITE SYS$OUTPUT ""
+$      GOTO EXIT
+$ENDIF
+$NEXT4:
+$!
+$!
+$!"Checking for CHAPG zlib library    "
+$DEFINE SYS$ERROR _NLA0:
+$DEFINE SYS$OUTPUT _NLA0:
+$ CC/OBJECT=TEST.OBJ/INCLUDE=(ZLIB) SYS$INPUT
+      #include <stdlib.h>
+      #include <stdio.h>
+      #include <string.h>
+      #include <zlib.h>
+   int main()
+     {
+        printf("checking version zlib:  %s\n",zlibVersion());
+       // printf("checking zlib is correct ");
+     }
+
+$TMP = $STATUS
+$DEASS SYS$ERROR
+$DEAS  SYS$OUTPUT
+$IF (TMP .NE. %X10B90001)
+$  THEN
+$       HAVE_ZLIB=0
+$       GOTO ERR4
+$ENDIF
+$DEFINE SYS$ERROR _NLA0:
+$DEFINE SYS$OUTPUT _NLA0:
+$!
+$LINK/EXE=TEST TEST,ZLIB:ZLIB.OPT/OPT
+$TMP = $STATUS
+$DEAS SYS$ERROR
+$DEAS SYS$OUTPUT
+$IF (TMP .NE. %X10000001)
+$  THEN
+$       HAVE_ZLIB=0
+$       GOTO ERR4
+$  ELSE
+$       HAVE_ZLIB=1
+$ENDIF
+$ERR4:
+$IF (HAVE_ZLIB.EQ.1)
+$  THEN
+$       WRITE SYS$OUTPUT "Checking for CHAPG zlib library ...   Yes"
+$       RUN TEST
+$       GOTO NEXT5
+$  ELSE
+$       WRITE SYS$OUTPUT "Checking for CHAPG zlib library ...   No"
+$       WRITE SYS$OUTPUT "Please install ZLIB from"
+$       WRITE SYS$OUTPUT "http://vaxvms.org/libsdl/required.html"
+$       GOTO EXIT
+$ENDIF
+$!
+$NEXT5:
+
+$!
+$!WRITING BUILD FILES
+$OPEN/WRITE OUT BUILD.COM
+$ WRITE OUT "$","SET DEF [.SRC]"
+$ WRITE OUT "$",MAKE
+$ WRITE OUT "$ CURRENT = F$ENVIRONMENT (""DEFAULT"") "
+$ WRITE OUT "$","SET DEF [-]"
+$ WRITE OUT "$CLAM=CURRENT"
+$ WRITE OUT "$OPEN/WRITE OUTT PCRE2$STARTUP.COM"
+$ WRITE OUT "$WRITE OUTT ""DEFINE PCRE2 ","'","'","CLAM'"" "
+$ WRITE OUT "$WRITE OUTT ""DEFINE PCRE2$SHR ","'","'","CLAM'PCRE2$SHR.EXE"" "
+$ WRITE OUT "$WRITE OUTT ""PCRE2GREP:==$", "'","'","CLAM'PCRE2GREP.EXE"""
+$ WRITE OUT "$CLOSE OUTT"
+$ WRITE OUT "$WRITE SYS$OUTPUT "" "" "
+$ WRITE OUT "$WRITE SYS$OUTPUT ""***************************************************************************** "" "
+$ WRITE OUT "$WRITE SYS$OUTPUT ""Compilation is completed."" "
+$ WRITE OUT "$WRITE SYS$OUTPUT ""PCRE2$STARTUP.COM is created. "" "
+$ WRITE OUT "$WRITE SYS$OUTPUT ""This file setups all logicals needed."" " 
+$ WRITE OUT "$WRITE SYS$OUTPUT ""It should be executed before using PCRE2 Library. "" "
+$ WRITE OUT "$WRITE SYS$OUTPUT ""Use PCRE2:PCRE2.OPT to link you program"" "
+$ WRITE OUT "$WRITE SYS$OUTPUT ""PCRE2GREP grep utility is installed here for your needs "" "
+$ WRITE OUT "$WRITE SYS$OUTPUT ""***************************************************************************** "" "
+$CLOSE OUT 
+$! BUILD.COM finished
+$ WRITE SYS$OUTPUT "BUILD.COM has been created"
+$!
+$!Creating OPT.OPT file containig external libraries for linker
+$OPEN/WRITE OUT [.SRC]PCRE2.OPT
+$IF (SHARED.GT.0)  THEN  WRITE OUT "PCRE2:PCRE2$SHR/SHARE"
+$IF (SHARED.EQ.0)
+$  THEN  
+$      WRITE OUT "PCRE2:PCRE2/LIB"
+$ENDIF
+$CLOSE OUT
+$WRITE SYS$OUTPUT "PCRE2.OPT has been created"
+$IF (SHARED.EQ.64)
+$ THEN
+$      COPY SYS$INPUT [.SRC]PCRE2$DEF.OPT
+!
+case_sensitive=NO
+symbol_vector = (PCRE2_CONFIG_8        = PROCEDURE)
+symbol_vector = (PCRE2_MAKETABLES_8    = PROCEDURE)
+symbol_vector = (PCRE2_MAKETABLES_FREE_8       = PROCEDURE)
+symbol_vector = (PCRE2_CODE_COPY_8     = PROCEDURE)
+symbol_vector = (PCRE2_CODE_FREE_8     = PROCEDURE)
+symbol_vector = (_PCRE2_CHECK_ESCAPE_8 = PROCEDURE)
+symbol_vector = (PCRE2_COMPILE_8       = PROCEDURE)
+symbol_vector = (PCRE2_CODE_COPY_WITH_TABLES_8 = PROCEDURE)
+symbol_vector = (PCRE2_GET_ERROR_MESSAGE_8     = PROCEDURE)
+symbol_vector = (PCRE2_MATCH_DATA_CREATE_8     = PROCEDURE)
+symbol_vector = (VMS_PCRE2_GET_M_D_HPFRAM_S_8  = PROCEDURE)
+symbol_vector = (PCRE2_GET_MATCH_DATA_SIZE_8   = PROCEDURE)
+symbol_vector = (PCRE2_GET_STARTCHAR_8 = PROCEDURE)
+symbol_vector = (PCRE2_GET_OVECTOR_COUNT_8     = PROCEDURE)
+symbol_vector = (PCRE2_GET_OVECTOR_POINTER_8   = PROCEDURE)
+symbol_vector = (PCRE2_GET_MARK_8      = PROCEDURE)
+symbol_vector = (PCRE2_MATCH_DATA_FREE_8       = PROCEDURE)
+symbol_vector = (VMS_PCRE2_M_D_CRT_FR_PATT_8   = PROCEDURE)
+symbol_vector = (PCRE2_MATCH_8 = PROCEDURE)
+symbol_vector = (PCRE2_PATTERN_INFO_8  = PROCEDURE)
+symbol_vector = (PCRE2_CALLOUT_ENUMERATE_8     = PROCEDURE)
+symbol_vector = (PCRE2_SET_GLOB_ESCAPE_8       = PROCEDURE)
+symbol_vector = (PCRE2_SET_GLOB_SEPARATOR_8    = PROCEDURE)
+symbol_vector = (VMS_PCRE2_SET_RCRS_MEM_MNG_8  = PROCEDURE)
+symbol_vector = (PCRE2_SET_DEPTH_LIMIT_8       = PROCEDURE)
+symbol_vector = (PCRE2_SET_RECURSION_LIMIT_8   = PROCEDURE)
+symbol_vector = (PCRE2_SET_OFFSET_LIMIT_8      = PROCEDURE)
+symbol_vector = (PCRE2_SET_MATCH_LIMIT_8       = PROCEDURE)
+symbol_vector = (PCRE2_SET_HEAP_LIMIT_8        = PROCEDURE)
+symbol_vector = (PCRE2_SET_SUBSTITUTE_CALLOUT_8        = PROCEDURE)
+symbol_vector = (PCRE2_SET_CALLOUT_8   = PROCEDURE)
+symbol_vector = (VMS_PCRE2_SET_CMPL_RCRS_GRD_8 = PROCEDURE)
+symbol_vector = (VMS_PCRE2_SET_CMPL_EXT_OPT_8  = PROCEDURE)
+symbol_vector = (PCRE2_SET_PARENS_NEST_LIMIT_8 = PROCEDURE)
+symbol_vector = (PCRE2_SET_MAX_VARLOOKBEHIND_8 = PROCEDURE)
+symbol_vector = (PCRE2_SET_NEWLINE_8   = PROCEDURE)
+symbol_vector = (PCRE2_SET_MAX_PATTERN_LENGTH_8        = PROCEDURE)
+symbol_vector = (PCRE2_SET_BSR_8       = PROCEDURE)
+symbol_vector = (PCRE2_SET_CHARACTER_TABLES_8  = PROCEDURE)
+symbol_vector = (PCRE2_CONVERT_CONTEXT_FREE_8  = PROCEDURE)
+symbol_vector = (PCRE2_MATCH_CONTEXT_FREE_8    = PROCEDURE)
+symbol_vector = (PCRE2_COMPILE_CONTEXT_FREE_8  = PROCEDURE)
+symbol_vector = (PCRE2_GENERAL_CONTEXT_FREE_8  = PROCEDURE)
+symbol_vector = (PCRE2_CONVERT_CONTEXT_COPY_8  = PROCEDURE)
+symbol_vector = (PCRE2_MATCH_CONTEXT_COPY_8    = PROCEDURE)
+symbol_vector = (PCRE2_COMPILE_CONTEXT_COPY_8  = PROCEDURE)
+symbol_vector = (PCRE2_GENERAL_CONTEXT_COPY_8  = PROCEDURE)
+symbol_vector = (_PCRE2_MEMCTL_MALLOC_8        = PROCEDURE)
+symbol_vector = (PCRE2_CONVERT_CONTEXT_CREATE_8        = PROCEDURE)
+symbol_vector = (PCRE2_MATCH_CONTEXT_CREATE_8  = PROCEDURE)
+symbol_vector = (PCRE2_COMPILE_CONTEXT_CREATE_8        = PROCEDURE)
+symbol_vector = (PCRE2_GENERAL_CONTEXT_CREATE_8        = PROCEDURE)
+symbol_vector = (_PCRE2_AUTO_POSSESSIFY_8      = PROCEDURE)
+symbol_vector = (_PCRE2_CKD_SMUL       = PROCEDURE)
+symbol_vector = (_PCRE2_FIND_BRACKET_8 = PROCEDURE)
+symbol_vector = (_PCRE2_IS_NEWLINE_8   = PROCEDURE)
+symbol_vector = (_PCRE2_WAS_NEWLINE_8  = PROCEDURE)
+symbol_vector = (_PCRE2_SCRIPT_RUN_8   = PROCEDURE)
+symbol_vector = (_PCRE2_STRCMP_8       = PROCEDURE)
+symbol_vector = (_PCRE2_STRCPY_C8_8    = PROCEDURE)
+symbol_vector = (_PCRE2_STRLEN_8       = PROCEDURE)
+symbol_vector = (_PCRE2_STRNCMP_C8_8   = PROCEDURE)
+symbol_vector = (_PCRE2_STRNCMP_8      = PROCEDURE)
+symbol_vector = (_PCRE2_STRCMP_C8_8    = PROCEDURE)
+symbol_vector = (_PCRE2_STUDY_8        = PROCEDURE)
+symbol_vector = (_PCRE2_VALID_UTF_8    = PROCEDURE)
+symbol_vector = (VMS_PCRE2_DEF_CMPL_CNTXT_8    = DATA)
+symbol_vector = (VMS_PCRE2_DEF_CNVRT_CNTXT_8   = DATA)
+symbol_vector = (_PCRE2_CALLOUT_END_DELIMS_8   = DATA)
+symbol_vector = (_PCRE2_CALLOUT_START_DELIMS_8 = DATA)
+symbol_vector = (_PCRE2_DEFAULT_MATCH_CONTEXT_8        = DATA)
+symbol_vector = (_PCRE2_DEFAULT_TABLES_8       = DATA)
+symbol_vector = (_PCRE2_HSPACE_LIST_8  = DATA)
+symbol_vector = (_PCRE2_OP_LENGTHS_8   = DATA)
+symbol_vector = (_PCRE2_UCD_CASELESS_SETS_8    = DATA)
+symbol_vector = (_PCRE2_UCD_RECORDS_8  = DATA)
+symbol_vector = (_PCRE2_UCD_STAGE1_8   = DATA)
+symbol_vector = (_PCRE2_UCD_STAGE2_8   = DATA)
+symbol_vector = (_PCRE2_VSPACE_LIST_8  = DATA)
+!
+! ### PSECT list extracted from PCRE2.MAP;1
+!
+$ENDIF
+$!
+$!
+COPY SYS$INPUT [.SRC]CONFIG.H
+/* src/config.h.in.  Generated from configure.ac by autoheader.  */
+
+
+/* PCRE2 is written in Standard C, but there are a few non-standard things it
+can cope with, allowing it to run on SunOS4 and other "close to standard"
+systems.
+
+In environments that support the GNU autotools, config.h.in is converted into
+config.h by the "configure" script. In environments that use CMake,
+config-cmake.in is converted into config.h. If you are going to build PCRE2 "by
+hand" without using "configure" or CMake, you should copy the distributed
+config.h.generic to config.h, and edit the macro definitions to be the way you
+need them. You must then add -DHAVE_CONFIG_H to all of your compile commands,
+so that config.h is included at the start of every source.
+
+Alternatively, you can avoid editing by using -D on the compiler command line
+to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H,
+but if you do, default values will be taken from config.h for non-boolean
+macros that are not defined on the command line.
+
+Boolean macros such as HAVE_STDLIB_H and SUPPORT_PCRE2_8 should either be
+defined (conventionally to 1) for TRUE, and not defined at all for FALSE. All
+such macros are listed as a commented #undef in config.h.generic. Macros such
+as MATCH_LIMIT, whose actual value is relevant, have defaults defined, but are
+surrounded by #ifndef/#endif lines so that the value can be overridden by -D.
+
+PCRE2 uses memmove() if HAVE_MEMMOVE is defined; otherwise it uses bcopy() if
+HAVE_BCOPY is defined. If your system has neither bcopy() nor memmove(), make
+sure both macros are undefined; an emulation function will then be used. */
+
+/* By default, the \R escape sequence matches any Unicode line ending
+   character or sequence of characters. If BSR_ANYCRLF is defined (to any
+   value), this is changed so that backslash-R matches only CR, LF, or CRLF.
+   The build-time default can be overridden by the user of PCRE2 at runtime.
+   */
+#undef BSR_ANYCRLF
+
+/* Define to any value to disable the use of the z and t modifiers in
+   formatting settings such as %zu or %td (this is rarely needed). */
+#undef DISABLE_PERCENT_ZT
+
+/* If you are compiling for a system that uses EBCDIC instead of ASCII
+   character codes, define this macro to any value. When EBCDIC is set, PCRE2
+   assumes that all input strings are in EBCDIC. If you do not define this
+   macro, PCRE2 will assume input strings are ASCII or UTF-8/16/32 Unicode. It
+   is not possible to build a version of PCRE2 that supports both EBCDIC and
+   UTF-8/16/32. */
+#undef EBCDIC
+
+/* In an EBCDIC environment, define this macro to any value to arrange for the
+   NL character to be 0x25 instead of the default 0x15. NL plays the role that
+   LF does in an ASCII/Unicode environment. */
+#undef EBCDIC_NL25
+
+/* Define this if your compiler supports __attribute__((uninitialized)) */
+#undef HAVE_ATTRIBUTE_UNINITIALIZED
+
+/* Define to 1 if you have the 'bcopy' function. */
+#define HAVE_BCOPY 1
+
+/* Define this if your compiler provides __builtin_mul_overflow() */
+#undef HAVE_BUILTIN_MUL_OVERFLOW
+
+
+/* Define to 1 if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <editline/readline.h> header file. */
+#undef HAVE_EDITLINE_READLINE_H
+
+/* Define to 1 if you have the <edit/readline/readline.h> header file. */
+#undef HAVE_EDIT_READLINE_READLINE_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the 'memfd_create' function. */
+#undef HAVE_MEMFD_CREATE
+
+/* Define to 1 if you have the 'memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <minix/config.h> header file. */
+#undef HAVE_MINIX_CONFIG_H
+
+/* Define to 1 if you have the 'mkostemp' function. */
+#undef HAVE_MKOSTEMP
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#undef HAVE_PTHREAD_PRIO_INHERIT
+
+/* Define to 1 if you have the <readline.h> header file. */
+#undef HAVE_READLINE_H
+
+/* Define to 1 if you have the <readline/history.h> header file. */
+#undef HAVE_READLINE_HISTORY_H
+
+/* Define to 1 if you have the <readline/readline.h> header file. */
+#undef HAVE_READLINE_READLINE_H
+
+/* Define to 1 if you have the `realpath' function. */
+#define HAVE_REALPATH 1
+
+/* Define to 1 if you have the 'secure_getenv' function. */
+#undef HAVE_SECURE_GETENV
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#define HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the 'strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if the compiler supports simple visibility declarations. */
+#undef HAVE_VISIBILITY
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#define HAVE_WCHAR_H 1
+
+/* Define to 1 if you have the <windows.h> header file. */
+#undef HAVE_WINDOWS_H
+
+/* Define to 1 if you have the <zlib.h> header file. */
+
+/* This limits the amount of memory that may be used while matching a pattern.
+   It applies to both pcre2_match() and pcre2_dfa_match(). It does not apply
+   to JIT matching. The value is in kibibytes (units of 1024 bytes). */
+#undef HEAP_LIMIT
+
+/* The value of LINK_SIZE determines the number of bytes used to store links
+   as offsets within the compiled regex. The default is 2, which allows for
+   compiled patterns up to 65535 code units long. This covers the vast
+   majority of cases. However, PCRE2 can also be compiled to use 3 or 4 bytes
+   instead. This allows for longer patterns in extreme cases. */
+#undef LINK_SIZE
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* The value of MATCH_LIMIT determines the default number of times the
+   pcre2_match() function can record a backtrack position during a single
+   matching attempt. The value is also used to limit a loop counter in
+   pcre2_dfa_match(). There is a runtime interface for setting a different
+   limit. The limit exists in order to catch runaway regular expressions that
+   take forever to determine that they do not match. The default is set very
+   large so that it does not accidentally catch legitimate cases. */
+#undef MATCH_LIMIT
+
+/* The above limit applies to all backtracks, whether or not they are nested.
+   In some environments it is desirable to limit the nesting of backtracking
+   (that is, the depth of tree that is searched) more strictly, in order to
+   restrict the maximum amount of heap memory that is used. The value of
+   MATCH_LIMIT_DEPTH provides this facility. To have any useful effect, it
+   must be less than the value of MATCH_LIMIT. The default is to use the same
+   value as MATCH_LIMIT. There is a runtime method for setting a different
+   limit. In the case of pcre2_dfa_match(), this limit controls the depth of
+   the internal nested function calls that are used for pattern recursions,
+   lookarounds, and atomic groups. */
+#undef MATCH_LIMIT_DEPTH
+
+/* This limit is parameterized just in case anybody ever wants to change it.
+   Care must be taken if it is increased, because it guards against integer
+   overflow caused by enormously large patterns. */
+#undef MAX_NAME_COUNT
+
+/* This limit is parameterized just in case anybody ever wants to change it.
+   Care must be taken if it is increased, because it guards against integer
+   overflow caused by enormously large patterns. */
+#undef MAX_NAME_SIZE
+
+/* The value of MAX_VARLOOKBEHIND specifies the default maximum length, in
+   characters, for a variable-length lookbehind assertion. */
+#undef MAX_VARLOOKBEHIND
+
+/* Defining NEVER_BACKSLASH_C locks out the use of \C in all patterns. */
+#undef NEVER_BACKSLASH_C
+
+/* The value of NEWLINE_DEFAULT determines the default newline character
+   sequence. PCRE2 client programs can override this by selecting other values
+   at run time. The valid values are 1 (CR), 2 (LF), 3 (CRLF), 4 (ANY), 5
+   (ANYCRLF), and 6 (NUL). */
+#undef NEWLINE_DEFAULT
+
+/* Name of package */
+#define PACKAGE "pcre2"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "PCRE2"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "PCRE2 10.43 VMS"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "pcre2"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "10.43"
+
+/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
+   parentheses (of any kind) in a pattern. This limits the amount of system
+   stack that is used while compiling a pattern. */
+#undef PARENS_NEST_LIMIT
+
+/* The value of PCRE2GREP_BUFSIZE is the starting size of the buffer used by
+   pcre2grep to hold parts of the file it is searching. The buffer will be
+   expanded up to PCRE2GREP_MAX_BUFSIZE if necessary, for files containing
+   very long lines. The actual amount of memory used by pcre2grep is three
+   times this number, because it allows for the buffering of "before" and
+   "after" lines. */
+#define PCRE2GREP_BUFSIZE 20480
+
+/* The value of PCRE2GREP_MAX_BUFSIZE specifies the maximum size of the buffer
+   used by pcre2grep to hold parts of the file it is searching. The actual
+   amount of memory used by pcre2grep is three times this number, because it
+   allows for the buffering of "before" and "after" lines. */
+#define PCRE2GREP_MAX_BUFSIZE 1048576
+
+/* Define to any value to include debugging code. */
+#undef PCRE2_DEBUG
+
+/* to make a symbol visible */
+#undef PCRE2_EXPORT
+
+
+/* If you are compiling for a system other than a Unix-like system or
+   Win32, and it needs some magic to be inserted before the definition
+   of a function that is exported by the library, define this macro to
+   contain the relevant magic. If you do not define this macro, a suitable
+   __declspec value is used for Windows systems; in other environments
+   a compiler relevant "extern" is used with any "visibility" related
+   attributes from PCRE2_EXPORT included.
+   This macro apears at the start of every exported function that is part
+   of the external API. It does not appear on functions that are "external"
+   in the C sense, but which are internal to the library. */
+#undef PCRE2_EXP_DEFN
+
+/* Define to any value if linking statically (TODO: make nice with Libtool) */
+#undef PCRE2_STATIC
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+   your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Define to any non-zero number to enable support for SELinux compatible
+   executable memory allocator in JIT. Note that this will have no effect
+   unless SUPPORT_JIT is also defined. */
+#undef SLJIT_PROT_EXECUTABLE_ALLOCATOR
+
+/* Define to 1 if all of the C89 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
+#define STDC_HEADERS 1
+
+/* Define to any value to enable differential fuzzing support. */
+#undef SUPPORT_DIFF_FUZZ
+
+/* Define to any value to enable support for Just-In-Time compiling. */
+#undef SUPPORT_JIT
+
+/* Define to any value to allow pcre2grep to be linked with libbz2, so that it
+   is able to handle .bz2 files. */
+
+/* Define to any value to allow pcre2test to be linked with libedit. */
+#undef SUPPORT_LIBEDIT
+
+/* Define to any value to allow pcre2test to be linked with libreadline. */
+#undef SUPPORT_LIBREADLINE
+
+/* Define to any value to allow pcre2grep to be linked with libz, so that it
+   is able to handle .gz files. */
+
+/* Define to any value to enable callout script support in pcre2grep. */
+#undef SUPPORT_PCRE2GREP_CALLOUT
+
+/* Define to any value to enable fork support in pcre2grep callout scripts.
+   This will have no effect unless SUPPORT_PCRE2GREP_CALLOUT is also defined.
+   */
+#undef SUPPORT_PCRE2GREP_CALLOUT_FORK
+
+/* Define to any value to enable JIT support in pcre2grep. Note that this will
+   have no effect unless SUPPORT_JIT is also defined. */
+#undef SUPPORT_PCRE2GREP_JIT
+
+/* Define to any value to enable the 16 bit PCRE2 library. */
+#undef SUPPORT_PCRE2_16
+
+/* Define to any value to enable the 32 bit PCRE2 library. */
+#undef SUPPORT_PCRE2_32
+
+/* Define to any value to enable the 8 bit PCRE2 library. */
+#define SUPPORT_PCRE2_8 1
+
+/* Define to any value to enable support for Unicode and UTF encoding. This
+   will work even in an EBCDIC environment, but it is incompatible with the
+   EBCDIC macro. That is, PCRE2 can support *either* EBCDIC code *or*
+   ASCII/Unicode, but not both at once. */
+#undef SUPPORT_UNICODE
+
+/* Define to any value for valgrind support to find invalid memory reads. */
+#undef SUPPORT_VALGRIND
+
+/* Enable extensions on AIX, Interix, z/OS.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable general extensions on macOS.  */
+#ifndef _DARWIN_C_SOURCE
+# undef _DARWIN_C_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable X/Open compliant socket functions that do not require linking
+   with -lxnet on HP-UX 11.11.  */
+#ifndef _HPUX_ALT_XOPEN_SOCKET_API
+# undef _HPUX_ALT_XOPEN_SOCKET_API
+#endif
+/* Identify the host operating system as Minix.
+   This macro does not affect the system headers' behavior.
+   A future release of Autoconf may stop defining this macro.  */
+#ifndef _MINIX
+# undef _MINIX
+#endif
+/* Enable general extensions on NetBSD.
+   Enable NetBSD compatibility extensions on Minix.  */
+#ifndef _NETBSD_SOURCE
+# undef _NETBSD_SOURCE
+#endif
+/* Enable OpenBSD compatibility extensions on NetBSD.
+   Oddly enough, this does nothing on OpenBSD.  */
+#ifndef _OPENBSD_SOURCE
+# undef _OPENBSD_SOURCE
+#endif
+/* Define to 1 if needed for POSIX-compatible behavior.  */
+#ifndef _POSIX_SOURCE
+# undef _POSIX_SOURCE
+#endif
+/* Define to 2 if needed for POSIX-compatible behavior.  */
+#ifndef _POSIX_1_SOURCE
+# undef _POSIX_1_SOURCE
+#endif
+/* Enable POSIX-compatible threading on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-5:2014.  */
+#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-1:2014.  */
+#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
+# undef __STDC_WANT_IEC_60559_BFP_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-2:2015.  */
+#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
+# undef __STDC_WANT_IEC_60559_DFP_EXT__
+#endif
+/* Enable extensions specified by C23 Annex F.  */
+#ifndef __STDC_WANT_IEC_60559_EXT__
+# undef __STDC_WANT_IEC_60559_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TS 18661-4:2015.  */
+#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
+# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
+#endif
+/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015.  */
+#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
+# undef __STDC_WANT_IEC_60559_TYPES_EXT__
+#endif
+/* Enable extensions specified by ISO/IEC TR 24731-2:2010.  */
+#ifndef __STDC_WANT_LIB_EXT2__
+# undef __STDC_WANT_LIB_EXT2__
+#endif
+/* Enable extensions specified by ISO/IEC 24747:2009.  */
+#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
+# undef __STDC_WANT_MATH_SPEC_FUNCS__
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable X/Open extensions.  Define to 500 only if necessary
+   to make mbstate_t available.  */
+#ifndef _XOPEN_SOURCE
+# undef _XOPEN_SOURCE
+#endif
+
+
+/* Version number of package */
+#undef VERSION
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define to 1 on platforms where this makes off_t a 64-bit type. */
+#undef _LARGE_FILES
+
+/* Number of bits in time_t, on hosts where this is settable. */
+#undef _TIME_BITS
+
+/* Define to 1 on platforms where this makes time_t a 64-bit type. */
+#undef __MINGW_USE_VC2005_COMPAT
+
+/* Define to empty if 'const' does not conform to ANSI C. */
+#undef const
+
+/* Define to the type of a signed integer type of width exactly 64 bits if
+   such a type exists and the standard includes do not define it. */
+#undef int64_t
+
+/* Define as 'unsigned int' if <stddef.h> doesn't define. */
+#undef size_t
+
+// VMS
+#include <stdint.h>
+#define PCRE2_EXPORT
+#define LINK_SIZE 2
+#define MAX_NAME_COUNT 10000
+#define MAX_NAME_SIZE 32
+#define MATCH_LIMIT 10000000
+#define HEAP_LIMIT 20000000
+#define NEWLINE_DEFAULT 2
+#define PARENS_NEST_LIMIT 250
+#define MATCH_LIMIT_DEPTH MATCH_LIMIT
+#define MAX_VARLOOKBEHIND 255
+
+/*
+#define _pcre2_default_compile_context_ vms_pcre2_def_cmpl_cntxt_
+#define _pcre2_default_convert_context_ vms_pcre2_def_cnvrt_cntxt_
+#define pcre2_set_compile_extra_options_8 vms_pcre2_set_cmpl_ext_opt_8
+#define pcre2_set_compile_recursion_guard_8 vms_pcre2_set_cmpl_rcrs_grd_8
+#define pcre2_set_recursion_memory_management_8 vms_pcre2_set_rcrs_mem_mng_8
+#define pcre2_match_data_create_from_pattern_8 vms_pcre2_m_d_crt_fr_patt_8
+#define pcre2_get_match_data_heapframes_size_8 vms_pcre2_get_m_d_hpfram_s_8
+#define pcre2_serialize_get_number_of_codes_8 vms_pcre2_ser_get_n_of_cod_8
+#define pcre2_substring_nametable_scan_8    vms_pcre2_substr_nmtab_scan_8
+#define pcre2_substring_length_bynumber_8   vms_pcre2_substr_len_bynum_8
+#define pcre2_substring_number_from_name_8 vms_pcre2_substr_num_f_nam_8
+*/
+
+#define HAVE_BZLIB_H 1
+#define SUPPORT_LIBBZ2 1
+
+#define HAVE_ZLIB_H 1
+#define SUPPORT_LIBZ 1
+$!
+$!
+$WRITE SYS$OUTPUT "config.h created"
+$!
+$!Creating Descrip.mms in each directory needed
+$!
+$!
+$COPY SYS$INPUT [.SRC]DESCRIP.MMS
+# (c) Alexey Chupahin 09-APR-2024
+# OpenVMS 7.3-2, DEC 2000 mod.300
+# OpenVMS 8.3,   Digital PW 600au
+# OpenVMS 8.4,   Compaq DS10L
+# OpenVMS 8.3,   HP rx1620
+
+
+.FIRST
+        DEF PCRE2 []
+
+
+CC=cc
+CFLAGS =  /INCLUDE=([],[-],[-.VMS],ZLIB,BZ2LIB) \
+          /DEFINE=(HAVE_CONFIG_H,PCRE2_CODE_UNIT_WIDTH=8)\
+          /OPTIMIZE=(INLINE=SPEED) \
+          /DEB
+
+OBJ=\
+PCRE2POSIX.OBJ,\
+PCRE2_AUTO_POSSESS.OBJ,\
+PCRE2_CHKDINT.OBJ,\
+PCRE2_CHARTABLES.OBJ,\
+PCRE2_COMPILE.OBJ,\
+PCRE2_CONFIG.OBJ,\
+PCRE2_CONTEXT.OBJ,\
+PCRE2_CONVERT.OBJ,\
+PCRE2_DFA_MATCH.OBJ,\
+PCRE2_ERROR.OBJ,\
+PCRE2_EXTUNI.OBJ,\
+PCRE2_FIND_BRACKET.OBJ,\
+PCRE2_JIT_COMPILE.OBJ,\
+PCRE2_MAKETABLES.OBJ,\
+PCRE2_MATCH.OBJ,\
+PCRE2_MATCH_DATA.OBJ,\
+PCRE2_NEWLINE.OBJ,\
+PCRE2_ORD2UTF.OBJ,\
+PCRE2_PATTERN_INFO.OBJ,\
+PCRE2_SCRIPT_RUN.OBJ,\
+PCRE2_SERIALIZE.OBJ,\
+PCRE2_STRING_UTILS.OBJ,\
+PCRE2_STUDY.OBJ,\
+PCRE2_SUBSTITUTE.OBJ,\
+PCRE2_SUBSTRING.OBJ,\
+PCRE2_TABLES.OBJ,\
+PCRE2_UCD.OBJ,\
+PCRE2_VALID_UTF.OBJ,\
+PCRE2_XCLASS.OBJ
+
+ALL : PCRE2.H PCRE2.OLB PCRE2$SHR.EXE PCRE2DEMO.EXE PCRE2GREP.EXE
+        $!
+
+PCRE2$SHR.EXE : PCRE2.OLB
+        LINK/SHARE=PCRE2$SHR.EXE PCRE2:PCRE2.OLB/LIB,PCRE2:PCRE2$DEF.OPT/OPT
+
+PCRE2.OLB : $(OBJ)
+        LIB/CREA PCRE2.OLB $(OBJ)
+
+PCRE2DEMO.EXE : PCRE2DEMO.OBJ
+        LINK/EXE=PCRE2DEMO PCRE2DEMO,PCRE2:PCRE2.OPT/OPT
+
+PCRE2GREP.EXE : PCRE2GREP.OBJ
+        LINK/EXE=PCRE2GREP PCRE2GREP,PCRE2:PCRE2.OPT/OPT,ZLIB:ZLIB.OPT/OPT,BZ2LIB:BZIP2.OPT/OPT
+
+PCRE2.H : PCRE2.H_GENERIC
+        WRITE SYS$OUTPUT "Patching PCRE2.H"
+        COPY/CONCAT [-.VMS]PCRE2.H_PATCH,[]PCRE2.H_GENERIC PCRE2.H
+
+PCRE2_CHARTABLES.OBJ : PCRE2_CHARTABLES.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_CHARTABLES.C : PCRE2_CHARTABLES.C_DIST
+         COPY PCRE2_CHARTABLES.C_DIST PCRE2_CHARTABLES.C
+
+PCRE2DEMO.OBJ : PCRE2DEMO.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2GREP.OBJ : PCRE2GREP.C
+         $(CC) $(CFLAGS) /WARN=DIS=ALL $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2POSIX.OBJ : PCRE2POSIX.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2POSIX_TEST.OBJ : PCRE2POSIX_TEST.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2TEST.OBJ : PCRE2TEST.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_AUTO_POSSESS.OBJ : PCRE2_AUTO_POSSESS.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_CHKDINT.OBJ : PCRE2_CHKDINT.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_COMPILE.OBJ : PCRE2_COMPILE.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_CONFIG.OBJ : PCRE2_CONFIG.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_CONTEXT.OBJ : PCRE2_CONTEXT.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_CONVERT.OBJ : PCRE2_CONVERT.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_DFA_MATCH.OBJ : PCRE2_DFA_MATCH.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_DFTABLES.OBJ : PCRE2_DFTABLES.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_ERROR.OBJ : PCRE2_ERROR.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_EXTUNI.OBJ : PCRE2_EXTUNI.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_FIND_BRACKET.OBJ : PCRE2_FIND_BRACKET.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_FUZZSUPPORT.OBJ : PCRE2_FUZZSUPPORT.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_JIT_COMPILE.OBJ : PCRE2_JIT_COMPILE.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_JIT_MATCH.OBJ : PCRE2_JIT_MATCH.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_JIT_MISC.OBJ : PCRE2_JIT_MISC.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_JIT_TEST.OBJ : PCRE2_JIT_TEST.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_MAKETABLES.OBJ : PCRE2_MAKETABLES.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_MATCH.OBJ : PCRE2_MATCH.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_MATCH_DATA.OBJ : PCRE2_MATCH_DATA.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_NEWLINE.OBJ : PCRE2_NEWLINE.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_ORD2UTF.OBJ : PCRE2_ORD2UTF.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_PATTERN_INFO.OBJ : PCRE2_PATTERN_INFO.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_PRINTINT.OBJ : PCRE2_PRINTINT.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_SCRIPT_RUN.OBJ : PCRE2_SCRIPT_RUN.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_SERIALIZE.OBJ : PCRE2_SERIALIZE.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_STRING_UTILS.OBJ : PCRE2_STRING_UTILS.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_STUDY.OBJ : PCRE2_STUDY.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_SUBSTITUTE.OBJ : PCRE2_SUBSTITUTE.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_SUBSTRING.OBJ : PCRE2_SUBSTRING.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_TABLES.OBJ : PCRE2_TABLES.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_UCD.OBJ : PCRE2_UCD.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_UCPTABLES.OBJ : PCRE2_UCPTABLES.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_VALID_UTF.OBJ : PCRE2_VALID_UTF.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+PCRE2_XCLASS.OBJ : PCRE2_XCLASS.C
+         $(CC) $(CFLAGS) $(MMS$SOURCE) /OBJ=$(MMS$TARGET)
+
+$!
+$!
+$WRITE SYS$OUTPUT "DESCRIP.MMS's have been created"
+$WRITE SYS$OUTPUT " "
+$WRITE SYS$OUTPUT " "
+$WRITE SYS$OUTPUT "Now you can type @BUILD "
+$!
+$EXIT:
+$DEFINE SYS$ERROR _NLA0:
+$DEFINE SYS$OUTPUT _NLA0:
+$DEL TEST.C;*
+$DEL TEST.OBJ;*
+$DEL TEST.EXE;*
+$DEL TEST.OPT;*
+$DEAS SYS$ERROR
+$DEAS SYS$OUTPUT
+
diff --git a/vms/openvms_readme.txt b/vms/openvms_readme.txt
new file mode 100644 (file)
index 0000000..7978a75
--- /dev/null
@@ -0,0 +1,20 @@
+This is directory for OpenVMS support,
+provided shared and static library,
+pcre2grep  utility also.
+
+Requires:
+bzip2 library : http://vaxvms.org/clamav/
+zlib library  : http://vaxvms.org/libsdl/required.html
+
+
+To build the library please:
+
+@[.VMS]CONFIGURE.COM
+@BUILD
+
+After build, PCRE2$STARTUP.COM has been created
+it should be started before use (good place from LOGIN.COM)
+
+Feel free to contact:
+alexey@vaxman.de
+Alexey Chupahin
diff --git a/vms/pcre2.h_patch b/vms/pcre2.h_patch
new file mode 100644 (file)
index 0000000..0134734
--- /dev/null
@@ -0,0 +1,12 @@
+#define _pcre2_default_compile_context_ vms_pcre2_def_cmpl_cntxt_
+#define _pcre2_default_convert_context_ vms_pcre2_def_cnvrt_cntxt_
+#define pcre2_set_compile_extra_options_8 vms_pcre2_set_cmpl_ext_opt_8
+#define pcre2_set_compile_recursion_guard_8 vms_pcre2_set_cmpl_rcrs_grd_8
+#define pcre2_set_recursion_memory_management_8 vms_pcre2_set_rcrs_mem_mng_8
+#define pcre2_match_data_create_from_pattern_8 vms_pcre2_m_d_crt_fr_patt_8
+#define pcre2_get_match_data_heapframes_size_8 vms_pcre2_get_m_d_hpfram_s_8
+#define pcre2_serialize_get_number_of_codes_8 vms_pcre2_ser_get_n_of_cod_8
+#define pcre2_substring_nametable_scan_8    vms_pcre2_substr_nmtab_scan_8
+#define pcre2_substring_length_bynumber_8   vms_pcre2_substr_len_bynum_8
+#define pcre2_substring_number_from_name_8 vms_pcre2_substr_num_f_nam_8
+#define pcre2_set_max_pattern_compiled_length vms_pcre2_set_max_pat_cmpl_len
diff --git a/vms/stdint.h b/vms/stdint.h
new file mode 100644 (file)
index 0000000..3a5a5a2
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef MY_VMS_STDINT
+#define MY_VMS_STDINT
+#include <inttypes.h>
+#include <limits.h>
+#include <stdbool.h>
+#define SIZE_MAX UINT_MAX
+#define UINT32_MAX  4294967295u
+#define UINT16_MAX             (65535)
+#endif