summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Vernon <matthew@debian.org>2020-12-07 12:33:40 +0000
committerMatthew Vernon <matthew@debian.org>2020-12-07 12:33:40 +0000
commitb28ccbd4005872e894e22f3cb28dcd1df00a5bb3 (patch)
tree49ffbd2a13cc8c17c434b3ff2abd6c844d1923ca
parentade48696948d66ff3ebba92f966ba554f7984fe8 (diff)
New upstream version 10.36
-rw-r--r--AUTHORS4
-rw-r--r--CMakeLists.txt67
-rw-r--r--ChangeLog105
-rw-r--r--LICENCE4
-rw-r--r--Makefile.am9
-rw-r--r--Makefile.in59
-rw-r--r--NEWS13
-rw-r--r--README19
-rwxr-xr-xRunGrepTest51
-rwxr-xr-xRunTest11
-rw-r--r--RunTest.bat2
-rwxr-xr-xconfigure77
-rw-r--r--configure.ac30
-rw-r--r--doc/html/README.txt19
-rw-r--r--doc/html/pcre2api.html57
-rw-r--r--doc/html/pcre2compat.html75
-rw-r--r--doc/html/pcre2grep.html239
-rw-r--r--doc/html/pcre2pattern.html46
-rw-r--r--doc/html/pcre2test.html26
-rw-r--r--doc/pcre2.txt1103
-rw-r--r--doc/pcre2api.358
-rw-r--r--doc/pcre2compat.377
-rw-r--r--doc/pcre2grep.1234
-rw-r--r--doc/pcre2grep.txt391
-rw-r--r--doc/pcre2pattern.349
-rw-r--r--doc/pcre2test.127
-rw-r--r--doc/pcre2test.txt1051
-rw-r--r--libpcre2-16.pc.in2
-rw-r--r--libpcre2-32.pc.in2
-rw-r--r--libpcre2-8.pc.in2
-rw-r--r--libpcre2-posix.pc.in2
-rw-r--r--pcre2-config.in8
-rwxr-xr-xperltest.sh3
-rw-r--r--src/config.h.generic6
-rw-r--r--src/pcre2.h.generic4
-rw-r--r--src/pcre2_compile.c3
-rw-r--r--src/pcre2_dftables.c6
-rw-r--r--src/pcre2_jit_compile.c220
-rw-r--r--src/pcre2_jit_misc.c2
-rw-r--r--src/pcre2_jit_neon_inc.h4
-rw-r--r--src/pcre2_jit_test.c40
-rw-r--r--src/pcre2_match.c10
-rw-r--r--src/pcre2grep.c693
-rw-r--r--src/pcre2test.c8
-rw-r--r--src/sljit/sljitConfig.h46
-rw-r--r--src/sljit/sljitConfigInternal.h145
-rw-r--r--src/sljit/sljitExecAllocator.c59
-rw-r--r--src/sljit/sljitLir.c59
-rw-r--r--src/sljit/sljitLir.h42
-rw-r--r--src/sljit/sljitNativeARM_32.c80
-rw-r--r--src/sljit/sljitNativeARM_64.c32
-rw-r--r--src/sljit/sljitNativeARM_T2_32.c23
-rw-r--r--src/sljit/sljitNativeMIPS_32.c11
-rw-r--r--src/sljit/sljitNativeMIPS_64.c12
-rw-r--r--src/sljit/sljitNativeMIPS_common.c15
-rw-r--r--src/sljit/sljitNativePPC_32.c11
-rw-r--r--src/sljit/sljitNativePPC_64.c12
-rw-r--r--src/sljit/sljitNativePPC_common.c3
-rw-r--r--src/sljit/sljitNativeS390X.c2812
-rw-r--r--src/sljit/sljitNativeSPARC_32.c11
-rw-r--r--src/sljit/sljitNativeSPARC_common.c3
-rw-r--r--src/sljit/sljitNativeTILEGX-encoder.c10159
-rw-r--r--src/sljit/sljitNativeTILEGX_64.c2563
-rw-r--r--src/sljit/sljitNativeX86_common.c55
-rw-r--r--src/sljit/sljitProtExecAllocator.c139
-rw-r--r--src/sljit/sljitUtils.c261
-rw-r--r--src/sljit/sljitWXExecAllocator.c225
-rw-r--r--testdata/grepoutput24
-rw-r--r--testdata/grepoutput83
-rw-r--r--testdata/grepoutputC2
-rw-r--r--testdata/grepoutputCN2
-rw-r--r--testdata/testinput161
-rw-r--r--testdata/testinput107
-rw-r--r--testdata/testinput220
-rw-r--r--testdata/testinput48
-rw-r--r--testdata/testoutput166
-rw-r--r--testdata/testoutput1010
-rw-r--r--testdata/testoutput225
-rw-r--r--testdata/testoutput48
79 files changed, 6570 insertions, 15362 deletions
diff --git a/AUTHORS b/AUTHORS
index 645c065..f001cb7 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -2,8 +2,8 @@ THE MAIN PCRE2 LIBRARY CODE
---------------------------
Written by: Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
+Email local part: Philip.Hazel
+Email domain: gmail.com
University of Cambridge Computing Service,
Cambridge, England.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 86b8896..aec2979 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -92,11 +92,13 @@
# library versioning.
# 2020-04-25 Carlo added function check for mkostemp used in ProtExecAllocator
# 2020-04-28 PH added function check for memfd_create based on Carlo's patch
+# 2020-05-25 PH added a check for Intel CET
+# 2020-12-03 PH altered the definition of pcre2test as suggested by Daniel
PROJECT(PCRE2 C)
-# Increased minimum to 2.8.0 to support newer add_test features.
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
+# Increased minimum to 2.8.5 to support GNUInstallDirs.
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8.5)
# Set policy CMP0026 to avoid warnings for the use of LOCATION in
# GET_TARGET_PROPERTY. This should no longer be required.
@@ -108,7 +110,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${PROJECT_SOURCE_DIR}/src")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I\"${PROJECT_SOURCE_DIR}/src\"")
# external packages
FIND_PACKAGE( BZip2 )
@@ -123,6 +125,7 @@ INCLUDE(CheckFunctionExists)
INCLUDE(CheckSymbolExists)
INCLUDE(CheckIncludeFile)
INCLUDE(CheckTypeSize)
+INCLUDE(GNUInstallDirs) # for CMAKE_INSTALL_LIBDIR
CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H)
CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H)
@@ -132,11 +135,11 @@ CHECK_INCLUDE_FILE(sys/types.h HAVE_SYS_TYPES_H)
CHECK_INCLUDE_FILE(unistd.h HAVE_UNISTD_H)
CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H)
-CHECK_FUNCTION_EXISTS(bcopy HAVE_BCOPY)
-CHECK_FUNCTION_EXISTS(memfd_create HAVE_MEMFD_CREATE)
-CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE)
-CHECK_FUNCTION_EXISTS(secure_getenv HAVE_SECURE_GETENV)
-CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR)
+CHECK_SYMBOL_EXISTS(bcopy "strings.h" HAVE_BCOPY)
+CHECK_SYMBOL_EXISTS(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE)
+CHECK_SYMBOL_EXISTS(memmove "string.h" HAVE_MEMMOVE)
+CHECK_SYMBOL_EXISTS(secure_getenv "stdlib.h" HAVE_SECURE_GETENV)
+CHECK_SYMBOL_EXISTS(strerror "string.h" HAVE_STRERROR)
set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
@@ -146,6 +149,24 @@ CHECK_C_SOURCE_COMPILES(
)
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
+# Check whether Intel CET is enabled, and if so, adjust compiler flags. This
+# code was written by PH, trying to imitate the logic from the autotools
+# configuration.
+
+CHECK_C_SOURCE_COMPILES(
+ "#ifndef __CET__
+ #error CET is not enabled
+ #endif
+ int main() { return 0; }"
+ INTEL_CET_ENABLED
+)
+
+IF (INTEL_CET_ENABLED)
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mshstk")
+ENDIF(INTEL_CET_ENABLED)
+
+
+
# User-configurable options
#
# Note: CMakeSetup displays these in alphabetical order, regardless of
@@ -445,7 +466,7 @@ foreach(configure_line ${configure_lines})
foreach(_substitution_variable ${SEARCHED_VARIABLES})
string(TOUPPER ${_substitution_variable} _substitution_variable_upper)
if (NOT ${_substitution_variable_upper})
- string(REGEX MATCH "m4_define\\(${_substitution_variable}, *\\[(.*)\\]" MACTHED_STRING ${configure_line})
+ string(REGEX MATCH "m4_define\\(${_substitution_variable}, *\\[(.*)\\]" MATCHED_STRING ${configure_line})
if (CMAKE_MATCH_1)
set(${_substitution_variable_upper} ${CMAKE_MATCH_1})
endif()
@@ -475,14 +496,23 @@ CONFIGURE_FILE(src/pcre2.h.in
${PROJECT_BINARY_DIR}/pcre2.h
@ONLY)
+# Make sure to not link debug libs
+# against release libs and vice versa
+IF(WIN32)
+ SET(CMAKE_DEBUG_POSTFIX "d")
+ENDIF(WIN32)
+
# Generate pkg-config files
SET(PACKAGE_VERSION "${PCRE2_MAJOR}.${PCRE2_MINOR}")
SET(prefix ${CMAKE_INSTALL_PREFIX})
SET(exec_prefix "\${prefix}")
-SET(libdir "\${exec_prefix}/lib")
+SET(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
SET(includedir "\${prefix}/include")
+IF(WIN32 AND (CMAKE_BUILD_TYPE MATCHES Debug))
+ SET(LIB_POSTFIX ${CMAKE_DEBUG_POSTFIX})
+ENDIF()
CONFIGURE_FILE(libpcre2-posix.pc.in libpcre2-posix.pc @ONLY)
SET(pkg_config_files ${pkg_config_files} "${CMAKE_CURRENT_BINARY_DIR}/libpcre2-posix.pc")
@@ -622,11 +652,6 @@ IF(MSVC)
ENDIF(MSVC)
SET(CMAKE_INCLUDE_CURRENT_DIR 1)
-# needed to make sure to not link debug libs
-# against release libs and vice versa
-IF(WIN32)
- SET(CMAKE_DEBUG_POSTFIX "d")
-ENDIF(WIN32)
SET(targets)
@@ -827,7 +852,9 @@ if test \"$?\" != \"0\"; then exit 1; fi
\@echo off
setlocal
SET srcdir=\"${winsrc}\"
-SET pcre2test=\"${winexe}\"
+# The next line was replaced by the following one after a user comment.
+# SET pcre2test=\"${winexe}\"
+SET pcre2test=\"${winbin}\\pcre2test.exe\"
if not [%CMAKE_CONFIG_TYPE%]==[] SET pcre2test=\"${winbin}\\%CMAKE_CONFIG_TYPE%\\pcre2test.exe\"
call %srcdir%\\RunTest.Bat
if errorlevel 1 exit /b 1
@@ -863,9 +890,9 @@ SET(CMAKE_INSTALL_ALWAYS 1)
INSTALL(TARGETS ${targets}
RUNTIME DESTINATION bin
- LIBRARY DESTINATION lib
- ARCHIVE DESTINATION lib)
-INSTALL(FILES ${pkg_config_files} DESTINATION lib/pkgconfig)
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
+INSTALL(FILES ${pkg_config_files} DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
INSTALL(FILES "${CMAKE_CURRENT_BINARY_DIR}/pcre2-config"
DESTINATION bin
# Set 0755 permissions
@@ -916,7 +943,7 @@ IF(PCRE2_SHOW_REPORT)
ENDIF(CMAKE_C_FLAGS)
MESSAGE(STATUS "")
MESSAGE(STATUS "")
- MESSAGE(STATUS "PCRE2 configuration summary:")
+ MESSAGE(STATUS "PCRE2-${PCRE2_MAJOR}.${PCRE2_MINOR} configuration summary:")
MESSAGE(STATUS "")
MESSAGE(STATUS " Install prefix .................. : ${CMAKE_INSTALL_PREFIX}")
MESSAGE(STATUS " C compiler ...................... : ${CMAKE_C_COMPILER}")
diff --git a/ChangeLog b/ChangeLog
index 310eb60..2e20bdb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,111 @@
Change Log for PCRE2
--------------------
+Version 10.36-RC1 04-December-2020
+----------------------------------
+
+1. Add CET_CFLAGS so that when Intel CET is enabled, pass -mshstk to
+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
+invalid utf8 mode is enabled.
+
+3. Updated CMakeLists.txt with patch from Wolfgang Stöggl (Bugzilla #2584):
+
+ - Include GNUInstallDirs and use ${CMAKE_INSTALL_LIBDIR} instead of hardcoded
+ lib. This allows differentiation between lib and lib64.
+ CMAKE_INSTALL_LIBDIR is used for installation of libraries and also for
+ pkgconfig file generation.
+
+ - Add the version of PCRE2 to the configuration summary like ./configure
+ does.
+
+ - Fix typo: MACTHED_STRING->MATCHED_STRING
+
+4. Updated CMakeLists.txt with another patch from Wolfgang Stöggl (Bugzilla
+#2588):
+
+ - Add escaped double quotes around include directory in CMakeLists.txt to
+ allow spaces in directory names.
+
+ - This fixes a cmake error, if the path of the pcre2 source contains a space.
+
+5. Updated CMakeLists.txt with a patch from B. Scott Michel: CMake's
+documentation suggests using CHECK_SYMBOL_EXISTS over CHECK_FUNCTION_EXIST.
+Moreover, these functions come from specific header files, which need to be
+specified (and, thankfully, are the same on both the Linux and WinXX
+platforms.)
+
+6. Added a (uint32_t) cast to prevent a compiler warning in pcre2_compile.c.
+
+7. Applied a patch from Wolfgang Stöggl (Bugzilla #2600) to fix postfix for
+debug Windows builds using CMake. This also updated configure so that it
+generates *.pc files and pcre2-config with the same content, as in the past.
+
+8. If a pattern ended with (?(VERSION=n.d where n is any number but d is just a
+single digit, the code unit beyond d was being read (i.e. there was a read
+buffer overflow). Fixes ClusterFuzz 23779.
+
+9. After the rework in r1235, certain character ranges were incorrectly
+handled by an optimization in JIT. Furthermore a wrong offset was used to
+read a value from a buffer which could lead to memory overread.
+
+10. Unnoticed for many years was the fact that delimiters other than / in the
+testinput1 and testinput4 files could cause incorrect behaviour when these
+files were processed by perltest.sh. There were several tests that used quotes
+as delimiters, and it was just luck that they didn't go wrong with perltest.sh.
+All the patterns in testinput1 and testinput4 now use / as their delimiter.
+This fixes Bugzilla #2641.
+
+11. Perl has started to give an error for \K within lookarounds (though there
+are cases where it doesn't). PCRE2 still allows this, so the tests that include
+this case have been moved from test 1 to test 2.
+
+12. Further to 10 above, pcre2test has been updated to detect and grumble if a
+delimiter other than / is used after #perltest.
+
+13. Fixed a bug with PCRE2_MATCH_INVALID_UTF in 8-bit mode when PCRE2_CASELESS
+was set and PCRE2_NO_START_OPTIMIZE was not set. The optimization for finding
+the start of a match was not resetting correctly after a failed match on the
+first valid fragment of the subject, possibly causing incorrect "no match"
+returns on subsequent fragments. For example, the pattern /A/ failed to match
+the subject \xe5A. Fixes Bugzilla #2642.
+
+14. Fixed a bug in character set matching when JIT is enabled and both unicode
+scripts and unicode classes are present at the same time.
+
+15. Added GNU grep's -m (aka --max-count) option to pcre2grep.
+
+16. Refactored substitution processing in pcre2grep strings, both for the -O
+option and when dealing with callouts. There is now a single function that
+handles $ expansion in all cases (instead of multiple copies of almost
+identical code). This means that the same escape sequences are available
+everywhere, which was not previously the case. At the same time, the escape
+sequences $x{...} and $o{...} have been introduced, to allow for characters
+whose code points are greater than 255 in Unicode mode.
+
+17. Applied the patch from Bugzilla #2628 to RunGrepTest. This does an explicit
+test for a version of sed that can handle binary zero, instead of assuming that
+any Linux version will work. Later: replaced $(...) by `...` because not all
+shells recognize the former.
+
+18. Fixed a word boundary check bug in JIT when partial matching is enabled.
+
+19. Fix ARM64 compilation warning in JIT. Patch by Carlo.
+
+20. A bug in the RunTest script meant that if the first part of test 2 failed,
+the failure was not reported.
+
+21. Test 2 was failing when run from a directory other than the source
+directory. This failure was previously missed in RunTest because of 20 above.
+Fixes added to both RunTest and RunTest.bat.
+
+22. Patch to CMakeLists.txt from Daniel to fix problem with testing under
+Windows.
+
+
Version 10.35 09-May-2020
---------------------------
diff --git a/LICENCE b/LICENCE
index 1568be3..155d073 100644
--- a/LICENCE
+++ b/LICENCE
@@ -20,8 +20,8 @@ THE BASIC LIBRARY FUNCTIONS
---------------------------
Written by: Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
+Email local part: Philip.Hazel
+Email domain: gmail.com
University of Cambridge Computing Service,
Cambridge, England.
diff --git a/Makefile.am b/Makefile.am
index bb888f2..bd8e6f0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -391,6 +391,7 @@ nodist_libpcre2_8_la_SOURCES = \
libpcre2_8_la_CFLAGS = \
-DPCRE2_CODE_UNIT_WIDTH=8 \
$(VISIBILITY_CFLAGS) \
+ $(CET_CFLAGS) \
$(AM_CFLAGS)
libpcre2_8_la_LIBADD =
endif # WITH_PCRE2_8
@@ -404,6 +405,7 @@ nodist_libpcre2_16_la_SOURCES = \
libpcre2_16_la_CFLAGS = \
-DPCRE2_CODE_UNIT_WIDTH=16 \
$(VISIBILITY_CFLAGS) \
+ $(CET_CFLAGS) \
$(AM_CFLAGS)
libpcre2_16_la_LIBADD =
endif # WITH_PCRE2_16
@@ -417,6 +419,7 @@ nodist_libpcre2_32_la_SOURCES = \
libpcre2_32_la_CFLAGS = \
-DPCRE2_CODE_UNIT_WIDTH=32 \
$(VISIBILITY_CFLAGS) \
+ $(CET_CFLAGS) \
$(AM_CFLAGS)
libpcre2_32_la_LIBADD =
endif # WITH_PCRE2_32
@@ -445,15 +448,15 @@ EXTRA_DIST += \
src/sljit/sljitNativePPC_32.c \
src/sljit/sljitNativePPC_64.c \
src/sljit/sljitNativePPC_common.c \
+ src/sljit/sljitNativeS390X.c \
src/sljit/sljitNativeSPARC_32.c \
src/sljit/sljitNativeSPARC_common.c \
- src/sljit/sljitNativeTILEGX-encoder.c \
- src/sljit/sljitNativeTILEGX_64.c \
src/sljit/sljitNativeX86_32.c \
src/sljit/sljitNativeX86_64.c \
src/sljit/sljitNativeX86_common.c \
src/sljit/sljitProtExecAllocator.c \
- src/sljit/sljitUtils.c
+ src/sljit/sljitUtils.c \
+ src/sljit/sljitWXExecAllocator.c
# Some of the JIT sources are also in separate files that are #included.
diff --git a/Makefile.in b/Makefile.in
index 2873912..350ef05 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -806,6 +806,7 @@ AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
+CET_CFLAGS = @CET_CFLAGS@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
@@ -846,6 +847,7 @@ LIBREADLINE = @LIBREADLINE@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBZ = @LIBZ@
+LIB_POSTFIX = @LIB_POSTFIX@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
@@ -1208,32 +1210,30 @@ EXTRA_DIST = m4/ax_pthread.m4 m4/pcre2_visibility.m4 \
src/sljit/sljitNativeMIPS_32.c src/sljit/sljitNativeMIPS_64.c \
src/sljit/sljitNativeMIPS_common.c \
src/sljit/sljitNativePPC_32.c src/sljit/sljitNativePPC_64.c \
- src/sljit/sljitNativePPC_common.c \
+ src/sljit/sljitNativePPC_common.c src/sljit/sljitNativeS390X.c \
src/sljit/sljitNativeSPARC_32.c \
src/sljit/sljitNativeSPARC_common.c \
- src/sljit/sljitNativeTILEGX-encoder.c \
- src/sljit/sljitNativeTILEGX_64.c src/sljit/sljitNativeX86_32.c \
- src/sljit/sljitNativeX86_64.c \
+ src/sljit/sljitNativeX86_32.c src/sljit/sljitNativeX86_64.c \
src/sljit/sljitNativeX86_common.c \
src/sljit/sljitProtExecAllocator.c src/sljit/sljitUtils.c \
- src/pcre2_jit_match.c src/pcre2_jit_misc.c \
- src/pcre2_printint.c RunTest.bat $(am__append_33) \
- testdata/grepbinary testdata/grepfilelist testdata/grepinput \
- testdata/grepinput3 testdata/grepinput8 testdata/grepinputM \
- testdata/grepinputv testdata/grepinputx testdata/greplist \
- testdata/grepoutput testdata/grepoutput8 testdata/grepoutputC \
- testdata/grepoutputCN testdata/grepoutputN testdata/greppatN4 \
- testdata/testbtables testdata/testinput1 testdata/testinput2 \
- testdata/testinput3 testdata/testinput4 testdata/testinput5 \
- testdata/testinput6 testdata/testinput7 testdata/testinput8 \
- testdata/testinput9 testdata/testinput10 testdata/testinput11 \
- testdata/testinput12 testdata/testinput13 testdata/testinput14 \
- testdata/testinput15 testdata/testinput16 testdata/testinput17 \
- testdata/testinput18 testdata/testinput19 testdata/testinput20 \
- testdata/testinput21 testdata/testinput22 testdata/testinput23 \
- testdata/testinput24 testdata/testinput25 \
- testdata/testinputEBC testdata/testoutput1 \
- testdata/testoutput2 testdata/testoutput3 \
+ src/sljit/sljitWXExecAllocator.c src/pcre2_jit_match.c \
+ src/pcre2_jit_misc.c src/pcre2_printint.c RunTest.bat \
+ $(am__append_33) testdata/grepbinary testdata/grepfilelist \
+ testdata/grepinput testdata/grepinput3 testdata/grepinput8 \
+ testdata/grepinputM testdata/grepinputv testdata/grepinputx \
+ testdata/greplist testdata/grepoutput testdata/grepoutput8 \
+ testdata/grepoutputC testdata/grepoutputCN \
+ testdata/grepoutputN testdata/greppatN4 testdata/testbtables \
+ testdata/testinput1 testdata/testinput2 testdata/testinput3 \
+ testdata/testinput4 testdata/testinput5 testdata/testinput6 \
+ testdata/testinput7 testdata/testinput8 testdata/testinput9 \
+ testdata/testinput10 testdata/testinput11 testdata/testinput12 \
+ testdata/testinput13 testdata/testinput14 testdata/testinput15 \
+ testdata/testinput16 testdata/testinput17 testdata/testinput18 \
+ testdata/testinput19 testdata/testinput20 testdata/testinput21 \
+ testdata/testinput22 testdata/testinput23 testdata/testinput24 \
+ testdata/testinput25 testdata/testinputEBC \
+ testdata/testoutput1 testdata/testoutput2 testdata/testoutput3 \
testdata/testoutput3A testdata/testoutput3B \
testdata/testoutput4 testdata/testoutput5 testdata/testoutput6 \
testdata/testoutput7 testdata/testoutput8-16-2 \
@@ -1310,8 +1310,9 @@ COMMON_SOURCES = \
@WITH_PCRE2_8_TRUE@ $(NODIST_SOURCES)
@WITH_PCRE2_8_TRUE@libpcre2_8_la_CFLAGS = -DPCRE2_CODE_UNIT_WIDTH=8 \
-@WITH_PCRE2_8_TRUE@ $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \
-@WITH_PCRE2_8_TRUE@ $(am__append_5) $(am__append_8)
+@WITH_PCRE2_8_TRUE@ $(VISIBILITY_CFLAGS) $(CET_CFLAGS) \
+@WITH_PCRE2_8_TRUE@ $(AM_CFLAGS) $(am__append_5) \
+@WITH_PCRE2_8_TRUE@ $(am__append_8)
@WITH_PCRE2_8_TRUE@libpcre2_8_la_LIBADD =
@WITH_PCRE2_16_TRUE@libpcre2_16_la_SOURCES = \
@WITH_PCRE2_16_TRUE@ $(COMMON_SOURCES)
@@ -1321,8 +1322,9 @@ COMMON_SOURCES = \
@WITH_PCRE2_16_TRUE@libpcre2_16_la_CFLAGS = \
@WITH_PCRE2_16_TRUE@ -DPCRE2_CODE_UNIT_WIDTH=16 \
-@WITH_PCRE2_16_TRUE@ $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \
-@WITH_PCRE2_16_TRUE@ $(am__append_6) $(am__append_9)
+@WITH_PCRE2_16_TRUE@ $(VISIBILITY_CFLAGS) $(CET_CFLAGS) \
+@WITH_PCRE2_16_TRUE@ $(AM_CFLAGS) $(am__append_6) \
+@WITH_PCRE2_16_TRUE@ $(am__append_9)
@WITH_PCRE2_16_TRUE@libpcre2_16_la_LIBADD =
@WITH_PCRE2_32_TRUE@libpcre2_32_la_SOURCES = \
@WITH_PCRE2_32_TRUE@ $(COMMON_SOURCES)
@@ -1332,8 +1334,9 @@ COMMON_SOURCES = \
@WITH_PCRE2_32_TRUE@libpcre2_32_la_CFLAGS = \
@WITH_PCRE2_32_TRUE@ -DPCRE2_CODE_UNIT_WIDTH=32 \
-@WITH_PCRE2_32_TRUE@ $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \
-@WITH_PCRE2_32_TRUE@ $(am__append_7) $(am__append_10)
+@WITH_PCRE2_32_TRUE@ $(VISIBILITY_CFLAGS) $(CET_CFLAGS) \
+@WITH_PCRE2_32_TRUE@ $(AM_CFLAGS) $(am__append_7) \
+@WITH_PCRE2_32_TRUE@ $(am__append_10)
@WITH_PCRE2_32_TRUE@libpcre2_32_la_LIBADD =
@WITH_PCRE2_8_TRUE@libpcre2_8_la_LDFLAGS = $(EXTRA_LIBPCRE2_8_LDFLAGS)
@WITH_PCRE2_16_TRUE@libpcre2_16_la_LDFLAGS = $(EXTRA_LIBPCRE2_16_LDFLAGS)
diff --git a/NEWS b/NEWS
index 97b9350..de797e7 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,19 @@ News about PCRE2 releases
-------------------------
+Version 10.36 04-December-2020
+------------------------------
+
+Again, mainly bug fixes and tidies. The only enhancements are the addition of
+GNU grep's -m (aka --max-count) option to pcre2grep, and also unifying the
+handling of substitution strings for both -O and callouts in pcre2grep, with
+the addition of $x{...} and $o{...} to allow for characters whose code points
+are greater than 255 in Unicode mode.
+
+NOTE: there is an outstanding issue with JIT support for MacOS on arm64
+hardware. For details, please see Bugzilla issue #2618.
+
+
Version 10.35 15-April-2020
---------------------------
diff --git a/README b/README
index 241376f..1d6df8f 100644
--- a/README
+++ b/README
@@ -297,8 +297,8 @@ library. They are also documented in the pcre2build man page.
unaddressable. This allows it to detect invalid memory accesses, and is
mostly useful for debugging PCRE2 itself.
-. In environments where the gcc compiler is used and lcov version 1.6 or above
- is installed, if you specify
+. In environments where the gcc compiler is used and lcov is installed, if you
+ specify
--enable-coverage
@@ -757,6 +757,15 @@ that represent character classes for code points less than 256. The final
8 decimal digit
16 alphanumeric or '_'
+You can also specify -b (with or without -L) when running pcre2_dftables. This
+causes the tables to be written in binary instead of as source code. A set of
+binary tables can be loaded into memory by an application and passed to
+pcre2_compile() in the same way as tables created dynamically by calling
+pcre2_maketables(). The tables are just a string of bytes, independent of
+hardware characteristics such as endianness. This means they can be bundled
+with an application that runs in different environments, to ensure consistent
+behaviour.
+
See also the pcre2build section "Creating character tables at build time".
@@ -892,6 +901,6 @@ The distribution should contain the files listed below.
) environments
Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
-Last updated: 20 March 2020
+Email local part: Philip.Hazel
+Email domain: gmail.com
+Last updated: 04 December 2020
diff --git a/RunGrepTest b/RunGrepTest
index 2ff4f7c..4d514e4 100755
--- a/RunGrepTest
+++ b/RunGrepTest
@@ -661,6 +661,26 @@ echo "---------------------------- Test 128 -----------------------------" >>tes
(cd $srcdir; $valgrind $vjs $pcre2grep -o1 --om-capture=0 'pattern()()()()' testdata/grepinput) >>testtrygrep 2>&1
echo "RC=$?" >>testtrygrep
+echo "---------------------------- Test 129 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -m 2 'fox' testdata/grepinput) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 130 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -o -m2 'fox' testdata/grepinput) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 131 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -oc -m2 'fox' testdata/grepinput) >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 132 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -m1 -A3 '^match'; echo '---'; head -1) <$srcdir/testdata/grepinput >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
+echo "---------------------------- Test 133 -----------------------------" >>testtrygrep
+(cd $srcdir; $valgrind $vjs $pcre2grep -m1 -O '=$x{41}$x423$o{103}$o1045=' 'fox') <$srcdir/testdata/grepinputv >>testtrygrep 2>&1
+echo "RC=$?" >>testtrygrep
+
# Now compare the results.
$cf $srcdir/testdata/grepoutput testtrygrep
@@ -694,6 +714,10 @@ if [ $utf8 -ne 0 ] ; then
(cd $srcdir; $valgrind $vjs $pcre2grep -U -o '....' $builddir/testtemp1grep) >>testtrygrep
echo "RC=$?" >>testtrygrep
+ echo "---------------------------- Test U6 -----------------------------" >>testtrygrep
+ (cd $srcdir; $valgrind $vjs $pcre2grep -u -m1 -O '=$x{1d3}$o{744}=' 'fox') <$srcdir/testdata/grepinputv >>testtrygrep 2>&1
+ echo "RC=$?" >>testtrygrep
+
$cf $srcdir/testdata/grepoutput8 testtrygrep
if [ $? != 0 ] ; then exit 1; fi
@@ -733,22 +757,20 @@ $valgrind $vjs $pcre2grep -n --newline=anycrlf "^(abc|def|ghi|jkl)" testNinputgr
# It seems impossible to handle NUL characters easily in many operating
# systems, including Solaris (aka SunOS), where the version of sed explicitly
-# doesn't like them, and also MacOS (Darwin), OpenBSD, FreeBSD, and NetBSD. So
-# now we run this test only on OS that are known to work. For the rest, we
-# fudge the output so that the comparison works.
+# doesn't like them, and also MacOS (Darwin), OpenBSD, FreeBSD, NetBSD, and
+# some Linux distributions like Alpine, even when using GNU sed, so test for
+# a usable sed and fudge the output so that the comparison works when sed
+# doesn't.
printf '%c--------------------------- Test N7 ------------------------------\r\n' - >>testtrygrep
-uname=`uname`
-case $uname in
- Linux)
- printf 'abc\0def' >testNinputgrep
- $valgrind $vjs $pcre2grep -na --newline=nul "^(abc|def)" testNinputgrep | sed 's/\x00/ZERO/g' >>testtrygrep
- echo "" >>testtrygrep
- ;;
- *)
- echo '1:abcZERO2:defZERO' >>testtrygrep
- ;;
-esac
+Z=`printf '\0' | sed 's/\x00/Z/g'`
+if [ "$Z" = "Z" ]; then
+ printf 'abc\0def' >testNinputgrep
+ $valgrind $vjs $pcre2grep -na --newline=nul "^(abc|def)" testNinputgrep | sed 's/\x00/ZERO/g' >>testtrygrep
+ echo "" >>testtrygrep
+else
+ echo '1:abcZERO2:defZERO' >>testtrygrep
+fi
$cf $srcdir/testdata/grepoutputN testtrygrep
if [ $? != 0 ] ; then exit 1; fi
@@ -764,6 +786,7 @@ if $valgrind $vjs $pcre2grep --help | $valgrind $vjs $pcre2grep -q 'callout scri
$valgrind $vjs $pcre2grep '(T)(..(.))()()()()()()()(..)(?C"/bin/echo|Arg1: [$11] [${11}]")' $srcdir/testdata/grepinputv >>testtrygrep
$valgrind $vjs $pcre2grep '(T)(?C"|$0:$1$n")' $srcdir/testdata/grepinputv >>testtrygrep
$valgrind $vjs $pcre2grep '(T)(?C"|$1$n")(*F)' $srcdir/testdata/grepinputv >>testtrygrep
+ $valgrind $vjs $pcre2grep -m1 '(T)(?C"|$0:$1:$x{41}$o{101}$n")' $srcdir/testdata/grepinputv >>testtrygrep
if $valgrind $vjs $pcre2grep --help | $valgrind $vjs $pcre2grep -q 'Non-fork callout scripts in patterns are supported'; then
$cf $srcdir/testdata/grepoutputCN testtrygrep
diff --git a/RunTest b/RunTest
index 6715d15..14d9f60 100755
--- a/RunTest
+++ b/RunTest
@@ -493,15 +493,20 @@ for bmode in "$test8" "$test16" "$test32"; do
done
fi
- # PCRE2 tests that are not Perl-compatible: API, errors, internals
+ # PCRE2 tests that are not Perl-compatible: API, errors, internals. We copy
+ # the testbtables file to the current directory for use by this test.
if [ $do2 = yes ] ; then
echo $title2 "(excluding UTF-$bits)"
+ cp $testdata/testbtables .
for opt in "" $jitopt; do
$sim $valgrind ${opt:+$vjs} ./pcre2test -q $setstack $bmode $opt $testdata/testinput2 testtry
- if [ $? = 0 ] ; then
+ saverc=$?
+ if [ $saverc = 0 ] ; then
$sim $valgrind ${opt:+$vjs} ./pcre2test -q $bmode $opt -error -70,-62,-2,-1,0,100,101,191,200 >>testtry
checkresult $? 2 "$opt"
+ else
+ checkresult $saverc 2 "$opt"
fi
done
fi
@@ -859,6 +864,6 @@ for bmode in "$test8" "$test16" "$test32"; do
done
# Clean up local working files
-rm -f testSinput test3input testsaved1 testsaved2 test3output test3outputA test3outputB teststdout teststderr testtry
+rm -f testbtables testSinput test3input testsaved1 testsaved2 test3output test3outputA test3outputB teststdout teststderr testtry
# End
diff --git a/RunTest.bat b/RunTest.bat
index 9474434..791f265 100644
--- a/RunTest.bat
+++ b/RunTest.bat
@@ -26,6 +26,7 @@
@rem Updated for new test 14 (moving others up a number), August 2015.
@rem Tidied and updated for new tests 21, 22, 23 by PH, October 2015.
@rem PH added missing "set type" for test 22, April 2016.
+@rem PH added copy command for new testbtables file, November 2020
setlocal enabledelayedexpansion
@@ -305,6 +306,7 @@ if %jit% EQU 1 call :runsub 1 testoutjit "Test with JIT Override" -q -jit
goto :eof
:do2
+ copy /y %srcdir%\testdata\testbtables testbtables
call :runsub 2 testout "API, errors, internals, and non-Perl stuff" -q
if %jit% EQU 1 call :runsub 2 testoutjit "Test with JIT Override" -q -jit
goto :eof
diff --git a/configure b/configure
index 615f638..c22d3ab 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for PCRE2 10.35.
+# Generated by GNU Autoconf 2.69 for PCRE2 10.36.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='PCRE2'
PACKAGE_TARNAME='pcre2'
-PACKAGE_VERSION='10.35'
-PACKAGE_STRING='PCRE2 10.35'
+PACKAGE_VERSION='10.36'
+PACKAGE_STRING='PCRE2 10.36'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -633,6 +633,8 @@ ac_subst_vars='am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
+LIB_POSTFIX
+CET_CFLAGS
WITH_GCOV_FALSE
WITH_GCOV_TRUE
GCOV_LIBS
@@ -1413,7 +1415,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.35 to adapt to many kinds of systems.
+\`configure' configures PCRE2 10.36 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1483,7 +1485,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of PCRE2 10.35:";;
+ short | recursive ) echo "Configuration of PCRE2 10.36:";;
esac
cat <<\_ACEOF
@@ -1663,7 +1665,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-PCRE2 configure 10.35
+PCRE2 configure 10.36
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2158,7 +2160,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.35, which was
+It was created by PCRE2 $as_me 10.36, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3022,7 +3024,7 @@ fi
# Define the identity of the package.
PACKAGE='pcre2'
- VERSION='10.35'
+ VERSION='10.36'
cat >>confdefs.h <<_ACEOF
@@ -13026,9 +13028,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
# Versioning
PCRE2_MAJOR="10"
-PCRE2_MINOR="35"
+PCRE2_MINOR="36"
PCRE2_PRERELEASE=""
-PCRE2_DATE="2020-05-09"
+PCRE2_DATE="2020-12-04"
if test "$PCRE2_MINOR" = "08" -o "$PCRE2_MINOR" = "09"
then
@@ -15024,13 +15026,13 @@ esac
# are m4 variables, assigned above.
EXTRA_LIBPCRE2_8_LDFLAGS="$EXTRA_LIBPCRE2_8_LDFLAGS \
- $NO_UNDEFINED -version-info 10:0:10"
+ $NO_UNDEFINED -version-info 10:1:10"
EXTRA_LIBPCRE2_16_LDFLAGS="$EXTRA_LIBPCRE2_16_LDFLAGS \
- $NO_UNDEFINED -version-info 10:0:10"
+ $NO_UNDEFINED -version-info 10:1:10"
EXTRA_LIBPCRE2_32_LDFLAGS="$EXTRA_LIBPCRE2_32_LDFLAGS \
- $NO_UNDEFINED -version-info 10:0:10"
+ $NO_UNDEFINED -version-info 10:1:10"
EXTRA_LIBPCRE2_POSIX_LDFLAGS="$EXTRA_LIBPCRE2_POSIX_LDFLAGS \
$NO_UNDEFINED -version-info 2:3:0"
@@ -15493,7 +15495,52 @@ else
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Intel CET is enabled" >&5
+$as_echo_n "checking whether Intel CET is enabled... " >&6; }
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __CET__
+# error CET is not enabled
+#endif
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ pcre2_cc_cv_intel_cet_enabled=yes
+else
+ pcre2_cc_cv_intel_cet_enabled=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pcre2_cc_cv_intel_cet_enabled" >&5
+$as_echo "$pcre2_cc_cv_intel_cet_enabled" >&6; }
+if test "$pcre2_cc_cv_intel_cet_enabled" = yes; then
+ CET_CFLAGS="-mshstk"
+
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+# LIB_POSTFIX is used by CMakeLists.txt for Windows debug builds.
+# Pass empty LIB_POSTFIX to *.pc files and pcre2-config here.
+
+
# Produce these files, in addition to config.h.
+
ac_config_files="$ac_config_files Makefile libpcre2-8.pc libpcre2-16.pc libpcre2-32.pc libpcre2-posix.pc pcre2-config src/pcre2.h"
@@ -16076,7 +16123,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.35, which was
+This file was extended by PCRE2 $as_me 10.36, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -16142,7 +16189,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-PCRE2 config.status 10.35
+PCRE2 config.status 10.36
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 180d3dc..af26f0b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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, [35])
+m4_define(pcre2_minor, [36])
m4_define(pcre2_prerelease, [])
-m4_define(pcre2_date, [2020-05-09])
+m4_define(pcre2_date, [2020-12-04])
# Libtool shared library interface versions (current:revision:age)
-m4_define(libpcre2_8_version, [10:0:10])
-m4_define(libpcre2_16_version, [10:0:10])
-m4_define(libpcre2_32_version, [10:0:10])
+m4_define(libpcre2_8_version, [10:1:10])
+m4_define(libpcre2_16_version, [10:1:10])
+m4_define(libpcre2_32_version, [10:1:10])
m4_define(libpcre2_posix_version, [2:3:0])
# NOTE: The CMakeLists.txt file searches for the above variables in the first
@@ -1006,7 +1006,27 @@ fi # enable_coverage
AM_CONDITIONAL([WITH_GCOV],[test "x$enable_coverage" = "xyes"])
+AC_MSG_CHECKING([whether Intel CET is enabled])
+AC_LANG_PUSH([C])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,
+ [[#ifndef __CET__
+# error CET is not enabled
+#endif]])],
+ [pcre2_cc_cv_intel_cet_enabled=yes],
+ [pcre2_cc_cv_intel_cet_enabled=no])
+AC_MSG_RESULT([$pcre2_cc_cv_intel_cet_enabled])
+if test "$pcre2_cc_cv_intel_cet_enabled" = yes; then
+ CET_CFLAGS="-mshstk"
+ AC_SUBST([CET_CFLAGS])
+fi
+AC_LANG_POP([C])
+
+# LIB_POSTFIX is used by CMakeLists.txt for Windows debug builds.
+# Pass empty LIB_POSTFIX to *.pc files and pcre2-config here.
+AC_SUBST(LIB_POSTFIX)
+
# Produce these files, in addition to config.h.
+
AC_CONFIG_FILES(
Makefile
libpcre2-8.pc
diff --git a/doc/html/README.txt b/doc/html/README.txt
index 241376f..1d6df8f 100644
--- a/doc/html/README.txt
+++ b/doc/html/README.txt
@@ -297,8 +297,8 @@ library. They are also documented in the pcre2build man page.
unaddressable. This allows it to detect invalid memory accesses, and is
mostly useful for debugging PCRE2 itself.
-. In environments where the gcc compiler is used and lcov version 1.6 or above
- is installed, if you specify
+. In environments where the gcc compiler is used and lcov is installed, if you
+ specify
--enable-coverage
@@ -757,6 +757,15 @@ that represent character classes for code points less than 256. The final
8 decimal digit
16 alphanumeric or '_'
+You can also specify -b (with or without -L) when running pcre2_dftables. This
+causes the tables to be written in binary instead of as source code. A set of
+binary tables can be loaded into memory by an application and passed to
+pcre2_compile() in the same way as tables created dynamically by calling
+pcre2_maketables(). The tables are just a string of bytes, independent of
+hardware characteristics such as endianness. This means they can be bundled
+with an application that runs in different environments, to ensure consistent
+behaviour.
+
See also the pcre2build section "Creating character tables at build time".
@@ -892,6 +901,6 @@ The distribution should contain the files listed below.
) environments
Philip Hazel
-Email local part: ph10
-Email domain: cam.ac.uk
-Last updated: 20 March 2020
+Email local part: Philip.Hazel
+Email domain: gmail.com
+Last updated: 04 December 2020
diff --git a/doc/html/pcre2api.html b/doc/html/pcre2api.html
index 36c2e3d..4ca0eb0 100644
--- a/doc/html/pcre2api.html
+++ b/doc/html/pcre2api.html
@@ -626,14 +626,15 @@ documentation for more details.
<P>
In a more complicated situation, where patterns are compiled only when they are
first needed, but are still shared between threads, pointers to compiled
-patterns must be protected from simultaneous writing by multiple threads, at
-least until a pattern has been compiled. The logic can be something like this:
+patterns must be protected from simultaneous writing by multiple threads. This
+is somewhat tricky to do correctly. If you know that writing to a pointer is
+atomic in your environment, you can use logic like this:
<pre>
Get a read-only (shared) lock (mutex) for pointer
if (pointer == NULL)
{
Get a write (unique) lock for pointer
- pointer = pcre2_compile(...
+ if (pointer == NULL) pointer = pcre2_compile(...
}
Release the lock
Use pointer in pcre2_match()
@@ -641,10 +642,39 @@ least until a pattern has been compiled. The logic can be something like this:
Of course, testing for compilation errors should also be included in the code.
</P>
<P>
-If JIT is being used, but the JIT compilation is not being done immediately,
-(perhaps waiting to see if the pattern is used often enough) similar logic is
-required. JIT compilation updates a pointer within the compiled code block, so
-a thread must gain unique write access to the pointer before calling
+The reason for checking the pointer a second time is as follows: Several
+threads may have acquired the shared lock and tested the pointer for being
+NULL, but only one of them will be given the write lock, with the rest kept
+waiting. The winning thread will compile the pattern and store the result.
+After this thread releases the write lock, another thread will get it, and if
+it does not retest pointer for being NULL, will recompile the pattern and
+overwrite the pointer, creating a memory leak and possibly causing other
+issues.
+</P>
+<P>
+In an environment where writing to a pointer may not be atomic, the above logic
+is not sufficient. The thread that is doing the compiling may be descheduled
+after writing only part of the pointer, which could cause other threads to use
+an invalid value. Instead of checking the pointer itself, a separate "pointer
+is valid" flag (that can be updated atomically) must be used:
+<pre>
+ Get a read-only (shared) lock (mutex) for pointer
+ if (!pointer_is_valid)
+ {
+ Get a write (unique) lock for pointer
+ if (!pointer_is_valid)
+ {
+ pointer = pcre2_compile(...
+ pointer_is_valid = TRUE
+ }
+ }
+ Release the lock
+ Use pointer in pcre2_match()
+</pre>
+If JIT is being used, but the JIT compilation is not being done immediately
+(perhaps waiting to see if the pattern is used often enough), similar logic is
+required. JIT compilation updates a value within the compiled code block, so a
+thread must gain unique write access to the pointer before calling
<b>pcre2_jit_compile()</b>. Alternatively, <b>pcre2_code_copy()</b> or
<b>pcre2_code_copy_with_tables()</b> can be used to obtain a private copy of the
compiled code before calling the JIT compiler.
@@ -1492,10 +1522,13 @@ letters in the subject. It is equivalent to Perl's /i option, and it can be
changed within a pattern by a (?i) option setting. If either PCRE2_UTF or
PCRE2_UCP is set, Unicode properties are used for all characters with more than
one other case, and for all characters whose code points are greater than
-U+007F. For lower valued characters with only one other case, a lookup table is
-used for speed. When neither PCRE2_UTF nor PCRE2_UCP is set, a lookup table is
-used for all code points less than 256, and higher code points (available only
-in 16-bit or 32-bit mode) are treated as not having another case.
+U+007F. Note that there are two ASCII characters, K and S, that, in addition to
+their lower case ASCII equivalents, are case-equivalent with U+212A (Kelvin
+sign) and U+017F (long S) respectively. For lower valued characters with only
+one other case, a lookup table is used for speed. When neither PCRE2_UTF nor
+PCRE2_UCP is set, a lookup table is used for all code points less than 256, and
+higher code points (available only in 16-bit or 32-bit mode) are treated as not
+having another case.
<pre>
PCRE2_DOLLAR_ENDONLY
</pre>
@@ -3956,7 +3989,7 @@ Cambridge, England.
</P>
<br><a name="SEC42" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 19 March 2020
+Last updated: 04 November 2020
<br>
Copyright &copy; 1997-2020 University of Cambridge.
<br>
diff --git a/doc/html/pcre2compat.html b/doc/html/pcre2compat.html
index 0c72a9a..54fb643 100644
--- a/doc/html/pcre2compat.html
+++ b/doc/html/pcre2compat.html
@@ -16,10 +16,10 @@ please consult the man page, in case the conversion went wrong.
DIFFERENCES BETWEEN PCRE2 AND PERL
</b><br>
<P>
-This document describes the differences in the ways that PCRE2 and Perl handle
-regular expressions. The differences described here are with respect to Perl
-versions 5.26, but as both Perl and PCRE2 are continually changing, the
-information may sometimes be out of date.
+This document describes some of the differences in the ways that PCRE2 and Perl
+handle regular expressions. The differences described here are with respect to
+Perl version 5.32.0, but as both Perl and PCRE2 are continually changing, the
+information may at times be out of date.
</P>
<P>
1. PCRE2 has only a subset of Perl's Unicode support. Details of what it does
@@ -33,12 +33,15 @@ they do not mean what you might think. For example, (?!a){3} does not assert
that the next three characters are not "a". It just asserts that the next
character is not "a" three times (in principle; PCRE2 optimizes this to run the
assertion just once). Perl allows some repeat quantifiers on other assertions,
-for example, \b* (but not \b{3}), but these do not seem to have any use.
+for example, \b* (but not \b{3}, though oddly it does allow ^{3}), but these
+do not seem to have any use. PCRE2 does not allow any kind of quantifier on
+non-lookaround assertions.
</P>
<P>
3. Capture groups that occur inside negative lookaround assertions are counted,
but their entries in the offsets vector are set only when a negative assertion
is a condition that has a matching branch (that is, the condition is false).
+Perl may set such capture groups in other circumstances.
</P>
<P>
4. The following Perl escape sequences are not supported: \F, \l, \L, \u,
@@ -56,10 +59,12 @@ interprets them.
built with Unicode support (the default). The properties that can be tested
with \p and \P are limited to the general category properties such as Lu and
Nd, script names such as Greek or Han, and the derived properties Any and L&.
-PCRE2 does support the Cs (surrogate) property, which Perl does not; the Perl
-documentation says "Because Perl hides the need for the user to understand the
-internal representation of Unicode characters, there is no need to implement
-the somewhat messy concept of surrogates."
+Both PCRE2 and Perl support the Cs (surrogate) property, but in PCRE2 its use
+is limited. See the
+<a href="pcre2pattern.html"><b>pcre2pattern</b></a>
+documentation for details. The long synonyms for property names that Perl
+supports (such as \p{Letter}) are not supported by PCRE2, nor is it permitted
+to prefix any of these properties with "Is".
</P>
<P>
6. PCRE2 supports the \Q...\E escape for quoting substrings. Characters
@@ -79,7 +84,8 @@ other character. Note the following examples:
\QA\B\E A\B A\B
\Q\\E \ \\E
</pre>
-The \Q...\E sequence is recognized both inside and outside character classes.
+The \Q...\E sequence is recognized both inside and outside character classes
+by both PCRE2 and Perl.
</P>
<P>
7. Fairly obviously, PCRE2 does not support the (?{code}) and (??{code})
@@ -94,13 +100,13 @@ to PCRE2 release 10.23, but from release 10.30 this changed, and backtracking
into subroutine calls is now supported, as in Perl.
</P>
<P>
-9. If any of the backtracking control verbs are used in a group that is called
-as a subroutine (whether or not recursively), their effect is confined to that
-group; it does not extend to the surrounding pattern. This is not always the
-case in Perl. In particular, if (*THEN) is present in a group that is called as
-a subroutine, its action is limited to that group, even if the group does not
-contain any | characters. Note that such groups are processed as anchored
-at the point where they are tested.
+9. In PCRE2, if any of the backtracking control verbs are used in a group that
+is called as a subroutine (whether or not recursively), their effect is
+confined to that group; it does not extend to the surrounding pattern. This is
+not always the case in Perl. In particular, if (*THEN) is present in a group
+that is called as a subroutine, its action is limited to that group, even if
+the group does not contain any | characters. Note that such groups are
+processed as anchored at the point where they are tested.
</P>
<P>
10. If a pattern contains more than one backtracking control verb, the first
@@ -110,55 +116,56 @@ triggers (*PRUNE). Perl's behaviour is more complex; in many cases it is the
same as PCRE2, but there are cases where it differs.
</P>
<P>
-11. Most backtracking verbs in assertions have their normal actions. They are
-not confined to the assertion.
-</P>
-<P>
-12. There are some differences that are concerned with the settings of captured
+11. There are some differences that are concerned with the settings of captured
strings when part of a pattern is repeated. For example, matching "aba" against
the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE2 it is set to
"b".
</P>
<P>
-13. PCRE2's handling of duplicate capture group numbers and names is not as
+12. PCRE2's handling of duplicate capture group numbers and names is not as
general as Perl's. This is a consequence of the fact the PCRE2 works internally
just with numbers, using an external table to translate between numbers and
-names. In particular, a pattern such as (?|(?&#60;a&#62;A)|(?&#60;b&#62;B), where the two
+names. In particular, a pattern such as (?|(?&#60;a&#62;A)|(?&#60;b&#62;B)), where the two
capture groups have the same number but different names, is not supported, and
causes an error at compile time. If it were allowed, it would not be possible
to distinguish which group matched, because both names map to capture group
number 1. To avoid this confusing situation, an error is given at compile time.
</P>
<P>
-14. Perl used to recognize comments in some places that PCRE2 does not, for
+13. Perl used to recognize comments in some places that PCRE2 does not, for
example, between the ( and ? at the start of a group. If the /x modifier is
set, Perl allowed white space between ( and ? though the latest Perls give an
error (for a while it was just deprecated). There may still be some cases where
Perl behaves differently.
</P>
<P>
-15. Perl, when in warning mode, gives warnings for character classes such as
+14. Perl, when in warning mode, gives warnings for character classes such as
[A-\d] or [a-[:digit:]]. It then treats the hyphens as literals. PCRE2 has no
warning features, so it gives an error in these cases because they are almost
certainly user mistakes.
</P>
<P>
-16. In PCRE2, the upper/lower case character properties Lu and Ll are not
+15. In PCRE2, the upper/lower case character properties Lu and Ll are not
affected when case-independent matching is specified. For example, \p{Lu}
always matches an upper case letter. I think Perl has changed in this respect;
-in the release at the time of writing (5.24), \p{Lu} and \p{Ll} match all
+in the release at the time of writing (5.32), \p{Lu} and \p{Ll} match all
letters, regardless of case, when case independence is specified.
</P>
<P>
+16. From release 5.32.0, Perl locks out the use of \K in lookaround
+assertions. In PCRE2, \K is acted on when it occurs in positive assertions,
+but is ignored in negative assertions.
+</P>
+<P>
17. PCRE2 provides some extensions to the Perl regular expression facilities.
-Perl 5.10 includes new features that are not in earlier versions of Perl, some
+Perl 5.10 included new features that were not in earlier versions of Perl, some
of which (such as named parentheses) were in PCRE2 for some time before. This
-list is with respect to Perl 5.26:
+list is with respect to Perl 5.32:
<br>
<br>
(a) Although lookbehind assertions in PCRE2 must match fixed length strings,
-each alternative branch of a lookbehind assertion can match a different length
-of string. Perl requires them all to have the same length.
+each alternative toplevel branch of a lookbehind assertion can match a
+different length of string. Perl requires them all to have the same length.
<br>
<br>
(b) From PCRE2 10.23, backreferences to groups of fixed length are supported
@@ -203,7 +210,7 @@ different way and is not Perl-compatible.
<br>
<br>
(l) PCRE2 recognizes some special sequences such as (*CR) or (*NO_JIT) at
-the start of a pattern that set overall options that cannot be changed within
+the start of a pattern. These set overall options that cannot be changed within
the pattern.
<br>
<br>
@@ -239,7 +246,7 @@ Cambridge, England.
REVISION
</b><br>
<P>
-Last updated: 13 July 2019
+Last updated: 06 October 2020
<br>
Copyright &copy; 1997-2019 University of Cambridge.
<br>
diff --git a/doc/html/pcre2grep.html b/doc/html/pcre2grep.html
index 0b2f241..995e0ea 100644
--- a/doc/html/pcre2grep.html
+++ b/doc/html/pcre2grep.html
@@ -111,8 +111,8 @@ matching substrings, or if <b>--only-matching</b>, <b>--file-offsets</b>, or
(either shown literally, or as an offset), scanning resumes immediately
following the match, so that further matches on the same line can be found. If
there are multiple patterns, they are all tried on the remainder of the line,
-but patterns that follow the one that matched are not tried on the earlier part
-of the line.
+but patterns that follow the one that matched are not tried on the earlier
+matched part of the line.
</P>
<P>
This behaviour means that the order in which multiple patterns are specified
@@ -146,11 +146,10 @@ ignored.
<br><a name="SEC4" href="#TOC1">BINARY FILES</a><br>
<P>
By default, a file that contains a binary zero byte within the first 1024 bytes
-is identified as a binary file, and is processed specially. (GNU grep
-identifies binary files in this manner.) However, if the newline type is
-specified as NUL, that is, the line terminator is a binary zero, the test for
-a binary file is not applied. See the <b>--binary-files</b> option for a means
-of changing the way binary files are handled.
+is identified as a binary file, and is processed specially. However, if the
+newline type is specified as NUL, that is, the line terminator is a binary
+zero, the test for a binary file is not applied. See the <b>--binary-files</b>
+option for a means of changing the way binary files are handled.
</P>
<br><a name="SEC5" href="#TOC1">BINARY ZEROS IN PATTERNS</a><br>
<P>
@@ -443,8 +442,8 @@ Ignore upper/lower case distinctions during comparisons.
<P>
<b>--include</b>=<i>pattern</i>
If any <b>--include</b> patterns are specified, the only files that are
-processed are those that match one of the patterns (and do not match an
-<b>--exclude</b> pattern). This option does not affect directories, but it
+processed are those whose names match one of the patterns and do not match an
+<b>--exclude</b> pattern. This option does not affect directories, but it
applies to all files, whether listed on the command line, obtained from
<b>--file-list</b>, or by scanning a directory. The pattern is a PCRE2 regular
expression, and is matched against the final component of the file name, not
@@ -463,8 +462,8 @@ may be given any number of times; all the files are read.
<P>
<b>--include-dir</b>=<i>pattern</i>
If any <b>--include-dir</b> patterns are specified, the only directories that
-are processed are those that match one of the patterns (and do not match an
-<b>--exclude-dir</b> pattern). This applies to all directories, whether listed
+are processed are those whose names match one of the patterns and do not match
+an <b>--exclude-dir</b> pattern. This applies to all directories, whether listed
on the command line, obtained from <b>--file-list</b>, or by scanning a parent
directory. The pattern is a PCRE2 regular expression, and is matched against
the final component of the directory name, not the entire path. The <b>-F</b>,
@@ -487,8 +486,9 @@ a separate line. Searching normally stops as soon as a matching line is found
in a file. However, if the <b>-c</b> (count) option is also used, matching
continues in order to obtain the correct count, and those files that have at
least one match are listed along with their counts. Using this option with
-<b>-c</b> is a way of suppressing the listing of files with no matches. This
-opeion overrides any previous <b>-H</b>, <b>-h</b>, or <b>-L</b> options.
+<b>-c</b> is a way of suppressing the listing of files with no matches that
+occurs with <b>-c</b> on its own. This option overrides any previous <b>-H</b>,
+<b>-h</b>, or <b>-L</b> options.
</P>
<P>
<b>--label</b>=<i>name</i>
@@ -501,8 +501,8 @@ short form for this option.
When this option is given, non-compressed input is read and processed line by
line, and the output is flushed after each write. By default, input is read in
large chunks, unless <b>pcre2grep</b> can determine that it is reading from a
-terminal (which is currently possible only in Unix-like environments or
-Windows). Output to terminal is normally automatically flushed by the operating
+terminal, which is currently possible only in Unix-like environments or
+Windows. Output to terminal is normally automatically flushed by the operating
system. This option can be useful when the input or output is attached to a
pipe and you do not want <b>pcre2grep</b> to buffer up large amounts of data.
However, its use will affect performance, and the <b>-M</b> (multiline) option
@@ -528,6 +528,49 @@ locale is specified, the PCRE2 library's default (usually the "C" locale) is
used. There is no short form for this option.
</P>
<P>
+<b>-M</b>, <b>--multiline</b>
+Allow patterns to match more than one line. When this option is set, the PCRE2
+library is called in "multiline" mode. This allows a matched string to extend
+past the end of a line and continue on one or more subsequent lines. Patterns
+used with <b>-M</b> may usefully contain literal newline characters and internal
+occurrences of ^ and $ characters. The output for a successful match may
+consist of more than one line. The first line is the line in which the match
+started, and the last line is the line in which the match ended. If the matched
+string ends with a newline sequence, the output ends at the end of that line.
+If <b>-v</b> is set, none of the lines in a multi-line match are output. Once a
+match has been handled, scanning restarts at the beginning of the line after
+the one in which the match ended.
+<br>
+<br>
+The newline sequence that separates multiple lines must be matched as part of
+the pattern. For example, to find the phrase "regular expression" in a file
+where "regular" might be at the end of a line and "expression" at the start of
+the next line, you could use this command:
+<pre>
+ pcre2grep -M 'regular\s+expression' &#60;file&#62;
+</pre>
+The \s escape sequence matches any white space character, including newlines,
+and is followed by + so as to match trailing white space on the first line as
+well as possibly handling a two-character newline sequence.
+<br>
+<br>
+There is a limit to the number of lines that can be matched, imposed by the way
+that <b>pcre2grep</b> buffers the input file as it scans it. With a sufficiently
+large processing buffer, this should not be a problem, but the <b>-M</b> option
+does not work when input is read line by line (see <b>--line-buffered</b>.)
+</P>
+<P>
+<b>-m</b> <i>number</i>, <b>--max-count</b>=<i>number</i>
+Stop processing after finding <i>number</i> matching lines, or non-matching
+lines if <b>-v</b> is also set. Any trailing context lines are output after the
+final match. In multiline mode, each multiline match counts as just one line
+for this purpose. If this limit is reached when reading the standard input from
+a regular file, the file is left positioned just after the last matching line.
+If <b>-c</b> is also set, the count that is output is never greater than
+<i>number</i>. This option has no effect if used with <b>-L</b>, <b>-l</b>, or
+<b>-q</b>, or when just checking for a match in a binary file.
+</P>
+<P>
<b>--match-limit</b>=<i>number</i>
Processing some regular expression patterns may take a very long time to search
for all possible matching strings. Others may require a very large amount of
@@ -568,38 +611,6 @@ set by <b>--buffer-size</b>. The maximum buffer size is silently forced to be no
smaller than the starting buffer size.
</P>
<P>
-<b>-M</b>, <b>--multiline</b>
-Allow patterns to match more than one line. When this option is set, the PCRE2
-library is called in "multiline" mode. This allows a matched string to extend
-past the end of a line and continue on one or more subsequent lines. Patterns
-used with <b>-M</b> may usefully contain literal newline characters and internal
-occurrences of ^ and $ characters. The output for a successful match may
-consist of more than one line. The first line is the line in which the match
-started, and the last line is the line in which the match ended. If the matched
-string ends with a newline sequence, the output ends at the end of that line.
-If <b>-v</b> is set, none of the lines in a multi-line match are output. Once a
-match has been handled, scanning restarts at the beginning of the line after
-the one in which the match ended.
-<br>
-<br>
-The newline sequence that separates multiple lines must be matched as part of
-the pattern. For example, to find the phrase "regular expression" in a file
-where "regular" might be at the end of a line and "expression" at the start of
-the next line, you could use this command:
-<pre>
- pcre2grep -M 'regular\s+expression' &#60;file&#62;
-</pre>
-The \s escape sequence matches any white space character, including newlines,
-and is followed by + so as to match trailing white space on the first line as
-well as possibly handling a two-character newline sequence.
-<br>
-<br>
-There is a limit to the number of lines that can be matched, imposed by the way
-that <b>pcre2grep</b> buffers the input file as it scans it. With a sufficiently
-large processing buffer, this should not be a problem, but the <b>-M</b> option
-does not work when input is read line by line (see <b>--line-buffered</b>.)
-</P>
-<P>
<b>-N</b> <i>newline-type</i>, <b>--newline</b>=<i>newline-type</i>
Six different conventions for indicating the ends of lines in scanned files are
supported. For example:
@@ -648,31 +659,41 @@ It should never be needed in normal use.
</P>
<P>
<b>-O</b> <i>text</i>, <b>--output</b>=<i>text</i>
-When there is a match, instead of outputting the whole line that matched,
-output just the given text, followed by an operating-system standard newline.
-The <b>--newline</b> option has no effect on this option, which is mutually
-exclusive with <b>--only-matching</b>, <b>--file-offsets</b>, and
-<b>--line-offsets</b>. Escape sequences starting with a dollar character may be
-used to insert the contents of the matched part of the line and/or captured
-substrings into the text.
+When there is a match, instead of outputting the line that matched, output just
+the text specified in this option, followed by an operating-system standard
+newline. In this mode, no context is shown. That is, the <b>-A</b>, <b>-B</b>,
+and <b>-C</b> options are ignored. The <b>--newline</b> option has no effect on
+this option, which is mutually exclusive with <b>--only-matching</b>,
+<b>--file-offsets</b>, and <b>--line-offsets</b>. However, like
+<b>--only-matching</b>, if there is more than one match in a line, each of them
+causes a line of output.
+<br>
+<br>
+Escape sequences starting with a dollar character may be used to insert the
+contents of the matched part of the line and/or captured substrings into the
+text.
<br>
<br>
-$&#60;digits&#62; or ${&#60;digits&#62;} is replaced by the captured
-substring of the given decimal number; zero substitutes the whole match. If
-the number is greater than the number of capturing substrings, or if the
-capture is unset, the replacement is empty.
+$&#60;digits&#62; or ${&#60;digits&#62;} is replaced by the captured substring of the given
+decimal number; zero substitutes the whole match. If the number is greater than
+the number of capturing substrings, or if the capture is unset, the replacement
+is empty.
<br>
<br>
$a is replaced by bell; $b by backspace; $e by escape; $f by form feed; $n by
newline; $r by carriage return; $t by tab; $v by vertical tab.
<br>
<br>
-$o&#60;digits&#62; is replaced by the character represented by the given octal
-number; up to three digits are processed.
+$o&#60;digits&#62; or $o{&#60;digits&#62;} is replaced by the character whose code point is the
+given octal number. In the first form, up to three octal digits are processed.
+When more digits are needed in Unicode mode to specify a wide character, the
+second form must be used.
<br>
<br>
-$x&#60;digits&#62; is replaced by the character represented by the given hexadecimal
-number; up to two digits are processed.
+$x&#60;digits&#62; or $x{&#60;digits&#62;} is replaced by the character represented by the
+given hexadecimal number. In the first form, up to two hexadecimal digits are
+processed. When more digits are needed in Unicode mode to specify a wide
+character, the second form must be used.
<br>
<br>
Any other character is substituted by itself. In particular, $$ is replaced by
@@ -741,7 +762,8 @@ option to "recurse".
</P>
<P>
<b>--recursion-limit</b>=<i>number</i>
-See <b>--match-limit</b> above.
+This is an obsolete synonym for <b>--depth-limit</b>. See <b>--match-limit</b>
+above for details.
</P>
<P>
<b>-s</b>, <b>--no-messages</b>
@@ -765,15 +787,18 @@ total would always be zero.
<b>-u</b>, <b>--utf</b>
Operate in UTF-8 mode. This option is available only if PCRE2 has been compiled
with UTF-8 support. All patterns (including those for any <b>--exclude</b> and
-<b>--include</b> options) and all subject lines that are scanned must be valid
-strings of UTF-8 characters.
+<b>--include</b> options) and all lines that are scanned must be valid strings
+of UTF-8 characters. If an invalid UTF-8 string is encountered, an error
+occurs.
</P>
<P>
<b>-U</b>, <b>--utf-allow-invalid</b>
As <b>--utf</b>, but in addition subject lines may contain invalid UTF-8 code
-unit sequences. These can never form part of any pattern match. This facility
-allows valid UTF-8 strings to be sought in executable or other binary files.
-For more details about matching in non-valid UTF-8 strings, see the
+unit sequences. These can never form part of any pattern match. Patterns
+themselves, however, must still be valid UTF-8 strings. This facility allows
+valid UTF-8 strings to be sought within arbitrary byte sequences in executable
+or other binary files. For more details about matching in non-valid UTF-8
+strings, see the
<a href="pcre2unicode.html"><b>pcre2unicode</b>(3)</a>
documentation.
</P>
@@ -786,7 +811,9 @@ ignored.
<P>
<b>-v</b>, <b>--invert-match</b>
Invert the sense of the match, so that lines which do <i>not</i> match any of
-the patterns are the ones that are found.
+the patterns are the ones that are found. When this option is set, options such
+as <b>--only-matching</b> and <b>--output</b>, which specify parts of a match
+that are to be output, are ignored.
</P>
<P>
<b>-w</b>, <b>--word-regex</b>, <b>--word-regexp</b>
@@ -909,12 +936,36 @@ documentation for details). Numbered callouts are ignored by <b>pcre2grep</b>;
only callouts with string arguments are useful.
</P>
<br><b>
+Echoing a specific string
+</b><br>
+<P>
+Starting the callout string with a pipe character invokes an echoing facility
+that avoids calling an external program or script. This facility is always
+available, provided that callouts were not completely disabled when
+<b>pcre2grep</b> was built. The rest of the callout string is processed as a
+zero-terminated string, which means it should not contain any internal binary
+zeros. It is written to the output, having first been passed through the same
+escape processing as text from the <b>--output</b> (<b>-O</b>) option (see
+above). However, $0 cannot be used to insert a matched substring because the
+match is still in progress. Instead, the single character '0' is inserted. Any
+syntax errors in the string (for example, a dollar not followed by another
+character) causes the callout to be ignored. No terminator is added to the
+output string, so if you want a newline, you must include it explicitly using
+the escape $n. For example:
+<pre>
+ pcre2grep '(.)(..(.))(?C"|[$1] [$2] [$3]$n")' &#60;some file&#62;
+</pre>
+Matching continues normally after the string is output. If you want to see only
+the callout output but not any output from an actual match, you should end the
+pattern with (*FAIL).
+</P>
+<br><b>
Calling external programs or scripts
</b><br>
<P>
This facility can be independently disabled when <b>pcre2grep</b> is built. It
is supported for Windows, where a call to <b>_spawnvp()</b> is used, for VMS,
-where <b>lib$spawn()</b> is used, and for any other Unix-like environment where
+where <b>lib$spawn()</b> is used, and for any Unix-like environment where
<b>fork()</b> and <b>execv()</b> are available.
</P>
<P>
@@ -926,14 +977,11 @@ arguments:
executable_name|arg1|arg2|...
</pre>
Any substring (including the executable name) may contain escape sequences
-started by a dollar character: $&#60;digits&#62; or ${&#60;digits&#62;} is replaced by the
-captured substring of the given decimal number, which must be greater than
-zero. If the number is greater than the number of capturing substrings, or if
-the capture is unset, the replacement is empty.
-</P>
-<P>
-Any other character is substituted by itself. In particular, $$ is replaced by
-a single dollar and $| is replaced by a pipe character. Here is an example:
+started by a dollar character. These are the same as for the <b>--output</b>
+(<b>-O</b>) option documented above, except that $0 cannot insert the matched
+string because the match is still in progress. Instead, the character '0'
+is inserted. If you need a literal dollar or pipe character in any
+substring, use $$ or $| respectively. Here is an example:
<pre>
echo -e "abcde\n12345" | pcre2grep \
'(?x)(.)(..(.))
@@ -946,28 +994,14 @@ a single dollar and $| is replaced by a pipe character. Here is an example:
Arg1: [1] [234] [4] Arg2: |1| ()
12345
</pre>
-The parameters for the system call that is used to run the
-program or script are zero-terminated strings. This means that binary zero
-characters in the callout argument will cause premature termination of their
-substrings, and therefore should not be present. Any syntax errors in the
-string (for example, a dollar not followed by another character) cause the
-callout to be ignored. If running the program fails for any reason (including
-the non-existence of the executable), a local matching failure occurs and the
-matcher backtracks in the normal way.
-</P>
-<br><b>
-Echoing a specific string
-</b><br>
-<P>
-This facility is always available, provided that callouts were not completely
-disabled when <b>pcre2grep</b> was built. If the callout string starts with a
-pipe (vertical bar) character, the rest of the string is written to the output,
-having been passed through the same escape processing as text from the --output
-option. This provides a simple echoing facility that avoids calling an external
-program or script. No terminator is added to the string, so if you want a
-newline, you must include it explicitly. Matching continues normally after the
-string is output. If you want to see only the callout output but not any output
-from an actual match, you should end the relevant pattern with (*FAIL).
+The parameters for the system call that is used to run the program or script
+are zero-terminated strings. This means that binary zero characters in the
+callout argument will cause premature termination of their substrings, and
+therefore should not be present. Any syntax errors in the string (for example,
+a dollar not followed by another character) causes the callout to be ignored.
+If running the program fails for any reason (including the non-existence of the
+executable), a local matching failure occurs and the matcher backtracks in the
+normal way.
</P>
<br><a name="SEC12" href="#TOC1">MATCHING ERRORS</a><br>
<P>
@@ -999,7 +1033,8 @@ because VMS does not distinguish between exit(0) and exit(1).
</P>
<br><a name="SEC14" href="#TOC1">SEE ALSO</a><br>
<P>
-<b>pcre2pattern</b>(3), <b>pcre2syntax</b>(3), <b>pcre2callout</b>(3).
+<b>pcre2pattern</b>(3), <b>pcre2syntax</b>(3), <b>pcre2callout</b>(3),
+<b>pcre2unicode</b>(3).
</P>
<br><a name="SEC15" href="#TOC1">AUTHOR</a><br>
<P>
@@ -1012,7 +1047,7 @@ Cambridge, England.
</P>
<br><a name="SEC16" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 25 January 2020
+Last updated: 04 October 2020
<br>
Copyright &copy; 1997-2020 University of Cambridge.
<br>
diff --git a/doc/html/pcre2pattern.html b/doc/html/pcre2pattern.html
index ec2e8c9..9db15b9 100644
--- a/doc/html/pcre2pattern.html
+++ b/doc/html/pcre2pattern.html
@@ -289,8 +289,11 @@ corresponding characters in the subject. As a trivial example, the pattern
The quick brown fox
</pre>
matches a portion of a subject string that is identical to itself. When
-caseless matching is specified (the PCRE2_CASELESS option), letters are matched
-independently of case.
+caseless matching is specified (the PCRE2_CASELESS option or (?i) within the
+pattern), letters are matched independently of case. Note that there are two
+ASCII characters, K and S, that, in addition to their lower case ASCII
+equivalents, are case-equivalent with Unicode U+212A (Kelvin sign) and U+017F
+(long S) respectively when either PCRE2_UTF or PCRE2_UCP is set.
</P>
<P>
The power of regular expressions comes from the ability to include wild cards,
@@ -326,6 +329,20 @@ a character class the only metacharacters are:
[ POSIX character class (if followed by POSIX syntax)
] terminates the character class
</pre>
+If a pattern is compiled with the PCRE2_EXTENDED option, most white space in
+the pattern, other than in a character class, and characters between a #
+outside a character class and the next newline, inclusive, are ignored. An
+escaping backslash can be used to include a white space or a # character as
+part of the pattern. If the PCRE2_EXTENDED_MORE option is set, the same
+applies, but in addition unescaped space and horizontal tab characters are
+ignored inside a character class. Note: only these two characters are ignored,
+not the full set of pattern white space characters that are ignored outside a
+character class. Option settings can be changed within a pattern; see the
+section entitled
+<a href="#internaloptions">"Internal Option Setting"</a>
+below.
+</P>
+<P>
The following sections describe the use of each of the metacharacters.
</P>
<br><a name="SEC5" href="#TOC1">BACKSLASH</a><br>
@@ -343,16 +360,9 @@ precede a non-alphanumeric with backslash to specify that it stands for itself.
In particular, if you want to match a backslash, you write \\.
</P>
<P>
-In a UTF mode, only ASCII digits and letters have any special meaning after a
-backslash. All other characters (in particular, those whose code points are
-greater than 127) are treated as literals.
-</P>
-<P>
-If a pattern is compiled with the PCRE2_EXTENDED option, most white space in
-the pattern (other than in a character class), and characters between a #
-outside a character class and the next newline, inclusive, are ignored. An
-escaping backslash can be used to include a white space or # character as part
-of the pattern.
+Only ASCII digits and letters have any special meaning after a backslash. All
+other characters (in particular, those whose code points are greater than 127)
+are treated as literals.
</P>
<P>
If you want to treat all characters in a sequence as literals, you can do so by
@@ -1165,8 +1175,9 @@ For example, when the pattern
matches "foobar", the first substring is still set to "foo".
</P>
<P>
-Perl documents that the use of \K within assertions is "not well defined". In
-PCRE2, \K is acted upon when it occurs inside positive assertions, but is
+Perl used to document that the use of \K within lookaround assertions is "not
+well defined", but from version 5.32.0 Perl does not support this usage at all.
+In PCRE2, \K is acted upon when it occurs inside positive assertions, but is
ignored in negative assertions. Note that when a pattern such as (?=ab\K)
matches, the reported start of the match can be greater than the end of the
match. Using \K in a lookbehind assertion at the start of a pattern can also
@@ -1443,7 +1454,10 @@ Characters in a class may be specified by their code points using \o, \x, or
\N{U+hh..} in the usual way. When caseless matching is set, any letters in a
class represent both their upper case and lower case versions, so for example,
a caseless [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not
-match "A", whereas a caseful version would.
+match "A", whereas a caseful version would. Note that there are two ASCII
+characters, K and S, that, in addition to their lower case ASCII equivalents,
+are case-equivalent with Unicode U+212A (Kelvin sign) and U+017F (long S)
+respectively when either PCRE2_UTF or PCRE2_UCP is set.
</P>
<P>
Characters that might indicate line breaks are never treated in any special way
@@ -3838,7 +3852,7 @@ Cambridge, England.
</P>
<br><a name="SEC32" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 24 February 2020
+Last updated: 06 October 2020
<br>
Copyright &copy; 1997-2020 University of Cambridge.
<br>
diff --git a/doc/html/pcre2test.html b/doc/html/pcre2test.html
index 920b265..4a7e55f 100644
--- a/doc/html/pcre2test.html
+++ b/doc/html/pcre2test.html
@@ -323,7 +323,7 @@ test data, command lines that begin with # may appear. This file format, with
some restrictions, can also be processed by the <b>perltest.sh</b> script that
is distributed with PCRE2 as a means of checking that the behaviour of PCRE2
and Perl is the same. For a specification of <b>perltest.sh</b>, see the
-comments near its beginning.
+comments near its beginning. See also the #perltest command below.
</P>
<P>
When the input is a terminal, <b>pcre2test</b> prompts for each line of input,
@@ -420,14 +420,20 @@ patterns. Modifiers on a pattern can change these settings.
<pre>
#perltest
</pre>
-The appearance of this line causes all subsequent modifier settings to be
-checked for compatibility with the <b>perltest.sh</b> script, which is used to
-confirm that Perl gives the same results as PCRE2. Also, apart from comment
-lines, #pattern commands, and #subject commands that set or unset "mark", no
-command lines are permitted, because they and many of the modifiers are
-specific to <b>pcre2test</b>, and should not be used in test files that are also
-processed by <b>perltest.sh</b>. The <b>#perltest</b> command helps detect tests
-that are accidentally put in the wrong file.
+This line is used in test files that can also be processed by <b>perltest.sh</b>
+to confirm that Perl gives the same results as PCRE2. Subsequent tests are
+checked for the use of <b>pcre2test</b> features that are incompatible with the
+<b>perltest.sh</b> script.
+</P>
+<P>
+Patterns must use '/' as their delimiter, and only certain modifiers are
+supported. Comment lines, #pattern commands, and #subject commands that set or
+unset "mark" are recognized and acted on. The #perltest, #forbid_utf, and
+#newline_default commands, which are needed in the relevant pcre2test files,
+are silently ignored. All other command lines are ignored, but give a warning
+message. The <b>#perltest</b> command helps detect tests that are accidentally
+put in the wrong file or use the wrong delimiter. For more details of the
+<b>perltest.sh</b> script see the comments it contains.
<pre>
#pop [&#60;modifiers&#62;]
#popcopy [&#60;modifiers&#62;]
@@ -2113,7 +2119,7 @@ Cambridge, England.
</P>
<br><a name="SEC21" href="#TOC1">REVISION</a><br>
<P>
-Last updated: 20 March 2020
+Last updated: 14 September 2020
<br>
Copyright &copy; 1997-2020 University of Cambridge.
<br>
diff --git a/doc/pcre2.txt b/doc/pcre2.txt
index 4651bba..365ecc4 100644
--- a/doc/pcre2.txt
+++ b/doc/pcre2.txt
@@ -683,84 +683,114 @@ MULTITHREADING
In a more complicated situation, where patterns are compiled only when
they are first needed, but are still shared between threads, pointers
to compiled patterns must be protected from simultaneous writing by
- multiple threads, at least until a pattern has been compiled. The logic
- can be something like this:
+ multiple threads. This is somewhat tricky to do correctly. If you know
+ that writing to a pointer is atomic in your environment, you can use
+ logic like this:
Get a read-only (shared) lock (mutex) for pointer
if (pointer == NULL)
{
Get a write (unique) lock for pointer
- pointer = pcre2_compile(...
+ if (pointer == NULL) pointer = pcre2_compile(...
}
Release the lock
Use pointer in pcre2_match()
- Of course, testing for compilation errors should also be included in
+ Of course, testing for compilation errors should also be included in
the code.
+ The reason for checking the pointer a second time is as follows: Sev-
+ eral threads may have acquired the shared lock and tested the pointer
+ for being NULL, but only one of them will be given the write lock, with
+ the rest kept waiting. The winning thread will compile the pattern and
+ store the result. After this thread releases the write lock, another
+ thread will get it, and if it does not retest pointer for being NULL,
+ will recompile the pattern and overwrite the pointer, creating a memory
+ leak and possibly causing other issues.
+
+ In an environment where writing to a pointer may not be atomic, the
+ above logic is not sufficient. The thread that is doing the compiling
+ may be descheduled after writing only part of the pointer, which could
+ cause other threads to use an invalid value. Instead of checking the
+ pointer itself, a separate "pointer is valid" flag (that can be updated
+ atomically) must be used:
+
+ Get a read-only (shared) lock (mutex) for pointer
+ if (!pointer_is_valid)
+ {
+ Get a write (unique) lock for pointer
+ if (!pointer_is_valid)
+ {
+ pointer = pcre2_compile(...
+ pointer_is_valid = TRUE
+ }
+ }
+ Release the lock
+ Use pointer in pcre2_match()
+
If JIT is being used, but the JIT compilation is not being done immedi-
- ately, (perhaps waiting to see if the pattern is used often enough)
- similar logic is required. JIT compilation updates a pointer within the
- compiled code block, so a thread must gain unique write access to the
- pointer before calling pcre2_jit_compile(). Alternatively,
- pcre2_code_copy() or pcre2_code_copy_with_tables() can be used to ob-
- tain a private copy of the compiled code before calling the JIT com-
+ ately (perhaps waiting to see if the pattern is used often enough),
+ similar logic is required. JIT compilation updates a value within the
+ compiled code block, so a thread must gain unique write access to the
+ pointer before calling pcre2_jit_compile(). Alternatively,
+ pcre2_code_copy() or pcre2_code_copy_with_tables() can be used to ob-
+ tain a private copy of the compiled code before calling the JIT com-
piler.
Context blocks
- The next main section below introduces the idea of "contexts" in which
+ The next main section below introduces the idea of "contexts" in which
PCRE2 functions are called. A context is nothing more than a collection
of parameters that control the way PCRE2 operates. Grouping a number of
parameters together in a context is a convenient way of passing them to
- a PCRE2 function without using lots of arguments. The parameters that
- are stored in contexts are in some sense "advanced features" of the
+ a PCRE2 function without using lots of arguments. The parameters that
+ are stored in contexts are in some sense "advanced features" of the
API. Many straightforward applications will not need to use contexts.
In a multithreaded application, if the parameters in a context are val-
- ues that are never changed, the same context can be used by all the
+ ues that are never changed, the same context can be used by all the
threads. However, if any thread needs to change any value in a context,
it must make its own thread-specific copy.
Match blocks
- The matching functions need a block of memory for storing the results
+ The matching functions need a block of memory for storing the results
of a match. This includes details of what was matched, as well as addi-
- tional information such as the name of a (*MARK) setting. Each thread
+ tional information such as the name of a (*MARK) setting. Each thread
must provide its own copy of this memory.
PCRE2 CONTEXTS
- Some PCRE2 functions have a lot of parameters, many of which are used
- only by specialist applications, for example, those that use custom
- memory management or non-standard character tables. To keep function
- argument lists at a reasonable size, and at the same time to keep the
- API extensible, "uncommon" parameters are passed to certain functions
- in a context instead of directly. A context is just a block of memory
- that holds the parameter values. Applications that do not need to ad-
+ Some PCRE2 functions have a lot of parameters, many of which are used
+ only by specialist applications, for example, those that use custom
+ memory management or non-standard character tables. To keep function
+ argument lists at a reasonable size, and at the same time to keep the
+ API extensible, "uncommon" parameters are passed to certain functions
+ in a context instead of directly. A context is just a block of memory
+ that holds the parameter values. Applications that do not need to ad-
just any of the context parameters can pass NULL when a context pointer
is required.
- There are three different types of context: a general context that is
- relevant for several PCRE2 operations, a compile-time context, and a
+ There are three different types of context: a general context that is
+ relevant for several PCRE2 operations, a compile-time context, and a
match-time context.
The general context
- At present, this context just contains pointers to (and data for) ex-
- ternal memory management functions that are called from several places
- in the PCRE2 library. The context is named `general' rather than
- specifically `memory' because in future other fields may be added. If
- you do not want to supply your own custom memory management functions,
- you do not need to bother with a general context. A general context is
+ At present, this context just contains pointers to (and data for) ex-
+ ternal memory management functions that are called from several places
+ in the PCRE2 library. The context is named `general' rather than
+ specifically `memory' because in future other fields may be added. If
+ you do not want to supply your own custom memory management functions,
+ you do not need to bother with a general context. A general context is
created by:
pcre2_general_context *pcre2_general_context_create(
void *(*private_malloc)(PCRE2_SIZE, void *),
void (*private_free)(void *, void *), void *memory_data);
- The two function pointers specify custom memory management functions,
+ The two function pointers specify custom memory management functions,
whose prototypes are:
void *private_malloc(PCRE2_SIZE, void *);
@@ -768,16 +798,16 @@ PCRE2 CONTEXTS
Whenever code in PCRE2 calls these functions, the final argument is the
value of memory_data. Either of the first two arguments of the creation
- function may be NULL, in which case the system memory management func-
- tions malloc() and free() are used. (This is not currently useful, as
- there are no other fields in a general context, but in future there
- might be.) The private_malloc() function is used (if supplied) to ob-
- tain memory for storing the context, and all three values are saved as
+ function may be NULL, in which case the system memory management func-
+ tions malloc() and free() are used. (This is not currently useful, as
+ there are no other fields in a general context, but in future there
+ might be.) The private_malloc() function is used (if supplied) to ob-
+ tain memory for storing the context, and all three values are saved as
part of the context.
- Whenever PCRE2 creates a data block of any kind, the block contains a
- pointer to the free() function that matches the malloc() function that
- was used. When the time comes to free the block, this function is
+ Whenever PCRE2 creates a data block of any kind, the block contains a
+ pointer to the free() function that matches the malloc() function that
+ was used. When the time comes to free the block, this function is
called.
A general context can be copied by calling:
@@ -789,13 +819,13 @@ PCRE2 CONTEXTS
void pcre2_general_context_free(pcre2_general_context *gcontext);
- If this function is passed a NULL argument, it returns immediately
+ If this function is passed a NULL argument, it returns immediately
without doing anything.
The compile context
- A compile context is required if you want to provide an external func-
- tion for stack checking during compilation or to change the default
+ A compile context is required if you want to provide an external func-
+ tion for stack checking during compilation or to change the default
values of any of the following compile-time parameters:
What \R matches (Unicode newlines or CR, LF, CRLF only)
@@ -805,11 +835,11 @@ PCRE2 CONTEXTS
The maximum length of the pattern string
The extra options bits (none set by default)
- A compile context is also required if you are using custom memory man-
- agement. If none of these apply, just pass NULL as the context argu-
+ A compile context is also required if you are using custom memory man-
+ agement. If none of these apply, just pass NULL as the context argu-
ment of pcre2_compile().
- A compile context is created, copied, and freed by the following func-
+ A compile context is created, copied, and freed by the following func-
tions:
pcre2_compile_context *pcre2_compile_context_create(
@@ -820,91 +850,91 @@ PCRE2 CONTEXTS
void pcre2_compile_context_free(pcre2_compile_context *ccontext);
- A compile context is created with default values for its parameters.
+ A compile context is created with default values for its parameters.
These can be changed by calling the following functions, which return 0
on success, or PCRE2_ERROR_BADDATA if invalid data is detected.
int pcre2_set_bsr(pcre2_compile_context *ccontext,
uint32_t value);
- The value must be PCRE2_BSR_ANYCRLF, to specify that \R matches only
- CR, LF, or CRLF, or PCRE2_BSR_UNICODE, to specify that \R matches any
+ The value must be PCRE2_BSR_ANYCRLF, to specify that \R matches only
+ CR, LF, or CRLF, or PCRE2_BSR_UNICODE, to specify that \R matches any
Unicode line ending sequence. The value is used by the JIT compiler and
- by the two interpreted matching functions, pcre2_match() and
+ by the two interpreted matching functions, pcre2_match() and
pcre2_dfa_match().
int pcre2_set_character_tables(pcre2_compile_context *ccontext,
const uint8_t *tables);
- The value must be the result of a call to pcre2_maketables(), whose
+ The value must be the result of a call to pcre2_maketables(), whose
only argument is a general context. This function builds a set of char-
acter tables in the current locale.
int pcre2_set_compile_extra_options(pcre2_compile_context *ccontext,
uint32_t extra_options);
- As PCRE2 has developed, almost all the 32 option bits that are avail-
- able in the options argument of pcre2_compile() have been used up. To
- avoid running out, the compile context contains a set of extra option
- bits which are used for some newer, assumed rarer, options. This func-
- tion sets those bits. It always sets all the bits (either on or off).
- It does not modify any existing setting. The available options are de-
+ As PCRE2 has developed, almost all the 32 option bits that are avail-
+ able in the options argument of pcre2_compile() have been used up. To
+ avoid running out, the compile context contains a set of extra option
+ bits which are used for some newer, assumed rarer, options. This func-
+ tion sets those bits. It always sets all the bits (either on or off).
+ It does not modify any existing setting. The available options are de-
fined in the section entitled "Extra compile options" below.
int pcre2_set_max_pattern_length(pcre2_compile_context *ccontext,
PCRE2_SIZE value);
- This sets a maximum length, in code units, for any pattern string that
- is compiled with this context. If the pattern is longer, an error is
- generated. This facility is provided so that applications that accept
+ This sets a maximum length, in code units, for any pattern string that
+ is compiled with this context. If the pattern is longer, an error is
+ generated. This facility is provided so that applications that accept
patterns from external sources can limit their size. The default is the
- largest number that a PCRE2_SIZE variable can hold, which is effec-
+ largest number that a PCRE2_SIZE variable can hold, which is effec-
tively unlimited.
int pcre2_set_newline(pcre2_compile_context *ccontext,
uint32_t value);
This specifies which characters or character sequences are to be recog-
- nized as newlines. The value must be one of PCRE2_NEWLINE_CR (carriage
+ nized as newlines. The value must be one of PCRE2_NEWLINE_CR (carriage
return only), PCRE2_NEWLINE_LF (linefeed only), PCRE2_NEWLINE_CRLF (the
- two-character sequence CR followed by LF), PCRE2_NEWLINE_ANYCRLF (any
- of the above), PCRE2_NEWLINE_ANY (any Unicode newline sequence), or
+ two-character sequence CR followed by LF), PCRE2_NEWLINE_ANYCRLF (any
+ of the above), PCRE2_NEWLINE_ANY (any Unicode newline sequence), or
PCRE2_NEWLINE_NUL (the NUL character, that is a binary zero).
A pattern can override the value set in the compile context by starting
with a sequence such as (*CRLF). See the pcre2pattern page for details.
- When a pattern is compiled with the PCRE2_EXTENDED or PCRE2_EX-
- TENDED_MORE option, the newline convention affects the recognition of
- the end of internal comments starting with #. The value is saved with
- the compiled pattern for subsequent use by the JIT compiler and by the
- two interpreted matching functions, pcre2_match() and
+ When a pattern is compiled with the PCRE2_EXTENDED or PCRE2_EX-
+ TENDED_MORE option, the newline convention affects the recognition of
+ the end of internal comments starting with #. The value is saved with
+ the compiled pattern for subsequent use by the JIT compiler and by the
+ two interpreted matching functions, pcre2_match() and
pcre2_dfa_match().
int pcre2_set_parens_nest_limit(pcre2_compile_context *ccontext,
uint32_t value);
- This parameter adjusts the limit, set when PCRE2 is built (default
- 250), on the depth of parenthesis nesting in a pattern. This limit
- stops rogue patterns using up too much system stack when being com-
- piled. The limit applies to parentheses of all kinds, not just captur-
+ This parameter adjusts the limit, set when PCRE2 is built (default
+ 250), on the depth of parenthesis nesting in a pattern. This limit
+ stops rogue patterns using up too much system stack when being com-
+ piled. The limit applies to parentheses of all kinds, not just captur-
ing parentheses.
int pcre2_set_compile_recursion_guard(pcre2_compile_context *ccontext,
int (*guard_function)(uint32_t, void *), void *user_data);
- There is at least one application that runs PCRE2 in threads with very
- limited system stack, where running out of stack is to be avoided at
- all costs. The parenthesis limit above cannot take account of how much
- stack is actually available during compilation. For a finer control,
- you can supply a function that is called whenever pcre2_compile()
- starts to compile a parenthesized part of a pattern. This function can
- check the actual stack size (or anything else that it wants to, of
+ There is at least one application that runs PCRE2 in threads with very
+ limited system stack, where running out of stack is to be avoided at
+ all costs. The parenthesis limit above cannot take account of how much
+ stack is actually available during compilation. For a finer control,
+ you can supply a function that is called whenever pcre2_compile()
+ starts to compile a parenthesized part of a pattern. This function can
+ check the actual stack size (or anything else that it wants to, of
course).
- The first argument to the callout function gives the current depth of
- nesting, and the second is user data that is set up by the last argu-
- ment of pcre2_set_compile_recursion_guard(). The callout function
+ The first argument to the callout function gives the current depth of
+ nesting, and the second is user data that is set up by the last argu-
+ ment of pcre2_set_compile_recursion_guard(). The callout function
should return zero if all is well, or non-zero to force an error.
The match context
@@ -918,10 +948,10 @@ PCRE2 CONTEXTS
Change the backtracking depth limit
Set custom memory management specifically for the match
- If none of these apply, just pass NULL as the context argument of
+ If none of these apply, just pass NULL as the context argument of
pcre2_match(), pcre2_dfa_match(), or pcre2_jit_match().
- A match context is created, copied, and freed by the following func-
+ A match context is created, copied, and freed by the following func-
tions:
pcre2_match_context *pcre2_match_context_create(
@@ -932,7 +962,7 @@ PCRE2 CONTEXTS
void pcre2_match_context_free(pcre2_match_context *mcontext);
- A match context is created with default values for its parameters.
+ A match context is created with default values for its parameters.
These can be changed by calling the following functions, which return 0
on success, or PCRE2_ERROR_BADDATA if invalid data is detected.
@@ -940,7 +970,7 @@ PCRE2 CONTEXTS
int (*callout_function)(pcre2_callout_block *, void *),
void *callout_data);
- This sets up a callout function for PCRE2 to call at specified points
+ This sets up a callout function for PCRE2 to call at specified points
during a matching operation. Details are given in the pcre2callout doc-
umentation.
@@ -948,34 +978,34 @@ PCRE2 CONTEXTS
int (*callout_function)(pcre2_substitute_callout_block *, void *),
void *callout_data);
- This sets up a callout function for PCRE2 to call after each substitu-
+ This sets up a callout function for PCRE2 to call after each substitu-
tion made by pcre2_substitute(). Details are given in the section enti-
tled "Creating a new string with substitutions" below.
int pcre2_set_offset_limit(pcre2_match_context *mcontext,
PCRE2_SIZE value);
- The offset_limit parameter limits how far an unanchored search can ad-
- vance in the subject string. The default value is PCRE2_UNSET. The
- pcre2_match() and pcre2_dfa_match() functions return PCRE2_ERROR_NO-
+ The offset_limit parameter limits how far an unanchored search can ad-
+ vance in the subject string. The default value is PCRE2_UNSET. The
+ pcre2_match() and pcre2_dfa_match() functions return PCRE2_ERROR_NO-
MATCH if a match with a starting point before or at the given offset is
not found. The pcre2_substitute() function makes no more substitutions.
- For example, if the pattern /abc/ is matched against "123abc" with an
- offset limit less than 3, the result is PCRE2_ERROR_NOMATCH. A match
- can never be found if the startoffset argument of pcre2_match(),
- pcre2_dfa_match(), or pcre2_substitute() is greater than the offset
+ For example, if the pattern /abc/ is matched against "123abc" with an
+ offset limit less than 3, the result is PCRE2_ERROR_NOMATCH. A match
+ can never be found if the startoffset argument of pcre2_match(),
+ pcre2_dfa_match(), or pcre2_substitute() is greater than the offset
limit set in the match context.
- When using this facility, you must set the PCRE2_USE_OFFSET_LIMIT op-
+ When using this facility, you must set the PCRE2_USE_OFFSET_LIMIT op-
tion when calling pcre2_compile() so that when JIT is in use, different
- code can be compiled. If a match is started with a non-default match
+ code can be compiled. If a match is started with a non-default match
limit when PCRE2_USE_OFFSET_LIMIT is not set, an error is generated.
- The offset limit facility can be used to track progress when searching
- large subject strings or to limit the extent of global substitutions.
- See also the PCRE2_FIRSTLINE option, which requires a match to start
- before or at the first newline that follows the start of matching in
+ The offset limit facility can be used to track progress when searching
+ large subject strings or to limit the extent of global substitutions.
+ See also the PCRE2_FIRSTLINE option, which requires a match to start
+ before or at the first newline that follows the start of matching in
the subject. If this is set with an offset limit, a match must occur in
the first line and also within the offset limit. In other words, which-
ever limit comes first is used.
@@ -984,15 +1014,15 @@ PCRE2 CONTEXTS
uint32_t value);
The heap_limit parameter specifies, in units of kibibytes (1024 bytes),
- the maximum amount of heap memory that pcre2_match() may use to hold
+ the maximum amount of heap memory that pcre2_match() may use to hold
backtracking information when running an interpretive match. This limit
also applies to pcre2_dfa_match(), which may use the heap when process-
- ing patterns with a lot of nested pattern recursion or lookarounds or
+ ing patterns with a lot of nested pattern recursion or lookarounds or
atomic groups. This limit does not apply to matching with the JIT opti-
- mization, which has its own memory control arrangements (see the
- pcre2jit documentation for more details). If the limit is reached, the
- negative error code PCRE2_ERROR_HEAPLIMIT is returned. The default
- limit can be set when PCRE2 is built; if it is not, the default is set
+ mization, which has its own memory control arrangements (see the
+ pcre2jit documentation for more details). If the limit is reached, the
+ negative error code PCRE2_ERROR_HEAPLIMIT is returned. The default
+ limit can be set when PCRE2 is built; if it is not, the default is set
very large and is essentially "unlimited".
A value for the heap limit may also be supplied by an item at the start
@@ -1000,101 +1030,101 @@ PCRE2 CONTEXTS
(*LIMIT_HEAP=ddd)
- where ddd is a decimal number. However, such a setting is ignored un-
- less ddd is less than the limit set by the caller of pcre2_match() or,
+ where ddd is a decimal number. However, such a setting is ignored un-
+ less ddd is less than the limit set by the caller of pcre2_match() or,
if no such limit is set, less than the default.
- The pcre2_match() function starts out using a 20KiB vector on the sys-
+ The pcre2_match() function starts out using a 20KiB vector on the sys-
tem stack for recording backtracking points. The more nested backtrack-
- ing points there are (that is, the deeper the search tree), the more
- memory is needed. Heap memory is used only if the initial vector is
+ ing points there are (that is, the deeper the search tree), the more
+ memory is needed. Heap memory is used only if the initial vector is
too small. If the heap limit is set to a value less than 21 (in partic-
- ular, zero) no heap memory will be used. In this case, only patterns
- that do not have a lot of nested backtracking can be successfully pro-
+ ular, zero) no heap memory will be used. In this case, only patterns
+ that do not have a lot of nested backtracking can be successfully pro-
cessed.
- Similarly, for pcre2_dfa_match(), a vector on the system stack is used
- when processing pattern recursions, lookarounds, or atomic groups, and
- only if this is not big enough is heap memory used. In this case, too,
+ Similarly, for pcre2_dfa_match(), a vector on the system stack is used
+ when processing pattern recursions, lookarounds, or atomic groups, and
+ only if this is not big enough is heap memory used. In this case, too,
setting a value of zero disables the use of the heap.
int pcre2_set_match_limit(pcre2_match_context *mcontext,
uint32_t value);
The match_limit parameter provides a means of preventing PCRE2 from us-
- ing up too many computing resources when processing patterns that are
+ ing up too many computing resources when processing patterns that are
not going to match, but which have a very large number of possibilities
- in their search trees. The classic example is a pattern that uses
+ in their search trees. The classic example is a pattern that uses
nested unlimited repeats.
- There is an internal counter in pcre2_match() that is incremented each
- time round its main matching loop. If this value reaches the match
+ There is an internal counter in pcre2_match() that is incremented each
+ time round its main matching loop. If this value reaches the match
limit, pcre2_match() returns the negative value PCRE2_ERROR_MATCHLIMIT.
- This has the effect of limiting the amount of backtracking that can
+ This has the effect of limiting the amount of backtracking that can
take place. For patterns that are not anchored, the count restarts from
- zero for each position in the subject string. This limit also applies
+ zero for each position in the subject string. This limit also applies
to pcre2_dfa_match(), though the counting is done in a different way.
- When pcre2_match() is called with a pattern that was successfully pro-
+ When pcre2_match() is called with a pattern that was successfully pro-
cessed by pcre2_jit_compile(), the way in which matching is executed is
- entirely different. However, there is still the possibility of runaway
- matching that goes on for a very long time, and so the match_limit
- value is also used in this case (but in a different way) to limit how
+ entirely different. However, there is still the possibility of runaway
+ matching that goes on for a very long time, and so the match_limit
+ value is also used in this case (but in a different way) to limit how
long the matching can continue.
The default value for the limit can be set when PCRE2 is built; the de-
- fault default is 10 million, which handles all but the most extreme
- cases. A value for the match limit may also be supplied by an item at
+ fault default is 10 million, which handles all but the most extreme
+ cases. A value for the match limit may also be supplied by an item at
the start of a pattern of the form
(*LIMIT_MATCH=ddd)
- where ddd is a decimal number. However, such a setting is ignored un-
- less ddd is less than the limit set by the caller of pcre2_match() or
+ where ddd is a decimal number. However, such a setting is ignored un-
+ less ddd is less than the limit set by the caller of pcre2_match() or
pcre2_dfa_match() or, if no such limit is set, less than the default.
int pcre2_set_depth_limit(pcre2_match_context *mcontext,
uint32_t value);
- This parameter limits the depth of nested backtracking in
- pcre2_match(). Each time a nested backtracking point is passed, a new
+ This parameter limits the depth of nested backtracking in
+ pcre2_match(). Each time a nested backtracking point is passed, a new
memory "frame" is used to remember the state of matching at that point.
- Thus, this parameter indirectly limits the amount of memory that is
- used in a match. However, because the size of each memory "frame" de-
- pends on the number of capturing parentheses, the actual memory limit
- varies from pattern to pattern. This limit was more useful in versions
+ Thus, this parameter indirectly limits the amount of memory that is
+ used in a match. However, because the size of each memory "frame" de-
+ pends on the number of capturing parentheses, the actual memory limit
+ varies from pattern to pattern. This limit was more useful in versions
before 10.30, where function recursion was used for backtracking.
- The depth limit is not relevant, and is ignored, when matching is done
+ The depth limit is not relevant, and is ignored, when matching is done
using JIT compiled code. However, it is supported by pcre2_dfa_match(),
- which uses it to limit the depth of nested internal recursive function
- calls that implement atomic groups, lookaround assertions, and pattern
+ which uses it to limit the depth of nested internal recursive function
+ calls that implement atomic groups, lookaround assertions, and pattern
recursions. This limits, indirectly, the amount of system stack that is
- used. It was more useful in versions before 10.32, when stack memory
+ used. It was more useful in versions before 10.32, when stack memory
was used for local workspace vectors for recursive function calls. From
- version 10.32, only local variables are allocated on the stack and as
+ version 10.32, only local variables are allocated on the stack and as
each call uses only a few hundred bytes, even a small stack can support
quite a lot of recursion.
- If the depth of internal recursive function calls is great enough, lo-
- cal workspace vectors are allocated on the heap from version 10.32 on-
- wards, so the depth limit also indirectly limits the amount of heap
+ If the depth of internal recursive function calls is great enough, lo-
+ cal workspace vectors are allocated on the heap from version 10.32 on-
+ wards, so the depth limit also indirectly limits the amount of heap
memory that is used. A recursive pattern such as /(.(?2))((?1)|)/, when
- matched to a very long string using pcre2_dfa_match(), can use a great
- deal of memory. However, it is probably better to limit heap usage di-
+ matched to a very long string using pcre2_dfa_match(), can use a great
+ deal of memory. However, it is probably better to limit heap usage di-
rectly by calling pcre2_set_heap_limit().
- The default value for the depth limit can be set when PCRE2 is built;
- if it is not, the default is set to the same value as the default for
- the match limit. If the limit is exceeded, pcre2_match() or
+ The default value for the depth limit can be set when PCRE2 is built;
+ if it is not, the default is set to the same value as the default for
+ the match limit. If the limit is exceeded, pcre2_match() or
pcre2_dfa_match() returns PCRE2_ERROR_DEPTHLIMIT. A value for the depth
- limit may also be supplied by an item at the start of a pattern of the
+ limit may also be supplied by an item at the start of a pattern of the
form
(*LIMIT_DEPTH=ddd)
- where ddd is a decimal number. However, such a setting is ignored un-
- less ddd is less than the limit set by the caller of pcre2_match() or
+ where ddd is a decimal number. However, such a setting is ignored un-
+ less ddd is less than the limit set by the caller of pcre2_match() or
pcre2_dfa_match() or, if no such limit is set, less than the default.
@@ -1102,96 +1132,96 @@ CHECKING BUILD-TIME OPTIONS
int pcre2_config(uint32_t what, void *where);
- The function pcre2_config() makes it possible for a PCRE2 client to
- find the value of certain configuration parameters and to discover
- which optional features have been compiled into the PCRE2 library. The
+ The function pcre2_config() makes it possible for a PCRE2 client to
+ find the value of certain configuration parameters and to discover
+ which optional features have been compiled into the PCRE2 library. The
pcre2build documentation has more details about these features.
- The first argument for pcre2_config() specifies which information is
+ The first argument for pcre2_config() specifies which information is
required. The second argument is a pointer to memory into which the in-
formation is placed. If NULL is passed, the function returns the amount
- of memory that is needed for the requested information. For calls that
- return numerical values, the value is in bytes; when requesting these
- values, where should point to appropriately aligned memory. For calls
- that return strings, the required length is given in code units, not
+ of memory that is needed for the requested information. For calls that
+ return numerical values, the value is in bytes; when requesting these
+ values, where should point to appropriately aligned memory. For calls
+ that return strings, the required length is given in code units, not
counting the terminating zero.
- When requesting information, the returned value from pcre2_config() is
- non-negative on success, or the negative error code PCRE2_ERROR_BADOP-
- TION if the value in the first argument is not recognized. The follow-
+ When requesting information, the returned value from pcre2_config() is
+ non-negative on success, or the negative error code PCRE2_ERROR_BADOP-
+ TION if the value in the first argument is not recognized. The follow-
ing information is available:
PCRE2_CONFIG_BSR
- The output is a uint32_t integer whose value indicates what character
- sequences the \R escape sequence matches by default. A value of
- PCRE2_BSR_UNICODE means that \R matches any Unicode line ending se-
+ The output is a uint32_t integer whose value indicates what character
+ sequences the \R escape sequence matches by default. A value of
+ PCRE2_BSR_UNICODE means that \R matches any Unicode line ending se-
quence; a value of PCRE2_BSR_ANYCRLF means that \R matches only CR, LF,
or CRLF. The default can be overridden when a pattern is compiled.
PCRE2_CONFIG_COMPILED_WIDTHS
- The output is a uint32_t integer whose lower bits indicate which code
- unit widths were selected when PCRE2 was built. The 1-bit indicates
- 8-bit support, and the 2-bit and 4-bit indicate 16-bit and 32-bit sup-
+ The output is a uint32_t integer whose lower bits indicate which code
+ unit widths were selected when PCRE2 was built. The 1-bit indicates
+ 8-bit support, and the 2-bit and 4-bit indicate 16-bit and 32-bit sup-
port, respectively.
PCRE2_CONFIG_DEPTHLIMIT
- The output is a uint32_t integer that gives the default limit for the
- depth of nested backtracking in pcre2_match() or the depth of nested
- recursions, lookarounds, and atomic groups in pcre2_dfa_match(). Fur-
+ The output is a uint32_t integer that gives the default limit for the
+ depth of nested backtracking in pcre2_match() or the depth of nested
+ recursions, lookarounds, and atomic groups in pcre2_dfa_match(). Fur-
ther details are given with pcre2_set_depth_limit() above.
PCRE2_CONFIG_HEAPLIMIT
- The output is a uint32_t integer that gives, in kibibytes, the default
- limit for the amount of heap memory used by pcre2_match() or
- pcre2_dfa_match(). Further details are given with
+ The output is a uint32_t integer that gives, in kibibytes, the default
+ limit for the amount of heap memory used by pcre2_match() or
+ pcre2_dfa_match(). Further details are given with
pcre2_set_heap_limit() above.
PCRE2_CONFIG_JIT
- The output is a uint32_t integer that is set to one if support for
+ The output is a uint32_t integer that is set to one if support for
just-in-time compiling is available; otherwise it is set to zero.
PCRE2_CONFIG_JITTARGET
- The where argument should point to a buffer that is at least 48 code
- units long. (The exact length required can be found by calling
- pcre2_config() with where set to NULL.) The buffer is filled with a
- string that contains the name of the architecture for which the JIT
- compiler is configured, for example "x86 32bit (little endian + un-
- aligned)". If JIT support is not available, PCRE2_ERROR_BADOPTION is
- returned, otherwise the number of code units used is returned. This is
+ The where argument should point to a buffer that is at least 48 code
+ units long. (The exact length required can be found by calling
+ pcre2_config() with where set to NULL.) The buffer is filled with a
+ string that contains the name of the architecture for which the JIT
+ compiler is configured, for example "x86 32bit (little endian + un-
+ aligned)". If JIT support is not available, PCRE2_ERROR_BADOPTION is
+ returned, otherwise the number of code units used is returned. This is
the length of the string, plus one unit for the terminating zero.
PCRE2_CONFIG_LINKSIZE
The output is a uint32_t integer that contains the number of bytes used
- for internal linkage in compiled regular expressions. When PCRE2 is
- configured, the value can be set to 2, 3, or 4, with the default being
- 2. This is the value that is returned by pcre2_config(). However, when
- the 16-bit library is compiled, a value of 3 is rounded up to 4, and
- when the 32-bit library is compiled, internal linkages always use 4
+ for internal linkage in compiled regular expressions. When PCRE2 is
+ configured, the value can be set to 2, 3, or 4, with the default being
+ 2. This is the value that is returned by pcre2_config(). However, when
+ the 16-bit library is compiled, a value of 3 is rounded up to 4, and
+ when the 32-bit library is compiled, internal linkages always use 4
bytes, so the configured value is not relevant.
The default value of 2 for the 8-bit and 16-bit libraries is sufficient
- for all but the most massive patterns, since it allows the size of the
- compiled pattern to be up to 65535 code units. Larger values allow
- larger regular expressions to be compiled by those two libraries, but
+ for all but the most massive patterns, since it allows the size of the
+ compiled pattern to be up to 65535 code units. Larger values allow
+ larger regular expressions to be compiled by those two libraries, but
at the expense of slower matching.
PCRE2_CONFIG_MATCHLIMIT
The output is a uint32_t integer that gives the default match limit for
- pcre2_match(). Further details are given with pcre2_set_match_limit()
+ pcre2_match(). Further details are given with pcre2_set_match_limit()
above.
PCRE2_CONFIG_NEWLINE
- The output is a uint32_t integer whose value specifies the default
- character sequence that is recognized as meaning "newline". The values
+ The output is a uint32_t integer whose value specifies the default
+ character sequence that is recognized as meaning "newline". The values
are:
PCRE2_NEWLINE_CR Carriage return (CR)
@@ -1201,23 +1231,23 @@ CHECKING BUILD-TIME OPTIONS
PCRE2_NEWLINE_ANYCRLF Any of CR, LF, or CRLF
PCRE2_NEWLINE_NUL The NUL character (binary zero)
- The default should normally correspond to the standard sequence for
+ The default should normally correspond to the standard sequence for
your operating system.
PCRE2_CONFIG_NEVER_BACKSLASH_C
- The output is a uint32_t integer that is set to one if the use of \C
- was permanently disabled when PCRE2 was built; otherwise it is set to
+ The output is a uint32_t integer that is set to one if the use of \C
+ was permanently disabled when PCRE2 was built; otherwise it is set to
zero.
PCRE2_CONFIG_PARENSLIMIT
- The output is a uint32_t integer that gives the maximum depth of nest-
+ The output is a uint32_t integer that gives the maximum depth of nest-
ing of parentheses (of any kind) in a pattern. This limit is imposed to
- cap the amount of system stack used when a pattern is compiled. It is
- specified when PCRE2 is built; the default is 250. This limit does not
+ cap the amount of system stack used when a pattern is compiled. It is
+ specified when PCRE2 is built; the default is 250. This limit does not
take into account the stack that may already be used by the calling ap-
- plication. For finer control over compilation stack usage, see
+ plication. For finer control over compilation stack usage, see
pcre2_set_compile_recursion_guard().
PCRE2_CONFIG_STACKRECURSE
@@ -1228,30 +1258,30 @@ CHECKING BUILD-TIME OPTIONS
PCRE2_CONFIG_TABLES_LENGTH
The output is a uint32_t integer that gives the length of PCRE2's char-
- acter processing tables in bytes. For details of these tables see the
+ acter processing tables in bytes. For details of these tables see the
section on locale support below.
PCRE2_CONFIG_UNICODE_VERSION
- The where argument should point to a buffer that is at least 24 code
- units long. (The exact length required can be found by calling
- pcre2_config() with where set to NULL.) If PCRE2 has been compiled
- without Unicode support, the buffer is filled with the text "Unicode
- not supported". Otherwise, the Unicode version string (for example,
- "8.0.0") is inserted. The number of code units used is returned. This
+ The where argument should point to a buffer that is at least 24 code
+ units long. (The exact length required can be found by calling
+ pcre2_config() with where set to NULL.) If PCRE2 has been compiled
+ without Unicode support, the buffer is filled with the text "Unicode
+ not supported". Otherwise, the Unicode version string (for example,
+ "8.0.0") is inserted. The number of code units used is returned. This
is the length of the string plus one unit for the terminating zero.
PCRE2_CONFIG_UNICODE
- The output is a uint32_t integer that is set to one if Unicode support
- is available; otherwise it is set to zero. Unicode support implies UTF
+ The output is a uint32_t integer that is set to one if Unicode support
+ is available; otherwise it is set to zero. Unicode support implies UTF
support.
PCRE2_CONFIG_VERSION
- The where argument should point to a buffer that is at least 24 code
- units long. (The exact length required can be found by calling
- pcre2_config() with where set to NULL.) The buffer is filled with the
+ The where argument should point to a buffer that is at least 24 code
+ units long. (The exact length required can be found by calling
+ pcre2_config() with where set to NULL.) The buffer is filled with the
PCRE2 version string, zero-terminated. The number of code units used is
returned. This is the length of the string plus one unit for the termi-
nating zero.
@@ -1269,103 +1299,103 @@ COMPILING A PATTERN
pcre2_code *pcre2_code_copy_with_tables(const pcre2_code *code);
- The pcre2_compile() function compiles a pattern into an internal form.
- The pattern is defined by a pointer to a string of code units and a
- length (in code units). If the pattern is zero-terminated, the length
- can be specified as PCRE2_ZERO_TERMINATED. The function returns a
+ The pcre2_compile() function compiles a pattern into an internal form.
+ The pattern is defined by a pointer to a string of code units and a
+ length (in code units). If the pattern is zero-terminated, the length
+ can be specified as PCRE2_ZERO_TERMINATED. The function returns a
pointer to a block of memory that contains the compiled pattern and re-
lated data, or NULL if an error occurred.
- If the compile context argument ccontext is NULL, memory for the com-
- piled pattern is obtained by calling malloc(). Otherwise, it is ob-
+ If the compile context argument ccontext is NULL, memory for the com-
+ piled pattern is obtained by calling malloc(). Otherwise, it is ob-
tained from the same memory function that was used for the compile con-
text. The caller must free the memory by calling pcre2_code_free() when
it is no longer needed. If pcre2_code_free() is called with a NULL ar-
gument, it returns immediately, without doing anything.
The function pcre2_code_copy() makes a copy of the compiled code in new
- memory, using the same memory allocator as was used for the original.
- However, if the code has been processed by the JIT compiler (see be-
- low), the JIT information cannot be copied (because it is position-de-
- pendent). The new copy can initially be used only for non-JIT match-
- ing, though it can be passed to pcre2_jit_compile() if required. If
+ memory, using the same memory allocator as was used for the original.
+ However, if the code has been processed by the JIT compiler (see be-
+ low), the JIT information cannot be copied (because it is position-de-
+ pendent). The new copy can initially be used only for non-JIT match-
+ ing, though it can be passed to pcre2_jit_compile() if required. If
pcre2_code_copy() is called with a NULL argument, it returns NULL.
The pcre2_code_copy() function provides a way for individual threads in
- a multithreaded application to acquire a private copy of shared com-
- piled code. However, it does not make a copy of the character tables
- used by the compiled pattern; the new pattern code points to the same
- tables as the original code. (See "Locale Support" below for details
- of these character tables.) In many applications the same tables are
- used throughout, so this behaviour is appropriate. Nevertheless, there
+ a multithreaded application to acquire a private copy of shared com-
+ piled code. However, it does not make a copy of the character tables
+ used by the compiled pattern; the new pattern code points to the same
+ tables as the original code. (See "Locale Support" below for details
+ of these character tables.) In many applications the same tables are
+ used throughout, so this behaviour is appropriate. Nevertheless, there
are occasions when a copy of a compiled pattern and the relevant tables
- are needed. The pcre2_code_copy_with_tables() provides this facility.
- Copies of both the code and the tables are made, with the new code
- pointing to the new tables. The memory for the new tables is automati-
- cally freed when pcre2_code_free() is called for the new copy of the
- compiled code. If pcre2_code_copy_with_tables() is called with a NULL
+ are needed. The pcre2_code_copy_with_tables() provides this facility.
+ Copies of both the code and the tables are made, with the new code
+ pointing to the new tables. The memory for the new tables is automati-
+ cally freed when pcre2_code_free() is called for the new copy of the
+ compiled code. If pcre2_code_copy_with_tables() is called with a NULL
argument, it returns NULL.
- NOTE: When one of the matching functions is called, pointers to the
+ NOTE: When one of the matching functions is called, pointers to the
compiled pattern and the subject string are set in the match data block
- so that they can be referenced by the substring extraction functions
- after a successful match. After running a match, you must not free a
- compiled pattern or a subject string until after all operations on the
- match data block have taken place, unless, in the case of the subject
- string, you have used the PCRE2_COPY_MATCHED_SUBJECT option, which is
- described in the section entitled "Option bits for pcre2_match()" be-
+ so that they can be referenced by the substring extraction functions
+ after a successful match. After running a match, you must not free a
+ compiled pattern or a subject string until after all operations on the
+ match data block have taken place, unless, in the case of the subject
+ string, you have used the PCRE2_COPY_MATCHED_SUBJECT option, which is
+ described in the section entitled "Option bits for pcre2_match()" be-
low.
- The options argument for pcre2_compile() contains various bit settings
- that affect the compilation. It should be zero if none of them are re-
- quired. The available options are described below. Some of them (in
- particular, those that are compatible with Perl, but some others as
- well) can also be set and unset from within the pattern (see the de-
+ The options argument for pcre2_compile() contains various bit settings
+ that affect the compilation. It should be zero if none of them are re-
+ quired. The available options are described below. Some of them (in
+ particular, those that are compatible with Perl, but some others as
+ well) can also be set and unset from within the pattern (see the de-
tailed description in the pcre2pattern documentation).
- For those options that can be different in different parts of the pat-
- tern, the contents of the options argument specifies their settings at
- the start of compilation. The PCRE2_ANCHORED, PCRE2_ENDANCHORED, and
- PCRE2_NO_UTF_CHECK options can be set at the time of matching as well
+ For those options that can be different in different parts of the pat-
+ tern, the contents of the options argument specifies their settings at
+ the start of compilation. The PCRE2_ANCHORED, PCRE2_ENDANCHORED, and
+ PCRE2_NO_UTF_CHECK options can be set at the time of matching as well
as at compile time.
- Some additional options and less frequently required compile-time pa-
- rameters (for example, the newline setting) can be provided in a com-
+ Some additional options and less frequently required compile-time pa-
+ rameters (for example, the newline setting) can be provided in a com-
pile context (as described above).
If errorcode or erroroffset is NULL, pcre2_compile() returns NULL imme-
- diately. Otherwise, the variables to which these point are set to an
+ diately. Otherwise, the variables to which these point are set to an
error code and an offset (number of code units) within the pattern, re-
spectively, when pcre2_compile() returns NULL because a compilation er-
- ror has occurred. The values are not defined when compilation is suc-
+ ror has occurred. The values are not defined when compilation is suc-
cessful and pcre2_compile() returns a non-NULL value.
- There are nearly 100 positive error codes that pcre2_compile() may re-
- turn if it finds an error in the pattern. There are also some negative
- error codes that are used for invalid UTF strings when validity check-
- ing is in force. These are the same as given by pcre2_match() and
+ There are nearly 100 positive error codes that pcre2_compile() may re-
+ turn if it finds an error in the pattern. There are also some negative
+ error codes that are used for invalid UTF strings when validity check-
+ ing is in force. These are the same as given by pcre2_match() and
pcre2_dfa_match(), and are described in the pcre2unicode documentation.
- There is no separate documentation for the positive error codes, be-
- cause the textual error messages that are obtained by calling the
+ There is no separate documentation for the positive error codes, be-
+ cause the textual error messages that are obtained by calling the
pcre2_get_error_message() function (see "Obtaining a textual error mes-
- sage" below) should be self-explanatory. Macro names starting with
- PCRE2_ERROR_ are defined for both positive and negative error codes in
+ sage" below) should be self-explanatory. Macro names starting with
+ PCRE2_ERROR_ are defined for both positive and negative error codes in
pcre2.h.
The value returned in erroroffset is an indication of where in the pat-
- tern the error occurred. It is not necessarily the furthest point in
+ tern the error occurred. It is not necessarily the furthest point in
the pattern that was read. For example, after the error "lookbehind as-
- sertion is not fixed length", the error offset points to the start of
- the failing assertion. For an invalid UTF-8 or UTF-16 string, the off-
+ sertion is not fixed length", the error offset points to the start of
+ the failing assertion. For an invalid UTF-8 or UTF-16 string, the off-
set is that of the first code unit of the failing character.
- Some errors are not detected until the whole pattern has been scanned;
- in these cases, the offset passed back is the length of the pattern.
- Note that the offset is in code units, not characters, even in a UTF
+ Some errors are not detected until the whole pattern has been scanned;
+ in these cases, the offset passed back is the length of the pattern.
+ Note that the offset is in code units, not characters, even in a UTF
mode. It may sometimes point into the middle of a UTF-8 or UTF-16 char-
acter.
- This code fragment shows a typical straightforward call to pcre2_com-
+ This code fragment shows a typical straightforward call to pcre2_com-
pile():
pcre2_code *re;
@@ -1382,92 +1412,95 @@ COMPILING A PATTERN
Main compile options
- The following names for option bits are defined in the pcre2.h header
+ The following names for option bits are defined in the pcre2.h header
file:
PCRE2_ANCHORED
If this bit is set, the pattern is forced to be "anchored", that is, it
- is constrained to match only at the first matching point in the string
- that is being searched (the "subject string"). This effect can also be
- achieved by appropriate constructs in the pattern itself, which is the
+ is constrained to match only at the first matching point in the string
+ that is being searched (the "subject string"). This effect can also be
+ achieved by appropriate constructs in the pattern itself, which is the
only way to do it in Perl.
PCRE2_ALLOW_EMPTY_CLASS
- By default, for compatibility with Perl, a closing square bracket that
- immediately follows an opening one is treated as a data character for
- the class. When PCRE2_ALLOW_EMPTY_CLASS is set, it terminates the
+ By default, for compatibility with Perl, a closing square bracket that
+ immediately follows an opening one is treated as a data character for
+ the class. When PCRE2_ALLOW_EMPTY_CLASS is set, it terminates the
class, which therefore contains no characters and so can never match.
PCRE2_ALT_BSUX
- This option request alternative handling of three escape sequences,
- which makes PCRE2's behaviour more like ECMAscript (aka JavaScript).
+ This option request alternative handling of three escape sequences,
+ which makes PCRE2's behaviour more like ECMAscript (aka JavaScript).
When it is set:
(1) \U matches an upper case "U" character; by default \U causes a com-
pile time error (Perl uses \U to upper case subsequent characters).
(2) \u matches a lower case "u" character unless it is followed by four
- hexadecimal digits, in which case the hexadecimal number defines the
- code point to match. By default, \u causes a compile time error (Perl
+ hexadecimal digits, in which case the hexadecimal number defines the
+ code point to match. By default, \u causes a compile time error (Perl
uses it to upper case the following character).
- (3) \x matches a lower case "x" character unless it is followed by two
- hexadecimal digits, in which case the hexadecimal number defines the
- code point to match. By default, as in Perl, a hexadecimal number is
+ (3) \x matches a lower case "x" character unless it is followed by two
+ hexadecimal digits, in which case the hexadecimal number defines the
+ code point to match. By default, as in Perl, a hexadecimal number is
always expected after \x, but it may have zero, one, or two digits (so,
for example, \xz matches a binary zero character followed by z).
ECMAscript 6 added additional functionality to \u. This can be accessed
- using the PCRE2_EXTRA_ALT_BSUX extra option (see "Extra compile op-
+ using the PCRE2_EXTRA_ALT_BSUX extra option (see "Extra compile op-
tions" below). Note that this alternative escape handling applies only
- to patterns. Neither of these options affects the processing of re-
+ to patterns. Neither of these options affects the processing of re-
placement strings passed to pcre2_substitute().
PCRE2_ALT_CIRCUMFLEX
In multiline mode (when PCRE2_MULTILINE is set), the circumflex
- metacharacter matches at the start of the subject (unless PCRE2_NOTBOL
- is set), and also after any internal newline. However, it does not
+ metacharacter matches at the start of the subject (unless PCRE2_NOTBOL
+ is set), and also after any internal newline. However, it does not
match after a newline at the end of the subject, for compatibility with
- Perl. If you want a multiline circumflex also to match after a termi-
+ Perl. If you want a multiline circumflex also to match after a termi-
nating newline, you must set PCRE2_ALT_CIRCUMFLEX.
PCRE2_ALT_VERBNAMES
- By default, for compatibility with Perl, the name in any verb sequence
- such as (*MARK:NAME) is any sequence of characters that does not in-
- clude a closing parenthesis. The name is not processed in any way, and
- it is not possible to include a closing parenthesis in the name. How-
- ever, if the PCRE2_ALT_VERBNAMES option is set, normal backslash pro-
- cessing is applied to verb names and only an unescaped closing paren-
- thesis terminates the name. A closing parenthesis can be included in a
- name either as \) or between \Q and \E. If the PCRE2_EXTENDED or
- PCRE2_EXTENDED_MORE option is set with PCRE2_ALT_VERBNAMES, unescaped
- whitespace in verb names is skipped and #-comments are recognized, ex-
+ By default, for compatibility with Perl, the name in any verb sequence
+ such as (*MARK:NAME) is any sequence of characters that does not in-
+ clude a closing parenthesis. The name is not processed in any way, and
+ it is not possible to include a closing parenthesis in the name. How-
+ ever, if the PCRE2_ALT_VERBNAMES option is set, normal backslash pro-
+ cessing is applied to verb names and only an unescaped closing paren-
+ thesis terminates the name. A closing parenthesis can be included in a
+ name either as \) or between \Q and \E. If the PCRE2_EXTENDED or
+ PCRE2_EXTENDED_MORE option is set with PCRE2_ALT_VERBNAMES, unescaped
+ whitespace in verb names is skipped and #-comments are recognized, ex-
actly as in the rest of the pattern.
PCRE2_AUTO_CALLOUT
- If this bit is set, pcre2_compile() automatically inserts callout
- items, all with number 255, before each pattern item, except immedi-
- ately before or after an explicit callout in the pattern. For discus-
+ If this bit is set, pcre2_compile() automatically inserts callout
+ items, all with number 255, before each pattern item, except immedi-
+ ately before or after an explicit callout in the pattern. For discus-
sion of the callout facility, see the pcre2callout documentation.
PCRE2_CASELESS
- If this bit is set, letters in the pattern match both upper and lower
- case letters in the subject. It is equivalent to Perl's /i option, and
- it can be changed within a pattern by a (?i) option setting. If either
- PCRE2_UTF or PCRE2_UCP is set, Unicode properties are used for all
- characters with more than one other case, and for all characters whose
- code points are greater than U+007F. For lower valued characters with
- only one other case, a lookup table is used for speed. When neither
- PCRE2_UTF nor PCRE2_UCP is set, a lookup table is used for all code
- points less than 256, and higher code points (available only in 16-bit
- or 32-bit mode) are treated as not having another case.
+ If this bit is set, letters in the pattern match both upper and lower
+ case letters in the subject. It is equivalent to Perl's /i option, and
+ it can be changed within a pattern by a (?i) option setting. If either
+ PCRE2_UTF or PCRE2_UCP is set, Unicode properties are used for all
+ characters with more than one other case, and for all characters whose
+ code points are greater than U+007F. Note that there are two ASCII
+ characters, K and S, that, in addition to their lower case ASCII equiv-
+ alents, are case-equivalent with U+212A (Kelvin sign) and U+017F (long
+ S) respectively. For lower valued characters with only one other case,
+ a lookup table is used for speed. When neither PCRE2_UTF nor PCRE2_UCP
+ is set, a lookup table is used for all code points less than 256, and
+ higher code points (available only in 16-bit or 32-bit mode) are
+ treated as not having another case.
PCRE2_DOLLAR_ENDONLY
@@ -3793,7 +3826,7 @@ AUTHOR
REVISION
- Last updated: 19 March 2020
+ Last updated: 04 November 2020
Copyright (c) 1997-2020 University of Cambridge.
------------------------------------------------------------------------------
@@ -4831,10 +4864,10 @@ NAME
DIFFERENCES BETWEEN PCRE2 AND PERL
- This document describes the differences in the ways that PCRE2 and Perl
- handle regular expressions. The differences described here are with re-
- spect to Perl versions 5.26, but as both Perl and PCRE2 are continually
- changing, the information may sometimes be out of date.
+ This document describes some of the differences in the ways that PCRE2
+ and Perl handle regular expressions. The differences described here are
+ with respect to Perl version 5.32.0, but as both Perl and PCRE2 are
+ continually changing, the information may at times be out of date.
1. PCRE2 has only a subset of Perl's Unicode support. Details of what
it does have are given in the pcre2unicode page.
@@ -4845,40 +4878,43 @@ DIFFERENCES BETWEEN PCRE2 AND PERL
serts that the next character is not "a" three times (in principle;
PCRE2 optimizes this to run the assertion just once). Perl allows some
repeat quantifiers on other assertions, for example, \b* (but not
- \b{3}), but these do not seem to have any use.
+ \b{3}, though oddly it does allow ^{3}), but these do not seem to have
+ any use. PCRE2 does not allow any kind of quantifier on non-lookaround
+ assertions.
3. Capture groups that occur inside negative lookaround assertions are
counted, but their entries in the offsets vector are set only when a
negative assertion is a condition that has a matching branch (that is,
- the condition is false).
+ the condition is false). Perl may set such capture groups in other
+ circumstances.
- 4. The following Perl escape sequences are not supported: \F, \l, \L,
+ 4. The following Perl escape sequences are not supported: \F, \l, \L,
\u, \U, and \N when followed by a character name. \N on its own, match-
- ing a non-newline character, and \N{U+dd..}, matching a Unicode code
- point, are supported. The escapes that modify the case of following
- letters are implemented by Perl's general string-handling and are not
+ ing a non-newline character, and \N{U+dd..}, matching a Unicode code
+ point, are supported. The escapes that modify the case of following
+ letters are implemented by Perl's general string-handling and are not
part of its pattern matching engine. If any of these are encountered by
- PCRE2, an error is generated by default. However, if either of the
- PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX options is set, \U and \u are
+ PCRE2, an error is generated by default. However, if either of the
+ PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX options is set, \U and \u are
interpreted as ECMAScript interprets them.
5. The Perl escape sequences \p, \P, and \X are supported only if PCRE2
is built with Unicode support (the default). The properties that can be
- tested with \p and \P are limited to the general category properties
- such as Lu and Nd, script names such as Greek or Han, and the derived
- properties Any and L&. PCRE2 does support the Cs (surrogate) property,
- which Perl does not; the Perl documentation says "Because Perl hides
- the need for the user to understand the internal representation of Uni-
- code characters, there is no need to implement the somewhat messy con-
- cept of surrogates."
+ tested with \p and \P are limited to the general category properties
+ such as Lu and Nd, script names such as Greek or Han, and the derived
+ properties Any and L&. Both PCRE2 and Perl support the Cs (surrogate)
+ property, but in PCRE2 its use is limited. See the pcre2pattern docu-
+ mentation for details. The long synonyms for property names that Perl
+ supports (such as \p{Letter}) are not supported by PCRE2, nor is it
+ permitted to prefix any of these properties with "Is".
6. PCRE2 supports the \Q...\E escape for quoting substrings. Characters
in between are treated as literals. However, this is slightly different
- from Perl in that $ and @ are also handled as literals inside the
+ from Perl in that $ and @ are also handled as literals inside the
quotes. In Perl, they cause variable interpolation (but of course PCRE2
does not have variables). Also, Perl does "double-quotish backslash in-
terpolation" on any backslashes between \Q and \E which, its documenta-
- tion says, "may lead to confusing results". PCRE2 treats a backslash
+ tion says, "may lead to confusing results". PCRE2 treats a backslash
between \Q and \E just like any other character. Note the following ex-
amples:
@@ -4891,78 +4927,79 @@ DIFFERENCES BETWEEN PCRE2 AND PERL
\QA\B\E A\B A\B
\Q\\E \ \\E
- The \Q...\E sequence is recognized both inside and outside character
- classes.
+ The \Q...\E sequence is recognized both inside and outside character
+ classes by both PCRE2 and Perl.
- 7. Fairly obviously, PCRE2 does not support the (?{code}) and
+ 7. Fairly obviously, PCRE2 does not support the (?{code}) and
(??{code}) constructions. However, PCRE2 does have a "callout" feature,
which allows an external function to be called during pattern matching.
See the pcre2callout documentation for details.
- 8. Subroutine calls (whether recursive or not) were treated as atomic
- groups up to PCRE2 release 10.23, but from release 10.30 this changed,
+ 8. Subroutine calls (whether recursive or not) were treated as atomic
+ groups up to PCRE2 release 10.23, but from release 10.30 this changed,
and backtracking into subroutine calls is now supported, as in Perl.
- 9. If any of the backtracking control verbs are used in a group that is
- called as a subroutine (whether or not recursively), their effect is
- confined to that group; it does not extend to the surrounding pattern.
- This is not always the case in Perl. In particular, if (*THEN) is
- present in a group that is called as a subroutine, its action is lim-
- ited to that group, even if the group does not contain any | charac-
- ters. Note that such groups are processed as anchored at the point
- where they are tested.
-
- 10. If a pattern contains more than one backtracking control verb, the
- first one that is backtracked onto acts. For example, in the pattern
- A(*COMMIT)B(*PRUNE)C a failure in B triggers (*COMMIT), but a failure
+ 9. In PCRE2, if any of the backtracking control verbs are used in a
+ group that is called as a subroutine (whether or not recursively),
+ their effect is confined to that group; it does not extend to the sur-
+ rounding pattern. This is not always the case in Perl. In particular,
+ if (*THEN) is present in a group that is called as a subroutine, its
+ action is limited to that group, even if the group does not contain any
+ | characters. Note that such groups are processed as anchored at the
+ point where they are tested.
+
+ 10. If a pattern contains more than one backtracking control verb, the
+ first one that is backtracked onto acts. For example, in the pattern
+ A(*COMMIT)B(*PRUNE)C a failure in B triggers (*COMMIT), but a failure
in C triggers (*PRUNE). Perl's behaviour is more complex; in many cases
it is the same as PCRE2, but there are cases where it differs.
- 11. Most backtracking verbs in assertions have their normal actions.
- They are not confined to the assertion.
-
- 12. There are some differences that are concerned with the settings of
+ 11. There are some differences that are concerned with the settings of
captured strings when part of a pattern is repeated. For example,
matching "aba" against the pattern /^(a(b)?)+$/ in Perl leaves $2 un-
set, but in PCRE2 it is set to "b".
- 13. PCRE2's handling of duplicate capture group numbers and names is
+ 12. PCRE2's handling of duplicate capture group numbers and names is
not as general as Perl's. This is a consequence of the fact the PCRE2
works internally just with numbers, using an external table to trans-
late between numbers and names. In particular, a pattern such as
- (?|(?<a>A)|(?<b>B), where the two capture groups have the same number
+ (?|(?<a>A)|(?<b>B)), where the two capture groups have the same number
but different names, is not supported, and causes an error at compile
time. If it were allowed, it would not be possible to distinguish which
group matched, because both names map to capture group number 1. To
avoid this confusing situation, an error is given at compile time.
- 14. Perl used to recognize comments in some places that PCRE2 does not,
+ 13. Perl used to recognize comments in some places that PCRE2 does not,
for example, between the ( and ? at the start of a group. If the /x
modifier is set, Perl allowed white space between ( and ? though the
latest Perls give an error (for a while it was just deprecated). There
may still be some cases where Perl behaves differently.
- 15. Perl, when in warning mode, gives warnings for character classes
+ 14. Perl, when in warning mode, gives warnings for character classes
such as [A-\d] or [a-[:digit:]]. It then treats the hyphens as liter-
als. PCRE2 has no warning features, so it gives an error in these cases
because they are almost certainly user mistakes.
- 16. In PCRE2, the upper/lower case character properties Lu and Ll are
+ 15. In PCRE2, the upper/lower case character properties Lu and Ll are
not affected when case-independent matching is specified. For example,
\p{Lu} always matches an upper case letter. I think Perl has changed in
- this respect; in the release at the time of writing (5.24), \p{Lu} and
+ this respect; in the release at the time of writing (5.32), \p{Lu} and
\p{Ll} match all letters, regardless of case, when case independence is
specified.
+ 16. From release 5.32.0, Perl locks out the use of \K in lookaround as-
+ sertions. In PCRE2, \K is acted on when it occurs in positive asser-
+ tions, but is ignored in negative assertions.
+
17. PCRE2 provides some extensions to the Perl regular expression fa-
- cilities. Perl 5.10 includes new features that are not in earlier ver-
- sions of Perl, some of which (such as named parentheses) were in PCRE2
- for some time before. This list is with respect to Perl 5.26:
+ cilities. Perl 5.10 included new features that were not in earlier
+ versions of Perl, some of which (such as named parentheses) were in
+ PCRE2 for some time before. This list is with respect to Perl 5.32:
(a) Although lookbehind assertions in PCRE2 must match fixed length
- strings, each alternative branch of a lookbehind assertion can match a
- different length of string. Perl requires them all to have the same
- length.
+ strings, each alternative toplevel branch of a lookbehind assertion can
+ match a different length of string. Perl requires them all to have the
+ same length.
(b) From PCRE2 10.23, backreferences to groups of fixed length are sup-
ported in lookbehinds, provided that there is no possibility of refer-
@@ -4997,7 +5034,7 @@ DIFFERENCES BETWEEN PCRE2 AND PERL
different way and is not Perl-compatible.
(l) PCRE2 recognizes some special sequences such as (*CR) or (*NO_JIT)
- at the start of a pattern that set overall options that cannot be
+ at the start of a pattern. These set overall options that cannot be
changed within the pattern.
(m) PCRE2 supports non-atomic positive lookaround assertions. This is
@@ -5026,7 +5063,7 @@ AUTHOR
REVISION
- Last updated: 13 July 2019
+ Last updated: 06 October 2020
Copyright (c) 1997-2019 University of Cambridge.
------------------------------------------------------------------------------
@@ -6353,8 +6390,12 @@ CHARACTERS AND METACHARACTERS
The quick brown fox
matches a portion of a subject string that is identical to itself. When
- caseless matching is specified (the PCRE2_CASELESS option), letters are
- matched independently of case.
+ caseless matching is specified (the PCRE2_CASELESS option or (?i)
+ within the pattern), letters are matched independently of case. Note
+ that there are two ASCII characters, K and S, that, in addition to
+ their lower case ASCII equivalents, are case-equivalent with Unicode
+ U+212A (Kelvin sign) and U+017F (long S) respectively when either
+ PCRE2_UTF or PCRE2_UCP is set.
The power of regular expressions comes from the ability to include wild
cards, character classes, alternatives, and repetitions in the pattern.
@@ -6389,6 +6430,18 @@ CHARACTERS AND METACHARACTERS
[ POSIX character class (if followed by POSIX syntax)
] terminates the character class
+ If a pattern is compiled with the PCRE2_EXTENDED option, most white
+ space in the pattern, other than in a character class, and characters
+ between a # outside a character class and the next newline, inclusive,
+ are ignored. An escaping backslash can be used to include a white space
+ or a # character as part of the pattern. If the PCRE2_EXTENDED_MORE op-
+ tion is set, the same applies, but in addition unescaped space and hor-
+ izontal tab characters are ignored inside a character class. Note: only
+ these two characters are ignored, not the full set of pattern white
+ space characters that are ignored outside a character class. Option
+ settings can be changed within a pattern; see the section entitled "In-
+ ternal Option Setting" below.
+
The following sections describe the use of each of the metacharacters.
@@ -6406,15 +6459,9 @@ BACKSLASH
that it stands for itself. In particular, if you want to match a back-
slash, you write \\.
- In a UTF mode, only ASCII digits and letters have any special meaning
- after a backslash. All other characters (in particular, those whose
- code points are greater than 127) are treated as literals.
-
- If a pattern is compiled with the PCRE2_EXTENDED option, most white
- space in the pattern (other than in a character class), and characters
- between a # outside a character class and the next newline, inclusive,
- are ignored. An escaping backslash can be used to include a white space
- or # character as part of the pattern.
+ Only ASCII digits and letters have any special meaning after a back-
+ slash. All other characters (in particular, those whose code points are
+ greater than 127) are treated as literals.
If you want to treat all characters in a sequence as literals, you can
do so by putting them between \Q and \E. This is different from Perl in
@@ -7039,27 +7086,28 @@ BACKSLASH
matches "foobar", the first substring is still set to "foo".
- Perl documents that the use of \K within assertions is "not well de-
- fined". In PCRE2, \K is acted upon when it occurs inside positive as-
- sertions, but is ignored in negative assertions. Note that when a pat-
- tern such as (?=ab\K) matches, the reported start of the match can be
- greater than the end of the match. Using \K in a lookbehind assertion
- at the start of a pattern can also lead to odd effects. For example,
- consider this pattern:
+ Perl used to document that the use of \K within lookaround assertions
+ is "not well defined", but from version 5.32.0 Perl does not support
+ this usage at all. In PCRE2, \K is acted upon when it occurs inside
+ positive assertions, but is ignored in negative assertions. Note that
+ when a pattern such as (?=ab\K) matches, the reported start of the
+ match can be greater than the end of the match. Using \K in a lookbe-
+ hind assertion at the start of a pattern can also lead to odd effects.
+ For example, consider this pattern:
(?<=\Kfoo)bar
- If the subject is "foobar", a call to pcre2_match() with a starting
- offset of 3 succeeds and reports the matching string as "foobar", that
- is, the start of the reported match is earlier than where the match
+ If the subject is "foobar", a call to pcre2_match() with a starting
+ offset of 3 succeeds and reports the matching string as "foobar", that
+ is, the start of the reported match is earlier than where the match
started.
Simple assertions
- The final use of backslash is for certain simple assertions. An asser-
- tion specifies a condition that has to be met at a particular point in
- a match, without consuming any characters from the subject string. The
- use of groups for more complicated assertions is described below. The
+ The final use of backslash is for certain simple assertions. An asser-
+ tion specifies a condition that has to be met at a particular point in
+ a match, without consuming any characters from the subject string. The
+ use of groups for more complicated assertions is described below. The
backslashed assertions are:
\b matches at a word boundary
@@ -7070,191 +7118,191 @@ BACKSLASH
\z matches only at the end of the subject
\G matches at the first matching position in the subject
- Inside a character class, \b has a different meaning; it matches the
- backspace character. If any other of these assertions appears in a
+ Inside a character class, \b has a different meaning; it matches the
+ backspace character. If any other of these assertions appears in a
character class, an "invalid escape sequence" error is generated.
- A word boundary is a position in the subject string where the current
- character and the previous character do not both match \w or \W (i.e.
- one matches \w and the other matches \W), or the start or end of the
- string if the first or last character matches \w, respectively. When
- PCRE2 is built with Unicode support, the meanings of \w and \W can be
+ A word boundary is a position in the subject string where the current
+ character and the previous character do not both match \w or \W (i.e.
+ one matches \w and the other matches \W), or the start or end of the
+ string if the first or last character matches \w, respectively. When
+ PCRE2 is built with Unicode support, the meanings of \w and \W can be
changed by setting the PCRE2_UCP option. When this is done, it also af-
- fects \b and \B. Neither PCRE2 nor Perl has a separate "start of word"
- or "end of word" metasequence. However, whatever follows \b normally
- determines which it is. For example, the fragment \ba matches "a" at
+ fects \b and \B. Neither PCRE2 nor Perl has a separate "start of word"
+ or "end of word" metasequence. However, whatever follows \b normally
+ determines which it is. For example, the fragment \ba matches "a" at
the start of a word.
- The \A, \Z, and \z assertions differ from the traditional circumflex
+ The \A, \Z, and \z assertions differ from the traditional circumflex
and dollar (described in the next section) in that they only ever match
- at the very start and end of the subject string, whatever options are
- set. Thus, they are independent of multiline mode. These three asser-
- tions are not affected by the PCRE2_NOTBOL or PCRE2_NOTEOL options,
- which affect only the behaviour of the circumflex and dollar metachar-
- acters. However, if the startoffset argument of pcre2_match() is non-
- zero, indicating that matching is to start at a point other than the
- beginning of the subject, \A can never match. The difference between
- \Z and \z is that \Z matches before a newline at the end of the string
+ at the very start and end of the subject string, whatever options are
+ set. Thus, they are independent of multiline mode. These three asser-
+ tions are not affected by the PCRE2_NOTBOL or PCRE2_NOTEOL options,
+ which affect only the behaviour of the circumflex and dollar metachar-
+ acters. However, if the startoffset argument of pcre2_match() is non-
+ zero, indicating that matching is to start at a point other than the
+ beginning of the subject, \A can never match. The difference between
+ \Z and \z is that \Z matches before a newline at the end of the string
as well as at the very end, whereas \z matches only at the end.
- The \G assertion is true only when the current matching position is at
- the start point of the matching process, as specified by the startoff-
- set argument of pcre2_match(). It differs from \A when the value of
- startoffset is non-zero. By calling pcre2_match() multiple times with
- appropriate arguments, you can mimic Perl's /g option, and it is in
+ The \G assertion is true only when the current matching position is at
+ the start point of the matching process, as specified by the startoff-
+ set argument of pcre2_match(). It differs from \A when the value of
+ startoffset is non-zero. By calling pcre2_match() multiple times with
+ appropriate arguments, you can mimic Perl's /g option, and it is in
this kind of implementation where \G can be useful.
- Note, however, that PCRE2's implementation of \G, being true at the
- starting character of the matching process, is subtly different from
- Perl's, which defines it as true at the end of the previous match. In
- Perl, these can be different when the previously matched string was
+ Note, however, that PCRE2's implementation of \G, being true at the
+ starting character of the matching process, is subtly different from
+ Perl's, which defines it as true at the end of the previous match. In
+ Perl, these can be different when the previously matched string was
empty. Because PCRE2 does just one match at a time, it cannot reproduce
this behaviour.
- If all the alternatives of a pattern begin with \G, the expression is
+ If all the alternatives of a pattern begin with \G, the expression is
anchored to the starting match position, and the "anchored" flag is set
in the compiled regular expression.
CIRCUMFLEX AND DOLLAR
- The circumflex and dollar metacharacters are zero-width assertions.
- That is, they test for a particular condition being true without con-
+ The circumflex and dollar metacharacters are zero-width assertions.
+ That is, they test for a particular condition being true without con-
suming any characters from the subject string. These two metacharacters
- are concerned with matching the starts and ends of lines. If the new-
- line convention is set so that only the two-character sequence CRLF is
- recognized as a newline, isolated CR and LF characters are treated as
+ are concerned with matching the starts and ends of lines. If the new-
+ line convention is set so that only the two-character sequence CRLF is
+ recognized as a newline, isolated CR and LF characters are treated as
ordinary data characters, and are not recognized as newlines.
Outside a character class, in the default matching mode, the circumflex
- character is an assertion that is true only if the current matching
- point is at the start of the subject string. If the startoffset argu-
- ment of pcre2_match() is non-zero, or if PCRE2_NOTBOL is set, circum-
- flex can never match if the PCRE2_MULTILINE option is unset. Inside a
- character class, circumflex has an entirely different meaning (see be-
+ character is an assertion that is true only if the current matching
+ point is at the start of the subject string. If the startoffset argu-
+ ment of pcre2_match() is non-zero, or if PCRE2_NOTBOL is set, circum-
+ flex can never match if the PCRE2_MULTILINE option is unset. Inside a
+ character class, circumflex has an entirely different meaning (see be-
low).
- Circumflex need not be the first character of the pattern if a number
- of alternatives are involved, but it should be the first thing in each
- alternative in which it appears if the pattern is ever to match that
- branch. If all possible alternatives start with a circumflex, that is,
- if the pattern is constrained to match only at the start of the sub-
- ject, it is said to be an "anchored" pattern. (There are also other
+ Circumflex need not be the first character of the pattern if a number
+ of alternatives are involved, but it should be the first thing in each
+ alternative in which it appears if the pattern is ever to match that
+ branch. If all possible alternatives start with a circumflex, that is,
+ if the pattern is constrained to match only at the start of the sub-
+ ject, it is said to be an "anchored" pattern. (There are also other
constructs that can cause a pattern to be anchored.)
- The dollar character is an assertion that is true only if the current
- matching point is at the end of the subject string, or immediately be-
- fore a newline at the end of the string (by default), unless PCRE2_NO-
- TEOL is set. Note, however, that it does not actually match the new-
- line. Dollar need not be the last character of the pattern if a number
- of alternatives are involved, but it should be the last item in any
- branch in which it appears. Dollar has no special meaning in a charac-
+ The dollar character is an assertion that is true only if the current
+ matching point is at the end of the subject string, or immediately be-
+ fore a newline at the end of the string (by default), unless PCRE2_NO-
+ TEOL is set. Note, however, that it does not actually match the new-
+ line. Dollar need not be the last character of the pattern if a number
+ of alternatives are involved, but it should be the last item in any
+ branch in which it appears. Dollar has no special meaning in a charac-
ter class.
- The meaning of dollar can be changed so that it matches only at the
- very end of the string, by setting the PCRE2_DOLLAR_ENDONLY option at
+ The meaning of dollar can be changed so that it matches only at the
+ very end of the string, by setting the PCRE2_DOLLAR_ENDONLY option at
compile time. This does not affect the \Z assertion.
The meanings of the circumflex and dollar metacharacters are changed if
- the PCRE2_MULTILINE option is set. When this is the case, a dollar
- character matches before any newlines in the string, as well as at the
- very end, and a circumflex matches immediately after internal newlines
- as well as at the start of the subject string. It does not match after
- a newline that ends the string, for compatibility with Perl. However,
+ the PCRE2_MULTILINE option is set. When this is the case, a dollar
+ character matches before any newlines in the string, as well as at the
+ very end, and a circumflex matches immediately after internal newlines
+ as well as at the start of the subject string. It does not match after
+ a newline that ends the string, for compatibility with Perl. However,
this can be changed by setting the PCRE2_ALT_CIRCUMFLEX option.
- For example, the pattern /^abc$/ matches the subject string "def\nabc"
- (where \n represents a newline) in multiline mode, but not otherwise.
- Consequently, patterns that are anchored in single line mode because
- all branches start with ^ are not anchored in multiline mode, and a
- match for circumflex is possible when the startoffset argument of
- pcre2_match() is non-zero. The PCRE2_DOLLAR_ENDONLY option is ignored
+ For example, the pattern /^abc$/ matches the subject string "def\nabc"
+ (where \n represents a newline) in multiline mode, but not otherwise.
+ Consequently, patterns that are anchored in single line mode because
+ all branches start with ^ are not anchored in multiline mode, and a
+ match for circumflex is possible when the startoffset argument of
+ pcre2_match() is non-zero. The PCRE2_DOLLAR_ENDONLY option is ignored
if PCRE2_MULTILINE is set.
- When the newline convention (see "Newline conventions" below) recog-
- nizes the two-character sequence CRLF as a newline, this is preferred,
- even if the single characters CR and LF are also recognized as new-
- lines. For example, if the newline convention is "any", a multiline
- mode circumflex matches before "xyz" in the string "abc\r\nxyz" rather
- than after CR, even though CR on its own is a valid newline. (It also
+ When the newline convention (see "Newline conventions" below) recog-
+ nizes the two-character sequence CRLF as a newline, this is preferred,
+ even if the single characters CR and LF are also recognized as new-
+ lines. For example, if the newline convention is "any", a multiline
+ mode circumflex matches before "xyz" in the string "abc\r\nxyz" rather
+ than after CR, even though CR on its own is a valid newline. (It also
matches at the very start of the string, of course.)
- Note that the sequences \A, \Z, and \z can be used to match the start
- and end of the subject in both modes, and if all branches of a pattern
- start with \A it is always anchored, whether or not PCRE2_MULTILINE is
+ Note that the sequences \A, \Z, and \z can be used to match the start
+ and end of the subject in both modes, and if all branches of a pattern
+ start with \A it is always anchored, whether or not PCRE2_MULTILINE is
set.
FULL STOP (PERIOD, DOT) AND \N
Outside a character class, a dot in the pattern matches any one charac-
- ter in the subject string except (by default) a character that signi-
+ ter in the subject string except (by default) a character that signi-
fies the end of a line.
- When a line ending is defined as a single character, dot never matches
- that character; when the two-character sequence CRLF is used, dot does
- not match CR if it is immediately followed by LF, but otherwise it
- matches all characters (including isolated CRs and LFs). When any Uni-
- code line endings are being recognized, dot does not match CR or LF or
+ When a line ending is defined as a single character, dot never matches
+ that character; when the two-character sequence CRLF is used, dot does
+ not match CR if it is immediately followed by LF, but otherwise it
+ matches all characters (including isolated CRs and LFs). When any Uni-
+ code line endings are being recognized, dot does not match CR or LF or
any of the other line ending characters.
- The behaviour of dot with regard to newlines can be changed. If the
- PCRE2_DOTALL option is set, a dot matches any one character, without
- exception. If the two-character sequence CRLF is present in the sub-
+ The behaviour of dot with regard to newlines can be changed. If the
+ PCRE2_DOTALL option is set, a dot matches any one character, without
+ exception. If the two-character sequence CRLF is present in the sub-
ject string, it takes two dots to match it.
- The handling of dot is entirely independent of the handling of circum-
- flex and dollar, the only relationship being that they both involve
+ The handling of dot is entirely independent of the handling of circum-
+ flex and dollar, the only relationship being that they both involve
newlines. Dot has no special meaning in a character class.
- The escape sequence \N when not followed by an opening brace behaves
- like a dot, except that it is not affected by the PCRE2_DOTALL option.
- In other words, it matches any character except one that signifies the
+ The escape sequence \N when not followed by an opening brace behaves
+ like a dot, except that it is not affected by the PCRE2_DOTALL option.
+ In other words, it matches any character except one that signifies the
end of a line.
When \N is followed by an opening brace it has a different meaning. See
- the section entitled "Non-printing characters" above for details. Perl
- also uses \N{name} to specify characters by Unicode name; PCRE2 does
+ the section entitled "Non-printing characters" above for details. Perl
+ also uses \N{name} to specify characters by Unicode name; PCRE2 does
not support this.
MATCHING A SINGLE CODE UNIT
- Outside a character class, the escape sequence \C matches any one code
- unit, whether or not a UTF mode is set. In the 8-bit library, one code
- unit is one byte; in the 16-bit library it is a 16-bit unit; in the
- 32-bit library it is a 32-bit unit. Unlike a dot, \C always matches
- line-ending characters. The feature is provided in Perl in order to
+ Outside a character class, the escape sequence \C matches any one code
+ unit, whether or not a UTF mode is set. In the 8-bit library, one code
+ unit is one byte; in the 16-bit library it is a 16-bit unit; in the
+ 32-bit library it is a 32-bit unit. Unlike a dot, \C always matches
+ line-ending characters. The feature is provided in Perl in order to
match individual bytes in UTF-8 mode, but it is unclear how it can use-
fully be used.
- Because \C breaks up characters into individual code units, matching
- one unit with \C in UTF-8 or UTF-16 mode means that the rest of the
+ Because \C breaks up characters into individual code units, matching
+ one unit with \C in UTF-8 or UTF-16 mode means that the rest of the
string may start with a malformed UTF character. This has undefined re-
sults, because PCRE2 assumes that it is matching character by character
in a valid UTF string (by default it checks the subject string's valid-
- ity at the start of processing unless the PCRE2_NO_UTF_CHECK or
+ ity at the start of processing unless the PCRE2_NO_UTF_CHECK or
PCRE2_MATCH_INVALID_UTF option is used).
- An application can lock out the use of \C by setting the
- PCRE2_NEVER_BACKSLASH_C option when compiling a pattern. It is also
+ An application can lock out the use of \C by setting the
+ PCRE2_NEVER_BACKSLASH_C option when compiling a pattern. It is also
possible to build PCRE2 with the use of \C permanently disabled.
- PCRE2 does not allow \C to appear in lookbehind assertions (described
- below) in UTF-8 or UTF-16 modes, because this would make it impossible
- to calculate the length of the lookbehind. Neither the alternative
+ PCRE2 does not allow \C to appear in lookbehind assertions (described
+ below) in UTF-8 or UTF-16 modes, because this would make it impossible
+ to calculate the length of the lookbehind. Neither the alternative
matching function pcre2_dfa_match() nor the JIT optimizer support \C in
these UTF modes. The former gives a match-time error; the latter fails
to optimize and so the match is always run using the interpreter.
- In the 32-bit library, however, \C is always supported (when not ex-
- plicitly locked out) because it always matches a single code unit,
+ In the 32-bit library, however, \C is always supported (when not ex-
+ plicitly locked out) because it always matches a single code unit,
whether or not UTF-32 is specified.
In general, the \C escape sequence is best avoided. However, one way of
- using it that avoids the problem of malformed UTF-8 or UTF-16 charac-
- ters is to use a lookahead to check the length of the next character,
- as in this pattern, which could be used with a UTF-8 string (ignore
+ using it that avoids the problem of malformed UTF-8 or UTF-16 charac-
+ ters is to use a lookahead to check the length of the next character,
+ as in this pattern, which could be used with a UTF-8 string (ignore
white space and line breaks):
(?| (?=[\x00-\x7f])(\C) |
@@ -7262,11 +7310,11 @@ MATCHING A SINGLE CODE UNIT
(?=[\x{800}-\x{ffff}])(\C)(\C)(\C) |
(?=[\x{10000}-\x{1fffff}])(\C)(\C)(\C)(\C))
- In this example, a group that starts with (?| resets the capturing
- parentheses numbers in each alternative (see "Duplicate Group Numbers"
+ In this example, a group that starts with (?| resets the capturing
+ parentheses numbers in each alternative (see "Duplicate Group Numbers"
below). The assertions at the start of each branch check the next UTF-8
- character for values whose encoding uses 1, 2, 3, or 4 bytes, respec-
- tively. The character's individual bytes are then captured by the ap-
+ character for values whose encoding uses 1, 2, 3, or 4 bytes, respec-
+ tively. The character's individual bytes are then captured by the ap-
propriate number of \C groups.
@@ -7274,34 +7322,37 @@ SQUARE BRACKETS AND CHARACTER CLASSES
An opening square bracket introduces a character class, terminated by a
closing square bracket. A closing square bracket on its own is not spe-
- cial by default. If a closing square bracket is required as a member
+ cial by default. If a closing square bracket is required as a member
of the class, it should be the first data character in the class (after
- an initial circumflex, if present) or escaped with a backslash. This
- means that, by default, an empty class cannot be defined. However, if
- the PCRE2_ALLOW_EMPTY_CLASS option is set, a closing square bracket at
+ an initial circumflex, if present) or escaped with a backslash. This
+ means that, by default, an empty class cannot be defined. However, if
+ the PCRE2_ALLOW_EMPTY_CLASS option is set, a closing square bracket at
the start does end the (empty) class.
- A character class matches a single character in the subject. A matched
+ A character class matches a single character in the subject. A matched
character must be in the set of characters defined by the class, unless
- the first character in the class definition is a circumflex, in which
+ the first character in the class definition is a circumflex, in which
case the subject character must not be in the set defined by the class.
- If a circumflex is actually required as a member of the class, ensure
+ If a circumflex is actually required as a member of the class, ensure
it is not the first character, or escape it with a backslash.
- For example, the character class [aeiou] matches any lower case vowel,
- while [^aeiou] matches any character that is not a lower case vowel.
+ For example, the character class [aeiou] matches any lower case vowel,
+ while [^aeiou] matches any character that is not a lower case vowel.
Note that a circumflex is just a convenient notation for specifying the
- characters that are in the class by enumerating those that are not. A
- class that starts with a circumflex is not an assertion; it still con-
- sumes a character from the subject string, and therefore it fails if
+ characters that are in the class by enumerating those that are not. A
+ class that starts with a circumflex is not an assertion; it still con-
+ sumes a character from the subject string, and therefore it fails if
the current pointer is at the end of the string.
- Characters in a class may be specified by their code points using \o,
- \x, or \N{U+hh..} in the usual way. When caseless matching is set, any
- letters in a class represent both their upper case and lower case ver-
- sions, so for example, a caseless [aeiou] matches "A" as well as "a",
- and a caseless [^aeiou] does not match "A", whereas a caseful version
- would.
+ Characters in a class may be specified by their code points using \o,
+ \x, or \N{U+hh..} in the usual way. When caseless matching is set, any
+ letters in a class represent both their upper case and lower case ver-
+ sions, so for example, a caseless [aeiou] matches "A" as well as "a",
+ and a caseless [^aeiou] does not match "A", whereas a caseful version
+ would. Note that there are two ASCII characters, K and S, that, in ad-
+ dition to their lower case ASCII equivalents, are case-equivalent with
+ Unicode U+212A (Kelvin sign) and U+017F (long S) respectively when ei-
+ ther PCRE2_UTF or PCRE2_UCP is set.
Characters that might indicate line breaks are never treated in any
special way when matching character classes, whatever line-ending se-
@@ -9559,7 +9610,7 @@ AUTHOR
REVISION
- Last updated: 24 February 2020
+ Last updated: 06 October 2020
Copyright (c) 1997-2020 University of Cambridge.
------------------------------------------------------------------------------
diff --git a/doc/pcre2api.3 b/doc/pcre2api.3
index 8c581a0..148dca6 100644
--- a/doc/pcre2api.3
+++ b/doc/pcre2api.3
@@ -1,4 +1,4 @@
-.TH PCRE2API 3 "19 March 2020" "PCRE2 10.35"
+.TH PCRE2API 3 "04 November 2020" "PCRE2 10.36"
.SH NAME
PCRE2 - Perl-compatible regular expressions (revised API)
.sp
@@ -564,24 +564,53 @@ documentation for more details.
.P
In a more complicated situation, where patterns are compiled only when they are
first needed, but are still shared between threads, pointers to compiled
-patterns must be protected from simultaneous writing by multiple threads, at
-least until a pattern has been compiled. The logic can be something like this:
+patterns must be protected from simultaneous writing by multiple threads. This
+is somewhat tricky to do correctly. If you know that writing to a pointer is
+atomic in your environment, you can use logic like this:
.sp
Get a read-only (shared) lock (mutex) for pointer
if (pointer == NULL)
{
Get a write (unique) lock for pointer
- pointer = pcre2_compile(...
+ if (pointer == NULL) pointer = pcre2_compile(...
}
Release the lock
Use pointer in pcre2_match()
.sp
Of course, testing for compilation errors should also be included in the code.
.P
-If JIT is being used, but the JIT compilation is not being done immediately,
-(perhaps waiting to see if the pattern is used often enough) similar logic is
-required. JIT compilation updates a pointer within the compiled code block, so
-a thread must gain unique write access to the pointer before calling
+The reason for checking the pointer a second time is as follows: Several
+threads may have acquired the shared lock and tested the pointer for being
+NULL, but only one of them will be given the write lock, with the rest kept
+waiting. The winning thread will compile the pattern and store the result.
+After this thread releases the write lock, another thread will get it, and if
+it does not retest pointer for being NULL, will recompile the pattern and
+overwrite the pointer, creating a memory leak and possibly causing other
+issues.
+.P
+In an environment where writing to a pointer may not be atomic, the above logic
+is not sufficient. The thread that is doing the compiling may be descheduled
+after writing only part of the pointer, which could cause other threads to use
+an invalid value. Instead of checking the pointer itself, a separate "pointer
+is valid" flag (that can be updated atomically) must be used:
+.sp
+ Get a read-only (shared) lock (mutex) for pointer
+ if (!pointer_is_valid)
+ {
+ Get a write (unique) lock for pointer
+ if (!pointer_is_valid)
+ {
+ pointer = pcre2_compile(...
+ pointer_is_valid = TRUE
+ }
+ }
+ Release the lock
+ Use pointer in pcre2_match()
+.sp
+If JIT is being used, but the JIT compilation is not being done immediately
+(perhaps waiting to see if the pattern is used often enough), similar logic is
+required. JIT compilation updates a value within the compiled code block, so a
+thread must gain unique write access to the pointer before calling
\fBpcre2_jit_compile()\fP. Alternatively, \fBpcre2_code_copy()\fP or
\fBpcre2_code_copy_with_tables()\fP can be used to obtain a private copy of the
compiled code before calling the JIT compiler.
@@ -1434,10 +1463,13 @@ letters in the subject. It is equivalent to Perl's /i option, and it can be
changed within a pattern by a (?i) option setting. If either PCRE2_UTF or
PCRE2_UCP is set, Unicode properties are used for all characters with more than
one other case, and for all characters whose code points are greater than
-U+007F. For lower valued characters with only one other case, a lookup table is
-used for speed. When neither PCRE2_UTF nor PCRE2_UCP is set, a lookup table is
-used for all code points less than 256, and higher code points (available only
-in 16-bit or 32-bit mode) are treated as not having another case.
+U+007F. Note that there are two ASCII characters, K and S, that, in addition to
+their lower case ASCII equivalents, are case-equivalent with U+212A (Kelvin
+sign) and U+017F (long S) respectively. For lower valued characters with only
+one other case, a lookup table is used for speed. When neither PCRE2_UTF nor
+PCRE2_UCP is set, a lookup table is used for all code points less than 256, and
+higher code points (available only in 16-bit or 32-bit mode) are treated as not
+having another case.
.sp
PCRE2_DOLLAR_ENDONLY
.sp
@@ -3968,6 +4000,6 @@ Cambridge, England.
.rs
.sp
.nf
-Last updated: 19 March 2020
+Last updated: 04 November 2020
Copyright (c) 1997-2020 University of Cambridge.
.fi
diff --git a/doc/pcre2compat.3 b/doc/pcre2compat.3
index b4209db..026e664 100644
--- a/doc/pcre2compat.3
+++ b/doc/pcre2compat.3
@@ -1,13 +1,13 @@
-.TH PCRE2COMPAT 3 "13 July 2019" "PCRE2 10.34"
+.TH PCRE2COMPAT 3 "06 October 2020" "PCRE2 10.36"
.SH NAME
PCRE2 - Perl-compatible regular expressions (revised API)
.SH "DIFFERENCES BETWEEN PCRE2 AND PERL"
.rs
.sp
-This document describes the differences in the ways that PCRE2 and Perl handle
-regular expressions. The differences described here are with respect to Perl
-versions 5.26, but as both Perl and PCRE2 are continually changing, the
-information may sometimes be out of date.
+This document describes some of the differences in the ways that PCRE2 and Perl
+handle regular expressions. The differences described here are with respect to
+Perl version 5.32.0, but as both Perl and PCRE2 are continually changing, the
+information may at times be out of date.
.P
1. PCRE2 has only a subset of Perl's Unicode support. Details of what it does
have are given in the
@@ -21,11 +21,14 @@ they do not mean what you might think. For example, (?!a){3} does not assert
that the next three characters are not "a". It just asserts that the next
character is not "a" three times (in principle; PCRE2 optimizes this to run the
assertion just once). Perl allows some repeat quantifiers on other assertions,
-for example, \eb* (but not \eb{3}), but these do not seem to have any use.
+for example, \eb* (but not \eb{3}, though oddly it does allow ^{3}), but these
+do not seem to have any use. PCRE2 does not allow any kind of quantifier on
+non-lookaround assertions.
.P
3. Capture groups that occur inside negative lookaround assertions are counted,
but their entries in the offsets vector are set only when a negative assertion
is a condition that has a matching branch (that is, the condition is false).
+Perl may set such capture groups in other circumstances.
.P
4. The following Perl escape sequences are not supported: \eF, \el, \eL, \eu,
\eU, and \eN when followed by a character name. \eN on its own, matching a
@@ -41,10 +44,14 @@ interprets them.
built with Unicode support (the default). The properties that can be tested
with \ep and \eP are limited to the general category properties such as Lu and
Nd, script names such as Greek or Han, and the derived properties Any and L&.
-PCRE2 does support the Cs (surrogate) property, which Perl does not; the Perl
-documentation says "Because Perl hides the need for the user to understand the
-internal representation of Unicode characters, there is no need to implement
-the somewhat messy concept of surrogates."
+Both PCRE2 and Perl support the Cs (surrogate) property, but in PCRE2 its use
+is limited. See the
+.\" HREF
+\fBpcre2pattern\fP
+.\"
+documentation for details. The long synonyms for property names that Perl
+supports (such as \ep{Letter}) are not supported by PCRE2, nor is it permitted
+to prefix any of these properties with "Is".
.P
6. PCRE2 supports the \eQ...\eE escape for quoting substrings. Characters
in between are treated as literals. However, this is slightly different from
@@ -65,7 +72,8 @@ other character. Note the following examples:
\eQA\eB\eE A\eB A\eB
\eQ\e\eE \e \e\eE
.sp
-The \eQ...\eE sequence is recognized both inside and outside character classes.
+The \eQ...\eE sequence is recognized both inside and outside character classes
+by both PCRE2 and Perl.
.P
7. Fairly obviously, PCRE2 does not support the (?{code}) and (??{code})
constructions. However, PCRE2 does have a "callout" feature, which allows an
@@ -79,13 +87,13 @@ documentation for details.
to PCRE2 release 10.23, but from release 10.30 this changed, and backtracking
into subroutine calls is now supported, as in Perl.
.P
-9. If any of the backtracking control verbs are used in a group that is called
-as a subroutine (whether or not recursively), their effect is confined to that
-group; it does not extend to the surrounding pattern. This is not always the
-case in Perl. In particular, if (*THEN) is present in a group that is called as
-a subroutine, its action is limited to that group, even if the group does not
-contain any | characters. Note that such groups are processed as anchored
-at the point where they are tested.
+9. In PCRE2, if any of the backtracking control verbs are used in a group that
+is called as a subroutine (whether or not recursively), their effect is
+confined to that group; it does not extend to the surrounding pattern. This is
+not always the case in Perl. In particular, if (*THEN) is present in a group
+that is called as a subroutine, its action is limited to that group, even if
+the group does not contain any | characters. Note that such groups are
+processed as anchored at the point where they are tested.
.P
10. If a pattern contains more than one backtracking control verb, the first
one that is backtracked onto acts. For example, in the pattern
@@ -93,48 +101,49 @@ A(*COMMIT)B(*PRUNE)C a failure in B triggers (*COMMIT), but a failure in C
triggers (*PRUNE). Perl's behaviour is more complex; in many cases it is the
same as PCRE2, but there are cases where it differs.
.P
-11. Most backtracking verbs in assertions have their normal actions. They are
-not confined to the assertion.
-.P
-12. There are some differences that are concerned with the settings of captured
+11. There are some differences that are concerned with the settings of captured
strings when part of a pattern is repeated. For example, matching "aba" against
the pattern /^(a(b)?)+$/ in Perl leaves $2 unset, but in PCRE2 it is set to
"b".
.P
-13. PCRE2's handling of duplicate capture group numbers and names is not as
+12. PCRE2's handling of duplicate capture group numbers and names is not as
general as Perl's. This is a consequence of the fact the PCRE2 works internally
just with numbers, using an external table to translate between numbers and
-names. In particular, a pattern such as (?|(?<a>A)|(?<b>B), where the two
+names. In particular, a pattern such as (?|(?<a>A)|(?<b>B)), where the two
capture groups have the same number but different names, is not supported, and
causes an error at compile time. If it were allowed, it would not be possible
to distinguish which group matched, because both names map to capture group
number 1. To avoid this confusing situation, an error is given at compile time.
.P
-14. Perl used to recognize comments in some places that PCRE2 does not, for
+13. Perl used to recognize comments in some places that PCRE2 does not, for
example, between the ( and ? at the start of a group. If the /x modifier is
set, Perl allowed white space between ( and ? though the latest Perls give an
error (for a while it was just deprecated). There may still be some cases where
Perl behaves differently.
.P
-15. Perl, when in warning mode, gives warnings for character classes such as
+14. Perl, when in warning mode, gives warnings for character classes such as
[A-\ed] or [a-[:digit:]]. It then treats the hyphens as literals. PCRE2 has no
warning features, so it gives an error in these cases because they are almost
certainly user mistakes.
.P
-16. In PCRE2, the upper/lower case character properties Lu and Ll are not
+15. In PCRE2, the upper/lower case character properties Lu and Ll are not
affected when case-independent matching is specified. For example, \ep{Lu}
always matches an upper case letter. I think Perl has changed in this respect;
-in the release at the time of writing (5.24), \ep{Lu} and \ep{Ll} match all
+in the release at the time of writing (5.32), \ep{Lu} and \ep{Ll} match all
letters, regardless of case, when case independence is specified.
.P
+16. From release 5.32.0, Perl locks out the use of \eK in lookaround
+assertions. In PCRE2, \eK is acted on when it occurs in positive assertions,
+but is ignored in negative assertions.
+.P
17. PCRE2 provides some extensions to the Perl regular expression facilities.
-Perl 5.10 includes new features that are not in earlier versions of Perl, some
+Perl 5.10 included new features that were not in earlier versions of Perl, some
of which (such as named parentheses) were in PCRE2 for some time before. This
-list is with respect to Perl 5.26:
+list is with respect to Perl 5.32:
.sp
(a) Although lookbehind assertions in PCRE2 must match fixed length strings,
-each alternative branch of a lookbehind assertion can match a different length
-of string. Perl requires them all to have the same length.
+each alternative toplevel branch of a lookbehind assertion can match a
+different length of string. Perl requires them all to have the same length.
.sp
(b) From PCRE2 10.23, backreferences to groups of fixed length are supported
in lookbehinds, provided that there is no possibility of referencing a
@@ -168,7 +177,7 @@ variable interpolation, but not general hooks on every match.
different way and is not Perl-compatible.
.sp
(l) PCRE2 recognizes some special sequences such as (*CR) or (*NO_JIT) at
-the start of a pattern that set overall options that cannot be changed within
+the start of a pattern. These set overall options that cannot be changed within
the pattern.
.sp
(m) PCRE2 supports non-atomic positive lookaround assertions. This is an
@@ -203,6 +212,6 @@ Cambridge, England.
.rs
.sp
.nf
-Last updated: 13 July 2019
+Last updated: 06 October 2020
Copyright (c) 1997-2019 University of Cambridge.
.fi
diff --git a/doc/pcre2grep.1 b/doc/pcre2grep.1
index 137117a..66377ce 100644
--- a/doc/pcre2grep.1
+++ b/doc/pcre2grep.1
@@ -1,4 +1,4 @@
-.TH PCRE2GREP 1 "25 January 2020" "PCRE2 10.35"
+.TH PCRE2GREP 1 "04 October 2020" "PCRE2 10.36"
.SH NAME
pcre2grep - a grep with Perl-compatible regular expressions.
.SH SYNOPSIS
@@ -79,8 +79,8 @@ matching substrings, or if \fB--only-matching\fP, \fB--file-offsets\fP, or
(either shown literally, or as an offset), scanning resumes immediately
following the match, so that further matches on the same line can be found. If
there are multiple patterns, they are all tried on the remainder of the line,
-but patterns that follow the one that matched are not tried on the earlier part
-of the line.
+but patterns that follow the one that matched are not tried on the earlier
+matched part of the line.
.P
This behaviour means that the order in which multiple patterns are specified
can affect the output when one of the above options is used. This is no longer
@@ -115,11 +115,10 @@ ignored.
.rs
.sp
By default, a file that contains a binary zero byte within the first 1024 bytes
-is identified as a binary file, and is processed specially. (GNU grep
-identifies binary files in this manner.) However, if the newline type is
-specified as NUL, that is, the line terminator is a binary zero, the test for
-a binary file is not applied. See the \fB--binary-files\fP option for a means
-of changing the way binary files are handled.
+is identified as a binary file, and is processed specially. However, if the
+newline type is specified as NUL, that is, the line terminator is a binary
+zero, the test for a binary file is not applied. See the \fB--binary-files\fP
+option for a means of changing the way binary files are handled.
.
.
.SH "BINARY ZEROS IN PATTERNS"
@@ -383,8 +382,8 @@ Ignore upper/lower case distinctions during comparisons.
.TP
\fB--include\fP=\fIpattern\fP
If any \fB--include\fP patterns are specified, the only files that are
-processed are those that match one of the patterns (and do not match an
-\fB--exclude\fP pattern). This option does not affect directories, but it
+processed are those whose names match one of the patterns and do not match an
+\fB--exclude\fP pattern. This option does not affect directories, but it
applies to all files, whether listed on the command line, obtained from
\fB--file-list\fP, or by scanning a directory. The pattern is a PCRE2 regular
expression, and is matched against the final component of the file name, not
@@ -401,8 +400,8 @@ may be given any number of times; all the files are read.
.TP
\fB--include-dir\fP=\fIpattern\fP
If any \fB--include-dir\fP patterns are specified, the only directories that
-are processed are those that match one of the patterns (and do not match an
-\fB--exclude-dir\fP pattern). This applies to all directories, whether listed
+are processed are those whose names match one of the patterns and do not match
+an \fB--exclude-dir\fP pattern. This applies to all directories, whether listed
on the command line, obtained from \fB--file-list\fP, or by scanning a parent
directory. The pattern is a PCRE2 regular expression, and is matched against
the final component of the directory name, not the entire path. The \fB-F\fP,
@@ -423,8 +422,9 @@ a separate line. Searching normally stops as soon as a matching line is found
in a file. However, if the \fB-c\fP (count) option is also used, matching
continues in order to obtain the correct count, and those files that have at
least one match are listed along with their counts. Using this option with
-\fB-c\fP is a way of suppressing the listing of files with no matches. This
-opeion overrides any previous \fB-H\fP, \fB-h\fP, or \fB-L\fP options.
+\fB-c\fP is a way of suppressing the listing of files with no matches that
+occurs with \fB-c\fP on its own. This option overrides any previous \fB-H\fP,
+\fB-h\fP, or \fB-L\fP options.
.TP
\fB--label\fP=\fIname\fP
This option supplies a name to be used for the standard input when file names
@@ -435,8 +435,8 @@ short form for this option.
When this option is given, non-compressed input is read and processed line by
line, and the output is flushed after each write. By default, input is read in
large chunks, unless \fBpcre2grep\fP can determine that it is reading from a
-terminal (which is currently possible only in Unix-like environments or
-Windows). Output to terminal is normally automatically flushed by the operating
+terminal, which is currently possible only in Unix-like environments or
+Windows. Output to terminal is normally automatically flushed by the operating
system. This option can be useful when the input or output is attached to a
pipe and you do not want \fBpcre2grep\fP to buffer up large amounts of data.
However, its use will affect performance, and the \fB-M\fP (multiline) option
@@ -459,6 +459,45 @@ the value in the \fBLC_ALL\fP or \fBLC_CTYPE\fP environment variables. If no
locale is specified, the PCRE2 library's default (usually the "C" locale) is
used. There is no short form for this option.
.TP
+\fB-M\fP, \fB--multiline\fP
+Allow patterns to match more than one line. When this option is set, the PCRE2
+library is called in "multiline" mode. This allows a matched string to extend
+past the end of a line and continue on one or more subsequent lines. Patterns
+used with \fB-M\fP may usefully contain literal newline characters and internal
+occurrences of ^ and $ characters. The output for a successful match may
+consist of more than one line. The first line is the line in which the match
+started, and the last line is the line in which the match ended. If the matched
+string ends with a newline sequence, the output ends at the end of that line.
+If \fB-v\fP is set, none of the lines in a multi-line match are output. Once a
+match has been handled, scanning restarts at the beginning of the line after
+the one in which the match ended.
+.sp
+The newline sequence that separates multiple lines must be matched as part of
+the pattern. For example, to find the phrase "regular expression" in a file
+where "regular" might be at the end of a line and "expression" at the start of
+the next line, you could use this command:
+.sp
+ pcre2grep -M 'regular\es+expression' <file>
+.sp
+The \es escape sequence matches any white space character, including newlines,
+and is followed by + so as to match trailing white space on the first line as
+well as possibly handling a two-character newline sequence.
+.sp
+There is a limit to the number of lines that can be matched, imposed by the way
+that \fBpcre2grep\fP buffers the input file as it scans it. With a sufficiently
+large processing buffer, this should not be a problem, but the \fB-M\fP option
+does not work when input is read line by line (see \fB--line-buffered\fP.)
+.TP
+\fB-m\fP \fInumber\fP, \fB--max-count\fP=\fInumber\fP
+Stop processing after finding \fInumber\fP matching lines, or non-matching
+lines if \fB-v\fP is also set. Any trailing context lines are output after the
+final match. In multiline mode, each multiline match counts as just one line
+for this purpose. If this limit is reached when reading the standard input from
+a regular file, the file is left positioned just after the last matching line.
+If \fB-c\fP is also set, the count that is output is never greater than
+\fInumber\fP. This option has no effect if used with \fB-L\fP, \fB-l\fP, or
+\fB-q\fP, or when just checking for a match in a binary file.
+.TP
\fB--match-limit\fP=\fInumber\fP
Processing some regular expression patterns may take a very long time to search
for all possible matching strings. Others may require a very large amount of
@@ -493,35 +532,6 @@ This limits the expansion of the processing buffer, whose initial size can be
set by \fB--buffer-size\fP. The maximum buffer size is silently forced to be no
smaller than the starting buffer size.
.TP
-\fB-M\fP, \fB--multiline\fP
-Allow patterns to match more than one line. When this option is set, the PCRE2
-library is called in "multiline" mode. This allows a matched string to extend
-past the end of a line and continue on one or more subsequent lines. Patterns
-used with \fB-M\fP may usefully contain literal newline characters and internal
-occurrences of ^ and $ characters. The output for a successful match may
-consist of more than one line. The first line is the line in which the match
-started, and the last line is the line in which the match ended. If the matched
-string ends with a newline sequence, the output ends at the end of that line.
-If \fB-v\fP is set, none of the lines in a multi-line match are output. Once a
-match has been handled, scanning restarts at the beginning of the line after
-the one in which the match ended.
-.sp
-The newline sequence that separates multiple lines must be matched as part of
-the pattern. For example, to find the phrase "regular expression" in a file
-where "regular" might be at the end of a line and "expression" at the start of
-the next line, you could use this command:
-.sp
- pcre2grep -M 'regular\es+expression' <file>
-.sp
-The \es escape sequence matches any white space character, including newlines,
-and is followed by + so as to match trailing white space on the first line as
-well as possibly handling a two-character newline sequence.
-.sp
-There is a limit to the number of lines that can be matched, imposed by the way
-that \fBpcre2grep\fP buffers the input file as it scans it. With a sufficiently
-large processing buffer, this should not be a problem, but the \fB-M\fP option
-does not work when input is read line by line (see \fB--line-buffered\fP.)
-.TP
\fB-N\fP \fInewline-type\fP, \fB--newline\fP=\fInewline-type\fP
Six different conventions for indicating the ends of lines in scanned files are
supported. For example:
@@ -565,27 +575,36 @@ use of JIT at run time. It is provided for testing and working round problems.
It should never be needed in normal use.
.TP
\fB-O\fP \fItext\fP, \fB--output\fP=\fItext\fP
-When there is a match, instead of outputting the whole line that matched,
-output just the given text, followed by an operating-system standard newline.
-The \fB--newline\fP option has no effect on this option, which is mutually
-exclusive with \fB--only-matching\fP, \fB--file-offsets\fP, and
-\fB--line-offsets\fP. Escape sequences starting with a dollar character may be
-used to insert the contents of the matched part of the line and/or captured
-substrings into the text.
-.sp
-$<digits> or ${<digits>} is replaced by the captured
-substring of the given decimal number; zero substitutes the whole match. If
-the number is greater than the number of capturing substrings, or if the
-capture is unset, the replacement is empty.
+When there is a match, instead of outputting the line that matched, output just
+the text specified in this option, followed by an operating-system standard
+newline. In this mode, no context is shown. That is, the \fB-A\fP, \fB-B\fP,
+and \fB-C\fP options are ignored. The \fB--newline\fP option has no effect on
+this option, which is mutually exclusive with \fB--only-matching\fP,
+\fB--file-offsets\fP, and \fB--line-offsets\fP. However, like
+\fB--only-matching\fP, if there is more than one match in a line, each of them
+causes a line of output.
+.sp
+Escape sequences starting with a dollar character may be used to insert the
+contents of the matched part of the line and/or captured substrings into the
+text.
+.sp
+$<digits> or ${<digits>} is replaced by the captured substring of the given
+decimal number; zero substitutes the whole match. If the number is greater than
+the number of capturing substrings, or if the capture is unset, the replacement
+is empty.
.sp
$a is replaced by bell; $b by backspace; $e by escape; $f by form feed; $n by
newline; $r by carriage return; $t by tab; $v by vertical tab.
.sp
-$o<digits> is replaced by the character represented by the given octal
-number; up to three digits are processed.
+$o<digits> or $o{<digits>} is replaced by the character whose code point is the
+given octal number. In the first form, up to three octal digits are processed.
+When more digits are needed in Unicode mode to specify a wide character, the
+second form must be used.
.sp
-$x<digits> is replaced by the character represented by the given hexadecimal
-number; up to two digits are processed.
+$x<digits> or $x{<digits>} is replaced by the character represented by the
+given hexadecimal number. In the first form, up to two hexadecimal digits are
+processed. When more digits are needed in Unicode mode to specify a wide
+character, the second form must be used.
.sp
Any other character is substituted by itself. In particular, $$ is replaced by
a single dollar.
@@ -644,7 +663,8 @@ immediate end-of-file. This option is a shorthand for setting the \fB-d\fP
option to "recurse".
.TP
\fB--recursion-limit\fP=\fInumber\fP
-See \fB--match-limit\fP above.
+This is an obsolete synonym for \fB--depth-limit\fP. See \fB--match-limit\fP
+above for details.
.TP
\fB-s\fP, \fB--no-messages\fP
Suppress error messages about non-existent or unreadable files. Such files are
@@ -665,14 +685,17 @@ total would always be zero.
\fB-u\fP, \fB--utf\fP
Operate in UTF-8 mode. This option is available only if PCRE2 has been compiled
with UTF-8 support. All patterns (including those for any \fB--exclude\fP and
-\fB--include\fP options) and all subject lines that are scanned must be valid
-strings of UTF-8 characters.
+\fB--include\fP options) and all lines that are scanned must be valid strings
+of UTF-8 characters. If an invalid UTF-8 string is encountered, an error
+occurs.
.TP
\fB-U\fP, \fB--utf-allow-invalid\fP
As \fB--utf\fP, but in addition subject lines may contain invalid UTF-8 code
-unit sequences. These can never form part of any pattern match. This facility
-allows valid UTF-8 strings to be sought in executable or other binary files.
-For more details about matching in non-valid UTF-8 strings, see the
+unit sequences. These can never form part of any pattern match. Patterns
+themselves, however, must still be valid UTF-8 strings. This facility allows
+valid UTF-8 strings to be sought within arbitrary byte sequences in executable
+or other binary files. For more details about matching in non-valid UTF-8
+strings, see the
.\" HREF
\fBpcre2unicode\fP(3)
.\"
@@ -685,7 +708,9 @@ ignored.
.TP
\fB-v\fP, \fB--invert-match\fP
Invert the sense of the match, so that lines which do \fInot\fP match any of
-the patterns are the ones that are found.
+the patterns are the ones that are found. When this option is set, options such
+as \fB--only-matching\fP and \fB--output\fP, which specify parts of a match
+that are to be output, are ignored.
.TP
\fB-w\fP, \fB--word-regex\fP, \fB--word-regexp\fP
Force the patterns only to match "words". That is, there must be a word
@@ -812,12 +837,36 @@ documentation for details). Numbered callouts are ignored by \fBpcre2grep\fP;
only callouts with string arguments are useful.
.
.
+.SS "Echoing a specific string"
+.rs
+.sp
+Starting the callout string with a pipe character invokes an echoing facility
+that avoids calling an external program or script. This facility is always
+available, provided that callouts were not completely disabled when
+\fBpcre2grep\fP was built. The rest of the callout string is processed as a
+zero-terminated string, which means it should not contain any internal binary
+zeros. It is written to the output, having first been passed through the same
+escape processing as text from the \fB--output\fP (\fB-O\fP) option (see
+above). However, $0 cannot be used to insert a matched substring because the
+match is still in progress. Instead, the single character '0' is inserted. Any
+syntax errors in the string (for example, a dollar not followed by another
+character) causes the callout to be ignored. No terminator is added to the
+output string, so if you want a newline, you must include it explicitly using
+the escape $n. For example:
+.sp
+ pcre2grep '(.)(..(.))(?C"|[$1] [$2] [$3]$n")' <some file>
+.sp
+Matching continues normally after the string is output. If you want to see only
+the callout output but not any output from an actual match, you should end the
+pattern with (*FAIL).
+.
+.
.SS "Calling external programs or scripts"
.rs
.sp
This facility can be independently disabled when \fBpcre2grep\fP is built. It
is supported for Windows, where a call to \fB_spawnvp()\fP is used, for VMS,
-where \fBlib$spawn()\fP is used, and for any other Unix-like environment where
+where \fBlib$spawn()\fP is used, and for any Unix-like environment where
\fBfork()\fP and \fBexecv()\fP are available.
.P
If the callout string does not start with a pipe (vertical bar) character, it
@@ -828,13 +877,11 @@ arguments:
executable_name|arg1|arg2|...
.sp
Any substring (including the executable name) may contain escape sequences
-started by a dollar character: $<digits> or ${<digits>} is replaced by the
-captured substring of the given decimal number, which must be greater than
-zero. If the number is greater than the number of capturing substrings, or if
-the capture is unset, the replacement is empty.
-.P
-Any other character is substituted by itself. In particular, $$ is replaced by
-a single dollar and $| is replaced by a pipe character. Here is an example:
+started by a dollar character. These are the same as for the \fB--output\fP
+(\fB-O\fP) option documented above, except that $0 cannot insert the matched
+string because the match is still in progress. Instead, the character '0'
+is inserted. If you need a literal dollar or pipe character in any
+substring, use $$ or $| respectively. Here is an example:
.sp
echo -e "abcde\en12345" | pcre2grep \e
'(?x)(.)(..(.))
@@ -847,28 +894,14 @@ a single dollar and $| is replaced by a pipe character. Here is an example:
Arg1: [1] [234] [4] Arg2: |1| ()
12345
.sp
-The parameters for the system call that is used to run the
-program or script are zero-terminated strings. This means that binary zero
-characters in the callout argument will cause premature termination of their
-substrings, and therefore should not be present. Any syntax errors in the
-string (for example, a dollar not followed by another character) cause the
-callout to be ignored. If running the program fails for any reason (including
-the non-existence of the executable), a local matching failure occurs and the
-matcher backtracks in the normal way.
-.
-.
-.SS "Echoing a specific string"
-.rs
-.sp
-This facility is always available, provided that callouts were not completely
-disabled when \fBpcre2grep\fP was built. If the callout string starts with a
-pipe (vertical bar) character, the rest of the string is written to the output,
-having been passed through the same escape processing as text from the --output
-option. This provides a simple echoing facility that avoids calling an external
-program or script. No terminator is added to the string, so if you want a
-newline, you must include it explicitly. Matching continues normally after the
-string is output. If you want to see only the callout output but not any output
-from an actual match, you should end the relevant pattern with (*FAIL).
+The parameters for the system call that is used to run the program or script
+are zero-terminated strings. This means that binary zero characters in the
+callout argument will cause premature termination of their substrings, and
+therefore should not be present. Any syntax errors in the string (for example,
+a dollar not followed by another character) causes the callout to be ignored.
+If running the program fails for any reason (including the non-existence of the
+executable), a local matching failure occurs and the matcher backtracks in the
+normal way.
.
.
.SH "MATCHING ERRORS"
@@ -904,7 +937,8 @@ because VMS does not distinguish between exit(0) and exit(1).
.SH "SEE ALSO"
.rs
.sp
-\fBpcre2pattern\fP(3), \fBpcre2syntax\fP(3), \fBpcre2callout\fP(3).
+\fBpcre2pattern\fP(3), \fBpcre2syntax\fP(3), \fBpcre2callout\fP(3),
+\fBpcre2unicode\fP(3).
.
.
.SH AUTHOR
@@ -921,6 +955,6 @@ Cambridge, England.
.rs
.sp
.nf
-Last updated: 25 January 2020
+Last updated: 04 October 2020
Copyright (c) 1997-2020 University of Cambridge.
.fi
diff --git a/doc/pcre2grep.txt b/doc/pcre2grep.txt
index 4d41f54..0e839c7 100644
--- a/doc/pcre2grep.txt
+++ b/doc/pcre2grep.txt
@@ -80,7 +80,7 @@ DESCRIPTION
following the match, so that further matches on the same line can be
found. If there are multiple patterns, they are all tried on the re-
mainder of the line, but patterns that follow the one that matched are
- not tried on the earlier part of the line.
+ not tried on the earlier matched part of the line.
This behaviour means that the order in which multiple patterns are
specified can affect the output when one of the above options is used.
@@ -115,10 +115,10 @@ BINARY FILES
By default, a file that contains a binary zero byte within the first
1024 bytes is identified as a binary file, and is processed specially.
- (GNU grep identifies binary files in this manner.) However, if the new-
- line type is specified as NUL, that is, the line terminator is a binary
- zero, the test for a binary file is not applied. See the --binary-files
- option for a means of changing the way binary files are handled.
+ However, if the newline type is specified as NUL, that is, the line
+ terminator is a binary zero, the test for a binary file is not applied.
+ See the --binary-files option for a means of changing the way binary
+ files are handled.
BINARY ZEROS IN PATTERNS
@@ -413,17 +413,17 @@ OPTIONS
--include=pattern
If any --include patterns are specified, the only files that
- are processed are those that match one of the patterns (and
- do not match an --exclude pattern). This option does not af-
- fect directories, but it applies to all files, whether listed
- on the command line, obtained from --file-list, or by scan-
- ning a directory. The pattern is a PCRE2 regular expression,
- and is matched against the final component of the file name,
- not the entire path. The -F, -w, and -x options do not apply
- to this pattern. The option may be given any number of times.
- If a file name matches both an --include and an --exclude
- pattern, it is excluded. There is no short form for this op-
- tion.
+ are processed are those whose names match one of the patterns
+ and do not match an --exclude pattern. This option does not
+ affect directories, but it applies to all files, whether
+ listed on the command line, obtained from --file-list, or by
+ scanning a directory. The pattern is a PCRE2 regular expres-
+ sion, and is matched against the final component of the file
+ name, not the entire path. The -F, -w, and -x options do not
+ apply to this pattern. The option may be given any number of
+ times. If a file name matches both an --include and an --ex-
+ clude pattern, it is excluded. There is no short form for
+ this option.
--include-from=filename
Treat each non-empty line of the file as the data for an
@@ -434,8 +434,8 @@ OPTIONS
--include-dir=pattern
If any --include-dir patterns are specified, the only direc-
- tories that are processed are those that match one of the
- patterns (and do not match an --exclude-dir pattern). This
+ tories that are processed are those whose names match one of
+ the patterns and do not match an --exclude-dir pattern. This
applies to all directories, whether listed on the command
line, obtained from --file-list, or by scanning a parent di-
rectory. The pattern is a PCRE2 regular expression, and is
@@ -461,8 +461,9 @@ OPTIONS
matching continues in order to obtain the correct count, and
those files that have at least one match are listed along
with their counts. Using this option with -c is a way of sup-
- pressing the listing of files with no matches. This opeion
- overrides any previous -H, -h, or -L options.
+ pressing the listing of files with no matches that occurs
+ with -c on its own. This option overrides any previous -H,
+ -h, or -L options.
--label=name
This option supplies a name to be used for the standard input
@@ -470,37 +471,84 @@ OPTIONS
input)" is used. There is no short form for this option.
--line-buffered
- When this option is given, non-compressed input is read and
- processed line by line, and the output is flushed after each
- write. By default, input is read in large chunks, unless
- pcre2grep can determine that it is reading from a terminal
- (which is currently possible only in Unix-like environments
- or Windows). Output to terminal is normally automatically
- flushed by the operating system. This option can be useful
- when the input or output is attached to a pipe and you do not
- want pcre2grep to buffer up large amounts of data. However,
- its use will affect performance, and the -M (multiline) op-
- tion ceases to work. When input is from a compressed .gz or
- .bz2 file, --line-buffered is ignored.
+ When this option is given, non-compressed input is read and
+ processed line by line, and the output is flushed after each
+ write. By default, input is read in large chunks, unless
+ pcre2grep can determine that it is reading from a terminal,
+ which is currently possible only in Unix-like environments or
+ Windows. Output to terminal is normally automatically flushed
+ by the operating system. This option can be useful when the
+ input or output is attached to a pipe and you do not want
+ pcre2grep to buffer up large amounts of data. However, its
+ use will affect performance, and the -M (multiline) option
+ ceases to work. When input is from a compressed .gz or .bz2
+ file, --line-buffered is ignored.
--line-offsets
- Instead of showing lines or parts of lines that match, show
+ Instead of showing lines or parts of lines that match, show
each match as a line number, the offset from the start of the
- line, and a length. The line number is terminated by a colon
- (as usual; see the -n option), and the offset and length are
- separated by a comma. In this mode, no context is shown.
- That is, the -A, -B, and -C options are ignored. If there is
- more than one match in a line, each of them is shown sepa-
- rately. This option is mutually exclusive with --output,
+ line, and a length. The line number is terminated by a colon
+ (as usual; see the -n option), and the offset and length are
+ separated by a comma. In this mode, no context is shown.
+ That is, the -A, -B, and -C options are ignored. If there is
+ more than one match in a line, each of them is shown sepa-
+ rately. This option is mutually exclusive with --output,
--file-offsets, and --only-matching.
--locale=locale-name
- This option specifies a locale to be used for pattern match-
- ing. It overrides the value in the LC_ALL or LC_CTYPE envi-
- ronment variables. If no locale is specified, the PCRE2 li-
+ This option specifies a locale to be used for pattern match-
+ ing. It overrides the value in the LC_ALL or LC_CTYPE envi-
+ ronment variables. If no locale is specified, the PCRE2 li-
brary's default (usually the "C" locale) is used. There is no
short form for this option.
+ -M, --multiline
+ Allow patterns to match more than one line. When this option
+ is set, the PCRE2 library is called in "multiline" mode. This
+ allows a matched string to extend past the end of a line and
+ continue on one or more subsequent lines. Patterns used with
+ -M may usefully contain literal newline characters and inter-
+ nal occurrences of ^ and $ characters. The output for a suc-
+ cessful match may consist of more than one line. The first
+ line is the line in which the match started, and the last
+ line is the line in which the match ended. If the matched
+ string ends with a newline sequence, the output ends at the
+ end of that line. If -v is set, none of the lines in a
+ multi-line match are output. Once a match has been handled,
+ scanning restarts at the beginning of the line after the one
+ in which the match ended.
+
+ The newline sequence that separates multiple lines must be
+ matched as part of the pattern. For example, to find the
+ phrase "regular expression" in a file where "regular" might
+ be at the end of a line and "expression" at the start of the
+ next line, you could use this command:
+
+ pcre2grep -M 'regular\s+expression' <file>
+
+ The \s escape sequence matches any white space character, in-
+ cluding newlines, and is followed by + so as to match trail-
+ ing white space on the first line as well as possibly han-
+ dling a two-character newline sequence.
+
+ There is a limit to the number of lines that can be matched,
+ imposed by the way that pcre2grep buffers the input file as
+ it scans it. With a sufficiently large processing buffer,
+ this should not be a problem, but the -M option does not work
+ when input is read line by line (see --line-buffered.)
+
+ -m number, --max-count=number
+ Stop processing after finding number matching lines, or non-
+ matching lines if -v is also set. Any trailing context lines
+ are output after the final match. In multiline mode, each
+ multiline match counts as just one line for this purpose. If
+ this limit is reached when reading the standard input from a
+ regular file, the file is left positioned just after the last
+ matching line. If -c is also set, the count that is output
+ is never greater than number. This option has no effect if
+ used with -L, -l, or -q, or when just checking for a match in
+ a binary file.
+
--match-limit=number
Processing some regular expression patterns may take a very
long time to search for all possible matching strings. Others
@@ -542,41 +590,6 @@ OPTIONS
size is silently forced to be no smaller than the starting
buffer size.
- -M, --multiline
- Allow patterns to match more than one line. When this option
- is set, the PCRE2 library is called in "multiline" mode. This
- allows a matched string to extend past the end of a line and
- continue on one or more subsequent lines. Patterns used with
- -M may usefully contain literal newline characters and inter-
- nal occurrences of ^ and $ characters. The output for a suc-
- cessful match may consist of more than one line. The first
- line is the line in which the match started, and the last
- line is the line in which the match ended. If the matched
- string ends with a newline sequence, the output ends at the
- end of that line. If -v is set, none of the lines in a
- multi-line match are output. Once a match has been handled,
- scanning restarts at the beginning of the line after the one
- in which the match ended.
-
- The newline sequence that separates multiple lines must be
- matched as part of the pattern. For example, to find the
- phrase "regular expression" in a file where "regular" might
- be at the end of a line and "expression" at the start of the
- next line, you could use this command:
-
- pcre2grep -M 'regular\s+expression' <file>
-
- The \s escape sequence matches any white space character, in-
- cluding newlines, and is followed by + so as to match trail-
- ing white space on the first line as well as possibly han-
- dling a two-character newline sequence.
-
- There is a limit to the number of lines that can be matched,
- imposed by the way that pcre2grep buffers the input file as
- it scans it. With a sufficiently large processing buffer,
- this should not be a problem, but the -M option does not work
- when input is read line by line (see --line-buffered.)
-
-N newline-type, --newline=newline-type
Six different conventions for indicating the ends of lines in
scanned files are supported. For example:
@@ -625,97 +638,109 @@ OPTIONS
lems. It should never be needed in normal use.
-O text, --output=text
- When there is a match, instead of outputting the whole line
- that matched, output just the given text, followed by an op-
- erating-system standard newline. The --newline option has no
- effect on this option, which is mutually exclusive with
- --only-matching, --file-offsets, and --line-offsets. Escape
- sequences starting with a dollar character may be used to in-
- sert the contents of the matched part of the line and/or cap-
- tured substrings into the text.
-
- $<digits> or ${<digits>} is replaced by the captured sub-
- string of the given decimal number; zero substitutes the
+ When there is a match, instead of outputting the line that
+ matched, output just the text specified in this option, fol-
+ lowed by an operating-system standard newline. In this mode,
+ no context is shown. That is, the -A, -B, and -C options are
+ ignored. The --newline option has no effect on this option,
+ which is mutually exclusive with --only-matching, --file-off-
+ sets, and --line-offsets. However, like --only-matching, if
+ there is more than one match in a line, each of them causes a
+ line of output.
+
+ Escape sequences starting with a dollar character may be used
+ to insert the contents of the matched part of the line and/or
+ captured substrings into the text.
+
+ $<digits> or ${<digits>} is replaced by the captured sub-
+ string of the given decimal number; zero substitutes the
whole match. If the number is greater than the number of cap-
- turing substrings, or if the capture is unset, the replace-
+ turing substrings, or if the capture is unset, the replace-
ment is empty.
- $a is replaced by bell; $b by backspace; $e by escape; $f by
- form feed; $n by newline; $r by carriage return; $t by tab;
+ $a is replaced by bell; $b by backspace; $e by escape; $f by
+ form feed; $n by newline; $r by carriage return; $t by tab;
$v by vertical tab.
- $o<digits> is replaced by the character represented by the
- given octal number; up to three digits are processed.
+ $o<digits> or $o{<digits>} is replaced by the character whose
+ code point is the given octal number. In the first form, up
+ to three octal digits are processed. When more digits are
+ needed in Unicode mode to specify a wide character, the sec-
+ ond form must be used.
- $x<digits> is replaced by the character represented by the
- given hexadecimal number; up to two digits are processed.
+ $x<digits> or $x{<digits>} is replaced by the character rep-
+ resented by the given hexadecimal number. In the first form,
+ up to two hexadecimal digits are processed. When more digits
+ are needed in Unicode mode to specify a wide character, the
+ second form must be used.
- Any other character is substituted by itself. In particular,
+ Any other character is substituted by itself. In particular,
$$ is replaced by a single dollar.
-o, --only-matching
Show only the part of the line that matched a pattern instead
- of the whole line. In this mode, no context is shown. That
- is, the -A, -B, and -C options are ignored. If there is more
- than one match in a line, each of them is shown separately,
- on a separate line of output. If -o is combined with -v (in-
- vert the sense of the match to find non-matching lines), no
- output is generated, but the return code is set appropri-
- ately. If the matched portion of the line is empty, nothing
- is output unless the file name or line number are being
- printed, in which case they are shown on an otherwise empty
+ of the whole line. In this mode, no context is shown. That
+ is, the -A, -B, and -C options are ignored. If there is more
+ than one match in a line, each of them is shown separately,
+ on a separate line of output. If -o is combined with -v (in-
+ vert the sense of the match to find non-matching lines), no
+ output is generated, but the return code is set appropri-
+ ately. If the matched portion of the line is empty, nothing
+ is output unless the file name or line number are being
+ printed, in which case they are shown on an otherwise empty
line. This option is mutually exclusive with --output,
--file-offsets and --line-offsets.
-onumber, --only-matching=number
- Show only the part of the line that matched the capturing
+ Show only the part of the line that matched the capturing
parentheses of the given number. Up to 50 capturing parenthe-
- ses are supported by default. This limit can be changed via
- the --om-capture option. A pattern may contain any number of
- capturing parentheses, but only those whose number is within
- the limit can be accessed by -o. An error occurs if the num-
+ ses are supported by default. This limit can be changed via
+ the --om-capture option. A pattern may contain any number of
+ capturing parentheses, but only those whose number is within
+ the limit can be accessed by -o. An error occurs if the num-
ber specified by -o is greater than the limit.
-o0 is the same as -o without a number. Because these options
- can be given without an argument (see above), if an argument
- is present, it must be given in the same shell item, for ex-
- ample, -o3 or --only-matching=2. The comments given for the
- non-argument case above also apply to this option. If the
- specified capturing parentheses do not exist in the pattern,
- or were not set in the match, nothing is output unless the
+ can be given without an argument (see above), if an argument
+ is present, it must be given in the same shell item, for ex-
+ ample, -o3 or --only-matching=2. The comments given for the
+ non-argument case above also apply to this option. If the
+ specified capturing parentheses do not exist in the pattern,
+ or were not set in the match, nothing is output unless the
file name or line number are being output.
- If this option is given multiple times, multiple substrings
- are output for each match, in the order the options are
- given, and all on one line. For example, -o3 -o1 -o3 causes
- the substrings matched by capturing parentheses 3 and 1 and
- then 3 again to be output. By default, there is no separator
+ If this option is given multiple times, multiple substrings
+ are output for each match, in the order the options are
+ given, and all on one line. For example, -o3 -o1 -o3 causes
+ the substrings matched by capturing parentheses 3 and 1 and
+ then 3 again to be output. By default, there is no separator
(but see the next but one option).
--om-capture=number
- Set the number of capturing parentheses that can be accessed
+ Set the number of capturing parentheses that can be accessed
by -o. The default is 50.
--om-separator=text
- Specify a separating string for multiple occurrences of -o.
- The default is an empty string. Separating strings are never
+ Specify a separating string for multiple occurrences of -o.
+ The default is an empty string. Separating strings are never
coloured.
-q, --quiet
Work quietly, that is, display nothing except error messages.
- The exit status indicates whether or not any matches were
+ The exit status indicates whether or not any matches were
found.
-r, --recursive
- If any given path is a directory, recursively scan the files
- it contains, taking note of any --include and --exclude set-
- tings. By default, a directory is read as a normal file; in
- some operating systems this gives an immediate end-of-file.
- This option is a shorthand for setting the -d option to "re-
+ If any given path is a directory, recursively scan the files
+ it contains, taking note of any --include and --exclude set-
+ tings. By default, a directory is read as a normal file; in
+ some operating systems this gives an immediate end-of-file.
+ This option is a shorthand for setting the -d option to "re-
curse".
--recursion-limit=number
- See --match-limit above.
+ This is an obsolete synonym for --depth-limit. See --match-
+ limit above for details.
-s, --no-messages
Suppress error messages about non-existent or unreadable
@@ -737,26 +762,30 @@ OPTIONS
-u, --utf Operate in UTF-8 mode. This option is available only if PCRE2
has been compiled with UTF-8 support. All patterns (including
- those for any --exclude and --include options) and all sub-
- ject lines that are scanned must be valid strings of UTF-8
- characters.
+ those for any --exclude and --include options) and all lines
+ that are scanned must be valid strings of UTF-8 characters.
+ If an invalid UTF-8 string is encountered, an error occurs.
-U, --utf-allow-invalid
As --utf, but in addition subject lines may contain invalid
UTF-8 code unit sequences. These can never form part of any
- pattern match. This facility allows valid UTF-8 strings to be
- sought in executable or other binary files. For more details
- about matching in non-valid UTF-8 strings, see the pcre2uni-
- code(3) documentation.
+ pattern match. Patterns themselves, however, must still be
+ valid UTF-8 strings. This facility allows valid UTF-8 strings
+ to be sought within arbitrary byte sequences in executable or
+ other binary files. For more details about matching in non-
+ valid UTF-8 strings, see the pcre2unicode(3) documentation.
-V, --version
- Write the version numbers of pcre2grep and the PCRE2 library
- to the standard output and then exit. Anything else on the
+ Write the version numbers of pcre2grep and the PCRE2 library
+ to the standard output and then exit. Anything else on the
command line is ignored.
-v, --invert-match
- Invert the sense of the match, so that lines which do not
- match any of the patterns are the ones that are found.
+ Invert the sense of the match, so that lines which do not
+ match any of the patterns are the ones that are found. When
+ this option is set, options such as --only-matching and
+ --output, which specify parts of a match that are to be out-
+ put, are ignored.
-w, --word-regex, --word-regexp
Force the patterns only to match "words". That is, there must
@@ -878,30 +907,49 @@ USING PCRE2'S CALLOUT FACILITY
mentation for details). Numbered callouts are ignored by pcre2grep;
only callouts with string arguments are useful.
+ Echoing a specific string
+
+ Starting the callout string with a pipe character invokes an echoing
+ facility that avoids calling an external program or script. This facil-
+ ity is always available, provided that callouts were not completely
+ disabled when pcre2grep was built. The rest of the callout string is
+ processed as a zero-terminated string, which means it should not con-
+ tain any internal binary zeros. It is written to the output, having
+ first been passed through the same escape processing as text from the
+ --output (-O) option (see above). However, $0 cannot be used to insert
+ a matched substring because the match is still in progress. Instead,
+ the single character '0' is inserted. Any syntax errors in the string
+ (for example, a dollar not followed by another character) causes the
+ callout to be ignored. No terminator is added to the output string, so
+ if you want a newline, you must include it explicitly using the escape
+ $n. For example:
+
+ pcre2grep '(.)(..(.))(?C"|[$1] [$2] [$3]$n")' <some file>
+
+ Matching continues normally after the string is output. If you want to
+ see only the callout output but not any output from an actual match,
+ you should end the pattern with (*FAIL).
+
Calling external programs or scripts
This facility can be independently disabled when pcre2grep is built. It
- is supported for Windows, where a call to _spawnvp() is used, for VMS,
- where lib$spawn() is used, and for any other Unix-like environment
- where fork() and execv() are available.
+ is supported for Windows, where a call to _spawnvp() is used, for VMS,
+ where lib$spawn() is used, and for any Unix-like environment where
+ fork() and execv() are available.
If the callout string does not start with a pipe (vertical bar) charac-
- ter, it is parsed into a list of substrings separated by pipe charac-
- ters. The first substring must be an executable name, with the follow-
+ ter, it is parsed into a list of substrings separated by pipe charac-
+ ters. The first substring must be an executable name, with the follow-
ing substrings specifying arguments:
executable_name|arg1|arg2|...
- Any substring (including the executable name) may contain escape se-
- quences started by a dollar character: $<digits> or ${<digits>} is re-
- placed by the captured substring of the given decimal number, which
- must be greater than zero. If the number is greater than the number of
- capturing substrings, or if the capture is unset, the replacement is
- empty.
-
- Any other character is substituted by itself. In particular, $$ is re-
- placed by a single dollar and $| is replaced by a pipe character. Here
- is an example:
+ Any substring (including the executable name) may contain escape se-
+ quences started by a dollar character. These are the same as for the
+ --output (-O) option documented above, except that $0 cannot insert the
+ matched string because the match is still in progress. Instead, the
+ character '0' is inserted. If you need a literal dollar or pipe charac-
+ ter in any substring, use $$ or $| respectively. Here is an example:
echo -e "abcde\n12345" | pcre2grep \
'(?x)(.)(..(.))
@@ -914,28 +962,15 @@ USING PCRE2'S CALLOUT FACILITY
Arg1: [1] [234] [4] Arg2: |1| ()
12345
- The parameters for the system call that is used to run the program or
+ The parameters for the system call that is used to run the program or
script are zero-terminated strings. This means that binary zero charac-
- ters in the callout argument will cause premature termination of their
- substrings, and therefore should not be present. Any syntax errors in
- the string (for example, a dollar not followed by another character)
- cause the callout to be ignored. If running the program fails for any
- reason (including the non-existence of the executable), a local match-
+ ters in the callout argument will cause premature termination of their
+ substrings, and therefore should not be present. Any syntax errors in
+ the string (for example, a dollar not followed by another character)
+ causes the callout to be ignored. If running the program fails for any
+ reason (including the non-existence of the executable), a local match-
ing failure occurs and the matcher backtracks in the normal way.
- Echoing a specific string
-
- This facility is always available, provided that callouts were not com-
- pletely disabled when pcre2grep was built. If the callout string starts
- with a pipe (vertical bar) character, the rest of the string is written
- to the output, having been passed through the same escape processing as
- text from the --output option. This provides a simple echoing facility
- that avoids calling an external program or script. No terminator is
- added to the string, so if you want a newline, you must include it ex-
- plicitly. Matching continues normally after the string is output. If
- you want to see only the callout output but not any output from an ac-
- tual match, you should end the relevant pattern with (*FAIL).
-
MATCHING ERRORS
@@ -969,7 +1004,7 @@ DIAGNOSTICS
SEE ALSO
- pcre2pattern(3), pcre2syntax(3), pcre2callout(3).
+ pcre2pattern(3), pcre2syntax(3), pcre2callout(3), pcre2unicode(3).
AUTHOR
@@ -981,5 +1016,5 @@ AUTHOR
REVISION
- Last updated: 25 January 2020
+ Last updated: 04 October 2020
Copyright (c) 1997-2020 University of Cambridge.
diff --git a/doc/pcre2pattern.3 b/doc/pcre2pattern.3
index c88ce03..dc78e4d 100644
--- a/doc/pcre2pattern.3
+++ b/doc/pcre2pattern.3
@@ -1,4 +1,4 @@
-.TH PCRE2PATTERN 3 "24 February 2020" "PCRE2 10.35"
+.TH PCRE2PATTERN 3 "06 October 2020" "PCRE2 10.35"
.SH NAME
PCRE2 - Perl-compatible regular expressions (revised API)
.SH "PCRE2 REGULAR EXPRESSION DETAILS"
@@ -263,8 +263,11 @@ corresponding characters in the subject. As a trivial example, the pattern
The quick brown fox
.sp
matches a portion of a subject string that is identical to itself. When
-caseless matching is specified (the PCRE2_CASELESS option), letters are matched
-independently of case.
+caseless matching is specified (the PCRE2_CASELESS option or (?i) within the
+pattern), letters are matched independently of case. Note that there are two
+ASCII characters, K and S, that, in addition to their lower case ASCII
+equivalents, are case-equivalent with Unicode U+212A (Kelvin sign) and U+017F
+(long S) respectively when either PCRE2_UTF or PCRE2_UCP is set.
.P
The power of regular expressions comes from the ability to include wild cards,
character classes, alternatives, and repetitions in the pattern. These are
@@ -298,6 +301,22 @@ a character class the only metacharacters are:
[ POSIX character class (if followed by POSIX syntax)
] terminates the character class
.sp
+If a pattern is compiled with the PCRE2_EXTENDED option, most white space in
+the pattern, other than in a character class, and characters between a #
+outside a character class and the next newline, inclusive, are ignored. An
+escaping backslash can be used to include a white space or a # character as
+part of the pattern. If the PCRE2_EXTENDED_MORE option is set, the same
+applies, but in addition unescaped space and horizontal tab characters are
+ignored inside a character class. Note: only these two characters are ignored,
+not the full set of pattern white space characters that are ignored outside a
+character class. Option settings can be changed within a pattern; see the
+section entitled
+.\" HTML <a href="#internaloptions">
+.\" </a>
+"Internal Option Setting"
+.\"
+below.
+.P
The following sections describe the use of each of the metacharacters.
.
.
@@ -315,15 +334,9 @@ would otherwise be interpreted as a metacharacter, so it is always safe to
precede a non-alphanumeric with backslash to specify that it stands for itself.
In particular, if you want to match a backslash, you write \e\e.
.P
-In a UTF mode, only ASCII digits and letters have any special meaning after a
-backslash. All other characters (in particular, those whose code points are
-greater than 127) are treated as literals.
-.P
-If a pattern is compiled with the PCRE2_EXTENDED option, most white space in
-the pattern (other than in a character class), and characters between a #
-outside a character class and the next newline, inclusive, are ignored. An
-escaping backslash can be used to include a white space or # character as part
-of the pattern.
+Only ASCII digits and letters have any special meaning after a backslash. All
+other characters (in particular, those whose code points are greater than 127)
+are treated as literals.
.P
If you want to treat all characters in a sequence as literals, you can do so by
putting them between \eQ and \eE. This is different from Perl in that $ and @
@@ -1155,8 +1168,9 @@ For example, when the pattern
.sp
matches "foobar", the first substring is still set to "foo".
.P
-Perl documents that the use of \eK within assertions is "not well defined". In
-PCRE2, \eK is acted upon when it occurs inside positive assertions, but is
+Perl used to document that the use of \eK within lookaround assertions is "not
+well defined", but from version 5.32.0 Perl does not support this usage at all.
+In PCRE2, \eK is acted upon when it occurs inside positive assertions, but is
ignored in negative assertions. Note that when a pattern such as (?=ab\eK)
matches, the reported start of the match can be greater than the end of the
match. Using \eK in a lookbehind assertion at the start of a pattern can also
@@ -1436,7 +1450,10 @@ Characters in a class may be specified by their code points using \eo, \ex, or
\eN{U+hh..} in the usual way. When caseless matching is set, any letters in a
class represent both their upper case and lower case versions, so for example,
a caseless [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not
-match "A", whereas a caseful version would.
+match "A", whereas a caseful version would. Note that there are two ASCII
+characters, K and S, that, in addition to their lower case ASCII equivalents,
+are case-equivalent with Unicode U+212A (Kelvin sign) and U+017F (long S)
+respectively when either PCRE2_UTF or PCRE2_UCP is set.
.P
Characters that might indicate line breaks are never treated in any special way
when matching character classes, whatever line-ending sequence is in use, and
@@ -3881,6 +3898,6 @@ Cambridge, England.
.rs
.sp
.nf
-Last updated: 24 February 2020
+Last updated: 06 October 2020
Copyright (c) 1997-2020 University of Cambridge.
.fi
diff --git a/doc/pcre2test.1 b/doc/pcre2test.1
index ec17763..c63f03d 100644
--- a/doc/pcre2test.1
+++ b/doc/pcre2test.1
@@ -1,4 +1,4 @@
-.TH PCRE2TEST 1 "20 March 2020" "PCRE 10.35"
+.TH PCRE2TEST 1 "14 September 2020" "PCRE 10.36"
.SH NAME
pcre2test - a program for testing Perl-compatible regular expressions.
.SH SYNOPSIS
@@ -273,7 +273,7 @@ test data, command lines that begin with # may appear. This file format, with
some restrictions, can also be processed by the \fBperltest.sh\fP script that
is distributed with PCRE2 as a means of checking that the behaviour of PCRE2
and Perl is the same. For a specification of \fBperltest.sh\fP, see the
-comments near its beginning.
+comments near its beginning. See also the #perltest command below.
.P
When the input is a terminal, \fBpcre2test\fP prompts for each line of input,
using "re>" to prompt for regular expression patterns, and "data>" to prompt
@@ -369,14 +369,19 @@ patterns. Modifiers on a pattern can change these settings.
.sp
#perltest
.sp
-The appearance of this line causes all subsequent modifier settings to be
-checked for compatibility with the \fBperltest.sh\fP script, which is used to
-confirm that Perl gives the same results as PCRE2. Also, apart from comment
-lines, #pattern commands, and #subject commands that set or unset "mark", no
-command lines are permitted, because they and many of the modifiers are
-specific to \fBpcre2test\fP, and should not be used in test files that are also
-processed by \fBperltest.sh\fP. The \fB#perltest\fP command helps detect tests
-that are accidentally put in the wrong file.
+This line is used in test files that can also be processed by \fBperltest.sh\fP
+to confirm that Perl gives the same results as PCRE2. Subsequent tests are
+checked for the use of \fBpcre2test\fP features that are incompatible with the
+\fBperltest.sh\fP script.
+.P
+Patterns must use '/' as their delimiter, and only certain modifiers are
+supported. Comment lines, #pattern commands, and #subject commands that set or
+unset "mark" are recognized and acted on. The #perltest, #forbid_utf, and
+#newline_default commands, which are needed in the relevant pcre2test files,
+are silently ignored. All other command lines are ignored, but give a warning
+message. The \fB#perltest\fP command helps detect tests that are accidentally
+put in the wrong file or use the wrong delimiter. For more details of the
+\fBperltest.sh\fP script see the comments it contains.
.sp
#pop [<modifiers>]
#popcopy [<modifiers>]
@@ -2096,6 +2101,6 @@ Cambridge, England.
.rs
.sp
.nf
-Last updated: 20 March 2020
+Last updated: 14 September 2020
Copyright (c) 1997-2020 University of Cambridge.
.fi
diff --git a/doc/pcre2test.txt b/doc/pcre2test.txt
index c0ba83f..645156e 100644
--- a/doc/pcre2test.txt
+++ b/doc/pcre2test.txt
@@ -257,127 +257,134 @@ DESCRIPTION
appear. This file format, with some restrictions, can also be processed
by the perltest.sh script that is distributed with PCRE2 as a means of
checking that the behaviour of PCRE2 and Perl is the same. For a speci-
- fication of perltest.sh, see the comments near its beginning.
+ fication of perltest.sh, see the comments near its beginning. See also
+ the #perltest command below.
When the input is a terminal, pcre2test prompts for each line of input,
- using "re>" to prompt for regular expression patterns, and "data>" to
- prompt for subject lines. Command lines starting with # can be entered
+ using "re>" to prompt for regular expression patterns, and "data>" to
+ prompt for subject lines. Command lines starting with # can be entered
only in response to the "re>" prompt.
- Each subject line is matched separately and independently. If you want
+ Each subject line is matched separately and independently. If you want
to do multi-line matches, you have to use the \n escape sequence (or \r
- or \r\n, etc., depending on the newline setting) in a single line of
- input to encode the newline sequences. There is no limit on the length
- of subject lines; the input buffer is automatically extended if it is
- too small. There are replication features that makes it possible to
- generate long repetitive pattern or subject lines without having to
+ or \r\n, etc., depending on the newline setting) in a single line of
+ input to encode the newline sequences. There is no limit on the length
+ of subject lines; the input buffer is automatically extended if it is
+ too small. There are replication features that makes it possible to
+ generate long repetitive pattern or subject lines without having to
supply them explicitly.
- An empty line or the end of the file signals the end of the subject
- lines for a test, at which point a new pattern or command line is ex-
+ An empty line or the end of the file signals the end of the subject
+ lines for a test, at which point a new pattern or command line is ex-
pected if there is still input to be read.
COMMAND LINES
- In between sets of test data, a line that begins with # is interpreted
+ In between sets of test data, a line that begins with # is interpreted
as a command line. If the first character is followed by white space or
- an exclamation mark, the line is treated as a comment, and ignored.
+ an exclamation mark, the line is treated as a comment, and ignored.
Otherwise, the following commands are recognized:
#forbid_utf
- Subsequent patterns automatically have the PCRE2_NEVER_UTF and
- PCRE2_NEVER_UCP options set, which locks out the use of the PCRE2_UTF
- and PCRE2_UCP options and the use of (*UTF) and (*UCP) at the start of
- patterns. This command also forces an error if a subsequent pattern
- contains any occurrences of \P, \p, or \X, which are still supported
- when PCRE2_UTF is not set, but which require Unicode property support
+ Subsequent patterns automatically have the PCRE2_NEVER_UTF and
+ PCRE2_NEVER_UCP options set, which locks out the use of the PCRE2_UTF
+ and PCRE2_UCP options and the use of (*UTF) and (*UCP) at the start of
+ patterns. This command also forces an error if a subsequent pattern
+ contains any occurrences of \P, \p, or \X, which are still supported
+ when PCRE2_UTF is not set, but which require Unicode property support
to be included in the library.
- This is a trigger guard that is used in test files to ensure that UTF
- or Unicode property tests are not accidentally added to files that are
- used when Unicode support is not included in the library. Setting
- PCRE2_NEVER_UTF and PCRE2_NEVER_UCP as a default can also be obtained
- by the use of #pattern; the difference is that #forbid_utf cannot be
- unset, and the automatic options are not displayed in pattern informa-
+ This is a trigger guard that is used in test files to ensure that UTF
+ or Unicode property tests are not accidentally added to files that are
+ used when Unicode support is not included in the library. Setting
+ PCRE2_NEVER_UTF and PCRE2_NEVER_UCP as a default can also be obtained
+ by the use of #pattern; the difference is that #forbid_utf cannot be
+ unset, and the automatic options are not displayed in pattern informa-
tion, to avoid cluttering up test output.
#load <filename>
This command is used to load a set of precompiled patterns from a file,
- as described in the section entitled "Saving and restoring compiled
+ as described in the section entitled "Saving and restoring compiled
patterns" below.
#loadtables <filename>
- This command is used to load a set of binary character tables that can
- be accessed by the tables=3 qualifier. Such tables can be created by
+ This command is used to load a set of binary character tables that can
+ be accessed by the tables=3 qualifier. Such tables can be created by
the pcre2_dftables program with the -b option.
#newline_default [<newline-list>]
- When PCRE2 is built, a default newline convention can be specified.
- This determines which characters and/or character pairs are recognized
+ When PCRE2 is built, a default newline convention can be specified.
+ This determines which characters and/or character pairs are recognized
as indicating a newline in a pattern or subject string. The default can
- be overridden when a pattern is compiled. The standard test files con-
- tain tests of various newline conventions, but the majority of the
- tests expect a single linefeed to be recognized as a newline by de-
- fault. Without special action the tests would fail when PCRE2 is com-
+ be overridden when a pattern is compiled. The standard test files con-
+ tain tests of various newline conventions, but the majority of the
+ tests expect a single linefeed to be recognized as a newline by de-
+ fault. Without special action the tests would fail when PCRE2 is com-
piled with either CR or CRLF as the default newline.
The #newline_default command specifies a list of newline types that are
- acceptable as the default. The types must be one of CR, LF, CRLF, ANY-
+ acceptable as the default. The types must be one of CR, LF, CRLF, ANY-
CRLF, ANY, or NUL (in upper or lower case), for example:
#newline_default LF Any anyCRLF
If the default newline is in the list, this command has no effect. Oth-
- erwise, except when testing the POSIX API, a newline modifier that
+ erwise, except when testing the POSIX API, a newline modifier that
specifies the first newline convention in the list (LF in the above ex-
- ample) is added to any pattern that does not already have a newline
+ ample) is added to any pattern that does not already have a newline
modifier. If the newline list is empty, the feature is turned off. This
command is present in a number of the standard test input files.
- When the POSIX API is being tested there is no way to override the de-
+ When the POSIX API is being tested there is no way to override the de-
fault newline convention, though it is possible to set the newline con-
- vention from within the pattern. A warning is given if the posix or
- posix_nosub modifier is used when #newline_default would set a default
+ vention from within the pattern. A warning is given if the posix or
+ posix_nosub modifier is used when #newline_default would set a default
for the non-POSIX API.
#pattern <modifier-list>
- This command sets a default modifier list that applies to all subse-
+ This command sets a default modifier list that applies to all subse-
quent patterns. Modifiers on a pattern can change these settings.
#perltest
- The appearance of this line causes all subsequent modifier settings to
- be checked for compatibility with the perltest.sh script, which is used
- to confirm that Perl gives the same results as PCRE2. Also, apart from
- comment lines, #pattern commands, and #subject commands that set or un-
- set "mark", no command lines are permitted, because they and many of
- the modifiers are specific to pcre2test, and should not be used in test
- files that are also processed by perltest.sh. The #perltest command
- helps detect tests that are accidentally put in the wrong file.
+ This line is used in test files that can also be processed by perl-
+ test.sh to confirm that Perl gives the same results as PCRE2. Subse-
+ quent tests are checked for the use of pcre2test features that are in-
+ compatible with the perltest.sh script.
+
+ Patterns must use '/' as their delimiter, and only certain modifiers
+ are supported. Comment lines, #pattern commands, and #subject commands
+ that set or unset "mark" are recognized and acted on. The #perltest,
+ #forbid_utf, and #newline_default commands, which are needed in the
+ relevant pcre2test files, are silently ignored. All other command lines
+ are ignored, but give a warning message. The #perltest command helps
+ detect tests that are accidentally put in the wrong file or use the
+ wrong delimiter. For more details of the perltest.sh script see the
+ comments it contains.
#pop [<modifiers>]
#popcopy [<modifiers>]
- These commands are used to manipulate the stack of compiled patterns,
- as described in the section entitled "Saving and restoring compiled
+ These commands are used to manipulate the stack of compiled patterns,
+ as described in the section entitled "Saving and restoring compiled
patterns" below.
#save <filename>
- This command is used to save a set of compiled patterns to a file, as
- described in the section entitled "Saving and restoring compiled pat-
+ This command is used to save a set of compiled patterns to a file, as
+ described in the section entitled "Saving and restoring compiled pat-
terns" below.
#subject <modifier-list>
- This command sets a default modifier list that applies to all subse-
- quent subject lines. Modifiers on a subject line can change these set-
+ This command sets a default modifier list that applies to all subse-
+ quent subject lines. Modifiers on a subject line can change these set-
tings.
@@ -385,58 +392,58 @@ MODIFIER SYNTAX
Modifier lists are used with both pattern and subject lines. Items in a
list are separated by commas followed by optional white space. Trailing
- whitespace in a modifier list is ignored. Some modifiers may be given
- for both patterns and subject lines, whereas others are valid only for
- one or the other. Each modifier has a long name, for example "an-
- chored", and some of them must be followed by an equals sign and a
- value, for example, "offset=12". Values cannot contain comma charac-
- ters, but may contain spaces. Modifiers that do not take values may be
+ whitespace in a modifier list is ignored. Some modifiers may be given
+ for both patterns and subject lines, whereas others are valid only for
+ one or the other. Each modifier has a long name, for example "an-
+ chored", and some of them must be followed by an equals sign and a
+ value, for example, "offset=12". Values cannot contain comma charac-
+ ters, but may contain spaces. Modifiers that do not take values may be
preceded by a minus sign to turn off a previous setting.
A few of the more common modifiers can also be specified as single let-
- ters, for example "i" for "caseless". In documentation, following the
+ ters, for example "i" for "caseless". In documentation, following the
Perl convention, these are written with a slash ("the /i modifier") for
- clarity. Abbreviated modifiers must all be concatenated in the first
- item of a modifier list. If the first item is not recognized as a long
- modifier name, it is interpreted as a sequence of these abbreviations.
+ clarity. Abbreviated modifiers must all be concatenated in the first
+ item of a modifier list. If the first item is not recognized as a long
+ modifier name, it is interpreted as a sequence of these abbreviations.
For example:
/abc/ig,newline=cr,jit=3
- This is a pattern line whose modifier list starts with two one-letter
- modifiers (/i and /g). The lower-case abbreviated modifiers are the
+ This is a pattern line whose modifier list starts with two one-letter
+ modifiers (/i and /g). The lower-case abbreviated modifiers are the
same as used in Perl.
PATTERN SYNTAX
- A pattern line must start with one of the following characters (common
+ A pattern line must start with one of the following characters (common
symbols, excluding pattern meta-characters):
/ ! " ' ` - = _ : ; , % & @ ~
- This is interpreted as the pattern's delimiter. A regular expression
- may be continued over several input lines, in which case the newline
+ This is interpreted as the pattern's delimiter. A regular expression
+ may be continued over several input lines, in which case the newline
characters are included within it. It is possible to include the delim-
iter within the pattern by escaping it with a backslash, for example
/abc\/def/
- If you do this, the escape and the delimiter form part of the pattern,
+ If you do this, the escape and the delimiter form part of the pattern,
but since the delimiters are all non-alphanumeric, this does not affect
- its interpretation. If the terminating delimiter is immediately fol-
+ its interpretation. If the terminating delimiter is immediately fol-
lowed by a backslash, for example,
/abc/\
- then a backslash is added to the end of the pattern. This is done to
- provide a way of testing the error condition that arises if a pattern
+ then a backslash is added to the end of the pattern. This is done to
+ provide a way of testing the error condition that arises if a pattern
finishes with a backslash, because
/abc\/
- is interpreted as the first line of a pattern that starts with "abc/",
- causing pcre2test to read the next line as a continuation of the regu-
+ is interpreted as the first line of a pattern that starts with "abc/",
+ causing pcre2test to read the next line as a continuation of the regu-
lar expression.
A pattern can be followed by a modifier list (details below).
@@ -444,7 +451,7 @@ PATTERN SYNTAX
SUBJECT LINE SYNTAX
- Before each subject line is passed to pcre2_match() or
+ Before each subject line is passed to pcre2_match() or
pcre2_dfa_match(), leading and trailing white space is removed, and the
line is scanned for backslash escapes, unless the subject_literal modi-
fier was set for the pattern. The following provide a means of encoding
@@ -465,23 +472,23 @@ SUBJECT LINE SYNTAX
\x{hh...} hexadecimal character (any number of hex digits)
The use of \x{hh...} is not dependent on the use of the utf modifier on
- the pattern. It is recognized always. There may be any number of hexa-
- decimal digits inside the braces; invalid values provoke error mes-
+ the pattern. It is recognized always. There may be any number of hexa-
+ decimal digits inside the braces; invalid values provoke error mes-
sages.
- Note that \xhh specifies one byte rather than one character in UTF-8
- mode; this makes it possible to construct invalid UTF-8 sequences for
- testing purposes. On the other hand, \x{hh} is interpreted as a UTF-8
- character in UTF-8 mode, generating more than one byte if the value is
- greater than 127. When testing the 8-bit library not in UTF-8 mode,
+ Note that \xhh specifies one byte rather than one character in UTF-8
+ mode; this makes it possible to construct invalid UTF-8 sequences for
+ testing purposes. On the other hand, \x{hh} is interpreted as a UTF-8
+ character in UTF-8 mode, generating more than one byte if the value is
+ greater than 127. When testing the 8-bit library not in UTF-8 mode,
\x{hh} generates one byte for values less than 256, and causes an error
for greater values.
In UTF-16 mode, all 4-digit \x{hhhh} values are accepted. This makes it
possible to construct invalid UTF-16 sequences for testing purposes.
- In UTF-32 mode, all 4- to 8-digit \x{...} values are accepted. This
- makes it possible to construct invalid UTF-32 sequences for testing
+ In UTF-32 mode, all 4- to 8-digit \x{...} values are accepted. This
+ makes it possible to construct invalid UTF-32 sequences for testing
purposes.
There is a special backslash sequence that specifies replication of one
@@ -489,31 +496,31 @@ SUBJECT LINE SYNTAX
\[<characters>]{<count>}
- This makes it possible to test long strings without having to provide
+ This makes it possible to test long strings without having to provide
them as part of the file. For example:
\[abc]{4}
- is converted to "abcabcabcabc". This feature does not support nesting.
+ is converted to "abcabcabcabc". This feature does not support nesting.
To include a closing square bracket in the characters, code it as \x5D.
- A backslash followed by an equals sign marks the end of the subject
+ A backslash followed by an equals sign marks the end of the subject
string and the start of a modifier list. For example:
abc\=notbol,notempty
- If the subject string is empty and \= is followed by whitespace, the
- line is treated as a comment line, and is not used for matching. For
+ If the subject string is empty and \= is followed by whitespace, the
+ line is treated as a comment line, and is not used for matching. For
example:
\= This is a comment.
abc\= This is an invalid modifier list.
- A backslash followed by any other non-alphanumeric character just es-
- capes that character. A backslash followed by anything else causes an
- error. However, if the very last character in the line is a backslash
- (and there is no modifier list), it is ignored. This gives a way of
- passing an empty line as data, since a real empty line terminates the
+ A backslash followed by any other non-alphanumeric character just es-
+ capes that character. A backslash followed by anything else causes an
+ error. However, if the very last character in the line is a backslash
+ (and there is no modifier list), it is ignored. This gives a way of
+ passing an empty line as data, since a real empty line terminates the
data input.
If the subject_literal modifier is set for a pattern, all subject lines
@@ -524,22 +531,22 @@ SUBJECT LINE SYNTAX
PATTERN MODIFIERS
- There are several types of modifier that can appear in pattern lines.
+ There are several types of modifier that can appear in pattern lines.
Except where noted below, they may also be used in #pattern commands. A
- pattern's modifier list can add to or override default modifiers that
+ pattern's modifier list can add to or override default modifiers that
were set by a previous #pattern command.
Setting compilation options
- The following modifiers set options for pcre2_compile(). Most of them
- set bits in the options argument of that function, but those whose
+ The following modifiers set options for pcre2_compile(). Most of them
+ set bits in the options argument of that function, but those whose
names start with PCRE2_EXTRA are additional options that are set in the
compile context. For the main options, there are some single-letter ab-
- breviations that are the same as Perl options. There is special han-
- dling for /x: if a second x is present, PCRE2_EXTENDED is converted
- into PCRE2_EXTENDED_MORE as in Perl. A third appearance adds PCRE2_EX-
- TENDED as well, though this makes no difference to the way pcre2_com-
- pile() behaves. See pcre2api for a description of the effects of these
+ breviations that are the same as Perl options. There is special han-
+ dling for /x: if a second x is present, PCRE2_EXTENDED is converted
+ into PCRE2_EXTENDED_MORE as in Perl. A third appearance adds PCRE2_EX-
+ TENDED as well, though this makes no difference to the way pcre2_com-
+ pile() behaves. See pcre2api for a description of the effects of these
options.
allow_empty_class set PCRE2_ALLOW_EMPTY_CLASS
@@ -580,16 +587,16 @@ PATTERN MODIFIERS
utf set PCRE2_UTF
As well as turning on the PCRE2_UTF option, the utf modifier causes all
- non-printing characters in output strings to be printed using the
- \x{hh...} notation. Otherwise, those less than 0x100 are output in hex
- without the curly brackets. Setting utf in 16-bit or 32-bit mode also
- causes pattern and subject strings to be translated to UTF-16 or
+ non-printing characters in output strings to be printed using the
+ \x{hh...} notation. Otherwise, those less than 0x100 are output in hex
+ without the curly brackets. Setting utf in 16-bit or 32-bit mode also
+ causes pattern and subject strings to be translated to UTF-16 or
UTF-32, respectively, before being passed to library functions.
Setting compilation controls
- The following modifiers affect the compilation process or request in-
- formation about the pattern. There are single-letter abbreviations for
+ The following modifiers affect the compilation process or request in-
+ formation about the pattern. There are single-letter abbreviations for
some that are heavily used in the test files.
bsr=[anycrlf|unicode] specify \R handling
@@ -627,35 +634,35 @@ PATTERN MODIFIERS
Newline and \R handling
- The bsr modifier specifies what \R in a pattern should match. If it is
- set to "anycrlf", \R matches CR, LF, or CRLF only. If it is set to
- "unicode", \R matches any Unicode newline sequence. The default can be
+ The bsr modifier specifies what \R in a pattern should match. If it is
+ set to "anycrlf", \R matches CR, LF, or CRLF only. If it is set to
+ "unicode", \R matches any Unicode newline sequence. The default can be
specified when PCRE2 is built; if it is not, the default is set to Uni-
code.
- The newline modifier specifies which characters are to be interpreted
+ The newline modifier specifies which characters are to be interpreted
as newlines, both in the pattern and in subject lines. The type must be
one of CR, LF, CRLF, ANYCRLF, ANY, or NUL (in upper or lower case).
Information about a pattern
- The debug modifier is a shorthand for info,fullbincode, requesting all
+ The debug modifier is a shorthand for info,fullbincode, requesting all
available information.
The bincode modifier causes a representation of the compiled code to be
- output after compilation. This information does not contain length and
+ output after compilation. This information does not contain length and
offset values, which ensures that the same output is generated for dif-
- ferent internal link sizes and different code unit widths. By using
- bincode, the same regression tests can be used in different environ-
+ ferent internal link sizes and different code unit widths. By using
+ bincode, the same regression tests can be used in different environ-
ments.
- The fullbincode modifier, by contrast, does include length and offset
- values. This is used in a few special tests that run only for specific
+ The fullbincode modifier, by contrast, does include length and offset
+ values. This is used in a few special tests that run only for specific
code unit widths and link sizes, and is also useful for one-off tests.
- The info modifier requests information about the compiled pattern
- (whether it is anchored, has a fixed first character, and so on). The
- information is obtained from the pcre2_pattern_info() function. Here
+ The info modifier requests information about the compiled pattern
+ (whether it is anchored, has a fixed first character, and so on). The
+ information is obtained from the pcre2_pattern_info() function. Here
are some typical examples:
re> /(?i)(^a|^b)/m,info
@@ -673,117 +680,117 @@ PATTERN MODIFIERS
Last code unit = 'c' (caseless)
Subject length lower bound = 3
- "Compile options" are those specified by modifiers; "overall options"
- have added options that are taken or deduced from the pattern. If both
- sets of options are the same, just a single "options" line is output;
- if there are no options, the line is omitted. "First code unit" is
- where any match must start; if there is more than one they are listed
- as "starting code units". "Last code unit" is the last literal code
- unit that must be present in any match. This is not necessarily the
- last character. These lines are omitted if no starting or ending code
- units are recorded. The subject length line is omitted when
- no_start_optimize is set because the minimum length is not calculated
+ "Compile options" are those specified by modifiers; "overall options"
+ have added options that are taken or deduced from the pattern. If both
+ sets of options are the same, just a single "options" line is output;
+ if there are no options, the line is omitted. "First code unit" is
+ where any match must start; if there is more than one they are listed
+ as "starting code units". "Last code unit" is the last literal code
+ unit that must be present in any match. This is not necessarily the
+ last character. These lines are omitted if no starting or ending code
+ units are recorded. The subject length line is omitted when
+ no_start_optimize is set because the minimum length is not calculated
when it can never be used.
- The framesize modifier shows the size, in bytes, of the storage frames
- used by pcre2_match() for handling backtracking. The size depends on
+ The framesize modifier shows the size, in bytes, of the storage frames
+ used by pcre2_match() for handling backtracking. The size depends on
the number of capturing parentheses in the pattern.
- The callout_info modifier requests information about all the callouts
+ The callout_info modifier requests information about all the callouts
in the pattern. A list of them is output at the end of any other infor-
mation that is requested. For each callout, either its number or string
is given, followed by the item that follows it in the pattern.
Passing a NULL context
- Normally, pcre2test passes a context block to pcre2_compile(). If the
- null_context modifier is set, however, NULL is passed. This is for
- testing that pcre2_compile() behaves correctly in this case (it uses
+ Normally, pcre2test passes a context block to pcre2_compile(). If the
+ null_context modifier is set, however, NULL is passed. This is for
+ testing that pcre2_compile() behaves correctly in this case (it uses
default values).
Specifying pattern characters in hexadecimal
- The hex modifier specifies that the characters of the pattern, except
- for substrings enclosed in single or double quotes, are to be inter-
- preted as pairs of hexadecimal digits. This feature is provided as a
+ The hex modifier specifies that the characters of the pattern, except
+ for substrings enclosed in single or double quotes, are to be inter-
+ preted as pairs of hexadecimal digits. This feature is provided as a
way of creating patterns that contain binary zeros and other non-print-
- ing characters. White space is permitted between pairs of digits. For
+ ing characters. White space is permitted between pairs of digits. For
example, this pattern contains three characters:
/ab 32 59/hex
- Parts of such a pattern are taken literally if quoted. This pattern
- contains nine characters, only two of which are specified in hexadeci-
+ Parts of such a pattern are taken literally if quoted. This pattern
+ contains nine characters, only two of which are specified in hexadeci-
mal:
/ab "literal" 32/hex
- Either single or double quotes may be used. There is no way of includ-
- ing the delimiter within a substring. The hex and expand modifiers are
+ Either single or double quotes may be used. There is no way of includ-
+ ing the delimiter within a substring. The hex and expand modifiers are
mutually exclusive.
Specifying the pattern's length
By default, patterns are passed to the compiling functions as zero-ter-
- minated strings but can be passed by length instead of being zero-ter-
- minated. The use_length modifier causes this to happen. Using a length
- happens automatically (whether or not use_length is set) when hex is
- set, because patterns specified in hexadecimal may contain binary ze-
+ minated strings but can be passed by length instead of being zero-ter-
+ minated. The use_length modifier causes this to happen. Using a length
+ happens automatically (whether or not use_length is set) when hex is
+ set, because patterns specified in hexadecimal may contain binary ze-
ros.
If hex or use_length is used with the POSIX wrapper API (see "Using the
- POSIX wrapper API" below), the REG_PEND extension is used to pass the
+ POSIX wrapper API" below), the REG_PEND extension is used to pass the
pattern's length.
Specifying wide characters in 16-bit and 32-bit modes
In 16-bit and 32-bit modes, all input is automatically treated as UTF-8
- and translated to UTF-16 or UTF-32 when the utf modifier is set. For
+ and translated to UTF-16 or UTF-32 when the utf modifier is set. For
testing the 16-bit and 32-bit libraries in non-UTF mode, the utf8_input
- modifier can be used. It is mutually exclusive with utf. Input lines
+ modifier can be used. It is mutually exclusive with utf. Input lines
are interpreted as UTF-8 as a means of specifying wide characters. More
details are given in "Input encoding" above.
Generating long repetitive patterns
- Some tests use long patterns that are very repetitive. Instead of cre-
- ating a very long input line for such a pattern, you can use a special
- repetition feature, similar to the one described for subject lines
- above. If the expand modifier is present on a pattern, parts of the
+ Some tests use long patterns that are very repetitive. Instead of cre-
+ ating a very long input line for such a pattern, you can use a special
+ repetition feature, similar to the one described for subject lines
+ above. If the expand modifier is present on a pattern, parts of the
pattern that have the form
\[<characters>]{<count>}
are expanded before the pattern is passed to pcre2_compile(). For exam-
ple, \[AB]{6000} is expanded to "ABAB..." 6000 times. This construction
- cannot be nested. An initial "\[" sequence is recognized only if "]{"
- followed by decimal digits and "}" is found later in the pattern. If
+ cannot be nested. An initial "\[" sequence is recognized only if "]{"
+ followed by decimal digits and "}" is found later in the pattern. If
not, the characters remain in the pattern unaltered. The expand and hex
modifiers are mutually exclusive.
- If part of an expanded pattern looks like an expansion, but is really
+ If part of an expanded pattern looks like an expansion, but is really
part of the actual pattern, unwanted expansion can be avoided by giving
two values in the quantifier. For example, \[AB]{6000,6000} is not rec-
ognized as an expansion item.
- If the info modifier is set on an expanded pattern, the result of the
+ If the info modifier is set on an expanded pattern, the result of the
expansion is included in the information that is output.
JIT compilation
- Just-in-time (JIT) compiling is a heavyweight optimization that can
- greatly speed up pattern matching. See the pcre2jit documentation for
- details. JIT compiling happens, optionally, after a pattern has been
- successfully compiled into an internal form. The JIT compiler converts
+ Just-in-time (JIT) compiling is a heavyweight optimization that can
+ greatly speed up pattern matching. See the pcre2jit documentation for
+ details. JIT compiling happens, optionally, after a pattern has been
+ successfully compiled into an internal form. The JIT compiler converts
this to optimized machine code. It needs to know whether the match-time
options PCRE2_PARTIAL_HARD and PCRE2_PARTIAL_SOFT are going to be used,
- because different code is generated for the different cases. See the
- partial modifier in "Subject Modifiers" below for details of how these
+ because different code is generated for the different cases. See the
+ partial modifier in "Subject Modifiers" below for details of how these
options are specified for each match attempt.
JIT compilation is requested by the jit pattern modifier, which may op-
- tionally be followed by an equals sign and a number in the range 0 to
- 7. The three bits that make up the number specify which of the three
+ tionally be followed by an equals sign and a number in the range 0 to
+ 7. The three bits that make up the number specify which of the three
JIT operating modes are to be compiled:
1 compile JIT code for non-partial matching
@@ -800,31 +807,31 @@ PATTERN MODIFIERS
6 soft and hard partial matching only
7 all three modes
- If no number is given, 7 is assumed. The phrase "partial matching"
+ If no number is given, 7 is assumed. The phrase "partial matching"
means a call to pcre2_match() with either the PCRE2_PARTIAL_SOFT or the
- PCRE2_PARTIAL_HARD option set. Note that such a call may return a com-
+ PCRE2_PARTIAL_HARD option set. Note that such a call may return a com-
plete match; the options enable the possibility of a partial match, but
- do not require it. Note also that if you request JIT compilation only
- for partial matching (for example, jit=2) but do not set the partial
- modifier on a subject line, that match will not use JIT code because
+ do not require it. Note also that if you request JIT compilation only
+ for partial matching (for example, jit=2) but do not set the partial
+ modifier on a subject line, that match will not use JIT code because
none was compiled for non-partial matching.
- If JIT compilation is successful, the compiled JIT code will automati-
+ If JIT compilation is successful, the compiled JIT code will automati-
cally be used when an appropriate type of match is run, except when in-
- compatible run-time options are specified. For more details, see the
- pcre2jit documentation. See also the jitstack modifier below for a way
+ compatible run-time options are specified. For more details, see the
+ pcre2jit documentation. See also the jitstack modifier below for a way
of setting the size of the JIT stack.
- If the jitfast modifier is specified, matching is done using the JIT
- "fast path" interface, pcre2_jit_match(), which skips some of the san-
- ity checks that are done by pcre2_match(), and of course does not work
- when JIT is not supported. If jitfast is specified without jit, jit=7
+ If the jitfast modifier is specified, matching is done using the JIT
+ "fast path" interface, pcre2_jit_match(), which skips some of the san-
+ ity checks that are done by pcre2_match(), and of course does not work
+ when JIT is not supported. If jitfast is specified without jit, jit=7
is assumed.
- If the jitverify modifier is specified, information about the compiled
- pattern shows whether JIT compilation was or was not successful. If
- jitverify is specified without jit, jit=7 is assumed. If JIT compila-
- tion is successful when jitverify is set, the text "(JIT)" is added to
+ If the jitverify modifier is specified, information about the compiled
+ pattern shows whether JIT compilation was or was not successful. If
+ jitverify is specified without jit, jit=7 is assumed. If JIT compila-
+ tion is successful when jitverify is set, the text "(JIT)" is added to
the first output line after a match or non match when JIT-compiled code
was actually used in the match.
@@ -835,19 +842,19 @@ PATTERN MODIFIERS
/pattern/locale=fr_FR
The given locale is set, pcre2_maketables() is called to build a set of
- character tables for the locale, and this is then passed to pcre2_com-
- pile() when compiling the regular expression. The same tables are used
- when matching the following subject lines. The locale modifier applies
+ character tables for the locale, and this is then passed to pcre2_com-
+ pile() when compiling the regular expression. The same tables are used
+ when matching the following subject lines. The locale modifier applies
only to the pattern on which it appears, but can be given in a #pattern
- command if a default is needed. Setting a locale and alternate charac-
+ command if a default is needed. Setting a locale and alternate charac-
ter tables are mutually exclusive.
Showing pattern memory
The memory modifier causes the size in bytes of the memory used to hold
- the compiled pattern to be output. This does not include the size of
- the pcre2_code block; it is just the actual compiled data. If the pat-
- tern is subsequently passed to the JIT compiler, the size of the JIT
+ the compiled pattern to be output. This does not include the size of
+ the pcre2_code block; it is just the actual compiled data. If the pat-
+ tern is subsequently passed to the JIT compiler, the size of the JIT
compiled code is also output. Here is an example:
re> /a(b)c/jit,memory
@@ -857,27 +864,27 @@ PATTERN MODIFIERS
Limiting nested parentheses
- The parens_nest_limit modifier sets a limit on the depth of nested
- parentheses in a pattern. Breaching the limit causes a compilation er-
- ror. The default for the library is set when PCRE2 is built, but
- pcre2test sets its own default of 220, which is required for running
+ The parens_nest_limit modifier sets a limit on the depth of nested
+ parentheses in a pattern. Breaching the limit causes a compilation er-
+ ror. The default for the library is set when PCRE2 is built, but
+ pcre2test sets its own default of 220, which is required for running
the standard test suite.
Limiting the pattern length
- The max_pattern_length modifier sets a limit, in code units, to the
+ The max_pattern_length modifier sets a limit, in code units, to the
length of pattern that pcre2_compile() will accept. Breaching the limit
- causes a compilation error. The default is the largest number a
+ 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
@@ -887,42 +894,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
@@ -933,15 +940,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
@@ -966,39 +973,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
@@ -1010,19 +1017,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.
@@ -1033,7 +1040,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
@@ -1049,34 +1056,34 @@ 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
+ 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.
aftertext show text after match
@@ -1125,29 +1132,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)/
@@ -1158,16 +1165,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:
@@ -1176,7 +1183,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
@@ -1184,99 +1191,99 @@ 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 decribed 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 decribed 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.
- 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
@@ -1290,8 +1297,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
@@ -1300,12 +1307,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/
@@ -1315,12 +1322,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:
@@ -1329,15 +1336,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
the input and output strings are output. For example:
/abc/g,replace=<$0>,substitute_callout
@@ -1346,19 +1353,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
@@ -1376,160 +1383,160 @@ 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 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
- minimum values 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
+ minimum values for each parameter that allows the match to complete
without error. If JIT is being used, only the match limit is relevant.
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. A value of zero disables the use of any heap memory; many
- simple pattern matches can be done without using the heap, so zero is
+ simple pattern matches can be done without using the heap, so zero is
not an unreasonable setting.
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(). These occur only when a match re-
- quires a bigger vector than the default for remembering backtracking
- points (pcre2_match()) or for internal workspace (pcre2_dfa_match()).
- In many cases there will be no heap memory used and therefore no addi-
+ 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(). These occur only when a match re-
+ quires a bigger vector than the default for remembering backtracking
+ points (pcre2_match()) or for internal workspace (pcre2_dfa_match()).
+ In many cases there will be no heap memory used and therefore no addi-
tional output. No heap memory is allocated during matching with JIT, so
- in that case the memory modifier never has any effect. For this modi-
- fier to work, the null_context modifier must not be set on both the
+ in that case the memory modifier never has any effect. For this modi-
+ fier 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.
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 match block of
+ 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 match block of
exactly the right size for the pattern. (It is not possible to create a
- match block with a zero-length ovector; there is always at least one
+ match block with a zero-length ovector; there is always at least one
pair of offsets.)
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
- 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
+ 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 or substitute_callout modifiers.
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
@@ -1545,8 +1552,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)/
@@ -1558,11 +1565,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 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 the rest of the subject
string, identified by "0+" like this:
re> /cat/aftertext
@@ -1582,8 +1589,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/
@@ -1591,7 +1598,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).
@@ -1599,7 +1606,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)/
@@ -1608,11 +1615,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.)
@@ -1628,16 +1635,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$/
@@ -1646,37 +1653,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
@@ -1703,17 +1710,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/
@@ -1729,26 +1736,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
@@ -1785,86 +1792,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
+ It is possible to save compiled patterns on disc or elsewhere, and
reload them later, subject to a number of restrictions. JIT data cannot
- be saved. The host on which the patterns are reloaded must be running
+ 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
@@ -1872,21 +1879,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
@@ -1899,10 +1906,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 analagous to the pushcopy modifier in that it
+ The #popcopy command is analagous to the pushcopy modifier in that it
makes current a copy of the topmost stack pattern, leaving the original
still on the stack.
@@ -1922,5 +1929,5 @@ AUTHOR
REVISION
- Last updated: 20 March 2020
+ Last updated: 14 September 2020
Copyright (c) 1997-2020 University of Cambridge.
diff --git a/libpcre2-16.pc.in b/libpcre2-16.pc.in
index 978040d..bacb466 100644
--- a/libpcre2-16.pc.in
+++ b/libpcre2-16.pc.in
@@ -8,6 +8,6 @@ includedir=@includedir@
Name: libpcre2-16
Description: PCRE2 - Perl compatible regular expressions C library (2nd API) with 16 bit character support
Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lpcre2-16
+Libs: -L${libdir} -lpcre2-16@LIB_POSTFIX@
Libs.private: @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@
diff --git a/libpcre2-32.pc.in b/libpcre2-32.pc.in
index d8fb187..06241f0 100644
--- a/libpcre2-32.pc.in
+++ b/libpcre2-32.pc.in
@@ -8,6 +8,6 @@ includedir=@includedir@
Name: libpcre2-32
Description: PCRE2 - Perl compatible regular expressions C library (2nd API) with 32 bit character support
Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lpcre2-32
+Libs: -L${libdir} -lpcre2-32@LIB_POSTFIX@
Libs.private: @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@
diff --git a/libpcre2-8.pc.in b/libpcre2-8.pc.in
index 5c872d0..246bb9e 100644
--- a/libpcre2-8.pc.in
+++ b/libpcre2-8.pc.in
@@ -8,6 +8,6 @@ includedir=@includedir@
Name: libpcre2-8
Description: PCRE2 - Perl compatible regular expressions C library (2nd API) with 8 bit character support
Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lpcre2-8
+Libs: -L${libdir} -lpcre2-8@LIB_POSTFIX@
Libs.private: @PTHREAD_CFLAGS@ @PTHREAD_LIBS@
Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@
diff --git a/libpcre2-posix.pc.in b/libpcre2-posix.pc.in
index 9641555..758c306 100644
--- a/libpcre2-posix.pc.in
+++ b/libpcre2-posix.pc.in
@@ -8,6 +8,6 @@ includedir=@includedir@
Name: libpcre2-posix
Description: Posix compatible interface to libpcre2-8
Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lpcre2-posix
+Libs: -L${libdir} -lpcre2-posix@LIB_POSTFIX@
Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@
Requires.private: libpcre2-8
diff --git a/pcre2-config.in b/pcre2-config.in
index 74271c0..bacea87 100644
--- a/pcre2-config.in
+++ b/pcre2-config.in
@@ -86,28 +86,28 @@ while test $# -gt 0; do
;;
--libs-posix)
if test @enable_pcre2_8@ = yes ; then
- echo $libS$libR -lpcre2-posix -lpcre2-8
+ echo $libS$libR -lpcre2-posix@LIB_POSTFIX@ -lpcre2-8@LIB_POSTFIX@
else
echo "${usage}" 1>&2
fi
;;
--libs8)
if test @enable_pcre2_8@ = yes ; then
- echo $libS$libR -lpcre2-8
+ echo $libS$libR -lpcre2-8@LIB_POSTFIX@
else
echo "${usage}" 1>&2
fi
;;
--libs16)
if test @enable_pcre2_16@ = yes ; then
- echo $libS$libR -lpcre2-16
+ echo $libS$libR -lpcre2-16@LIB_POSTFIX@
else
echo "${usage}" 1>&2
fi
;;
--libs32)
if test @enable_pcre2_32@ = yes ; then
- echo $libS$libR -lpcre2-32
+ echo $libS$libR -lpcre2-32@LIB_POSTFIX@
else
echo "${usage}" 1>&2
fi
diff --git a/perltest.sh b/perltest.sh
index 8368781..31406c5 100755
--- a/perltest.sh
+++ b/perltest.sh
@@ -68,6 +68,9 @@ fi
# #newline_default commands, which are needed in the relevant pcre2test files,
# are ignored. Any other #-command is ignored, with a warning message.
#
+# The pattern lines should use only / as the delimiter. The other characters
+# that pcre2test supports cause problems with this script.
+#
# The data lines must not have any pcre2test modifiers. Unless
# "subject_literal" is on the pattern, data lines are processed as
# Perl double-quoted strings, so if they contain " $ or @ characters, these
diff --git a/src/config.h.generic b/src/config.h.generic
index 2c3b7f7..10f4104 100644
--- a/src/config.h.generic
+++ b/src/config.h.generic
@@ -224,7 +224,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.35"
+#define PACKAGE_STRING "PCRE2 10.36"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "pcre2"
@@ -233,7 +233,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.35"
+#define PACKAGE_VERSION "10.36"
/* 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
@@ -358,7 +358,7 @@ sure both macros are undefined; an emulation function will then be used. */
#endif
/* Version number of package */
-#define VERSION "10.35"
+#define VERSION "10.36"
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
diff --git a/src/pcre2.h.generic b/src/pcre2.h.generic
index 4a42a79..f204ec8 100644
--- a/src/pcre2.h.generic
+++ b/src/pcre2.h.generic
@@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
/* The current PCRE version information. */
#define PCRE2_MAJOR 10
-#define PCRE2_MINOR 35
+#define PCRE2_MINOR 36
#define PCRE2_PRERELEASE
-#define PCRE2_DATE 2020-05-09
+#define PCRE2_DATE 2020-12-04
/* 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
diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c
index 62393be..e811f12 100644
--- a/src/pcre2_compile.c
+++ b/src/pcre2_compile.c
@@ -2344,7 +2344,7 @@ if (ptr > *nameptr + MAX_NAME_SIZE)
*errorcodeptr = ERR48;
goto FAILED;
}
-*namelenptr = ptr - *nameptr;
+*namelenptr = (uint32_t)(ptr - *nameptr);
/* Subpattern names must not be empty, and their terminator is checked here.
(What follows a verb or alpha assertion name is checked separately.) */
@@ -4331,6 +4331,7 @@ while (ptr < ptrend)
{
if (++ptr >= ptrend || !IS_DIGIT(*ptr)) goto BAD_VERSION_CONDITION;
minor = (*ptr++ - CHAR_0) * 10;
+ if (ptr >= ptrend) goto BAD_VERSION_CONDITION;
if (IS_DIGIT(*ptr)) minor += *ptr++ - CHAR_0;
if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
goto BAD_VERSION_CONDITION;
diff --git a/src/pcre2_dftables.c b/src/pcre2_dftables.c
index 1c059e2..71b90ce 100644
--- a/src/pcre2_dftables.c
+++ b/src/pcre2_dftables.c
@@ -63,7 +63,7 @@ given, they are written in binary. */
#include "pcre2_maketables.c"
-static char *classlist[] =
+static const char *classlist[] =
{
"space", "xdigit", "digit", "upper", "lower",
"word", "graph", "print", "punct", "cntrl"
@@ -97,7 +97,7 @@ FILE *f;
int i;
int nclass = 0;
BOOL binary = FALSE;
-char *env = "C";
+char *env = (char *)"C";
const unsigned char *tables;
const unsigned char *base_of_tables;
@@ -105,7 +105,7 @@ const unsigned char *base_of_tables;
for (i = 1; i < argc; i++)
{
- unsigned char *arg = (unsigned char *)argv[i];
+ char *arg = argv[i];
if (*arg != '-') break;
if (strcmp(arg, "-help") == 0 || strcmp(arg, "--help") == 0)
diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c
index 33ad7e6..1977d28 100644
--- a/src/pcre2_jit_compile.c
+++ b/src/pcre2_jit_compile.c
@@ -1466,9 +1466,9 @@ do
default:
accelerated_start = NULL;
fast_forward_allowed = FALSE;
- break;
+ continue;
}
- continue;
+ break;
case OP_ONCE:
case OP_BRA:
@@ -1834,57 +1834,57 @@ while (cc < ccend)
case OP_BRAZERO:
case OP_BRAMINZERO:
case OP_BRAPOSZERO:
- repeat_check = FALSE;
size = 1;
+ repeat_check = FALSE;
break;
CASE_ITERATOR_PRIVATE_DATA_1
- space = 1;
size = -2;
+ space = 1;
break;
CASE_ITERATOR_PRIVATE_DATA_2A
- space = 2;
size = -2;
+ space = 2;
break;
CASE_ITERATOR_PRIVATE_DATA_2B
- space = 2;
size = -(2 + IMM2_SIZE);
+ space = 2;
break;
CASE_ITERATOR_TYPE_PRIVATE_DATA_1
- space = 1;
size = 1;
+ space = 1;
break;
CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
+ size = 1;
if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
space = 2;
- size = 1;
break;
case OP_TYPEUPTO:
+ size = 1 + IMM2_SIZE;
if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
space = 2;
- size = 1 + IMM2_SIZE;
break;
case OP_TYPEMINUPTO:
- space = 2;
size = 1 + IMM2_SIZE;
+ space = 2;
break;
case OP_CLASS:
case OP_NCLASS:
- space = get_class_iterator_size(cc + size);
size = 1 + 32 / sizeof(PCRE2_UCHAR);
+ space = get_class_iterator_size(cc + size);
break;
#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH != 8
case OP_XCLASS:
- space = get_class_iterator_size(cc + size);
size = GET(cc, 1);
+ space = get_class_iterator_size(cc + size);
break;
#endif
@@ -4578,7 +4578,14 @@ if (common->nltype != NLTYPE_ANY)
/* All newlines are ascii, just skip intermediate octets. */
jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
loop = LABEL();
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)) == SLJIT_SUCCESS)
+ sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, TMP2, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
+ else
+ {
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ }
+
OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0);
CMPTO(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, loop);
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
@@ -6161,9 +6168,9 @@ static SLJIT_INLINE void fast_forward_newline(compiler_common *common)
{
DEFINE_COMPILER;
struct sljit_label *loop;
-struct sljit_jump *lastchar;
+struct sljit_jump *lastchar = NULL;
struct sljit_jump *firstchar;
-struct sljit_jump *quit;
+struct sljit_jump *quit = NULL;
struct sljit_jump *foundcr = NULL;
struct sljit_jump *notfoundnl;
jump_list *newline = NULL;
@@ -6176,39 +6183,71 @@ if (common->match_end_ptr != 0)
if (common->nltype == NLTYPE_FIXED && common->newline > 255)
{
- lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- if (HAS_VIRTUAL_REGISTERS)
+#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD
+ if (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && common->mode == PCRE2_JIT_COMPLETE)
{
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
+ firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
+ OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_NOT_EQUAL);
+#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+ OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
+#endif
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+
+ fast_forward_char_pair_simd(common, 1, common->newline & 0xff, common->newline & 0xff, 0, (common->newline >> 8) & 0xff, (common->newline >> 8) & 0xff);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
}
else
+#endif /* JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD */
{
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
- }
- firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
+ lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
+ firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
- OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
- OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER_EQUAL);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
+ OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
+ OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_GREATER_EQUAL);
#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
#endif
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
- loop = LABEL();
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
- OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
- CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
+ loop = LABEL();
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ quit = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
+ OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
+ CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
+
+ JUMPHERE(quit);
+ JUMPHERE(lastchar);
+ }
- JUMPHERE(quit);
JUMPHERE(firstchar);
- JUMPHERE(lastchar);
if (common->match_end_ptr != 0)
OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
@@ -6225,22 +6264,59 @@ else
/* Example: match /^/ to \r\n from offset 1. */
firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
-move_back(common, NULL, FALSE);
+
+if (common->nltype == NLTYPE_ANY)
+ move_back(common, NULL, FALSE);
+else
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
loop = LABEL();
common->ff_newline_shortcut = loop;
-read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE);
-lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
- foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
-check_newlinechar(common, common->nltype, &newline, FALSE);
-set_jumps(newline, loop);
+#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD
+if (JIT_HAS_FAST_FORWARD_CHAR_SIMD && (common->nltype == NLTYPE_FIXED || common->nltype == NLTYPE_ANYCRLF))
+ {
+ if (common->nltype == NLTYPE_ANYCRLF)
+ {
+ fast_forward_char_simd(common, CHAR_CR, CHAR_LF, 0);
+ if (common->mode != PCRE2_JIT_COMPLETE)
+ lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ quit = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ }
+ else
+ {
+ fast_forward_char_simd(common, common->newline, common->newline, 0);
+
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ if (common->mode != PCRE2_JIT_COMPLETE)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
+ CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
+ }
+ }
+ }
+else
+#endif /* JIT_HAS_FAST_FORWARD_CHAR_SIMD */
+ {
+ read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE);
+ lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+ if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
+ foundcr = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
+ check_newlinechar(common, common->nltype, &newline, FALSE);
+ set_jumps(newline, loop);
+ }
if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
{
- quit = JUMP(SLJIT_JUMP);
- JUMPHERE(foundcr);
+ if (quit == NULL)
+ {
+ quit = JUMP(SLJIT_JUMP);
+ JUMPHERE(foundcr);
+ }
+
notfoundnl = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
@@ -6252,7 +6328,9 @@ if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
JUMPHERE(notfoundnl);
JUMPHERE(quit);
}
-JUMPHERE(lastchar);
+
+if (lastchar)
+ JUMPHERE(lastchar);
JUMPHERE(firstchar);
if (common->match_end_ptr != 0)
@@ -6493,9 +6571,11 @@ if (common->invalid_utf)
if (common->mode != PCRE2_JIT_COMPLETE)
{
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
move_back(common, NULL, TRUE);
check_start_used_ptr(common);
+ OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);
}
}
@@ -7594,25 +7674,43 @@ if (needstype || needsscript)
}
cc = ccbegin;
- }
- if (needschar)
- OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
+ if (needstype)
+ {
+ /* TMP2 has already been shifted by 2 */
+ if (!needschar)
+ {
+ OP2(SLJIT_ADD, TMP1, 0, TMP2, 0, TMP2, 0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
- if (needstype)
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
+ }
+ else
+ {
+ OP2(SLJIT_ADD, TMP1, 0, TMP2, 0, TMP2, 0);
+ OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
+
+ OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
+ OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
+ typereg = RETURN_ADDR;
+ }
+ }
+ else if (needschar)
+ OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
+ }
+ else if (needstype)
{
+ OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3);
+ OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
+
if (!needschar)
{
- OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
}
else
{
- OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
@@ -7620,6 +7718,8 @@ if (needstype || needsscript)
typereg = RETURN_ADDR;
}
}
+ else if (needschar)
+ OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0);
}
#endif /* SUPPORT_UNICODE */
@@ -13581,7 +13681,7 @@ if (common->has_then)
set_then_offsets(common, common->start, NULL);
}
-compiler = sljit_create_compiler(allocator_data);
+compiler = sljit_create_compiler(allocator_data, NULL);
if (!compiler)
{
SLJIT_FREE(common->optimized_cbracket, allocator_data);
@@ -13983,7 +14083,7 @@ else
{
/* This case is highly unlikely since we just recently
freed a lot of memory. Not impossible though. */
- sljit_free_code(executable_func);
+ sljit_free_code(executable_func, NULL);
PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
return PCRE2_ERROR_NOMEMORY;
}
@@ -14097,13 +14197,13 @@ if (executable_allocator_is_working == 0)
/* Checks whether the executable allocator is working. This check
might run multiple times in multi-threaded environments, but the
result should not be affected by it. */
- void *ptr = SLJIT_MALLOC_EXEC(32);
+ void *ptr = SLJIT_MALLOC_EXEC(32, NULL);
executable_allocator_is_working = -1;
if (ptr != NULL)
{
- SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr));
+ SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr), NULL);
executable_allocator_is_working = 1;
}
}
diff --git a/src/pcre2_jit_misc.c b/src/pcre2_jit_misc.c
index 36abdba..ec924e0 100644
--- a/src/pcre2_jit_misc.c
+++ b/src/pcre2_jit_misc.c
@@ -89,7 +89,7 @@ int i;
for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
{
if (functions->executable_funcs[i] != NULL)
- sljit_free_code(functions->executable_funcs[i]);
+ sljit_free_code(functions->executable_funcs[i], NULL);
PRIV(jit_free_rodata)(functions->read_only_data_heads[i], allocator_data);
}
diff --git a/src/pcre2_jit_neon_inc.h b/src/pcre2_jit_neon_inc.h
index 66373b6..150da29 100644
--- a/src/pcre2_jit_neon_inc.h
+++ b/src/pcre2_jit_neon_inc.h
@@ -87,6 +87,10 @@ static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 *str_ptr, sljit_u
{
quad_word qw;
int_char ic;
+
+SLJIT_UNUSED_ARG(offs1);
+SLJIT_UNUSED_ARG(offs2);
+
ic.x = chars;
#if defined(FFCS)
diff --git a/src/pcre2_jit_test.c b/src/pcre2_jit_test.c
index a29fffa..d935887 100644
--- a/src/pcre2_jit_test.c
+++ b/src/pcre2_jit_test.c
@@ -350,6 +350,7 @@ static struct regression_test_case regression_test_cases[] = {
{ MU, A, 0, 0, ".[ab]*.", "xx" },
{ MU, A, 0, 0, ".[ab]*a", "xxa" },
{ MU, A, 0, 0, ".[ab]?.", "xx" },
+ { MU, A, 0, 0, "_[ab]+_*a", "_aa" },
/* Bracket repeats with limit. */
{ MU, A, 0, 0, "(?:(ab){2}){5}M", "abababababababababababM" },
@@ -408,6 +409,7 @@ static struct regression_test_case regression_test_cases[] = {
{ MUP, A, 0, 0 | F_PROPERTY, "[\xc3\xa2-\xc3\xa6\xc3\x81-\xc3\x84\xe2\x80\xa8-\xe2\x80\xa9\xe6\x92\xad\\p{Zs}]{2,}", "\xe2\x80\xa7\xe2\x80\xa9\xe6\x92\xad \xe6\x92\xae" },
{ MUP, A, 0, 0 | F_PROPERTY, "[\\P{L&}]{2}[^\xc2\x85-\xc2\x89\\p{Ll}\\p{Lu}]{2}", "\xc3\xa9\xe6\x92\xad.a\xe6\x92\xad|\xc2\x8a#" },
{ PCRE2_UCP, 0, 0, 0 | F_PROPERTY, "[a-b\\s]{2,5}[^a]", "AB baaa" },
+ { MUP, 0, 0, 0 | F_NOMATCH, "[^\\p{Hangul}\\p{Z}]", " " },
/* Possible empty brackets. */
{ MU, A, 0, 0, "(?:|ab||bc|a)+d", "abcxabcabd" },
@@ -1831,7 +1833,9 @@ struct invalid_utf8_regression_test_case {
const char *input;
};
-static struct invalid_utf8_regression_test_case invalid_utf8_regression_test_cases[] = {
+static const char invalid_utf8_newline_cr;
+
+static const struct invalid_utf8_regression_test_case invalid_utf8_regression_test_cases[] = {
{ UDA, CI, 0, 0, 0, 0, 4, { ".", NULL }, "\xf4\x8f\xbf\xbf" },
{ UDA, CI, 0, 0, 0, 0, 4, { ".", NULL }, "\xf0\x90\x80\x80" },
{ UDA, CI, 0, 0, 0, -1, -1, { ".", NULL }, "\xf4\x90\x80\x80" },
@@ -1974,6 +1978,8 @@ static struct invalid_utf8_regression_test_case invalid_utf8_regression_test_cas
{ 0, PCRE2_JIT_COMPLETE, 0, 0, 1, -1, -1, { "\\X{2}", NULL }, "\r\n\n" },
{ 0, PCRE2_JIT_COMPLETE, 0, 0, 1, -1, -1, { "\\R{2}", NULL }, "\r\n\n" },
+ { PCRE2_UTF | PCRE2_MULTILINE, CI, 0, 0, 0, -1, -1, { "^.a", &invalid_utf8_newline_cr }, "\xc3\xa7#a" },
+
{ 0, 0, 0, 0, 0, 0, 0, { NULL, NULL }, NULL }
};
@@ -1981,7 +1987,7 @@ static struct invalid_utf8_regression_test_case invalid_utf8_regression_test_cas
#undef CI
#undef CPI
-static int run_invalid_utf8_test(struct invalid_utf8_regression_test_case *current,
+static int run_invalid_utf8_test(const struct invalid_utf8_regression_test_case *current,
int pattern_index, int i, pcre2_compile_context_8 *ccontext, pcre2_match_data_8 *mdata)
{
pcre2_code_8 *code;
@@ -2034,7 +2040,7 @@ static int run_invalid_utf8_test(struct invalid_utf8_regression_test_case *curre
static int invalid_utf8_regression_tests(void)
{
- struct invalid_utf8_regression_test_case *current;
+ const struct invalid_utf8_regression_test_case *current;
pcre2_compile_context_8 *ccontext;
pcre2_match_data_8 *mdata;
int total = 0, successful = 0;
@@ -2051,10 +2057,18 @@ static int invalid_utf8_regression_tests(void)
total++;
result = 1;
- if (!run_invalid_utf8_test(current, total - 1, 0, ccontext, mdata))
- result = 0;
- if (!run_invalid_utf8_test(current, total - 1, 1, ccontext, mdata))
- result = 0;
+ if (current->pattern[1] != &invalid_utf8_newline_cr)
+ {
+ if (!run_invalid_utf8_test(current, total - 1, 0, ccontext, mdata))
+ result = 0;
+ if (!run_invalid_utf8_test(current, total - 1, 1, ccontext, mdata))
+ result = 0;
+ } else {
+ pcre2_set_newline_8(ccontext, PCRE2_NEWLINE_CR);
+ if (!run_invalid_utf8_test(current, total - 1, 0, ccontext, mdata))
+ result = 0;
+ pcre2_set_newline_8(ccontext, PCRE2_NEWLINE_ANY);
+ }
if (result) {
successful++;
@@ -2128,7 +2142,7 @@ static PCRE2_UCHAR16 test16_10[] = { ' ', 0xdc00, 0xd800, 0x2028, '#', 0 };
static PCRE2_UCHAR16 test16_11[] = { 0xdc00, 0xdc00, 0xd800, 0xdc00, 0xdc00, '#', 0xd800, 0xdc00, '#', 0 };
static PCRE2_UCHAR16 test16_12[] = { '#', 0xd800, 0xdc00, 0xd800, '#', 0xd800, 0xdc00, 0xdc00, 0xdc00, '#', 0xd800, 0xdc00, '#', 0 };
-static struct invalid_utf16_regression_test_case invalid_utf16_regression_test_cases[] = {
+static const struct invalid_utf16_regression_test_case invalid_utf16_regression_test_cases[] = {
{ UDA, CI, 0, 0, 0, 0, 1, { allany16, NULL }, test16_1 },
{ UDA, CI, 1, 0, 0, 1, 2, { allany16, NULL }, test16_1 },
{ UDA, CI, 2, 0, 0, 2, 3, { allany16, NULL }, test16_1 },
@@ -2182,7 +2196,7 @@ static struct invalid_utf16_regression_test_case invalid_utf16_regression_test_c
#undef CI
#undef CPI
-static int run_invalid_utf16_test(struct invalid_utf16_regression_test_case *current,
+static int run_invalid_utf16_test(const struct invalid_utf16_regression_test_case *current,
int pattern_index, int i, pcre2_compile_context_16 *ccontext, pcre2_match_data_16 *mdata)
{
pcre2_code_16 *code;
@@ -2242,7 +2256,7 @@ static int run_invalid_utf16_test(struct invalid_utf16_regression_test_case *cur
static int invalid_utf16_regression_tests(void)
{
- struct invalid_utf16_regression_test_case *current;
+ const struct invalid_utf16_regression_test_case *current;
pcre2_compile_context_16 *ccontext;
pcre2_match_data_16 *mdata;
int total = 0, successful = 0;
@@ -2329,7 +2343,7 @@ static PCRE2_UCHAR32 test32_4[] = { '#', 0x10ffff, 0x110000, 0 };
static PCRE2_UCHAR32 test32_5[] = { ' ', 0x2028, '#', 0 };
static PCRE2_UCHAR32 test32_6[] = { ' ', 0x110000, 0x2028, '#', 0 };
-static struct invalid_utf32_regression_test_case invalid_utf32_regression_test_cases[] = {
+static const struct invalid_utf32_regression_test_case invalid_utf32_regression_test_cases[] = {
{ UDA, CI, 0, 0, 0, 0, 1, { allany32, NULL }, test32_1 },
{ UDA, CI, 2, 0, 0, -1, -1, { allany32, NULL }, test32_1 },
{ UDA, CI, 0, 0, 0, 0, 1, { allany32, NULL }, test32_2 },
@@ -2369,7 +2383,7 @@ static struct invalid_utf32_regression_test_case invalid_utf32_regression_test_c
#undef CI
#undef CPI
-static int run_invalid_utf32_test(struct invalid_utf32_regression_test_case *current,
+static int run_invalid_utf32_test(const struct invalid_utf32_regression_test_case *current,
int pattern_index, int i, pcre2_compile_context_32 *ccontext, pcre2_match_data_32 *mdata)
{
pcre2_code_32 *code;
@@ -2429,7 +2443,7 @@ static int run_invalid_utf32_test(struct invalid_utf32_regression_test_case *cur
static int invalid_utf32_regression_tests(void)
{
- struct invalid_utf32_regression_test_case *current;
+ const struct invalid_utf32_regression_test_case *current;
pcre2_compile_context_32 *ccontext;
pcre2_match_data_32 *mdata;
int total = 0, successful = 0;
diff --git a/src/pcre2_match.c b/src/pcre2_match.c
index 11289d5..e3f78c2 100644
--- a/src/pcre2_match.c
+++ b/src/pcre2_match.c
@@ -6115,8 +6115,8 @@ BOOL has_req_cu = FALSE;
BOOL startline;
#if PCRE2_CODE_UNIT_WIDTH == 8
-BOOL memchr_not_found_first_cu = FALSE;
-BOOL memchr_not_found_first_cu2 = FALSE;
+BOOL memchr_not_found_first_cu;
+BOOL memchr_not_found_first_cu2;
#endif
PCRE2_UCHAR first_cu = 0;
@@ -6709,6 +6709,11 @@ FRAGMENT_RESTART:
start_partial = match_partial = NULL;
mb->hitend = FALSE;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+memchr_not_found_first_cu = FALSE;
+memchr_not_found_first_cu2 = FALSE;
+#endif
+
for(;;)
{
PCRE2_SPTR new_start_match;
@@ -7187,6 +7192,7 @@ if (utf && end_subject != true_end_subject &&
starting code units in 8-bit and 16-bit modes. */
start_match = end_subject + 1;
+
#if PCRE2_CODE_UNIT_WIDTH != 32
while (start_match < true_end_subject && NOT_FIRSTCU(*start_match))
start_match++;
diff --git a/src/pcre2grep.c b/src/pcre2grep.c
index 10314a5..b54229b 100644
--- a/src/pcre2grep.c
+++ b/src/pcre2grep.c
@@ -164,6 +164,10 @@ enum { DEE_READ, DEE_SKIP };
enum { BIN_BINARY, BIN_NOMATCH, BIN_TEXT };
+/* Return values from decode_dollar_escape() */
+
+enum { DDE_ERROR, DDE_CAPTURE, DDE_CHAR };
+
/* In newer versions of gcc, with FORTIFY_SOURCE set (the default in some
environments), a warning is issued if the value of fwrite() is ignored.
Unfortunately, casting to (void) does not suppress the warning. To get round
@@ -179,13 +183,21 @@ handled by using STDOUT_NL as the newline string. We also use a normal double
quote for the example, as single quotes aren't usually available. */
#ifdef WIN32
-#define STDOUT_NL "\r\n"
-#define QUOT "\""
+#define STDOUT_NL "\r\n"
+#define STDOUT_NL_LEN 2
+#define QUOT "\""
#else
-#define STDOUT_NL "\n"
-#define QUOT "'"
+#define STDOUT_NL "\n"
+#define STDOUT_NL_LEN 1
+#define QUOT "'"
#endif
+/* This code is returned from decode_dollar_escape() when $n is encountered,
+and used to mean "output STDOUT_NL". It is, of course, not a valid Unicode code
+point. */
+
+#define STDOUT_NL_CODE 0x7fffffffu
+
/*************************************************
@@ -224,8 +236,9 @@ static int max_bufthird = PCRE2GREP_MAX_BUFSIZE;
static int bufsize = 3*PCRE2GREP_BUFSIZE;
static int endlinetype;
-static unsigned long int total_count = 0;
+static int count_limit = -1; /* Not long, so that it works with OP_NUMBER */
static unsigned long int counts_printed = 0;
+static unsigned long int total_count = 0;
#ifdef WIN32
static int dee_action = dee_SKIP;
@@ -277,6 +290,9 @@ static BOOL show_total_count = FALSE;
static BOOL silent = FALSE;
static BOOL utf = FALSE;
+static uint8_t utf8_buffer[8];
+
+
/* Structure for list of --only-matching capturing numbers. */
typedef struct omstr {
@@ -443,6 +459,7 @@ static option_item optionlist[] = {
{ OP_U32NUMBER, N_M_LIMIT_DEP, &depth_limit, "depth-limit=number", "set PCRE2 depth limit option" },
{ OP_U32NUMBER, N_M_LIMIT_DEP, &depth_limit, "recursion-limit=number", "obsolete synonym for depth-limit" },
{ OP_NODATA, 'M', NULL, "multiline", "run in multiline mode" },
+ { OP_NUMBER, 'm', &count_limit, "max-count=number", "stop after <number> matched lines" },
{ OP_STRING, 'N', &newline_arg, "newline=type", "set newline type (CR, LF, CRLF, ANYCRLF, ANY, or NUL)" },
{ OP_NODATA, 'n', NULL, "line-number", "print line number with output lines" },
#ifdef SUPPORT_PCRE2GREP_JIT
@@ -482,8 +499,13 @@ of PCRE2_NEWLINE_xx in pcre2.h. */
static const char *newlines[] = {
"DEFAULT", "CR", "LF", "CRLF", "ANY", "ANYCRLF", "NUL" };
-/* UTF-8 tables - used only when the newline setting is "any". */
+/* UTF-8 tables */
+const int utf8_table1[] =
+ { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
+const int utf8_table1_size = sizeof(utf8_table1) / sizeof(int);
+
+const int utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
const char utf8_table4[] = {
@@ -531,6 +553,32 @@ else
#endif /* not VPCOMPAT && not HAVE_MEMMOVE */
+
+/*************************************************
+* Convert code point to UTF-8 *
+*************************************************/
+
+/* A static buffer is used. Returns the number of bytes. */
+
+static int
+ord2utf8(uint32_t value)
+{
+int i, j;
+uint8_t *utf8bytes = utf8_buffer;
+for (i = 0; i < utf8_table1_size; i++)
+ if (value <= (uint32_t)utf8_table1[i]) break;
+utf8bytes += i;
+for (j = i; j > 0; j--)
+ {
+ *utf8bytes-- = 0x80 | (value & 0x3f);
+ value >>= 6;
+ }
+*utf8bytes = utf8_table2[i] | value;
+return i + 1;
+}
+
+
+
/*************************************************
* Case-independent string compare *
*************************************************/
@@ -1788,6 +1836,7 @@ if (slen > 200)
slen = 200;
msg = "text that starts:\n\n";
}
+
for (i = 1; p != NULL; p = p->next, i++)
{
*mrc = pcre2_match(p->compiled, (PCRE2_SPTR)matchptr, (int)length,
@@ -1823,140 +1872,254 @@ return FALSE; /* No match, no errors */
}
+
/*************************************************
-* Check output text for errors *
+* Decode dollar escape sequence *
*************************************************/
-static BOOL
-syntax_check_output_text(PCRE2_SPTR string, BOOL callout)
+/* Called from various places to decode $ escapes in output strings. The escape
+sequences are as follows:
+
+$<digits> or ${<digits>} returns a capture number. However, if callout is TRUE,
+zero is never returned; '0' is substituted.
+
+$a returns bell.
+$b returns backspace.
+$e returns escape.
+$f returns form feed.
+$n returns newline.
+$r returns carriage return.
+$t returns tab.
+$v returns vertical tab.
+$o<digits> returns the character represented by the given octal
+ number; up to three digits are processed.
+$o{<digits>} does the same, up to 7 digits, but gives an error for mode-invalid
+ code points.
+$x<digits> returns the character represented by the given hexadecimal
+ number; up to two digits are processed.
+$x{<digits} does the same, up to 6 digits, but gives an error for mode-invalid
+ code points.
+Any other character is substituted by itself. E.g: $$ is replaced by a single
+dollar.
+
+Arguments:
+ begin the start of the whole string
+ string points to the $
+ callout TRUE if in a callout (inhibits error messages)
+ value where to return a value
+ last where to return pointer to the last used character
+
+Returns: DDE_ERROR after a syntax error
+ DDE_CAPTURE if *value is a capture number
+ DDE_CHAR if *value is a character code
+*/
+
+static int
+decode_dollar_escape(PCRE2_SPTR begin, PCRE2_SPTR string, BOOL callout,
+ uint32_t *value, PCRE2_SPTR *last)
{
-PCRE2_SPTR begin = string;
-for (; *string != 0; string++)
+uint32_t c = 0;
+int base = 10;
+int dcount;
+int rc = DDE_CHAR;
+BOOL brace = FALSE;
+
+switch (*(++string))
{
- if (*string == '$')
+ case 0: /* Syntax error: a character must be present after $. */
+ if (!callout)
+ fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
+ (int)(string - begin), "no character after $");
+ *last = string;
+ return DDE_ERROR;
+
+ case '{':
+ brace = TRUE;
+ string++;
+ if (!isdigit(*string)) /* Syntax error: a decimal number required. */
{
- PCRE2_SIZE capture_id = 0;
- BOOL brace = FALSE;
+ if (!callout)
+ fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
+ (int)(string - begin), "decimal number expected");
+ rc = DDE_ERROR;
+ break;
+ }
+
+ /* Fall through */
+
+ /* The maximum capture number is 65535, so any number greater than that will
+ always be an unknown capture number. We just stop incrementing, in order to
+ avoid overflow. */
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ do
+ {
+ if (c <= 65535) c = c * 10 + (*string - '0');
string++;
+ }
+ while (*string >= '0' && *string <= '9');
+ string--; /* Point to last digit */
- /* Syntax error: a character must be present after $. */
- if (*string == 0)
- {
- if (!callout)
- fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
- (int)(string - begin), "no character after $");
- return FALSE;
- }
+ /* In a callout, capture number 0 is not available. No error can be given,
+ so just return the character '0'. */
- if (*string == '{')
- {
- /* Must be a decimal number in braces, e.g: {5} or {38} */
- string++;
+ if (callout && c == 0)
+ {
+ *value = '0';
+ }
+ else
+ {
+ *value = c;
+ rc = DDE_CAPTURE;
+ }
+ break;
- brace = TRUE;
- }
+ /* Limit octal numbers to 3 digits without braces, or up to 7 with braces,
+ for valid Unicode code points. */
- if ((*string >= '1' && *string <= '9') || (!callout && *string == '0'))
- {
- do
- {
- /* Maximum capture id is 65535. */
- if (capture_id <= 65535)
- capture_id = capture_id * 10 + (*string - '0');
+ case 'o':
+ base = 8;
+ string++;
+ if (*string == '{')
+ {
+ brace = TRUE;
+ string++;
+ dcount = 7;
+ }
+ else dcount = 3;
+ for (; dcount > 0; dcount--)
+ {
+ if (*string < '0' || *string > '7') break;
+ c = c * 8 + (*string++ - '0');
+ }
+ *value = c;
+ string--; /* Point to last digit */
+ break;
- string++;
- }
- while (*string >= '0' && *string <= '9');
+ /* Limit hex numbers to 2 digits without braces, or up to 6 with braces,
+ for valid Unicode code points. */
+
+ case 'x':
+ base = 16;
+ string++;
+ if (*string == '{')
+ {
+ brace = TRUE;
+ string++;
+ dcount = 6;
+ }
+ else dcount = 2;
+ for (; dcount > 0; dcount--)
+ {
+ if (!isxdigit(*string)) break;
+ if (*string >= '0' && *string <= '9')
+ c = c *16 + *string++ - '0';
+ else
+ c = c * 16 + (*string++ | 0x20) - 'a' + 10;
+ }
+ *value = c;
+ string--; /* Point to last digit */
+ break;
+
+ case 'a': *value = '\a'; break;
+ case 'b': *value = '\b'; break;
+#ifndef EBCDIC
+ case 'e': *value = '\033'; break;
+#else
+ case 'e': *value = '\047'; break;
+#endif
+ case 'f': *value = '\f'; break;
+ case 'n': *value = STDOUT_NL_CODE; break;
+ case 'r': *value = '\r'; break;
+ case 't': *value = '\t'; break;
+ case 'v': *value = '\v'; break;
+
+ default: *value = *string; break;
+ }
- if (brace)
+if (brace)
+ {
+ c = string[1];
+ if (c != '}')
+ {
+ rc = DDE_ERROR;
+ if (!callout)
+ {
+ if ((base == 8 && c >= '0' && c <= '7') ||
+ (base == 16 && isxdigit(c)))
{
- /* Syntax error: closing brace is missing. */
- if (*string != '}')
- {
- if (!callout)
- fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
- (int)(string - begin), "missing closing brace");
- return FALSE;
- }
+ fprintf(stderr, "pcre2grep: Error in output text at offset %d: "
+ "too many %s digits\n", (int)(string - begin),
+ (base == 8)? "octal" : "hex");
}
else
{
- /* To negate the effect of the for. */
- string--;
- }
- }
- else if (brace)
- {
- /* Syntax error: a decimal number required. */
- if (!callout)
fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
- (int)(string - begin), "decimal number expected");
- return FALSE;
- }
- else if (*string == 'o')
- {
- string++;
-
- if (*string < '0' || *string > '7')
- {
- /* Syntax error: an octal number required. */
- if (!callout)
- fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
- (int)(string - begin), "octal number expected");
- return FALSE;
+ (int)(string - begin), "missing closing brace");
}
}
- else if (*string == 'x')
- {
- string++;
+ }
+ else string++;
+ }
- if (!isxdigit((unsigned char)*string))
- {
- /* Syntax error: a hexdecimal number required. */
- if (!callout)
- fprintf(stderr, "pcre2grep: Error in output text at offset %d: %s\n",
- (int)(string - begin), "hexadecimal number expected");
- return FALSE;
- }
- }
+/* Check maximum code point values, but take note of STDOUT_NL_CODE. */
+
+if (rc == DDE_CHAR && *value != STDOUT_NL_CODE)
+ {
+ uint32_t max = utf? 0x0010ffffu : 0xffu;
+ if (*value > max)
+ {
+ if (!callout)
+ fprintf(stderr, "pcre2grep: Error in output text at offset %d: "
+ "code point greater than 0x%x is invalid\n", (int)(string - begin), max);
+ rc = DDE_ERROR;
}
}
- return TRUE;
+*last = string;
+return rc;
}
+
/*************************************************
-* Display output text *
+* Check output text for errors *
*************************************************/
-/* Display the output text, which is assumed to have already been syntax
-checked. Output may contain escape sequences started by the dollar sign. The
-escape sequences are substituted as follows:
+/* Called early, to get errors before doing anything for -O text; also called
+from callouts to check before outputting.
- $<digits> or ${<digits>} is replaced by the captured substring of the given
- decimal number; zero will substitute the whole match. If the number is
- greater than the number of capturing substrings, or if the capture is unset,
- the replacement is empty.
-
- $a is replaced by bell.
- $b is replaced by backspace.
- $e is replaced by escape.
- $f is replaced by form feed.
- $n is replaced by newline.
- $r is replaced by carriage return.
- $t is replaced by tab.
- $v is replaced by vertical tab.
-
- $o<digits> is replaced by the character represented by the given octal
- number; up to three digits are processed.
+Arguments:
+ string an --output text string
+ callout TRUE if in a callout (stops printing errors)
- $x<digits> is replaced by the character represented by the given hexadecimal
- number; up to two digits are processed.
+Returns: TRUE if OK, FALSE on error
+*/
- Any other character is substituted by itself. E.g: $$ is replaced by a single
- dollar.
+static BOOL
+syntax_check_output_text(PCRE2_SPTR string, BOOL callout)
+{
+uint32_t value;
+PCRE2_SPTR begin = string;
+
+for (; *string != 0; string++)
+ {
+ if (*string == '$' &&
+ decode_dollar_escape(begin, string, callout, &value, &string) == DDE_ERROR)
+ return FALSE;
+ }
+
+return TRUE;
+}
+
+
+/*************************************************
+* Display output text *
+*************************************************/
+
+/* Display the output text, which is assumed to have already been syntax
+checked. Output may contain escape sequences started by the dollar sign.
Arguments:
string: the output text
@@ -1973,121 +2136,54 @@ static BOOL
display_output_text(PCRE2_SPTR string, BOOL callout, PCRE2_SPTR subject,
PCRE2_SIZE *ovector, PCRE2_SIZE capture_top)
{
+uint32_t value;
BOOL printed = FALSE;
+PCRE2_SPTR begin = string;
for (; *string != 0; string++)
{
- int ch = EOF;
if (*string == '$')
{
- PCRE2_SIZE capture_id = 0;
- BOOL brace = FALSE;
-
- string++;
-
- if (*string == '{')
- {
- /* Must be a decimal number in braces, e.g: {5} or {38} */
- string++;
-
- brace = TRUE;
- }
-
- if ((*string >= '1' && *string <= '9') || (!callout && *string == '0'))
+ switch(decode_dollar_escape(begin, string, callout, &value, &string))
{
- do
+ case DDE_CHAR:
+ if (value == STDOUT_NL_CODE)
{
- /* Maximum capture id is 65535. */
- if (capture_id <= 65535)
- capture_id = capture_id * 10 + (*string - '0');
-
- string++;
+ fprintf(stdout, STDOUT_NL);
+ printed = FALSE;
+ continue;
}
- while (*string >= '0' && *string <= '9');
+ break; /* Will print value */
- if (!brace)
- {
- /* To negate the effect of the for. */
- string--;
- }
-
- if (capture_id < capture_top)
+ case DDE_CAPTURE:
+ if (value < capture_top)
{
PCRE2_SIZE capturesize;
- capture_id *= 2;
-
- capturesize = ovector[capture_id + 1] - ovector[capture_id];
+ value *= 2;
+ capturesize = ovector[value + 1] - ovector[value];
if (capturesize > 0)
{
- print_match(subject + ovector[capture_id], capturesize);
+ print_match(subject + ovector[value], capturesize);
printed = TRUE;
}
}
- }
- else if (*string == 'a') ch = '\a';
- else if (*string == 'b') ch = '\b';
-#ifndef EBCDIC
- else if (*string == 'e') ch = '\033';
-#else
- else if (*string == 'e') ch = '\047';
-#endif
- else if (*string == 'f') ch = '\f';
- else if (*string == 'r') ch = '\r';
- else if (*string == 't') ch = '\t';
- else if (*string == 'v') ch = '\v';
- else if (*string == 'n')
- {
- fprintf(stdout, STDOUT_NL);
- printed = FALSE;
- }
- else if (*string == 'o')
- {
- string++;
-
- ch = *string - '0';
- if (string[1] >= '0' && string[1] <= '7')
- {
- string++;
- ch = ch * 8 + (*string - '0');
- }
- if (string[1] >= '0' && string[1] <= '7')
- {
- string++;
- ch = ch * 8 + (*string - '0');
- }
- }
- else if (*string == 'x')
- {
- string++;
+ continue;
- if (*string >= '0' && *string <= '9')
- ch = *string - '0';
- else
- ch = (*string | 0x20) - 'a' + 10;
- if (isxdigit((unsigned char)string[1]))
- {
- string++;
- ch *= 16;
- if (*string >= '0' && *string <= '9')
- ch += *string - '0';
- else
- ch += (*string | 0x20) - 'a' + 10;
- }
- }
- else
- {
- ch = *string;
+ default: /* Should not occur */
+ break;
}
}
- else
- {
- ch = *string;
- }
- if (ch != EOF)
+
+ else value = *string; /* Not a $ escape */
+
+ if (utf && value <= 127) fprintf(stdout, "%c", *string); else
{
- fprintf(stdout, "%c", ch);
- printed = TRUE;
+ int i;
+ int n = ord2utf8(value);
+ for (i = 0; i < n; i++) fputc(utf8_buffer[i], stdout);
}
+
+ printed = TRUE;
}
return printed;
@@ -2166,7 +2262,7 @@ int result = 0;
(void)unused; /* Avoid compiler warning */
-/* Only callout with strings are supported. */
+/* Only callouts with strings are supported. */
if (string == NULL || length == 0) return 0;
@@ -2185,83 +2281,43 @@ return 0;
#else
/* Checking syntax and compute the number of string fragments. Callout strings
-are ignored in case of a syntax error. */
+are silently ignored in the event of a syntax error. */
while (length > 0)
{
if (*string == '|')
{
argsvectorlen++;
-
- /* Maximum 10000 arguments allowed. */
- if (argsvectorlen > 10000) return 0;
+ if (argsvectorlen > 10000) return 0; /* Too many args */
}
+
else if (*string == '$')
{
- PCRE2_SIZE capture_id = 0;
-
- string++;
- length--;
+ uint32_t value;
+ PCRE2_SPTR begin = string;
- /* Syntax error: a character must be present after $. */
- if (length == 0) return 0;
-
- if (*string >= '1' && *string <= '9')
+ switch (decode_dollar_escape(begin, string, TRUE, &value, &string))
{
- do
+ case DDE_CAPTURE:
+ if (value < capture_top)
{
- /* Maximum capture id is 65535. */
- if (capture_id <= 65535)
- capture_id = capture_id * 10 + (*string - '0');
-
- string++;
- length--;
+ value *= 2;
+ argslen += ovector[value + 1] - ovector[value];
}
- while (length > 0 && *string >= '0' && *string <= '9');
-
- /* To negate the effect of string++ below. */
- string--;
- length++;
- }
- else if (*string == '{')
- {
- /* Must be a decimal number in braces, e.g: {5} or {38} */
- string++;
- length--;
-
- /* Syntax error: a decimal number required. */
- if (length == 0) return 0;
- if (*string < '1' || *string > '9') return 0;
-
- do
- {
- /* Maximum capture id is 65535. */
- if (capture_id <= 65535)
- capture_id = capture_id * 10 + (*string - '0');
-
- string++;
- length--;
+ argslen--; /* Negate the effect of argslen++ below. */
+ break;
- /* Syntax error: no more characters */
- if (length == 0) return 0;
- }
- while (*string >= '0' && *string <= '9');
+ case DDE_CHAR:
+ if (value == STDOUT_NL_CODE) argslen += STDOUT_NL_LEN - 1;
+ else if (utf && value > 127) argslen += ord2utf8(value) - 1;
+ break;
- /* Syntax error: closing brace is missing. */
- if (*string != '}') return 0;
+ default: /* Should not occur */
+ case DDE_ERROR:
+ return 0;
}
- if (capture_id > 0)
- {
- if (capture_id < capture_top)
- {
- capture_id *= 2;
- argslen += ovector[capture_id + 1] - ovector[capture_id];
- }
-
- /* To negate the effect of argslen++ below. */
- argslen--;
- }
+ length -= (string - begin);
}
string++;
@@ -2269,6 +2325,8 @@ while (length > 0)
argslen++;
}
+/* Get memory for the argument vector and its strings. */
+
args = (char*)malloc(argslen);
if (args == NULL) return 0;
@@ -2279,9 +2337,10 @@ if (argsvector == NULL)
return 0;
}
+/* Now reprocess the string and set up the arguments. */
+
argsptr = args;
argsvectorptr = argsvector;
-
*argsvectorptr++ = argsptr;
length = calloutptr->callout_string_length;
@@ -2294,69 +2353,57 @@ while (length > 0)
*argsptr++ = '\0';
*argsvectorptr++ = argsptr;
}
+
else if (*string == '$')
{
- string++;
- length--;
+ uint32_t value;
+ PCRE2_SPTR begin = string;
- if ((*string >= '1' && *string <= '9') || *string == '{')
+ switch (decode_dollar_escape(begin, string, TRUE, &value, &string))
{
- PCRE2_SIZE capture_id = 0;
-
- if (*string != '{')
+ case DDE_CAPTURE:
+ if (value < capture_top)
{
- do
- {
- /* Maximum capture id is 65535. */
- if (capture_id <= 65535)
- capture_id = capture_id * 10 + (*string - '0');
-
- string++;
- length--;
- }
- while (length > 0 && *string >= '0' && *string <= '9');
+ PCRE2_SIZE capturesize;
+ value *= 2;
+ capturesize = ovector[value + 1] - ovector[value];
+ memcpy(argsptr, subject + ovector[value], capturesize);
+ argsptr += capturesize;
+ }
+ break;
- /* To negate the effect of string++ below. */
- string--;
- length++;
+ case DDE_CHAR:
+ if (value == STDOUT_NL_CODE)
+ {
+ memcpy(argsptr, STDOUT_NL, STDOUT_NL_LEN);
+ argsptr += STDOUT_NL_LEN;
+ }
+ else if (utf && value > 127)
+ {
+ int n = ord2utf8(value);
+ memcpy(argsptr, utf8_buffer, n);
+ argsptr += n;
}
else
{
- string++;
- length--;
-
- do
- {
- /* Maximum capture id is 65535. */
- if (capture_id <= 65535)
- capture_id = capture_id * 10 + (*string - '0');
-
- string++;
- length--;
- }
- while (*string != '}');
+ *argsptr++ = value;
}
+ break;
- if (capture_id < capture_top)
- {
- PCRE2_SIZE capturesize;
- capture_id *= 2;
-
- capturesize = ovector[capture_id + 1] - ovector[capture_id];
- memcpy(argsptr, subject + ovector[capture_id], capturesize);
- argsptr += capturesize;
- }
- }
- else
- {
- *argsptr++ = *string;
+ default: /* Even though this should not occur, the string having */
+ case DDE_ERROR: /* been checked above, we need to include the free() */
+ free(args); /* calls so that source checkers do not complain. */
+ free(argsvector);
+ return 0;
}
- }
- else
- {
- *argsptr++ = *string;
+
+ length -= (string - begin);
}
+ else *argsptr++ = *string;
+
+ /* Advance along the string */
+
string++;
length--;
}
@@ -2479,6 +2526,7 @@ int filepos = 0;
unsigned long int linenumber = 1;
unsigned long int lastmatchnumber = 0;
unsigned long int count = 0;
+long int count_matched_lines = 0;
char *lastmatchrestart = main_buffer;
char *ptr = main_buffer;
char *endptr;
@@ -2505,7 +2553,7 @@ bufflength = fill_buffer(handle, frtype, main_buffer, bufsize,
input_line_buffered);
#ifdef SUPPORT_LIBBZ2
-if (frtype == FR_LIBBZ2 && (int)bufflength < 0) return 2; /* Gotcha: bufflength is PCRE2_SIZE; */
+if (frtype == FR_LIBBZ2 && (int)bufflength < 0) return 2; /* Gotcha: bufflength is PCRE2_SIZE */
#endif
endptr = main_buffer + bufflength;
@@ -2533,10 +2581,23 @@ while (ptr < endptr)
int mrc = 0;
unsigned int options = 0;
BOOL match;
+ BOOL line_matched = FALSE;
char *t = ptr;
PCRE2_SIZE length, linelength;
PCRE2_SIZE startoffset = 0;
+ /* If the -m option set a limit for the number of matched or non-matched
+ lines, check it here. A limit of zero means that no matching is ever done.
+ For stdin from a file, set the file position. */
+
+ if (count_limit >= 0 && count_matched_lines >= count_limit)
+ {
+ if (frtype == FR_PLAIN && filename == stdin_name && !is_file_tty(handle))
+ (void)fseek(handle, (long int)filepos, SEEK_SET);
+ rc = (count_limit == 0)? 1 : 0;
+ break;
+ }
+
/* At this point, ptr is at the start of a line. We need to find the length
of the subject string to pass to pcre2_match(). In multiline mode, it is the
length remainder of the data in the buffer. Otherwise, it is the length of
@@ -2686,6 +2747,10 @@ while (ptr < endptr)
if (filenames == FN_NOMATCH_ONLY) return 1;
+ /* Remember that this line matched (for counting matched lines) */
+
+ line_matched = TRUE;
+
/* If all we want is a yes/no answer, we can return immediately. */
if (quiet) return 0;
@@ -3067,6 +3132,11 @@ while (ptr < endptr)
filepos += (int)(linelength + endlinelength);
linenumber++;
+ /* If there was at least one match (or a non-match, as required) in the line,
+ increment the count for the -m option. */
+
+ if (line_matched) count_matched_lines++;
+
/* If input is line buffered, and the buffer is not yet full, read another
line and add it into the buffer. */
@@ -4088,6 +4158,7 @@ if (only_matching_count > 1)
pcre2grep_exit(usage(2));
}
+
/* Check that there is a big enough ovector for all -o settings. */
for (om = only_matching; om != NULL; om = om->next)
diff --git a/src/pcre2test.c b/src/pcre2test.c
index 3f4fef4..aa007f8 100644
--- a/src/pcre2test.c
+++ b/src/pcre2test.c
@@ -5136,6 +5136,14 @@ PCRE2_SIZE patlen;
PCRE2_SIZE valgrind_access_length;
PCRE2_SIZE erroroffset;
+/* The perltest.sh script supports only / as a delimiter. */
+
+if (restrict_for_perl_test && delimiter != '/')
+ {
+ fprintf(outfile, "** The only allowed delimiter after #perltest is '/'\n");
+ return PR_ABEND;
+ }
+
/* Initialize the context and pattern/data controls for this test from the
defaults. */
diff --git a/src/sljit/sljitConfig.h b/src/sljit/sljitConfig.h
index 4560450..1c821d2 100644
--- a/src/sljit/sljitConfig.h
+++ b/src/sljit/sljitConfig.h
@@ -24,19 +24,19 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _SLJIT_CONFIG_H_
-#define _SLJIT_CONFIG_H_
+#ifndef SLJIT_CONFIG_H_
+#define SLJIT_CONFIG_H_
#ifdef __cplusplus
extern "C" {
#endif
-/* --------------------------------------------------------------------- */
-/* Custom defines */
-/* --------------------------------------------------------------------- */
-
-/* Put your custom defines here. This empty section will never change
- which helps maintaining patches (with diff / patch utilities). */
+/*
+ This file contains the basic configuration options for the SLJIT compiler
+ and their default values. These options can be overridden in the
+ sljitConfigPre.h header file when SLJIT_HAVE_CONFIG_PRE is set to a
+ non-zero value.
+*/
/* --------------------------------------------------------------------- */
/* Architecture */
@@ -54,7 +54,7 @@ extern "C" {
/* #define SLJIT_CONFIG_MIPS_32 1 */
/* #define SLJIT_CONFIG_MIPS_64 1 */
/* #define SLJIT_CONFIG_SPARC_32 1 */
-/* #define SLJIT_CONFIG_TILEGX 1 */
+/* #define SLJIT_CONFIG_S390X 1 */
/* #define SLJIT_CONFIG_AUTO 1 */
/* #define SLJIT_CONFIG_UNSUPPORTED 1 */
@@ -63,12 +63,6 @@ extern "C" {
/* Utilities */
/* --------------------------------------------------------------------- */
-/* Useful for thread-safe compiling of global functions. */
-#ifndef SLJIT_UTIL_GLOBAL_LOCK
-/* Enabled by default */
-#define SLJIT_UTIL_GLOBAL_LOCK 1
-#endif
-
/* Implements a stack like data structure (by using mmap / VirtualAlloc */
/* or a custom allocator). */
#ifndef SLJIT_UTIL_STACK
@@ -108,15 +102,31 @@ extern "C" {
/* When SLJIT_PROT_EXECUTABLE_ALLOCATOR is enabled SLJIT uses
an allocator which does not set writable and executable
- permission flags at the same time. The trade-of is increased
- memory consumption and disabled dynamic code modifications. */
+ permission flags at the same time.
+ Instead, it creates a shared memory segment (usually backed by a file)
+ and maps it twice, with different permissions, depending on the use
+ case.
+ The trade-off is increased use of virtual memory, incompatibility with
+ fork(), and some possible additional security risks by the use of
+ publicly accessible files for the generated code. */
#ifndef SLJIT_PROT_EXECUTABLE_ALLOCATOR
/* Disabled by default. */
#define SLJIT_PROT_EXECUTABLE_ALLOCATOR 0
#endif
+/* When SLJIT_WX_EXECUTABLE_ALLOCATOR is enabled SLJIT uses an
+ allocator which does not set writable and executable permission
+ flags at the same time.
+ Instead, it creates a new independent map on each invocation and
+ switches permissions at the underlying pages as needed.
+ The trade-off is increased memory use and degraded performance. */
+#ifndef SLJIT_WX_EXECUTABLE_ALLOCATOR
+/* Disabled by default. */
+#define SLJIT_WX_EXECUTABLE_ALLOCATOR 0
#endif
+#endif /* !SLJIT_EXECUTABLE_ALLOCATOR */
+
/* Force cdecl calling convention even if a better calling
convention (e.g. fastcall) is supported by the C compiler.
If this option is disabled (this is the default), functions
@@ -159,4 +169,4 @@ extern "C" {
} /* extern "C" */
#endif
-#endif
+#endif /* SLJIT_CONFIG_H_ */
diff --git a/src/sljit/sljitConfigInternal.h b/src/sljit/sljitConfigInternal.h
index 049ed2f..eb1132d 100644
--- a/src/sljit/sljitConfigInternal.h
+++ b/src/sljit/sljitConfigInternal.h
@@ -24,8 +24,8 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _SLJIT_CONFIG_INTERNAL_H_
-#define _SLJIT_CONFIG_INTERNAL_H_
+#ifndef SLJIT_CONFIG_INTERNAL_H_
+#define SLJIT_CONFIG_INTERNAL_H_
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|| (defined SLJIT_DEBUG && SLJIT_DEBUG && (!defined(SLJIT_ASSERT) || !defined(SLJIT_UNREACHABLE)))
@@ -81,30 +81,13 @@ extern "C" {
Other macros:
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 (compiler independent helper)
+ SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper)
*/
/*****************/
/* Sanity check. */
/*****************/
-#if !((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
- || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
- || (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
- || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
- || (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
- || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
- || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
- || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
- || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
- || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
- || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
- || (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \
- || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
- || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED))
-#error "An architecture must be selected"
-#endif
-
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
@@ -113,15 +96,36 @@ extern "C" {
+ (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+ (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
- + (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \
+ (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
+ (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
+ + (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
+ (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
+ (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
#error "Multiple architectures are selected"
#endif
+#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) \
+ && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
+ && !(defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) \
+ && !(defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) \
+ && !(defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
+ && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
+ && !(defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
+ && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ && !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+ && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
+ && !(defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
+ && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
+ && !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) \
+ && !(defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO)
+#if defined SLJIT_CONFIG_AUTO && !SLJIT_CONFIG_AUTO
+#error "An architecture must be selected"
+#else /* SLJIT_CONFIG_AUTO */
+#define SLJIT_CONFIG_AUTO 1
+#endif /* !SLJIT_CONFIG_AUTO */
+#endif /* !SLJIT_CONFIG */
+
/********************************************************/
/* Automatic CPU detection (requires compiler support). */
/********************************************************/
@@ -154,8 +158,6 @@ extern "C" {
#define SLJIT_CONFIG_MIPS_64 1
#elif defined(__sparc__) || defined(__sparc)
#define SLJIT_CONFIG_SPARC_32 1
-#elif defined(__tilegx__)
-#define SLJIT_CONFIG_TILEGX 1
#else
/* Unsupported architecture */
#define SLJIT_CONFIG_UNSUPPORTED 1
@@ -210,18 +212,16 @@ extern "C" {
/***********************************************************/
#ifdef SLJIT_CONFIG_X86
-#if defined(__CET__)
+
+#if defined(__CET__) && !(defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
#define SLJIT_CONFIG_X86_CET 1
#endif
-#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
-#if defined(__GNUC__)
-#if !defined (__SHSTK__)
-#error "-mshstk is needed to compile with -fcf-protection"
-#endif
+
+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined(__GNUC__)
#include <x86intrin.h>
#endif
-#endif
-#endif
+
+#endif /* SLJIT_CONFIG_X86 */
/**********************************/
/* External function definitions. */
@@ -411,7 +411,7 @@ typedef long int sljit_sw;
&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
&& !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
&& !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
- && !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+ && !(defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
#define SLJIT_32BIT_ARCHITECTURE 1
#define SLJIT_WORD_SHIFT 2
typedef unsigned int sljit_uw;
@@ -453,10 +453,14 @@ typedef double sljit_f64;
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
#define SLJIT_W(w) (w##l)
#elif (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
+#ifdef _WIN64
#define SLJIT_W(w) (w##ll)
-#else
+#else /* !windows */
+#define SLJIT_W(w) (w##l)
+#endif /* windows */
+#else /* 32 bit */
#define SLJIT_W(w) (w)
-#endif
+#endif /* unknown */
#endif /* !SLJIT_W */
@@ -504,7 +508,8 @@ typedef double sljit_f64;
#endif /* !SLJIT_MIPS_REV */
-#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
+ || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
#define SLJIT_BIG_ENDIAN 1
@@ -531,7 +536,8 @@ typedef double sljit_f64;
|| (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) \
|| (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|| (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
- || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+ || (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
#define SLJIT_UNALIGNED 1
#endif
@@ -549,17 +555,19 @@ typedef double sljit_f64;
#ifndef SLJIT_FUNC
-#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION)
+#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION) \
+ || !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-/* Force cdecl. */
#define SLJIT_FUNC
-#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-
-#if defined(__GNUC__) && !defined(__APPLE__)
+#elif defined(__GNUC__) && !defined(__APPLE__)
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define SLJIT_FUNC __attribute__ ((fastcall))
#define SLJIT_X86_32_FASTCALL 1
+#else
+#define SLJIT_FUNC
+#endif /* gcc >= 3.4 */
#elif defined(_MSC_VER)
@@ -573,16 +581,10 @@ typedef double sljit_f64;
#else /* Unknown compiler. */
-/* The cdecl attribute is the default. */
-#define SLJIT_FUNC
-
-#endif
-
-#else /* Non x86-32 architectures. */
-
+/* The cdecl calling convention is usually the x86 default. */
#define SLJIT_FUNC
-#endif /* SLJIT_CONFIG_X86_32 */
+#endif /* SLJIT_USE_CDECL_CALLING_CONVENTION */
#endif /* !SLJIT_FUNC */
@@ -613,8 +615,16 @@ determine the next executed instruction after return. */
SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size);
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr);
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void);
-#define SLJIT_MALLOC_EXEC(size) sljit_malloc_exec(size)
-#define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr)
+#define SLJIT_BUILTIN_MALLOC_EXEC(size, exec_allocator_data) sljit_malloc_exec(size)
+#define SLJIT_BUILTIN_FREE_EXEC(ptr, exec_allocator_data) sljit_free_exec(ptr)
+
+#ifndef SLJIT_MALLOC_EXEC
+#define SLJIT_MALLOC_EXEC(size, exec_allocator_data) SLJIT_BUILTIN_MALLOC_EXEC((size), (exec_allocator_data))
+#endif /* SLJIT_MALLOC_EXEC */
+
+#ifndef SLJIT_FREE_EXEC
+#define SLJIT_FREE_EXEC(ptr, exec_allocator_data) SLJIT_BUILTIN_FREE_EXEC((ptr), (exec_allocator_data))
+#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);
@@ -623,7 +633,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
#define SLJIT_EXEC_OFFSET(ptr) 0
#endif
-#endif
+#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
/**********************************************/
/* Registers and locals offset determination. */
@@ -699,11 +709,32 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
#define SLJIT_LOCALS_OFFSET_BASE ((16 + 1 + 6 + 2 + 1) * sizeof(sljit_sw))
#endif
-#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
+#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
-#define SLJIT_NUMBER_OF_REGISTERS 10
-#define SLJIT_NUMBER_OF_SAVED_REGISTERS 5
-#define SLJIT_LOCALS_OFFSET_BASE 0
+/*
+ * https://refspecs.linuxbase.org/ELF/zSeries/lzsabi0_zSeries.html#STACKFRAME
+ *
+ * 160
+ * .. FR6
+ * .. FR4
+ * .. FR2
+ * 128 FR0
+ * 120 R15 (used for SP)
+ * 112 R14
+ * 104 R13
+ * 96 R12
+ * ..
+ * 48 R6
+ * ..
+ * 16 R2
+ * 8 RESERVED
+ * 0 SP
+ */
+#define SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE 160
+
+#define SLJIT_NUMBER_OF_REGISTERS 12
+#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
+#define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE
#elif (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
@@ -791,4 +822,4 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
} /* extern "C" */
#endif
-#endif
+#endif /* SLJIT_CONFIG_INTERNAL_H_ */
diff --git a/src/sljit/sljitExecAllocator.c b/src/sljit/sljitExecAllocator.c
index 7653907..61a32f2 100644
--- a/src/sljit/sljitExecAllocator.c
+++ b/src/sljit/sljitExecAllocator.c
@@ -72,9 +72,8 @@
alloc_chunk / free_chunk :
* allocate executable system memory chunks
* the size is always divisible by CHUNK_SIZE
- allocator_grab_lock / allocator_release_lock :
- * make the allocator thread safe
- * can be empty if the OS (or the application) does not support threading
+ SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :
+ * provided as part of sljitUtils
* only the allocator requires this lock, sljit is fully thread safe
as it only uses local variables
*/
@@ -95,6 +94,7 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
#else
#ifdef __APPLE__
+#ifdef MAP_ANON
/* Configures TARGET_OS_OSX when appropriate */
#include <TargetConditionals.h>
@@ -104,17 +104,23 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
#ifdef MAP_JIT
+/*
+ On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a
+ version where it's OK to have more than one JIT block.
+ On non-macOS systems, returns MAP_JIT if it is defined.
+*/
static SLJIT_INLINE int get_map_jit_flag()
{
-/* On macOS systems, returns MAP_JIT if it is defined _and_ we're running on a version
- of macOS where it's OK to have more than one JIT block.
- On non-macOS systems, returns MAP_JIT if it is defined. */
#if TARGET_OS_OSX
+ sljit_sw page_size = get_page_alignment() + 1;
+ void *ptr;
static int map_jit_flag = -1;
- /* The following code is thread safe because multiple initialization
- sets map_jit_flag to the same value and the code has no side-effects.
- Changing the kernel version witout system restart is (very) unlikely. */
+ /*
+ The following code is thread safe because multiple initialization
+ sets map_jit_flag to the same value and the code has no side-effects.
+ Changing the kernel version witout system restart is (very) unlikely.
+ */
if (map_jit_flag == -1) {
struct utsname name;
@@ -123,15 +129,9 @@ static SLJIT_INLINE int get_map_jit_flag()
/* Kernel version for 10.14.0 (Mojave) */
if (atoi(name.release) >= 18) {
- /* Only use MAP_JIT if a hardened runtime is used, because MAP_JIT is incompatible with fork(). */
+ /* Only use MAP_JIT if a hardened runtime is used */
- /* mirroring page size detection from sljit_allocate_stack */
- long page_size = sysconf(_SC_PAGESIZE);
- /* Should never happen */
- if (page_size < 0)
- page_size = 4096;
-
- void *ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
+ ptr = mmap(NULL, page_size, PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
if (ptr == MAP_FAILED) {
map_jit_flag = MAP_JIT;
@@ -148,7 +148,7 @@ static SLJIT_INLINE int get_map_jit_flag()
}
#endif /* MAP_JIT */
-
+#endif /* MAP_ANON */
#endif /* __APPLE__ */
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
@@ -166,10 +166,9 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
retval = mmap(NULL, size, prot, flags, -1, 0);
#else /* !MAP_ANON */
- if (dev_zero < 0) {
- if (open_dev_zero())
- return NULL;
- }
+ if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero()))
+ return NULL;
+
retval = mmap(NULL, size, prot, MAP_PRIVATE, dev_zero, 0);
#endif /* MAP_ANON */
@@ -253,7 +252,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
struct free_block *free_block;
sljit_uw chunk_size;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
if (size < (64 - sizeof(struct block_header)))
size = (64 - sizeof(struct block_header));
size = ALIGN_SIZE(size);
@@ -277,7 +276,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
}
allocated_size += size;
header->size = size;
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return MEM_START(header);
}
free_block = free_block->next;
@@ -286,7 +285,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK;
header = (struct block_header*)alloc_chunk(chunk_size);
if (!header) {
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return NULL;
}
@@ -313,7 +312,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
}
next_header->size = 1;
next_header->prev_size = chunk_size;
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return MEM_START(header);
}
@@ -322,7 +321,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
struct block_header *header;
struct free_block* free_block;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
allocated_size -= header->size;
@@ -359,7 +358,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
}
}
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
@@ -367,7 +366,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
struct free_block* free_block;
struct free_block* next_free_block;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
free_block = free_blocks;
while (free_block) {
@@ -382,5 +381,5 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
}
SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
}
diff --git a/src/sljit/sljitLir.c b/src/sljit/sljitLir.c
index 86772cc..d817c90 100644
--- a/src/sljit/sljitLir.c
+++ b/src/sljit/sljitLir.c
@@ -28,7 +28,6 @@
#ifdef _WIN32
-/* For SLJIT_CACHE_FLUSH, which can expand to FlushInstructionCache. */
#include <windows.h>
#endif /* _WIN32 */
@@ -223,14 +222,6 @@
# define FCSR_FCC 33
#endif
-#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
-# define IS_JAL 0x04
-# define IS_COND 0x08
-
-# define PATCH_B 0x10
-# define PATCH_J 0x20
-#endif
-
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
# define IS_MOVABLE 0x04
# define IS_COND 0x08
@@ -274,6 +265,8 @@
#if (defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR)
#include "sljitProtExecAllocator.c"
+#elif (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
+#include "sljitWXExecAllocator.c"
#else
#include "sljitExecAllocator.c"
#endif
@@ -286,6 +279,10 @@
#define SLJIT_ADD_EXEC_OFFSET(ptr, exec_offset) ((sljit_u8 *)(ptr))
#endif
+#ifndef SLJIT_UPDATE_WX_FLAGS
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec)
+#endif
+
/* Argument checking features. */
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
@@ -366,7 +363,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)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
{
struct sljit_compiler *compiler = (struct sljit_compiler*)SLJIT_MALLOC(sizeof(struct sljit_compiler), allocator_data);
if (!compiler)
@@ -393,6 +390,7 @@ 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);
@@ -485,22 +483,28 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_compiler_memory_error(struct sljit_compi
}
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+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 & ~0x1));
+ SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1), exec_allocator_data);
}
#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+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);
+ SLJIT_FREE_EXEC(code, exec_allocator_data);
}
#else
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
{
- SLJIT_FREE_EXEC(code);
+ SLJIT_UNUSED_ARG(exec_allocator_data);
+
+ SLJIT_FREE_EXEC(code, exec_allocator_data);
}
#endif
@@ -627,7 +631,10 @@ static SLJIT_INLINE sljit_s32 get_arg_count(sljit_s32 arg_types)
return arg_count;
}
-#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+
+/* 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)
@@ -649,7 +656,7 @@ static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct
return result;
}
-#endif /* !SLJIT_CONFIG_X86 */
+#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_S390X */
static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
@@ -1378,6 +1385,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co
#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)
|| (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));
+#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
+ CHECK_ARGUMENT(size == 2 || size == 4 || size == 6);
#else
CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
#endif
@@ -2034,7 +2043,7 @@ static SLJIT_INLINE sljit_s32 emit_mov_before_return(struct sljit_compiler *comp
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
|| (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC) \
|| (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
- || ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1))
+ || ((defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) && !(defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6))
static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *compiler, sljit_s32 type,
sljit_s32 dst_reg,
@@ -2111,8 +2120,8 @@ static SLJIT_INLINE sljit_s32 sljit_emit_cmov_generic(struct sljit_compiler *com
# include "sljitNativeMIPS_common.c"
#elif (defined SLJIT_CONFIG_SPARC && SLJIT_CONFIG_SPARC)
# include "sljitNativeSPARC_common.c"
-#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
-# include "sljitNativeTILEGX_64.c"
+#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
+# include "sljitNativeS390X.c"
#endif
#if !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
@@ -2143,7 +2152,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
#endif
if (SLJIT_UNLIKELY((src1 & SLJIT_IMM) && !(src2 & SLJIT_IMM))) {
- /* Immediate is prefered as second argument by most architectures. */
+ /* Immediate is preferred as second argument by most architectures. */
switch (condition) {
case SLJIT_LESS:
condition = SLJIT_GREATER;
@@ -2292,9 +2301,10 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
return "unsupported";
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data)
{
SLJIT_UNUSED_ARG(allocator_data);
+ SLJIT_UNUSED_ARG(exec_allocator_data);
SLJIT_UNREACHABLE();
return NULL;
}
@@ -2342,9 +2352,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
return 0;
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data)
{
SLJIT_UNUSED_ARG(code);
+ SLJIT_UNUSED_ARG(exec_allocator_data);
SLJIT_UNREACHABLE();
}
diff --git a/src/sljit/sljitLir.h b/src/sljit/sljitLir.h
index 72595bb..93d2804 100644
--- a/src/sljit/sljitLir.h
+++ b/src/sljit/sljitLir.h
@@ -24,8 +24,8 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _SLJIT_LIR_H_
-#define _SLJIT_LIR_H_
+#ifndef SLJIT_LIR_H_
+#define SLJIT_LIR_H_
/*
------------------------------------------------------------------------
@@ -70,9 +70,11 @@
- pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code"
*/
-#if !(defined SLJIT_NO_DEFAULT_CONFIG && SLJIT_NO_DEFAULT_CONFIG)
+#if (defined SLJIT_HAVE_CONFIG_PRE && SLJIT_HAVE_CONFIG_PRE)
+#include "sljitConfigPre.h"
+#endif /* SLJIT_HAVE_CONFIG_PRE */
+
#include "sljitConfig.h"
-#endif
/* The following header file defines useful macros for fine tuning
sljit based code generators. They are listed in the beginning
@@ -80,6 +82,10 @@ of sljitConfigInternal.h */
#include "sljitConfigInternal.h"
+#if (defined SLJIT_HAVE_CONFIG_POST && SLJIT_HAVE_CONFIG_POST)
+#include "sljitConfigPost.h"
+#endif /* SLJIT_HAVE_CONFIG_POST */
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -385,6 +391,7 @@ struct sljit_compiler {
struct sljit_put_label *last_put_label;
void *allocator_data;
+ void *exec_allocator_data;
struct sljit_memory_fragment *buf;
struct sljit_memory_fragment *abuf;
@@ -451,9 +458,9 @@ struct sljit_compiler {
sljit_sw cache_argw;
#endif
-#if (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
- sljit_s32 cache_arg;
- sljit_sw cache_argw;
+#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
+ /* Need to allocate register save area to make calls. */
+ sljit_s32 have_save_area;
#endif
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
@@ -485,10 +492,12 @@ 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.
+ 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.
Returns NULL if failed. */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data);
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data, void *exec_allocator_data);
/* Frees everything except the compiled machine code. */
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler);
@@ -535,7 +544,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
/* Free executable code. */
-SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code, void *exec_allocator_data);
/*
When the protected executable allocator is used the JIT code is mapped
@@ -699,7 +708,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
*/
/*
- IMPORATNT NOTE: memory access MUST be naturally aligned except
+ IMPORTANT NOTE: memory access MUST be naturally aligned unless
SLJIT_UNALIGNED macro is defined and its value is 1.
length | alignment
@@ -741,6 +750,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *
mips: [reg+imm], -65536 <= imm <= 65535
sparc: [reg+imm], -4096 <= imm <= 4095
[reg+reg] is supported
+ s390x: [reg+imm], -2^19 <= imm < 2^19
+ [reg+reg] is supported
+ Write-back is not supported
*/
/* Macros for specifying operand types. */
@@ -1405,12 +1417,6 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void);
/* Portable helper function to get an offset of a member. */
#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
-#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
-/* This global lock is useful to compile common functions. */
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void);
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void);
-#endif
-
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
/* The sljit_stack structure and its manipulation functions provides
@@ -1538,4 +1544,4 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *com
} /* extern "C" */
#endif
-#endif /* _SLJIT_LIR_H_ */
+#endif /* SLJIT_LIR_H_ */
diff --git a/src/sljit/sljitNativeARM_32.c b/src/sljit/sljitNativeARM_32.c
index 5d180c2..ae8479f 100644
--- a/src/sljit/sljitNativeARM_32.c
+++ b/src/sljit/sljitNativeARM_32.c
@@ -467,18 +467,28 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut
sljit_s32 bl = (mov_pc & 0x0000f000) != RD(TMP_PC);
sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2) - executable_offset) >> 2);
+ SLJIT_UNUSED_ARG(executable_offset);
+
if (diff <= 0x7fffff && diff >= -0x800000) {
/* Turn to branch. */
if (!bl) {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ }
inst[0] = (mov_pc & COND_MASK) | (B - CONDITIONAL) | (diff & 0xffffff);
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 1);
}
} else {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ }
inst[0] = (mov_pc & COND_MASK) | (BL - CONDITIONAL) | (diff & 0xffffff);
inst[1] = NOP;
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
@@ -491,28 +501,52 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw jump_ptr, sljit_sw execut
ptr = inst + 1;
if (*inst != mov_pc) {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + (!bl ? 1 : 2), 0);
+ }
inst[0] = mov_pc;
if (!bl) {
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 1);
}
} else {
inst[1] = BLX | RM(TMP_REG1);
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
}
}
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);
+ }
+
*ptr = new_addr;
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);
+ }
}
#else
sljit_uw *inst = (sljit_uw*)jump_ptr;
+
+ SLJIT_UNUSED_ARG(executable_offset);
+
SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ }
+
inst[0] = MOVW | (inst[0] & 0xf000) | ((new_addr << 4) & 0xf0000) | (new_addr & 0xfff);
inst[1] = MOVT | (inst[1] & 0xf000) | ((new_addr >> 12) & 0xf0000) | ((new_addr >> 16) & 0xfff);
+
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
@@ -529,10 +563,18 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off
sljit_uw ldr_literal = ptr[1];
sljit_uw src2;
+ SLJIT_UNUSED_ARG(executable_offset);
+
src2 = get_imm(new_constant);
if (src2) {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ }
+
*inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2;
+
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 1);
}
@@ -541,8 +583,14 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off
src2 = get_imm(~new_constant);
if (src2) {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ }
+
*inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2;
+
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 1);
}
@@ -555,19 +603,44 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw executable_off
ptr = inst + 1;
if (*inst != ldr_literal) {
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ }
+
*inst = ldr_literal;
+
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 1);
}
}
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);
+ }
+
*ptr = new_constant;
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);
+ }
#else
sljit_uw *inst = (sljit_uw*)addr;
+
+ SLJIT_UNUSED_ARG(executable_offset);
+
SLJIT_ASSERT((inst[0] & 0xfff00000) == MOVW && (inst[1] & 0xfff00000) == MOVT);
+
+ if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ }
+
inst[0] = MOVW | (inst[0] & 0xf000) | ((new_constant << 4) & 0xf0000) | (new_constant & 0xfff);
inst[1] = MOVT | (inst[1] & 0xf000) | ((new_constant >> 12) & 0xf0000) | ((new_constant >> 16) & 0xfff);
+
if (flush_cache) {
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
@@ -612,7 +685,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
#else
size = compiler->size;
#endif
- code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw));
+ code = (sljit_uw*)SLJIT_MALLOC_EXEC(size * sizeof(sljit_uw), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -653,7 +726,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
}
else {
if (SLJIT_UNLIKELY(resolve_const_pool_index(compiler, &first_patch, cpool_current_index, cpool_start_address, buf_ptr))) {
- SLJIT_FREE_EXEC(code);
+ SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);
compiler->error = SLJIT_ERR_ALLOC_FAILED;
return NULL;
}
@@ -756,7 +829,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);
+ SLJIT_FREE_EXEC(code, compiler->exec_allocator_data);
compiler->error = SLJIT_ERR_ALLOC_FAILED;
return NULL;
}
@@ -856,6 +929,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = (sljit_uw *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
SLJIT_CACHE_FLUSH(code, code_ptr);
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
return code;
}
diff --git a/src/sljit/sljitNativeARM_64.c b/src/sljit/sljitNativeARM_64.c
index eaca095..52267e7 100644
--- a/src/sljit/sljitNativeARM_64.c
+++ b/src/sljit/sljitNativeARM_64.c
@@ -151,16 +151,6 @@ static SLJIT_INLINE sljit_s32 emit_imm64_const(struct sljit_compiler *compiler,
return push_inst(compiler, MOVK | RD(dst) | ((imm >> 48) << 5) | (3 << 21));
}
-static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm)
-{
- sljit_s32 dst = inst[0] & 0x1f;
- SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
- inst[0] = MOVZ | dst | ((new_imm & 0xffff) << 5);
- inst[1] = MOVK | dst | (((new_imm >> 16) & 0xffff) << 5) | (1 << 21);
- inst[2] = MOVK | dst | (((new_imm >> 32) & 0xffff) << 5) | (2 << 21);
- inst[3] = MOVK | dst | ((new_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)
{
sljit_sw diff;
@@ -253,7 +243,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
CHECK_PTR(check_sljit_generate_code(compiler));
reverse_buf(compiler);
- code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -380,6 +370,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
SLJIT_CACHE_FLUSH(code, code_ptr);
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
return code;
}
@@ -2034,15 +2025,24 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins* inst = (sljit_ins*)addr;
- modify_imm64_const(inst, new_target);
+ sljit_s32 dst;
+ SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);
+
+ dst = inst[0] & 0x1f;
+ SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
+ inst[0] = MOVZ | dst | ((new_target & 0xffff) << 5);
+ inst[1] = MOVK | dst | (((new_target >> 16) & 0xffff) << 5) | (1 << 21);
+ inst[2] = MOVK | dst | (((new_target >> 32) & 0xffff) << 5) | (2 << 21);
+ inst[3] = MOVK | dst | ((new_target >> 48) << 5) | (3 << 21);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 4);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins* inst = (sljit_ins*)addr;
- modify_imm64_const(inst, new_constant);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 4);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
diff --git a/src/sljit/sljitNativeARM_T2_32.c b/src/sljit/sljitNativeARM_T2_32.c
index a81e008..4624882 100644
--- a/src/sljit/sljitNativeARM_T2_32.c
+++ b/src/sljit/sljitNativeARM_T2_32.c
@@ -377,7 +377,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
CHECK_PTR(check_sljit_generate_code(compiler));
reverse_buf(compiler);
- code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16));
+ code = (sljit_u16*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_u16), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -463,6 +463,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
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);
+
/* Set thumb mode flag. */
return (void*)((sljit_uw)code | 0x1);
}
@@ -608,7 +610,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
Although some clever things could be done here, "NOT IMM" does not worth the efforts. */
break;
case SLJIT_ADD:
- nimm = -imm;
+ nimm = -(sljit_sw)imm;
if (IS_2_LO_REGS(reg, dst)) {
if (imm <= 0x7)
return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
@@ -630,7 +632,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
nimm = get_imm(imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
- nimm = get_imm(-imm);
+ nimm = get_imm(-(sljit_sw)imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
break;
@@ -655,11 +657,11 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
nimm = get_imm(imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, CMPI_W | RN4(reg) | nimm);
- nimm = get_imm(-imm);
+ nimm = get_imm(-(sljit_sw)imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, CMNI_W | RN4(reg) | nimm);
}
- nimm = -imm;
+ nimm = -(sljit_sw)imm;
if (IS_2_LO_REGS(reg, dst)) {
if (imm <= 0x7)
return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg));
@@ -681,7 +683,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
nimm = get_imm(imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, SUB_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
- nimm = get_imm(-imm);
+ nimm = get_imm(-(sljit_sw)imm);
if (nimm != INVALID_IMM)
return push_inst32(compiler, ADD_WI | (flags & SET_FLAGS) | RD4(dst) | RN4(reg) | nimm);
break;
@@ -2366,15 +2368,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_u16 *inst = (sljit_u16*)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);
modify_imm32_const(inst, new_target);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);
inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 4);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_u16 *inst = (sljit_u16*)addr;
- modify_imm32_const(inst, new_constant);
- inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 4);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
diff --git a/src/sljit/sljitNativeMIPS_32.c b/src/sljit/sljitNativeMIPS_32.c
index 777627b..f887ee1 100644
--- a/src/sljit/sljitNativeMIPS_32.c
+++ b/src/sljit/sljitNativeMIPS_32.c
@@ -425,23 +425,20 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins *)addr;
-
- SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
- inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
diff --git a/src/sljit/sljitNativeMIPS_64.c b/src/sljit/sljitNativeMIPS_64.c
index 479244d..5ab9b7d 100644
--- a/src/sljit/sljitNativeMIPS_64.c
+++ b/src/sljit/sljitNativeMIPS_64.c
@@ -525,25 +525,21 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 0);
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
inst[5] = (inst[5] & 0xffff0000) | (new_target & 0xffff);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 6);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins *)addr;
-
- inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
- inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
- inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 6);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
diff --git a/src/sljit/sljitNativeMIPS_common.c b/src/sljit/sljitNativeMIPS_common.c
index 88df904..ecf4dac 100644
--- a/src/sljit/sljitNativeMIPS_common.c
+++ b/src/sljit/sljitNativeMIPS_common.c
@@ -290,9 +290,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
Useful for reordering instructions in the delay slot. */
static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 delay_slot)
{
+ sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS
|| delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f));
- sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
FAIL_IF(!ptr);
*ptr = ins;
compiler->size++;
@@ -520,7 +520,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
CHECK_PTR(check_sljit_generate_code(compiler));
reverse_buf(compiler);
- code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -667,6 +667,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
/* GCC workaround for invalid code generation with -O2. */
sljit_cache_flush(code, code_ptr);
#endif
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
return code;
}
@@ -679,7 +680,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
#ifdef SLJIT_IS_FPU_AVAILABLE
return SLJIT_IS_FPU_AVAILABLE;
#elif defined(__GNUC__)
- asm ("cfc1 %0, $0" : "=r"(fir));
+ __asm__ ("cfc1 %0, $0" : "=r"(fir));
return (fir >> 22) & 0x1;
#else
#error "FIR check is not implemented for this architecture"
@@ -2185,14 +2186,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
sljit_s32 dst_reg,
sljit_s32 src, sljit_sw srcw)
{
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
sljit_ins ins;
-#endif /* SLJIT_MIPS_REV >= 1 */
+#endif /* SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6 */
CHECK_ERROR();
CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
-#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1)
+#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
@@ -2249,7 +2250,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
return push_inst(compiler, ins | S(src) | D(dst_reg), DR(dst_reg));
-#else /* SLJIT_MIPS_REV < 1 */
+#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
return sljit_emit_cmov_generic(compiler, type, dst_reg, src, srcw);
#endif /* SLJIT_MIPS_REV >= 1 */
}
diff --git a/src/sljit/sljitNativePPC_32.c b/src/sljit/sljitNativePPC_32.c
index 3ce7411..7d9ec53 100644
--- a/src/sljit/sljitNativePPC_32.c
+++ b/src/sljit/sljitNativePPC_32.c
@@ -258,21 +258,18 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins *)addr;
-
- SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
- inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
diff --git a/src/sljit/sljitNativePPC_64.c b/src/sljit/sljitNativePPC_64.c
index 3b73021..92147d2 100644
--- a/src/sljit/sljitNativePPC_64.c
+++ b/src/sljit/sljitNativePPC_64.c
@@ -477,23 +477,19 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins*)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 48) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | ((new_target >> 32) & 0xffff);
inst[3] = (inst[3] & 0xffff0000) | ((new_target >> 16) & 0xffff);
inst[4] = (inst[4] & 0xffff0000) | (new_target & 0xffff);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 5);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins*)addr;
-
- inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
- inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
- inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 5);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
diff --git a/src/sljit/sljitNativePPC_common.c b/src/sljit/sljitNativePPC_common.c
index 590f91c..d84562c 100644
--- a/src/sljit/sljitNativePPC_common.c
+++ b/src/sljit/sljitNativePPC_common.c
@@ -404,7 +404,7 @@ 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));
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -607,6 +607,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
SLJIT_CACHE_FLUSH(code, code_ptr);
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
return code_ptr;
diff --git a/src/sljit/sljitNativeS390X.c b/src/sljit/sljitNativeS390X.c
new file mode 100644
index 0000000..a8b6511
--- /dev/null
+++ b/src/sljit/sljitNativeS390X.c
@@ -0,0 +1,2812 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/auxv.h>
+
+#ifdef __ARCH__
+#define ENABLE_STATIC_FACILITY_DETECTION 1
+#else
+#define ENABLE_STATIC_FACILITY_DETECTION 0
+#endif
+#define ENABLE_DYNAMIC_FACILITY_DETECTION 1
+
+SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
+{
+ return "s390x" SLJIT_CPUINFO;
+}
+
+/* Instructions. */
+typedef sljit_uw sljit_ins;
+
+/* Instruction tags (most significant halfword). */
+const sljit_ins sljit_ins_const = (sljit_ins)1 << 48;
+
+static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
+ 14, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 0, 1
+};
+
+/* there are also a[2-15] available, but they are slower to access and
+ * their use is limited as mundaym explained:
+ * https://github.com/zherczeg/sljit/pull/91#discussion_r486895689
+ */
+
+/* General Purpose Registers [0-15]. */
+typedef sljit_uw sljit_gpr;
+
+/*
+ * WARNING
+ * the following code is non standard and should be improved for
+ * consistency, but doesn't use SLJIT_NUMBER_OF_REGISTERS based
+ * registers because r0 and r1 are the ABI recommended volatiles.
+ * there is a gpr() function that maps sljit to physical register numbers
+ * that should be used instead of the usual index into reg_map[] and
+ * will be retired ASAP (TODO: carenas)
+ */
+
+const sljit_gpr r0 = 0; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 2]: 0 in address calculations; reserved */
+const sljit_gpr r1 = 1; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 3]: reserved */
+const sljit_gpr r2 = 2; /* reg_map[1]: 1st argument */
+const sljit_gpr r3 = 3; /* reg_map[2]: 2nd argument */
+const sljit_gpr r4 = 4; /* reg_map[3]: 3rd argument */
+const sljit_gpr r5 = 5; /* reg_map[4]: 4th argument */
+const sljit_gpr r6 = 6; /* reg_map[5]: 5th argument; 1st saved register */
+const sljit_gpr r7 = 7; /* reg_map[6] */
+const sljit_gpr r8 = 8; /* reg_map[7] */
+const sljit_gpr r9 = 9; /* reg_map[8] */
+const sljit_gpr r10 = 10; /* reg_map[9] */
+const sljit_gpr r11 = 11; /* reg_map[10] */
+const sljit_gpr r12 = 12; /* reg_map[11]: GOT */
+const sljit_gpr r13 = 13; /* reg_map[12]: Literal Pool pointer */
+const sljit_gpr r14 = 14; /* reg_map[0]: return address and flag register */
+const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stack pointer */
+
+/* WARNING: r12 and r13 shouldn't be used as per ABI recommendation */
+/* TODO(carenas): r12 might conflict in PIC code, reserve? */
+/* TODO(carenas): r13 is usually pointed to "pool" per ABI, using a tmp
+ * like we do know might be faster though, reserve?
+ */
+
+/* TODO(carenas): should be named TMP_REG[1-2] for consistency */
+#define tmp0 r0
+#define tmp1 r1
+
+/* TODO(carenas): flags should move to a different register so that
+ * link register doesn't need to change
+ */
+
+/* Link registers. The normal link register is r14, but since
+ we use that for flags we need to use r0 instead to do fast
+ calls so that flags are preserved. */
+const sljit_gpr link_r = 14; /* r14 */
+const sljit_gpr fast_link_r = 0; /* r0 */
+
+/* Flag register layout:
+
+ 0 32 33 34 36 64
+ +---------------+---+---+-------+-------+
+ | ZERO | 0 | 0 | C C |///////|
+ +---------------+---+---+-------+-------+
+*/
+const sljit_gpr flag_r = 14; /* r14 */
+
+struct sljit_s390x_const {
+ struct sljit_const const_; /* must be first */
+ sljit_sw init_value; /* required to build literal pool */
+};
+
+/* Convert SLJIT register to hardware register. */
+static SLJIT_INLINE sljit_gpr gpr(sljit_s32 r)
+{
+ SLJIT_ASSERT(r != SLJIT_UNUSED);
+ SLJIT_ASSERT(r < (sljit_s32)(sizeof(reg_map) / sizeof(reg_map[0])));
+ 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;
+ compiler->size++;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 encode_inst(void **ptr, sljit_ins ins)
+{
+ sljit_u16 *ibuf = (sljit_u16 *)*ptr;
+ sljit_uw size = sizeof_ins(ins);
+
+ 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;
+}
+
+/* Map the given type to a 4-bit condition code mask. */
+static SLJIT_INLINE sljit_u8 get_cc(sljit_s32 type) {
+ const sljit_u8 eq = 1 << 3; /* equal {,to zero} */
+ const sljit_u8 lt = 1 << 2; /* less than {,zero} */
+ const sljit_u8 gt = 1 << 1; /* greater than {,zero} */
+ const sljit_u8 ov = 1 << 0; /* {overflow,NaN} */
+
+ switch (type) {
+ case SLJIT_EQUAL:
+ case SLJIT_EQUAL_F64:
+ return eq;
+
+ case SLJIT_NOT_EQUAL:
+ case SLJIT_NOT_EQUAL_F64:
+ return ~eq;
+
+ case SLJIT_LESS:
+ case SLJIT_SIG_LESS:
+ case SLJIT_LESS_F64:
+ return lt;
+
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_SIG_LESS_EQUAL:
+ case SLJIT_LESS_EQUAL_F64:
+ return (lt | eq);
+
+ case SLJIT_GREATER:
+ case SLJIT_SIG_GREATER:
+ case SLJIT_GREATER_F64:
+ return gt;
+
+ case SLJIT_GREATER_EQUAL:
+ case SLJIT_SIG_GREATER_EQUAL:
+ case SLJIT_GREATER_EQUAL_F64:
+ return (gt | eq);
+
+ case SLJIT_OVERFLOW:
+ case SLJIT_MUL_OVERFLOW:
+ case SLJIT_UNORDERED_F64:
+ return ov;
+
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_MUL_NOT_OVERFLOW:
+ case SLJIT_ORDERED_F64:
+ return ~ov;
+ }
+
+ SLJIT_UNREACHABLE();
+ return (sljit_u8)-1;
+}
+
+/* Facility to bit index mappings.
+ Note: some facilities share the same bit index. */
+typedef sljit_uw facility_bit;
+#define STORE_FACILITY_LIST_EXTENDED_FACILITY 7
+#define FAST_LONG_DISPLACEMENT_FACILITY 19
+#define EXTENDED_IMMEDIATE_FACILITY 21
+#define GENERAL_INSTRUCTION_EXTENSION_FACILITY 34
+#define DISTINCT_OPERAND_FACILITY 45
+#define HIGH_WORD_FACILITY 45
+#define POPULATION_COUNT_FACILITY 45
+#define LOAD_STORE_ON_CONDITION_1_FACILITY 45
+#define MISCELLANEOUS_INSTRUCTION_EXTENSIONS_1_FACILITY 49
+#define LOAD_STORE_ON_CONDITION_2_FACILITY 53
+#define MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY 58
+#define VECTOR_FACILITY 129
+#define VECTOR_ENHANCEMENTS_1_FACILITY 135
+
+/* Report whether a facility is known to be present due to the compiler
+ settings. This function should always be compiled to a constant
+ value given a constant argument. */
+static SLJIT_INLINE int have_facility_static(facility_bit x)
+{
+#if ENABLE_STATIC_FACILITY_DETECTION
+ switch (x) {
+ case FAST_LONG_DISPLACEMENT_FACILITY:
+ return (__ARCH__ >= 6 /* z990 */);
+ case EXTENDED_IMMEDIATE_FACILITY:
+ case STORE_FACILITY_LIST_EXTENDED_FACILITY:
+ return (__ARCH__ >= 7 /* z9-109 */);
+ case GENERAL_INSTRUCTION_EXTENSION_FACILITY:
+ return (__ARCH__ >= 8 /* z10 */);
+ case DISTINCT_OPERAND_FACILITY:
+ return (__ARCH__ >= 9 /* z196 */);
+ case MISCELLANEOUS_INSTRUCTION_EXTENSIONS_1_FACILITY:
+ return (__ARCH__ >= 10 /* zEC12 */);
+ case LOAD_STORE_ON_CONDITION_2_FACILITY:
+ case VECTOR_FACILITY:
+ return (__ARCH__ >= 11 /* z13 */);
+ case MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY:
+ case VECTOR_ENHANCEMENTS_1_FACILITY:
+ return (__ARCH__ >= 12 /* z14 */);
+ default:
+ SLJIT_UNREACHABLE();
+ }
+#endif
+ return 0;
+}
+
+static SLJIT_INLINE unsigned long get_hwcap()
+{
+ static unsigned long hwcap = 0;
+ if (SLJIT_UNLIKELY(!hwcap)) {
+ hwcap = getauxval(AT_HWCAP);
+ SLJIT_ASSERT(hwcap != 0);
+ }
+ return hwcap;
+}
+
+static SLJIT_INLINE int have_stfle()
+{
+ if (have_facility_static(STORE_FACILITY_LIST_EXTENDED_FACILITY))
+ return 1;
+
+ return (get_hwcap() & HWCAP_S390_STFLE);
+}
+
+/* Report whether the given facility is available. This function always
+ performs a runtime check. */
+static int have_facility_dynamic(facility_bit x)
+{
+#if ENABLE_DYNAMIC_FACILITY_DETECTION
+ static struct {
+ sljit_uw bits[4];
+ } cpu_features;
+ size_t size = sizeof(cpu_features);
+ const sljit_uw word_index = x >> 6;
+ const sljit_uw bit_index = ((1UL << 63) >> (x & 63));
+
+ SLJIT_ASSERT(x < size * 8);
+ if (SLJIT_UNLIKELY(!have_stfle()))
+ return 0;
+
+ if (SLJIT_UNLIKELY(cpu_features.bits[0] == 0)) {
+ __asm__ __volatile__ (
+ "lgr %%r0, %0;"
+ "stfle 0(%1);"
+ /* outputs */:
+ /* inputs */: "d" ((size / 8) - 1), "a" (&cpu_features)
+ /* clobbers */: "r0", "cc", "memory"
+ );
+ SLJIT_ASSERT(cpu_features.bits[0] != 0);
+ }
+ return (cpu_features.bits[word_index] & bit_index) != 0;
+#else
+ return 0;
+#endif
+}
+
+#define HAVE_FACILITY(name, bit) \
+static SLJIT_INLINE int name() \
+{ \
+ static int have = -1; \
+ /* Static check first. May allow the function to be optimized away. */ \
+ if (have_facility_static(bit)) \
+ have = 1; \
+ else if (SLJIT_UNLIKELY(have < 0)) \
+ have = have_facility_dynamic(bit) ? 1 : 0; \
+\
+ return have; \
+}
+
+HAVE_FACILITY(have_eimm, EXTENDED_IMMEDIATE_FACILITY)
+HAVE_FACILITY(have_ldisp, FAST_LONG_DISPLACEMENT_FACILITY)
+HAVE_FACILITY(have_genext, GENERAL_INSTRUCTION_EXTENSION_FACILITY)
+HAVE_FACILITY(have_lscond1, LOAD_STORE_ON_CONDITION_1_FACILITY)
+HAVE_FACILITY(have_lscond2, LOAD_STORE_ON_CONDITION_2_FACILITY)
+HAVE_FACILITY(have_misc2, MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY)
+#undef HAVE_FACILITY
+
+#define is_u12(d) (0 <= (d) && (d) <= 0x00000fffL)
+#define is_u32(d) (0 <= (d) && (d) <= 0xffffffffL)
+
+#define CHECK_SIGNED(v, bitlen) \
+ ((v) == (((v) << (sizeof(v) * 8 - bitlen)) >> (sizeof(v) * 8 - bitlen)))
+
+#define is_s16(d) CHECK_SIGNED((d), 16)
+#define is_s20(d) CHECK_SIGNED((d), 20)
+#define is_s32(d) CHECK_SIGNED((d), 32)
+
+static SLJIT_INLINE sljit_uw disp_s20(sljit_s32 d)
+{
+ sljit_uw dh = (d >> 12) & 0xff;
+ sljit_uw dl = (d << 8) & 0xfff00;
+
+ SLJIT_ASSERT(is_s20(d));
+ return dh | dl;
+}
+
+/* TODO(carenas): variadic macro is not strictly needed */
+#define SLJIT_S390X_INSTRUCTION(op, ...) \
+static SLJIT_INLINE sljit_ins op(__VA_ARGS__)
+
+/* RR form instructions. */
+#define SLJIT_S390X_RR(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src) \
+{ \
+ return (pattern) | ((dst & 0xf) << 4) | (src & 0xf); \
+}
+
+/* ADD */
+SLJIT_S390X_RR(ar, 0x1a00)
+
+/* ADD LOGICAL */
+SLJIT_S390X_RR(alr, 0x1e00)
+
+/* AND */
+SLJIT_S390X_RR(nr, 0x1400)
+
+/* BRANCH AND SAVE */
+SLJIT_S390X_RR(basr, 0x0d00)
+
+/* BRANCH ON CONDITION */
+SLJIT_S390X_RR(bcr, 0x0700) /* TODO(mundaym): type for mask? */
+
+/* COMPARE */
+SLJIT_S390X_RR(cr, 0x1900)
+
+/* COMPARE LOGICAL */
+SLJIT_S390X_RR(clr, 0x1500)
+
+/* DIVIDE */
+SLJIT_S390X_RR(dr, 0x1d00)
+
+/* EXCLUSIVE OR */
+SLJIT_S390X_RR(xr, 0x1700)
+
+/* LOAD */
+SLJIT_S390X_RR(lr, 0x1800)
+
+/* LOAD COMPLEMENT */
+SLJIT_S390X_RR(lcr, 0x1300)
+
+/* OR */
+SLJIT_S390X_RR(or, 0x1600)
+
+/* SUBTRACT */
+SLJIT_S390X_RR(sr, 0x1b00)
+
+/* SUBTRACT LOGICAL */
+SLJIT_S390X_RR(slr, 0x1f00)
+
+#undef SLJIT_S390X_RR
+
+/* RRE form instructions */
+#define SLJIT_S390X_RRE(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src) \
+{ \
+ return (pattern) | ((dst & 0xf) << 4) | (src & 0xf); \
+}
+
+/* ADD */
+SLJIT_S390X_RRE(agr, 0xb9080000)
+
+/* ADD LOGICAL */
+SLJIT_S390X_RRE(algr, 0xb90a0000)
+
+/* ADD LOGICAL WITH CARRY */
+SLJIT_S390X_RRE(alcr, 0xb9980000)
+SLJIT_S390X_RRE(alcgr, 0xb9880000)
+
+/* AND */
+SLJIT_S390X_RRE(ngr, 0xb9800000)
+
+/* COMPARE */
+SLJIT_S390X_RRE(cgr, 0xb9200000)
+
+/* COMPARE LOGICAL */
+SLJIT_S390X_RRE(clgr, 0xb9210000)
+
+/* DIVIDE LOGICAL */
+SLJIT_S390X_RRE(dlr, 0xb9970000)
+SLJIT_S390X_RRE(dlgr, 0xb9870000)
+
+/* DIVIDE SINGLE */
+SLJIT_S390X_RRE(dsgr, 0xb90d0000)
+
+/* EXCLUSIVE OR */
+SLJIT_S390X_RRE(xgr, 0xb9820000)
+
+/* LOAD */
+SLJIT_S390X_RRE(lgr, 0xb9040000)
+SLJIT_S390X_RRE(lgfr, 0xb9140000)
+
+/* LOAD BYTE */
+SLJIT_S390X_RRE(lbr, 0xb9260000)
+SLJIT_S390X_RRE(lgbr, 0xb9060000)
+
+/* LOAD COMPLEMENT */
+SLJIT_S390X_RRE(lcgr, 0xb9030000)
+
+/* LOAD HALFWORD */
+SLJIT_S390X_RRE(lhr, 0xb9270000)
+SLJIT_S390X_RRE(lghr, 0xb9070000)
+
+/* LOAD LOGICAL */
+SLJIT_S390X_RRE(llgfr, 0xb9160000)
+
+/* LOAD LOGICAL CHARACTER */
+SLJIT_S390X_RRE(llcr, 0xb9940000)
+SLJIT_S390X_RRE(llgcr, 0xb9840000)
+
+/* LOAD LOGICAL HALFWORD */
+SLJIT_S390X_RRE(llhr, 0xb9950000)
+SLJIT_S390X_RRE(llghr, 0xb9850000)
+
+/* MULTIPLY LOGICAL */
+SLJIT_S390X_RRE(mlgr, 0xb9860000)
+
+/* MULTIPLY SINGLE */
+SLJIT_S390X_RRE(msr, 0xb2520000)
+SLJIT_S390X_RRE(msgr, 0xb90c0000)
+SLJIT_S390X_RRE(msgfr, 0xb91c0000)
+
+/* OR */
+SLJIT_S390X_RRE(ogr, 0xb9810000)
+
+/* SUBTRACT */
+SLJIT_S390X_RRE(sgr, 0xb9090000)
+
+/* SUBTRACT LOGICAL */
+SLJIT_S390X_RRE(slgr, 0xb90b0000)
+
+/* SUBTRACT LOGICAL WITH BORROW */
+SLJIT_S390X_RRE(slbr, 0xb9990000)
+SLJIT_S390X_RRE(slbgr, 0xb9890000)
+
+#undef SLJIT_S390X_RRE
+
+/* RI-a form instructions */
+#define SLJIT_S390X_RIA(name, pattern, imm_type) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, imm_type imm) \
+{ \
+ return (pattern) | ((reg & 0xf) << 20) | (imm & 0xffff); \
+}
+
+/* ADD HALFWORD IMMEDIATE */
+SLJIT_S390X_RIA(ahi, 0xa70a0000, sljit_s16)
+SLJIT_S390X_RIA(aghi, 0xa70b0000, sljit_s16)
+
+/* COMPARE HALFWORD IMMEDIATE */
+SLJIT_S390X_RIA(chi, 0xa70e0000, sljit_s16)
+SLJIT_S390X_RIA(cghi, 0xa70f0000, sljit_s16)
+
+/* LOAD HALFWORD IMMEDIATE */
+SLJIT_S390X_RIA(lhi, 0xa7080000, sljit_s16)
+SLJIT_S390X_RIA(lghi, 0xa7090000, sljit_s16)
+
+/* LOAD LOGICAL IMMEDIATE */
+SLJIT_S390X_RIA(llihh, 0xa50c0000, sljit_u16)
+SLJIT_S390X_RIA(llihl, 0xa50d0000, sljit_u16)
+SLJIT_S390X_RIA(llilh, 0xa50e0000, sljit_u16)
+SLJIT_S390X_RIA(llill, 0xa50f0000, sljit_u16)
+
+/* MULTIPLY HALFWORD IMMEDIATE */
+SLJIT_S390X_RIA(mhi, 0xa70c0000, sljit_s16)
+SLJIT_S390X_RIA(mghi, 0xa70d0000, sljit_s16)
+
+/* OR IMMEDIATE */
+SLJIT_S390X_RIA(oilh, 0xa50a0000, sljit_u16)
+
+/* TEST UNDER MASK */
+SLJIT_S390X_RIA(tmlh, 0xa7000000, sljit_u16)
+
+#undef SLJIT_S390X_RIA
+
+/* RIL-a form instructions (requires extended immediate facility) */
+#define SLJIT_S390X_RILA(name, pattern, imm_type) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, imm_type imm) \
+{ \
+ SLJIT_ASSERT(have_eimm()); \
+ return (pattern) | ((sljit_ins)(reg & 0xf) << 36) | (imm & 0xffffffff); \
+}
+
+/* ADD IMMEDIATE */
+SLJIT_S390X_RILA(afi, 0xc20900000000, sljit_s32)
+SLJIT_S390X_RILA(agfi, 0xc20800000000, sljit_s32)
+
+/* ADD IMMEDIATE HIGH */
+SLJIT_S390X_RILA(aih, 0xcc0800000000, sljit_s32) /* TODO(mundaym): high-word facility? */
+
+/* ADD LOGICAL IMMEDIATE */
+SLJIT_S390X_RILA(alfi, 0xc20b00000000, sljit_u32)
+SLJIT_S390X_RILA(algfi, 0xc20a00000000, sljit_u32)
+
+/* AND IMMEDIATE */
+SLJIT_S390X_RILA(nihf, 0xc00a00000000, sljit_u32)
+SLJIT_S390X_RILA(nilf, 0xc00b00000000, sljit_u32)
+
+/* COMPARE IMMEDIATE */
+SLJIT_S390X_RILA(cfi, 0xc20d00000000, sljit_s32)
+SLJIT_S390X_RILA(cgfi, 0xc20c00000000, sljit_s32)
+
+/* COMPARE IMMEDIATE HIGH */
+SLJIT_S390X_RILA(cih, 0xcc0d00000000, sljit_s32) /* TODO(mundaym): high-word facility? */
+
+/* COMPARE LOGICAL IMMEDIATE */
+SLJIT_S390X_RILA(clfi, 0xc20f00000000, sljit_u32)
+SLJIT_S390X_RILA(clgfi, 0xc20e00000000, sljit_u32)
+
+/* EXCLUSIVE OR IMMEDIATE */
+SLJIT_S390X_RILA(xilf, 0xc00700000000, sljit_u32)
+
+/* INSERT IMMEDIATE */
+SLJIT_S390X_RILA(iihf, 0xc00800000000, sljit_u32)
+SLJIT_S390X_RILA(iilf, 0xc00900000000, sljit_u32)
+
+/* LOAD IMMEDIATE */
+SLJIT_S390X_RILA(lgfi, 0xc00100000000, sljit_s32)
+
+/* LOAD LOGICAL IMMEDIATE */
+SLJIT_S390X_RILA(llihf, 0xc00e00000000, sljit_u32)
+SLJIT_S390X_RILA(llilf, 0xc00f00000000, sljit_u32)
+
+/* OR IMMEDIATE */
+SLJIT_S390X_RILA(oilf, 0xc00d00000000, sljit_u32)
+
+#undef SLJIT_S390X_RILA
+
+/* RX-a form instructions */
+#define SLJIT_S390X_RXA(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr r, sljit_u16 d, sljit_gpr x, sljit_gpr b) \
+{ \
+ sljit_ins ri, xi, bi, di; \
+\
+ SLJIT_ASSERT((d & 0xfff) == d); \
+ ri = (sljit_ins)(r & 0xf) << 20; \
+ xi = (sljit_ins)(x & 0xf) << 16; \
+ bi = (sljit_ins)(b & 0xf) << 12; \
+ di = (sljit_ins)(d & 0xfff); \
+\
+ return (pattern) | ri | xi | bi | di; \
+}
+
+/* ADD */
+SLJIT_S390X_RXA(a, 0x5a000000)
+
+/* ADD LOGICAL */
+SLJIT_S390X_RXA(al, 0x5e000000)
+
+/* AND */
+SLJIT_S390X_RXA(n, 0x54000000)
+
+/* EXCLUSIVE OR */
+SLJIT_S390X_RXA(x, 0x57000000)
+
+/* LOAD */
+SLJIT_S390X_RXA(l, 0x58000000)
+
+/* LOAD ADDRESS */
+SLJIT_S390X_RXA(la, 0x41000000)
+
+/* LOAD HALFWORD */
+SLJIT_S390X_RXA(lh, 0x48000000)
+
+/* MULTIPLY SINGLE */
+SLJIT_S390X_RXA(ms, 0x71000000)
+
+/* OR */
+SLJIT_S390X_RXA(o, 0x56000000)
+
+/* STORE */
+SLJIT_S390X_RXA(st, 0x50000000)
+
+/* STORE CHARACTER */
+SLJIT_S390X_RXA(stc, 0x42000000)
+
+/* STORE HALFWORD */
+SLJIT_S390X_RXA(sth, 0x40000000)
+
+/* SUBTRACT */
+SLJIT_S390X_RXA(s, 0x5b000000)
+
+/* SUBTRACT LOGICAL */
+SLJIT_S390X_RXA(sl, 0x5f000000)
+
+#undef SLJIT_S390X_RXA
+
+/* RXY-a instructions */
+#define SLJIT_S390X_RXYA(name, pattern, cond) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b) \
+{ \
+ sljit_ins ri, xi, bi, di; \
+\
+ SLJIT_ASSERT(cond); \
+ ri = (sljit_ins)(r & 0xf) << 36; \
+ xi = (sljit_ins)(x & 0xf) << 32; \
+ bi = (sljit_ins)(b & 0xf) << 28; \
+ di = (sljit_ins)disp_s20(d) << 8; \
+\
+ return (pattern) | ri | xi | bi | di; \
+}
+
+/* ADD */
+SLJIT_S390X_RXYA(ay, 0xe3000000005a, have_ldisp())
+SLJIT_S390X_RXYA(ag, 0xe30000000008, 1)
+
+/* ADD LOGICAL */
+SLJIT_S390X_RXYA(aly, 0xe3000000005e, have_ldisp())
+SLJIT_S390X_RXYA(alg, 0xe3000000000a, 1)
+
+/* ADD LOGICAL WITH CARRY */
+SLJIT_S390X_RXYA(alc, 0xe30000000098, 1)
+SLJIT_S390X_RXYA(alcg, 0xe30000000088, 1)
+
+/* AND */
+SLJIT_S390X_RXYA(ny, 0xe30000000054, have_ldisp())
+SLJIT_S390X_RXYA(ng, 0xe30000000080, 1)
+
+/* EXCLUSIVE OR */
+SLJIT_S390X_RXYA(xy, 0xe30000000057, have_ldisp())
+SLJIT_S390X_RXYA(xg, 0xe30000000082, 1)
+
+/* LOAD */
+SLJIT_S390X_RXYA(ly, 0xe30000000058, have_ldisp())
+SLJIT_S390X_RXYA(lg, 0xe30000000004, 1)
+SLJIT_S390X_RXYA(lgf, 0xe30000000014, 1)
+
+/* LOAD BYTE */
+SLJIT_S390X_RXYA(lb, 0xe30000000076, have_ldisp())
+SLJIT_S390X_RXYA(lgb, 0xe30000000077, have_ldisp())
+
+/* LOAD HALFWORD */
+SLJIT_S390X_RXYA(lhy, 0xe30000000078, have_ldisp())
+SLJIT_S390X_RXYA(lgh, 0xe30000000015, 1)
+
+/* LOAD LOGICAL */
+SLJIT_S390X_RXYA(llgf, 0xe30000000016, 1)
+
+/* LOAD LOGICAL CHARACTER */
+SLJIT_S390X_RXYA(llc, 0xe30000000094, have_eimm())
+SLJIT_S390X_RXYA(llgc, 0xe30000000090, 1)
+
+/* LOAD LOGICAL HALFWORD */
+SLJIT_S390X_RXYA(llh, 0xe30000000095, have_eimm())
+SLJIT_S390X_RXYA(llgh, 0xe30000000091, 1)
+
+/* MULTIPLY SINGLE */
+SLJIT_S390X_RXYA(msy, 0xe30000000051, have_ldisp())
+SLJIT_S390X_RXYA(msg, 0xe3000000000c, 1)
+
+/* OR */
+SLJIT_S390X_RXYA(oy, 0xe30000000056, have_ldisp())
+SLJIT_S390X_RXYA(og, 0xe30000000081, 1)
+
+/* STORE */
+SLJIT_S390X_RXYA(sty, 0xe30000000050, have_ldisp())
+SLJIT_S390X_RXYA(stg, 0xe30000000024, 1)
+
+/* STORE CHARACTER */
+SLJIT_S390X_RXYA(stcy, 0xe30000000072, have_ldisp())
+
+/* STORE HALFWORD */
+SLJIT_S390X_RXYA(sthy, 0xe30000000070, have_ldisp())
+
+/* SUBTRACT */
+SLJIT_S390X_RXYA(sy, 0xe3000000005b, have_ldisp())
+SLJIT_S390X_RXYA(sg, 0xe30000000009, 1)
+
+/* SUBTRACT LOGICAL */
+SLJIT_S390X_RXYA(sly, 0xe3000000005f, have_ldisp())
+SLJIT_S390X_RXYA(slg, 0xe3000000000b, 1)
+
+/* SUBTRACT LOGICAL WITH BORROW */
+SLJIT_S390X_RXYA(slb, 0xe30000000099, 1)
+SLJIT_S390X_RXYA(slbg, 0xe30000000089, 1)
+
+#undef SLJIT_S390X_RXYA
+
+/* RS-a instructions */
+#define SLJIT_S390X_RSA(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw d, sljit_gpr b) \
+{ \
+ sljit_ins r1 = (sljit_ins)(reg & 0xf) << 20; \
+ sljit_ins b2 = (sljit_ins)(b & 0xf) << 12; \
+ sljit_ins d2 = (sljit_ins)(d & 0xfff); \
+ return (pattern) | r1 | b2 | d2; \
+}
+
+/* SHIFT LEFT SINGLE LOGICAL */
+SLJIT_S390X_RSA(sll, 0x89000000)
+
+/* SHIFT RIGHT SINGLE */
+SLJIT_S390X_RSA(sra, 0x8a000000)
+
+/* SHIFT RIGHT SINGLE LOGICAL */
+SLJIT_S390X_RSA(srl, 0x88000000)
+
+#undef SLJIT_S390X_RSA
+
+/* RSY-a instructions */
+#define SLJIT_S390X_RSYA(name, pattern, cond) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_sw d, sljit_gpr b) \
+{ \
+ sljit_ins r1, r3, b2, d2; \
+\
+ SLJIT_ASSERT(cond); \
+ r1 = (sljit_ins)(dst & 0xf) << 36; \
+ r3 = (sljit_ins)(src & 0xf) << 32; \
+ b2 = (sljit_ins)(b & 0xf) << 28; \
+ d2 = (sljit_ins)disp_s20(d) << 8; \
+\
+ return (pattern) | r1 | r3 | b2 | d2; \
+}
+
+/* LOAD MULTIPLE */
+SLJIT_S390X_RSYA(lmg, 0xeb0000000004, 1)
+
+/* SHIFT LEFT LOGICAL */
+SLJIT_S390X_RSYA(sllg, 0xeb000000000d, 1)
+
+/* SHIFT RIGHT SINGLE */
+SLJIT_S390X_RSYA(srag, 0xeb000000000a, 1)
+
+/* SHIFT RIGHT SINGLE LOGICAL */
+SLJIT_S390X_RSYA(srlg, 0xeb000000000c, 1)
+
+/* STORE MULTIPLE */
+SLJIT_S390X_RSYA(stmg, 0xeb0000000024, 1)
+
+#undef SLJIT_S390X_RSYA
+
+/* RIE-f instructions (require general-instructions-extension facility) */
+#define SLJIT_S390X_RIEF(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_u8 start, sljit_u8 end, sljit_u8 rot) \
+{ \
+ sljit_ins r1, r2, i3, i4, i5; \
+\
+ SLJIT_ASSERT(have_genext()); \
+ r1 = (sljit_ins)(dst & 0xf) << 36; \
+ r2 = (sljit_ins)(src & 0xf) << 32; \
+ i3 = (sljit_ins)start << 24; \
+ i4 = (sljit_ins)end << 16; \
+ i5 = (sljit_ins)rot << 8; \
+\
+ return (pattern) | r1 | r2 | i3 | i4 | i5; \
+}
+
+/* ROTATE THEN AND SELECTED BITS */
+/* SLJIT_S390X_RIEF(rnsbg, 0xec0000000054) */
+
+/* ROTATE THEN EXCLUSIVE OR SELECTED BITS */
+/* SLJIT_S390X_RIEF(rxsbg, 0xec0000000057) */
+
+/* ROTATE THEN OR SELECTED BITS */
+SLJIT_S390X_RIEF(rosbg, 0xec0000000056)
+
+/* ROTATE THEN INSERT SELECTED BITS */
+/* SLJIT_S390X_RIEF(risbg, 0xec0000000055) */
+/* SLJIT_S390X_RIEF(risbgn, 0xec0000000059) */
+
+/* ROTATE THEN INSERT SELECTED BITS HIGH */
+SLJIT_S390X_RIEF(risbhg, 0xec000000005d)
+
+/* ROTATE THEN INSERT SELECTED BITS LOW */
+/* SLJIT_S390X_RIEF(risblg, 0xec0000000051) */
+
+#undef SLJIT_S390X_RIEF
+
+/* RRF-a instructions */
+#define SLJIT_S390X_RRFA(name, pattern, cond) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src1, sljit_gpr src2) \
+{ \
+ sljit_ins r1, r2, r3; \
+\
+ SLJIT_ASSERT(cond); \
+ r1 = (sljit_ins)(dst & 0xf) << 4; \
+ r2 = (sljit_ins)(src1 & 0xf); \
+ r3 = (sljit_ins)(src2 & 0xf) << 12; \
+\
+ return (pattern) | r3 | r1 | r2; \
+}
+
+/* MULTIPLY */
+SLJIT_S390X_RRFA(msrkc, 0xb9fd0000, have_misc2())
+SLJIT_S390X_RRFA(msgrkc, 0xb9ed0000, have_misc2())
+
+#undef SLJIT_S390X_RRFA
+
+/* RRF-c instructions (require load/store-on-condition 1 facility) */
+#define SLJIT_S390X_RRFC(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr dst, sljit_gpr src, sljit_uw mask) \
+{ \
+ sljit_ins r1, r2, m3; \
+\
+ SLJIT_ASSERT(have_lscond1()); \
+ r1 = (sljit_ins)(dst & 0xf) << 4; \
+ r2 = (sljit_ins)(src & 0xf); \
+ m3 = (sljit_ins)(mask & 0xf) << 12; \
+\
+ return (pattern) | m3 | r1 | r2; \
+}
+
+/* LOAD HALFWORD IMMEDIATE ON CONDITION */
+SLJIT_S390X_RRFC(locr, 0xb9f20000)
+SLJIT_S390X_RRFC(locgr, 0xb9e20000)
+
+#undef SLJIT_S390X_RRFC
+
+/* RIE-g instructions (require load/store-on-condition 2 facility) */
+#define SLJIT_S390X_RIEG(name, pattern) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw imm, sljit_uw mask) \
+{ \
+ sljit_ins r1, m3, i2; \
+\
+ SLJIT_ASSERT(have_lscond2()); \
+ r1 = (sljit_ins)(reg & 0xf) << 36; \
+ m3 = (sljit_ins)(mask & 0xf) << 32; \
+ i2 = (sljit_ins)(imm & 0xffffL) << 16; \
+\
+ return (pattern) | r1 | m3 | i2; \
+}
+
+/* LOAD HALFWORD IMMEDIATE ON CONDITION */
+SLJIT_S390X_RIEG(lochi, 0xec0000000042)
+SLJIT_S390X_RIEG(locghi, 0xec0000000046)
+
+#undef SLJIT_S390X_RIEG
+
+#define SLJIT_S390X_RILB(name, pattern, cond) \
+SLJIT_S390X_INSTRUCTION(name, sljit_gpr reg, sljit_sw ri) \
+{ \
+ sljit_ins r1, ri2; \
+\
+ SLJIT_ASSERT(cond); \
+ r1 = (sljit_ins)(reg & 0xf) << 36; \
+ ri2 = (sljit_ins)(ri & 0xffffffff); \
+\
+ return (pattern) | r1 | ri2; \
+}
+
+/* BRANCH RELATIVE AND SAVE LONG */
+SLJIT_S390X_RILB(brasl, 0xc00500000000, 1)
+
+/* LOAD ADDRESS RELATIVE LONG */
+SLJIT_S390X_RILB(larl, 0xc00000000000, 1)
+
+/* LOAD RELATIVE LONG */
+SLJIT_S390X_RILB(lgrl, 0xc40800000000, have_genext())
+
+#undef SLJIT_S390X_RILB
+
+SLJIT_S390X_INSTRUCTION(br, sljit_gpr target)
+{
+ return 0x07f0 | target;
+}
+
+SLJIT_S390X_INSTRUCTION(brcl, sljit_uw mask, sljit_sw target)
+{
+ sljit_ins m1 = (sljit_ins)(mask & 0xf) << 36;
+ sljit_ins ri2 = (sljit_ins)target & 0xffffffff;
+ return 0xc00400000000L | m1 | ri2;
+}
+
+SLJIT_S390X_INSTRUCTION(flogr, sljit_gpr dst, sljit_gpr src)
+{
+ sljit_ins r1 = ((sljit_ins)dst & 0xf) << 8;
+ sljit_ins r2 = ((sljit_ins)src & 0xf);
+ SLJIT_ASSERT(have_eimm());
+ return 0xb9830000 | r1 | r2;
+}
+
+/* INSERT PROGRAM MASK */
+SLJIT_S390X_INSTRUCTION(ipm, sljit_gpr dst)
+{
+ return 0xb2220000 | ((sljit_ins)(dst & 0xf) << 4);
+}
+
+/* ROTATE THEN INSERT SELECTED BITS HIGH (ZERO) */
+SLJIT_S390X_INSTRUCTION(risbhgz, sljit_gpr dst, sljit_gpr src, sljit_u8 start, sljit_u8 end, sljit_u8 rot)
+{
+ return risbhg(dst, src, start, 0x8 | end, rot);
+}
+
+#undef SLJIT_S390X_INSTRUCTION
+
+/* load condition code as needed to match type */
+static sljit_s32 push_load_cc(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ type &= ~SLJIT_I32_OP;
+ switch (type) {
+ case SLJIT_ZERO:
+ case SLJIT_NOT_ZERO:
+ return push_inst(compiler, cih(flag_r, 0));
+ break;
+ default:
+ return push_inst(compiler, tmlh(flag_r, 0x3000));
+ break;
+ }
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_store_zero_flag(struct sljit_compiler *compiler, sljit_s32 op, sljit_gpr source)
+{
+ /* insert low 32-bits into high 32-bits of flag register */
+ FAIL_IF(push_inst(compiler, risbhgz(flag_r, source, 0, 31, 32)));
+ if (!(op & SLJIT_I32_OP)) {
+ /* OR high 32-bits with high 32-bits of flag register */
+ return push_inst(compiler, rosbg(flag_r, source, 0, 31, 0));
+ }
+ return SLJIT_SUCCESS;
+}
+
+/* load 64-bit immediate into register without clobbering flags */
+static sljit_s32 push_load_imm_inst(struct sljit_compiler *compiler, sljit_gpr target, sljit_sw v)
+{
+ /* 4 byte instructions */
+ if (is_s16(v))
+ return push_inst(compiler, lghi(target, (sljit_s16)v));
+
+ if ((sljit_uw)v == (v & 0x000000000000ffffU))
+ return push_inst(compiler, llill(target, (sljit_u16)v));
+
+ if ((sljit_uw)v == (v & 0x00000000ffff0000U))
+ return push_inst(compiler, llilh(target, (sljit_u16)(v >> 16)));
+
+ if ((sljit_uw)v == (v & 0x0000ffff00000000U))
+ return push_inst(compiler, llihl(target, (sljit_u16)(v >> 32)));
+
+ if ((sljit_uw)v == (v & 0xffff000000000000U))
+ return push_inst(compiler, llihh(target, (sljit_u16)(v >> 48)));
+
+ /* 6 byte instructions (requires extended immediate facility) */
+ if (have_eimm()) {
+ if (is_s32(v))
+ return push_inst(compiler, lgfi(target, (sljit_s32)v));
+
+ if ((sljit_uw)v == (v & 0x00000000ffffffffU))
+ return push_inst(compiler, llilf(target, (sljit_u32)v));
+
+ if ((sljit_uw)v == (v & 0xffffffff00000000U))
+ return push_inst(compiler, llihf(target, (sljit_u32)(v >> 32)));
+
+ FAIL_IF(push_inst(compiler, llilf(target, (sljit_u32)v)));
+ return push_inst(compiler, iihf(target, (sljit_u32)(v >> 32)));
+ }
+ /* TODO(mundaym): instruction sequences that don't use extended immediates */
+ abort();
+}
+
+struct addr {
+ sljit_gpr base;
+ sljit_gpr index;
+ sljit_sw offset;
+};
+
+/* transform memory operand into D(X,B) form with a signed 20-bit offset */
+static sljit_s32 make_addr_bxy(struct sljit_compiler *compiler,
+ struct addr *addr, sljit_s32 mem, sljit_sw off,
+ sljit_gpr tmp /* clobbered, must not be r0 */)
+{
+ sljit_gpr base = r0;
+ sljit_gpr index = r0;
+
+ SLJIT_ASSERT(tmp != r0);
+ if (mem & REG_MASK)
+ base = gpr(mem & REG_MASK);
+
+ if (mem & OFFS_REG_MASK) {
+ index = gpr(OFFS_REG(mem));
+ if (off != 0) {
+ /* shift and put the result into tmp */
+ SLJIT_ASSERT(0 <= off && off < 64);
+ FAIL_IF(push_inst(compiler, sllg(tmp, index, off, 0)));
+ index = tmp;
+ off = 0; /* clear offset */
+ }
+ }
+ else if (!is_s20(off)) {
+ FAIL_IF(push_load_imm_inst(compiler, tmp, off));
+ index = tmp;
+ off = 0; /* clear offset */
+ }
+ addr->base = base;
+ addr->index = index;
+ addr->offset = off;
+ return SLJIT_SUCCESS;
+}
+
+/* transform memory operand into D(X,B) form with an unsigned 12-bit offset */
+static sljit_s32 make_addr_bx(struct sljit_compiler *compiler,
+ struct addr *addr, sljit_s32 mem, sljit_sw off,
+ sljit_gpr tmp /* clobbered, must not be r0 */)
+{
+ sljit_gpr base = r0;
+ sljit_gpr index = r0;
+
+ SLJIT_ASSERT(tmp != r0);
+ if (mem & REG_MASK)
+ base = gpr(mem & REG_MASK);
+
+ if (mem & OFFS_REG_MASK) {
+ index = gpr(OFFS_REG(mem));
+ if (off != 0) {
+ /* shift and put the result into tmp */
+ SLJIT_ASSERT(0 <= off && off < 64);
+ FAIL_IF(push_inst(compiler, sllg(tmp, index, off, 0)));
+ index = tmp;
+ off = 0; /* clear offset */
+ }
+ }
+ else if (!is_u12(off)) {
+ FAIL_IF(push_load_imm_inst(compiler, tmp, off));
+ index = tmp;
+ off = 0; /* clear offset */
+ }
+ addr->base = base;
+ addr->index = index;
+ addr->offset = off;
+ return SLJIT_SUCCESS;
+}
+
+#define EVAL(op, r, addr) op(r, addr.offset, addr.index, addr.base)
+#define WHEN(cond, r, i1, i2, addr) \
+ (cond) ? EVAL(i1, r, addr) : EVAL(i2, r, addr)
+
+static sljit_s32 load_word(struct sljit_compiler *compiler, sljit_gpr dst,
+ sljit_s32 src, sljit_sw srcw,
+ sljit_gpr tmp /* clobbered */, sljit_s32 is_32bit)
+{
+ struct addr addr;
+ sljit_ins ins;
+
+ SLJIT_ASSERT(src & SLJIT_MEM);
+ if (have_ldisp() || !is_32bit)
+ FAIL_IF(make_addr_bxy(compiler, &addr, src, srcw, tmp));
+ else
+ FAIL_IF(make_addr_bx(compiler, &addr, src, srcw, tmp));
+
+ if (is_32bit)
+ ins = WHEN(is_u12(addr.offset), dst, l, ly, addr);
+ else
+ ins = lg(dst, addr.offset, addr.index, addr.base);
+
+ return push_inst(compiler, ins);
+}
+
+static sljit_s32 store_word(struct sljit_compiler *compiler, sljit_gpr src,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_gpr tmp /* clobbered */, sljit_s32 is_32bit)
+{
+ struct addr addr;
+ sljit_ins ins;
+
+ SLJIT_ASSERT(dst & SLJIT_MEM);
+ if (have_ldisp() || !is_32bit)
+ FAIL_IF(make_addr_bxy(compiler, &addr, dst, dstw, tmp));
+ else
+ FAIL_IF(make_addr_bx(compiler, &addr, dst, dstw, tmp));
+
+ if (is_32bit)
+ ins = WHEN(is_u12(addr.offset), src, st, sty, addr);
+ else
+ ins = stg(src, addr.offset, addr.index, addr.base);
+
+ return push_inst(compiler, ins);
+}
+
+#undef WHEN
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+ struct sljit_jump *jump;
+ struct sljit_s390x_const *const_;
+ struct sljit_put_label *put_label;
+ sljit_sw executable_offset;
+ sljit_uw ins_size = 0; /* instructions */
+ sljit_uw pool_size = 0; /* literal pool */
+ sljit_uw pad_size;
+ sljit_uw i, j = 0;
+ struct sljit_memory_fragment *buf;
+ void *code, *code_ptr;
+ sljit_uw *pool, *pool_ptr;
+
+ sljit_uw source;
+ sljit_sw offset; /* TODO(carenas): only need 32 bit */
+
+ 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);
+ }
+ }
+
+ /* emit trailing label */
+ if (label && label->size == j) {
+ label->size = ins_size;
+ label = label->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);
+ 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
+ * globally; if generated code is too big could
+ * need offsets bigger than 32bit words and asser()
+ */
+ pool = (sljit_uw *)((sljit_uw)code + ins_size + pad_size);
+ pool_ptr = pool;
+ const_ = (struct sljit_s390x_const *)compiler->consts;
+
+ /* 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;
+
+ /* 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;
+
+ /* update instruction with relative address of constant */
+ source = (sljit_uw)code_ptr;
+ offset = (sljit_uw)pool_ptr - source;
+ SLJIT_ASSERT(!(offset & 1));
+ offset >>= 1; /* halfword (not byte) offset */
+ SLJIT_ASSERT(is_s32(offset));
+ ins |= (sljit_ins)offset & 0xffffffff;
+
+ /* update address */
+ const_->const_.addr = (sljit_uw)pool_ptr;
+
+ /* store initial value into pool and update pool address */
+ *(pool_ptr++) = const_->init_value;
+
+ /* move to next constant */
+ const_ = (struct sljit_s390x_const *)const_->const_.next;
+ }
+ if (jump && jump->addr == j) {
+ sljit_sw target = (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target;
+ if ((jump->flags & SLJIT_REWRITABLE_JUMP) || (jump->flags & JUMP_ADDR)) {
+ jump->addr = (sljit_uw)pool_ptr;
+
+ /* load address into tmp1 */
+ source = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ offset = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
+ SLJIT_ASSERT(!(offset & 1));
+ offset >>= 1;
+ SLJIT_ASSERT(is_s32(offset));
+ encode_inst(&code_ptr,
+ lgrl(tmp1, offset & 0xffffffff));
+
+ /* store jump target into pool and update pool address */
+ *(pool_ptr++) = target;
+
+ /* branch to tmp1 */
+ sljit_ins op = (ins >> 32) & 0xf;
+ sljit_ins 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_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ offset = target - source;
+
+ /* offset must be halfword aligned */
+ SLJIT_ASSERT(!(offset & 1));
+ offset >>= 1;
+ SLJIT_ASSERT(is_s32(offset)); /* TODO(mundaym): handle arbitrary offsets */
+
+ /* patch jump target */
+ ins |= (sljit_ins)offset & 0xffffffff;
+ }
+ jump = jump->next;
+ }
+ if (put_label && put_label->addr == j) {
+ source = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+
+ SLJIT_ASSERT(put_label->label);
+ put_label->addr = (sljit_uw)code_ptr;
+
+ /* store target into pool */
+ *pool_ptr = put_label->label->addr;
+ offset = (sljit_uw)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;
+
+ put_label = put_label->next;
+ }
+ encode_inst(&code_ptr, ins);
+ }
+ }
+ 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;
+ code = SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+ code_ptr = SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ SLJIT_CACHE_FLUSH(code, code_ptr);
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
+ return code;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
+{
+ /* TODO(mundaym): implement all */
+ switch (feature_type) {
+ case SLJIT_HAS_CLZ:
+ return have_eimm() ? 1 : 0; /* FLOGR instruction */
+ case SLJIT_HAS_CMOV:
+ return have_lscond1() ? 1 : 0;
+ case SLJIT_HAS_FPU:
+ return 0;
+ }
+ return 0;
+}
+
+/* --------------------------------------------------------------------- */
+/* Entry, exit */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ sljit_s32 args = get_arg_count(arg_types);
+ sljit_sw frame_size;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
+ set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
+
+ /* saved registers go in callee allocated save area */
+ compiler->local_size = (local_size + 0xf) & ~0xf;
+ frame_size = compiler->local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE;
+
+ FAIL_IF(push_inst(compiler, stmg(r6, r15, r6 * sizeof(sljit_sw), r15))); /* save registers TODO(MGM): optimize */
+ if (frame_size != 0) {
+ if (is_s16(-frame_size))
+ FAIL_IF(push_inst(compiler, aghi(r15, -((sljit_s16)frame_size))));
+ else if (is_s32(-frame_size))
+ FAIL_IF(push_inst(compiler, agfi(r15, -((sljit_s32)frame_size))));
+ else {
+ FAIL_IF(push_load_imm_inst(compiler, tmp1, -frame_size));
+ FAIL_IF(push_inst(compiler, la(r15, 0, tmp1, r15)));
+ }
+ }
+
+ if (args >= 1)
+ FAIL_IF(push_inst(compiler, lgr(gpr(SLJIT_S0), gpr(SLJIT_R0))));
+ if (args >= 2)
+ FAIL_IF(push_inst(compiler, lgr(gpr(SLJIT_S1), gpr(SLJIT_R1))));
+ if (args >= 3)
+ FAIL_IF(push_inst(compiler, lgr(gpr(SLJIT_S2), gpr(SLJIT_R2))));
+ SLJIT_ASSERT(args < 4);
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
+ sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
+ sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
+ set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
+
+ /* TODO(mundaym): stack space for saved floating point registers */
+ compiler->local_size = (local_size + 0xf) & ~0xf;
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_sw size;
+ sljit_gpr end;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_return(compiler, op, src, srcw));
+
+ FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
+
+ size = compiler->local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE + (r6 * sizeof(sljit_sw));
+ if (!is_s20(size)) {
+ FAIL_IF(push_load_imm_inst(compiler, tmp1, compiler->local_size + SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE));
+ FAIL_IF(push_inst(compiler, la(r15, 0, tmp1, r15)));
+ size = r6 * sizeof(sljit_sw);
+ end = r14; /* r15 has been restored already */
+ }
+ else
+ end = r15;
+
+ FAIL_IF(push_inst(compiler, lmg(r6, end, size, r15))); /* restore registers TODO(MGM): optimize */
+ FAIL_IF(push_inst(compiler, br(r14))); /* return */
+
+ return SLJIT_SUCCESS;
+}
+
+/* --------------------------------------------------------------------- */
+/* Operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
+{
+ sljit_gpr arg0 = gpr(SLJIT_R0);
+ sljit_gpr arg1 = gpr(SLJIT_R1);
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op0(compiler, op));
+
+ op = GET_OPCODE(op) | (op & SLJIT_I32_OP);
+ switch (op) {
+ case SLJIT_BREAKPOINT:
+ /* TODO(mundaym): insert real breakpoint? */
+ case SLJIT_NOP:
+ return push_inst(compiler, 0x0700 /* 2-byte nop */);
+ case SLJIT_LMUL_UW:
+ FAIL_IF(push_inst(compiler, mlgr(arg0, arg0)));
+ break;
+ case SLJIT_LMUL_SW:
+ /* signed multiplication from: */
+ /* Hacker's Delight, Second Edition: Chapter 8-3. */
+ FAIL_IF(push_inst(compiler, srag(tmp0, arg0, 63, 0)));
+ FAIL_IF(push_inst(compiler, srag(tmp1, arg1, 63, 0)));
+ FAIL_IF(push_inst(compiler, ngr(tmp0, arg1)));
+ FAIL_IF(push_inst(compiler, ngr(tmp1, arg0)));
+
+ /* unsigned multiplication */
+ FAIL_IF(push_inst(compiler, mlgr(arg0, arg0)));
+
+ FAIL_IF(push_inst(compiler, sgr(arg0, tmp0)));
+ FAIL_IF(push_inst(compiler, sgr(arg0, tmp1)));
+ break;
+ case SLJIT_DIV_U32:
+ case SLJIT_DIVMOD_U32:
+ FAIL_IF(push_inst(compiler, lhi(tmp0, 0)));
+ FAIL_IF(push_inst(compiler, lr(tmp1, arg0)));
+ FAIL_IF(push_inst(compiler, dlr(tmp0, arg1)));
+ FAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */
+ if (op == SLJIT_DIVMOD_U32)
+ return push_inst(compiler, lr(arg1, tmp0)); /* remainder */
+
+ return SLJIT_SUCCESS;
+ case SLJIT_DIV_S32:
+ case SLJIT_DIVMOD_S32:
+ FAIL_IF(push_inst(compiler, lhi(tmp0, 0)));
+ FAIL_IF(push_inst(compiler, lr(tmp1, arg0)));
+ FAIL_IF(push_inst(compiler, dr(tmp0, arg1)));
+ FAIL_IF(push_inst(compiler, lr(arg0, tmp1))); /* quotient */
+ if (op == SLJIT_DIVMOD_S32)
+ return push_inst(compiler, lr(arg1, tmp0)); /* remainder */
+
+ return SLJIT_SUCCESS;
+ case SLJIT_DIV_UW:
+ case SLJIT_DIVMOD_UW:
+ FAIL_IF(push_inst(compiler, lghi(tmp0, 0)));
+ FAIL_IF(push_inst(compiler, lgr(tmp1, arg0)));
+ FAIL_IF(push_inst(compiler, dlgr(tmp0, arg1)));
+ FAIL_IF(push_inst(compiler, lgr(arg0, tmp1))); /* quotient */
+ if (op == SLJIT_DIVMOD_UW)
+ return push_inst(compiler, lgr(arg1, tmp0)); /* remainder */
+
+ return SLJIT_SUCCESS;
+ case SLJIT_DIV_SW:
+ case SLJIT_DIVMOD_SW:
+ FAIL_IF(push_inst(compiler, lgr(tmp1, arg0)));
+ FAIL_IF(push_inst(compiler, dsgr(tmp0, arg1)));
+ FAIL_IF(push_inst(compiler, lgr(arg0, tmp1))); /* quotient */
+ if (op == SLJIT_DIVMOD_SW)
+ return push_inst(compiler, lgr(arg1, tmp0)); /* remainder */
+
+ return SLJIT_SUCCESS;
+ case SLJIT_ENDBR:
+ return SLJIT_SUCCESS;
+ case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
+ return SLJIT_SUCCESS;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ /* swap result registers */
+ FAIL_IF(push_inst(compiler, lgr(tmp0, arg0)));
+ FAIL_IF(push_inst(compiler, lgr(arg0, arg1)));
+ return push_inst(compiler, lgr(arg1, tmp0));
+}
+
+/* LEVAL will be defined later with different parameters as needed */
+#define WHEN2(cond, i1, i2) (cond) ? LEVAL(i1) : LEVAL(i2)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_ins ins;
+ struct addr mem;
+ sljit_gpr dst_r;
+ sljit_gpr src_r;
+ sljit_s32 opcode = GET_OPCODE(op);
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if ((dst == SLJIT_UNUSED) && !HAS_FLAGS(op)) {
+ /* TODO(carenas): implement prefetch? */
+ return SLJIT_SUCCESS;
+ }
+ if (opcode >= SLJIT_MOV && opcode <= SLJIT_MOV_P) {
+ /* LOAD REGISTER */
+ if (FAST_IS_REG(dst) && FAST_IS_REG(src)) {
+ dst_r = gpr(dst);
+ src_r = gpr(src);
+ switch (opcode | (op & SLJIT_I32_OP)) {
+ /* 32-bit */
+ case SLJIT_MOV32_U8:
+ ins = llcr(dst_r, src_r);
+ break;
+ case SLJIT_MOV32_S8:
+ ins = lbr(dst_r, src_r);
+ break;
+ case SLJIT_MOV32_U16:
+ ins = llhr(dst_r, src_r);
+ break;
+ case SLJIT_MOV32_S16:
+ ins = lhr(dst_r, src_r);
+ break;
+ case SLJIT_MOV32:
+ ins = lr(dst_r, src_r);
+ break;
+ /* 64-bit */
+ case SLJIT_MOV_U8:
+ ins = llgcr(dst_r, src_r);
+ break;
+ case SLJIT_MOV_S8:
+ ins = lgbr(dst_r, src_r);
+ break;
+ case SLJIT_MOV_U16:
+ ins = llghr(dst_r, src_r);
+ break;
+ case SLJIT_MOV_S16:
+ ins = lghr(dst_r, src_r);
+ break;
+ case SLJIT_MOV_U32:
+ ins = llgfr(dst_r, src_r);
+ break;
+ case SLJIT_MOV_S32:
+ ins = lgfr(dst_r, src_r);
+ break;
+ case SLJIT_MOV:
+ case SLJIT_MOV_P:
+ ins = lgr(dst_r, src_r);
+ break;
+ default:
+ ins = 0;
+ SLJIT_UNREACHABLE();
+ }
+ FAIL_IF(push_inst(compiler, ins));
+ if (HAS_FLAGS(op)) {
+ /* only handle zero flag */
+ SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK));
+ return push_store_zero_flag(compiler, op, dst_r);
+ }
+ return SLJIT_SUCCESS;
+ }
+ /* LOAD IMMEDIATE */
+ if (FAST_IS_REG(dst) && (src & SLJIT_IMM)) {
+ switch (opcode) {
+ case SLJIT_MOV_U8:
+ srcw = (sljit_sw)((sljit_u8)(srcw));
+ break;
+ case SLJIT_MOV_S8:
+ srcw = (sljit_sw)((sljit_s8)(srcw));
+ break;
+ case SLJIT_MOV_U16:
+ srcw = (sljit_sw)((sljit_u16)(srcw));
+ break;
+ case SLJIT_MOV_S16:
+ srcw = (sljit_sw)((sljit_s16)(srcw));
+ break;
+ case SLJIT_MOV_U32:
+ srcw = (sljit_sw)((sljit_u32)(srcw));
+ break;
+ case SLJIT_MOV_S32:
+ srcw = (sljit_sw)((sljit_s32)(srcw));
+ break;
+ }
+ return push_load_imm_inst(compiler, gpr(dst), srcw);
+ }
+ /* LOAD */
+ /* TODO(carenas): avoid reg being defined later */
+ #define LEVAL(i) EVAL(i, reg, mem)
+ if (FAST_IS_REG(dst) && (src & SLJIT_MEM)) {
+ sljit_gpr reg = gpr(dst);
+
+ FAIL_IF(make_addr_bxy(compiler, &mem, src, srcw, tmp1));
+ /* TODO(carenas): convert all calls below to LEVAL */
+ switch (opcode | (op & SLJIT_I32_OP)) {
+ case SLJIT_MOV32_U8:
+ ins = llc(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV32_S8:
+ ins = lb(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV32_U16:
+ ins = llh(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV32_S16:
+ ins = WHEN2(is_u12(mem.offset), lh, lhy);
+ break;
+ case SLJIT_MOV32:
+ ins = WHEN2(is_u12(mem.offset), l, ly);
+ break;
+ case SLJIT_MOV_U8:
+ ins = LEVAL(llgc);
+ break;
+ case SLJIT_MOV_S8:
+ ins = lgb(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV_U16:
+ ins = LEVAL(llgh);
+ break;
+ case SLJIT_MOV_S16:
+ ins = lgh(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV_U32:
+ ins = LEVAL(llgf);
+ break;
+ case SLJIT_MOV_S32:
+ ins = lgf(reg, mem.offset, mem.index, mem.base);
+ break;
+ case SLJIT_MOV_P:
+ case SLJIT_MOV:
+ ins = lg(reg, mem.offset, mem.index, mem.base);
+ break;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ FAIL_IF(push_inst(compiler, ins));
+ if (HAS_FLAGS(op)) {
+ /* only handle zero flag */
+ SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK));
+ return push_store_zero_flag(compiler, op, reg);
+ }
+ return SLJIT_SUCCESS;
+ }
+ /* STORE and STORE IMMEDIATE */
+ if ((dst & SLJIT_MEM)
+ && (FAST_IS_REG(src) || (src & SLJIT_IMM))) {
+ sljit_gpr reg = FAST_IS_REG(src) ? gpr(src) : tmp0;
+ if (src & SLJIT_IMM) {
+ /* TODO(mundaym): MOVE IMMEDIATE? */
+ FAIL_IF(push_load_imm_inst(compiler, reg, srcw));
+ }
+ struct addr mem;
+ FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
+ switch (opcode) {
+ case SLJIT_MOV_U8:
+ case SLJIT_MOV_S8:
+ return push_inst(compiler,
+ WHEN2(is_u12(mem.offset), stc, stcy));
+ case SLJIT_MOV_U16:
+ case SLJIT_MOV_S16:
+ return push_inst(compiler,
+ WHEN2(is_u12(mem.offset), sth, sthy));
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ return push_inst(compiler,
+ WHEN2(is_u12(mem.offset), st, sty));
+ case SLJIT_MOV_P:
+ case SLJIT_MOV:
+ FAIL_IF(push_inst(compiler, LEVAL(stg)));
+ if (HAS_FLAGS(op)) {
+ /* only handle zero flag */
+ SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK));
+ return push_store_zero_flag(compiler, op, reg);
+ }
+ return SLJIT_SUCCESS;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ }
+ #undef LEVAL
+ /* MOVE CHARACTERS */
+ if ((dst & SLJIT_MEM) && (src & SLJIT_MEM)) {
+ struct addr mem;
+ FAIL_IF(make_addr_bxy(compiler, &mem, src, srcw, tmp1));
+ switch (opcode) {
+ case SLJIT_MOV_U8:
+ case SLJIT_MOV_S8:
+ FAIL_IF(push_inst(compiler,
+ EVAL(llgc, tmp0, mem)));
+ FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
+ return push_inst(compiler,
+ EVAL(stcy, tmp0, mem));
+ case SLJIT_MOV_U16:
+ case SLJIT_MOV_S16:
+ FAIL_IF(push_inst(compiler,
+ EVAL(llgh, tmp0, mem)));
+ FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
+ return push_inst(compiler,
+ EVAL(sthy, tmp0, mem));
+ case SLJIT_MOV_U32:
+ case SLJIT_MOV_S32:
+ FAIL_IF(push_inst(compiler,
+ EVAL(ly, tmp0, mem)));
+ FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
+ return push_inst(compiler,
+ EVAL(sty, tmp0, mem));
+ case SLJIT_MOV_P:
+ case SLJIT_MOV:
+ FAIL_IF(push_inst(compiler,
+ EVAL(lg, tmp0, mem)));
+ FAIL_IF(make_addr_bxy(compiler, &mem, dst, dstw, tmp1));
+ FAIL_IF(push_inst(compiler,
+ EVAL(stg, tmp0, mem)));
+ if (HAS_FLAGS(op)) {
+ /* only handle zero flag */
+ SLJIT_ASSERT(!(op & VARIABLE_FLAG_MASK));
+ return push_store_zero_flag(compiler, op, tmp0);
+ }
+ return SLJIT_SUCCESS;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ }
+ SLJIT_UNREACHABLE();
+ }
+
+ SLJIT_ASSERT((src & SLJIT_IMM) == 0); /* no immediates */
+
+ dst_r = SLOW_IS_REG(dst) ? gpr(REG_MASK & dst) : tmp0;
+ src_r = FAST_IS_REG(src) ? gpr(REG_MASK & src) : tmp0;
+ if (src & SLJIT_MEM)
+ FAIL_IF(load_word(compiler, src_r, src, srcw, tmp1, src & SLJIT_I32_OP));
+
+ /* TODO(mundaym): optimize loads and stores */
+ switch (opcode | (op & SLJIT_I32_OP)) {
+ case SLJIT_NOT:
+ /* emulate ~x with x^-1 */
+ FAIL_IF(push_load_imm_inst(compiler, tmp1, -1));
+ if (src_r != dst_r)
+ FAIL_IF(push_inst(compiler, lgr(dst_r, src_r)));
+
+ FAIL_IF(push_inst(compiler, xgr(dst_r, tmp1)));
+ break;
+ case SLJIT_NOT32:
+ /* emulate ~x with x^-1 */
+ if (have_eimm())
+ FAIL_IF(push_inst(compiler, xilf(dst_r, -1)));
+ else {
+ FAIL_IF(push_load_imm_inst(compiler, tmp1, -1));
+ if (src_r != dst_r)
+ FAIL_IF(push_inst(compiler, lr(dst_r, src_r)));
+
+ FAIL_IF(push_inst(compiler, xr(dst_r, tmp1)));
+ }
+ break;
+ case SLJIT_NEG:
+ FAIL_IF(push_inst(compiler, lcgr(dst_r, src_r)));
+ break;
+ case SLJIT_NEG32:
+ FAIL_IF(push_inst(compiler, lcr(dst_r, src_r)));
+ break;
+ case SLJIT_CLZ:
+ if (have_eimm()) {
+ FAIL_IF(push_inst(compiler, flogr(tmp0, src_r))); /* clobbers tmp1 */
+ if (dst_r != tmp0)
+ FAIL_IF(push_inst(compiler, lgr(dst_r, tmp0)));
+ } else {
+ abort(); /* TODO(mundaym): no eimm (?) */
+ }
+ break;
+ case SLJIT_CLZ32:
+ if (have_eimm()) {
+ FAIL_IF(push_inst(compiler, sllg(tmp1, src_r, 32, 0)));
+ FAIL_IF(push_inst(compiler, iilf(tmp1, 0xffffffff)));
+ FAIL_IF(push_inst(compiler, flogr(tmp0, tmp1))); /* clobbers tmp1 */
+ if (dst_r != tmp0)
+ FAIL_IF(push_inst(compiler, lr(dst_r, tmp0)));
+ } else {
+ abort(); /* TODO(mundaym): no eimm (?) */
+ }
+ break;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+
+ /* write condition code to emulated flag register */
+ if (op & VARIABLE_FLAG_MASK)
+ FAIL_IF(push_inst(compiler, ipm(flag_r)));
+
+ /* write zero flag to emulated flag register */
+ if (op & SLJIT_SET_Z)
+ FAIL_IF(push_store_zero_flag(compiler, op, dst_r));
+
+ /* TODO(carenas): doesn't need FAIL_IF */
+ if ((dst != SLJIT_UNUSED) && (dst & SLJIT_MEM))
+ FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP));
+
+ return SLJIT_SUCCESS;
+}
+
+static SLJIT_INLINE int is_commutative(sljit_s32 op)
+{
+ switch (GET_OPCODE(op)) {
+ case SLJIT_ADD:
+ case SLJIT_ADDC:
+ case SLJIT_MUL:
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ return 1;
+ }
+ return 0;
+}
+
+static SLJIT_INLINE int is_shift(sljit_s32 op) {
+ sljit_s32 v = GET_OPCODE(op);
+ return (v == SLJIT_SHL || v == SLJIT_ASHR || v == SLJIT_LSHR) ? 1 : 0;
+}
+
+static SLJIT_INLINE int sets_signed_flag(sljit_s32 op)
+{
+ switch (GET_FLAG_TYPE(op)) {
+ case SLJIT_OVERFLOW:
+ case SLJIT_NOT_OVERFLOW:
+ case SLJIT_SIG_LESS:
+ case SLJIT_SIG_LESS_EQUAL:
+ case SLJIT_SIG_GREATER:
+ case SLJIT_SIG_GREATER_EQUAL:
+ return 1;
+ }
+ return 0;
+}
+
+/* Report whether we have an instruction for:
+ op dst src imm
+ where dst and src are separate registers. */
+static int have_op_3_imm(sljit_s32 op, sljit_sw imm) {
+ return 0; /* TODO(mundaym): implement */
+}
+
+/* Report whether we have an instruction for:
+ op reg imm
+ where reg is both a source and the destination. */
+static int have_op_2_imm(sljit_s32 op, sljit_sw imm) {
+ switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) {
+ case SLJIT_ADD32:
+ case SLJIT_ADD:
+ if (!HAS_FLAGS(op) || sets_signed_flag(op))
+ return have_eimm() ? is_s32(imm) : is_s16(imm);
+
+ return have_eimm() && is_u32(imm);
+ case SLJIT_MUL32:
+ case SLJIT_MUL:
+ /* TODO(mundaym): general extension check */
+ /* for ms{,g}fi */
+ if (op & VARIABLE_FLAG_MASK)
+ return 0;
+
+ return have_genext() && is_s16(imm);
+ case SLJIT_OR32:
+ case SLJIT_XOR32:
+ case SLJIT_AND32:
+ /* only use if have extended immediate facility */
+ /* this ensures flags are set correctly */
+ return have_eimm();
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ /* TODO(mundaym): make this more flexible */
+ /* avoid using immediate variations, flags */
+ /* won't be set correctly */
+ return 0;
+ case SLJIT_ADDC32:
+ case SLJIT_ADDC:
+ /* no ADD LOGICAL WITH CARRY IMMEDIATE */
+ return 0;
+ case SLJIT_SUB:
+ case SLJIT_SUB32:
+ case SLJIT_SUBC:
+ case SLJIT_SUBC32:
+ /* no SUBTRACT IMMEDIATE */
+ /* TODO(mundaym): SUBTRACT LOGICAL IMMEDIATE */
+ return 0;
+ }
+ return 0;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ if (dst == SLJIT_UNUSED && !HAS_FLAGS(op))
+ return SLJIT_SUCCESS;
+
+ sljit_gpr dst_r = SLOW_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
+
+ if (is_commutative(op)) {
+ #define SWAP_ARGS \
+ do { \
+ sljit_s32 t = src1; \
+ sljit_sw tw = src1w; \
+ src1 = src2; \
+ src1w = src2w; \
+ src2 = t; \
+ src2w = tw; \
+ } while(0);
+
+ /* prefer immediate in src2 */
+ if (src1 & SLJIT_IMM) {
+ SWAP_ARGS
+ }
+
+ /* prefer to have src1 use same register as dst */
+ if (FAST_IS_REG(src2) && gpr(src2 & REG_MASK) == dst_r) {
+ SWAP_ARGS
+ }
+
+ /* prefer memory argument in src2 */
+ if (FAST_IS_REG(src2) && (src1 & SLJIT_MEM)) {
+ SWAP_ARGS
+ }
+ #undef SWAP_ARGS
+ }
+
+ /* src1 must be in a register */
+ sljit_gpr src1_r = FAST_IS_REG(src1) ? gpr(src1 & REG_MASK) : tmp0;
+ if (src1 & SLJIT_IMM)
+ FAIL_IF(push_load_imm_inst(compiler, src1_r, src1w));
+
+ if (src1 & SLJIT_MEM)
+ FAIL_IF(load_word(compiler, src1_r, src1, src1w, tmp1, op & SLJIT_I32_OP));
+
+ /* emit comparison before subtract */
+ if (GET_OPCODE(op) == SLJIT_SUB && (op & VARIABLE_FLAG_MASK)) {
+ sljit_sw cmp = 0;
+ switch (GET_FLAG_TYPE(op)) {
+ case SLJIT_LESS:
+ case SLJIT_LESS_EQUAL:
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_EQUAL:
+ cmp = 1; /* unsigned */
+ break;
+ case SLJIT_EQUAL:
+ case SLJIT_SIG_LESS:
+ case SLJIT_SIG_LESS_EQUAL:
+ case SLJIT_SIG_GREATER:
+ case SLJIT_SIG_GREATER_EQUAL:
+ cmp = -1; /* signed */
+ break;
+ }
+ if (cmp) {
+ /* clear flags - no need to generate now */
+ op &= ~VARIABLE_FLAG_MASK;
+ sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1;
+ if (src2 & SLJIT_IMM) {
+ #define LEVAL(i) i(src1_r, src2w)
+ if (cmp > 0 && is_u32(src2w)) {
+ /* unsigned */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, clfi, clgfi)));
+ }
+ else if (cmp < 0 && is_s16(src2w)) {
+ /* signed */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, chi, cghi)));
+ }
+ else if (cmp < 0 && is_s32(src2w)) {
+ /* signed */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, cfi, cgfi)));
+ }
+ #undef LEVAL
+ #define LEVAL(i) i(src1_r, src2_r)
+ else {
+ FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w));
+ if (cmp > 0) {
+ /* unsigned */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, clr, clgr)));
+ }
+ if (cmp < 0) {
+ /* signed */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, cr, cgr)));
+ }
+ }
+ }
+ else {
+ if (src2 & SLJIT_MEM) {
+ /* TODO(mundaym): comparisons with memory */
+ /* load src2 into register */
+ FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP));
+ }
+ if (cmp > 0) {
+ /* unsigned */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, clr, clgr)));
+ }
+ if (cmp < 0) {
+ /* signed */
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, cr, cgr)));
+ }
+ #undef LEVAL
+ }
+ FAIL_IF(push_inst(compiler, ipm(flag_r)));
+ }
+ }
+
+ if (!HAS_FLAGS(op) && dst == SLJIT_UNUSED)
+ return SLJIT_SUCCESS;
+
+ /* need to specify signed or logical operation */
+ int signed_flags = sets_signed_flag(op);
+
+ if (is_shift(op)) {
+ /* handle shifts first, they have more constraints than other operations */
+ sljit_sw d = 0;
+ sljit_gpr b = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : r0;
+ if (src2 & SLJIT_IMM)
+ d = src2w & ((op & SLJIT_I32_OP) ? 31 : 63);
+
+ if (src2 & SLJIT_MEM) {
+ /* shift amount (b) cannot be in r0 (i.e. tmp0) */
+ FAIL_IF(load_word(compiler, tmp1, src2, src2w, tmp1, op & SLJIT_I32_OP));
+ b = tmp1;
+ }
+ /* src1 and dst share the same register in the base 32-bit ISA */
+ /* TODO(mundaym): not needed when distinct-operand facility is available */
+ int workaround_alias = op & SLJIT_I32_OP && src1_r != dst_r;
+ if (workaround_alias) {
+ /* put src1 into tmp0 so we can overwrite it */
+ FAIL_IF(push_inst(compiler, lr(tmp0, src1_r)));
+ src1_r = tmp0;
+ }
+ switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) {
+ case SLJIT_SHL:
+ FAIL_IF(push_inst(compiler, sllg(dst_r, src1_r, d, b)));
+ break;
+ case SLJIT_SHL32:
+ FAIL_IF(push_inst(compiler, sll(src1_r, d, b)));
+ break;
+ case SLJIT_LSHR:
+ FAIL_IF(push_inst(compiler, srlg(dst_r, src1_r, d, b)));
+ break;
+ case SLJIT_LSHR32:
+ FAIL_IF(push_inst(compiler, srl(src1_r, d, b)));
+ break;
+ case SLJIT_ASHR:
+ FAIL_IF(push_inst(compiler, srag(dst_r, src1_r, d, b)));
+ break;
+ case SLJIT_ASHR32:
+ FAIL_IF(push_inst(compiler, sra(src1_r, d, b)));
+ break;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ if (workaround_alias && dst_r != src1_r)
+ FAIL_IF(push_inst(compiler, lr(dst_r, src1_r)));
+
+ }
+ else if ((GET_OPCODE(op) == SLJIT_MUL) && HAS_FLAGS(op)) {
+ /* multiply instructions do not generally set flags so we need to manually */
+ /* detect overflow conditions */
+ /* TODO(mundaym): 64-bit overflow */
+ SLJIT_ASSERT(GET_FLAG_TYPE(op) == SLJIT_MUL_OVERFLOW ||
+ GET_FLAG_TYPE(op) == SLJIT_MUL_NOT_OVERFLOW);
+ sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1;
+ if (src2 & SLJIT_IMM) {
+ /* load src2 into register */
+ FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w));
+ }
+ if (src2 & SLJIT_MEM) {
+ /* load src2 into register */
+ FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP));
+ }
+ if (have_misc2()) {
+ #define LEVAL(i) i(dst_r, src1_r, src2_r)
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, msrkc, msgrkc)));
+ #undef LEVAL
+ }
+ else if (op & SLJIT_I32_OP) {
+ op &= ~VARIABLE_FLAG_MASK;
+ FAIL_IF(push_inst(compiler, lgfr(tmp0, src1_r)));
+ FAIL_IF(push_inst(compiler, msgfr(tmp0, src2_r)));
+ if (dst_r != tmp0) {
+ FAIL_IF(push_inst(compiler, lr(dst_r, tmp0)));
+ }
+ FAIL_IF(push_inst(compiler, aih(tmp0, 1)));
+ FAIL_IF(push_inst(compiler, nihf(tmp0, ~1U)));
+ FAIL_IF(push_inst(compiler, ipm(flag_r)));
+ FAIL_IF(push_inst(compiler, oilh(flag_r, 0x2000)));
+ }
+ else
+ return SLJIT_ERR_UNSUPPORTED;
+
+ }
+ else if ((GET_OPCODE(op) == SLJIT_SUB) && (op & SLJIT_SET_Z) && !signed_flags) {
+ /* subtract logical instructions do not set the right flags unfortunately */
+ /* instead, negate src2 and issue an add logical */
+ /* TODO(mundaym): distinct operand facility where needed */
+ if (src1_r != dst_r && src1_r != tmp0) {
+ #define LEVAL(i) i(tmp0, src1_r)
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, lr, lgr)));
+ src1_r = tmp0;
+ #undef LEVAL
+ }
+ sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1;
+ if (src2 & SLJIT_IMM) {
+ /* load src2 into register */
+ FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w));
+ }
+ if (src2 & SLJIT_MEM) {
+ /* load src2 into register */
+ FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP));
+ }
+ if (op & SLJIT_I32_OP) {
+ FAIL_IF(push_inst(compiler, lcr(tmp1, src2_r)));
+ FAIL_IF(push_inst(compiler, alr(src1_r, tmp1)));
+ if (src1_r != dst_r)
+ FAIL_IF(push_inst(compiler, lr(dst_r, src1_r)));
+ }
+ else {
+ FAIL_IF(push_inst(compiler, lcgr(tmp1, src2_r)));
+ FAIL_IF(push_inst(compiler, algr(src1_r, tmp1)));
+ if (src1_r != dst_r)
+ FAIL_IF(push_inst(compiler, lgr(dst_r, src1_r)));
+ }
+ }
+ else if ((src2 & SLJIT_IMM) && (src1_r == dst_r) && have_op_2_imm(op, src2w)) {
+ switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) {
+ #define LEVAL(i) i(dst_r, src2w)
+ case SLJIT_ADD:
+ if (!HAS_FLAGS(op) || signed_flags) {
+ FAIL_IF(push_inst(compiler,
+ WHEN2(is_s16(src2w), aghi, agfi)));
+ }
+ else
+ FAIL_IF(push_inst(compiler, LEVAL(algfi)));
+
+ break;
+ case SLJIT_ADD32:
+ if (!HAS_FLAGS(op) || signed_flags)
+ FAIL_IF(push_inst(compiler,
+ WHEN2(is_s16(src2w), ahi, afi)));
+ else
+ FAIL_IF(push_inst(compiler, LEVAL(alfi)));
+
+ break;
+ #undef LEVAL /* TODO(carenas): move down and refactor? */
+ case SLJIT_MUL:
+ FAIL_IF(push_inst(compiler, mhi(dst_r, src2w)));
+ break;
+ case SLJIT_MUL32:
+ FAIL_IF(push_inst(compiler, mghi(dst_r, src2w)));
+ break;
+ case SLJIT_OR32:
+ FAIL_IF(push_inst(compiler, oilf(dst_r, src2w)));
+ break;
+ case SLJIT_XOR32:
+ FAIL_IF(push_inst(compiler, xilf(dst_r, src2w)));
+ break;
+ case SLJIT_AND32:
+ FAIL_IF(push_inst(compiler, nilf(dst_r, src2w)));
+ break;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ }
+ else if ((src2 & SLJIT_IMM) && have_op_3_imm(op, src2w)) {
+ abort(); /* TODO(mundaym): implement */
+ }
+ else if ((src2 & SLJIT_MEM) && (dst_r == src1_r)) {
+ /* most 32-bit instructions can only handle 12-bit immediate offsets */
+ int need_u12 = !have_ldisp() &&
+ (op & SLJIT_I32_OP) &&
+ (GET_OPCODE(op) != SLJIT_ADDC) &&
+ (GET_OPCODE(op) != SLJIT_SUBC);
+ struct addr mem;
+ if (need_u12)
+ FAIL_IF(make_addr_bx(compiler, &mem, src2, src2w, tmp1));
+ else
+ FAIL_IF(make_addr_bxy(compiler, &mem, src2, src2w, tmp1));
+
+ int can_u12 = is_u12(mem.offset) ? 1 : 0;
+ sljit_ins ins = 0;
+ switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) {
+ /* 64-bit ops */
+ #define LEVAL(i) EVAL(i, dst_r, mem)
+ case SLJIT_ADD:
+ ins = WHEN2(signed_flags, ag, alg);
+ break;
+ case SLJIT_SUB:
+ ins = WHEN2(signed_flags, sg, slg);
+ break;
+ case SLJIT_ADDC:
+ ins = LEVAL(alcg);
+ break;
+ case SLJIT_SUBC:
+ ins = LEVAL(slbg);
+ break;
+ case SLJIT_MUL:
+ ins = LEVAL(msg);
+ break;
+ case SLJIT_OR:
+ ins = LEVAL(og);
+ break;
+ case SLJIT_XOR:
+ ins = LEVAL(xg);
+ break;
+ case SLJIT_AND:
+ ins = LEVAL(ng);
+ break;
+ /* 32-bit ops */
+ case SLJIT_ADD32:
+ if (signed_flags)
+ ins = WHEN2(can_u12, a, ay);
+ else
+ ins = WHEN2(can_u12, al, aly);
+ break;
+ case SLJIT_SUB32:
+ if (signed_flags)
+ ins = WHEN2(can_u12, s, sy);
+ else
+ ins = WHEN2(can_u12, sl, sly);
+ break;
+ case SLJIT_ADDC32:
+ ins = LEVAL(alc);
+ break;
+ case SLJIT_SUBC32:
+ ins = LEVAL(slb);
+ break;
+ case SLJIT_MUL32:
+ ins = WHEN2(can_u12, ms, msy);
+ break;
+ case SLJIT_OR32:
+ ins = WHEN2(can_u12, o, oy);
+ break;
+ case SLJIT_XOR32:
+ ins = WHEN2(can_u12, x, xy);
+ break;
+ case SLJIT_AND32:
+ ins = WHEN2(can_u12, n, ny);
+ break;
+ #undef LEVAL
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ FAIL_IF(push_inst(compiler, ins));
+ }
+ else {
+ sljit_gpr src2_r = FAST_IS_REG(src2) ? gpr(src2 & REG_MASK) : tmp1;
+ if (src2 & SLJIT_IMM) {
+ /* load src2 into register */
+ FAIL_IF(push_load_imm_inst(compiler, src2_r, src2w));
+ }
+ if (src2 & SLJIT_MEM) {
+ /* load src2 into register */
+ FAIL_IF(load_word(compiler, src2_r, src2, src2w, tmp1, op & SLJIT_I32_OP));
+ }
+ /* TODO(mundaym): distinct operand facility where needed */
+ #define LEVAL(i) i(tmp0, src1_r)
+ if (src1_r != dst_r && src1_r != tmp0) {
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, lr, lgr)));
+ src1_r = tmp0;
+ }
+ #undef LEVAL
+ sljit_ins ins = 0;
+ switch (GET_OPCODE(op) | (op & SLJIT_I32_OP)) {
+ #define LEVAL(i) i(src1_r, src2_r)
+ /* 64-bit ops */
+ case SLJIT_ADD:
+ ins = WHEN2(signed_flags, agr, algr);
+ break;
+ case SLJIT_SUB:
+ ins = WHEN2(signed_flags, sgr, slgr);
+ break;
+ case SLJIT_ADDC:
+ ins = LEVAL(alcgr);
+ break;
+ case SLJIT_SUBC:
+ ins = LEVAL(slbgr);
+ break;
+ case SLJIT_MUL:
+ ins = LEVAL(msgr);
+ break;
+ case SLJIT_AND:
+ ins = LEVAL(ngr);
+ break;
+ case SLJIT_OR:
+ ins = LEVAL(ogr);
+ break;
+ case SLJIT_XOR:
+ ins = LEVAL(xgr);
+ break;
+ /* 32-bit ops */
+ case SLJIT_ADD32:
+ ins = WHEN2(signed_flags, ar, alr);
+ break;
+ case SLJIT_SUB32:
+ ins = WHEN2(signed_flags, sr, slr);
+ break;
+ case SLJIT_ADDC32:
+ ins = LEVAL(alcr);
+ break;
+ case SLJIT_SUBC32:
+ ins = LEVAL(slbr);
+ break;
+ case SLJIT_MUL32:
+ ins = LEVAL(msr);
+ break;
+ case SLJIT_AND32:
+ ins = LEVAL(nr);
+ break;
+ case SLJIT_OR32:
+ ins = LEVAL(or);
+ break;
+ case SLJIT_XOR32:
+ ins = LEVAL(xr);
+ break;
+ #undef LEVAL
+ default:
+ SLJIT_UNREACHABLE();
+ }
+ FAIL_IF(push_inst(compiler, ins));
+ #define LEVAL(i) i(dst_r, src1_r)
+ if (src1_r != dst_r)
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, lr, lgr)));
+ #undef LEVAL
+ }
+
+ /* write condition code to emulated flag register */
+ if (op & VARIABLE_FLAG_MASK)
+ FAIL_IF(push_inst(compiler, ipm(flag_r)));
+
+ /* write zero flag to emulated flag register */
+ if (op & SLJIT_SET_Z)
+ FAIL_IF(push_store_zero_flag(compiler, op, dst_r));
+
+ /* finally write the result to memory if required */
+ if (dst & SLJIT_MEM) {
+ SLJIT_ASSERT(dst_r != tmp1);
+ /* TODO(carenas): s/FAIL_IF/ return */
+ FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP));
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(
+ struct sljit_compiler *compiler,
+ sljit_s32 op, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_gpr src_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ switch (op) {
+ case SLJIT_FAST_RETURN:
+ src_r = FAST_IS_REG(src) ? gpr(src) : tmp1;
+ if (src & SLJIT_MEM)
+ FAIL_IF(load_word(compiler, tmp1, src, srcw, tmp1, 0));
+
+ return push_inst(compiler, br(src_r));
+ case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
+ /* TODO(carenas): implement? */
+ return SLJIT_SUCCESS;
+ case SLJIT_PREFETCH_L1:
+ case SLJIT_PREFETCH_L2:
+ case SLJIT_PREFETCH_L3:
+ case SLJIT_PREFETCH_ONCE:
+ /* TODO(carenas): implement */
+ return SLJIT_SUCCESS;
+ default:
+ /* TODO(carenas): probably should not success by default */
+ return SLJIT_SUCCESS;
+ }
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_register_index(reg));
+ return gpr(reg);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
+{
+ CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
+ abort();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
+ void *instruction, sljit_s32 size)
+{
+ sljit_ins ins = 0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
+
+ memcpy((sljit_u8 *)&ins + sizeof(ins) - size, instruction, size);
+ return push_inst(compiler, ins);
+}
+
+/* --------------------------------------------------------------------- */
+/* Floating point operators */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ abort();
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ CHECK_ERROR();
+ abort();
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ if (FAST_IS_REG(dst))
+ return push_inst(compiler, lgr(gpr(dst), fast_link_r));
+
+ /* memory */
+ return store_word(compiler, fast_link_r, dst, dstw, tmp1, 0);
+}
+
+/* --------------------------------------------------------------------- */
+/* Conditional instructions */
+/* --------------------------------------------------------------------- */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler)
+{
+ struct sljit_label *label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_label(compiler));
+
+ if (compiler->last_label && compiler->last_label->size == compiler->size)
+ return compiler->last_label;
+
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ PTR_FAIL_IF(!label);
+ set_label(label, compiler);
+ return label;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
+{
+ sljit_u8 mask = ((type & 0xff) < SLJIT_JUMP) ? get_cc(type & 0xff) : 0xf;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_jump(compiler, type));
+
+ /* reload condition code */
+ if (mask != 0xf)
+ PTR_FAIL_IF(push_load_cc(compiler, type & 0xff));
+
+ /* record jump */
+ struct sljit_jump *jump = (struct sljit_jump *)
+ ensure_abuf(compiler, sizeof(struct sljit_jump));
+ PTR_FAIL_IF(!jump);
+ set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ jump->addr = compiler->size;
+
+ /* emit jump instruction */
+ type &= 0xff;
+ if (type >= SLJIT_FAST_CALL)
+ PTR_FAIL_IF(push_inst(compiler, brasl(type == SLJIT_FAST_CALL ? fast_link_r : link_r, 0)));
+ else
+ PTR_FAIL_IF(push_inst(compiler, brcl(mask, 0)));
+
+ return jump;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 arg_types)
+{
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+
+ return sljit_emit_jump(compiler, type);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
+{
+ sljit_gpr src_r = FAST_IS_REG(src) ? gpr(src) : tmp1;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
+ ADJUST_LOCAL_OFFSET(src, srcw);
+
+ if (src & SLJIT_IMM) {
+ SLJIT_ASSERT(!(srcw & 1)); /* target address must be even */
+ FAIL_IF(push_load_imm_inst(compiler, src_r, srcw));
+ }
+ else if (src & SLJIT_MEM)
+ FAIL_IF(load_word(compiler, src_r, src, srcw, tmp1, 0 /* 64-bit */));
+
+ /* emit jump instruction */
+ if (type >= SLJIT_FAST_CALL)
+ return push_inst(compiler, basr(type == SLJIT_FAST_CALL ? fast_link_r : link_r, src_r));
+
+ return push_inst(compiler, br(src_r));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 arg_types,
+ sljit_s32 src, sljit_sw srcw)
+{
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
+ || (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ compiler->skip_checks = 1;
+#endif
+
+ return sljit_emit_ijump(compiler, type, src, srcw);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 type)
+{
+ sljit_u8 mask = get_cc(type & 0xff);
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, type));
+
+ sljit_gpr dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
+ sljit_gpr loc_r = tmp1;
+ switch (GET_OPCODE(op)) {
+ case SLJIT_AND:
+ case SLJIT_OR:
+ case SLJIT_XOR:
+ /* dst is also source operand */
+ if (dst & SLJIT_MEM)
+ FAIL_IF(load_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP));
+
+ break;
+ case SLJIT_MOV:
+ case (SLJIT_MOV32 & ~SLJIT_I32_OP):
+ /* can write straight into destination */
+ loc_r = dst_r;
+ break;
+ default:
+ SLJIT_UNREACHABLE();
+ }
+
+ if (mask != 0xf)
+ FAIL_IF(push_load_cc(compiler, type & 0xff));
+
+ /* TODO(mundaym): fold into cmov helper function? */
+ #define LEVAL(i) i(loc_r, 1, mask)
+ if (have_lscond2()) {
+ FAIL_IF(push_load_imm_inst(compiler, loc_r, 0));
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, lochi, locghi)));
+ } else {
+ /* TODO(mundaym): no load/store-on-condition 2 facility (ipm? branch-and-set?) */
+ abort();
+ }
+ #undef LEVAL
+
+ /* apply bitwise op and set condition codes */
+ switch (GET_OPCODE(op)) {
+ #define LEVAL(i) i(dst_r, loc_r)
+ case SLJIT_AND:
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, nr, ngr)));
+ break;
+ case SLJIT_OR:
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, or, ogr)));
+ break;
+ case SLJIT_XOR:
+ FAIL_IF(push_inst(compiler,
+ WHEN2(op & SLJIT_I32_OP, xr, xgr)));
+ break;
+ #undef LEVAL
+ }
+
+ /* set zero flag if needed */
+ if (op & SLJIT_SET_Z)
+ FAIL_IF(push_store_zero_flag(compiler, op, dst_r));
+
+ /* store result to memory if required */
+ /* TODO(carenas): s/FAIL_IF/ return */
+ if (dst & SLJIT_MEM)
+ FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, op & SLJIT_I32_OP));
+
+ return SLJIT_SUCCESS;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compiler, sljit_s32 type,
+ sljit_s32 dst_reg,
+ sljit_s32 src, sljit_sw srcw)
+{
+ sljit_u8 mask = get_cc(type & 0xff);
+ sljit_gpr dst_r = gpr(dst_reg & ~SLJIT_I32_OP);
+ sljit_gpr src_r = FAST_IS_REG(src) ? gpr(src) : tmp0;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_cmov(compiler, type, dst_reg, src, srcw));
+
+ if (mask != 0xf)
+ FAIL_IF(push_load_cc(compiler, type & 0xff));
+
+ if (src & SLJIT_IMM) {
+ /* TODO(mundaym): fast path with lscond2 */
+ FAIL_IF(push_load_imm_inst(compiler, src_r, srcw));
+ }
+
+ #define LEVAL(i) i(dst_r, src_r, mask)
+ if (have_lscond1())
+ return push_inst(compiler,
+ WHEN2(dst_reg & SLJIT_I32_OP, locr, locgr));
+
+ #undef LEVAL
+
+ /* TODO(mundaym): implement */
+ return SLJIT_ERR_UNSUPPORTED;
+}
+
+/* --------------------------------------------------------------------- */
+/* Other instructions */
+/* --------------------------------------------------------------------- */
+
+/* On s390x we build a literal pool to hold constants. This has two main
+ advantages:
+
+ 1. we only need one instruction in the instruction stream (LGRL)
+ 2. we can store 64 bit addresses and use 32 bit offsets
+
+ To retrofit the extra information needed to build the literal pool we
+ add a new sljit_s390x_const struct that contains the initial value but
+ can still be cast to a sljit_const. */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+{
+ struct sljit_s390x_const *const_;
+ sljit_gpr dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+
+ const_ = (struct sljit_s390x_const*)ensure_abuf(compiler,
+ sizeof(struct sljit_s390x_const));
+ PTR_FAIL_IF(!const_);
+ set_const((struct sljit_const*)const_, compiler);
+ const_->init_value = init_value;
+
+ 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)));
+ else {
+ PTR_FAIL_IF(push_inst(compiler, sljit_ins_const | larl(tmp1, 0)));
+ PTR_FAIL_IF(push_inst(compiler, lg(dst_r, 0, r0, tmp1)));
+ }
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, 0 /* always 64-bit */));
+
+ return (struct sljit_const*)const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
+{
+ /* Update the constant pool. */
+ sljit_uw *ptr = (sljit_uw *)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 0);
+ *ptr = new_target;
+ SLJIT_UPDATE_WX_FLAGS(ptr, ptr + 1, 1);
+ SLJIT_CACHE_FLUSH(ptr, ptr + 1);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ sljit_set_jump_addr(addr, 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)
+{
+ struct sljit_put_label *put_label;
+ sljit_gpr dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_put_label(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);
+
+ dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
+
+ if (have_genext())
+ PTR_FAIL_IF(push_inst(compiler, lgrl(dst_r, 0)));
+ else {
+ PTR_FAIL_IF(push_inst(compiler, larl(tmp1, 0)));
+ PTR_FAIL_IF(push_inst(compiler, lg(dst_r, 0, r0, tmp1)));
+ }
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, tmp1, 0));
+
+ return put_label;
+}
+
+/* TODO(carenas): EVAL probably should move up or be refactored */
+#undef WHEN2
+#undef EVAL
+
+#undef tmp1
+#undef tmp0
+
+/* TODO(carenas): undef other macros that spill like is_u12? */
diff --git a/src/sljit/sljitNativeSPARC_32.c b/src/sljit/sljitNativeSPARC_32.c
index 8079fad..e5167f0 100644
--- a/src/sljit/sljitNativeSPARC_32.c
+++ b/src/sljit/sljitNativeSPARC_32.c
@@ -266,21 +266,18 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000));
inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff);
inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins *)addr;
-
- SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000));
- inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff);
- inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 2);
+ sljit_set_jump_addr(addr, new_constant, executable_offset);
}
diff --git a/src/sljit/sljitNativeSPARC_common.c b/src/sljit/sljitNativeSPARC_common.c
index 7d6be6c..544d80d 100644
--- a/src/sljit/sljitNativeSPARC_common.c
+++ b/src/sljit/sljitNativeSPARC_common.c
@@ -311,7 +311,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
CHECK_PTR(check_sljit_generate_code(compiler));
reverse_buf(compiler);
- code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
+ code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins), compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -437,6 +437,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
SLJIT_CACHE_FLUSH(code, code_ptr);
+ SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
return code;
}
diff --git a/src/sljit/sljitNativeTILEGX-encoder.c b/src/sljit/sljitNativeTILEGX-encoder.c
deleted file mode 100644
index dd82eba..0000000
--- a/src/sljit/sljitNativeTILEGX-encoder.c
+++ /dev/null
@@ -1,10159 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved.
- * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
- * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* This code is owned by Tilera Corporation, and distributed as part
- of multiple projects. In sljit, the code is under BSD licence. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#define BFD_RELOC(x) R_##x
-
-/* Special registers. */
-#define TREG_LR 55
-#define TREG_SN 56
-#define TREG_ZERO 63
-
-/* Canonical name of each register. */
-const char *const tilegx_register_names[] =
-{
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
- "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
- "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
- "r48", "r49", "r50", "r51", "r52", "tp", "sp", "lr",
- "sn", "idn0", "idn1", "udn0", "udn1", "udn2", "udn3", "zero"
-};
-
-enum
-{
- R_NONE = 0,
- R_TILEGX_NONE = 0,
- R_TILEGX_64 = 1,
- R_TILEGX_32 = 2,
- R_TILEGX_16 = 3,
- R_TILEGX_8 = 4,
- R_TILEGX_64_PCREL = 5,
- R_TILEGX_32_PCREL = 6,
- R_TILEGX_16_PCREL = 7,
- R_TILEGX_8_PCREL = 8,
- R_TILEGX_HW0 = 9,
- R_TILEGX_HW1 = 10,
- R_TILEGX_HW2 = 11,
- R_TILEGX_HW3 = 12,
- R_TILEGX_HW0_LAST = 13,
- R_TILEGX_HW1_LAST = 14,
- R_TILEGX_HW2_LAST = 15,
- R_TILEGX_COPY = 16,
- R_TILEGX_GLOB_DAT = 17,
- R_TILEGX_JMP_SLOT = 18,
- R_TILEGX_RELATIVE = 19,
- R_TILEGX_BROFF_X1 = 20,
- R_TILEGX_JUMPOFF_X1 = 21,
- R_TILEGX_JUMPOFF_X1_PLT = 22,
- R_TILEGX_IMM8_X0 = 23,
- R_TILEGX_IMM8_Y0 = 24,
- R_TILEGX_IMM8_X1 = 25,
- R_TILEGX_IMM8_Y1 = 26,
- R_TILEGX_DEST_IMM8_X1 = 27,
- R_TILEGX_MT_IMM14_X1 = 28,
- R_TILEGX_MF_IMM14_X1 = 29,
- R_TILEGX_MMSTART_X0 = 30,
- R_TILEGX_MMEND_X0 = 31,
- R_TILEGX_SHAMT_X0 = 32,
- R_TILEGX_SHAMT_X1 = 33,
- R_TILEGX_SHAMT_Y0 = 34,
- R_TILEGX_SHAMT_Y1 = 35,
- R_TILEGX_IMM16_X0_HW0 = 36,
- R_TILEGX_IMM16_X1_HW0 = 37,
- R_TILEGX_IMM16_X0_HW1 = 38,
- R_TILEGX_IMM16_X1_HW1 = 39,
- R_TILEGX_IMM16_X0_HW2 = 40,
- R_TILEGX_IMM16_X1_HW2 = 41,
- R_TILEGX_IMM16_X0_HW3 = 42,
- R_TILEGX_IMM16_X1_HW3 = 43,
- R_TILEGX_IMM16_X0_HW0_LAST = 44,
- R_TILEGX_IMM16_X1_HW0_LAST = 45,
- R_TILEGX_IMM16_X0_HW1_LAST = 46,
- R_TILEGX_IMM16_X1_HW1_LAST = 47,
- R_TILEGX_IMM16_X0_HW2_LAST = 48,
- R_TILEGX_IMM16_X1_HW2_LAST = 49,
- R_TILEGX_IMM16_X0_HW0_PCREL = 50,
- R_TILEGX_IMM16_X1_HW0_PCREL = 51,
- R_TILEGX_IMM16_X0_HW1_PCREL = 52,
- R_TILEGX_IMM16_X1_HW1_PCREL = 53,
- R_TILEGX_IMM16_X0_HW2_PCREL = 54,
- R_TILEGX_IMM16_X1_HW2_PCREL = 55,
- R_TILEGX_IMM16_X0_HW3_PCREL = 56,
- R_TILEGX_IMM16_X1_HW3_PCREL = 57,
- R_TILEGX_IMM16_X0_HW0_LAST_PCREL = 58,
- R_TILEGX_IMM16_X1_HW0_LAST_PCREL = 59,
- R_TILEGX_IMM16_X0_HW1_LAST_PCREL = 60,
- R_TILEGX_IMM16_X1_HW1_LAST_PCREL = 61,
- R_TILEGX_IMM16_X0_HW2_LAST_PCREL = 62,
- R_TILEGX_IMM16_X1_HW2_LAST_PCREL = 63,
- R_TILEGX_IMM16_X0_HW0_GOT = 64,
- R_TILEGX_IMM16_X1_HW0_GOT = 65,
-
- R_TILEGX_IMM16_X0_HW0_PLT_PCREL = 66,
- R_TILEGX_IMM16_X1_HW0_PLT_PCREL = 67,
- R_TILEGX_IMM16_X0_HW1_PLT_PCREL = 68,
- R_TILEGX_IMM16_X1_HW1_PLT_PCREL = 69,
- R_TILEGX_IMM16_X0_HW2_PLT_PCREL = 70,
- R_TILEGX_IMM16_X1_HW2_PLT_PCREL = 71,
-
- R_TILEGX_IMM16_X0_HW0_LAST_GOT = 72,
- R_TILEGX_IMM16_X1_HW0_LAST_GOT = 73,
- R_TILEGX_IMM16_X0_HW1_LAST_GOT = 74,
- R_TILEGX_IMM16_X1_HW1_LAST_GOT = 75,
- R_TILEGX_IMM16_X0_HW0_TLS_GD = 78,
- R_TILEGX_IMM16_X1_HW0_TLS_GD = 79,
- R_TILEGX_IMM16_X0_HW0_TLS_LE = 80,
- R_TILEGX_IMM16_X1_HW0_TLS_LE = 81,
- R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE = 82,
- R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE = 83,
- R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE = 84,
- R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE = 85,
- R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD = 86,
- R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD = 87,
- R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD = 88,
- R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD = 89,
- R_TILEGX_IMM16_X0_HW0_TLS_IE = 92,
- R_TILEGX_IMM16_X1_HW0_TLS_IE = 93,
-
- R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL = 94,
- R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL = 95,
- R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL = 96,
- R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL = 97,
- R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL = 98,
- R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL = 99,
-
- R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE = 100,
- R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE = 101,
- R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE = 102,
- R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE = 103,
- R_TILEGX_TLS_DTPMOD64 = 106,
- R_TILEGX_TLS_DTPOFF64 = 107,
- R_TILEGX_TLS_TPOFF64 = 108,
- R_TILEGX_TLS_DTPMOD32 = 109,
- R_TILEGX_TLS_DTPOFF32 = 110,
- R_TILEGX_TLS_TPOFF32 = 111,
- R_TILEGX_TLS_GD_CALL = 112,
- R_TILEGX_IMM8_X0_TLS_GD_ADD = 113,
- R_TILEGX_IMM8_X1_TLS_GD_ADD = 114,
- R_TILEGX_IMM8_Y0_TLS_GD_ADD = 115,
- R_TILEGX_IMM8_Y1_TLS_GD_ADD = 116,
- R_TILEGX_TLS_IE_LOAD = 117,
- R_TILEGX_IMM8_X0_TLS_ADD = 118,
- R_TILEGX_IMM8_X1_TLS_ADD = 119,
- R_TILEGX_IMM8_Y0_TLS_ADD = 120,
- R_TILEGX_IMM8_Y1_TLS_ADD = 121,
- R_TILEGX_GNU_VTINHERIT = 128,
- R_TILEGX_GNU_VTENTRY = 129,
- R_TILEGX_IRELATIVE = 130,
- R_TILEGX_NUM = 131
-};
-
-typedef enum
-{
- TILEGX_PIPELINE_X0,
- TILEGX_PIPELINE_X1,
- TILEGX_PIPELINE_Y0,
- TILEGX_PIPELINE_Y1,
- TILEGX_PIPELINE_Y2,
-} tilegx_pipeline;
-
-typedef unsigned long long tilegx_bundle_bits;
-
-/* These are the bits that determine if a bundle is in the X encoding. */
-#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62)
-
-enum
-{
- /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
- TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
-
- /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
- TILEGX_NUM_PIPELINE_ENCODINGS = 5,
-
- /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */
- TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
-
- /* Instructions take this many bytes. */
- TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES,
-
- /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */
- TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
-
- /* Bundles should be aligned modulo this number of bytes. */
- TILEGX_BUNDLE_ALIGNMENT_IN_BYTES =
- (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
-
- /* Number of registers (some are magic, such as network I/O). */
- TILEGX_NUM_REGISTERS = 64,
-};
-
-/* Make a few "tile_" variables to simplify common code between
- architectures. */
-
-typedef tilegx_bundle_bits tile_bundle_bits;
-#define TILE_BUNDLE_SIZE_IN_BYTES TILEGX_BUNDLE_SIZE_IN_BYTES
-#define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
-#define TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES \
- TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES
-
-/* 64-bit pattern for a { bpt ; nop } bundle. */
-#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
-
-typedef enum
-{
- TILEGX_OP_TYPE_REGISTER,
- TILEGX_OP_TYPE_IMMEDIATE,
- TILEGX_OP_TYPE_ADDRESS,
- TILEGX_OP_TYPE_SPR
-} tilegx_operand_type;
-
-struct tilegx_operand
-{
- /* Is this operand a register, immediate or address? */
- tilegx_operand_type type;
-
- /* The default relocation type for this operand. */
- signed int default_reloc : 16;
-
- /* How many bits is this value? (used for range checking) */
- unsigned int num_bits : 5;
-
- /* Is the value signed? (used for range checking) */
- unsigned int is_signed : 1;
-
- /* Is this operand a source register? */
- unsigned int is_src_reg : 1;
-
- /* Is this operand written? (i.e. is it a destination register) */
- unsigned int is_dest_reg : 1;
-
- /* Is this operand PC-relative? */
- unsigned int is_pc_relative : 1;
-
- /* By how many bits do we right shift the value before inserting? */
- unsigned int rightshift : 2;
-
- /* Return the bits for this operand to be ORed into an existing bundle. */
- tilegx_bundle_bits (*insert) (int op);
-
- /* Extract this operand and return it. */
- unsigned int (*extract) (tilegx_bundle_bits bundle);
-};
-
-typedef enum
-{
- TILEGX_OPC_BPT,
- TILEGX_OPC_INFO,
- TILEGX_OPC_INFOL,
- TILEGX_OPC_LD4S_TLS,
- TILEGX_OPC_LD_TLS,
- TILEGX_OPC_MOVE,
- TILEGX_OPC_MOVEI,
- TILEGX_OPC_MOVELI,
- TILEGX_OPC_PREFETCH,
- TILEGX_OPC_PREFETCH_ADD_L1,
- TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L2,
- TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L3,
- TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- TILEGX_OPC_PREFETCH_L1,
- TILEGX_OPC_PREFETCH_L1_FAULT,
- TILEGX_OPC_PREFETCH_L2,
- TILEGX_OPC_PREFETCH_L2_FAULT,
- TILEGX_OPC_PREFETCH_L3,
- TILEGX_OPC_PREFETCH_L3_FAULT,
- TILEGX_OPC_RAISE,
- TILEGX_OPC_ADD,
- TILEGX_OPC_ADDI,
- TILEGX_OPC_ADDLI,
- TILEGX_OPC_ADDX,
- TILEGX_OPC_ADDXI,
- TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXSC,
- TILEGX_OPC_AND,
- TILEGX_OPC_ANDI,
- TILEGX_OPC_BEQZ,
- TILEGX_OPC_BEQZT,
- TILEGX_OPC_BFEXTS,
- TILEGX_OPC_BFEXTU,
- TILEGX_OPC_BFINS,
- TILEGX_OPC_BGEZ,
- TILEGX_OPC_BGEZT,
- TILEGX_OPC_BGTZ,
- TILEGX_OPC_BGTZT,
- TILEGX_OPC_BLBC,
- TILEGX_OPC_BLBCT,
- TILEGX_OPC_BLBS,
- TILEGX_OPC_BLBST,
- TILEGX_OPC_BLEZ,
- TILEGX_OPC_BLEZT,
- TILEGX_OPC_BLTZ,
- TILEGX_OPC_BLTZT,
- TILEGX_OPC_BNEZ,
- TILEGX_OPC_BNEZT,
- TILEGX_OPC_CLZ,
- TILEGX_OPC_CMOVEQZ,
- TILEGX_OPC_CMOVNEZ,
- TILEGX_OPC_CMPEQ,
- TILEGX_OPC_CMPEQI,
- TILEGX_OPC_CMPEXCH,
- TILEGX_OPC_CMPEXCH4,
- TILEGX_OPC_CMPLES,
- TILEGX_OPC_CMPLEU,
- TILEGX_OPC_CMPLTS,
- TILEGX_OPC_CMPLTSI,
- TILEGX_OPC_CMPLTU,
- TILEGX_OPC_CMPLTUI,
- TILEGX_OPC_CMPNE,
- TILEGX_OPC_CMUL,
- TILEGX_OPC_CMULA,
- TILEGX_OPC_CMULAF,
- TILEGX_OPC_CMULF,
- TILEGX_OPC_CMULFR,
- TILEGX_OPC_CMULH,
- TILEGX_OPC_CMULHR,
- TILEGX_OPC_CRC32_32,
- TILEGX_OPC_CRC32_8,
- TILEGX_OPC_CTZ,
- TILEGX_OPC_DBLALIGN,
- TILEGX_OPC_DBLALIGN2,
- TILEGX_OPC_DBLALIGN4,
- TILEGX_OPC_DBLALIGN6,
- TILEGX_OPC_DRAIN,
- TILEGX_OPC_DTLBPR,
- TILEGX_OPC_EXCH,
- TILEGX_OPC_EXCH4,
- TILEGX_OPC_FDOUBLE_ADD_FLAGS,
- TILEGX_OPC_FDOUBLE_ADDSUB,
- TILEGX_OPC_FDOUBLE_MUL_FLAGS,
- TILEGX_OPC_FDOUBLE_PACK1,
- TILEGX_OPC_FDOUBLE_PACK2,
- TILEGX_OPC_FDOUBLE_SUB_FLAGS,
- TILEGX_OPC_FDOUBLE_UNPACK_MAX,
- TILEGX_OPC_FDOUBLE_UNPACK_MIN,
- TILEGX_OPC_FETCHADD,
- TILEGX_OPC_FETCHADD4,
- TILEGX_OPC_FETCHADDGEZ,
- TILEGX_OPC_FETCHADDGEZ4,
- TILEGX_OPC_FETCHAND,
- TILEGX_OPC_FETCHAND4,
- TILEGX_OPC_FETCHOR,
- TILEGX_OPC_FETCHOR4,
- TILEGX_OPC_FINV,
- TILEGX_OPC_FLUSH,
- TILEGX_OPC_FLUSHWB,
- TILEGX_OPC_FNOP,
- TILEGX_OPC_FSINGLE_ADD1,
- TILEGX_OPC_FSINGLE_ADDSUB2,
- TILEGX_OPC_FSINGLE_MUL1,
- TILEGX_OPC_FSINGLE_MUL2,
- TILEGX_OPC_FSINGLE_PACK1,
- TILEGX_OPC_FSINGLE_PACK2,
- TILEGX_OPC_FSINGLE_SUB1,
- TILEGX_OPC_ICOH,
- TILEGX_OPC_ILL,
- TILEGX_OPC_INV,
- TILEGX_OPC_IRET,
- TILEGX_OPC_J,
- TILEGX_OPC_JAL,
- TILEGX_OPC_JALR,
- TILEGX_OPC_JALRP,
- TILEGX_OPC_JR,
- TILEGX_OPC_JRP,
- TILEGX_OPC_LD,
- TILEGX_OPC_LD1S,
- TILEGX_OPC_LD1S_ADD,
- TILEGX_OPC_LD1U,
- TILEGX_OPC_LD1U_ADD,
- TILEGX_OPC_LD2S,
- TILEGX_OPC_LD2S_ADD,
- TILEGX_OPC_LD2U,
- TILEGX_OPC_LD2U_ADD,
- TILEGX_OPC_LD4S,
- TILEGX_OPC_LD4S_ADD,
- TILEGX_OPC_LD4U,
- TILEGX_OPC_LD4U_ADD,
- TILEGX_OPC_LD_ADD,
- TILEGX_OPC_LDNA,
- TILEGX_OPC_LDNA_ADD,
- TILEGX_OPC_LDNT,
- TILEGX_OPC_LDNT1S,
- TILEGX_OPC_LDNT1S_ADD,
- TILEGX_OPC_LDNT1U,
- TILEGX_OPC_LDNT1U_ADD,
- TILEGX_OPC_LDNT2S,
- TILEGX_OPC_LDNT2S_ADD,
- TILEGX_OPC_LDNT2U,
- TILEGX_OPC_LDNT2U_ADD,
- TILEGX_OPC_LDNT4S,
- TILEGX_OPC_LDNT4S_ADD,
- TILEGX_OPC_LDNT4U,
- TILEGX_OPC_LDNT4U_ADD,
- TILEGX_OPC_LDNT_ADD,
- TILEGX_OPC_LNK,
- TILEGX_OPC_MF,
- TILEGX_OPC_MFSPR,
- TILEGX_OPC_MM,
- TILEGX_OPC_MNZ,
- TILEGX_OPC_MTSPR,
- TILEGX_OPC_MUL_HS_HS,
- TILEGX_OPC_MUL_HS_HU,
- TILEGX_OPC_MUL_HS_LS,
- TILEGX_OPC_MUL_HS_LU,
- TILEGX_OPC_MUL_HU_HU,
- TILEGX_OPC_MUL_HU_LS,
- TILEGX_OPC_MUL_HU_LU,
- TILEGX_OPC_MUL_LS_LS,
- TILEGX_OPC_MUL_LS_LU,
- TILEGX_OPC_MUL_LU_LU,
- TILEGX_OPC_MULA_HS_HS,
- TILEGX_OPC_MULA_HS_HU,
- TILEGX_OPC_MULA_HS_LS,
- TILEGX_OPC_MULA_HS_LU,
- TILEGX_OPC_MULA_HU_HU,
- TILEGX_OPC_MULA_HU_LS,
- TILEGX_OPC_MULA_HU_LU,
- TILEGX_OPC_MULA_LS_LS,
- TILEGX_OPC_MULA_LS_LU,
- TILEGX_OPC_MULA_LU_LU,
- TILEGX_OPC_MULAX,
- TILEGX_OPC_MULX,
- TILEGX_OPC_MZ,
- TILEGX_OPC_NAP,
- TILEGX_OPC_NOP,
- TILEGX_OPC_NOR,
- TILEGX_OPC_OR,
- TILEGX_OPC_ORI,
- TILEGX_OPC_PCNT,
- TILEGX_OPC_REVBITS,
- TILEGX_OPC_REVBYTES,
- TILEGX_OPC_ROTL,
- TILEGX_OPC_ROTLI,
- TILEGX_OPC_SHL,
- TILEGX_OPC_SHL16INSLI,
- TILEGX_OPC_SHL1ADD,
- TILEGX_OPC_SHL1ADDX,
- TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL2ADDX,
- TILEGX_OPC_SHL3ADD,
- TILEGX_OPC_SHL3ADDX,
- TILEGX_OPC_SHLI,
- TILEGX_OPC_SHLX,
- TILEGX_OPC_SHLXI,
- TILEGX_OPC_SHRS,
- TILEGX_OPC_SHRSI,
- TILEGX_OPC_SHRU,
- TILEGX_OPC_SHRUI,
- TILEGX_OPC_SHRUX,
- TILEGX_OPC_SHRUXI,
- TILEGX_OPC_SHUFFLEBYTES,
- TILEGX_OPC_ST,
- TILEGX_OPC_ST1,
- TILEGX_OPC_ST1_ADD,
- TILEGX_OPC_ST2,
- TILEGX_OPC_ST2_ADD,
- TILEGX_OPC_ST4,
- TILEGX_OPC_ST4_ADD,
- TILEGX_OPC_ST_ADD,
- TILEGX_OPC_STNT,
- TILEGX_OPC_STNT1,
- TILEGX_OPC_STNT1_ADD,
- TILEGX_OPC_STNT2,
- TILEGX_OPC_STNT2_ADD,
- TILEGX_OPC_STNT4,
- TILEGX_OPC_STNT4_ADD,
- TILEGX_OPC_STNT_ADD,
- TILEGX_OPC_SUB,
- TILEGX_OPC_SUBX,
- TILEGX_OPC_SUBXSC,
- TILEGX_OPC_SWINT0,
- TILEGX_OPC_SWINT1,
- TILEGX_OPC_SWINT2,
- TILEGX_OPC_SWINT3,
- TILEGX_OPC_TBLIDXB0,
- TILEGX_OPC_TBLIDXB1,
- TILEGX_OPC_TBLIDXB2,
- TILEGX_OPC_TBLIDXB3,
- TILEGX_OPC_V1ADD,
- TILEGX_OPC_V1ADDI,
- TILEGX_OPC_V1ADDUC,
- TILEGX_OPC_V1ADIFFU,
- TILEGX_OPC_V1AVGU,
- TILEGX_OPC_V1CMPEQ,
- TILEGX_OPC_V1CMPEQI,
- TILEGX_OPC_V1CMPLES,
- TILEGX_OPC_V1CMPLEU,
- TILEGX_OPC_V1CMPLTS,
- TILEGX_OPC_V1CMPLTSI,
- TILEGX_OPC_V1CMPLTU,
- TILEGX_OPC_V1CMPLTUI,
- TILEGX_OPC_V1CMPNE,
- TILEGX_OPC_V1DDOTPU,
- TILEGX_OPC_V1DDOTPUA,
- TILEGX_OPC_V1DDOTPUS,
- TILEGX_OPC_V1DDOTPUSA,
- TILEGX_OPC_V1DOTP,
- TILEGX_OPC_V1DOTPA,
- TILEGX_OPC_V1DOTPU,
- TILEGX_OPC_V1DOTPUA,
- TILEGX_OPC_V1DOTPUS,
- TILEGX_OPC_V1DOTPUSA,
- TILEGX_OPC_V1INT_H,
- TILEGX_OPC_V1INT_L,
- TILEGX_OPC_V1MAXU,
- TILEGX_OPC_V1MAXUI,
- TILEGX_OPC_V1MINU,
- TILEGX_OPC_V1MINUI,
- TILEGX_OPC_V1MNZ,
- TILEGX_OPC_V1MULTU,
- TILEGX_OPC_V1MULU,
- TILEGX_OPC_V1MULUS,
- TILEGX_OPC_V1MZ,
- TILEGX_OPC_V1SADAU,
- TILEGX_OPC_V1SADU,
- TILEGX_OPC_V1SHL,
- TILEGX_OPC_V1SHLI,
- TILEGX_OPC_V1SHRS,
- TILEGX_OPC_V1SHRSI,
- TILEGX_OPC_V1SHRU,
- TILEGX_OPC_V1SHRUI,
- TILEGX_OPC_V1SUB,
- TILEGX_OPC_V1SUBUC,
- TILEGX_OPC_V2ADD,
- TILEGX_OPC_V2ADDI,
- TILEGX_OPC_V2ADDSC,
- TILEGX_OPC_V2ADIFFS,
- TILEGX_OPC_V2AVGS,
- TILEGX_OPC_V2CMPEQ,
- TILEGX_OPC_V2CMPEQI,
- TILEGX_OPC_V2CMPLES,
- TILEGX_OPC_V2CMPLEU,
- TILEGX_OPC_V2CMPLTS,
- TILEGX_OPC_V2CMPLTSI,
- TILEGX_OPC_V2CMPLTU,
- TILEGX_OPC_V2CMPLTUI,
- TILEGX_OPC_V2CMPNE,
- TILEGX_OPC_V2DOTP,
- TILEGX_OPC_V2DOTPA,
- TILEGX_OPC_V2INT_H,
- TILEGX_OPC_V2INT_L,
- TILEGX_OPC_V2MAXS,
- TILEGX_OPC_V2MAXSI,
- TILEGX_OPC_V2MINS,
- TILEGX_OPC_V2MINSI,
- TILEGX_OPC_V2MNZ,
- TILEGX_OPC_V2MULFSC,
- TILEGX_OPC_V2MULS,
- TILEGX_OPC_V2MULTS,
- TILEGX_OPC_V2MZ,
- TILEGX_OPC_V2PACKH,
- TILEGX_OPC_V2PACKL,
- TILEGX_OPC_V2PACKUC,
- TILEGX_OPC_V2SADAS,
- TILEGX_OPC_V2SADAU,
- TILEGX_OPC_V2SADS,
- TILEGX_OPC_V2SADU,
- TILEGX_OPC_V2SHL,
- TILEGX_OPC_V2SHLI,
- TILEGX_OPC_V2SHLSC,
- TILEGX_OPC_V2SHRS,
- TILEGX_OPC_V2SHRSI,
- TILEGX_OPC_V2SHRU,
- TILEGX_OPC_V2SHRUI,
- TILEGX_OPC_V2SUB,
- TILEGX_OPC_V2SUBSC,
- TILEGX_OPC_V4ADD,
- TILEGX_OPC_V4ADDSC,
- TILEGX_OPC_V4INT_H,
- TILEGX_OPC_V4INT_L,
- TILEGX_OPC_V4PACKSC,
- TILEGX_OPC_V4SHL,
- TILEGX_OPC_V4SHLSC,
- TILEGX_OPC_V4SHRS,
- TILEGX_OPC_V4SHRU,
- TILEGX_OPC_V4SUB,
- TILEGX_OPC_V4SUBSC,
- TILEGX_OPC_WH64,
- TILEGX_OPC_XOR,
- TILEGX_OPC_XORI,
- TILEGX_OPC_NONE
-} tilegx_mnemonic;
-
-enum
-{
- TILEGX_MAX_OPERANDS = 4 /* bfexts */
-};
-
-struct tilegx_opcode
-{
- /* The opcode mnemonic, e.g. "add" */
- const char *name;
-
- /* The enum value for this mnemonic. */
- tilegx_mnemonic mnemonic;
-
- /* A bit mask of which of the five pipes this instruction
- is compatible with:
- X0 0x01
- X1 0x02
- Y0 0x04
- Y1 0x08
- Y2 0x10 */
- unsigned char pipes;
-
- /* How many operands are there? */
- unsigned char num_operands;
-
- /* Which register does this write implicitly, or TREG_ZERO if none? */
- unsigned char implicitly_written_register;
-
- /* Can this be bundled with other instructions (almost always true). */
- unsigned char can_bundle;
-
- /* The description of the operands. Each of these is an
- * index into the tilegx_operands[] table. */
- unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS];
-
- /* A mask of which bits have predefined values for each pipeline.
- * This is useful for disassembly. */
- tilegx_bundle_bits fixed_bit_masks[TILEGX_NUM_PIPELINE_ENCODINGS];
-
- /* For each bit set in fixed_bit_masks, what the value is for this
- * instruction. */
- tilegx_bundle_bits fixed_bit_values[TILEGX_NUM_PIPELINE_ENCODINGS];
-};
-
-/* Used for non-textual disassembly into structs. */
-struct tilegx_decoded_instruction
-{
- const struct tilegx_opcode *opcode;
- const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS];
- long long operand_values[TILEGX_MAX_OPERANDS];
-};
-
-enum
-{
- ADDI_IMM8_OPCODE_X0 = 1,
- ADDI_IMM8_OPCODE_X1 = 1,
- ADDI_OPCODE_Y0 = 0,
- ADDI_OPCODE_Y1 = 1,
- ADDLI_OPCODE_X0 = 1,
- ADDLI_OPCODE_X1 = 0,
- ADDXI_IMM8_OPCODE_X0 = 2,
- ADDXI_IMM8_OPCODE_X1 = 2,
- ADDXI_OPCODE_Y0 = 1,
- ADDXI_OPCODE_Y1 = 2,
- ADDXLI_OPCODE_X0 = 2,
- ADDXLI_OPCODE_X1 = 1,
- ADDXSC_RRR_0_OPCODE_X0 = 1,
- ADDXSC_RRR_0_OPCODE_X1 = 1,
- ADDX_RRR_0_OPCODE_X0 = 2,
- ADDX_RRR_0_OPCODE_X1 = 2,
- ADDX_RRR_0_OPCODE_Y0 = 0,
- ADDX_SPECIAL_0_OPCODE_Y1 = 0,
- ADD_RRR_0_OPCODE_X0 = 3,
- ADD_RRR_0_OPCODE_X1 = 3,
- ADD_RRR_0_OPCODE_Y0 = 1,
- ADD_SPECIAL_0_OPCODE_Y1 = 1,
- ANDI_IMM8_OPCODE_X0 = 3,
- ANDI_IMM8_OPCODE_X1 = 3,
- ANDI_OPCODE_Y0 = 2,
- ANDI_OPCODE_Y1 = 3,
- AND_RRR_0_OPCODE_X0 = 4,
- AND_RRR_0_OPCODE_X1 = 4,
- AND_RRR_5_OPCODE_Y0 = 0,
- AND_RRR_5_OPCODE_Y1 = 0,
- BEQZT_BRANCH_OPCODE_X1 = 16,
- BEQZ_BRANCH_OPCODE_X1 = 17,
- BFEXTS_BF_OPCODE_X0 = 4,
- BFEXTU_BF_OPCODE_X0 = 5,
- BFINS_BF_OPCODE_X0 = 6,
- BF_OPCODE_X0 = 3,
- BGEZT_BRANCH_OPCODE_X1 = 18,
- BGEZ_BRANCH_OPCODE_X1 = 19,
- BGTZT_BRANCH_OPCODE_X1 = 20,
- BGTZ_BRANCH_OPCODE_X1 = 21,
- BLBCT_BRANCH_OPCODE_X1 = 22,
- BLBC_BRANCH_OPCODE_X1 = 23,
- BLBST_BRANCH_OPCODE_X1 = 24,
- BLBS_BRANCH_OPCODE_X1 = 25,
- BLEZT_BRANCH_OPCODE_X1 = 26,
- BLEZ_BRANCH_OPCODE_X1 = 27,
- BLTZT_BRANCH_OPCODE_X1 = 28,
- BLTZ_BRANCH_OPCODE_X1 = 29,
- BNEZT_BRANCH_OPCODE_X1 = 30,
- BNEZ_BRANCH_OPCODE_X1 = 31,
- BRANCH_OPCODE_X1 = 2,
- CMOVEQZ_RRR_0_OPCODE_X0 = 5,
- CMOVEQZ_RRR_4_OPCODE_Y0 = 0,
- CMOVNEZ_RRR_0_OPCODE_X0 = 6,
- CMOVNEZ_RRR_4_OPCODE_Y0 = 1,
- CMPEQI_IMM8_OPCODE_X0 = 4,
- CMPEQI_IMM8_OPCODE_X1 = 4,
- CMPEQI_OPCODE_Y0 = 3,
- CMPEQI_OPCODE_Y1 = 4,
- CMPEQ_RRR_0_OPCODE_X0 = 7,
- CMPEQ_RRR_0_OPCODE_X1 = 5,
- CMPEQ_RRR_3_OPCODE_Y0 = 0,
- CMPEQ_RRR_3_OPCODE_Y1 = 2,
- CMPEXCH4_RRR_0_OPCODE_X1 = 6,
- CMPEXCH_RRR_0_OPCODE_X1 = 7,
- CMPLES_RRR_0_OPCODE_X0 = 8,
- CMPLES_RRR_0_OPCODE_X1 = 8,
- CMPLES_RRR_2_OPCODE_Y0 = 0,
- CMPLES_RRR_2_OPCODE_Y1 = 0,
- CMPLEU_RRR_0_OPCODE_X0 = 9,
- CMPLEU_RRR_0_OPCODE_X1 = 9,
- CMPLEU_RRR_2_OPCODE_Y0 = 1,
- CMPLEU_RRR_2_OPCODE_Y1 = 1,
- CMPLTSI_IMM8_OPCODE_X0 = 5,
- CMPLTSI_IMM8_OPCODE_X1 = 5,
- CMPLTSI_OPCODE_Y0 = 4,
- CMPLTSI_OPCODE_Y1 = 5,
- CMPLTS_RRR_0_OPCODE_X0 = 10,
- CMPLTS_RRR_0_OPCODE_X1 = 10,
- CMPLTS_RRR_2_OPCODE_Y0 = 2,
- CMPLTS_RRR_2_OPCODE_Y1 = 2,
- CMPLTUI_IMM8_OPCODE_X0 = 6,
- CMPLTUI_IMM8_OPCODE_X1 = 6,
- CMPLTU_RRR_0_OPCODE_X0 = 11,
- CMPLTU_RRR_0_OPCODE_X1 = 11,
- CMPLTU_RRR_2_OPCODE_Y0 = 3,
- CMPLTU_RRR_2_OPCODE_Y1 = 3,
- CMPNE_RRR_0_OPCODE_X0 = 12,
- CMPNE_RRR_0_OPCODE_X1 = 12,
- CMPNE_RRR_3_OPCODE_Y0 = 1,
- CMPNE_RRR_3_OPCODE_Y1 = 3,
- CMULAF_RRR_0_OPCODE_X0 = 13,
- CMULA_RRR_0_OPCODE_X0 = 14,
- CMULFR_RRR_0_OPCODE_X0 = 15,
- CMULF_RRR_0_OPCODE_X0 = 16,
- CMULHR_RRR_0_OPCODE_X0 = 17,
- CMULH_RRR_0_OPCODE_X0 = 18,
- CMUL_RRR_0_OPCODE_X0 = 19,
- CNTLZ_UNARY_OPCODE_X0 = 1,
- CNTLZ_UNARY_OPCODE_Y0 = 1,
- CNTTZ_UNARY_OPCODE_X0 = 2,
- CNTTZ_UNARY_OPCODE_Y0 = 2,
- CRC32_32_RRR_0_OPCODE_X0 = 20,
- CRC32_8_RRR_0_OPCODE_X0 = 21,
- DBLALIGN2_RRR_0_OPCODE_X0 = 22,
- DBLALIGN2_RRR_0_OPCODE_X1 = 13,
- DBLALIGN4_RRR_0_OPCODE_X0 = 23,
- DBLALIGN4_RRR_0_OPCODE_X1 = 14,
- DBLALIGN6_RRR_0_OPCODE_X0 = 24,
- DBLALIGN6_RRR_0_OPCODE_X1 = 15,
- DBLALIGN_RRR_0_OPCODE_X0 = 25,
- DRAIN_UNARY_OPCODE_X1 = 1,
- DTLBPR_UNARY_OPCODE_X1 = 2,
- EXCH4_RRR_0_OPCODE_X1 = 16,
- EXCH_RRR_0_OPCODE_X1 = 17,
- FDOUBLE_ADDSUB_RRR_0_OPCODE_X0 = 26,
- FDOUBLE_ADD_FLAGS_RRR_0_OPCODE_X0 = 27,
- FDOUBLE_MUL_FLAGS_RRR_0_OPCODE_X0 = 28,
- FDOUBLE_PACK1_RRR_0_OPCODE_X0 = 29,
- FDOUBLE_PACK2_RRR_0_OPCODE_X0 = 30,
- FDOUBLE_SUB_FLAGS_RRR_0_OPCODE_X0 = 31,
- FDOUBLE_UNPACK_MAX_RRR_0_OPCODE_X0 = 32,
- FDOUBLE_UNPACK_MIN_RRR_0_OPCODE_X0 = 33,
- FETCHADD4_RRR_0_OPCODE_X1 = 18,
- FETCHADDGEZ4_RRR_0_OPCODE_X1 = 19,
- FETCHADDGEZ_RRR_0_OPCODE_X1 = 20,
- FETCHADD_RRR_0_OPCODE_X1 = 21,
- FETCHAND4_RRR_0_OPCODE_X1 = 22,
- FETCHAND_RRR_0_OPCODE_X1 = 23,
- FETCHOR4_RRR_0_OPCODE_X1 = 24,
- FETCHOR_RRR_0_OPCODE_X1 = 25,
- FINV_UNARY_OPCODE_X1 = 3,
- FLUSHWB_UNARY_OPCODE_X1 = 4,
- FLUSH_UNARY_OPCODE_X1 = 5,
- FNOP_UNARY_OPCODE_X0 = 3,
- FNOP_UNARY_OPCODE_X1 = 6,
- FNOP_UNARY_OPCODE_Y0 = 3,
- FNOP_UNARY_OPCODE_Y1 = 8,
- FSINGLE_ADD1_RRR_0_OPCODE_X0 = 34,
- FSINGLE_ADDSUB2_RRR_0_OPCODE_X0 = 35,
- FSINGLE_MUL1_RRR_0_OPCODE_X0 = 36,
- FSINGLE_MUL2_RRR_0_OPCODE_X0 = 37,
- FSINGLE_PACK1_UNARY_OPCODE_X0 = 4,
- FSINGLE_PACK1_UNARY_OPCODE_Y0 = 4,
- FSINGLE_PACK2_RRR_0_OPCODE_X0 = 38,
- FSINGLE_SUB1_RRR_0_OPCODE_X0 = 39,
- ICOH_UNARY_OPCODE_X1 = 7,
- ILL_UNARY_OPCODE_X1 = 8,
- ILL_UNARY_OPCODE_Y1 = 9,
- IMM8_OPCODE_X0 = 4,
- IMM8_OPCODE_X1 = 3,
- INV_UNARY_OPCODE_X1 = 9,
- IRET_UNARY_OPCODE_X1 = 10,
- JALRP_UNARY_OPCODE_X1 = 11,
- JALRP_UNARY_OPCODE_Y1 = 10,
- JALR_UNARY_OPCODE_X1 = 12,
- JALR_UNARY_OPCODE_Y1 = 11,
- JAL_JUMP_OPCODE_X1 = 0,
- JRP_UNARY_OPCODE_X1 = 13,
- JRP_UNARY_OPCODE_Y1 = 12,
- JR_UNARY_OPCODE_X1 = 14,
- JR_UNARY_OPCODE_Y1 = 13,
- JUMP_OPCODE_X1 = 4,
- J_JUMP_OPCODE_X1 = 1,
- LD1S_ADD_IMM8_OPCODE_X1 = 7,
- LD1S_OPCODE_Y2 = 0,
- LD1S_UNARY_OPCODE_X1 = 15,
- LD1U_ADD_IMM8_OPCODE_X1 = 8,
- LD1U_OPCODE_Y2 = 1,
- LD1U_UNARY_OPCODE_X1 = 16,
- LD2S_ADD_IMM8_OPCODE_X1 = 9,
- LD2S_OPCODE_Y2 = 2,
- LD2S_UNARY_OPCODE_X1 = 17,
- LD2U_ADD_IMM8_OPCODE_X1 = 10,
- LD2U_OPCODE_Y2 = 3,
- LD2U_UNARY_OPCODE_X1 = 18,
- LD4S_ADD_IMM8_OPCODE_X1 = 11,
- LD4S_OPCODE_Y2 = 1,
- LD4S_UNARY_OPCODE_X1 = 19,
- LD4U_ADD_IMM8_OPCODE_X1 = 12,
- LD4U_OPCODE_Y2 = 2,
- LD4U_UNARY_OPCODE_X1 = 20,
- LDNA_UNARY_OPCODE_X1 = 21,
- LDNT1S_ADD_IMM8_OPCODE_X1 = 13,
- LDNT1S_UNARY_OPCODE_X1 = 22,
- LDNT1U_ADD_IMM8_OPCODE_X1 = 14,
- LDNT1U_UNARY_OPCODE_X1 = 23,
- LDNT2S_ADD_IMM8_OPCODE_X1 = 15,
- LDNT2S_UNARY_OPCODE_X1 = 24,
- LDNT2U_ADD_IMM8_OPCODE_X1 = 16,
- LDNT2U_UNARY_OPCODE_X1 = 25,
- LDNT4S_ADD_IMM8_OPCODE_X1 = 17,
- LDNT4S_UNARY_OPCODE_X1 = 26,
- LDNT4U_ADD_IMM8_OPCODE_X1 = 18,
- LDNT4U_UNARY_OPCODE_X1 = 27,
- LDNT_ADD_IMM8_OPCODE_X1 = 19,
- LDNT_UNARY_OPCODE_X1 = 28,
- LD_ADD_IMM8_OPCODE_X1 = 20,
- LD_OPCODE_Y2 = 3,
- LD_UNARY_OPCODE_X1 = 29,
- LNK_UNARY_OPCODE_X1 = 30,
- LNK_UNARY_OPCODE_Y1 = 14,
- LWNA_ADD_IMM8_OPCODE_X1 = 21,
- MFSPR_IMM8_OPCODE_X1 = 22,
- MF_UNARY_OPCODE_X1 = 31,
- MM_BF_OPCODE_X0 = 7,
- MNZ_RRR_0_OPCODE_X0 = 40,
- MNZ_RRR_0_OPCODE_X1 = 26,
- MNZ_RRR_4_OPCODE_Y0 = 2,
- MNZ_RRR_4_OPCODE_Y1 = 2,
- MODE_OPCODE_YA2 = 1,
- MODE_OPCODE_YB2 = 2,
- MODE_OPCODE_YC2 = 3,
- MTSPR_IMM8_OPCODE_X1 = 23,
- MULAX_RRR_0_OPCODE_X0 = 41,
- MULAX_RRR_3_OPCODE_Y0 = 2,
- MULA_HS_HS_RRR_0_OPCODE_X0 = 42,
- MULA_HS_HS_RRR_9_OPCODE_Y0 = 0,
- MULA_HS_HU_RRR_0_OPCODE_X0 = 43,
- MULA_HS_LS_RRR_0_OPCODE_X0 = 44,
- MULA_HS_LU_RRR_0_OPCODE_X0 = 45,
- MULA_HU_HU_RRR_0_OPCODE_X0 = 46,
- MULA_HU_HU_RRR_9_OPCODE_Y0 = 1,
- MULA_HU_LS_RRR_0_OPCODE_X0 = 47,
- MULA_HU_LU_RRR_0_OPCODE_X0 = 48,
- MULA_LS_LS_RRR_0_OPCODE_X0 = 49,
- MULA_LS_LS_RRR_9_OPCODE_Y0 = 2,
- MULA_LS_LU_RRR_0_OPCODE_X0 = 50,
- MULA_LU_LU_RRR_0_OPCODE_X0 = 51,
- MULA_LU_LU_RRR_9_OPCODE_Y0 = 3,
- MULX_RRR_0_OPCODE_X0 = 52,
- MULX_RRR_3_OPCODE_Y0 = 3,
- MUL_HS_HS_RRR_0_OPCODE_X0 = 53,
- MUL_HS_HS_RRR_8_OPCODE_Y0 = 0,
- MUL_HS_HU_RRR_0_OPCODE_X0 = 54,
- MUL_HS_LS_RRR_0_OPCODE_X0 = 55,
- MUL_HS_LU_RRR_0_OPCODE_X0 = 56,
- MUL_HU_HU_RRR_0_OPCODE_X0 = 57,
- MUL_HU_HU_RRR_8_OPCODE_Y0 = 1,
- MUL_HU_LS_RRR_0_OPCODE_X0 = 58,
- MUL_HU_LU_RRR_0_OPCODE_X0 = 59,
- MUL_LS_LS_RRR_0_OPCODE_X0 = 60,
- MUL_LS_LS_RRR_8_OPCODE_Y0 = 2,
- MUL_LS_LU_RRR_0_OPCODE_X0 = 61,
- MUL_LU_LU_RRR_0_OPCODE_X0 = 62,
- MUL_LU_LU_RRR_8_OPCODE_Y0 = 3,
- MZ_RRR_0_OPCODE_X0 = 63,
- MZ_RRR_0_OPCODE_X1 = 27,
- MZ_RRR_4_OPCODE_Y0 = 3,
- MZ_RRR_4_OPCODE_Y1 = 3,
- NAP_UNARY_OPCODE_X1 = 32,
- NOP_UNARY_OPCODE_X0 = 5,
- NOP_UNARY_OPCODE_X1 = 33,
- NOP_UNARY_OPCODE_Y0 = 5,
- NOP_UNARY_OPCODE_Y1 = 15,
- NOR_RRR_0_OPCODE_X0 = 64,
- NOR_RRR_0_OPCODE_X1 = 28,
- NOR_RRR_5_OPCODE_Y0 = 1,
- NOR_RRR_5_OPCODE_Y1 = 1,
- ORI_IMM8_OPCODE_X0 = 7,
- ORI_IMM8_OPCODE_X1 = 24,
- OR_RRR_0_OPCODE_X0 = 65,
- OR_RRR_0_OPCODE_X1 = 29,
- OR_RRR_5_OPCODE_Y0 = 2,
- OR_RRR_5_OPCODE_Y1 = 2,
- PCNT_UNARY_OPCODE_X0 = 6,
- PCNT_UNARY_OPCODE_Y0 = 6,
- REVBITS_UNARY_OPCODE_X0 = 7,
- REVBITS_UNARY_OPCODE_Y0 = 7,
- REVBYTES_UNARY_OPCODE_X0 = 8,
- REVBYTES_UNARY_OPCODE_Y0 = 8,
- ROTLI_SHIFT_OPCODE_X0 = 1,
- ROTLI_SHIFT_OPCODE_X1 = 1,
- ROTLI_SHIFT_OPCODE_Y0 = 0,
- ROTLI_SHIFT_OPCODE_Y1 = 0,
- ROTL_RRR_0_OPCODE_X0 = 66,
- ROTL_RRR_0_OPCODE_X1 = 30,
- ROTL_RRR_6_OPCODE_Y0 = 0,
- ROTL_RRR_6_OPCODE_Y1 = 0,
- RRR_0_OPCODE_X0 = 5,
- RRR_0_OPCODE_X1 = 5,
- RRR_0_OPCODE_Y0 = 5,
- RRR_0_OPCODE_Y1 = 6,
- RRR_1_OPCODE_Y0 = 6,
- RRR_1_OPCODE_Y1 = 7,
- RRR_2_OPCODE_Y0 = 7,
- RRR_2_OPCODE_Y1 = 8,
- RRR_3_OPCODE_Y0 = 8,
- RRR_3_OPCODE_Y1 = 9,
- RRR_4_OPCODE_Y0 = 9,
- RRR_4_OPCODE_Y1 = 10,
- RRR_5_OPCODE_Y0 = 10,
- RRR_5_OPCODE_Y1 = 11,
- RRR_6_OPCODE_Y0 = 11,
- RRR_6_OPCODE_Y1 = 12,
- RRR_7_OPCODE_Y0 = 12,
- RRR_7_OPCODE_Y1 = 13,
- RRR_8_OPCODE_Y0 = 13,
- RRR_9_OPCODE_Y0 = 14,
- SHIFT_OPCODE_X0 = 6,
- SHIFT_OPCODE_X1 = 6,
- SHIFT_OPCODE_Y0 = 15,
- SHIFT_OPCODE_Y1 = 14,
- SHL16INSLI_OPCODE_X0 = 7,
- SHL16INSLI_OPCODE_X1 = 7,
- SHL1ADDX_RRR_0_OPCODE_X0 = 67,
- SHL1ADDX_RRR_0_OPCODE_X1 = 31,
- SHL1ADDX_RRR_7_OPCODE_Y0 = 1,
- SHL1ADDX_RRR_7_OPCODE_Y1 = 1,
- SHL1ADD_RRR_0_OPCODE_X0 = 68,
- SHL1ADD_RRR_0_OPCODE_X1 = 32,
- SHL1ADD_RRR_1_OPCODE_Y0 = 0,
- SHL1ADD_RRR_1_OPCODE_Y1 = 0,
- SHL2ADDX_RRR_0_OPCODE_X0 = 69,
- SHL2ADDX_RRR_0_OPCODE_X1 = 33,
- SHL2ADDX_RRR_7_OPCODE_Y0 = 2,
- SHL2ADDX_RRR_7_OPCODE_Y1 = 2,
- SHL2ADD_RRR_0_OPCODE_X0 = 70,
- SHL2ADD_RRR_0_OPCODE_X1 = 34,
- SHL2ADD_RRR_1_OPCODE_Y0 = 1,
- SHL2ADD_RRR_1_OPCODE_Y1 = 1,
- SHL3ADDX_RRR_0_OPCODE_X0 = 71,
- SHL3ADDX_RRR_0_OPCODE_X1 = 35,
- SHL3ADDX_RRR_7_OPCODE_Y0 = 3,
- SHL3ADDX_RRR_7_OPCODE_Y1 = 3,
- SHL3ADD_RRR_0_OPCODE_X0 = 72,
- SHL3ADD_RRR_0_OPCODE_X1 = 36,
- SHL3ADD_RRR_1_OPCODE_Y0 = 2,
- SHL3ADD_RRR_1_OPCODE_Y1 = 2,
- SHLI_SHIFT_OPCODE_X0 = 2,
- SHLI_SHIFT_OPCODE_X1 = 2,
- SHLI_SHIFT_OPCODE_Y0 = 1,
- SHLI_SHIFT_OPCODE_Y1 = 1,
- SHLXI_SHIFT_OPCODE_X0 = 3,
- SHLXI_SHIFT_OPCODE_X1 = 3,
- SHLX_RRR_0_OPCODE_X0 = 73,
- SHLX_RRR_0_OPCODE_X1 = 37,
- SHL_RRR_0_OPCODE_X0 = 74,
- SHL_RRR_0_OPCODE_X1 = 38,
- SHL_RRR_6_OPCODE_Y0 = 1,
- SHL_RRR_6_OPCODE_Y1 = 1,
- SHRSI_SHIFT_OPCODE_X0 = 4,
- SHRSI_SHIFT_OPCODE_X1 = 4,
- SHRSI_SHIFT_OPCODE_Y0 = 2,
- SHRSI_SHIFT_OPCODE_Y1 = 2,
- SHRS_RRR_0_OPCODE_X0 = 75,
- SHRS_RRR_0_OPCODE_X1 = 39,
- SHRS_RRR_6_OPCODE_Y0 = 2,
- SHRS_RRR_6_OPCODE_Y1 = 2,
- SHRUI_SHIFT_OPCODE_X0 = 5,
- SHRUI_SHIFT_OPCODE_X1 = 5,
- SHRUI_SHIFT_OPCODE_Y0 = 3,
- SHRUI_SHIFT_OPCODE_Y1 = 3,
- SHRUXI_SHIFT_OPCODE_X0 = 6,
- SHRUXI_SHIFT_OPCODE_X1 = 6,
- SHRUX_RRR_0_OPCODE_X0 = 76,
- SHRUX_RRR_0_OPCODE_X1 = 40,
- SHRU_RRR_0_OPCODE_X0 = 77,
- SHRU_RRR_0_OPCODE_X1 = 41,
- SHRU_RRR_6_OPCODE_Y0 = 3,
- SHRU_RRR_6_OPCODE_Y1 = 3,
- SHUFFLEBYTES_RRR_0_OPCODE_X0 = 78,
- ST1_ADD_IMM8_OPCODE_X1 = 25,
- ST1_OPCODE_Y2 = 0,
- ST1_RRR_0_OPCODE_X1 = 42,
- ST2_ADD_IMM8_OPCODE_X1 = 26,
- ST2_OPCODE_Y2 = 1,
- ST2_RRR_0_OPCODE_X1 = 43,
- ST4_ADD_IMM8_OPCODE_X1 = 27,
- ST4_OPCODE_Y2 = 2,
- ST4_RRR_0_OPCODE_X1 = 44,
- STNT1_ADD_IMM8_OPCODE_X1 = 28,
- STNT1_RRR_0_OPCODE_X1 = 45,
- STNT2_ADD_IMM8_OPCODE_X1 = 29,
- STNT2_RRR_0_OPCODE_X1 = 46,
- STNT4_ADD_IMM8_OPCODE_X1 = 30,
- STNT4_RRR_0_OPCODE_X1 = 47,
- STNT_ADD_IMM8_OPCODE_X1 = 31,
- STNT_RRR_0_OPCODE_X1 = 48,
- ST_ADD_IMM8_OPCODE_X1 = 32,
- ST_OPCODE_Y2 = 3,
- ST_RRR_0_OPCODE_X1 = 49,
- SUBXSC_RRR_0_OPCODE_X0 = 79,
- SUBXSC_RRR_0_OPCODE_X1 = 50,
- SUBX_RRR_0_OPCODE_X0 = 80,
- SUBX_RRR_0_OPCODE_X1 = 51,
- SUBX_RRR_0_OPCODE_Y0 = 2,
- SUBX_RRR_0_OPCODE_Y1 = 2,
- SUB_RRR_0_OPCODE_X0 = 81,
- SUB_RRR_0_OPCODE_X1 = 52,
- SUB_RRR_0_OPCODE_Y0 = 3,
- SUB_RRR_0_OPCODE_Y1 = 3,
- SWINT0_UNARY_OPCODE_X1 = 34,
- SWINT1_UNARY_OPCODE_X1 = 35,
- SWINT2_UNARY_OPCODE_X1 = 36,
- SWINT3_UNARY_OPCODE_X1 = 37,
- TBLIDXB0_UNARY_OPCODE_X0 = 9,
- TBLIDXB0_UNARY_OPCODE_Y0 = 9,
- TBLIDXB1_UNARY_OPCODE_X0 = 10,
- TBLIDXB1_UNARY_OPCODE_Y0 = 10,
- TBLIDXB2_UNARY_OPCODE_X0 = 11,
- TBLIDXB2_UNARY_OPCODE_Y0 = 11,
- TBLIDXB3_UNARY_OPCODE_X0 = 12,
- TBLIDXB3_UNARY_OPCODE_Y0 = 12,
- UNARY_RRR_0_OPCODE_X0 = 82,
- UNARY_RRR_0_OPCODE_X1 = 53,
- UNARY_RRR_1_OPCODE_Y0 = 3,
- UNARY_RRR_1_OPCODE_Y1 = 3,
- V1ADDI_IMM8_OPCODE_X0 = 8,
- V1ADDI_IMM8_OPCODE_X1 = 33,
- V1ADDUC_RRR_0_OPCODE_X0 = 83,
- V1ADDUC_RRR_0_OPCODE_X1 = 54,
- V1ADD_RRR_0_OPCODE_X0 = 84,
- V1ADD_RRR_0_OPCODE_X1 = 55,
- V1ADIFFU_RRR_0_OPCODE_X0 = 85,
- V1AVGU_RRR_0_OPCODE_X0 = 86,
- V1CMPEQI_IMM8_OPCODE_X0 = 9,
- V1CMPEQI_IMM8_OPCODE_X1 = 34,
- V1CMPEQ_RRR_0_OPCODE_X0 = 87,
- V1CMPEQ_RRR_0_OPCODE_X1 = 56,
- V1CMPLES_RRR_0_OPCODE_X0 = 88,
- V1CMPLES_RRR_0_OPCODE_X1 = 57,
- V1CMPLEU_RRR_0_OPCODE_X0 = 89,
- V1CMPLEU_RRR_0_OPCODE_X1 = 58,
- V1CMPLTSI_IMM8_OPCODE_X0 = 10,
- V1CMPLTSI_IMM8_OPCODE_X1 = 35,
- V1CMPLTS_RRR_0_OPCODE_X0 = 90,
- V1CMPLTS_RRR_0_OPCODE_X1 = 59,
- V1CMPLTUI_IMM8_OPCODE_X0 = 11,
- V1CMPLTUI_IMM8_OPCODE_X1 = 36,
- V1CMPLTU_RRR_0_OPCODE_X0 = 91,
- V1CMPLTU_RRR_0_OPCODE_X1 = 60,
- V1CMPNE_RRR_0_OPCODE_X0 = 92,
- V1CMPNE_RRR_0_OPCODE_X1 = 61,
- V1DDOTPUA_RRR_0_OPCODE_X0 = 161,
- V1DDOTPUSA_RRR_0_OPCODE_X0 = 93,
- V1DDOTPUS_RRR_0_OPCODE_X0 = 94,
- V1DDOTPU_RRR_0_OPCODE_X0 = 162,
- V1DOTPA_RRR_0_OPCODE_X0 = 95,
- V1DOTPUA_RRR_0_OPCODE_X0 = 163,
- V1DOTPUSA_RRR_0_OPCODE_X0 = 96,
- V1DOTPUS_RRR_0_OPCODE_X0 = 97,
- V1DOTPU_RRR_0_OPCODE_X0 = 164,
- V1DOTP_RRR_0_OPCODE_X0 = 98,
- V1INT_H_RRR_0_OPCODE_X0 = 99,
- V1INT_H_RRR_0_OPCODE_X1 = 62,
- V1INT_L_RRR_0_OPCODE_X0 = 100,
- V1INT_L_RRR_0_OPCODE_X1 = 63,
- V1MAXUI_IMM8_OPCODE_X0 = 12,
- V1MAXUI_IMM8_OPCODE_X1 = 37,
- V1MAXU_RRR_0_OPCODE_X0 = 101,
- V1MAXU_RRR_0_OPCODE_X1 = 64,
- V1MINUI_IMM8_OPCODE_X0 = 13,
- V1MINUI_IMM8_OPCODE_X1 = 38,
- V1MINU_RRR_0_OPCODE_X0 = 102,
- V1MINU_RRR_0_OPCODE_X1 = 65,
- V1MNZ_RRR_0_OPCODE_X0 = 103,
- V1MNZ_RRR_0_OPCODE_X1 = 66,
- V1MULTU_RRR_0_OPCODE_X0 = 104,
- V1MULUS_RRR_0_OPCODE_X0 = 105,
- V1MULU_RRR_0_OPCODE_X0 = 106,
- V1MZ_RRR_0_OPCODE_X0 = 107,
- V1MZ_RRR_0_OPCODE_X1 = 67,
- V1SADAU_RRR_0_OPCODE_X0 = 108,
- V1SADU_RRR_0_OPCODE_X0 = 109,
- V1SHLI_SHIFT_OPCODE_X0 = 7,
- V1SHLI_SHIFT_OPCODE_X1 = 7,
- V1SHL_RRR_0_OPCODE_X0 = 110,
- V1SHL_RRR_0_OPCODE_X1 = 68,
- V1SHRSI_SHIFT_OPCODE_X0 = 8,
- V1SHRSI_SHIFT_OPCODE_X1 = 8,
- V1SHRS_RRR_0_OPCODE_X0 = 111,
- V1SHRS_RRR_0_OPCODE_X1 = 69,
- V1SHRUI_SHIFT_OPCODE_X0 = 9,
- V1SHRUI_SHIFT_OPCODE_X1 = 9,
- V1SHRU_RRR_0_OPCODE_X0 = 112,
- V1SHRU_RRR_0_OPCODE_X1 = 70,
- V1SUBUC_RRR_0_OPCODE_X0 = 113,
- V1SUBUC_RRR_0_OPCODE_X1 = 71,
- V1SUB_RRR_0_OPCODE_X0 = 114,
- V1SUB_RRR_0_OPCODE_X1 = 72,
- V2ADDI_IMM8_OPCODE_X0 = 14,
- V2ADDI_IMM8_OPCODE_X1 = 39,
- V2ADDSC_RRR_0_OPCODE_X0 = 115,
- V2ADDSC_RRR_0_OPCODE_X1 = 73,
- V2ADD_RRR_0_OPCODE_X0 = 116,
- V2ADD_RRR_0_OPCODE_X1 = 74,
- V2ADIFFS_RRR_0_OPCODE_X0 = 117,
- V2AVGS_RRR_0_OPCODE_X0 = 118,
- V2CMPEQI_IMM8_OPCODE_X0 = 15,
- V2CMPEQI_IMM8_OPCODE_X1 = 40,
- V2CMPEQ_RRR_0_OPCODE_X0 = 119,
- V2CMPEQ_RRR_0_OPCODE_X1 = 75,
- V2CMPLES_RRR_0_OPCODE_X0 = 120,
- V2CMPLES_RRR_0_OPCODE_X1 = 76,
- V2CMPLEU_RRR_0_OPCODE_X0 = 121,
- V2CMPLEU_RRR_0_OPCODE_X1 = 77,
- V2CMPLTSI_IMM8_OPCODE_X0 = 16,
- V2CMPLTSI_IMM8_OPCODE_X1 = 41,
- V2CMPLTS_RRR_0_OPCODE_X0 = 122,
- V2CMPLTS_RRR_0_OPCODE_X1 = 78,
- V2CMPLTUI_IMM8_OPCODE_X0 = 17,
- V2CMPLTUI_IMM8_OPCODE_X1 = 42,
- V2CMPLTU_RRR_0_OPCODE_X0 = 123,
- V2CMPLTU_RRR_0_OPCODE_X1 = 79,
- V2CMPNE_RRR_0_OPCODE_X0 = 124,
- V2CMPNE_RRR_0_OPCODE_X1 = 80,
- V2DOTPA_RRR_0_OPCODE_X0 = 125,
- V2DOTP_RRR_0_OPCODE_X0 = 126,
- V2INT_H_RRR_0_OPCODE_X0 = 127,
- V2INT_H_RRR_0_OPCODE_X1 = 81,
- V2INT_L_RRR_0_OPCODE_X0 = 128,
- V2INT_L_RRR_0_OPCODE_X1 = 82,
- V2MAXSI_IMM8_OPCODE_X0 = 18,
- V2MAXSI_IMM8_OPCODE_X1 = 43,
- V2MAXS_RRR_0_OPCODE_X0 = 129,
- V2MAXS_RRR_0_OPCODE_X1 = 83,
- V2MINSI_IMM8_OPCODE_X0 = 19,
- V2MINSI_IMM8_OPCODE_X1 = 44,
- V2MINS_RRR_0_OPCODE_X0 = 130,
- V2MINS_RRR_0_OPCODE_X1 = 84,
- V2MNZ_RRR_0_OPCODE_X0 = 131,
- V2MNZ_RRR_0_OPCODE_X1 = 85,
- V2MULFSC_RRR_0_OPCODE_X0 = 132,
- V2MULS_RRR_0_OPCODE_X0 = 133,
- V2MULTS_RRR_0_OPCODE_X0 = 134,
- V2MZ_RRR_0_OPCODE_X0 = 135,
- V2MZ_RRR_0_OPCODE_X1 = 86,
- V2PACKH_RRR_0_OPCODE_X0 = 136,
- V2PACKH_RRR_0_OPCODE_X1 = 87,
- V2PACKL_RRR_0_OPCODE_X0 = 137,
- V2PACKL_RRR_0_OPCODE_X1 = 88,
- V2PACKUC_RRR_0_OPCODE_X0 = 138,
- V2PACKUC_RRR_0_OPCODE_X1 = 89,
- V2SADAS_RRR_0_OPCODE_X0 = 139,
- V2SADAU_RRR_0_OPCODE_X0 = 140,
- V2SADS_RRR_0_OPCODE_X0 = 141,
- V2SADU_RRR_0_OPCODE_X0 = 142,
- V2SHLI_SHIFT_OPCODE_X0 = 10,
- V2SHLI_SHIFT_OPCODE_X1 = 10,
- V2SHLSC_RRR_0_OPCODE_X0 = 143,
- V2SHLSC_RRR_0_OPCODE_X1 = 90,
- V2SHL_RRR_0_OPCODE_X0 = 144,
- V2SHL_RRR_0_OPCODE_X1 = 91,
- V2SHRSI_SHIFT_OPCODE_X0 = 11,
- V2SHRSI_SHIFT_OPCODE_X1 = 11,
- V2SHRS_RRR_0_OPCODE_X0 = 145,
- V2SHRS_RRR_0_OPCODE_X1 = 92,
- V2SHRUI_SHIFT_OPCODE_X0 = 12,
- V2SHRUI_SHIFT_OPCODE_X1 = 12,
- V2SHRU_RRR_0_OPCODE_X0 = 146,
- V2SHRU_RRR_0_OPCODE_X1 = 93,
- V2SUBSC_RRR_0_OPCODE_X0 = 147,
- V2SUBSC_RRR_0_OPCODE_X1 = 94,
- V2SUB_RRR_0_OPCODE_X0 = 148,
- V2SUB_RRR_0_OPCODE_X1 = 95,
- V4ADDSC_RRR_0_OPCODE_X0 = 149,
- V4ADDSC_RRR_0_OPCODE_X1 = 96,
- V4ADD_RRR_0_OPCODE_X0 = 150,
- V4ADD_RRR_0_OPCODE_X1 = 97,
- V4INT_H_RRR_0_OPCODE_X0 = 151,
- V4INT_H_RRR_0_OPCODE_X1 = 98,
- V4INT_L_RRR_0_OPCODE_X0 = 152,
- V4INT_L_RRR_0_OPCODE_X1 = 99,
- V4PACKSC_RRR_0_OPCODE_X0 = 153,
- V4PACKSC_RRR_0_OPCODE_X1 = 100,
- V4SHLSC_RRR_0_OPCODE_X0 = 154,
- V4SHLSC_RRR_0_OPCODE_X1 = 101,
- V4SHL_RRR_0_OPCODE_X0 = 155,
- V4SHL_RRR_0_OPCODE_X1 = 102,
- V4SHRS_RRR_0_OPCODE_X0 = 156,
- V4SHRS_RRR_0_OPCODE_X1 = 103,
- V4SHRU_RRR_0_OPCODE_X0 = 157,
- V4SHRU_RRR_0_OPCODE_X1 = 104,
- V4SUBSC_RRR_0_OPCODE_X0 = 158,
- V4SUBSC_RRR_0_OPCODE_X1 = 105,
- V4SUB_RRR_0_OPCODE_X0 = 159,
- V4SUB_RRR_0_OPCODE_X1 = 106,
- WH64_UNARY_OPCODE_X1 = 38,
- XORI_IMM8_OPCODE_X0 = 20,
- XORI_IMM8_OPCODE_X1 = 45,
- XOR_RRR_0_OPCODE_X0 = 160,
- XOR_RRR_0_OPCODE_X1 = 107,
- XOR_RRR_5_OPCODE_Y0 = 3,
- XOR_RRR_5_OPCODE_Y1 = 3
-};
-
-static __inline unsigned int
-get_BFEnd_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_BFOpcodeExtension_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 24)) & 0xf);
-}
-
-static __inline unsigned int
-get_BFStart_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 18)) & 0x3f);
-}
-
-static __inline unsigned int
-get_BrOff_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x0000003f) |
- (((unsigned int)(n >> 37)) & 0x0001ffc0);
-}
-
-static __inline unsigned int
-get_BrType_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 54)) & 0x1f);
-}
-
-static __inline unsigned int
-get_Dest_Imm8_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x0000003f) |
- (((unsigned int)(n >> 43)) & 0x000000c0);
-}
-
-static __inline unsigned int
-get_Dest_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 0)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 0)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Dest_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x3f);
-}
-
-static __inline unsigned int
-get_Imm16_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0xffff);
-}
-
-static __inline unsigned int
-get_Imm16_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0xffff);
-}
-
-static __inline unsigned int
-get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 20)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 51)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0xff);
-}
-
-static __inline unsigned int
-get_JumpOff_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x7ffffff);
-}
-
-static __inline unsigned int
-get_JumpOpcodeExtension_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 58)) & 0x1);
-}
-
-static __inline unsigned int
-get_MF_Imm14_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 37)) & 0x3fff);
-}
-
-static __inline unsigned int
-get_MT_Imm14_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 31)) & 0x0000003f) |
- (((unsigned int)(n >> 37)) & 0x00003fc0);
-}
-
-static __inline unsigned int
-get_Mode(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 62)) & 0x3);
-}
-
-static __inline unsigned int
-get_Opcode_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 28)) & 0x7);
-}
-
-static __inline unsigned int
-get_Opcode_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 59)) & 0x7);
-}
-
-static __inline unsigned int
-get_Opcode_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 27)) & 0xf);
-}
-
-static __inline unsigned int
-get_Opcode_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 58)) & 0xf);
-}
-
-static __inline unsigned int
-get_Opcode_Y2(tilegx_bundle_bits n)
-{
- return (((n >> 26)) & 0x00000001) |
- (((unsigned int)(n >> 56)) & 0x00000002);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 18)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 49)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 18)) & 0x3);
-}
-
-static __inline unsigned int
-get_RRROpcodeExtension_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 49)) & 0x3);
-}
-
-static __inline unsigned int
-get_ShAmt_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShAmt_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShAmt_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShAmt_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 18)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 49)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 18)) & 0x3);
-}
-
-static __inline unsigned int
-get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 49)) & 0x3);
-}
-
-static __inline unsigned int
-get_SrcA_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 6)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 37)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 6)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 37)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcA_Y2(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 20)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcBDest_Y2(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 51)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_SrcB_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num)
-{
- const unsigned int n = (unsigned int)num;
- return (((n >> 12)) & 0x3f);
-}
-
-static __inline unsigned int
-get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n)
-{
- return (((unsigned int)(n >> 43)) & 0x3f);
-}
-
-static __inline int
-sign_extend(int n, int num_bits)
-{
- int shift = (int)(sizeof(int) * 8 - num_bits);
- return (n << shift) >> shift;
-}
-
-static __inline tilegx_bundle_bits
-create_BFEnd_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_BFOpcodeExtension_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xf) << 24);
-}
-
-static __inline tilegx_bundle_bits
-create_BFStart_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_BrOff_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
- (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_BrType_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x1f)) << 54);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_Imm8_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
- (((tilegx_bundle_bits)(n & 0x000000c0)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 0);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 0);
-}
-
-static __inline tilegx_bundle_bits
-create_Dest_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm16_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xffff) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm16_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0xffff)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8OpcodeExtension_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xff) << 20);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8OpcodeExtension_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0xff)) << 51);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xff) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0xff)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xff) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_Imm8_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0xff)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_JumpOff_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31);
-}
-
-static __inline tilegx_bundle_bits
-create_JumpOpcodeExtension_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x1)) << 58);
-}
-
-static __inline tilegx_bundle_bits
-create_MF_Imm14_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3fff)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_MT_Imm14_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
- (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_Mode(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3)) << 62);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x7) << 28);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x7)) << 59);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0xf) << 27);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0xf)) << 58);
-}
-
-static __inline tilegx_bundle_bits
-create_Opcode_Y2(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x00000001) << 26) |
- (((tilegx_bundle_bits)(n & 0x00000002)) << 56);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3ff) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_RRROpcodeExtension_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_ShAmt_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3ff) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3) << 18);
-}
-
-static __inline tilegx_bundle_bits
-create_ShiftOpcodeExtension_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3)) << 49);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 6);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 6);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcA_Y2(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 20);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcBDest_Y2(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 51);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_SrcB_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_X0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_X1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_Y0(int num)
-{
- const unsigned int n = (unsigned int)num;
- return ((n & 0x3f) << 12);
-}
-
-static __inline tilegx_bundle_bits
-create_UnaryOpcodeExtension_Y1(int num)
-{
- const unsigned int n = (unsigned int)num;
- return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
-}
-
-const struct tilegx_opcode tilegx_opcodes[336] =
-{
- { "bpt", TILEGX_OPC_BPT, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffffffff80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a44ae00000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "info", TILEGX_OPC_INFO, 0xf, 1, TREG_ZERO, 1,
- { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00fffULL,
- 0xfff807ff80000000ULL,
- 0x0000000078000fffULL,
- 0x3c0007ff80000000ULL,
- 0ULL
- },
- {
- 0x0000000040300fffULL,
- 0x181807ff80000000ULL,
- 0x0000000010000fffULL,
- 0x0c0007ff80000000ULL,
- -1ULL
- }
-#endif
- },
- { "infol", TILEGX_OPC_INFOL, 0x3, 1, TREG_ZERO, 1,
- { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc000000070000fffULL,
- 0xf80007ff80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000070000fffULL,
- 0x380007ff80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld4s_tls", TILEGX_OPC_LD4S_TLS, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1858000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld_tls", TILEGX_OPC_LD_TLS, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18a0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "move", TILEGX_OPC_MOVE, 0xf, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 6, 7 }, { 10, 11 }, { 12, 13 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0xfffff80000000000ULL,
- 0x00000000780ff000ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- 0x000000005107f000ULL,
- 0x283bf80000000000ULL,
- 0x00000000500bf000ULL,
- 0x2c05f80000000000ULL,
- -1ULL
- }
-#endif
- },
- { "movei", TILEGX_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1,
- { { 8, 0 }, { 6, 1 }, { 10, 2 }, { 12, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00fc0ULL,
- 0xfff807e000000000ULL,
- 0x0000000078000fc0ULL,
- 0x3c0007e000000000ULL,
- 0ULL
- },
- {
- 0x0000000040100fc0ULL,
- 0x180807e000000000ULL,
- 0x0000000000000fc0ULL,
- 0x040007e000000000ULL,
- -1ULL
- }
-#endif
- },
- { "moveli", TILEGX_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1,
- { { 8, 4 }, { 6, 5 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc000000070000fc0ULL,
- 0xf80007e000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000010000fc0ULL,
- 0x000007e000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch", TILEGX_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a801f80000000ULL,
- -1ULL,
- -1ULL,
- 0x41f8000004000000ULL
- }
-#endif
- },
- { "prefetch_add_l1", TILEGX_OPC_PREFETCH_ADD_L1, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1840001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_add_l1_fault", TILEGX_OPC_PREFETCH_ADD_L1_FAULT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1838001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_add_l2", TILEGX_OPC_PREFETCH_ADD_L2, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1850001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_add_l2_fault", TILEGX_OPC_PREFETCH_ADD_L2_FAULT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1848001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_add_l3", TILEGX_OPC_PREFETCH_ADD_L3, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1860001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_add_l3_fault", TILEGX_OPC_PREFETCH_ADD_L3_FAULT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8001f80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1858001f80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "prefetch_l1", TILEGX_OPC_PREFETCH_L1, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a801f80000000ULL,
- -1ULL,
- -1ULL,
- 0x41f8000004000000ULL
- }
-#endif
- },
- { "prefetch_l1_fault", TILEGX_OPC_PREFETCH_L1_FAULT, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a781f80000000ULL,
- -1ULL,
- -1ULL,
- 0x41f8000000000000ULL
- }
-#endif
- },
- { "prefetch_l2", TILEGX_OPC_PREFETCH_L2, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a901f80000000ULL,
- -1ULL,
- -1ULL,
- 0x43f8000004000000ULL
- }
-#endif
- },
- { "prefetch_l2_fault", TILEGX_OPC_PREFETCH_L2_FAULT, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a881f80000000ULL,
- -1ULL,
- -1ULL,
- 0x43f8000000000000ULL
- }
-#endif
- },
- { "prefetch_l3", TILEGX_OPC_PREFETCH_L3, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286aa01f80000000ULL,
- -1ULL,
- -1ULL,
- 0x83f8000000000000ULL
- }
-#endif
- },
- { "prefetch_l3_fault", TILEGX_OPC_PREFETCH_L3_FAULT, 0x12, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff81f80000000ULL,
- 0ULL,
- 0ULL,
- 0xc3f8000004000000ULL
- },
- {
- -1ULL,
- 0x286a981f80000000ULL,
- -1ULL,
- -1ULL,
- 0x81f8000004000000ULL
- }
-#endif
- },
- { "raise", TILEGX_OPC_RAISE, 0x2, 0, TREG_ZERO, 1,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffffffff80000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a44ae80000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "add", TILEGX_OPC_ADD, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000500c0000ULL,
- 0x2806000000000000ULL,
- 0x0000000028040000ULL,
- 0x1802000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "addi", TILEGX_OPC_ADDI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0x0000000078000000ULL,
- 0x3c00000000000000ULL,
- 0ULL
- },
- {
- 0x0000000040100000ULL,
- 0x1808000000000000ULL,
- 0ULL,
- 0x0400000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "addli", TILEGX_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc000000070000000ULL,
- 0xf800000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000010000000ULL,
- 0ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "addx", TILEGX_OPC_ADDX, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050080000ULL,
- 0x2804000000000000ULL,
- 0x0000000028000000ULL,
- 0x1800000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "addxi", TILEGX_OPC_ADDXI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0x0000000078000000ULL,
- 0x3c00000000000000ULL,
- 0ULL
- },
- {
- 0x0000000040200000ULL,
- 0x1810000000000000ULL,
- 0x0000000008000000ULL,
- 0x0800000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "addxli", TILEGX_OPC_ADDXLI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc000000070000000ULL,
- 0xf800000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000020000000ULL,
- 0x0800000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "addxsc", TILEGX_OPC_ADDXSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050040000ULL,
- 0x2802000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "and", TILEGX_OPC_AND, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050100000ULL,
- 0x2808000000000000ULL,
- 0x0000000050000000ULL,
- 0x2c00000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "andi", TILEGX_OPC_ANDI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0x0000000078000000ULL,
- 0x3c00000000000000ULL,
- 0ULL
- },
- {
- 0x0000000040300000ULL,
- 0x1818000000000000ULL,
- 0x0000000010000000ULL,
- 0x0c00000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "beqz", TILEGX_OPC_BEQZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1440000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "beqzt", TILEGX_OPC_BEQZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1400000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bfexts", TILEGX_OPC_BFEXTS, 0x1, 4, TREG_ZERO, 1,
- { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007f000000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000034000000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bfextu", TILEGX_OPC_BFEXTU, 0x1, 4, TREG_ZERO, 1,
- { { 8, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007f000000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000035000000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bfins", TILEGX_OPC_BFINS, 0x1, 4, TREG_ZERO, 1,
- { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007f000000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000036000000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bgez", TILEGX_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x14c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bgezt", TILEGX_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1480000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bgtz", TILEGX_OPC_BGTZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1540000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bgtzt", TILEGX_OPC_BGTZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1500000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blbc", TILEGX_OPC_BLBC, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x15c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blbct", TILEGX_OPC_BLBCT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1580000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blbs", TILEGX_OPC_BLBS, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1640000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blbst", TILEGX_OPC_BLBST, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1600000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blez", TILEGX_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x16c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "blezt", TILEGX_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1680000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bltz", TILEGX_OPC_BLTZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1740000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bltzt", TILEGX_OPC_BLTZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1700000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bnez", TILEGX_OPC_BNEZ, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x17c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "bnezt", TILEGX_OPC_BNEZT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 20 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xffc0000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1780000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "clz", TILEGX_OPC_CLZ, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051481000ULL,
- -1ULL,
- 0x00000000300c1000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmoveqz", TILEGX_OPC_CMOVEQZ, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050140000ULL,
- -1ULL,
- 0x0000000048000000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmovnez", TILEGX_OPC_CMOVNEZ, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050180000ULL,
- -1ULL,
- 0x0000000048040000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmpeq", TILEGX_OPC_CMPEQ, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000501c0000ULL,
- 0x280a000000000000ULL,
- 0x0000000040000000ULL,
- 0x2404000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpeqi", TILEGX_OPC_CMPEQI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0x0000000078000000ULL,
- 0x3c00000000000000ULL,
- 0ULL
- },
- {
- 0x0000000040400000ULL,
- 0x1820000000000000ULL,
- 0x0000000018000000ULL,
- 0x1000000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpexch", TILEGX_OPC_CMPEXCH, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x280e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmpexch4", TILEGX_OPC_CMPEXCH4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x280c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmples", TILEGX_OPC_CMPLES, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050200000ULL,
- 0x2810000000000000ULL,
- 0x0000000038000000ULL,
- 0x2000000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpleu", TILEGX_OPC_CMPLEU, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050240000ULL,
- 0x2812000000000000ULL,
- 0x0000000038040000ULL,
- 0x2002000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmplts", TILEGX_OPC_CMPLTS, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050280000ULL,
- 0x2814000000000000ULL,
- 0x0000000038080000ULL,
- 0x2004000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpltsi", TILEGX_OPC_CMPLTSI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0x0000000078000000ULL,
- 0x3c00000000000000ULL,
- 0ULL
- },
- {
- 0x0000000040500000ULL,
- 0x1828000000000000ULL,
- 0x0000000020000000ULL,
- 0x1400000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpltu", TILEGX_OPC_CMPLTU, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000502c0000ULL,
- 0x2816000000000000ULL,
- 0x00000000380c0000ULL,
- 0x2006000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmpltui", TILEGX_OPC_CMPLTUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040600000ULL,
- 0x1830000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmpne", TILEGX_OPC_CMPNE, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050300000ULL,
- 0x2818000000000000ULL,
- 0x0000000040040000ULL,
- 0x2406000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "cmul", TILEGX_OPC_CMUL, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000504c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmula", TILEGX_OPC_CMULA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050380000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmulaf", TILEGX_OPC_CMULAF, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050340000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmulf", TILEGX_OPC_CMULF, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050400000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmulfr", TILEGX_OPC_CMULFR, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000503c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmulh", TILEGX_OPC_CMULH, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050480000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "cmulhr", TILEGX_OPC_CMULHR, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050440000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "crc32_32", TILEGX_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050500000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "crc32_8", TILEGX_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050540000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ctz", TILEGX_OPC_CTZ, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051482000ULL,
- -1ULL,
- 0x00000000300c2000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "dblalign", TILEGX_OPC_DBLALIGN, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050640000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "dblalign2", TILEGX_OPC_DBLALIGN2, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050580000ULL,
- 0x281a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "dblalign4", TILEGX_OPC_DBLALIGN4, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000505c0000ULL,
- 0x281c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "dblalign6", TILEGX_OPC_DBLALIGN6, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050600000ULL,
- 0x281e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "drain", TILEGX_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a080000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "dtlbpr", TILEGX_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a100000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "exch", TILEGX_OPC_EXCH, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2822000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "exch4", TILEGX_OPC_EXCH4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2820000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_add_flags", TILEGX_OPC_FDOUBLE_ADD_FLAGS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000506c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_addsub", TILEGX_OPC_FDOUBLE_ADDSUB, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050680000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_mul_flags", TILEGX_OPC_FDOUBLE_MUL_FLAGS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050700000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_pack1", TILEGX_OPC_FDOUBLE_PACK1, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050740000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_pack2", TILEGX_OPC_FDOUBLE_PACK2, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050780000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_sub_flags", TILEGX_OPC_FDOUBLE_SUB_FLAGS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000507c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_unpack_max", TILEGX_OPC_FDOUBLE_UNPACK_MAX, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050800000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fdouble_unpack_min", TILEGX_OPC_FDOUBLE_UNPACK_MIN, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050840000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchadd", TILEGX_OPC_FETCHADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x282a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchadd4", TILEGX_OPC_FETCHADD4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2824000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchaddgez", TILEGX_OPC_FETCHADDGEZ, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2828000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchaddgez4", TILEGX_OPC_FETCHADDGEZ4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2826000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchand", TILEGX_OPC_FETCHAND, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x282e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchand4", TILEGX_OPC_FETCHAND4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x282c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchor", TILEGX_OPC_FETCHOR, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2832000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fetchor4", TILEGX_OPC_FETCHOR4, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2830000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "finv", TILEGX_OPC_FINV, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a180000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "flush", TILEGX_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a280000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "flushwb", TILEGX_OPC_FLUSHWB, 0x2, 0, TREG_ZERO, 1,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a200000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fnop", TILEGX_OPC_FNOP, 0xf, 0, TREG_ZERO, 1,
- { { }, { }, { }, { }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0xfffff80000000000ULL,
- 0x00000000780ff000ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- 0x0000000051483000ULL,
- 0x286a300000000000ULL,
- 0x00000000300c3000ULL,
- 0x1c06400000000000ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_add1", TILEGX_OPC_FSINGLE_ADD1, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050880000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_addsub2", TILEGX_OPC_FSINGLE_ADDSUB2, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000508c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_mul1", TILEGX_OPC_FSINGLE_MUL1, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050900000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_mul2", TILEGX_OPC_FSINGLE_MUL2, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050940000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_pack1", TILEGX_OPC_FSINGLE_PACK1, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051484000ULL,
- -1ULL,
- 0x00000000300c4000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_pack2", TILEGX_OPC_FSINGLE_PACK2, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050980000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "fsingle_sub1", TILEGX_OPC_FSINGLE_SUB1, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000509c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "icoh", TILEGX_OPC_ICOH, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a380000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ill", TILEGX_OPC_ILL, 0xa, 0, TREG_ZERO, 1,
- { { 0, }, { }, { 0, }, { }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a400000000000ULL,
- -1ULL,
- 0x1c06480000000000ULL,
- -1ULL
- }
-#endif
- },
- { "inv", TILEGX_OPC_INV, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a480000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "iret", TILEGX_OPC_IRET, 0x2, 0, TREG_ZERO, 1,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a500000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "j", TILEGX_OPC_J, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfc00000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2400000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "jal", TILEGX_OPC_JAL, 0x2, 1, TREG_LR, 1,
- { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfc00000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2000000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "jalr", TILEGX_OPC_JALR, 0xa, 1, TREG_LR, 1,
- { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a600000000000ULL,
- -1ULL,
- 0x1c06580000000000ULL,
- -1ULL
- }
-#endif
- },
- { "jalrp", TILEGX_OPC_JALRP, 0xa, 1, TREG_LR, 1,
- { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a580000000000ULL,
- -1ULL,
- 0x1c06500000000000ULL,
- -1ULL
- }
-#endif
- },
- { "jr", TILEGX_OPC_JR, 0xa, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a700000000000ULL,
- -1ULL,
- 0x1c06680000000000ULL,
- -1ULL
- }
-#endif
- },
- { "jrp", TILEGX_OPC_JRP, 0xa, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 13 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286a680000000000ULL,
- -1ULL,
- 0x1c06600000000000ULL,
- -1ULL
- }
-#endif
- },
- { "ld", TILEGX_OPC_LD, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286ae80000000000ULL,
- -1ULL,
- -1ULL,
- 0x8200000004000000ULL
- }
-#endif
- },
- { "ld1s", TILEGX_OPC_LD1S, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286a780000000000ULL,
- -1ULL,
- -1ULL,
- 0x4000000000000000ULL
- }
-#endif
- },
- { "ld1s_add", TILEGX_OPC_LD1S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1838000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld1u", TILEGX_OPC_LD1U, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286a800000000000ULL,
- -1ULL,
- -1ULL,
- 0x4000000004000000ULL
- }
-#endif
- },
- { "ld1u_add", TILEGX_OPC_LD1U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1840000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld2s", TILEGX_OPC_LD2S, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286a880000000000ULL,
- -1ULL,
- -1ULL,
- 0x4200000000000000ULL
- }
-#endif
- },
- { "ld2s_add", TILEGX_OPC_LD2S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1848000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld2u", TILEGX_OPC_LD2U, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286a900000000000ULL,
- -1ULL,
- -1ULL,
- 0x4200000004000000ULL
- }
-#endif
- },
- { "ld2u_add", TILEGX_OPC_LD2U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1850000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld4s", TILEGX_OPC_LD4S, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286a980000000000ULL,
- -1ULL,
- -1ULL,
- 0x8000000004000000ULL
- }
-#endif
- },
- { "ld4s_add", TILEGX_OPC_LD4S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1858000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld4u", TILEGX_OPC_LD4U, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 26, 14 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x286aa00000000000ULL,
- -1ULL,
- -1ULL,
- 0x8200000000000000ULL
- }
-#endif
- },
- { "ld4u_add", TILEGX_OPC_LD4U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1860000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ld_add", TILEGX_OPC_LD_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18a0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldna", TILEGX_OPC_LDNA, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286aa80000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldna_add", TILEGX_OPC_LDNA_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18a8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt", TILEGX_OPC_LDNT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ae00000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt1s", TILEGX_OPC_LDNT1S, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ab00000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt1s_add", TILEGX_OPC_LDNT1S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1868000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt1u", TILEGX_OPC_LDNT1U, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ab80000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt1u_add", TILEGX_OPC_LDNT1U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1870000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt2s", TILEGX_OPC_LDNT2S, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ac00000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt2s_add", TILEGX_OPC_LDNT2S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1878000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt2u", TILEGX_OPC_LDNT2U, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ac80000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt2u_add", TILEGX_OPC_LDNT2U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1880000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt4s", TILEGX_OPC_LDNT4S, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ad00000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt4s_add", TILEGX_OPC_LDNT4S_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1888000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt4u", TILEGX_OPC_LDNT4U, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286ad80000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt4u_add", TILEGX_OPC_LDNT4U_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1890000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "ldnt_add", TILEGX_OPC_LDNT_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 6, 15, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1898000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "lnk", TILEGX_OPC_LNK, 0xa, 1, TREG_ZERO, 1,
- { { 0, }, { 6 }, { 0, }, { 12 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286af00000000000ULL,
- -1ULL,
- 0x1c06700000000000ULL,
- -1ULL
- }
-#endif
- },
- { "mf", TILEGX_OPC_MF, 0x2, 0, TREG_ZERO, 1,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286af80000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mfspr", TILEGX_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 6, 27 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18b0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mm", TILEGX_OPC_MM, 0x1, 4, TREG_ZERO, 1,
- { { 23, 9, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007f000000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000037000000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mnz", TILEGX_OPC_MNZ, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050a00000ULL,
- 0x2834000000000000ULL,
- 0x0000000048080000ULL,
- 0x2804000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "mtspr", TILEGX_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 28, 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18b8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hs_hs", TILEGX_OPC_MUL_HS_HS, 0x5, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050d40000ULL,
- -1ULL,
- 0x0000000068000000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hs_hu", TILEGX_OPC_MUL_HS_HU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050d80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hs_ls", TILEGX_OPC_MUL_HS_LS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050dc0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hs_lu", TILEGX_OPC_MUL_HS_LU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050e00000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hu_hu", TILEGX_OPC_MUL_HU_HU, 0x5, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050e40000ULL,
- -1ULL,
- 0x0000000068040000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hu_ls", TILEGX_OPC_MUL_HU_LS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050e80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_hu_lu", TILEGX_OPC_MUL_HU_LU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050ec0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_ls_ls", TILEGX_OPC_MUL_LS_LS, 0x5, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050f00000ULL,
- -1ULL,
- 0x0000000068080000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_ls_lu", TILEGX_OPC_MUL_LS_LU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050f40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mul_lu_lu", TILEGX_OPC_MUL_LU_LU, 0x5, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050f80000ULL,
- -1ULL,
- 0x00000000680c0000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hs_hs", TILEGX_OPC_MULA_HS_HS, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050a80000ULL,
- -1ULL,
- 0x0000000070000000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hs_hu", TILEGX_OPC_MULA_HS_HU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050ac0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hs_ls", TILEGX_OPC_MULA_HS_LS, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050b00000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hs_lu", TILEGX_OPC_MULA_HS_LU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050b40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hu_hu", TILEGX_OPC_MULA_HU_HU, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050b80000ULL,
- -1ULL,
- 0x0000000070040000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hu_ls", TILEGX_OPC_MULA_HU_LS, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050bc0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_hu_lu", TILEGX_OPC_MULA_HU_LU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050c00000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_ls_ls", TILEGX_OPC_MULA_LS_LS, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050c40000ULL,
- -1ULL,
- 0x0000000070080000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_ls_lu", TILEGX_OPC_MULA_LS_LU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050c80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mula_lu_lu", TILEGX_OPC_MULA_LU_LU, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050cc0000ULL,
- -1ULL,
- 0x00000000700c0000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mulax", TILEGX_OPC_MULAX, 0x5, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050a40000ULL,
- -1ULL,
- 0x0000000040080000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mulx", TILEGX_OPC_MULX, 0x5, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0x00000000780c0000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000050d00000ULL,
- -1ULL,
- 0x00000000400c0000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "mz", TILEGX_OPC_MZ, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000050fc0000ULL,
- 0x2836000000000000ULL,
- 0x00000000480c0000ULL,
- 0x2806000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "nap", TILEGX_OPC_NAP, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "nop", TILEGX_OPC_NOP, 0xf, 0, TREG_ZERO, 1,
- { { }, { }, { }, { }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0xfffff80000000000ULL,
- 0x00000000780ff000ULL,
- 0x3c07f80000000000ULL,
- 0ULL
- },
- {
- 0x0000000051485000ULL,
- 0x286b080000000000ULL,
- 0x00000000300c5000ULL,
- 0x1c06780000000000ULL,
- -1ULL
- }
-#endif
- },
- { "nor", TILEGX_OPC_NOR, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051000000ULL,
- 0x2838000000000000ULL,
- 0x0000000050040000ULL,
- 0x2c02000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "or", TILEGX_OPC_OR, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051040000ULL,
- 0x283a000000000000ULL,
- 0x0000000050080000ULL,
- 0x2c04000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "ori", TILEGX_OPC_ORI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040700000ULL,
- 0x18c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "pcnt", TILEGX_OPC_PCNT, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051486000ULL,
- -1ULL,
- 0x00000000300c6000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "revbits", TILEGX_OPC_REVBITS, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051487000ULL,
- -1ULL,
- 0x00000000300c7000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "revbytes", TILEGX_OPC_REVBYTES, 0x5, 2, TREG_ZERO, 1,
- { { 8, 9 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051488000ULL,
- -1ULL,
- 0x00000000300c8000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "rotl", TILEGX_OPC_ROTL, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051080000ULL,
- 0x283c000000000000ULL,
- 0x0000000058000000ULL,
- 0x3000000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "rotli", TILEGX_OPC_ROTLI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000060040000ULL,
- 0x3002000000000000ULL,
- 0x0000000078000000ULL,
- 0x3800000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl", TILEGX_OPC_SHL, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051280000ULL,
- 0x284c000000000000ULL,
- 0x0000000058040000ULL,
- 0x3002000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl16insli", TILEGX_OPC_SHL16INSLI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 4 }, { 6, 7, 5 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc000000070000000ULL,
- 0xf800000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000070000000ULL,
- 0x3800000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "shl1add", TILEGX_OPC_SHL1ADD, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051100000ULL,
- 0x2840000000000000ULL,
- 0x0000000030000000ULL,
- 0x1c00000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl1addx", TILEGX_OPC_SHL1ADDX, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000510c0000ULL,
- 0x283e000000000000ULL,
- 0x0000000060040000ULL,
- 0x3402000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl2add", TILEGX_OPC_SHL2ADD, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051180000ULL,
- 0x2844000000000000ULL,
- 0x0000000030040000ULL,
- 0x1c02000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl2addx", TILEGX_OPC_SHL2ADDX, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051140000ULL,
- 0x2842000000000000ULL,
- 0x0000000060080000ULL,
- 0x3404000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl3add", TILEGX_OPC_SHL3ADD, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051200000ULL,
- 0x2848000000000000ULL,
- 0x0000000030080000ULL,
- 0x1c04000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shl3addx", TILEGX_OPC_SHL3ADDX, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000511c0000ULL,
- 0x2846000000000000ULL,
- 0x00000000600c0000ULL,
- 0x3406000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shli", TILEGX_OPC_SHLI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000060080000ULL,
- 0x3004000000000000ULL,
- 0x0000000078040000ULL,
- 0x3802000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shlx", TILEGX_OPC_SHLX, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051240000ULL,
- 0x284a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "shlxi", TILEGX_OPC_SHLXI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000600c0000ULL,
- 0x3006000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "shrs", TILEGX_OPC_SHRS, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x00000000512c0000ULL,
- 0x284e000000000000ULL,
- 0x0000000058080000ULL,
- 0x3004000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shrsi", TILEGX_OPC_SHRSI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000060100000ULL,
- 0x3008000000000000ULL,
- 0x0000000078080000ULL,
- 0x3804000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shru", TILEGX_OPC_SHRU, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051340000ULL,
- 0x2852000000000000ULL,
- 0x00000000580c0000ULL,
- 0x3006000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shrui", TILEGX_OPC_SHRUI, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000060140000ULL,
- 0x300a000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3806000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "shrux", TILEGX_OPC_SHRUX, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051300000ULL,
- 0x2850000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "shruxi", TILEGX_OPC_SHRUXI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000060180000ULL,
- 0x300c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "shufflebytes", TILEGX_OPC_SHUFFLEBYTES, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051380000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "st", TILEGX_OPC_ST, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x2862000000000000ULL,
- -1ULL,
- -1ULL,
- 0xc200000004000000ULL
- }
-#endif
- },
- { "st1", TILEGX_OPC_ST1, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x2854000000000000ULL,
- -1ULL,
- -1ULL,
- 0xc000000000000000ULL
- }
-#endif
- },
- { "st1_add", TILEGX_OPC_ST1_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18c8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "st2", TILEGX_OPC_ST2, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x2856000000000000ULL,
- -1ULL,
- -1ULL,
- 0xc000000004000000ULL
- }
-#endif
- },
- { "st2_add", TILEGX_OPC_ST2_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18d0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "st4", TILEGX_OPC_ST4, 0x12, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 14, 33 } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0xc200000004000000ULL
- },
- {
- -1ULL,
- 0x2858000000000000ULL,
- -1ULL,
- -1ULL,
- 0xc200000000000000ULL
- }
-#endif
- },
- { "st4_add", TILEGX_OPC_ST4_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18d8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "st_add", TILEGX_OPC_ST_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x1900000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt", TILEGX_OPC_STNT, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x2860000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt1", TILEGX_OPC_STNT1, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x285a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt1_add", TILEGX_OPC_STNT1_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18e0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt2", TILEGX_OPC_STNT2, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x285c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt2_add", TILEGX_OPC_STNT2_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18e8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt4", TILEGX_OPC_STNT4, 0x2, 2, TREG_ZERO, 1,
- { { 0, }, { 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x285e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt4_add", TILEGX_OPC_STNT4_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18f0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "stnt_add", TILEGX_OPC_STNT_ADD, 0x2, 3, TREG_ZERO, 1,
- { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x18f8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "sub", TILEGX_OPC_SUB, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051440000ULL,
- 0x2868000000000000ULL,
- 0x00000000280c0000ULL,
- 0x1806000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "subx", TILEGX_OPC_SUBX, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000051400000ULL,
- 0x2866000000000000ULL,
- 0x0000000028080000ULL,
- 0x1804000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "subxsc", TILEGX_OPC_SUBXSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000513c0000ULL,
- 0x2864000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "swint0", TILEGX_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b100000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "swint1", TILEGX_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b180000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "swint2", TILEGX_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b200000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "swint3", TILEGX_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0,
- { { 0, }, { }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b280000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "tblidxb0", TILEGX_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1,
- { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051489000ULL,
- -1ULL,
- 0x00000000300c9000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "tblidxb1", TILEGX_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1,
- { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x000000005148a000ULL,
- -1ULL,
- 0x00000000300ca000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "tblidxb2", TILEGX_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1,
- { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x000000005148b000ULL,
- -1ULL,
- 0x00000000300cb000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "tblidxb3", TILEGX_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1,
- { { 23, 9 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffff000ULL,
- 0ULL,
- 0x00000000780ff000ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x000000005148c000ULL,
- -1ULL,
- 0x00000000300cc000ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1add", TILEGX_OPC_V1ADD, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051500000ULL,
- 0x286e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1addi", TILEGX_OPC_V1ADDI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040800000ULL,
- 0x1908000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1adduc", TILEGX_OPC_V1ADDUC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000514c0000ULL,
- 0x286c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1adiffu", TILEGX_OPC_V1ADIFFU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051540000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1avgu", TILEGX_OPC_V1AVGU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051580000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpeq", TILEGX_OPC_V1CMPEQ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000515c0000ULL,
- 0x2870000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpeqi", TILEGX_OPC_V1CMPEQI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040900000ULL,
- 0x1910000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmples", TILEGX_OPC_V1CMPLES, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051600000ULL,
- 0x2872000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpleu", TILEGX_OPC_V1CMPLEU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051640000ULL,
- 0x2874000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmplts", TILEGX_OPC_V1CMPLTS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051680000ULL,
- 0x2876000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpltsi", TILEGX_OPC_V1CMPLTSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040a00000ULL,
- 0x1918000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpltu", TILEGX_OPC_V1CMPLTU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000516c0000ULL,
- 0x2878000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpltui", TILEGX_OPC_V1CMPLTUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040b00000ULL,
- 0x1920000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1cmpne", TILEGX_OPC_V1CMPNE, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051700000ULL,
- 0x287a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1ddotpu", TILEGX_OPC_V1DDOTPU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052880000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1ddotpua", TILEGX_OPC_V1DDOTPUA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052840000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1ddotpus", TILEGX_OPC_V1DDOTPUS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051780000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1ddotpusa", TILEGX_OPC_V1DDOTPUSA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051740000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotp", TILEGX_OPC_V1DOTP, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051880000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotpa", TILEGX_OPC_V1DOTPA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000517c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotpu", TILEGX_OPC_V1DOTPU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052900000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotpua", TILEGX_OPC_V1DOTPUA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000528c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotpus", TILEGX_OPC_V1DOTPUS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051840000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1dotpusa", TILEGX_OPC_V1DOTPUSA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051800000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1int_h", TILEGX_OPC_V1INT_H, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000518c0000ULL,
- 0x287c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1int_l", TILEGX_OPC_V1INT_L, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051900000ULL,
- 0x287e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1maxu", TILEGX_OPC_V1MAXU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051940000ULL,
- 0x2880000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1maxui", TILEGX_OPC_V1MAXUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040c00000ULL,
- 0x1928000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1minu", TILEGX_OPC_V1MINU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051980000ULL,
- 0x2882000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1minui", TILEGX_OPC_V1MINUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040d00000ULL,
- 0x1930000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1mnz", TILEGX_OPC_V1MNZ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000519c0000ULL,
- 0x2884000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1multu", TILEGX_OPC_V1MULTU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051a00000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1mulu", TILEGX_OPC_V1MULU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051a80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1mulus", TILEGX_OPC_V1MULUS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051a40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1mz", TILEGX_OPC_V1MZ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051ac0000ULL,
- 0x2886000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1sadau", TILEGX_OPC_V1SADAU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051b00000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1sadu", TILEGX_OPC_V1SADU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051b40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shl", TILEGX_OPC_V1SHL, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051b80000ULL,
- 0x2888000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shli", TILEGX_OPC_V1SHLI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000601c0000ULL,
- 0x300e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shrs", TILEGX_OPC_V1SHRS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051bc0000ULL,
- 0x288a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shrsi", TILEGX_OPC_V1SHRSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000060200000ULL,
- 0x3010000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shru", TILEGX_OPC_V1SHRU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051c00000ULL,
- 0x288c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1shrui", TILEGX_OPC_V1SHRUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000060240000ULL,
- 0x3012000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1sub", TILEGX_OPC_V1SUB, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051c80000ULL,
- 0x2890000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v1subuc", TILEGX_OPC_V1SUBUC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051c40000ULL,
- 0x288e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2add", TILEGX_OPC_V2ADD, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051d00000ULL,
- 0x2894000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2addi", TILEGX_OPC_V2ADDI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040e00000ULL,
- 0x1938000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2addsc", TILEGX_OPC_V2ADDSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051cc0000ULL,
- 0x2892000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2adiffs", TILEGX_OPC_V2ADIFFS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051d40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2avgs", TILEGX_OPC_V2AVGS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051d80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpeq", TILEGX_OPC_V2CMPEQ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051dc0000ULL,
- 0x2896000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpeqi", TILEGX_OPC_V2CMPEQI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000040f00000ULL,
- 0x1940000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmples", TILEGX_OPC_V2CMPLES, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051e00000ULL,
- 0x2898000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpleu", TILEGX_OPC_V2CMPLEU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051e40000ULL,
- 0x289a000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmplts", TILEGX_OPC_V2CMPLTS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051e80000ULL,
- 0x289c000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpltsi", TILEGX_OPC_V2CMPLTSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000041000000ULL,
- 0x1948000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpltu", TILEGX_OPC_V2CMPLTU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051ec0000ULL,
- 0x289e000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpltui", TILEGX_OPC_V2CMPLTUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000041100000ULL,
- 0x1950000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2cmpne", TILEGX_OPC_V2CMPNE, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051f00000ULL,
- 0x28a0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2dotp", TILEGX_OPC_V2DOTP, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051f80000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2dotpa", TILEGX_OPC_V2DOTPA, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051f40000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2int_h", TILEGX_OPC_V2INT_H, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000051fc0000ULL,
- 0x28a2000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2int_l", TILEGX_OPC_V2INT_L, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052000000ULL,
- 0x28a4000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2maxs", TILEGX_OPC_V2MAXS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052040000ULL,
- 0x28a6000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2maxsi", TILEGX_OPC_V2MAXSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000041200000ULL,
- 0x1958000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2mins", TILEGX_OPC_V2MINS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052080000ULL,
- 0x28a8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2minsi", TILEGX_OPC_V2MINSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000041300000ULL,
- 0x1960000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2mnz", TILEGX_OPC_V2MNZ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000520c0000ULL,
- 0x28aa000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2mulfsc", TILEGX_OPC_V2MULFSC, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052100000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2muls", TILEGX_OPC_V2MULS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052140000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2mults", TILEGX_OPC_V2MULTS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052180000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2mz", TILEGX_OPC_V2MZ, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000521c0000ULL,
- 0x28ac000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2packh", TILEGX_OPC_V2PACKH, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052200000ULL,
- 0x28ae000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2packl", TILEGX_OPC_V2PACKL, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052240000ULL,
- 0x28b0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2packuc", TILEGX_OPC_V2PACKUC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052280000ULL,
- 0x28b2000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2sadas", TILEGX_OPC_V2SADAS, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000522c0000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2sadau", TILEGX_OPC_V2SADAU, 0x1, 3, TREG_ZERO, 1,
- { { 23, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052300000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2sads", TILEGX_OPC_V2SADS, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052340000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2sadu", TILEGX_OPC_V2SADU, 0x1, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052380000ULL,
- -1ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shl", TILEGX_OPC_V2SHL, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052400000ULL,
- 0x28b6000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shli", TILEGX_OPC_V2SHLI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000060280000ULL,
- 0x3014000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shlsc", TILEGX_OPC_V2SHLSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000523c0000ULL,
- 0x28b4000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shrs", TILEGX_OPC_V2SHRS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052440000ULL,
- 0x28b8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shrsi", TILEGX_OPC_V2SHRSI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000602c0000ULL,
- 0x3016000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shru", TILEGX_OPC_V2SHRU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052480000ULL,
- 0x28ba000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2shrui", TILEGX_OPC_V2SHRUI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 29 }, { 6, 7, 30 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000060300000ULL,
- 0x3018000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2sub", TILEGX_OPC_V2SUB, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052500000ULL,
- 0x28be000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v2subsc", TILEGX_OPC_V2SUBSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000524c0000ULL,
- 0x28bc000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4add", TILEGX_OPC_V4ADD, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052580000ULL,
- 0x28c2000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4addsc", TILEGX_OPC_V4ADDSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052540000ULL,
- 0x28c0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4int_h", TILEGX_OPC_V4INT_H, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000525c0000ULL,
- 0x28c4000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4int_l", TILEGX_OPC_V4INT_L, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052600000ULL,
- 0x28c6000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4packsc", TILEGX_OPC_V4PACKSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052640000ULL,
- 0x28c8000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4shl", TILEGX_OPC_V4SHL, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000526c0000ULL,
- 0x28cc000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4shlsc", TILEGX_OPC_V4SHLSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052680000ULL,
- 0x28ca000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4shrs", TILEGX_OPC_V4SHRS, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052700000ULL,
- 0x28ce000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4shru", TILEGX_OPC_V4SHRU, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052740000ULL,
- 0x28d0000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4sub", TILEGX_OPC_V4SUB, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x00000000527c0000ULL,
- 0x28d4000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "v4subsc", TILEGX_OPC_V4SUBSC, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000052780000ULL,
- 0x28d2000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "wh64", TILEGX_OPC_WH64, 0x2, 1, TREG_ZERO, 1,
- { { 0, }, { 7 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0ULL,
- 0xfffff80000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- -1ULL,
- 0x286b300000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { "xor", TILEGX_OPC_XOR, 0xf, 3, TREG_ZERO, 1,
- { { 8, 9, 16 }, { 6, 7, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ffc0000ULL,
- 0xfffe000000000000ULL,
- 0x00000000780c0000ULL,
- 0x3c06000000000000ULL,
- 0ULL
- },
- {
- 0x0000000052800000ULL,
- 0x28d6000000000000ULL,
- 0x00000000500c0000ULL,
- 0x2c06000000000000ULL,
- -1ULL
- }
-#endif
- },
- { "xori", TILEGX_OPC_XORI, 0x3, 3, TREG_ZERO, 1,
- { { 8, 9, 0 }, { 6, 7, 1 }, { 0, }, { 0, }, { 0, } },
-#ifndef DISASM_ONLY
- {
- 0xc00000007ff00000ULL,
- 0xfff8000000000000ULL,
- 0ULL,
- 0ULL,
- 0ULL
- },
- {
- 0x0000000041400000ULL,
- 0x1968000000000000ULL,
- -1ULL,
- -1ULL,
- -1ULL
- }
-#endif
- },
- { NULL, TILEGX_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } },
-#ifndef DISASM_ONLY
- { 0, }, { 0, }
-#endif
- }
-};
-
-#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6))
-#define CHILD(array_index) (TILEGX_OPC_NONE + (array_index))
-
-static const unsigned short decode_X0_fsm[936] =
-{
- BITFIELD(22, 9) /* index 0 */,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BFEXTS,
- TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTU,
- TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFINS,
- TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_MM,
- TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(528), CHILD(578),
- CHILD(583), CHILD(588), CHILD(593), CHILD(598), TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, CHILD(603), CHILD(620), CHILD(637), CHILD(654), CHILD(671),
- CHILD(703), CHILD(797), CHILD(814), CHILD(831), CHILD(848), CHILD(865),
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, CHILD(889), TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
- BITFIELD(6, 2) /* index 513 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518),
- BITFIELD(8, 2) /* index 518 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523),
- BITFIELD(10, 2) /* index 523 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI,
- BITFIELD(20, 2) /* index 528 */,
- TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548),
- BITFIELD(6, 2) /* index 533 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538),
- BITFIELD(8, 2) /* index 538 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543),
- BITFIELD(10, 2) /* index 543 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
- BITFIELD(0, 2) /* index 548 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553),
- BITFIELD(2, 2) /* index 553 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558),
- BITFIELD(4, 2) /* index 558 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563),
- BITFIELD(6, 2) /* index 563 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568),
- BITFIELD(8, 2) /* index 568 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573),
- BITFIELD(10, 2) /* index 573 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
- BITFIELD(20, 2) /* index 578 */,
- TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, TILEGX_OPC_ORI,
- BITFIELD(20, 2) /* index 583 */,
- TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, TILEGX_OPC_V1CMPLTSI,
- TILEGX_OPC_V1CMPLTUI,
- BITFIELD(20, 2) /* index 588 */,
- TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, TILEGX_OPC_V2ADDI,
- TILEGX_OPC_V2CMPEQI,
- BITFIELD(20, 2) /* index 593 */,
- TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, TILEGX_OPC_V2MAXSI,
- TILEGX_OPC_V2MINSI,
- BITFIELD(20, 2) /* index 598 */,
- TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(18, 4) /* index 603 */,
- TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD,
- TILEGX_OPC_AND, TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_CMPEQ,
- TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
- TILEGX_OPC_CMPNE, TILEGX_OPC_CMULAF, TILEGX_OPC_CMULA, TILEGX_OPC_CMULFR,
- BITFIELD(18, 4) /* index 620 */,
- TILEGX_OPC_CMULF, TILEGX_OPC_CMULHR, TILEGX_OPC_CMULH, TILEGX_OPC_CMUL,
- TILEGX_OPC_CRC32_32, TILEGX_OPC_CRC32_8, TILEGX_OPC_DBLALIGN2,
- TILEGX_OPC_DBLALIGN4, TILEGX_OPC_DBLALIGN6, TILEGX_OPC_DBLALIGN,
- TILEGX_OPC_FDOUBLE_ADDSUB, TILEGX_OPC_FDOUBLE_ADD_FLAGS,
- TILEGX_OPC_FDOUBLE_MUL_FLAGS, TILEGX_OPC_FDOUBLE_PACK1,
- TILEGX_OPC_FDOUBLE_PACK2, TILEGX_OPC_FDOUBLE_SUB_FLAGS,
- BITFIELD(18, 4) /* index 637 */,
- TILEGX_OPC_FDOUBLE_UNPACK_MAX, TILEGX_OPC_FDOUBLE_UNPACK_MIN,
- TILEGX_OPC_FSINGLE_ADD1, TILEGX_OPC_FSINGLE_ADDSUB2,
- TILEGX_OPC_FSINGLE_MUL1, TILEGX_OPC_FSINGLE_MUL2, TILEGX_OPC_FSINGLE_PACK2,
- TILEGX_OPC_FSINGLE_SUB1, TILEGX_OPC_MNZ, TILEGX_OPC_MULAX,
- TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HS_HU, TILEGX_OPC_MULA_HS_LS,
- TILEGX_OPC_MULA_HS_LU, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_HU_LS,
- BITFIELD(18, 4) /* index 654 */,
- TILEGX_OPC_MULA_HU_LU, TILEGX_OPC_MULA_LS_LS, TILEGX_OPC_MULA_LS_LU,
- TILEGX_OPC_MULA_LU_LU, TILEGX_OPC_MULX, TILEGX_OPC_MUL_HS_HS,
- TILEGX_OPC_MUL_HS_HU, TILEGX_OPC_MUL_HS_LS, TILEGX_OPC_MUL_HS_LU,
- TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_HU_LS, TILEGX_OPC_MUL_HU_LU,
- TILEGX_OPC_MUL_LS_LS, TILEGX_OPC_MUL_LS_LU, TILEGX_OPC_MUL_LU_LU,
- TILEGX_OPC_MZ,
- BITFIELD(18, 4) /* index 671 */,
- TILEGX_OPC_NOR, CHILD(688), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL,
- TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_SHUFFLEBYTES,
- TILEGX_OPC_SUBXSC,
- BITFIELD(12, 2) /* index 688 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(693),
- BITFIELD(14, 2) /* index 693 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(698),
- BITFIELD(16, 2) /* index 698 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
- BITFIELD(18, 4) /* index 703 */,
- TILEGX_OPC_SUBX, TILEGX_OPC_SUB, CHILD(720), TILEGX_OPC_V1ADDUC,
- TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADIFFU, TILEGX_OPC_V1AVGU,
- TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU,
- TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE,
- TILEGX_OPC_V1DDOTPUSA, TILEGX_OPC_V1DDOTPUS, TILEGX_OPC_V1DOTPA,
- BITFIELD(12, 4) /* index 720 */,
- TILEGX_OPC_NONE, CHILD(737), CHILD(742), CHILD(747), CHILD(752), CHILD(757),
- CHILD(762), CHILD(767), CHILD(772), CHILD(777), CHILD(782), CHILD(787),
- CHILD(792), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 737 */,
- TILEGX_OPC_CLZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 742 */,
- TILEGX_OPC_CTZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 747 */,
- TILEGX_OPC_FNOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 752 */,
- TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 757 */,
- TILEGX_OPC_NOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 762 */,
- TILEGX_OPC_PCNT, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 767 */,
- TILEGX_OPC_REVBITS, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 772 */,
- TILEGX_OPC_REVBYTES, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 777 */,
- TILEGX_OPC_TBLIDXB0, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 782 */,
- TILEGX_OPC_TBLIDXB1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 787 */,
- TILEGX_OPC_TBLIDXB2, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(16, 2) /* index 792 */,
- TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(18, 4) /* index 797 */,
- TILEGX_OPC_V1DOTPUSA, TILEGX_OPC_V1DOTPUS, TILEGX_OPC_V1DOTP,
- TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1MAXU,
- TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MULTU, TILEGX_OPC_V1MULUS,
- TILEGX_OPC_V1MULU, TILEGX_OPC_V1MZ, TILEGX_OPC_V1SADAU, TILEGX_OPC_V1SADU,
- TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS,
- BITFIELD(18, 4) /* index 814 */,
- TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC,
- TILEGX_OPC_V2ADD, TILEGX_OPC_V2ADIFFS, TILEGX_OPC_V2AVGS,
- TILEGX_OPC_V2CMPEQ, TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU,
- TILEGX_OPC_V2CMPLTS, TILEGX_OPC_V2CMPLTU, TILEGX_OPC_V2CMPNE,
- TILEGX_OPC_V2DOTPA, TILEGX_OPC_V2DOTP, TILEGX_OPC_V2INT_H,
- BITFIELD(18, 4) /* index 831 */,
- TILEGX_OPC_V2INT_L, TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ,
- TILEGX_OPC_V2MULFSC, TILEGX_OPC_V2MULS, TILEGX_OPC_V2MULTS, TILEGX_OPC_V2MZ,
- TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC,
- TILEGX_OPC_V2SADAS, TILEGX_OPC_V2SADAU, TILEGX_OPC_V2SADS,
- TILEGX_OPC_V2SADU, TILEGX_OPC_V2SHLSC,
- BITFIELD(18, 4) /* index 848 */,
- TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, TILEGX_OPC_V2SUBSC,
- TILEGX_OPC_V2SUB, TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H,
- TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC,
- TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC,
- TILEGX_OPC_V4SUB,
- BITFIELD(18, 3) /* index 865 */,
- CHILD(874), CHILD(877), CHILD(880), CHILD(883), CHILD(886), TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(21, 1) /* index 874 */,
- TILEGX_OPC_XOR, TILEGX_OPC_NONE,
- BITFIELD(21, 1) /* index 877 */,
- TILEGX_OPC_V1DDOTPUA, TILEGX_OPC_NONE,
- BITFIELD(21, 1) /* index 880 */,
- TILEGX_OPC_V1DDOTPU, TILEGX_OPC_NONE,
- BITFIELD(21, 1) /* index 883 */,
- TILEGX_OPC_V1DOTPUA, TILEGX_OPC_NONE,
- BITFIELD(21, 1) /* index 886 */,
- TILEGX_OPC_V1DOTPU, TILEGX_OPC_NONE,
- BITFIELD(18, 4) /* index 889 */,
- TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI,
- TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI,
- TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI,
- TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE,
- BITFIELD(0, 2) /* index 906 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(911),
- BITFIELD(2, 2) /* index 911 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(916),
- BITFIELD(4, 2) /* index 916 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(921),
- BITFIELD(6, 2) /* index 921 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(926),
- BITFIELD(8, 2) /* index 926 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(931),
- BITFIELD(10, 2) /* index 931 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- TILEGX_OPC_INFOL,
-};
-
-static const unsigned short decode_X1_fsm[1266] =
-{
- BITFIELD(53, 9) /* index 0 */,
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
- CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
- TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BEQZT,
- TILEGX_OPC_BEQZT, TILEGX_OPC_BEQZ, TILEGX_OPC_BEQZ, TILEGX_OPC_BGEZT,
- TILEGX_OPC_BGEZT, TILEGX_OPC_BGEZ, TILEGX_OPC_BGEZ, TILEGX_OPC_BGTZT,
- TILEGX_OPC_BGTZT, TILEGX_OPC_BGTZ, TILEGX_OPC_BGTZ, TILEGX_OPC_BLBCT,
- TILEGX_OPC_BLBCT, TILEGX_OPC_BLBC, TILEGX_OPC_BLBC, TILEGX_OPC_BLBST,
- TILEGX_OPC_BLBST, TILEGX_OPC_BLBS, TILEGX_OPC_BLBS, TILEGX_OPC_BLEZT,
- TILEGX_OPC_BLEZT, TILEGX_OPC_BLEZ, TILEGX_OPC_BLEZ, TILEGX_OPC_BLTZT,
- TILEGX_OPC_BLTZT, TILEGX_OPC_BLTZ, TILEGX_OPC_BLTZ, TILEGX_OPC_BNEZT,
- TILEGX_OPC_BNEZT, TILEGX_OPC_BNEZ, TILEGX_OPC_BNEZ, CHILD(528), CHILD(578),
- CHILD(598), CHILD(703), CHILD(723), CHILD(728), CHILD(753), CHILD(758),
- CHILD(763), CHILD(768), CHILD(773), CHILD(778), TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
- TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
- CHILD(783), CHILD(800), CHILD(832), CHILD(849), CHILD(1168), CHILD(1185),
- CHILD(1202), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1219), TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236), CHILD(1236),
- CHILD(1236),
- BITFIELD(37, 2) /* index 513 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518),
- BITFIELD(39, 2) /* index 518 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523),
- BITFIELD(41, 2) /* index 523 */,
- TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI,
- BITFIELD(51, 2) /* index 528 */,
- TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548),
- BITFIELD(37, 2) /* index 533 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538),
- BITFIELD(39, 2) /* index 538 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543),
- BITFIELD(41, 2) /* index 543 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
- BITFIELD(31, 2) /* index 548 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553),
- BITFIELD(33, 2) /* index 553 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558),
- BITFIELD(35, 2) /* index 558 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563),
- BITFIELD(37, 2) /* index 563 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568),
- BITFIELD(39, 2) /* index 568 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573),
- BITFIELD(41, 2) /* index 573 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
- BITFIELD(51, 2) /* index 578 */,
- TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, CHILD(583),
- BITFIELD(31, 2) /* index 583 */,
- TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(588),
- BITFIELD(33, 2) /* index 588 */,
- TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(593),
- BITFIELD(35, 2) /* index 593 */,
- TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD,
- TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
- BITFIELD(51, 2) /* index 598 */,
- CHILD(603), CHILD(618), CHILD(633), CHILD(648),
- BITFIELD(31, 2) /* index 603 */,
- TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(608),
- BITFIELD(33, 2) /* index 608 */,
- TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(613),
- BITFIELD(35, 2) /* index 613 */,
- TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD,
- TILEGX_OPC_PREFETCH_ADD_L1,
- BITFIELD(31, 2) /* index 618 */,
- TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(623),
- BITFIELD(33, 2) /* index 623 */,
- TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(628),
- BITFIELD(35, 2) /* index 628 */,
- TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD,
- TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
- BITFIELD(31, 2) /* index 633 */,
- TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(638),
- BITFIELD(33, 2) /* index 638 */,
- TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(643),
- BITFIELD(35, 2) /* index 643 */,
- TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD,
- TILEGX_OPC_PREFETCH_ADD_L2,
- BITFIELD(31, 2) /* index 648 */,
- CHILD(653), CHILD(653), CHILD(653), CHILD(673),
- BITFIELD(43, 2) /* index 653 */,
- CHILD(658), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
- BITFIELD(45, 2) /* index 658 */,
- CHILD(663), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
- BITFIELD(47, 2) /* index 663 */,
- CHILD(668), TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
- BITFIELD(49, 2) /* index 668 */,
- TILEGX_OPC_LD4S_TLS, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
- TILEGX_OPC_LD4S_ADD,
- BITFIELD(33, 2) /* index 673 */,
- CHILD(653), CHILD(653), CHILD(653), CHILD(678),
- BITFIELD(35, 2) /* index 678 */,
- CHILD(653), CHILD(653), CHILD(653), CHILD(683),
- BITFIELD(43, 2) /* index 683 */,
- CHILD(688), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- BITFIELD(45, 2) /* index 688 */,
- CHILD(693), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- BITFIELD(47, 2) /* index 693 */,
- CHILD(698), TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- BITFIELD(49, 2) /* index 698 */,
- TILEGX_OPC_LD4S_TLS, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- TILEGX_OPC_PREFETCH_ADD_L3_FAULT, TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
- BITFIELD(51, 2) /* index 703 */,
- CHILD(708), TILEGX_OPC_LDNT1S_ADD, TILEGX_OPC_LDNT1U_ADD,
- TILEGX_OPC_LDNT2S_ADD,
- BITFIELD(31, 2) /* index 708 */,
- TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(713),
- BITFIELD(33, 2) /* index 713 */,
- TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(718),
- BITFIELD(35, 2) /* index 718 */,
- TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD,
- TILEGX_OPC_PREFETCH_ADD_L3,
- BITFIELD(51, 2) /* index 723 */,
- TILEGX_OPC_LDNT2U_ADD, TILEGX_OPC_LDNT4S_ADD, TILEGX_OPC_LDNT4U_ADD,
- TILEGX_OPC_LDNT_ADD,
- BITFIELD(51, 2) /* index 728 */,
- CHILD(733), TILEGX_OPC_LDNA_ADD, TILEGX_OPC_MFSPR, TILEGX_OPC_MTSPR,
- BITFIELD(43, 2) /* index 733 */,
- CHILD(738), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
- BITFIELD(45, 2) /* index 738 */,
- CHILD(743), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
- BITFIELD(47, 2) /* index 743 */,
- CHILD(748), TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
- BITFIELD(49, 2) /* index 748 */,
- TILEGX_OPC_LD_TLS, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD, TILEGX_OPC_LD_ADD,
- BITFIELD(51, 2) /* index 753 */,
- TILEGX_OPC_ORI, TILEGX_OPC_ST1_ADD, TILEGX_OPC_ST2_ADD, TILEGX_OPC_ST4_ADD,
- BITFIELD(51, 2) /* index 758 */,
- TILEGX_OPC_STNT1_ADD, TILEGX_OPC_STNT2_ADD, TILEGX_OPC_STNT4_ADD,
- TILEGX_OPC_STNT_ADD,
- BITFIELD(51, 2) /* index 763 */,
- TILEGX_OPC_ST_ADD, TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI,
- TILEGX_OPC_V1CMPLTSI,
- BITFIELD(51, 2) /* index 768 */,
- TILEGX_OPC_V1CMPLTUI, TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI,
- TILEGX_OPC_V2ADDI,
- BITFIELD(51, 2) /* index 773 */,
- TILEGX_OPC_V2CMPEQI, TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI,
- TILEGX_OPC_V2MAXSI,
- BITFIELD(51, 2) /* index 778 */,
- TILEGX_OPC_V2MINSI, TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(49, 4) /* index 783 */,
- TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD,
- TILEGX_OPC_AND, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPEXCH4, TILEGX_OPC_CMPEXCH,
- TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
- TILEGX_OPC_CMPNE, TILEGX_OPC_DBLALIGN2, TILEGX_OPC_DBLALIGN4,
- TILEGX_OPC_DBLALIGN6,
- BITFIELD(49, 4) /* index 800 */,
- TILEGX_OPC_EXCH4, TILEGX_OPC_EXCH, TILEGX_OPC_FETCHADD4,
- TILEGX_OPC_FETCHADDGEZ4, TILEGX_OPC_FETCHADDGEZ, TILEGX_OPC_FETCHADD,
- TILEGX_OPC_FETCHAND4, TILEGX_OPC_FETCHAND, TILEGX_OPC_FETCHOR4,
- TILEGX_OPC_FETCHOR, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, TILEGX_OPC_NOR,
- CHILD(817), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX,
- BITFIELD(43, 2) /* index 817 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(822),
- BITFIELD(45, 2) /* index 822 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(827),
- BITFIELD(47, 2) /* index 827 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
- BITFIELD(49, 4) /* index 832 */,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL,
- TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_ST1,
- TILEGX_OPC_ST2, TILEGX_OPC_ST4, TILEGX_OPC_STNT1, TILEGX_OPC_STNT2,
- TILEGX_OPC_STNT4,
- BITFIELD(46, 7) /* index 849 */,
- TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT,
- TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT,
- TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST,
- TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_SUBXSC,
- TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC,
- TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBX,
- TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX,
- TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
- TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB,
- TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, CHILD(978), CHILD(987),
- CHILD(1066), CHILD(1150), CHILD(1159), TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC,
- TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC,
- TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD,
- TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD,
- TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
- TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
- TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
- TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES,
- TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES,
- TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU,
- TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU,
- TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU,
- TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
- TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
- TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
- TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU,
- TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU,
- TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE,
- TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE,
- TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE,
- TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
- TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
- TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
- TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
- TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
- TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
- BITFIELD(43, 3) /* index 978 */,
- TILEGX_OPC_NONE, TILEGX_OPC_DRAIN, TILEGX_OPC_DTLBPR, TILEGX_OPC_FINV,
- TILEGX_OPC_FLUSHWB, TILEGX_OPC_FLUSH, TILEGX_OPC_FNOP, TILEGX_OPC_ICOH,
- BITFIELD(43, 3) /* index 987 */,
- CHILD(996), TILEGX_OPC_INV, TILEGX_OPC_IRET, TILEGX_OPC_JALRP,
- TILEGX_OPC_JALR, TILEGX_OPC_JRP, TILEGX_OPC_JR, CHILD(1051),
- BITFIELD(31, 2) /* index 996 */,
- CHILD(1001), CHILD(1026), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(33, 2) /* index 1001 */,
- TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1006),
- BITFIELD(35, 2) /* index 1006 */,
- TILEGX_OPC_ILL, CHILD(1011), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(37, 2) /* index 1011 */,
- TILEGX_OPC_ILL, CHILD(1016), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(39, 2) /* index 1016 */,
- TILEGX_OPC_ILL, CHILD(1021), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(41, 2) /* index 1021 */,
- TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_BPT, TILEGX_OPC_ILL,
- BITFIELD(33, 2) /* index 1026 */,
- TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(1031),
- BITFIELD(35, 2) /* index 1031 */,
- TILEGX_OPC_ILL, CHILD(1036), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(37, 2) /* index 1036 */,
- TILEGX_OPC_ILL, CHILD(1041), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(39, 2) /* index 1041 */,
- TILEGX_OPC_ILL, CHILD(1046), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
- BITFIELD(41, 2) /* index 1046 */,
- TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_RAISE, TILEGX_OPC_ILL,
- BITFIELD(31, 2) /* index 1051 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1056),
- BITFIELD(33, 2) /* index 1056 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1061),
- BITFIELD(35, 2) /* index 1061 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S,
- TILEGX_OPC_PREFETCH_L1_FAULT,
- BITFIELD(43, 3) /* index 1066 */,
- CHILD(1075), CHILD(1090), CHILD(1105), CHILD(1120), CHILD(1135),
- TILEGX_OPC_LDNA, TILEGX_OPC_LDNT1S, TILEGX_OPC_LDNT1U,
- BITFIELD(31, 2) /* index 1075 */,
- TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1080),
- BITFIELD(33, 2) /* index 1080 */,
- TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1085),
- BITFIELD(35, 2) /* index 1085 */,
- TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH,
- BITFIELD(31, 2) /* index 1090 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1095),
- BITFIELD(33, 2) /* index 1095 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1100),
- BITFIELD(35, 2) /* index 1100 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S,
- TILEGX_OPC_PREFETCH_L2_FAULT,
- BITFIELD(31, 2) /* index 1105 */,
- TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1110),
- BITFIELD(33, 2) /* index 1110 */,
- TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1115),
- BITFIELD(35, 2) /* index 1115 */,
- TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2,
- BITFIELD(31, 2) /* index 1120 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1125),
- BITFIELD(33, 2) /* index 1125 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1130),
- BITFIELD(35, 2) /* index 1130 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S,
- TILEGX_OPC_PREFETCH_L3_FAULT,
- BITFIELD(31, 2) /* index 1135 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1140),
- BITFIELD(33, 2) /* index 1140 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1145),
- BITFIELD(35, 2) /* index 1145 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3,
- BITFIELD(43, 3) /* index 1150 */,
- TILEGX_OPC_LDNT2S, TILEGX_OPC_LDNT2U, TILEGX_OPC_LDNT4S, TILEGX_OPC_LDNT4U,
- TILEGX_OPC_LDNT, TILEGX_OPC_LD, TILEGX_OPC_LNK, TILEGX_OPC_MF,
- BITFIELD(43, 3) /* index 1159 */,
- TILEGX_OPC_NAP, TILEGX_OPC_NOP, TILEGX_OPC_SWINT0, TILEGX_OPC_SWINT1,
- TILEGX_OPC_SWINT2, TILEGX_OPC_SWINT3, TILEGX_OPC_WH64, TILEGX_OPC_NONE,
- BITFIELD(49, 4) /* index 1168 */,
- TILEGX_OPC_V1MAXU, TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MZ,
- TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC,
- TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, TILEGX_OPC_V2ADD, TILEGX_OPC_V2CMPEQ,
- TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, TILEGX_OPC_V2CMPLTS,
- TILEGX_OPC_V2CMPLTU,
- BITFIELD(49, 4) /* index 1185 */,
- TILEGX_OPC_V2CMPNE, TILEGX_OPC_V2INT_H, TILEGX_OPC_V2INT_L,
- TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, TILEGX_OPC_V2MZ,
- TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC,
- TILEGX_OPC_V2SHLSC, TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU,
- TILEGX_OPC_V2SUBSC, TILEGX_OPC_V2SUB,
- BITFIELD(49, 4) /* index 1202 */,
- TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H,
- TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC,
- TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC,
- TILEGX_OPC_V4SUB, TILEGX_OPC_XOR, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(49, 4) /* index 1219 */,
- TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI,
- TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI,
- TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI,
- TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE,
- BITFIELD(31, 2) /* index 1236 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(1241),
- BITFIELD(33, 2) /* index 1241 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(1246),
- BITFIELD(35, 2) /* index 1246 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(1251),
- BITFIELD(37, 2) /* index 1251 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(1256),
- BITFIELD(39, 2) /* index 1256 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- CHILD(1261),
- BITFIELD(41, 2) /* index 1261 */,
- TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
- TILEGX_OPC_INFOL,
-};
-
-static const unsigned short decode_Y0_fsm[178] =
-{
- BITFIELD(27, 4) /* index 0 */,
- CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI,
- TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(118), CHILD(123),
- CHILD(128), CHILD(133), CHILD(153), CHILD(158), CHILD(163), CHILD(168),
- CHILD(173),
- BITFIELD(6, 2) /* index 17 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22),
- BITFIELD(8, 2) /* index 22 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27),
- BITFIELD(10, 2) /* index 27 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
- BITFIELD(0, 2) /* index 32 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37),
- BITFIELD(2, 2) /* index 37 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42),
- BITFIELD(4, 2) /* index 42 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47),
- BITFIELD(6, 2) /* index 47 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52),
- BITFIELD(8, 2) /* index 52 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57),
- BITFIELD(10, 2) /* index 57 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
- BITFIELD(18, 2) /* index 62 */,
- TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
- BITFIELD(15, 5) /* index 67 */,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD,
- TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD,
- TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(100),
- CHILD(109), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(12, 3) /* index 100 */,
- TILEGX_OPC_NONE, TILEGX_OPC_CLZ, TILEGX_OPC_CTZ, TILEGX_OPC_FNOP,
- TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NOP, TILEGX_OPC_PCNT,
- TILEGX_OPC_REVBITS,
- BITFIELD(12, 3) /* index 109 */,
- TILEGX_OPC_REVBYTES, TILEGX_OPC_TBLIDXB0, TILEGX_OPC_TBLIDXB1,
- TILEGX_OPC_TBLIDXB2, TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- TILEGX_OPC_NONE,
- BITFIELD(18, 2) /* index 118 */,
- TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
- BITFIELD(18, 2) /* index 123 */,
- TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, TILEGX_OPC_MULAX, TILEGX_OPC_MULX,
- BITFIELD(18, 2) /* index 128 */,
- TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_MNZ, TILEGX_OPC_MZ,
- BITFIELD(18, 2) /* index 133 */,
- TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(138), TILEGX_OPC_XOR,
- BITFIELD(12, 2) /* index 138 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(143),
- BITFIELD(14, 2) /* index 143 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(148),
- BITFIELD(16, 2) /* index 148 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
- BITFIELD(18, 2) /* index 153 */,
- TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU,
- BITFIELD(18, 2) /* index 158 */,
- TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX,
- TILEGX_OPC_SHL3ADDX,
- BITFIELD(18, 2) /* index 163 */,
- TILEGX_OPC_MUL_HS_HS, TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_LS_LS,
- TILEGX_OPC_MUL_LU_LU,
- BITFIELD(18, 2) /* index 168 */,
- TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_LS_LS,
- TILEGX_OPC_MULA_LU_LU,
- BITFIELD(18, 2) /* index 173 */,
- TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI,
-};
-
-static const unsigned short decode_Y1_fsm[167] =
-{
- BITFIELD(58, 4) /* index 0 */,
- TILEGX_OPC_NONE, CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI,
- TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(117), CHILD(122),
- CHILD(127), CHILD(132), CHILD(152), CHILD(157), CHILD(162), TILEGX_OPC_NONE,
- BITFIELD(37, 2) /* index 17 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22),
- BITFIELD(39, 2) /* index 22 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27),
- BITFIELD(41, 2) /* index 27 */,
- TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
- BITFIELD(31, 2) /* index 32 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37),
- BITFIELD(33, 2) /* index 37 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42),
- BITFIELD(35, 2) /* index 42 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47),
- BITFIELD(37, 2) /* index 47 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52),
- BITFIELD(39, 2) /* index 52 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57),
- BITFIELD(41, 2) /* index 57 */,
- TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
- BITFIELD(49, 2) /* index 62 */,
- TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
- BITFIELD(47, 4) /* index 67 */,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
- TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
- TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD,
- TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(84),
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
- BITFIELD(43, 3) /* index 84 */,
- CHILD(93), CHILD(96), CHILD(99), CHILD(102), CHILD(105), CHILD(108),
- CHILD(111), CHILD(114),
- BITFIELD(46, 1) /* index 93 */,
- TILEGX_OPC_NONE, TILEGX_OPC_FNOP,
- BITFIELD(46, 1) /* index 96 */,
- TILEGX_OPC_NONE, TILEGX_OPC_ILL,
- BITFIELD(46, 1) /* index 99 */,
- TILEGX_OPC_NONE, TILEGX_OPC_JALRP,
- BITFIELD(46, 1) /* index 102 */,
- TILEGX_OPC_NONE, TILEGX_OPC_JALR,
- BITFIELD(46, 1) /* index 105 */,
- TILEGX_OPC_NONE, TILEGX_OPC_JRP,
- BITFIELD(46, 1) /* index 108 */,
- TILEGX_OPC_NONE, TILEGX_OPC_JR,
- BITFIELD(46, 1) /* index 111 */,
- TILEGX_OPC_NONE, TILEGX_OPC_LNK,
- BITFIELD(46, 1) /* index 114 */,
- TILEGX_OPC_NONE, TILEGX_OPC_NOP,
- BITFIELD(49, 2) /* index 117 */,
- TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
- BITFIELD(49, 2) /* index 122 */,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE,
- BITFIELD(49, 2) /* index 127 */,
- TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_MNZ, TILEGX_OPC_MZ,
- BITFIELD(49, 2) /* index 132 */,
- TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(137), TILEGX_OPC_XOR,
- BITFIELD(43, 2) /* index 137 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(142),
- BITFIELD(45, 2) /* index 142 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(147),
- BITFIELD(47, 2) /* index 147 */,
- TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
- BITFIELD(49, 2) /* index 152 */,
- TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU,
- BITFIELD(49, 2) /* index 157 */,
- TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX,
- TILEGX_OPC_SHL3ADDX,
- BITFIELD(49, 2) /* index 162 */,
- TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI,
-};
-
-static const unsigned short decode_Y2_fsm[118] =
-{
- BITFIELD(62, 2) /* index 0 */,
- TILEGX_OPC_NONE, CHILD(5), CHILD(66), CHILD(109),
- BITFIELD(55, 3) /* index 5 */,
- CHILD(14), CHILD(14), CHILD(14), CHILD(17), CHILD(40), CHILD(40), CHILD(40),
- CHILD(43),
- BITFIELD(26, 1) /* index 14 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1U,
- BITFIELD(26, 1) /* index 17 */,
- CHILD(20), CHILD(30),
- BITFIELD(51, 2) /* index 20 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(25),
- BITFIELD(53, 2) /* index 25 */,
- TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S,
- TILEGX_OPC_PREFETCH_L1_FAULT,
- BITFIELD(51, 2) /* index 30 */,
- TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(35),
- BITFIELD(53, 2) /* index 35 */,
- TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH,
- BITFIELD(26, 1) /* index 40 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2U,
- BITFIELD(26, 1) /* index 43 */,
- CHILD(46), CHILD(56),
- BITFIELD(51, 2) /* index 46 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(51),
- BITFIELD(53, 2) /* index 51 */,
- TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S,
- TILEGX_OPC_PREFETCH_L2_FAULT,
- BITFIELD(51, 2) /* index 56 */,
- TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(61),
- BITFIELD(53, 2) /* index 61 */,
- TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2,
- BITFIELD(56, 2) /* index 66 */,
- CHILD(71), CHILD(74), CHILD(90), CHILD(93),
- BITFIELD(26, 1) /* index 71 */,
- TILEGX_OPC_NONE, TILEGX_OPC_LD4S,
- BITFIELD(26, 1) /* index 74 */,
- TILEGX_OPC_NONE, CHILD(77),
- BITFIELD(51, 2) /* index 77 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(82),
- BITFIELD(53, 2) /* index 82 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(87),
- BITFIELD(55, 1) /* index 87 */,
- TILEGX_OPC_LD4S, TILEGX_OPC_PREFETCH_L3_FAULT,
- BITFIELD(26, 1) /* index 90 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD,
- BITFIELD(26, 1) /* index 93 */,
- CHILD(96), TILEGX_OPC_LD,
- BITFIELD(51, 2) /* index 96 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(101),
- BITFIELD(53, 2) /* index 101 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(106),
- BITFIELD(55, 1) /* index 106 */,
- TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3,
- BITFIELD(26, 1) /* index 109 */,
- CHILD(112), CHILD(115),
- BITFIELD(57, 1) /* index 112 */,
- TILEGX_OPC_ST1, TILEGX_OPC_ST4,
- BITFIELD(57, 1) /* index 115 */,
- TILEGX_OPC_ST2, TILEGX_OPC_ST,
-};
-
-#undef BITFIELD
-#undef CHILD
-
-const unsigned short * const
-tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS] =
-{
- decode_X0_fsm,
- decode_X1_fsm,
- decode_Y0_fsm,
- decode_Y1_fsm,
- decode_Y2_fsm
-};
-
-const struct tilegx_operand tilegx_operands[35] =
-{
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X0),
- 8, 1, 0, 0, 0, 0,
- create_Imm8_X0, get_Imm8_X0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X1),
- 8, 1, 0, 0, 0, 0,
- create_Imm8_X1, get_Imm8_X1
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y0),
- 8, 1, 0, 0, 0, 0,
- create_Imm8_Y0, get_Imm8_Y0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y1),
- 8, 1, 0, 0, 0, 0,
- create_Imm8_Y1, get_Imm8_Y1
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X0_HW0_LAST),
- 16, 1, 0, 0, 0, 0,
- create_Imm16_X0, get_Imm16_X0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X1_HW0_LAST),
- 16, 1, 0, 0, 0, 0,
- create_Imm16_X1, get_Imm16_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 0, 1, 0, 0,
- create_Dest_X1, get_Dest_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcA_X1, get_SrcA_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 0, 1, 0, 0,
- create_Dest_X0, get_Dest_X0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcA_X0, get_SrcA_X0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 0, 1, 0, 0,
- create_Dest_Y0, get_Dest_Y0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcA_Y0, get_SrcA_Y0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 0, 1, 0, 0,
- create_Dest_Y1, get_Dest_Y1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcA_Y1, get_SrcA_Y1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcA_Y2, get_SrcA_Y2
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 1, 0, 0,
- create_SrcA_X1, get_SrcA_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcB_X0, get_SrcB_X0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcB_X1, get_SrcB_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcB_Y0, get_SrcB_Y0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcB_Y1, get_SrcB_Y1
- },
- {
- TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_BROFF_X1),
- 17, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
- create_BrOff_X1, get_BrOff_X1
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMSTART_X0),
- 6, 0, 0, 0, 0, 0,
- create_BFStart_X0, get_BFStart_X0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_MMEND_X0),
- 6, 0, 0, 0, 0, 0,
- create_BFEnd_X0, get_BFEnd_X0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 1, 0, 0,
- create_Dest_X0, get_Dest_X0
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 1, 0, 0,
- create_Dest_Y0, get_Dest_Y0
- },
- {
- TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_JUMPOFF_X1),
- 27, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
- create_JumpOff_X1, get_JumpOff_X1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 0, 1, 0, 0,
- create_SrcBDest_Y2, get_SrcBDest_Y2
- },
- {
- TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MF_IMM14_X1),
- 14, 0, 0, 0, 0, 0,
- create_MF_Imm14_X1, get_MF_Imm14_X1
- },
- {
- TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MT_IMM14_X1),
- 14, 0, 0, 0, 0, 0,
- create_MT_Imm14_X1, get_MT_Imm14_X1
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X0),
- 6, 0, 0, 0, 0, 0,
- create_ShAmt_X0, get_ShAmt_X0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X1),
- 6, 0, 0, 0, 0, 0,
- create_ShAmt_X1, get_ShAmt_X1
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y0),
- 6, 0, 0, 0, 0, 0,
- create_ShAmt_Y0, get_ShAmt_Y0
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y1),
- 6, 0, 0, 0, 0, 0,
- create_ShAmt_Y1, get_ShAmt_Y1
- },
- {
- TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
- 6, 0, 1, 0, 0, 0,
- create_SrcBDest_Y2, get_SrcBDest_Y2
- },
- {
- TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_DEST_IMM8_X1),
- 8, 1, 0, 0, 0, 0,
- create_Dest_Imm8_X1, get_Dest_Imm8_X1
- }
-};
-
-/* Given a set of bundle bits and a specific pipe, returns which
- * instruction the bundle contains in that pipe.
- */
-const struct tilegx_opcode *
-find_opcode(tilegx_bundle_bits bits, tilegx_pipeline pipe)
-{
- const unsigned short *table = tilegx_bundle_decoder_fsms[pipe];
- int index = 0;
-
- while (1)
- {
- unsigned short bitspec = table[index];
- unsigned int bitfield =
- ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6);
-
- unsigned short next = table[index + 1 + bitfield];
- if (next <= TILEGX_OPC_NONE)
- return &tilegx_opcodes[next];
-
- index = next - TILEGX_OPC_NONE;
- }
-}
-
-int
-parse_insn_tilegx(tilegx_bundle_bits bits,
- unsigned long long pc,
- struct tilegx_decoded_instruction
- decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE])
-{
- int num_instructions = 0;
- int pipe;
-
- int min_pipe, max_pipe;
- if ((bits & TILEGX_BUNDLE_MODE_MASK) == 0)
- {
- min_pipe = TILEGX_PIPELINE_X0;
- max_pipe = TILEGX_PIPELINE_X1;
- }
- else
- {
- min_pipe = TILEGX_PIPELINE_Y0;
- max_pipe = TILEGX_PIPELINE_Y2;
- }
-
- /* For each pipe, find an instruction that fits. */
- for (pipe = min_pipe; pipe <= max_pipe; pipe++)
- {
- const struct tilegx_opcode *opc;
- struct tilegx_decoded_instruction *d;
- int i;
-
- d = &decoded[num_instructions++];
- opc = find_opcode (bits, (tilegx_pipeline)pipe);
- d->opcode = opc;
-
- /* Decode each operand, sign extending, etc. as appropriate. */
- for (i = 0; i < opc->num_operands; i++)
- {
- const struct tilegx_operand *op =
- &tilegx_operands[opc->operands[pipe][i]];
- int raw_opval = op->extract (bits);
- long long opval;
-
- if (op->is_signed)
- {
- /* Sign-extend the operand. */
- int shift = (int)((sizeof(int) * 8) - op->num_bits);
- raw_opval = (raw_opval << shift) >> shift;
- }
-
- /* Adjust PC-relative scaled branch offsets. */
- if (op->type == TILEGX_OP_TYPE_ADDRESS)
- opval = (raw_opval * TILEGX_BUNDLE_SIZE_IN_BYTES) + pc;
- else
- opval = raw_opval;
-
- /* Record the final value. */
- d->operands[i] = op;
- d->operand_values[i] = opval;
- }
- }
-
- return num_instructions;
-}
-
-struct tilegx_spr
-{
- /* The number */
- int number;
-
- /* The name */
- const char *name;
-};
-
-static int
-tilegx_spr_compare (const void *a_ptr, const void *b_ptr)
-{
- const struct tilegx_spr *a = (const struct tilegx_spr *) a_ptr;
- const struct tilegx_spr *b = (const struct tilegx_spr *) b_ptr;
- return (a->number - b->number);
-}
-
-const struct tilegx_spr tilegx_sprs[] = {
- { 0, "MPL_MEM_ERROR_SET_0" },
- { 1, "MPL_MEM_ERROR_SET_1" },
- { 2, "MPL_MEM_ERROR_SET_2" },
- { 3, "MPL_MEM_ERROR_SET_3" },
- { 4, "MPL_MEM_ERROR" },
- { 5, "MEM_ERROR_CBOX_ADDR" },
- { 6, "MEM_ERROR_CBOX_STATUS" },
- { 7, "MEM_ERROR_ENABLE" },
- { 8, "MEM_ERROR_MBOX_ADDR" },
- { 9, "MEM_ERROR_MBOX_STATUS" },
- { 10, "SBOX_ERROR" },
- { 11, "XDN_DEMUX_ERROR" },
- { 256, "MPL_SINGLE_STEP_3_SET_0" },
- { 257, "MPL_SINGLE_STEP_3_SET_1" },
- { 258, "MPL_SINGLE_STEP_3_SET_2" },
- { 259, "MPL_SINGLE_STEP_3_SET_3" },
- { 260, "MPL_SINGLE_STEP_3" },
- { 261, "SINGLE_STEP_CONTROL_3" },
- { 512, "MPL_SINGLE_STEP_2_SET_0" },
- { 513, "MPL_SINGLE_STEP_2_SET_1" },
- { 514, "MPL_SINGLE_STEP_2_SET_2" },
- { 515, "MPL_SINGLE_STEP_2_SET_3" },
- { 516, "MPL_SINGLE_STEP_2" },
- { 517, "SINGLE_STEP_CONTROL_2" },
- { 768, "MPL_SINGLE_STEP_1_SET_0" },
- { 769, "MPL_SINGLE_STEP_1_SET_1" },
- { 770, "MPL_SINGLE_STEP_1_SET_2" },
- { 771, "MPL_SINGLE_STEP_1_SET_3" },
- { 772, "MPL_SINGLE_STEP_1" },
- { 773, "SINGLE_STEP_CONTROL_1" },
- { 1024, "MPL_SINGLE_STEP_0_SET_0" },
- { 1025, "MPL_SINGLE_STEP_0_SET_1" },
- { 1026, "MPL_SINGLE_STEP_0_SET_2" },
- { 1027, "MPL_SINGLE_STEP_0_SET_3" },
- { 1028, "MPL_SINGLE_STEP_0" },
- { 1029, "SINGLE_STEP_CONTROL_0" },
- { 1280, "MPL_IDN_COMPLETE_SET_0" },
- { 1281, "MPL_IDN_COMPLETE_SET_1" },
- { 1282, "MPL_IDN_COMPLETE_SET_2" },
- { 1283, "MPL_IDN_COMPLETE_SET_3" },
- { 1284, "MPL_IDN_COMPLETE" },
- { 1285, "IDN_COMPLETE_PENDING" },
- { 1536, "MPL_UDN_COMPLETE_SET_0" },
- { 1537, "MPL_UDN_COMPLETE_SET_1" },
- { 1538, "MPL_UDN_COMPLETE_SET_2" },
- { 1539, "MPL_UDN_COMPLETE_SET_3" },
- { 1540, "MPL_UDN_COMPLETE" },
- { 1541, "UDN_COMPLETE_PENDING" },
- { 1792, "MPL_ITLB_MISS_SET_0" },
- { 1793, "MPL_ITLB_MISS_SET_1" },
- { 1794, "MPL_ITLB_MISS_SET_2" },
- { 1795, "MPL_ITLB_MISS_SET_3" },
- { 1796, "MPL_ITLB_MISS" },
- { 1797, "ITLB_TSB_BASE_ADDR_0" },
- { 1798, "ITLB_TSB_BASE_ADDR_1" },
- { 1920, "ITLB_CURRENT_ATTR" },
- { 1921, "ITLB_CURRENT_PA" },
- { 1922, "ITLB_CURRENT_VA" },
- { 1923, "ITLB_INDEX" },
- { 1924, "ITLB_MATCH_0" },
- { 1925, "ITLB_PERF" },
- { 1926, "ITLB_PR" },
- { 1927, "ITLB_TSB_ADDR_0" },
- { 1928, "ITLB_TSB_ADDR_1" },
- { 1929, "ITLB_TSB_FILL_CURRENT_ATTR" },
- { 1930, "ITLB_TSB_FILL_MATCH" },
- { 1931, "NUMBER_ITLB" },
- { 1932, "REPLACEMENT_ITLB" },
- { 1933, "WIRED_ITLB" },
- { 2048, "MPL_ILL_SET_0" },
- { 2049, "MPL_ILL_SET_1" },
- { 2050, "MPL_ILL_SET_2" },
- { 2051, "MPL_ILL_SET_3" },
- { 2052, "MPL_ILL" },
- { 2304, "MPL_GPV_SET_0" },
- { 2305, "MPL_GPV_SET_1" },
- { 2306, "MPL_GPV_SET_2" },
- { 2307, "MPL_GPV_SET_3" },
- { 2308, "MPL_GPV" },
- { 2309, "GPV_REASON" },
- { 2560, "MPL_IDN_ACCESS_SET_0" },
- { 2561, "MPL_IDN_ACCESS_SET_1" },
- { 2562, "MPL_IDN_ACCESS_SET_2" },
- { 2563, "MPL_IDN_ACCESS_SET_3" },
- { 2564, "MPL_IDN_ACCESS" },
- { 2565, "IDN_DEMUX_COUNT_0" },
- { 2566, "IDN_DEMUX_COUNT_1" },
- { 2567, "IDN_FLUSH_EGRESS" },
- { 2568, "IDN_PENDING" },
- { 2569, "IDN_ROUTE_ORDER" },
- { 2570, "IDN_SP_FIFO_CNT" },
- { 2688, "IDN_DATA_AVAIL" },
- { 2816, "MPL_UDN_ACCESS_SET_0" },
- { 2817, "MPL_UDN_ACCESS_SET_1" },
- { 2818, "MPL_UDN_ACCESS_SET_2" },
- { 2819, "MPL_UDN_ACCESS_SET_3" },
- { 2820, "MPL_UDN_ACCESS" },
- { 2821, "UDN_DEMUX_COUNT_0" },
- { 2822, "UDN_DEMUX_COUNT_1" },
- { 2823, "UDN_DEMUX_COUNT_2" },
- { 2824, "UDN_DEMUX_COUNT_3" },
- { 2825, "UDN_FLUSH_EGRESS" },
- { 2826, "UDN_PENDING" },
- { 2827, "UDN_ROUTE_ORDER" },
- { 2828, "UDN_SP_FIFO_CNT" },
- { 2944, "UDN_DATA_AVAIL" },
- { 3072, "MPL_SWINT_3_SET_0" },
- { 3073, "MPL_SWINT_3_SET_1" },
- { 3074, "MPL_SWINT_3_SET_2" },
- { 3075, "MPL_SWINT_3_SET_3" },
- { 3076, "MPL_SWINT_3" },
- { 3328, "MPL_SWINT_2_SET_0" },
- { 3329, "MPL_SWINT_2_SET_1" },
- { 3330, "MPL_SWINT_2_SET_2" },
- { 3331, "MPL_SWINT_2_SET_3" },
- { 3332, "MPL_SWINT_2" },
- { 3584, "MPL_SWINT_1_SET_0" },
- { 3585, "MPL_SWINT_1_SET_1" },
- { 3586, "MPL_SWINT_1_SET_2" },
- { 3587, "MPL_SWINT_1_SET_3" },
- { 3588, "MPL_SWINT_1" },
- { 3840, "MPL_SWINT_0_SET_0" },
- { 3841, "MPL_SWINT_0_SET_1" },
- { 3842, "MPL_SWINT_0_SET_2" },
- { 3843, "MPL_SWINT_0_SET_3" },
- { 3844, "MPL_SWINT_0" },
- { 4096, "MPL_ILL_TRANS_SET_0" },
- { 4097, "MPL_ILL_TRANS_SET_1" },
- { 4098, "MPL_ILL_TRANS_SET_2" },
- { 4099, "MPL_ILL_TRANS_SET_3" },
- { 4100, "MPL_ILL_TRANS" },
- { 4101, "ILL_TRANS_REASON" },
- { 4102, "ILL_VA_PC" },
- { 4352, "MPL_UNALIGN_DATA_SET_0" },
- { 4353, "MPL_UNALIGN_DATA_SET_1" },
- { 4354, "MPL_UNALIGN_DATA_SET_2" },
- { 4355, "MPL_UNALIGN_DATA_SET_3" },
- { 4356, "MPL_UNALIGN_DATA" },
- { 4608, "MPL_DTLB_MISS_SET_0" },
- { 4609, "MPL_DTLB_MISS_SET_1" },
- { 4610, "MPL_DTLB_MISS_SET_2" },
- { 4611, "MPL_DTLB_MISS_SET_3" },
- { 4612, "MPL_DTLB_MISS" },
- { 4613, "DTLB_TSB_BASE_ADDR_0" },
- { 4614, "DTLB_TSB_BASE_ADDR_1" },
- { 4736, "AAR" },
- { 4737, "CACHE_PINNED_WAYS" },
- { 4738, "DTLB_BAD_ADDR" },
- { 4739, "DTLB_BAD_ADDR_REASON" },
- { 4740, "DTLB_CURRENT_ATTR" },
- { 4741, "DTLB_CURRENT_PA" },
- { 4742, "DTLB_CURRENT_VA" },
- { 4743, "DTLB_INDEX" },
- { 4744, "DTLB_MATCH_0" },
- { 4745, "DTLB_PERF" },
- { 4746, "DTLB_TSB_ADDR_0" },
- { 4747, "DTLB_TSB_ADDR_1" },
- { 4748, "DTLB_TSB_FILL_CURRENT_ATTR" },
- { 4749, "DTLB_TSB_FILL_MATCH" },
- { 4750, "NUMBER_DTLB" },
- { 4751, "REPLACEMENT_DTLB" },
- { 4752, "WIRED_DTLB" },
- { 4864, "MPL_DTLB_ACCESS_SET_0" },
- { 4865, "MPL_DTLB_ACCESS_SET_1" },
- { 4866, "MPL_DTLB_ACCESS_SET_2" },
- { 4867, "MPL_DTLB_ACCESS_SET_3" },
- { 4868, "MPL_DTLB_ACCESS" },
- { 5120, "MPL_IDN_FIREWALL_SET_0" },
- { 5121, "MPL_IDN_FIREWALL_SET_1" },
- { 5122, "MPL_IDN_FIREWALL_SET_2" },
- { 5123, "MPL_IDN_FIREWALL_SET_3" },
- { 5124, "MPL_IDN_FIREWALL" },
- { 5125, "IDN_DIRECTION_PROTECT" },
- { 5376, "MPL_UDN_FIREWALL_SET_0" },
- { 5377, "MPL_UDN_FIREWALL_SET_1" },
- { 5378, "MPL_UDN_FIREWALL_SET_2" },
- { 5379, "MPL_UDN_FIREWALL_SET_3" },
- { 5380, "MPL_UDN_FIREWALL" },
- { 5381, "UDN_DIRECTION_PROTECT" },
- { 5632, "MPL_TILE_TIMER_SET_0" },
- { 5633, "MPL_TILE_TIMER_SET_1" },
- { 5634, "MPL_TILE_TIMER_SET_2" },
- { 5635, "MPL_TILE_TIMER_SET_3" },
- { 5636, "MPL_TILE_TIMER" },
- { 5637, "TILE_TIMER_CONTROL" },
- { 5888, "MPL_AUX_TILE_TIMER_SET_0" },
- { 5889, "MPL_AUX_TILE_TIMER_SET_1" },
- { 5890, "MPL_AUX_TILE_TIMER_SET_2" },
- { 5891, "MPL_AUX_TILE_TIMER_SET_3" },
- { 5892, "MPL_AUX_TILE_TIMER" },
- { 5893, "AUX_TILE_TIMER_CONTROL" },
- { 6144, "MPL_IDN_TIMER_SET_0" },
- { 6145, "MPL_IDN_TIMER_SET_1" },
- { 6146, "MPL_IDN_TIMER_SET_2" },
- { 6147, "MPL_IDN_TIMER_SET_3" },
- { 6148, "MPL_IDN_TIMER" },
- { 6149, "IDN_DEADLOCK_COUNT" },
- { 6150, "IDN_DEADLOCK_TIMEOUT" },
- { 6400, "MPL_UDN_TIMER_SET_0" },
- { 6401, "MPL_UDN_TIMER_SET_1" },
- { 6402, "MPL_UDN_TIMER_SET_2" },
- { 6403, "MPL_UDN_TIMER_SET_3" },
- { 6404, "MPL_UDN_TIMER" },
- { 6405, "UDN_DEADLOCK_COUNT" },
- { 6406, "UDN_DEADLOCK_TIMEOUT" },
- { 6656, "MPL_IDN_AVAIL_SET_0" },
- { 6657, "MPL_IDN_AVAIL_SET_1" },
- { 6658, "MPL_IDN_AVAIL_SET_2" },
- { 6659, "MPL_IDN_AVAIL_SET_3" },
- { 6660, "MPL_IDN_AVAIL" },
- { 6661, "IDN_AVAIL_EN" },
- { 6912, "MPL_UDN_AVAIL_SET_0" },
- { 6913, "MPL_UDN_AVAIL_SET_1" },
- { 6914, "MPL_UDN_AVAIL_SET_2" },
- { 6915, "MPL_UDN_AVAIL_SET_3" },
- { 6916, "MPL_UDN_AVAIL" },
- { 6917, "UDN_AVAIL_EN" },
- { 7168, "MPL_IPI_3_SET_0" },
- { 7169, "MPL_IPI_3_SET_1" },
- { 7170, "MPL_IPI_3_SET_2" },
- { 7171, "MPL_IPI_3_SET_3" },
- { 7172, "MPL_IPI_3" },
- { 7173, "IPI_EVENT_3" },
- { 7174, "IPI_EVENT_RESET_3" },
- { 7175, "IPI_EVENT_SET_3" },
- { 7176, "IPI_MASK_3" },
- { 7177, "IPI_MASK_RESET_3" },
- { 7178, "IPI_MASK_SET_3" },
- { 7424, "MPL_IPI_2_SET_0" },
- { 7425, "MPL_IPI_2_SET_1" },
- { 7426, "MPL_IPI_2_SET_2" },
- { 7427, "MPL_IPI_2_SET_3" },
- { 7428, "MPL_IPI_2" },
- { 7429, "IPI_EVENT_2" },
- { 7430, "IPI_EVENT_RESET_2" },
- { 7431, "IPI_EVENT_SET_2" },
- { 7432, "IPI_MASK_2" },
- { 7433, "IPI_MASK_RESET_2" },
- { 7434, "IPI_MASK_SET_2" },
- { 7680, "MPL_IPI_1_SET_0" },
- { 7681, "MPL_IPI_1_SET_1" },
- { 7682, "MPL_IPI_1_SET_2" },
- { 7683, "MPL_IPI_1_SET_3" },
- { 7684, "MPL_IPI_1" },
- { 7685, "IPI_EVENT_1" },
- { 7686, "IPI_EVENT_RESET_1" },
- { 7687, "IPI_EVENT_SET_1" },
- { 7688, "IPI_MASK_1" },
- { 7689, "IPI_MASK_RESET_1" },
- { 7690, "IPI_MASK_SET_1" },
- { 7936, "MPL_IPI_0_SET_0" },
- { 7937, "MPL_IPI_0_SET_1" },
- { 7938, "MPL_IPI_0_SET_2" },
- { 7939, "MPL_IPI_0_SET_3" },
- { 7940, "MPL_IPI_0" },
- { 7941, "IPI_EVENT_0" },
- { 7942, "IPI_EVENT_RESET_0" },
- { 7943, "IPI_EVENT_SET_0" },
- { 7944, "IPI_MASK_0" },
- { 7945, "IPI_MASK_RESET_0" },
- { 7946, "IPI_MASK_SET_0" },
- { 8192, "MPL_PERF_COUNT_SET_0" },
- { 8193, "MPL_PERF_COUNT_SET_1" },
- { 8194, "MPL_PERF_COUNT_SET_2" },
- { 8195, "MPL_PERF_COUNT_SET_3" },
- { 8196, "MPL_PERF_COUNT" },
- { 8197, "PERF_COUNT_0" },
- { 8198, "PERF_COUNT_1" },
- { 8199, "PERF_COUNT_CTL" },
- { 8200, "PERF_COUNT_DN_CTL" },
- { 8201, "PERF_COUNT_STS" },
- { 8202, "WATCH_MASK" },
- { 8203, "WATCH_VAL" },
- { 8448, "MPL_AUX_PERF_COUNT_SET_0" },
- { 8449, "MPL_AUX_PERF_COUNT_SET_1" },
- { 8450, "MPL_AUX_PERF_COUNT_SET_2" },
- { 8451, "MPL_AUX_PERF_COUNT_SET_3" },
- { 8452, "MPL_AUX_PERF_COUNT" },
- { 8453, "AUX_PERF_COUNT_0" },
- { 8454, "AUX_PERF_COUNT_1" },
- { 8455, "AUX_PERF_COUNT_CTL" },
- { 8456, "AUX_PERF_COUNT_STS" },
- { 8704, "MPL_INTCTRL_3_SET_0" },
- { 8705, "MPL_INTCTRL_3_SET_1" },
- { 8706, "MPL_INTCTRL_3_SET_2" },
- { 8707, "MPL_INTCTRL_3_SET_3" },
- { 8708, "MPL_INTCTRL_3" },
- { 8709, "INTCTRL_3_STATUS" },
- { 8710, "INTERRUPT_MASK_3" },
- { 8711, "INTERRUPT_MASK_RESET_3" },
- { 8712, "INTERRUPT_MASK_SET_3" },
- { 8713, "INTERRUPT_VECTOR_BASE_3" },
- { 8714, "SINGLE_STEP_EN_0_3" },
- { 8715, "SINGLE_STEP_EN_1_3" },
- { 8716, "SINGLE_STEP_EN_2_3" },
- { 8717, "SINGLE_STEP_EN_3_3" },
- { 8832, "EX_CONTEXT_3_0" },
- { 8833, "EX_CONTEXT_3_1" },
- { 8834, "SYSTEM_SAVE_3_0" },
- { 8835, "SYSTEM_SAVE_3_1" },
- { 8836, "SYSTEM_SAVE_3_2" },
- { 8837, "SYSTEM_SAVE_3_3" },
- { 8960, "MPL_INTCTRL_2_SET_0" },
- { 8961, "MPL_INTCTRL_2_SET_1" },
- { 8962, "MPL_INTCTRL_2_SET_2" },
- { 8963, "MPL_INTCTRL_2_SET_3" },
- { 8964, "MPL_INTCTRL_2" },
- { 8965, "INTCTRL_2_STATUS" },
- { 8966, "INTERRUPT_MASK_2" },
- { 8967, "INTERRUPT_MASK_RESET_2" },
- { 8968, "INTERRUPT_MASK_SET_2" },
- { 8969, "INTERRUPT_VECTOR_BASE_2" },
- { 8970, "SINGLE_STEP_EN_0_2" },
- { 8971, "SINGLE_STEP_EN_1_2" },
- { 8972, "SINGLE_STEP_EN_2_2" },
- { 8973, "SINGLE_STEP_EN_3_2" },
- { 9088, "EX_CONTEXT_2_0" },
- { 9089, "EX_CONTEXT_2_1" },
- { 9090, "SYSTEM_SAVE_2_0" },
- { 9091, "SYSTEM_SAVE_2_1" },
- { 9092, "SYSTEM_SAVE_2_2" },
- { 9093, "SYSTEM_SAVE_2_3" },
- { 9216, "MPL_INTCTRL_1_SET_0" },
- { 9217, "MPL_INTCTRL_1_SET_1" },
- { 9218, "MPL_INTCTRL_1_SET_2" },
- { 9219, "MPL_INTCTRL_1_SET_3" },
- { 9220, "MPL_INTCTRL_1" },
- { 9221, "INTCTRL_1_STATUS" },
- { 9222, "INTERRUPT_MASK_1" },
- { 9223, "INTERRUPT_MASK_RESET_1" },
- { 9224, "INTERRUPT_MASK_SET_1" },
- { 9225, "INTERRUPT_VECTOR_BASE_1" },
- { 9226, "SINGLE_STEP_EN_0_1" },
- { 9227, "SINGLE_STEP_EN_1_1" },
- { 9228, "SINGLE_STEP_EN_2_1" },
- { 9229, "SINGLE_STEP_EN_3_1" },
- { 9344, "EX_CONTEXT_1_0" },
- { 9345, "EX_CONTEXT_1_1" },
- { 9346, "SYSTEM_SAVE_1_0" },
- { 9347, "SYSTEM_SAVE_1_1" },
- { 9348, "SYSTEM_SAVE_1_2" },
- { 9349, "SYSTEM_SAVE_1_3" },
- { 9472, "MPL_INTCTRL_0_SET_0" },
- { 9473, "MPL_INTCTRL_0_SET_1" },
- { 9474, "MPL_INTCTRL_0_SET_2" },
- { 9475, "MPL_INTCTRL_0_SET_3" },
- { 9476, "MPL_INTCTRL_0" },
- { 9477, "INTCTRL_0_STATUS" },
- { 9478, "INTERRUPT_MASK_0" },
- { 9479, "INTERRUPT_MASK_RESET_0" },
- { 9480, "INTERRUPT_MASK_SET_0" },
- { 9481, "INTERRUPT_VECTOR_BASE_0" },
- { 9482, "SINGLE_STEP_EN_0_0" },
- { 9483, "SINGLE_STEP_EN_1_0" },
- { 9484, "SINGLE_STEP_EN_2_0" },
- { 9485, "SINGLE_STEP_EN_3_0" },
- { 9600, "EX_CONTEXT_0_0" },
- { 9601, "EX_CONTEXT_0_1" },
- { 9602, "SYSTEM_SAVE_0_0" },
- { 9603, "SYSTEM_SAVE_0_1" },
- { 9604, "SYSTEM_SAVE_0_2" },
- { 9605, "SYSTEM_SAVE_0_3" },
- { 9728, "MPL_BOOT_ACCESS_SET_0" },
- { 9729, "MPL_BOOT_ACCESS_SET_1" },
- { 9730, "MPL_BOOT_ACCESS_SET_2" },
- { 9731, "MPL_BOOT_ACCESS_SET_3" },
- { 9732, "MPL_BOOT_ACCESS" },
- { 9733, "BIG_ENDIAN_CONFIG" },
- { 9734, "CACHE_INVALIDATION_COMPRESSION_MODE" },
- { 9735, "CACHE_INVALIDATION_MASK_0" },
- { 9736, "CACHE_INVALIDATION_MASK_1" },
- { 9737, "CACHE_INVALIDATION_MASK_2" },
- { 9738, "CBOX_CACHEASRAM_CONFIG" },
- { 9739, "CBOX_CACHE_CONFIG" },
- { 9740, "CBOX_HOME_MAP_ADDR" },
- { 9741, "CBOX_HOME_MAP_DATA" },
- { 9742, "CBOX_MMAP_0" },
- { 9743, "CBOX_MMAP_1" },
- { 9744, "CBOX_MMAP_2" },
- { 9745, "CBOX_MMAP_3" },
- { 9746, "CBOX_MSR" },
- { 9747, "DIAG_BCST_CTL" },
- { 9748, "DIAG_BCST_MASK" },
- { 9749, "DIAG_BCST_TRIGGER" },
- { 9750, "DIAG_MUX_CTL" },
- { 9751, "DIAG_TRACE_CTL" },
- { 9752, "DIAG_TRACE_DATA" },
- { 9753, "DIAG_TRACE_STS" },
- { 9754, "IDN_DEMUX_BUF_THRESH" },
- { 9755, "L1_I_PIN_WAY_0" },
- { 9756, "MEM_ROUTE_ORDER" },
- { 9757, "MEM_STRIPE_CONFIG" },
- { 9758, "PERF_COUNT_PLS" },
- { 9759, "PSEUDO_RANDOM_NUMBER_MODIFY" },
- { 9760, "QUIESCE_CTL" },
- { 9761, "RSHIM_COORD" },
- { 9762, "SBOX_CONFIG" },
- { 9763, "UDN_DEMUX_BUF_THRESH" },
- { 9764, "XDN_CORE_STARVATION_COUNT" },
- { 9765, "XDN_ROUND_ROBIN_ARB_CTL" },
- { 9856, "CYCLE_MODIFY" },
- { 9857, "I_AAR" },
- { 9984, "MPL_WORLD_ACCESS_SET_0" },
- { 9985, "MPL_WORLD_ACCESS_SET_1" },
- { 9986, "MPL_WORLD_ACCESS_SET_2" },
- { 9987, "MPL_WORLD_ACCESS_SET_3" },
- { 9988, "MPL_WORLD_ACCESS" },
- { 9989, "DONE" },
- { 9990, "DSTREAM_PF" },
- { 9991, "FAIL" },
- { 9992, "INTERRUPT_CRITICAL_SECTION" },
- { 9993, "PASS" },
- { 9994, "PSEUDO_RANDOM_NUMBER" },
- { 9995, "TILE_COORD" },
- { 9996, "TILE_RTF_HWM" },
- { 10112, "CMPEXCH_VALUE" },
- { 10113, "CYCLE" },
- { 10114, "EVENT_BEGIN" },
- { 10115, "EVENT_END" },
- { 10116, "PROC_STATUS" },
- { 10117, "SIM_CONTROL" },
- { 10118, "SIM_SOCKET" },
- { 10119, "STATUS_SATURATE" },
- { 10240, "MPL_I_ASID_SET_0" },
- { 10241, "MPL_I_ASID_SET_1" },
- { 10242, "MPL_I_ASID_SET_2" },
- { 10243, "MPL_I_ASID_SET_3" },
- { 10244, "MPL_I_ASID" },
- { 10245, "I_ASID" },
- { 10496, "MPL_D_ASID_SET_0" },
- { 10497, "MPL_D_ASID_SET_1" },
- { 10498, "MPL_D_ASID_SET_2" },
- { 10499, "MPL_D_ASID_SET_3" },
- { 10500, "MPL_D_ASID" },
- { 10501, "D_ASID" },
- { 10752, "MPL_DOUBLE_FAULT_SET_0" },
- { 10753, "MPL_DOUBLE_FAULT_SET_1" },
- { 10754, "MPL_DOUBLE_FAULT_SET_2" },
- { 10755, "MPL_DOUBLE_FAULT_SET_3" },
- { 10756, "MPL_DOUBLE_FAULT" },
- { 10757, "LAST_INTERRUPT_REASON" },
-};
-
-const int tilegx_num_sprs = 441;
-
-const char *
-get_tilegx_spr_name (int num)
-{
- void *result;
- struct tilegx_spr key;
-
- key.number = num;
- result = bsearch((const void *) &key, (const void *) tilegx_sprs,
- tilegx_num_sprs, sizeof (struct tilegx_spr),
- tilegx_spr_compare);
-
- if (result == NULL)
- {
- return (NULL);
- }
- else
- {
- struct tilegx_spr *result_ptr = (struct tilegx_spr *) result;
- return (result_ptr->name);
- }
-}
-
-int
-print_insn_tilegx (unsigned char * memaddr)
-{
- struct tilegx_decoded_instruction
- decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
- unsigned char opbuf[TILEGX_BUNDLE_SIZE_IN_BYTES];
- int i, num_instructions, num_printed;
- tilegx_mnemonic padding_mnemonic;
-
- memcpy((void *)opbuf, (void *)memaddr, TILEGX_BUNDLE_SIZE_IN_BYTES);
-
- /* Parse the instructions in the bundle. */
- num_instructions =
- parse_insn_tilegx (*(unsigned long long *)opbuf, (unsigned long long)memaddr, decoded);
-
- /* Print the instructions in the bundle. */
- printf("{ ");
- num_printed = 0;
-
- /* Determine which nop opcode is used for padding and should be skipped. */
- padding_mnemonic = TILEGX_OPC_FNOP;
- for (i = 0; i < num_instructions; i++)
- {
- if (!decoded[i].opcode->can_bundle)
- {
- /* Instructions that cannot be bundled are padded out with nops,
- rather than fnops. Displaying them is always clutter. */
- padding_mnemonic = TILEGX_OPC_NOP;
- break;
- }
- }
-
- for (i = 0; i < num_instructions; i++)
- {
- const struct tilegx_opcode *opcode = decoded[i].opcode;
- const char *name;
- int j;
-
- /* Do not print out fnops, unless everything is an fnop, in
- which case we will print out just the last one. */
- if (opcode->mnemonic == padding_mnemonic
- && (num_printed > 0 || i + 1 < num_instructions))
- continue;
-
- if (num_printed > 0)
- printf(" ; ");
- ++num_printed;
-
- name = opcode->name;
- if (name == NULL)
- name = "<invalid>";
- printf("%s", name);
-
- for (j = 0; j < opcode->num_operands; j++)
- {
- unsigned long long num;
- const struct tilegx_operand *op;
- const char *spr_name;
-
- if (j > 0)
- printf (",");
- printf (" ");
-
- num = decoded[i].operand_values[j];
-
- op = decoded[i].operands[j];
- switch (op->type)
- {
- case TILEGX_OP_TYPE_REGISTER:
- printf ("%s", tilegx_register_names[(int)num]);
- break;
- case TILEGX_OP_TYPE_SPR:
- spr_name = get_tilegx_spr_name(num);
- if (spr_name != NULL)
- printf ("%s", spr_name);
- else
- printf ("%d", (int)num);
- break;
- case TILEGX_OP_TYPE_IMMEDIATE:
- printf ("%d", (int)num);
- break;
- case TILEGX_OP_TYPE_ADDRESS:
- printf ("0x%016llx", num);
- break;
- default:
- abort ();
- }
- }
- }
- printf (" }\n");
-
- return TILEGX_BUNDLE_SIZE_IN_BYTES;
-}
diff --git a/src/sljit/sljitNativeTILEGX_64.c b/src/sljit/sljitNativeTILEGX_64.c
deleted file mode 100644
index d69ecd6..0000000
--- a/src/sljit/sljitNativeTILEGX_64.c
+++ /dev/null
@@ -1,2563 +0,0 @@
-/*
- * Stack-less Just-In-Time compiler
- *
- * Copyright 2013-2013 Tilera Corporation(jiwang@tilera.com). All rights reserved.
- * 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.
- */
-
-/* TileGX architecture. */
-/* Contributed by Tilera Corporation. */
-#include "sljitNativeTILEGX-encoder.c"
-
-#define SIMM_8BIT_MAX (0x7f)
-#define SIMM_8BIT_MIN (-0x80)
-#define SIMM_16BIT_MAX (0x7fff)
-#define SIMM_16BIT_MIN (-0x8000)
-#define SIMM_17BIT_MAX (0xffff)
-#define SIMM_17BIT_MIN (-0x10000)
-#define SIMM_32BIT_MAX (0x7fffffff)
-#define SIMM_32BIT_MIN (-0x7fffffff - 1)
-#define SIMM_48BIT_MAX (0x7fffffff0000L)
-#define SIMM_48BIT_MIN (-0x800000000000L)
-#define IMM16(imm) ((imm) & 0xffff)
-
-#define UIMM_16BIT_MAX (0xffff)
-
-#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
-#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
-#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
-#define ADDR_TMP (SLJIT_NUMBER_OF_REGISTERS + 5)
-#define PIC_ADDR_REG TMP_REG2
-
-static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
- 63, 0, 1, 2, 3, 4, 30, 31, 32, 33, 34, 54, 5, 16, 6, 7
-};
-
-#define SLJIT_LOCALS_REG_mapped 54
-#define TMP_REG1_mapped 5
-#define TMP_REG2_mapped 16
-#define TMP_REG3_mapped 6
-#define ADDR_TMP_mapped 7
-
-/* Flags are keept in volatile registers. */
-#define EQUAL_FLAG 8
-/* And carry flag as well. */
-#define ULESS_FLAG 9
-#define UGREATER_FLAG 10
-#define LESS_FLAG 11
-#define GREATER_FLAG 12
-#define OVERFLOW_FLAG 13
-
-#define ZERO 63
-#define RA 55
-#define TMP_EREG1 14
-#define TMP_EREG2 15
-
-#define LOAD_DATA 0x01
-#define WORD_DATA 0x00
-#define BYTE_DATA 0x02
-#define HALF_DATA 0x04
-#define INT_DATA 0x06
-#define SIGNED_DATA 0x08
-#define DOUBLE_DATA 0x10
-
-/* Separates integer and floating point registers */
-#define GPR_REG 0xf
-
-#define MEM_MASK 0x1f
-
-#define WRITE_BACK 0x00020
-#define ARG_TEST 0x00040
-#define ALT_KEEP_CACHE 0x00080
-#define CUMULATIVE_OP 0x00100
-#define LOGICAL_OP 0x00200
-#define IMM_OP 0x00400
-#define SRC2_IMM 0x00800
-
-#define UNUSED_DEST 0x01000
-#define REG_DEST 0x02000
-#define REG1_SOURCE 0x04000
-#define REG2_SOURCE 0x08000
-#define SLOW_SRC1 0x10000
-#define SLOW_SRC2 0x20000
-#define SLOW_DEST 0x40000
-
-/* Only these flags are set. UNUSED_DEST is not set when no flags should be set.
- */
-#define CHECK_FLAGS(list) (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list))))
-
-SLJIT_API_FUNC_ATTRIBUTE const char *sljit_get_platform_name(void)
-{
- return "TileGX" SLJIT_CPUINFO;
-}
-
-/* Length of an instruction word */
-typedef sljit_uw sljit_ins;
-
-struct jit_instr {
- const struct tilegx_opcode* opcode;
- tilegx_pipeline pipe;
- unsigned long input_registers;
- unsigned long output_registers;
- int operand_value[4];
- int line;
-};
-
-/* Opcode Helper Macros */
-#define TILEGX_X_MODE 0
-
-#define X_MODE create_Mode(TILEGX_X_MODE)
-
-#define FNOP_X0 \
- create_Opcode_X0(RRR_0_OPCODE_X0) | \
- create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
- create_UnaryOpcodeExtension_X0(FNOP_UNARY_OPCODE_X0)
-
-#define FNOP_X1 \
- create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
- create_UnaryOpcodeExtension_X1(FNOP_UNARY_OPCODE_X1)
-
-#define NOP \
- create_Mode(TILEGX_X_MODE) | FNOP_X0 | FNOP_X1
-
-#define ANOP_X0 \
- create_Opcode_X0(RRR_0_OPCODE_X0) | \
- create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
- create_UnaryOpcodeExtension_X0(NOP_UNARY_OPCODE_X0)
-
-#define BPT create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
- create_UnaryOpcodeExtension_X1(ILL_UNARY_OPCODE_X1) | \
- create_Dest_X1(0x1C) | create_SrcA_X1(0x25) | ANOP_X0
-
-#define ADD_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(ADD_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define ADDI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
- create_Imm8OpcodeExtension_X1(ADDI_IMM8_OPCODE_X1) | FNOP_X0
-
-#define SUB_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(SUB_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define NOR_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(NOR_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define OR_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(OR_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define AND_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(AND_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define XOR_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(XOR_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define CMOVNEZ_X0 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
- create_RRROpcodeExtension_X0(CMOVNEZ_RRR_0_OPCODE_X0) | FNOP_X1
-
-#define CMOVEQZ_X0 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
- create_RRROpcodeExtension_X0(CMOVEQZ_RRR_0_OPCODE_X0) | FNOP_X1
-
-#define ADDLI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(ADDLI_OPCODE_X1) | FNOP_X0
-
-#define V4INT_L_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(V4INT_L_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define BFEXTU_X0 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \
- create_BFOpcodeExtension_X0(BFEXTU_BF_OPCODE_X0) | FNOP_X1
-
-#define BFEXTS_X0 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X0(BF_OPCODE_X0) | \
- create_BFOpcodeExtension_X0(BFEXTS_BF_OPCODE_X0) | FNOP_X1
-
-#define SHL16INSLI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHL16INSLI_OPCODE_X1) | FNOP_X0
-
-#define ST_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(ST_RRR_0_OPCODE_X1) | create_Dest_X1(0x0) | FNOP_X0
-
-#define LD_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
- create_UnaryOpcodeExtension_X1(LD_UNARY_OPCODE_X1) | FNOP_X0
-
-#define JR_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
- create_UnaryOpcodeExtension_X1(JR_UNARY_OPCODE_X1) | FNOP_X0
-
-#define JALR_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(UNARY_RRR_0_OPCODE_X1) | \
- create_UnaryOpcodeExtension_X1(JALR_UNARY_OPCODE_X1) | FNOP_X0
-
-#define CLZ_X0 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X0(RRR_0_OPCODE_X0) | \
- create_RRROpcodeExtension_X0(UNARY_RRR_0_OPCODE_X0) | \
- create_UnaryOpcodeExtension_X0(CNTLZ_UNARY_OPCODE_X0) | FNOP_X1
-
-#define CMPLTUI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
- create_Imm8OpcodeExtension_X1(CMPLTUI_IMM8_OPCODE_X1) | FNOP_X0
-
-#define CMPLTU_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(CMPLTU_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define CMPLTS_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(CMPLTS_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define XORI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
- create_Imm8OpcodeExtension_X1(XORI_IMM8_OPCODE_X1) | FNOP_X0
-
-#define ORI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
- create_Imm8OpcodeExtension_X1(ORI_IMM8_OPCODE_X1) | FNOP_X0
-
-#define ANDI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(IMM8_OPCODE_X1) | \
- create_Imm8OpcodeExtension_X1(ANDI_IMM8_OPCODE_X1) | FNOP_X0
-
-#define SHLI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
- create_ShiftOpcodeExtension_X1(SHLI_SHIFT_OPCODE_X1) | FNOP_X0
-
-#define SHL_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(SHL_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define SHRSI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
- create_ShiftOpcodeExtension_X1(SHRSI_SHIFT_OPCODE_X1) | FNOP_X0
-
-#define SHRS_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(SHRS_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define SHRUI_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(SHIFT_OPCODE_X1) | \
- create_ShiftOpcodeExtension_X1(SHRUI_SHIFT_OPCODE_X1) | FNOP_X0
-
-#define SHRU_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(RRR_0_OPCODE_X1) | \
- create_RRROpcodeExtension_X1(SHRU_RRR_0_OPCODE_X1) | FNOP_X0
-
-#define BEQZ_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \
- create_BrType_X1(BEQZ_BRANCH_OPCODE_X1) | FNOP_X0
-
-#define BNEZ_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(BRANCH_OPCODE_X1) | \
- create_BrType_X1(BNEZ_BRANCH_OPCODE_X1) | FNOP_X0
-
-#define J_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \
- create_JumpOpcodeExtension_X1(J_JUMP_OPCODE_X1) | FNOP_X0
-
-#define JAL_X1 \
- create_Mode(TILEGX_X_MODE) | create_Opcode_X1(JUMP_OPCODE_X1) | \
- create_JumpOpcodeExtension_X1(JAL_JUMP_OPCODE_X1) | FNOP_X0
-
-#define DEST_X0(x) create_Dest_X0(x)
-#define SRCA_X0(x) create_SrcA_X0(x)
-#define SRCB_X0(x) create_SrcB_X0(x)
-#define DEST_X1(x) create_Dest_X1(x)
-#define SRCA_X1(x) create_SrcA_X1(x)
-#define SRCB_X1(x) create_SrcB_X1(x)
-#define IMM16_X1(x) create_Imm16_X1(x)
-#define IMM8_X1(x) create_Imm8_X1(x)
-#define BFSTART_X0(x) create_BFStart_X0(x)
-#define BFEND_X0(x) create_BFEnd_X0(x)
-#define SHIFTIMM_X1(x) create_ShAmt_X1(x)
-#define JOFF_X1(x) create_JumpOff_X1(x)
-#define BOFF_X1(x) create_BrOff_X1(x)
-
-static const tilegx_mnemonic data_transfer_insts[16] = {
- /* u w s */ TILEGX_OPC_ST /* st */,
- /* u w l */ TILEGX_OPC_LD /* ld */,
- /* u b s */ TILEGX_OPC_ST1 /* st1 */,
- /* u b l */ TILEGX_OPC_LD1U /* ld1u */,
- /* u h s */ TILEGX_OPC_ST2 /* st2 */,
- /* u h l */ TILEGX_OPC_LD2U /* ld2u */,
- /* u i s */ TILEGX_OPC_ST4 /* st4 */,
- /* u i l */ TILEGX_OPC_LD4U /* ld4u */,
- /* s w s */ TILEGX_OPC_ST /* st */,
- /* s w l */ TILEGX_OPC_LD /* ld */,
- /* s b s */ TILEGX_OPC_ST1 /* st1 */,
- /* s b l */ TILEGX_OPC_LD1S /* ld1s */,
- /* s h s */ TILEGX_OPC_ST2 /* st2 */,
- /* s h l */ TILEGX_OPC_LD2S /* ld2s */,
- /* s i s */ TILEGX_OPC_ST4 /* st4 */,
- /* s i l */ TILEGX_OPC_LD4S /* ld4s */,
-};
-
-#ifdef TILEGX_JIT_DEBUG
-static sljit_s32 push_inst_debug(struct sljit_compiler *compiler, sljit_ins ins, int line)
-{
- sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
- FAIL_IF(!ptr);
- *ptr = ins;
- compiler->size++;
- printf("|%04d|S0|:\t\t", line);
- print_insn_tilegx(ptr);
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_inst_nodebug(struct sljit_compiler *compiler, sljit_ins ins)
-{
- sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
- FAIL_IF(!ptr);
- *ptr = ins;
- compiler->size++;
- return SLJIT_SUCCESS;
-}
-
-#define push_inst(a, b) push_inst_debug(a, b, __LINE__)
-#else
-static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
-{
- sljit_ins *ptr = (sljit_ins *)ensure_buf(compiler, sizeof(sljit_ins));
- FAIL_IF(!ptr);
- *ptr = ins;
- compiler->size++;
- return SLJIT_SUCCESS;
-}
-#endif
-
-#define BUNDLE_FORMAT_MASK(p0, p1, p2) \
- ((p0) | ((p1) << 8) | ((p2) << 16))
-
-#define BUNDLE_FORMAT(p0, p1, p2) \
- { \
- { \
- (tilegx_pipeline)(p0), \
- (tilegx_pipeline)(p1), \
- (tilegx_pipeline)(p2) \
- }, \
- BUNDLE_FORMAT_MASK(1 << (p0), 1 << (p1), (1 << (p2))) \
- }
-
-#define NO_PIPELINE TILEGX_NUM_PIPELINE_ENCODINGS
-
-#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1)
-
-#define PI(encoding) \
- push_inst(compiler, encoding)
-
-#define PB3(opcode, dst, srca, srcb) \
- push_3_buffer(compiler, opcode, dst, srca, srcb, __LINE__)
-
-#define PB2(opcode, dst, src) \
- push_2_buffer(compiler, opcode, dst, src, __LINE__)
-
-#define JR(reg) \
- push_jr_buffer(compiler, TILEGX_OPC_JR, reg, __LINE__)
-
-#define ADD(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_ADD, dst, srca, srcb, __LINE__)
-
-#define SUB(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_SUB, dst, srca, srcb, __LINE__)
-
-#define MUL(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_MULX, dst, srca, srcb, __LINE__)
-
-#define NOR(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_NOR, dst, srca, srcb, __LINE__)
-
-#define OR(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_OR, dst, srca, srcb, __LINE__)
-
-#define XOR(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_XOR, dst, srca, srcb, __LINE__)
-
-#define AND(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_AND, dst, srca, srcb, __LINE__)
-
-#define CLZ(dst, src) \
- push_2_buffer(compiler, TILEGX_OPC_CLZ, dst, src, __LINE__)
-
-#define SHLI(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_SHLI, dst, srca, srcb, __LINE__)
-
-#define SHRUI(dst, srca, imm) \
- push_3_buffer(compiler, TILEGX_OPC_SHRUI, dst, srca, imm, __LINE__)
-
-#define XORI(dst, srca, imm) \
- push_3_buffer(compiler, TILEGX_OPC_XORI, dst, srca, imm, __LINE__)
-
-#define ORI(dst, srca, imm) \
- push_3_buffer(compiler, TILEGX_OPC_ORI, dst, srca, imm, __LINE__)
-
-#define CMPLTU(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_CMPLTU, dst, srca, srcb, __LINE__)
-
-#define CMPLTS(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_CMPLTS, dst, srca, srcb, __LINE__)
-
-#define CMPLTUI(dst, srca, imm) \
- push_3_buffer(compiler, TILEGX_OPC_CMPLTUI, dst, srca, imm, __LINE__)
-
-#define CMOVNEZ(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_CMOVNEZ, dst, srca, srcb, __LINE__)
-
-#define CMOVEQZ(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_CMOVEQZ, dst, srca, srcb, __LINE__)
-
-#define ADDLI(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_ADDLI, dst, srca, srcb, __LINE__)
-
-#define SHL16INSLI(dst, srca, srcb) \
- push_3_buffer(compiler, TILEGX_OPC_SHL16INSLI, dst, srca, srcb, __LINE__)
-
-#define LD_ADD(dst, addr, adjust) \
- push_3_buffer(compiler, TILEGX_OPC_LD_ADD, dst, addr, adjust, __LINE__)
-
-#define ST_ADD(src, addr, adjust) \
- push_3_buffer(compiler, TILEGX_OPC_ST_ADD, src, addr, adjust, __LINE__)
-
-#define LD(dst, addr) \
- push_2_buffer(compiler, TILEGX_OPC_LD, dst, addr, __LINE__)
-
-#define BFEXTU(dst, src, start, end) \
- push_4_buffer(compiler, TILEGX_OPC_BFEXTU, dst, src, start, end, __LINE__)
-
-#define BFEXTS(dst, src, start, end) \
- push_4_buffer(compiler, TILEGX_OPC_BFEXTS, dst, src, start, end, __LINE__)
-
-#define ADD_SOLO(dest, srca, srcb) \
- push_inst(compiler, ADD_X1 | DEST_X1(dest) | SRCA_X1(srca) | SRCB_X1(srcb))
-
-#define ADDI_SOLO(dest, srca, imm) \
- push_inst(compiler, ADDI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM8_X1(imm))
-
-#define ADDLI_SOLO(dest, srca, imm) \
- push_inst(compiler, ADDLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm))
-
-#define SHL16INSLI_SOLO(dest, srca, imm) \
- push_inst(compiler, SHL16INSLI_X1 | DEST_X1(dest) | SRCA_X1(srca) | IMM16_X1(imm))
-
-#define JALR_SOLO(reg) \
- push_inst(compiler, JALR_X1 | SRCA_X1(reg))
-
-#define JR_SOLO(reg) \
- push_inst(compiler, JR_X1 | SRCA_X1(reg))
-
-struct Format {
- /* Mapping of bundle issue slot to assigned pipe. */
- tilegx_pipeline pipe[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
-
- /* Mask of pipes used by this bundle. */
- unsigned int pipe_mask;
-};
-
-const struct Format formats[] =
-{
- /* In Y format we must always have something in Y2, since it has
- * no fnop, so this conveys that Y2 must always be used. */
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, NO_PIPELINE),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, NO_PIPELINE),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, NO_PIPELINE),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, NO_PIPELINE),
-
- /* Y format has three instructions. */
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y2),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y0, TILEGX_PIPELINE_Y1),
- BUNDLE_FORMAT(TILEGX_PIPELINE_Y2, TILEGX_PIPELINE_Y1, TILEGX_PIPELINE_Y0),
-
- /* X format has only two instructions. */
- BUNDLE_FORMAT(TILEGX_PIPELINE_X0, TILEGX_PIPELINE_X1, NO_PIPELINE),
- BUNDLE_FORMAT(TILEGX_PIPELINE_X1, TILEGX_PIPELINE_X0, NO_PIPELINE)
-};
-
-
-struct jit_instr inst_buf[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE];
-unsigned long inst_buf_index;
-
-tilegx_pipeline get_any_valid_pipe(const struct tilegx_opcode* opcode)
-{
- /* FIXME: tile: we could pregenerate this. */
- int pipe;
- for (pipe = 0; ((opcode->pipes & (1 << pipe)) == 0 && pipe < TILEGX_NUM_PIPELINE_ENCODINGS); pipe++)
- ;
- return (tilegx_pipeline)(pipe);
-}
-
-void insert_nop(tilegx_mnemonic opc, int line)
-{
- const struct tilegx_opcode* opcode = NULL;
-
- memmove(&inst_buf[1], &inst_buf[0], inst_buf_index * sizeof inst_buf[0]);
-
- opcode = &tilegx_opcodes[opc];
- inst_buf[0].opcode = opcode;
- inst_buf[0].pipe = get_any_valid_pipe(opcode);
- inst_buf[0].input_registers = 0;
- inst_buf[0].output_registers = 0;
- inst_buf[0].line = line;
- ++inst_buf_index;
-}
-
-const struct Format* compute_format()
-{
- unsigned int compatible_pipes = BUNDLE_FORMAT_MASK(
- inst_buf[0].opcode->pipes,
- inst_buf[1].opcode->pipes,
- (inst_buf_index == 3 ? inst_buf[2].opcode->pipes : (1 << NO_PIPELINE)));
-
- const struct Format* match = NULL;
- const struct Format *b = NULL;
- unsigned int i;
- for (i = 0; i < sizeof formats / sizeof formats[0]; i++) {
- b = &formats[i];
- if ((b->pipe_mask & compatible_pipes) == b->pipe_mask) {
- match = b;
- break;
- }
- }
-
- return match;
-}
-
-sljit_s32 assign_pipes()
-{
- unsigned long output_registers = 0;
- unsigned int i = 0;
-
- if (inst_buf_index == 1) {
- tilegx_mnemonic opc = inst_buf[0].opcode->can_bundle
- ? TILEGX_OPC_FNOP : TILEGX_OPC_NOP;
- insert_nop(opc, __LINE__);
- }
-
- const struct Format* match = compute_format();
-
- if (match == NULL)
- return -1;
-
- for (i = 0; i < inst_buf_index; i++) {
-
- if ((i > 0) && ((inst_buf[i].input_registers & output_registers) != 0))
- return -1;
-
- if ((i > 0) && ((inst_buf[i].output_registers & output_registers) != 0))
- return -1;
-
- /* Don't include Rzero in the match set, to avoid triggering
- needlessly on 'prefetch' instrs. */
-
- output_registers |= inst_buf[i].output_registers & 0xFFFFFFFFFFFFFFL;
-
- inst_buf[i].pipe = match->pipe[i];
- }
-
- /* If only 2 instrs, and in Y-mode, insert a nop. */
- if (inst_buf_index == 2 && !tilegx_is_x_pipeline(match->pipe[0])) {
- insert_nop(TILEGX_OPC_FNOP, __LINE__);
-
- /* Select the yet unassigned pipe. */
- tilegx_pipeline pipe = (tilegx_pipeline)(((TILEGX_PIPELINE_Y0
- + TILEGX_PIPELINE_Y1 + TILEGX_PIPELINE_Y2)
- - (inst_buf[1].pipe + inst_buf[2].pipe)));
-
- inst_buf[0].pipe = pipe;
- }
-
- return 0;
-}
-
-tilegx_bundle_bits get_bundle_bit(struct jit_instr *inst)
-{
- int i, val;
- const struct tilegx_opcode* opcode = inst->opcode;
- tilegx_bundle_bits bits = opcode->fixed_bit_values[inst->pipe];
-
- const struct tilegx_operand* operand = NULL;
- for (i = 0; i < opcode->num_operands; i++) {
- operand = &tilegx_operands[opcode->operands[inst->pipe][i]];
- val = inst->operand_value[i];
-
- bits |= operand->insert(val);
- }
-
- return bits;
-}
-
-static sljit_s32 update_buffer(struct sljit_compiler *compiler)
-{
- int i;
- int orig_index = inst_buf_index;
- struct jit_instr inst0 = inst_buf[0];
- struct jit_instr inst1 = inst_buf[1];
- struct jit_instr inst2 = inst_buf[2];
- tilegx_bundle_bits bits = 0;
-
- /* If the bundle is valid as is, perform the encoding and return 1. */
- if (assign_pipes() == 0) {
- for (i = 0; i < inst_buf_index; i++) {
- bits |= get_bundle_bit(inst_buf + i);
-#ifdef TILEGX_JIT_DEBUG
- printf("|%04d", inst_buf[i].line);
-#endif
- }
-#ifdef TILEGX_JIT_DEBUG
- if (inst_buf_index == 3)
- printf("|M0|:\t");
- else
- printf("|M0|:\t\t");
- print_insn_tilegx(&bits);
-#endif
-
- inst_buf_index = 0;
-
-#ifdef TILEGX_JIT_DEBUG
- return push_inst_nodebug(compiler, bits);
-#else
- return push_inst(compiler, bits);
-#endif
- }
-
- /* If the bundle is invalid, split it in two. First encode the first two
- (or possibly 1) instructions, and then the last, separately. Note that
- assign_pipes may have re-ordered the instrs (by inserting no-ops in
- lower slots) so we need to reset them. */
-
- inst_buf_index = orig_index - 1;
- inst_buf[0] = inst0;
- inst_buf[1] = inst1;
- inst_buf[2] = inst2;
- if (assign_pipes() == 0) {
- for (i = 0; i < inst_buf_index; i++) {
- bits |= get_bundle_bit(inst_buf + i);
-#ifdef TILEGX_JIT_DEBUG
- printf("|%04d", inst_buf[i].line);
-#endif
- }
-
-#ifdef TILEGX_JIT_DEBUG
- if (inst_buf_index == 3)
- printf("|M1|:\t");
- else
- printf("|M1|:\t\t");
- print_insn_tilegx(&bits);
-#endif
-
- if ((orig_index - 1) == 2) {
- inst_buf[0] = inst2;
- inst_buf_index = 1;
- } else if ((orig_index - 1) == 1) {
- inst_buf[0] = inst1;
- inst_buf_index = 1;
- } else
- SLJIT_UNREACHABLE();
-
-#ifdef TILEGX_JIT_DEBUG
- return push_inst_nodebug(compiler, bits);
-#else
- return push_inst(compiler, bits);
-#endif
- } else {
- /* We had 3 instrs of which the first 2 can't live in the same bundle.
- Split those two. Note that we don't try to then combine the second
- and third instr into a single bundle. First instruction: */
- inst_buf_index = 1;
- inst_buf[0] = inst0;
- inst_buf[1] = inst1;
- inst_buf[2] = inst2;
- if (assign_pipes() == 0) {
- for (i = 0; i < inst_buf_index; i++) {
- bits |= get_bundle_bit(inst_buf + i);
-#ifdef TILEGX_JIT_DEBUG
- printf("|%04d", inst_buf[i].line);
-#endif
- }
-
-#ifdef TILEGX_JIT_DEBUG
- if (inst_buf_index == 3)
- printf("|M2|:\t");
- else
- printf("|M2|:\t\t");
- print_insn_tilegx(&bits);
-#endif
-
- inst_buf[0] = inst1;
- inst_buf[1] = inst2;
- inst_buf_index = orig_index - 1;
-#ifdef TILEGX_JIT_DEBUG
- return push_inst_nodebug(compiler, bits);
-#else
- return push_inst(compiler, bits);
-#endif
- } else
- SLJIT_UNREACHABLE();
- }
-
- SLJIT_UNREACHABLE();
-}
-
-static sljit_s32 flush_buffer(struct sljit_compiler *compiler)
-{
- while (inst_buf_index != 0) {
- FAIL_IF(update_buffer(compiler));
- }
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_4_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int op3, int line)
-{
- if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
- FAIL_IF(update_buffer(compiler));
-
- const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
- inst_buf[inst_buf_index].opcode = opcode;
- inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
- inst_buf[inst_buf_index].operand_value[0] = op0;
- inst_buf[inst_buf_index].operand_value[1] = op1;
- inst_buf[inst_buf_index].operand_value[2] = op2;
- inst_buf[inst_buf_index].operand_value[3] = op3;
- inst_buf[inst_buf_index].input_registers = 1L << op1;
- inst_buf[inst_buf_index].output_registers = 1L << op0;
- inst_buf[inst_buf_index].line = line;
- inst_buf_index++;
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_3_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int op2, int line)
-{
- if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
- FAIL_IF(update_buffer(compiler));
-
- const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
- inst_buf[inst_buf_index].opcode = opcode;
- inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
- inst_buf[inst_buf_index].operand_value[0] = op0;
- inst_buf[inst_buf_index].operand_value[1] = op1;
- inst_buf[inst_buf_index].operand_value[2] = op2;
- inst_buf[inst_buf_index].line = line;
-
- switch (opc) {
- case TILEGX_OPC_ST_ADD:
- inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1);
- inst_buf[inst_buf_index].output_registers = 1L << op0;
- break;
- case TILEGX_OPC_LD_ADD:
- inst_buf[inst_buf_index].input_registers = 1L << op1;
- inst_buf[inst_buf_index].output_registers = (1L << op0) | (1L << op1);
- break;
- case TILEGX_OPC_ADD:
- case TILEGX_OPC_AND:
- case TILEGX_OPC_SUB:
- case TILEGX_OPC_MULX:
- case TILEGX_OPC_OR:
- case TILEGX_OPC_XOR:
- case TILEGX_OPC_NOR:
- case TILEGX_OPC_SHL:
- case TILEGX_OPC_SHRU:
- case TILEGX_OPC_SHRS:
- case TILEGX_OPC_CMPLTU:
- case TILEGX_OPC_CMPLTS:
- case TILEGX_OPC_CMOVEQZ:
- case TILEGX_OPC_CMOVNEZ:
- inst_buf[inst_buf_index].input_registers = (1L << op1) | (1L << op2);
- inst_buf[inst_buf_index].output_registers = 1L << op0;
- break;
- case TILEGX_OPC_ADDLI:
- case TILEGX_OPC_XORI:
- case TILEGX_OPC_ORI:
- case TILEGX_OPC_SHLI:
- case TILEGX_OPC_SHRUI:
- case TILEGX_OPC_SHRSI:
- case TILEGX_OPC_SHL16INSLI:
- case TILEGX_OPC_CMPLTUI:
- case TILEGX_OPC_CMPLTSI:
- inst_buf[inst_buf_index].input_registers = 1L << op1;
- inst_buf[inst_buf_index].output_registers = 1L << op0;
- break;
- default:
- printf("unrecoginzed opc: %s\n", opcode->name);
- SLJIT_UNREACHABLE();
- }
-
- inst_buf_index++;
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_2_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int op1, int line)
-{
- if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
- FAIL_IF(update_buffer(compiler));
-
- const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
- inst_buf[inst_buf_index].opcode = opcode;
- inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
- inst_buf[inst_buf_index].operand_value[0] = op0;
- inst_buf[inst_buf_index].operand_value[1] = op1;
- inst_buf[inst_buf_index].line = line;
-
- switch (opc) {
- case TILEGX_OPC_BEQZ:
- case TILEGX_OPC_BNEZ:
- inst_buf[inst_buf_index].input_registers = 1L << op0;
- break;
- case TILEGX_OPC_ST:
- case TILEGX_OPC_ST1:
- case TILEGX_OPC_ST2:
- case TILEGX_OPC_ST4:
- inst_buf[inst_buf_index].input_registers = (1L << op0) | (1L << op1);
- inst_buf[inst_buf_index].output_registers = 0;
- break;
- case TILEGX_OPC_CLZ:
- case TILEGX_OPC_LD:
- case TILEGX_OPC_LD1U:
- case TILEGX_OPC_LD1S:
- case TILEGX_OPC_LD2U:
- case TILEGX_OPC_LD2S:
- case TILEGX_OPC_LD4U:
- case TILEGX_OPC_LD4S:
- inst_buf[inst_buf_index].input_registers = 1L << op1;
- inst_buf[inst_buf_index].output_registers = 1L << op0;
- break;
- default:
- printf("unrecoginzed opc: %s\n", opcode->name);
- SLJIT_UNREACHABLE();
- }
-
- inst_buf_index++;
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_0_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int line)
-{
- if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
- FAIL_IF(update_buffer(compiler));
-
- const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
- inst_buf[inst_buf_index].opcode = opcode;
- inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
- inst_buf[inst_buf_index].input_registers = 0;
- inst_buf[inst_buf_index].output_registers = 0;
- inst_buf[inst_buf_index].line = line;
- inst_buf_index++;
-
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 push_jr_buffer(struct sljit_compiler *compiler, tilegx_mnemonic opc, int op0, int line)
-{
- if (inst_buf_index == TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE)
- FAIL_IF(update_buffer(compiler));
-
- const struct tilegx_opcode* opcode = &tilegx_opcodes[opc];
- inst_buf[inst_buf_index].opcode = opcode;
- inst_buf[inst_buf_index].pipe = get_any_valid_pipe(opcode);
- inst_buf[inst_buf_index].operand_value[0] = op0;
- inst_buf[inst_buf_index].input_registers = 1L << op0;
- inst_buf[inst_buf_index].output_registers = 0;
- inst_buf[inst_buf_index].line = line;
- inst_buf_index++;
-
- return flush_buffer(compiler);
-}
-
-static SLJIT_INLINE sljit_ins * detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
-{
- sljit_sw diff;
- sljit_uw target_addr;
- sljit_ins *inst;
-
- if (jump->flags & SLJIT_REWRITABLE_JUMP)
- return code_ptr;
-
- if (jump->flags & JUMP_ADDR)
- target_addr = jump->u.target;
- else {
- SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- target_addr = (sljit_uw)(code + jump->u.label->size);
- }
-
- inst = (sljit_ins *)jump->addr;
- if (jump->flags & IS_COND)
- inst--;
-
- diff = ((sljit_sw) target_addr - (sljit_sw) inst) >> 3;
- if (diff <= SIMM_17BIT_MAX && diff >= SIMM_17BIT_MIN) {
- jump->flags |= PATCH_B;
-
- if (!(jump->flags & IS_COND)) {
- if (jump->flags & IS_JAL) {
- jump->flags &= ~(PATCH_B);
- jump->flags |= PATCH_J;
- inst[0] = JAL_X1;
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(inst);
-#endif
- } else {
- inst[0] = BEQZ_X1 | SRCA_X1(ZERO);
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(inst);
-#endif
- }
-
- return inst;
- }
-
- inst[0] = inst[0] ^ (0x7L << 55);
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(inst);
-#endif
- jump->addr -= sizeof(sljit_ins);
- return inst;
- }
-
- if (jump->flags & IS_COND) {
- if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) {
- jump->flags |= PATCH_J;
- inst[0] = (inst[0] & ~(BOFF_X1(-1))) | BOFF_X1(2);
- inst[1] = J_X1;
- return inst + 1;
- }
-
- return code_ptr;
- }
-
- if ((target_addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL)) {
- jump->flags |= PATCH_J;
-
- if (jump->flags & IS_JAL) {
- inst[0] = JAL_X1;
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(inst);
-#endif
-
- } else {
- inst[0] = J_X1;
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(inst);
-#endif
- }
-
- return inst;
- }
-
- return code_ptr;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void * sljit_generate_code(struct sljit_compiler *compiler)
-{
- struct sljit_memory_fragment *buf;
- sljit_ins *code;
- sljit_ins *code_ptr;
- sljit_ins *buf_ptr;
- sljit_ins *buf_end;
- sljit_uw word_count;
- sljit_uw addr;
-
- struct sljit_label *label;
- struct sljit_jump *jump;
- struct sljit_const *const_;
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
- reverse_buf(compiler);
-
- code = (sljit_ins *)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins));
- PTR_FAIL_WITH_EXEC_IF(code);
- buf = compiler->buf;
-
- code_ptr = code;
- word_count = 0;
- label = compiler->labels;
- jump = compiler->jumps;
- const_ = compiler->consts;
- do {
- buf_ptr = (sljit_ins *)buf->memory;
- buf_end = buf_ptr + (buf->used_size >> 3);
- do {
- *code_ptr = *buf_ptr++;
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- /* These structures are ordered by their address. */
- if (label && label->size == word_count) {
- /* Just recording the address. */
- label->addr = (sljit_uw) code_ptr;
- label->size = code_ptr - code;
- label = label->next;
- }
-
- if (jump && jump->addr == word_count) {
- if (jump->flags & IS_JAL)
- jump->addr = (sljit_uw)(code_ptr - 4);
- else
- jump->addr = (sljit_uw)(code_ptr - 3);
-
- code_ptr = detect_jump_type(jump, code_ptr, code);
- jump = jump->next;
- }
-
- if (const_ && const_->addr == word_count) {
- /* Just recording the address. */
- const_->addr = (sljit_uw) code_ptr;
- const_ = const_->next;
- }
-
- code_ptr++;
- word_count++;
- } while (buf_ptr < buf_end);
-
- buf = buf->next;
- } while (buf);
-
- if (label && label->size == word_count) {
- label->addr = (sljit_uw) code_ptr;
- label->size = code_ptr - code;
- label = label->next;
- }
-
- SLJIT_ASSERT(!label);
- SLJIT_ASSERT(!jump);
- SLJIT_ASSERT(!const_);
- 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;
- buf_ptr = (sljit_ins *)jump->addr;
-
- if (jump->flags & PATCH_B) {
- addr = (sljit_sw)(addr - (jump->addr)) >> 3;
- SLJIT_ASSERT((sljit_sw) addr <= SIMM_17BIT_MAX && (sljit_sw) addr >= SIMM_17BIT_MIN);
- buf_ptr[0] = (buf_ptr[0] & ~(BOFF_X1(-1))) | BOFF_X1(addr);
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(buf_ptr);
-#endif
- break;
- }
-
- if (jump->flags & PATCH_J) {
- SLJIT_ASSERT((addr & ~0x3FFFFFFFL) == ((jump->addr + sizeof(sljit_ins)) & ~0x3FFFFFFFL));
- addr = (sljit_sw)(addr - (jump->addr)) >> 3;
- buf_ptr[0] = (buf_ptr[0] & ~(JOFF_X1(-1))) | JOFF_X1(addr);
-
-#ifdef TILEGX_JIT_DEBUG
- printf("[runtime relocate]%04d:\t", __LINE__);
- print_insn_tilegx(buf_ptr);
-#endif
- break;
- }
-
- SLJIT_ASSERT(!(jump->flags & IS_JAL));
-
- /* Set the fields of immediate loads. */
- buf_ptr[0] = (buf_ptr[0] & ~(0xFFFFL << 43)) | (((addr >> 32) & 0xFFFFL) << 43);
- buf_ptr[1] = (buf_ptr[1] & ~(0xFFFFL << 43)) | (((addr >> 16) & 0xFFFFL) << 43);
- buf_ptr[2] = (buf_ptr[2] & ~(0xFFFFL << 43)) | ((addr & 0xFFFFL) << 43);
- } while (0);
-
- jump = jump->next;
- }
-
- compiler->error = SLJIT_ERR_COMPILED;
- compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
- SLJIT_CACHE_FLUSH(code, code_ptr);
- return code;
-}
-
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm)
-{
-
- if (imm <= SIMM_16BIT_MAX && imm >= SIMM_16BIT_MIN)
- return ADDLI(dst_ar, ZERO, imm);
-
- if (imm <= SIMM_32BIT_MAX && imm >= SIMM_32BIT_MIN) {
- FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 16));
- return SHL16INSLI(dst_ar, dst_ar, imm);
- }
-
- if (imm <= SIMM_48BIT_MAX && imm >= SIMM_48BIT_MIN) {
- FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32));
- FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
- return SHL16INSLI(dst_ar, dst_ar, imm);
- }
-
- FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 48));
- FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 32));
- FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
- return SHL16INSLI(dst_ar, dst_ar, imm);
-}
-
-static sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush)
-{
- /* Should *not* be optimized as load_immediate, as pcre relocation
- mechanism will match this fixed 4-instruction pattern. */
- if (flush) {
- FAIL_IF(ADDLI_SOLO(dst_ar, ZERO, imm >> 32));
- FAIL_IF(SHL16INSLI_SOLO(dst_ar, dst_ar, imm >> 16));
- return SHL16INSLI_SOLO(dst_ar, dst_ar, imm);
- }
-
- FAIL_IF(ADDLI(dst_ar, ZERO, imm >> 32));
- FAIL_IF(SHL16INSLI(dst_ar, dst_ar, imm >> 16));
- return SHL16INSLI(dst_ar, dst_ar, imm);
-}
-
-static sljit_s32 emit_const_64(struct sljit_compiler *compiler, sljit_s32 dst_ar, sljit_sw imm, int flush)
-{
- /* Should *not* be optimized as load_immediate, as pcre relocation
- mechanism will match this fixed 4-instruction pattern. */
- if (flush) {
- FAIL_IF(ADDLI_SOLO(reg_map[dst_ar], ZERO, imm >> 48));
- FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 32));
- FAIL_IF(SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm >> 16));
- return SHL16INSLI_SOLO(reg_map[dst_ar], reg_map[dst_ar], imm);
- }
-
- FAIL_IF(ADDLI(reg_map[dst_ar], ZERO, imm >> 48));
- FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 32));
- FAIL_IF(SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm >> 16));
- return SHL16INSLI(reg_map[dst_ar], reg_map[dst_ar], imm);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- sljit_ins base;
- sljit_s32 i, tmp;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
- set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
-
- local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
- local_size = (local_size + 7) & ~7;
- compiler->local_size = local_size;
-
- if (local_size <= SIMM_16BIT_MAX) {
- /* Frequent case. */
- FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, -local_size));
- base = SLJIT_LOCALS_REG_mapped;
- } else {
- FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size));
- FAIL_IF(ADD(TMP_REG2_mapped, SLJIT_LOCALS_REG_mapped, ZERO));
- FAIL_IF(SUB(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped));
- base = TMP_REG2_mapped;
- local_size = 0;
- }
-
- /* Save the return address. */
- FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
- FAIL_IF(ST_ADD(ADDR_TMP_mapped, RA, -8));
-
- /* Save the S registers. */
- tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
- for (i = SLJIT_S0; i >= tmp; i--) {
- FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));
- }
-
- /* Save the R registers that need to be reserved. */
- for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- FAIL_IF(ST_ADD(ADDR_TMP_mapped, reg_map[i], -8));
- }
-
- /* Move the arguments to S registers. */
- for (i = 0; i < args; i++) {
- FAIL_IF(ADD(reg_map[SLJIT_S0 - i], i, ZERO));
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
- sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
- sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
- set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
-
- local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
- compiler->local_size = (local_size + 7) & ~7;
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 local_size;
- sljit_ins base;
- sljit_s32 i, tmp;
- sljit_s32 saveds;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_return(compiler, op, src, srcw));
-
- FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));
-
- local_size = compiler->local_size;
- if (local_size <= SIMM_16BIT_MAX)
- base = SLJIT_LOCALS_REG_mapped;
- else {
- FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, local_size));
- FAIL_IF(ADD(TMP_REG1_mapped, SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped));
- base = TMP_REG1_mapped;
- local_size = 0;
- }
-
- /* Restore the return address. */
- FAIL_IF(ADDLI(ADDR_TMP_mapped, base, local_size - 8));
- FAIL_IF(LD_ADD(RA, ADDR_TMP_mapped, -8));
-
- /* Restore the S registers. */
- saveds = compiler->saveds;
- tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
- for (i = SLJIT_S0; i >= tmp; i--) {
- FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));
- }
-
- /* Restore the R registers that need to be reserved. */
- for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
- FAIL_IF(LD_ADD(reg_map[i], ADDR_TMP_mapped, -8));
- }
-
- if (compiler->local_size <= SIMM_16BIT_MAX)
- FAIL_IF(ADDLI(SLJIT_LOCALS_REG_mapped, SLJIT_LOCALS_REG_mapped, compiler->local_size));
- else
- FAIL_IF(ADD(SLJIT_LOCALS_REG_mapped, TMP_REG1_mapped, ZERO));
-
- return JR(RA);
-}
-
-/* reg_ar is an absoulute register! */
-
-/* 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_ar, sljit_s32 arg, sljit_sw argw)
-{
- SLJIT_ASSERT(arg & SLJIT_MEM);
-
- if ((!(flags & WRITE_BACK) || !(arg & REG_MASK))
- && !(arg & OFFS_REG_MASK) && argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
- /* Works for both absoulte and relative addresses. */
- if (SLJIT_UNLIKELY(flags & ARG_TEST))
- return 1;
-
- FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[arg & REG_MASK], argw));
-
- if (flags & LOAD_DATA)
- FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped));
- else
- FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar));
-
- return -1;
- }
-
- return 0;
-}
-
-/* See getput_arg below.
- Note: can_cache is called only for binary operators. Those
- operators always uses word arguments without write back. */
-static sljit_s32 can_cache(sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
- SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM));
-
- /* Simple operation except for updates. */
- if (arg & OFFS_REG_MASK) {
- argw &= 0x3;
- next_argw &= 0x3;
- if (argw && argw == next_argw
- && (arg == next_arg || (arg & OFFS_REG_MASK) == (next_arg & OFFS_REG_MASK)))
- return 1;
- return 0;
- }
-
- if (arg == next_arg) {
- if (((next_argw - argw) <= SIMM_16BIT_MAX
- && (next_argw - argw) >= SIMM_16BIT_MIN))
- return 1;
-
- return 0;
- }
-
- return 0;
-}
-
-/* Emit the necessary instructions. See can_cache above. */
-static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw, sljit_s32 next_arg, sljit_sw next_argw)
-{
- sljit_s32 tmp_ar, base;
-
- SLJIT_ASSERT(arg & SLJIT_MEM);
- if (!(next_arg & SLJIT_MEM)) {
- next_arg = 0;
- next_argw = 0;
- }
-
- if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA))
- tmp_ar = reg_ar;
- else
- tmp_ar = TMP_REG1_mapped;
-
- base = arg & REG_MASK;
-
- if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
- argw &= 0x3;
-
- if ((flags & WRITE_BACK) && reg_ar == reg_map[base]) {
- SLJIT_ASSERT(!(flags & LOAD_DATA) && reg_map[TMP_REG1] != reg_ar);
- FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));
- reg_ar = TMP_REG1_mapped;
- }
-
- /* Using the cache. */
- if (argw == compiler->cache_argw) {
- if (!(flags & WRITE_BACK)) {
- if (arg == compiler->cache_arg) {
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
- }
-
- if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
- if (arg == next_arg && argw == (next_argw & 0x3)) {
- compiler->cache_arg = arg;
- compiler->cache_argw = argw;
- FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], TMP_REG3_mapped));
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
- }
-
- FAIL_IF(ADD(tmp_ar, reg_map[base], TMP_REG3_mapped));
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
- }
- } else {
- if ((SLJIT_MEM | (arg & OFFS_REG_MASK)) == compiler->cache_arg) {
- FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
- }
- }
- }
-
- if (SLJIT_UNLIKELY(argw)) {
- compiler->cache_arg = SLJIT_MEM | (arg & OFFS_REG_MASK);
- compiler->cache_argw = argw;
- FAIL_IF(SHLI(TMP_REG3_mapped, reg_map[OFFS_REG(arg)], argw));
- }
-
- if (!(flags & WRITE_BACK)) {
- if (arg == next_arg && argw == (next_argw & 0x3)) {
- compiler->cache_arg = arg;
- compiler->cache_argw = argw;
- FAIL_IF(ADD(TMP_REG3_mapped, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
- tmp_ar = TMP_REG3_mapped;
- } else
- FAIL_IF(ADD(tmp_ar, reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
-
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
- }
-
- FAIL_IF(ADD(reg_map[base], reg_map[base], reg_map[!argw ? OFFS_REG(arg) : TMP_REG3]));
-
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
- }
-
- if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) {
- /* Update only applies if a base register exists. */
- if (reg_ar == reg_map[base]) {
- SLJIT_ASSERT(!(flags & LOAD_DATA) && TMP_REG1_mapped != reg_ar);
- if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
- FAIL_IF(ADDLI(ADDR_TMP_mapped, reg_map[base], argw));
- if (flags & LOAD_DATA)
- FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, ADDR_TMP_mapped));
- else
- FAIL_IF(PB2(data_transfer_insts[flags & MEM_MASK], ADDR_TMP_mapped, reg_ar));
-
- if (argw)
- return ADDLI(reg_map[base], reg_map[base], argw);
-
- return SLJIT_SUCCESS;
- }
-
- FAIL_IF(ADD(TMP_REG1_mapped, reg_ar, ZERO));
- reg_ar = TMP_REG1_mapped;
- }
-
- if (argw <= SIMM_16BIT_MAX && argw >= SIMM_16BIT_MIN) {
- if (argw)
- FAIL_IF(ADDLI(reg_map[base], reg_map[base], argw));
- } else {
- if (compiler->cache_arg == SLJIT_MEM
- && argw - compiler->cache_argw <= SIMM_16BIT_MAX
- && argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
- if (argw != compiler->cache_argw) {
- FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
- compiler->cache_argw = argw;
- }
-
- FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
- } else {
- compiler->cache_arg = SLJIT_MEM;
- compiler->cache_argw = argw;
- FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));
- FAIL_IF(ADD(reg_map[base], reg_map[base], TMP_REG3_mapped));
- }
- }
-
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, reg_map[base]);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_map[base], reg_ar);
- }
-
- if (compiler->cache_arg == arg
- && argw - compiler->cache_argw <= SIMM_16BIT_MAX
- && argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
- if (argw != compiler->cache_argw) {
- FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
- compiler->cache_argw = argw;
- }
-
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
- }
-
- if (compiler->cache_arg == SLJIT_MEM
- && argw - compiler->cache_argw <= SIMM_16BIT_MAX
- && argw - compiler->cache_argw >= SIMM_16BIT_MIN) {
- if (argw != compiler->cache_argw)
- FAIL_IF(ADDLI(TMP_REG3_mapped, TMP_REG3_mapped, argw - compiler->cache_argw));
- } else {
- compiler->cache_arg = SLJIT_MEM;
- FAIL_IF(load_immediate(compiler, TMP_REG3_mapped, argw));
- }
-
- compiler->cache_argw = argw;
-
- if (!base) {
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
- }
-
- if (arg == next_arg
- && next_argw - argw <= SIMM_16BIT_MAX
- && next_argw - argw >= SIMM_16BIT_MIN) {
- compiler->cache_arg = arg;
- FAIL_IF(ADD(TMP_REG3_mapped, TMP_REG3_mapped, reg_map[base]));
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, TMP_REG3_mapped);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], TMP_REG3_mapped, reg_ar);
- }
-
- FAIL_IF(ADD(tmp_ar, TMP_REG3_mapped, reg_map[base]));
-
- if (flags & LOAD_DATA)
- return PB2(data_transfer_insts[flags & MEM_MASK], reg_ar, tmp_ar);
- else
- return PB2(data_transfer_insts[flags & MEM_MASK], tmp_ar, reg_ar);
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
-{
- if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
- return compiler->error;
-
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
- return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0);
-}
-
-static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
-{
- if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
- return compiler->error;
- return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- /* For UNUSED dst. Uncommon, but possible. */
- if (dst == SLJIT_UNUSED)
- return SLJIT_SUCCESS;
-
- if (FAST_IS_REG(dst))
- return ADD(reg_map[dst], RA, ZERO);
-
- /* Memory. */
- return emit_op_mem(compiler, WORD_DATA, RA, dst, dstw);
-}
-
-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 overflow_ra = 0;
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV:
- case SLJIT_MOV_P:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if (dst != src2)
- return ADD(reg_map[dst], reg_map[src2], ZERO);
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U32:
- case SLJIT_MOV_S32:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- if (op == SLJIT_MOV_S32)
- return BFEXTS(reg_map[dst], reg_map[src2], 0, 31);
-
- return BFEXTU(reg_map[dst], reg_map[src2], 0, 31);
- } else if (dst != src2) {
- SLJIT_ASSERT(src2 == 0);
- return ADD(reg_map[dst], reg_map[src2], ZERO);
- }
-
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U8:
- case SLJIT_MOV_S8:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- if (op == SLJIT_MOV_S8)
- return BFEXTS(reg_map[dst], reg_map[src2], 0, 7);
-
- return BFEXTU(reg_map[dst], reg_map[src2], 0, 7);
- } else if (dst != src2) {
- SLJIT_ASSERT(src2 == 0);
- return ADD(reg_map[dst], reg_map[src2], ZERO);
- }
-
- return SLJIT_SUCCESS;
-
- case SLJIT_MOV_U16:
- case SLJIT_MOV_S16:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
- if (op == SLJIT_MOV_S16)
- return BFEXTS(reg_map[dst], reg_map[src2], 0, 15);
-
- return BFEXTU(reg_map[dst], reg_map[src2], 0, 15);
- } else if (dst != src2) {
- SLJIT_ASSERT(src2 == 0);
- return ADD(reg_map[dst], reg_map[src2], ZERO);
- }
-
- return SLJIT_SUCCESS;
-
- case SLJIT_NOT:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if (op & SLJIT_SET_E)
- FAIL_IF(NOR(EQUAL_FLAG, reg_map[src2], reg_map[src2]));
- if (CHECK_FLAGS(SLJIT_SET_E))
- FAIL_IF(NOR(reg_map[dst], reg_map[src2], reg_map[src2]));
-
- return SLJIT_SUCCESS;
-
- case SLJIT_CLZ:
- SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
- if (op & SLJIT_SET_E)
- FAIL_IF(CLZ(EQUAL_FLAG, reg_map[src2]));
- if (CHECK_FLAGS(SLJIT_SET_E))
- FAIL_IF(CLZ(reg_map[dst], reg_map[src2]));
-
- return SLJIT_SUCCESS;
-
- case SLJIT_ADD:
- if (flags & SRC2_IMM) {
- if (op & SLJIT_SET_O) {
- FAIL_IF(SHRUI(TMP_EREG1, reg_map[src1], 63));
- if (src2 < 0)
- FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1));
- }
-
- if (op & SLJIT_SET_E)
- FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], src2));
-
- if (op & SLJIT_SET_C) {
- if (src2 >= 0)
- FAIL_IF(ORI(ULESS_FLAG ,reg_map[src1], src2));
- else {
- FAIL_IF(ADDLI(ULESS_FLAG ,ZERO, src2));
- FAIL_IF(OR(ULESS_FLAG,reg_map[src1],ULESS_FLAG));
- }
- }
-
- /* dst may be the same as src1 or src2. */
- if (CHECK_FLAGS(SLJIT_SET_E))
- FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2));
-
- if (op & SLJIT_SET_O) {
- FAIL_IF(SHRUI(OVERFLOW_FLAG, reg_map[dst], 63));
-
- if (src2 < 0)
- FAIL_IF(XORI(OVERFLOW_FLAG, OVERFLOW_FLAG, 1));
- }
- } else {
- if (op & SLJIT_SET_O) {
- FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2]));
- FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63));
-
- if (src1 != dst)
- overflow_ra = reg_map[src1];
- else if (src2 != dst)
- overflow_ra = reg_map[src2];
- else {
- /* Rare ocasion. */
- FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
- overflow_ra = TMP_EREG2;
- }
- }
-
- if (op & SLJIT_SET_E)
- FAIL_IF(ADD(EQUAL_FLAG ,reg_map[src1], reg_map[src2]));
-
- if (op & SLJIT_SET_C)
- FAIL_IF(OR(ULESS_FLAG,reg_map[src1], reg_map[src2]));
-
- /* dst may be the same as src1 or src2. */
- if (CHECK_FLAGS(SLJIT_SET_E))
- FAIL_IF(ADD(reg_map[dst],reg_map[src1], reg_map[src2]));
-
- if (op & SLJIT_SET_O) {
- FAIL_IF(XOR(OVERFLOW_FLAG,reg_map[dst], overflow_ra));
- FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63));
- }
- }
-
- /* a + b >= a | b (otherwise, the carry should be set to 1). */
- if (op & SLJIT_SET_C)
- FAIL_IF(CMPLTU(ULESS_FLAG ,reg_map[dst] ,ULESS_FLAG));
-
- if (op & SLJIT_SET_O)
- return CMOVNEZ(OVERFLOW_FLAG, TMP_EREG1, ZERO);
-
- return SLJIT_SUCCESS;
-
- case SLJIT_ADDC:
- if (flags & SRC2_IMM) {
- if (op & SLJIT_SET_C) {
- if (src2 >= 0)
- FAIL_IF(ORI(TMP_EREG1, reg_map[src1], src2));
- else {
- FAIL_IF(ADDLI(TMP_EREG1, ZERO, src2));
- FAIL_IF(OR(TMP_EREG1, reg_map[src1], TMP_EREG1));
- }
- }
-
- FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], src2));
-
- } else {
- if (op & SLJIT_SET_C)
- FAIL_IF(OR(TMP_EREG1, reg_map[src1], reg_map[src2]));
-
- /* dst may be the same as src1 or src2. */
- FAIL_IF(ADD(reg_map[dst], reg_map[src1], reg_map[src2]));
- }
-
- if (op & SLJIT_SET_C)
- FAIL_IF(CMPLTU(TMP_EREG1, reg_map[dst], TMP_EREG1));
-
- FAIL_IF(ADD(reg_map[dst], reg_map[dst], ULESS_FLAG));
-
- if (!(op & SLJIT_SET_C))
- return SLJIT_SUCCESS;
-
- /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */
- FAIL_IF(CMPLTUI(TMP_EREG2, reg_map[dst], 1));
- FAIL_IF(AND(TMP_EREG2, TMP_EREG2, ULESS_FLAG));
- /* Set carry flag. */
- return OR(ULESS_FLAG, TMP_EREG2, TMP_EREG1);
-
- case SLJIT_SUB:
- if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_16BIT_MIN)) {
- FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- if (flags & SRC2_IMM) {
- if (op & SLJIT_SET_O) {
- FAIL_IF(SHRUI(TMP_EREG1,reg_map[src1], 63));
-
- if (src2 < 0)
- FAIL_IF(XORI(TMP_EREG1, TMP_EREG1, 1));
-
- if (src1 != dst)
- overflow_ra = reg_map[src1];
- else {
- /* Rare ocasion. */
- FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
- overflow_ra = TMP_EREG2;
- }
- }
-
- if (op & SLJIT_SET_E)
- FAIL_IF(ADDLI(EQUAL_FLAG, reg_map[src1], -src2));
-
- if (op & SLJIT_SET_C) {
- FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2));
- FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], ADDR_TMP_mapped));
- }
-
- /* dst may be the same as src1 or src2. */
- if (CHECK_FLAGS(SLJIT_SET_E))
- FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2));
-
- } else {
-
- if (op & SLJIT_SET_O) {
- FAIL_IF(XOR(TMP_EREG1, reg_map[src1], reg_map[src2]));
- FAIL_IF(SHRUI(TMP_EREG1, TMP_EREG1, 63));
-
- if (src1 != dst)
- overflow_ra = reg_map[src1];
- else {
- /* Rare ocasion. */
- FAIL_IF(ADD(TMP_EREG2, reg_map[src1], ZERO));
- overflow_ra = TMP_EREG2;
- }
- }
-
- if (op & SLJIT_SET_E)
- FAIL_IF(SUB(EQUAL_FLAG, reg_map[src1], reg_map[src2]));
-
- if (op & (SLJIT_SET_U | SLJIT_SET_C))
- FAIL_IF(CMPLTU(ULESS_FLAG, reg_map[src1], reg_map[src2]));
-
- if (op & SLJIT_SET_U)
- FAIL_IF(CMPLTU(UGREATER_FLAG, reg_map[src2], reg_map[src1]));
-
- if (op & SLJIT_SET_S) {
- FAIL_IF(CMPLTS(LESS_FLAG ,reg_map[src1] ,reg_map[src2]));
- FAIL_IF(CMPLTS(GREATER_FLAG ,reg_map[src2] ,reg_map[src1]));
- }
-
- /* dst may be the same as src1 or src2. */
- if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
- FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2]));
- }
-
- if (op & SLJIT_SET_O) {
- FAIL_IF(XOR(OVERFLOW_FLAG, reg_map[dst], overflow_ra));
- FAIL_IF(SHRUI(OVERFLOW_FLAG, OVERFLOW_FLAG, 63));
- return CMOVEQZ(OVERFLOW_FLAG, TMP_EREG1, ZERO);
- }
-
- return SLJIT_SUCCESS;
-
- case SLJIT_SUBC:
- if ((flags & SRC2_IMM) && src2 == SIMM_16BIT_MIN) {
- FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- if (flags & SRC2_IMM) {
- if (op & SLJIT_SET_C) {
- FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, -src2));
- FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], ADDR_TMP_mapped));
- }
-
- /* dst may be the same as src1 or src2. */
- FAIL_IF(ADDLI(reg_map[dst], reg_map[src1], -src2));
-
- } else {
- if (op & SLJIT_SET_C)
- FAIL_IF(CMPLTU(TMP_EREG1, reg_map[src1], reg_map[src2]));
- /* dst may be the same as src1 or src2. */
- FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2]));
- }
-
- if (op & SLJIT_SET_C)
- FAIL_IF(CMOVEQZ(TMP_EREG1, reg_map[dst], ULESS_FLAG));
-
- FAIL_IF(SUB(reg_map[dst], reg_map[dst], ULESS_FLAG));
-
- if (op & SLJIT_SET_C)
- FAIL_IF(ADD(ULESS_FLAG, TMP_EREG1, ZERO));
-
- return SLJIT_SUCCESS;
-
- case SLJIT_MUL:
- if (flags & SRC2_IMM) {
- FAIL_IF(load_immediate(compiler, TMP_REG2_mapped, src2));
- src2 = TMP_REG2;
- flags &= ~SRC2_IMM;
- }
-
- FAIL_IF(MUL(reg_map[dst], reg_map[src1], reg_map[src2]));
-
- return SLJIT_SUCCESS;
-
-#define EMIT_LOGICAL(op_imm, op_norm) \
- if (flags & SRC2_IMM) { \
- FAIL_IF(load_immediate(compiler, ADDR_TMP_mapped, src2)); \
- if (op & SLJIT_SET_E) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
- ADDR_TMP_mapped, __LINE__)); \
- if (CHECK_FLAGS(SLJIT_SET_E)) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, reg_map[dst], reg_map[src1], \
- ADDR_TMP_mapped, __LINE__)); \
- } else { \
- if (op & SLJIT_SET_E) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
- reg_map[src2], __LINE__)); \
- if (CHECK_FLAGS(SLJIT_SET_E)) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, reg_map[dst], reg_map[src1], \
- reg_map[src2], __LINE__)); \
- }
-
- case SLJIT_AND:
- EMIT_LOGICAL(TILEGX_OPC_ANDI, TILEGX_OPC_AND);
- return SLJIT_SUCCESS;
-
- case SLJIT_OR:
- EMIT_LOGICAL(TILEGX_OPC_ORI, TILEGX_OPC_OR);
- return SLJIT_SUCCESS;
-
- case SLJIT_XOR:
- EMIT_LOGICAL(TILEGX_OPC_XORI, TILEGX_OPC_XOR);
- return SLJIT_SUCCESS;
-
-#define EMIT_SHIFT(op_imm, op_norm) \
- if (flags & SRC2_IMM) { \
- if (op & SLJIT_SET_E) \
- FAIL_IF(push_3_buffer( \
- compiler, op_imm, EQUAL_FLAG, reg_map[src1], \
- src2 & 0x3F, __LINE__)); \
- if (CHECK_FLAGS(SLJIT_SET_E)) \
- FAIL_IF(push_3_buffer( \
- compiler, op_imm, reg_map[dst], reg_map[src1], \
- src2 & 0x3F, __LINE__)); \
- } else { \
- if (op & SLJIT_SET_E) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, EQUAL_FLAG, reg_map[src1], \
- reg_map[src2], __LINE__)); \
- if (CHECK_FLAGS(SLJIT_SET_E)) \
- FAIL_IF(push_3_buffer( \
- compiler, op_norm, reg_map[dst], reg_map[src1], \
- reg_map[src2], __LINE__)); \
- }
-
- case SLJIT_SHL:
- EMIT_SHIFT(TILEGX_OPC_SHLI, TILEGX_OPC_SHL);
- return SLJIT_SUCCESS;
-
- case SLJIT_LSHR:
- EMIT_SHIFT(TILEGX_OPC_SHRUI, TILEGX_OPC_SHRU);
- return SLJIT_SUCCESS;
-
- case SLJIT_ASHR:
- EMIT_SHIFT(TILEGX_OPC_SHRSI, TILEGX_OPC_SHRS);
- return SLJIT_SUCCESS;
- }
-
- SLJIT_UNREACHABLE();
- return SLJIT_SUCCESS;
-}
-
-static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
-{
- /* arg1 goes to TMP_REG1 or src reg.
- arg2 goes to TMP_REG2, imm or src reg.
- TMP_REG3 can be used for caching.
- result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */
- sljit_s32 dst_r = TMP_REG2;
- sljit_s32 src1_r;
- sljit_sw src2_r = 0;
- sljit_s32 sugg_src2_r = TMP_REG2;
-
- if (!(flags & ALT_KEEP_CACHE)) {
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
- }
-
- if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) {
- if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32 && !(src2 & SLJIT_MEM))
- return SLJIT_SUCCESS;
- if (GET_FLAGS(op))
- flags |= UNUSED_DEST;
- } else if (FAST_IS_REG(dst)) {
- dst_r = dst;
- flags |= REG_DEST;
- if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
- sugg_src2_r = dst_r;
- } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1_mapped, dst, dstw))
- flags |= SLOW_DEST;
-
- if (flags & IMM_OP) {
- if ((src2 & SLJIT_IMM) && src2w) {
- if ((!(flags & LOGICAL_OP)
- && (src2w <= SIMM_16BIT_MAX && src2w >= SIMM_16BIT_MIN))
- || ((flags & LOGICAL_OP) && !(src2w & ~UIMM_16BIT_MAX))) {
- flags |= SRC2_IMM;
- src2_r = src2w;
- }
- }
-
- if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) {
- if ((!(flags & LOGICAL_OP)
- && (src1w <= SIMM_16BIT_MAX && src1w >= SIMM_16BIT_MIN))
- || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_16BIT_MAX))) {
- flags |= SRC2_IMM;
- src2_r = src1w;
-
- /* And swap arguments. */
- src1 = src2;
- src1w = src2w;
- src2 = SLJIT_IMM;
- /* src2w = src2_r unneeded. */
- }
- }
- }
-
- /* Source 1. */
- if (FAST_IS_REG(src1)) {
- src1_r = src1;
- flags |= REG1_SOURCE;
- } else if (src1 & SLJIT_IMM) {
- if (src1w) {
- FAIL_IF(load_immediate(compiler, TMP_REG1_mapped, src1w));
- src1_r = TMP_REG1;
- } else
- src1_r = 0;
- } else {
- if (getput_arg_fast(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w))
- FAIL_IF(compiler->error);
- else
- flags |= SLOW_SRC1;
- src1_r = TMP_REG1;
- }
-
- /* Source 2. */
- if (FAST_IS_REG(src2)) {
- src2_r = src2;
- flags |= REG2_SOURCE;
- if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
- dst_r = src2_r;
- } else if (src2 & SLJIT_IMM) {
- if (!(flags & SRC2_IMM)) {
- if (src2w) {
- FAIL_IF(load_immediate(compiler, reg_map[sugg_src2_r], src2w));
- src2_r = sugg_src2_r;
- } else {
- src2_r = 0;
- if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM))
- dst_r = 0;
- }
- }
- } else {
- if (getput_arg_fast(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w))
- FAIL_IF(compiler->error);
- else
- flags |= SLOW_SRC2;
- src2_r = sugg_src2_r;
- }
-
- 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)) {
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, src1, src1w));
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw));
- } else {
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, src2, src2w));
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG2_mapped, src2, src2w, dst, dstw));
- }
- } else if (flags & SLOW_SRC1)
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, TMP_REG1_mapped, src1, src1w, dst, dstw));
- else if (flags & SLOW_SRC2)
- FAIL_IF(getput_arg(compiler, flags | LOAD_DATA, reg_map[sugg_src2_r], src2, src2w, dst, dstw));
-
- FAIL_IF(emit_single_op(compiler, op, flags, dst_r, src1_r, src2_r));
-
- if (dst & SLJIT_MEM) {
- if (!(flags & SLOW_DEST)) {
- getput_arg_fast(compiler, flags, reg_map[dst_r], dst, dstw);
- return compiler->error;
- }
-
- return getput_arg(compiler, flags, reg_map[dst_r], dst, dstw, 0, 0);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw, sljit_s32 type)
-{
- sljit_s32 sugg_dst_ar, dst_ar;
- sljit_s32 flags = GET_ALL_FLAGS(op);
- sljit_s32 mem_type = (op & SLJIT_I32_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type));
- ADJUST_LOCAL_OFFSET(dst, dstw);
-
- op = GET_OPCODE(op);
- if (op == SLJIT_MOV_S32 || op == SLJIT_MOV_U32)
- mem_type = INT_DATA | SIGNED_DATA;
- sugg_dst_ar = reg_map[(op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2];
-
- compiler->cache_arg = 0;
- compiler->cache_argw = 0;
- if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, TMP_REG1_mapped, src, srcw, dst, dstw));
- src = TMP_REG1;
- srcw = 0;
- }
-
- switch (type & 0xff) {
- case SLJIT_EQUAL:
- case SLJIT_NOT_EQUAL:
- FAIL_IF(CMPLTUI(sugg_dst_ar, EQUAL_FLAG, 1));
- dst_ar = sugg_dst_ar;
- break;
- case SLJIT_LESS:
- case SLJIT_GREATER_EQUAL:
- dst_ar = ULESS_FLAG;
- break;
- case SLJIT_GREATER:
- case SLJIT_LESS_EQUAL:
- dst_ar = UGREATER_FLAG;
- break;
- case SLJIT_SIG_LESS:
- case SLJIT_SIG_GREATER_EQUAL:
- dst_ar = LESS_FLAG;
- break;
- case SLJIT_SIG_GREATER:
- case SLJIT_SIG_LESS_EQUAL:
- dst_ar = GREATER_FLAG;
- break;
- case SLJIT_OVERFLOW:
- case SLJIT_NOT_OVERFLOW:
- dst_ar = OVERFLOW_FLAG;
- break;
- case SLJIT_MUL_OVERFLOW:
- case SLJIT_MUL_NOT_OVERFLOW:
- FAIL_IF(CMPLTUI(sugg_dst_ar, OVERFLOW_FLAG, 1));
- dst_ar = sugg_dst_ar;
- type ^= 0x1; /* Flip type bit for the XORI below. */
- break;
-
- default:
- SLJIT_UNREACHABLE();
- dst_ar = sugg_dst_ar;
- break;
- }
-
- if (type & 0x1) {
- FAIL_IF(XORI(sugg_dst_ar, dst_ar, 1));
- dst_ar = sugg_dst_ar;
- }
-
- if (op >= SLJIT_ADD) {
- if (TMP_REG2_mapped != dst_ar)
- FAIL_IF(ADD(TMP_REG2_mapped, dst_ar, ZERO));
- return emit_op(compiler, op | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
- }
-
- if (dst & SLJIT_MEM)
- return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw);
-
- if (sugg_dst_ar != dst_ar)
- return ADD(sugg_dst_ar, dst_ar, ZERO);
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) {
- CHECK_ERROR();
- CHECK(check_sljit_emit_op0(compiler, op));
-
- op = GET_OPCODE(op);
- switch (op) {
- case SLJIT_NOP:
- return push_0_buffer(compiler, TILEGX_OPC_FNOP, __LINE__);
-
- case SLJIT_BREAKPOINT:
- return PI(BPT);
-
- case SLJIT_LMUL_UW:
- case SLJIT_LMUL_SW:
- case SLJIT_DIVMOD_UW:
- case SLJIT_DIVMOD_SW:
- case SLJIT_DIV_UW:
- case SLJIT_DIV_SW:
- SLJIT_UNREACHABLE();
- case SLJIT_ENDBR:
- case SLJIT_SKIP_FRAMES_BEFORE_RETURN:
- return SLJIT_SUCCESS;
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- switch (GET_OPCODE(op)) {
- case SLJIT_MOV:
- case SLJIT_MOV_P:
- return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOV_U32:
- return emit_op(compiler, SLJIT_MOV_U32, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOV_S32:
- return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOV_U8:
- return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw);
-
- case SLJIT_MOV_S8:
- return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw);
-
- case SLJIT_MOV_U16:
- return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw);
-
- case SLJIT_MOV_S16:
- return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw);
-
- case SLJIT_MOVU:
- case SLJIT_MOVU_P:
- return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOVU_U32:
- return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOVU_S32:
- return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_MOVU_U8:
- return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8) srcw : srcw);
-
- case SLJIT_MOVU_S8:
- return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8) srcw : srcw);
-
- case SLJIT_MOVU_U16:
- return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16) srcw : srcw);
-
- case SLJIT_MOVU_S16:
- return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16) srcw : srcw);
-
- case SLJIT_NOT:
- return emit_op(compiler, op, 0, dst, dstw, TMP_REG1, 0, src, srcw);
-
- case SLJIT_NEG:
- return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw);
-
- case SLJIT_CLZ:
- return emit_op(compiler, op, (op & SLJIT_I32_OP) ? INT_DATA : WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w));
- ADJUST_LOCAL_OFFSET(dst, dstw);
- ADJUST_LOCAL_OFFSET(src1, src1w);
- ADJUST_LOCAL_OFFSET(src2, src2w);
-
- switch (GET_OPCODE(op)) {
- case SLJIT_ADD:
- case SLJIT_ADDC:
- return emit_op(compiler, op, CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SUB:
- case SLJIT_SUBC:
- return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_MUL:
- return emit_op(compiler, op, CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_AND:
- case SLJIT_OR:
- case SLJIT_XOR:
- return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
-
- case SLJIT_SHL:
- case SLJIT_LSHR:
- case SLJIT_ASHR:
- if (src2 & SLJIT_IMM)
- src2w &= 0x3f;
- if (op & SLJIT_I32_OP)
- src2w &= 0x1f;
-
- return emit_op(compiler, op, IMM_OP, dst, dstw, src1, src1w, src2, src2w);
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
- sljit_s32 src, sljit_sw srcw)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_src(compiler, op, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- switch (op) {
- case SLJIT_FAST_RETURN:
- if (FAST_IS_REG(src))
- FAIL_IF(ADD(RA, reg_map[src], ZERO));
-
- else
- FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RA, src, srcw));
-
- return JR(RA);
- case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
- return SLJIT_SUCCESS;
- }
-
- return SLJIT_SUCCESS;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_label * sljit_emit_label(struct sljit_compiler *compiler)
-{
- struct sljit_label *label;
-
- flush_buffer(compiler);
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_label(compiler));
-
- if (compiler->last_label && compiler->last_label->size == compiler->size)
- return compiler->last_label;
-
- label = (struct sljit_label *)ensure_abuf(compiler, sizeof(struct sljit_label));
- PTR_FAIL_IF(!label);
- set_label(label, compiler);
- return label;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
-{
- sljit_s32 src_r = TMP_REG2;
- struct sljit_jump *jump = NULL;
-
- flush_buffer(compiler);
-
- CHECK_ERROR();
- CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
- ADJUST_LOCAL_OFFSET(src, srcw);
-
- if (FAST_IS_REG(src)) {
- if (reg_map[src] != 0)
- src_r = src;
- else
- FAIL_IF(ADD_SOLO(TMP_REG2_mapped, reg_map[src], ZERO));
- }
-
- if (type >= SLJIT_CALL0) {
- SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2);
- if (src & (SLJIT_IMM | SLJIT_MEM)) {
- if (src & SLJIT_IMM)
- FAIL_IF(emit_const(compiler, reg_map[PIC_ADDR_REG], srcw, 1));
- else {
- SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM));
- FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
- }
-
- FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
-
- FAIL_IF(ADDI_SOLO(54, 54, -16));
-
- FAIL_IF(JALR_SOLO(reg_map[PIC_ADDR_REG]));
-
- return ADDI_SOLO(54, 54, 16);
- }
-
- /* Register input. */
- if (type >= SLJIT_CALL1)
- FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
-
- FAIL_IF(ADD_SOLO(reg_map[PIC_ADDR_REG], reg_map[src_r], ZERO));
-
- FAIL_IF(ADDI_SOLO(54, 54, -16));
-
- FAIL_IF(JALR_SOLO(reg_map[src_r]));
-
- return ADDI_SOLO(54, 54, 16);
- }
-
- if (src & SLJIT_IMM) {
- jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
- FAIL_IF(!jump);
- set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
- jump->u.target = srcw;
- FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1));
-
- if (type >= SLJIT_FAST_CALL) {
- FAIL_IF(ADD_SOLO(ZERO, ZERO, ZERO));
- jump->addr = compiler->size;
- FAIL_IF(JR_SOLO(reg_map[src_r]));
- } else {
- jump->addr = compiler->size;
- FAIL_IF(JR_SOLO(reg_map[src_r]));
- }
-
- return SLJIT_SUCCESS;
-
- } else if (src & SLJIT_MEM) {
- FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
- flush_buffer(compiler);
- }
-
- FAIL_IF(JR_SOLO(reg_map[src_r]));
-
- if (jump)
- jump->addr = compiler->size;
-
- return SLJIT_SUCCESS;
-}
-
-#define BR_Z(src) \
- inst = BEQZ_X1 | SRCA_X1(src); \
- flags = IS_COND;
-
-#define BR_NZ(src) \
- inst = BNEZ_X1 | SRCA_X1(src); \
- flags = IS_COND;
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump * sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
-{
- struct sljit_jump *jump;
- sljit_ins inst;
- sljit_s32 flags = 0;
-
- flush_buffer(compiler);
-
- CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_jump(compiler, type));
-
- jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
- PTR_FAIL_IF(!jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
- type &= 0xff;
-
- switch (type) {
- case SLJIT_EQUAL:
- BR_NZ(EQUAL_FLAG);
- break;
- case SLJIT_NOT_EQUAL:
- BR_Z(EQUAL_FLAG);
- break;
- case SLJIT_LESS:
- BR_Z(ULESS_FLAG);
- break;
- case SLJIT_GREATER_EQUAL:
- BR_NZ(ULESS_FLAG);
- break;
- case SLJIT_GREATER:
- BR_Z(UGREATER_FLAG);
- break;
- case SLJIT_LESS_EQUAL:
- BR_NZ(UGREATER_FLAG);
- break;
- case SLJIT_SIG_LESS:
- BR_Z(LESS_FLAG);
- break;
- case SLJIT_SIG_GREATER_EQUAL:
- BR_NZ(LESS_FLAG);
- break;
- case SLJIT_SIG_GREATER:
- BR_Z(GREATER_FLAG);
- break;
- case SLJIT_SIG_LESS_EQUAL:
- BR_NZ(GREATER_FLAG);
- break;
- case SLJIT_OVERFLOW:
- case SLJIT_MUL_OVERFLOW:
- BR_Z(OVERFLOW_FLAG);
- break;
- case SLJIT_NOT_OVERFLOW:
- case SLJIT_MUL_NOT_OVERFLOW:
- BR_NZ(OVERFLOW_FLAG);
- break;
- default:
- /* Not conditional branch. */
- inst = 0;
- break;
- }
-
- jump->flags |= flags;
-
- if (inst) {
- inst = inst | ((type <= SLJIT_JUMP) ? BOFF_X1(5) : BOFF_X1(6));
- PTR_FAIL_IF(PI(inst));
- }
-
- PTR_FAIL_IF(emit_const(compiler, TMP_REG2_mapped, 0, 1));
- if (type <= SLJIT_JUMP) {
- jump->addr = compiler->size;
- PTR_FAIL_IF(JR_SOLO(TMP_REG2_mapped));
- } else {
- SLJIT_ASSERT(reg_map[PIC_ADDR_REG] == 16 && PIC_ADDR_REG == TMP_REG2);
- /* Cannot be optimized out if type is >= CALL0. */
- jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0);
- PTR_FAIL_IF(ADD_SOLO(0, reg_map[SLJIT_R0], ZERO));
- jump->addr = compiler->size;
- PTR_FAIL_IF(JALR_SOLO(TMP_REG2_mapped));
- }
-
- return jump;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src, sljit_sw srcw)
-{
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw dstw, sljit_s32 src1, sljit_sw src1w, sljit_s32 src2, sljit_sw src2w)
-{
- SLJIT_UNREACHABLE();
-}
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const * sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
-{
- struct sljit_const *const_;
- sljit_s32 reg;
-
- flush_buffer(compiler);
-
- CHECK_ERROR_PTR();
- 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);
-
- reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
-
- PTR_FAIL_IF(emit_const_64(compiler, reg, init_value, 1));
-
- if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
- return const_;
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target)
-{
- sljit_ins *inst = (sljit_ins *)addr;
-
- inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_target >> 32) & 0xffff) << 43);
- inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_target >> 16) & 0xffff) << 43);
- inst[2] = (inst[2] & ~(0xFFFFL << 43)) | ((new_target & 0xffff) << 43);
- SLJIT_CACHE_FLUSH(inst, inst + 3);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
-{
- sljit_ins *inst = (sljit_ins *)addr;
-
- inst[0] = (inst[0] & ~(0xFFFFL << 43)) | (((new_constant >> 48) & 0xFFFFL) << 43);
- inst[1] = (inst[1] & ~(0xFFFFL << 43)) | (((new_constant >> 32) & 0xFFFFL) << 43);
- inst[2] = (inst[2] & ~(0xFFFFL << 43)) | (((new_constant >> 16) & 0xFFFFL) << 43);
- inst[3] = (inst[3] & ~(0xFFFFL << 43)) | ((new_constant & 0xFFFFL) << 43);
- SLJIT_CACHE_FLUSH(inst, inst + 4);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
-{
- CHECK_REG_INDEX(check_sljit_get_register_index(reg));
- return reg_map[reg];
-}
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
- void *instruction, sljit_s32 size)
-{
- CHECK_ERROR();
- CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
- return SLJIT_ERR_UNSUPPORTED;
-}
-
diff --git a/src/sljit/sljitNativeX86_common.c b/src/sljit/sljitNativeX86_common.c
index 74965e3..ddcc5eb 100644
--- a/src/sljit/sljitNativeX86_common.c
+++ b/src/sljit/sljitNativeX86_common.c
@@ -506,7 +506,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
reverse_buf(compiler);
/* Second code generation pass. */
- code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size);
+ code = (sljit_u8*)SLJIT_MALLOC_EXEC(compiler->size, compiler->exec_allocator_data);
PTR_FAIL_WITH_EXEC_IF(code);
buf = compiler->buf;
@@ -557,7 +557,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
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));
+ 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;
break;
@@ -629,7 +629,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
compiler->error = SLJIT_ERR_COMPILED;
compiler->executable_offset = executable_offset;
compiler->executable_size = code_ptr - code;
- return (void*)(code + executable_offset);
+
+ code = (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS(code, (sljit_u8*)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset), 1);
+ return (void*)code;
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
@@ -725,15 +729,16 @@ static SLJIT_INLINE sljit_s32 emit_endbranch(struct sljit_compiler *compiler)
#else
*inst = 0xfa;
#endif
-#else
+#else /* !SLJIT_CONFIG_X86_CET */
SLJIT_UNUSED_ARG(compiler);
-#endif
+#endif /* SLJIT_CONFIG_X86_CET */
return SLJIT_SUCCESS;
}
+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
+
static SLJIT_INLINE sljit_s32 emit_rdssp(struct sljit_compiler *compiler, sljit_s32 reg)
{
-#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
sljit_u8 *inst;
sljit_s32 size;
@@ -753,16 +758,11 @@ static SLJIT_INLINE sljit_s32 emit_rdssp(struct sljit_compiler *compiler, sljit_
*inst++ = 0x0f;
*inst++ = 0x1e;
*inst = (0x3 << 6) | (0x1 << 3) | (reg_map[reg] & 0x7);
-#else
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(reg);
-#endif
return SLJIT_SUCCESS;
}
static SLJIT_INLINE sljit_s32 emit_incssp(struct sljit_compiler *compiler, sljit_s32 reg)
{
-#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
sljit_u8 *inst;
sljit_s32 size;
@@ -782,29 +782,28 @@ static SLJIT_INLINE sljit_s32 emit_incssp(struct sljit_compiler *compiler, sljit
*inst++ = 0x0f;
*inst++ = 0xae;
*inst = (0x3 << 6) | (0x5 << 3) | (reg_map[reg] & 0x7);
-#else
- SLJIT_UNUSED_ARG(compiler);
- SLJIT_UNUSED_ARG(reg);
-#endif
return SLJIT_SUCCESS;
}
+#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
+
static SLJIT_INLINE sljit_s32 cpu_has_shadow_stack(void)
{
-#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
return _get_ssp() != 0;
-#else
+#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */
return 0;
-#endif
+#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
}
static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compiler,
sljit_s32 src, sljit_sw srcw, sljit_s32 base, sljit_sw disp)
{
-#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET)
- sljit_u8 *inst;
+#if (defined SLJIT_CONFIG_X86_CET && SLJIT_CONFIG_X86_CET) && defined (__SHSTK__)
+ sljit_u8 *inst, *jz_after_cmp_inst;
+ sljit_uw size_jz_after_cmp_inst;
- sljit_s32 size_before_rdssp_inst = compiler->size;
+ sljit_uw size_before_rdssp_inst = compiler->size;
/* Generate "RDSSP TMP_REG1". */
FAIL_IF(emit_rdssp(compiler, TMP_REG1));
@@ -839,8 +838,8 @@ static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compile
FAIL_IF(!inst);
INC_SIZE(2);
*inst++ = get_jump_code(SLJIT_EQUAL) - 0x10;
- sljit_uw size_jz_after_cmp_inst = compiler->size;
- sljit_u8 *jz_after_cmp_inst = inst;
+ size_jz_after_cmp_inst = compiler->size;
+ jz_after_cmp_inst = inst;
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
/* REX_W is not necessary. */
@@ -860,13 +859,13 @@ static SLJIT_INLINE sljit_s32 adjust_shadow_stack(struct sljit_compiler *compile
*inst = size_before_rdssp_inst - compiler->size;
*jz_after_cmp_inst = compiler->size - size_jz_after_cmp_inst;
-#else /* SLJIT_CONFIG_X86_CET */
+#else /* !SLJIT_CONFIG_X86_CET || !__SHSTK__ */
SLJIT_UNUSED_ARG(compiler);
SLJIT_UNUSED_ARG(src);
SLJIT_UNUSED_ARG(srcw);
SLJIT_UNUSED_ARG(base);
SLJIT_UNUSED_ARG(disp);
-#endif /* SLJIT_CONFIG_X86_CET */
+#endif /* SLJIT_CONFIG_X86_CET && __SHSTK__ */
return SLJIT_SUCCESS;
}
@@ -3123,15 +3122,21 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct slj
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 0);
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
sljit_unaligned_store_sw((void*)addr, new_target - (addr + 4) - (sljit_uw)executable_offset);
#else
sljit_unaligned_store_sw((void*)addr, (sljit_sw) new_target);
#endif
+ SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 1);
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
{
SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 0);
sljit_unaligned_store_sw((void*)addr, new_constant);
+ SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 1);
}
diff --git a/src/sljit/sljitProtExecAllocator.c b/src/sljit/sljitProtExecAllocator.c
index 3f412fe..147175a 100644
--- a/src/sljit/sljitProtExecAllocator.c
+++ b/src/sljit/sljitProtExecAllocator.c
@@ -76,105 +76,106 @@ struct chunk_header {
alloc_chunk / free_chunk :
* allocate executable system memory chunks
* the size is always divisible by CHUNK_SIZE
- allocator_grab_lock / allocator_release_lock :
- * make the allocator thread safe
- * can be empty if the OS (or the application) does not support threading
+ SLJIT_ALLOCATOR_LOCK / SLJIT_ALLOCATOR_UNLOCK :
+ * provided as part of sljitUtils
* only the allocator requires this lock, sljit is fully thread safe
as it only uses local variables
*/
+#ifndef __NetBSD__
+#include <sys/stat.h>
#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
#ifndef O_NOATIME
#define O_NOATIME 0
#endif
-#ifdef __O_TMPFILE
+/* this is a linux extension available since kernel 3.11 */
#ifndef O_TMPFILE
-#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
+#define O_TMPFILE 020200000
#endif
-#endif
-
-#if !(defined(__NetBSD__) && defined(MAP_REMAPDUP))
-int mkostemp(char *template, int flags);
-#ifdef __NetBSD__
-/*
- * this is a workaround for NetBSD < 8 that lacks a system provided
- * secure_getenv function.
- * ideally this should never be used, as the standard allocator is
- * a preferred option for those systems and should be used instead.
- */
-#define secure_getenv(name) issetugid() ? NULL : getenv(name)
-#else
+#ifndef _GNU_SOURCE
char *secure_getenv(const char *name);
+int mkostemp(char *template, int flags);
#endif
static SLJIT_INLINE int create_tempfile(void)
{
int fd;
-
char tmp_name[256];
- size_t tmp_name_len;
+ size_t tmp_name_len = 0;
char *dir;
- size_t len;
+ struct stat st;
+#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
+ mode_t mode;
+#endif
#ifdef HAVE_MEMFD_CREATE
/* this is a GNU extension, make sure to use -D_GNU_SOURCE */
fd = memfd_create("sljit", MFD_CLOEXEC);
- if (fd != -1)
+ if (fd != -1) {
+ fchmod(fd, 0);
return fd;
-#endif
-
-#ifdef P_tmpdir
- len = (P_tmpdir != NULL) ? strlen(P_tmpdir) : 0;
-
- if (len > 0 && len < sizeof(tmp_name)) {
- strcpy(tmp_name, P_tmpdir);
- tmp_name_len = len;
}
- else {
- strcpy(tmp_name, "/tmp");
- tmp_name_len = 4;
- }
-#else
- strcpy(tmp_name, "/tmp");
- tmp_name_len = 4;
#endif
dir = secure_getenv("TMPDIR");
if (dir) {
- len = strlen(dir);
- if (len > 0 && len < sizeof(tmp_name)) {
- strcpy(tmp_name, dir);
- tmp_name_len = len;
+ tmp_name_len = strlen(dir);
+ if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name)) {
+ if ((stat(dir, &st) == 0) && S_ISDIR(st.st_mode))
+ strcpy(tmp_name, dir);
}
}
+#ifdef P_tmpdir
+ if (!tmp_name_len) {
+ tmp_name_len = strlen(P_tmpdir);
+ if (tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name))
+ strcpy(tmp_name, P_tmpdir);
+ }
+#endif
+ if (!tmp_name_len) {
+ strcpy(tmp_name, "/tmp");
+ tmp_name_len = 4;
+ }
+
SLJIT_ASSERT(tmp_name_len > 0 && tmp_name_len < sizeof(tmp_name));
- while (tmp_name_len > 0 && tmp_name[tmp_name_len - 1] == '/') {
- tmp_name_len--;
- tmp_name[tmp_name_len] = '\0';
- }
+ if (tmp_name[tmp_name_len - 1] == '/')
+ tmp_name[--tmp_name_len] = '\0';
-#ifdef O_TMPFILE
- fd = open(tmp_name, O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, S_IRUSR | S_IWUSR);
+#ifdef __linux__
+ /*
+ * the previous trimming might had left an empty string if TMPDIR="/"
+ * so work around the problem below
+ */
+ fd = open(tmp_name_len ? tmp_name : "/",
+ O_TMPFILE | O_EXCL | O_RDWR | O_NOATIME | O_CLOEXEC, 0);
if (fd != -1)
return fd;
#endif
if (tmp_name_len + 7 >= sizeof(tmp_name))
- {
return -1;
- }
strcpy(tmp_name + tmp_name_len, "/XXXXXX");
+#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
+ mode = umask(0777);
+#endif
fd = mkostemp(tmp_name, O_CLOEXEC | O_NOATIME);
+#if defined(SLJIT_SINGLE_THREADED) && SLJIT_SINGLE_THREADED
+ umask(mode);
+#else
+ fchmod(fd, 0);
+#endif
if (fd == -1)
- return fd;
+ return -1;
if (unlink(tmp_name)) {
close(fd);
@@ -217,34 +218,36 @@ static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
return retval;
}
#else
+/*
+ * MAP_REMAPDUP is a NetBSD extension available sinde 8.0, make sure to
+ * adjust your feature macros (ex: -D_NETBSD_SOURCE) as needed
+ */
static SLJIT_INLINE struct chunk_header* alloc_chunk(sljit_uw size)
{
struct chunk_header *retval;
- void *maprx;
retval = (struct chunk_header *)mmap(NULL, size,
- PROT_MPROTECT(PROT_EXEC|PROT_WRITE|PROT_READ),
- MAP_ANON, -1, 0);
+ PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC),
+ MAP_ANON | MAP_SHARED, -1, 0);
if (retval == MAP_FAILED)
return NULL;
- maprx = mremap(retval, size, NULL, size, MAP_REMAPDUP);
- if (maprx == MAP_FAILED) {
+ retval->executable = mremap(retval, size, NULL, size, MAP_REMAPDUP);
+ if (retval->executable == MAP_FAILED) {
munmap((void *)retval, size);
return NULL;
}
- if (mprotect(retval, size, PROT_READ | PROT_WRITE) == -1 ||
- mprotect(maprx, size, PROT_READ | PROT_EXEC) == -1) {
- munmap(maprx, size);
+ if (mprotect(retval->executable, size, PROT_READ | PROT_EXEC) == -1) {
+ munmap(retval->executable, size);
munmap((void *)retval, size);
return NULL;
}
- retval->executable = maprx;
+
return retval;
}
-#endif /* NetBSD >= 8 */
+#endif /* NetBSD */
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
{
@@ -318,7 +321,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
sljit_uw chunk_size;
sljit_sw executable_offset;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
if (size < (64 - sizeof(struct block_header)))
size = (64 - sizeof(struct block_header));
size = ALIGN_SIZE(size);
@@ -343,7 +346,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
}
allocated_size += size;
header->size = size;
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return MEM_START(header);
}
free_block = free_block->next;
@@ -354,7 +357,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
chunk_header = alloc_chunk(chunk_size);
if (!chunk_header) {
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return NULL;
}
@@ -388,7 +391,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
next_header->size = 1;
next_header->prev_size = chunk_size;
next_header->executable_offset = executable_offset;
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
return MEM_START(header);
}
@@ -397,7 +400,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
struct block_header *header;
struct free_block* free_block;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header));
header = AS_BLOCK_HEADER(header, -header->executable_offset);
allocated_size -= header->size;
@@ -437,7 +440,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
}
}
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
@@ -445,7 +448,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
struct free_block* free_block;
struct free_block* next_free_block;
- allocator_grab_lock();
+ SLJIT_ALLOCATOR_LOCK();
free_block = free_blocks;
while (free_block) {
@@ -462,7 +465,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
}
SLJIT_ASSERT((total_size && free_blocks) || (!total_size && !free_blocks));
- allocator_release_lock();
+ SLJIT_ALLOCATOR_UNLOCK();
}
SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr)
diff --git a/src/sljit/sljitUtils.c b/src/sljit/sljitUtils.c
index 0276fa1..08ca35c 100644
--- a/src/sljit/sljitUtils.c
+++ b/src/sljit/sljitUtils.c
@@ -28,131 +28,50 @@
/* Locks */
/* ------------------------------------------------------------------------ */
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) || (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
+/* Executable Allocator */
+#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
+ && !(defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)
#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
-
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
-
-static SLJIT_INLINE void allocator_grab_lock(void)
-{
- /* Always successful. */
-}
-
-static SLJIT_INLINE void allocator_release_lock(void)
-{
- /* Always successful. */
-}
-
-#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
-
-#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
-
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
-{
- /* Always successful. */
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
-{
- /* Always successful. */
-}
-
-#endif /* SLJIT_UTIL_GLOBAL_LOCK */
-
-#elif defined(_WIN32) /* SLJIT_SINGLE_THREADED */
-
-#include "windows.h"
-
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
-
-static HANDLE allocator_mutex = 0;
-
-static SLJIT_INLINE void allocator_grab_lock(void)
-{
- /* No idea what to do if an error occures. Static mutexes should never fail... */
- if (!allocator_mutex)
- allocator_mutex = CreateMutex(NULL, TRUE, NULL);
- else
- WaitForSingleObject(allocator_mutex, INFINITE);
-}
-
-static SLJIT_INLINE void allocator_release_lock(void)
-{
- ReleaseMutex(allocator_mutex);
-}
-
-#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
-
-#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
-
-static HANDLE global_mutex = 0;
-
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
-{
- /* No idea what to do if an error occures. Static mutexes should never fail... */
- if (!global_mutex)
- global_mutex = CreateMutex(NULL, TRUE, NULL);
- else
- WaitForSingleObject(global_mutex, INFINITE);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
-{
- ReleaseMutex(global_mutex);
-}
-
-#endif /* SLJIT_UTIL_GLOBAL_LOCK */
-
-#else /* _WIN32 */
-
-#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
-
+#define SLJIT_ALLOCATOR_LOCK()
+#define SLJIT_ALLOCATOR_UNLOCK()
+#elif !(defined _WIN32)
#include <pthread.h>
-static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static SLJIT_INLINE void allocator_grab_lock(void)
-{
- pthread_mutex_lock(&allocator_mutex);
-}
+static pthread_mutex_t allocator_lock = PTHREAD_MUTEX_INITIALIZER;
-static SLJIT_INLINE void allocator_release_lock(void)
-{
- pthread_mutex_unlock(&allocator_mutex);
-}
+#define SLJIT_ALLOCATOR_LOCK() pthread_mutex_lock(&allocator_lock)
+#define SLJIT_ALLOCATOR_UNLOCK() pthread_mutex_unlock(&allocator_lock)
+#else /* windows */
+static HANDLE allocator_lock;
-#endif /* SLJIT_EXECUTABLE_ALLOCATOR */
-
-#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
-
-#include <pthread.h>
-
-static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
-{
- pthread_mutex_lock(&global_mutex);
-}
-
-SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
+static SLJIT_INLINE void allocator_grab_lock(void)
{
- pthread_mutex_unlock(&global_mutex);
+ HANDLE lock;
+ if (SLJIT_UNLIKELY(!allocator_lock)) {
+ lock = CreateMutex(NULL, FALSE, NULL);
+ if (InterlockedCompareExchangePointer(&allocator_lock, lock, NULL))
+ CloseHandle(lock);
+ }
+ WaitForSingleObject(allocator_lock, INFINITE);
}
-#endif /* SLJIT_UTIL_GLOBAL_LOCK */
-
-#endif /* _WIN32 */
+#define SLJIT_ALLOCATOR_LOCK() allocator_grab_lock()
+#define SLJIT_ALLOCATOR_UNLOCK() ReleaseMutex(allocator_lock)
+#endif /* thread implementation */
+#endif /* SLJIT_EXECUTABLE_ALLOCATOR && !SLJIT_WX_EXECUTABLE_ALLOCATOR */
/* ------------------------------------------------------------------------ */
/* Stack */
/* ------------------------------------------------------------------------ */
-#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
+#if ((defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
+ && !(defined SLJIT_UTIL_SIMPLE_STACK_ALLOCATION && SLJIT_UTIL_SIMPLE_STACK_ALLOCATION)) \
+ || ((defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) \
+ && !((defined SLJIT_PROT_EXECUTABLE_ALLOCATOR && SLJIT_PROT_EXECUTABLE_ALLOCATOR) \
+ || (defined SLJIT_WX_EXECUTABLE_ALLOCATOR && SLJIT_WX_EXECUTABLE_ALLOCATOR)))
-#ifdef _WIN32
-#include "windows.h"
-#else /* !_WIN32 */
+#ifndef _WIN32
/* Provides mmap function. */
#include <sys/types.h>
#include <sys/mman.h>
@@ -163,56 +82,84 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
#endif /* MAP_ANONYMOUS */
#endif /* !MAP_ANON */
-#ifndef MADV_DONTNEED
-#ifdef POSIX_MADV_DONTNEED
-#define MADV_DONTNEED POSIX_MADV_DONTNEED
-#endif /* POSIX_MADV_DONTNEED */
-#endif /* !MADV_DONTNEED */
-
-/* For detecting the page size. */
-#include <unistd.h>
-
#ifndef MAP_ANON
#include <fcntl.h>
-/* Some old systems does not have MAP_ANON. */
-static sljit_s32 dev_zero = -1;
+#ifdef O_CLOEXEC
+#define SLJIT_CLOEXEC O_CLOEXEC
+#else /* !O_CLOEXEC */
+#define SLJIT_CLOEXEC 0
+#endif /* O_CLOEXEC */
+
+/* Some old systems do not have MAP_ANON. */
+static int dev_zero = -1;
#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
-static SLJIT_INLINE sljit_s32 open_dev_zero(void)
+static SLJIT_INLINE int open_dev_zero(void)
{
- dev_zero = open("/dev/zero", O_RDWR);
+ dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
+
return dev_zero < 0;
}
-#else /* SLJIT_SINGLE_THREADED */
+#else /* !SLJIT_SINGLE_THREADED */
#include <pthread.h>
static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER;
-static SLJIT_INLINE sljit_s32 open_dev_zero(void)
+static SLJIT_INLINE int open_dev_zero(void)
{
pthread_mutex_lock(&dev_zero_mutex);
- /* The dev_zero might be initialized by another thread during the waiting. */
- if (dev_zero < 0) {
- dev_zero = open("/dev/zero", O_RDWR);
- }
+ if (SLJIT_UNLIKELY(dev_zero < 0))
+ dev_zero = open("/dev/zero", O_RDWR | SLJIT_CLOEXEC);
+
pthread_mutex_unlock(&dev_zero_mutex);
return dev_zero < 0;
}
#endif /* SLJIT_SINGLE_THREADED */
-
+#undef SLJIT_CLOEXEC
#endif /* !MAP_ANON */
+#endif /* !_WIN32 */
+#endif /* open_dev_zero */
-#endif /* _WIN32 */
+#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) \
+ || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR)
-#endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */
+#ifdef _WIN32
-#endif /* SLJIT_EXECUTABLE_ALLOCATOR || SLJIT_UTIL_GLOBAL_LOCK */
+static SLJIT_INLINE sljit_sw get_page_alignment(void) {
+ SYSTEM_INFO si;
+ static sljit_sw sljit_page_align;
+ if (!sljit_page_align) {
+ GetSystemInfo(&si);
+ sljit_page_align = si.dwPageSize - 1;
+ }
+ return sljit_page_align;
+}
+
+#else
+
+#include <unistd.h>
+
+static SLJIT_INLINE sljit_sw get_page_alignment(void) {
+ static sljit_sw sljit_page_align;
+ if (!sljit_page_align) {
+ sljit_page_align = sysconf(_SC_PAGESIZE);
+ /* Should never happen. */
+ if (sljit_page_align < 0)
+ sljit_page_align = 4096;
+ sljit_page_align--;
+ }
+ return sljit_page_align;
+}
+
+#endif /* _WIN32 */
+
+#endif /* get_page_alignment() */
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
@@ -264,16 +211,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_st
#ifdef _WIN32
-SLJIT_INLINE static sljit_sw get_page_alignment(void) {
- SYSTEM_INFO si;
- static sljit_sw sljit_page_align;
- if (!sljit_page_align) {
- GetSystemInfo(&si);
- sljit_page_align = si.dwPageSize - 1;
- }
- return sljit_page_align;
-}
-
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
{
SLJIT_UNUSED_ARG(allocator_data);
@@ -281,19 +218,7 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *st
SLJIT_FREE(stack, allocator_data);
}
-#else /* ! defined _WIN32 */
-
-SLJIT_INLINE static sljit_sw get_page_alignment(void) {
- static sljit_sw sljit_page_align;
- if (!sljit_page_align) {
- sljit_page_align = sysconf(_SC_PAGESIZE);
- /* Should never happen. */
- if (sljit_page_align < 0)
- sljit_page_align = 4096;
- sljit_page_align--;
- }
- return sljit_page_align;
-}
+#else /* !_WIN32 */
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
{
@@ -302,7 +227,7 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *st
SLJIT_FREE(stack, allocator_data);
}
-#endif /* defined _WIN32 */
+#endif /* _WIN32 */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
{
@@ -342,11 +267,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj
#ifdef MAP_ANON
ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
#else /* !MAP_ANON */
- if (dev_zero < 0) {
- if (open_dev_zero() != 0) {
- SLJIT_FREE(stack, allocator_data);
- return NULL;
- }
+ if (SLJIT_UNLIKELY((dev_zero < 0) && open_dev_zero())) {
+ SLJIT_FREE(stack, allocator_data);
+ return NULL;
}
ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
#endif /* MAP_ANON */
@@ -365,7 +288,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(slj
SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
{
-#if defined _WIN32 || defined(MADV_DONTNEED)
+#if defined _WIN32 || defined(POSIX_MADV_DONTNEED)
sljit_uw aligned_old_start;
sljit_uw aligned_new_start;
sljit_sw page_align;
@@ -389,15 +312,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_st
return NULL;
}
}
-#elif defined(MADV_DONTNEED)
+#elif defined(POSIX_MADV_DONTNEED)
if (stack->start < new_start) {
page_align = get_page_alignment();
aligned_new_start = (sljit_uw)new_start & ~page_align;
aligned_old_start = ((sljit_uw)stack->start) & ~page_align;
- /* If madvise is available, we release the unnecessary space. */
- if (aligned_new_start > aligned_old_start)
- madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_DONTNEED);
+
+ if (aligned_new_start > aligned_old_start) {
+ posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);
+#ifdef MADV_FREE
+ madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_FREE);
+#endif /* MADV_FREE */
+ }
}
#endif /* _WIN32 */
diff --git a/src/sljit/sljitWXExecAllocator.c b/src/sljit/sljitWXExecAllocator.c
new file mode 100644
index 0000000..6ef71f7
--- /dev/null
+++ b/src/sljit/sljitWXExecAllocator.c
@@ -0,0 +1,225 @@
+/*
+ * Stack-less Just-In-Time compiler
+ *
+ * Copyright Zoltan Herczeg (hzmester@freemail.hu). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ This file contains a simple W^X executable memory allocator for POSIX
+ like systems and Windows
+
+ In *NIX, MAP_ANON is required (that is considered a feature) so make
+ sure to set the right availability macros for your system or the code
+ will fail to build.
+
+ If your system doesn't support mapping of anonymous pages (ex: IRIX) it
+ is also likely that it doesn't need this allocator and should be using
+ the standard one instead.
+
+ It allocates a separate map for each code block and may waste a lot of
+ memory, because whatever was requested, will be rounded up to the page
+ size (minimum 4KB, but could be even bigger).
+
+ It changes the page permissions (RW <-> RX) as needed and therefore, if you
+ will be updating the code after it has been generated, need to make sure to
+ block any concurrent execution, or could result in a SIGBUS, that could
+ even manifest itself at a different address than the one that was being
+ modified.
+
+ Only use if you are unable to use the regular allocator because of security
+ restrictions and adding exceptions to your application or the system are
+ not possible.
+*/
+
+#define SLJIT_UPDATE_WX_FLAGS(from, to, enable_exec) \
+ sljit_update_wx_flags((from), (to), (enable_exec))
+
+#ifndef _WIN32
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#ifdef __NetBSD__
+#if defined(PROT_MPROTECT)
+#define check_se_protected(ptr, size) (0)
+#define SLJIT_PROT_WX PROT_MPROTECT(PROT_EXEC)
+#else /* !PROT_MPROTECT */
+#ifdef _NETBSD_SOURCE
+#include <sys/param.h>
+#else /* !_NETBSD_SOURCE */
+typedef unsigned int u_int;
+#define devmajor_t sljit_s32
+#endif /* _NETBSD_SOURCE */
+#include <sys/sysctl.h>
+#include <unistd.h>
+
+#define check_se_protected(ptr, size) netbsd_se_protected()
+
+static SLJIT_INLINE int netbsd_se_protected(void)
+{
+ int mib[3];
+ int paxflags;
+ size_t len = sizeof(paxflags);
+
+ mib[0] = CTL_PROC;
+ mib[1] = getpid();
+ mib[2] = PROC_PID_PAXFLAGS;
+
+ if (SLJIT_UNLIKELY(sysctl(mib, 3, &paxflags, &len, NULL, 0) < 0))
+ return -1;
+
+ return (paxflags & CTL_PROC_PAXFLAGS_MPROTECT) ? -1 : 0;
+}
+#endif /* PROT_MPROTECT */
+#else /* POSIX */
+#define check_se_protected(ptr, size) generic_se_protected(ptr, size)
+
+static SLJIT_INLINE int generic_se_protected(void *ptr, sljit_uw size)
+{
+ if (SLJIT_LIKELY(!mprotect(ptr, size, PROT_EXEC)))
+ return mprotect(ptr, size, PROT_READ | PROT_WRITE);
+
+ return -1;
+}
+#endif /* NetBSD */
+
+#if defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED
+#define SLJIT_SE_LOCK()
+#define SLJIT_SE_UNLOCK()
+#else /* !SLJIT_SINGLE_THREADED */
+#include <pthread.h>
+#define SLJIT_SE_LOCK() pthread_mutex_lock(&se_lock)
+#define SLJIT_SE_UNLOCK() pthread_mutex_unlock(&se_lock)
+#endif /* SLJIT_SINGLE_THREADED */
+
+#ifndef SLJIT_PROT_WX
+#define SLJIT_PROT_WX 0
+#endif /* !SLJIT_PROT_WX */
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
+{
+#if !(defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED)
+ static pthread_mutex_t se_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif
+ static int se_protected = !SLJIT_PROT_WX;
+ sljit_uw* ptr;
+
+ if (SLJIT_UNLIKELY(se_protected < 0))
+ return NULL;
+
+ size += sizeof(sljit_uw);
+ ptr = (sljit_uw*)mmap(NULL, size, PROT_READ | PROT_WRITE | SLJIT_PROT_WX,
+ MAP_PRIVATE | MAP_ANON, -1, 0);
+
+ if (ptr == MAP_FAILED)
+ return NULL;
+
+ if (SLJIT_UNLIKELY(se_protected > 0)) {
+ SLJIT_SE_LOCK();
+ se_protected = check_se_protected(ptr, size);
+ SLJIT_SE_UNLOCK();
+ if (SLJIT_UNLIKELY(se_protected < 0)) {
+ munmap((void *)ptr, size);
+ return NULL;
+ }
+ }
+
+ *ptr++ = size;
+ return ptr;
+}
+
+#undef SLJIT_PROT_WX
+#undef SLJIT_SE_UNLOCK
+#undef SLJIT_SE_LOCK
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
+{
+ sljit_uw *start_ptr = ((sljit_uw*)ptr) - 1;
+ munmap((void*)start_ptr, *start_ptr);
+}
+
+static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)
+{
+ sljit_uw page_mask = (sljit_uw)get_page_alignment();
+ sljit_uw start = (sljit_uw)from;
+ sljit_uw end = (sljit_uw)to;
+ int prot = PROT_READ | (enable_exec ? PROT_EXEC : PROT_WRITE);
+
+ SLJIT_ASSERT(start < end);
+
+ start &= ~page_mask;
+ end = (end + page_mask) & ~page_mask;
+
+ mprotect((void*)start, end - start, prot);
+}
+
+#else /* windows */
+
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
+{
+ sljit_uw *ptr;
+
+ size += sizeof(sljit_uw);
+ ptr = (sljit_uw*)VirtualAlloc(NULL, size,
+ MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+
+ if (!ptr)
+ return NULL;
+
+ *ptr++ = size;
+
+ return ptr;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr)
+{
+ sljit_uw start = (sljit_uw)ptr - sizeof(sljit_uw);
+#if defined(SLJIT_DEBUG) && SLJIT_DEBUG
+ sljit_uw page_mask = (sljit_uw)get_page_alignment();
+
+ SLJIT_ASSERT(!(start & page_mask));
+#endif
+ VirtualFree((void*)start, 0, MEM_RELEASE);
+}
+
+static void sljit_update_wx_flags(void *from, void *to, sljit_s32 enable_exec)
+{
+ DWORD oldprot;
+ sljit_uw page_mask = (sljit_uw)get_page_alignment();
+ sljit_uw start = (sljit_uw)from;
+ sljit_uw end = (sljit_uw)to;
+ DWORD prot = enable_exec ? PAGE_EXECUTE : PAGE_READWRITE;
+
+ SLJIT_ASSERT(start < end);
+
+ start &= ~page_mask;
+ end = (end + page_mask) & ~page_mask;
+
+ VirtualProtect((void*)start, end - start, prot, &oldprot);
+}
+
+#endif /* !windows */
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
+{
+ /* This allocator does not keep unused memory for future allocations. */
+}
diff --git a/testdata/grepoutput b/testdata/grepoutput
index a9297e1..5f3b97c 100644
--- a/testdata/grepoutput
+++ b/testdata/grepoutput
@@ -956,3 +956,27 @@ RC=0
pcre2grep: Requested group 1 cannot be captured.
pcre2grep: Use --om-capture to increase the size of the capture vector.
RC=2
+---------------------------- Test 129 -----------------------------
+The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the
+lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox
+RC=0
+---------------------------- Test 130 -----------------------------
+fox
+fox
+fox
+fox
+RC=0
+---------------------------- Test 131 -----------------------------
+2
+RC=0
+---------------------------- Test 132 -----------------------------
+match 1:
+ a
+match 2:
+ b
+---
+ a
+RC=0
+---------------------------- Test 133 -----------------------------
+=AB3CD5=
+RC=0
diff --git a/testdata/grepoutput8 b/testdata/grepoutput8
index 1bac20b..3888d9a 100644
--- a/testdata/grepoutput8
+++ b/testdata/grepoutput8
@@ -29,3 +29,6 @@ RC=1
---------------------------- Test U5 ------------------------------
CD Z
RC=0
+---------------------------- Test U6 -----------------------------
+=ǓǤ=
+RC=0
diff --git a/testdata/grepoutputC b/testdata/grepoutputC
index 60f249f..87897f0 100644
--- a/testdata/grepoutputC
+++ b/testdata/grepoutputC
@@ -40,3 +40,5 @@ T
T
T
T
+0:T:AA
+The quick brown
diff --git a/testdata/grepoutputCN b/testdata/grepoutputCN
index 5217b5a..838bee6 100644
--- a/testdata/grepoutputCN
+++ b/testdata/grepoutputCN
@@ -28,3 +28,5 @@ T
T
T
T
+0:T:AA
+The quick brown
diff --git a/testdata/testinput1 b/testdata/testinput1
index 8d952e2..d4e42ba 100644
--- a/testdata/testinput1
+++ b/testdata/testinput1
@@ -1,6 +1,10 @@
# This set of tests is for features that are compatible with all versions of
# Perl >= 5.10, in non-UTF mode. It should run clean for the 8-bit, 16-bit, and
# 32-bit PCRE libraries, and also using the perltest.sh script.
+
+# WARNING: Use only / as the pattern delimiter. Although pcre2test supports
+# a number of delimiters, all those other than / give problems with the
+# perltest.sh script.
#forbid_utf
#newline_default lf any anycrlf
@@ -1957,7 +1961,7 @@
abc\nzzz
qqq\nabc\nzzz
-"(?>.*/)foo"
+/(?>.*\/)foo/
/this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo
\= Expect no match
/this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/
@@ -3831,12 +3835,13 @@
/(?-x: )/x
A\x20B
-"(?x)(?-x: \s*#\s*)"
+/(?x)(?-x: \s*#\s*)/
A # B
\= Expect no match
#
+ A s#s B
-"(?x-is)(?:(?-ixs) \s*#\s*) include"
+/(?x-is)(?:(?-ixs) \s*#\s*) include/
A #include
\= Expect no match
A#include
@@ -5232,11 +5237,11 @@ name)/mark
alphabetabcd
endingwxyz
-"(?>.*)foo"
+/(?>.*)foo/
\= Expect no match
abcdfooxyz
-"(?>.*?)foo"
+/(?>.*?)foo/
abcdfooxyz
/(?:(a(*PRUNE)b)){0}(?:(?1)|ac)/
@@ -5423,18 +5428,6 @@ name)/mark
\= Expect no match
a
-/(?=a\Kb)ab/
- ab
-
-/(?!a\Kb)ac/
- ac
-
-/^abc(?<=b\Kc)d/
- abcd
-
-/^abc(?<!b\Kq)d/
- abcd
-
/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/x,mark
\= Expect no match
AAAC
@@ -5659,16 +5652,16 @@ name)/mark
\= Expect no match
acb
-'\A(?:[^\"]++|\"(?:[^\"]*+|\"\")*+\")++'
+/\A(?:[^\"]++|\"(?:[^\"]*+|\"\")*+\")++/
NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
-'\A(?:[^\"]++|\"(?:[^\"]++|\"\")*+\")++'
+/\A(?:[^\"]++|\"(?:[^\"]++|\"\")*+\")++/
NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
-'\A(?:[^\"]++|\"(?:[^\"]++|\"\")++\")++'
+/\A(?:[^\"]++|\"(?:[^\"]++|\"\")++\")++/
NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
-'\A([^\"1]++|[\"2]([^\"3]*+|[\"4][\"5])*+[\"6])++'
+/\A([^\"1]++|[\"2]([^\"3]*+|[\"4][\"5])*+[\"6])++/
NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
/^\w+(?>\s*)(?<=\w)/
@@ -5727,9 +5720,9 @@ name)/mark
/(\2)(\1)/
-"Z*(|d*){216}"
+/Z*(|d*){216}/
-"(?1)(?#?'){8}(a)"
+/(?1)(?#?'){8}(a)/
baaaaaaaaac
/((((((((((((x))))))))))))\12/
@@ -5741,7 +5734,7 @@ name)/mark
/(?1)()((((((\1++))\x85)+)|))/
\x85\x85
-"(?|(\k'Pm')|(?'Pm'))"
+/(?|(\k'Pm')|(?'Pm'))/
abcd
/(?|(aaa)|(b))\g{1}/
@@ -5833,19 +5826,19 @@ ef) x/x,mark
\= Expect no match
aab
-'(?>ab|abab){1,5}?M'
+/(?>ab|abab){1,5}?M/
abababababababababababM
-'(?>ab|abab){2}?M'
+/(?>ab|abab){2}?M/
abababM
-'((?(?=(a))a)+k)'
+/((?(?=(a))a)+k)/
bbak
-'((?(?=(a))a|)+k)'
+/((?(?=(a))a|)+k)/
bbak
-'(?(?!(b))a|b)+k'
+/(?(?!(b))a|b)+k/
ababbalbbadabak
/(?!(b))c|b/
@@ -6411,20 +6404,20 @@ ef) x/x,mark
Hackdaws love my big sphinx of quartz.
Pack my fox with five dozen liquor jugs.
-"(?<=X(?(DEFINE)(A)))X(*F)"
+/(?<=X(?(DEFINE)(A)))X(*F)/
\= Expect no match
AXYZ
-"(?<=X(?(DEFINE)(A)))."
+/(?<=X(?(DEFINE)(A)))./
AXYZ
-"(?<=X(?(DEFINE)(.*))Y)."
+/(?<=X(?(DEFINE)(.*))Y)./
AXYZ
-"(?<=X(?(DEFINE)(Y))(?1))."
+/(?<=X(?(DEFINE)(Y))(?1))./
AXYZ
-"(?(DEFINE)(?<foo>bar))(?<![-a-z0-9])word"
+/(?(DEFINE)(?<foo>bar))(?<![-a-z0-9])word/
word
# End of testinput1
diff --git a/testdata/testinput10 b/testdata/testinput10
index b3c3197..53e37cb 100644
--- a/testdata/testinput10
+++ b/testdata/testinput10
@@ -610,4 +610,11 @@
/X(\x{e1})Y/replace=>\U$1<,substitute_extended
X\x{e1}Y
+/A/utf,match_invalid_utf,caseless
+ \xe5A
+
+/\bch\b/utf,match_invalid_utf
+ qchq\=ph
+ qchq\=ps
+
# End of testinput10
diff --git a/testdata/testinput2 b/testdata/testinput2
index c816c5f..3f9dd6d 100644
--- a/testdata/testinput2
+++ b/testdata/testinput2
@@ -5850,7 +5850,7 @@ a)"xI
/^\w+/tables=3
École
-#loadtables ./testdata/testbtables
+#loadtables ./testbtables
/^\w+/tables=3
École
@@ -5864,4 +5864,22 @@ a)"xI
/"(*MARK:>" 00 "<).(?C1)."/hex,mark,no_start_optimize
AB
+/(?(VERSION=0.0/
+
+# Perl has made \K in lookarounds an error. At the moment PCRE2 still accepts.
+
+/(?=a\Kb)ab/
+ ab
+
+/(?!a\Kb)ac/
+ ac
+
+/^abc(?<=b\Kc)d/
+ abcd
+
+/^abc(?<!b\Kq)d/
+ abcd
+
+# ---------
+
# End of testinput2
diff --git a/testdata/testinput4 b/testdata/testinput4
index 0bdac57..4e2a0ab 100644
--- a/testdata/testinput4
+++ b/testdata/testinput4
@@ -3,6 +3,10 @@
# some of the property tests may differ because of different versions of
# Unicode in use by PCRE2 and Perl.
+# WARNING: Use only / as the pattern delimiter. Although pcre2test supports
+# a number of delimiters, all those other than / give problems with the
+# perltest.sh script.
+
#newline_default lf anycrlf any
#perltest
@@ -476,7 +480,7 @@
/^\ሴ/utf
-"(?s)(.{1,5})"utf
+/(?s)(.{1,5})/utf
abcdefg
ab
@@ -2220,7 +2224,7 @@
/[A-`]/i,utf
abcdefghijklmno
-"[\S\V\H]"utf
+/[\S\V\H]/utf
/[^\p{Any}]*+x/utf
x
diff --git a/testdata/testoutput1 b/testdata/testoutput1
index 470e412..16c91d2 100644
--- a/testdata/testoutput1
+++ b/testdata/testoutput1
@@ -1,6 +1,10 @@
# This set of tests is for features that are compatible with all versions of
# Perl >= 5.10, in non-UTF mode. It should run clean for the 8-bit, 16-bit, and
# 32-bit PCRE libraries, and also using the perltest.sh script.
+
+# WARNING: Use only / as the pattern delimiter. Although pcre2test supports
+# a number of delimiters, all those other than / give problems with the
+# perltest.sh script.
#forbid_utf
#newline_default lf any anycrlf
@@ -2949,7 +2953,7 @@ No match
qqq\nabc\nzzz
No match
-"(?>.*/)foo"
+/(?>.*\/)foo/
/this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo
0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo
\= Expect no match
@@ -6081,14 +6085,16 @@ No match
A\x20B
0:
-"(?x)(?-x: \s*#\s*)"
+/(?x)(?-x: \s*#\s*)/
A # B
0: #
\= Expect no match
#
No match
+ A s#s B
+No match
-"(?x-is)(?:(?-ixs) \s*#\s*) include"
+/(?x-is)(?:(?-ixs) \s*#\s*) include/
A #include
0: #include
\= Expect no match
@@ -8402,12 +8408,12 @@ No match
1: <unset>
2: wxyz
-"(?>.*)foo"
+/(?>.*)foo/
\= Expect no match
abcdfooxyz
No match
-"(?>.*?)foo"
+/(?>.*?)foo/
abcdfooxyz
0: foo
@@ -8648,22 +8654,6 @@ No match
a
No match
-/(?=a\Kb)ab/
- ab
- 0: b
-
-/(?!a\Kb)ac/
- ac
- 0: ac
-
-/^abc(?<=b\Kc)d/
- abcd
- 0: cd
-
-/^abc(?<!b\Kq)d/
- abcd
- 0: abcd
-
/A(*PRUNE:A)A+(*SKIP:A)(B|Z) | AC/x,mark
\= Expect no match
AAAC
@@ -8988,19 +8978,19 @@ No match
acb
No match
-'\A(?:[^\"]++|\"(?:[^\"]*+|\"\")*+\")++'
+/\A(?:[^\"]++|\"(?:[^\"]*+|\"\")*+\")++/
NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
0: NON QUOTED "QUOT""ED" AFTER
-'\A(?:[^\"]++|\"(?:[^\"]++|\"\")*+\")++'
+/\A(?:[^\"]++|\"(?:[^\"]++|\"\")*+\")++/
NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
0: NON QUOTED "QUOT""ED" AFTER
-'\A(?:[^\"]++|\"(?:[^\"]++|\"\")++\")++'
+/\A(?:[^\"]++|\"(?:[^\"]++|\"\")++\")++/
NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
0: NON QUOTED "QUOT""ED" AFTER
-'\A([^\"1]++|[\"2]([^\"3]*+|[\"4][\"5])*+[\"6])++'
+/\A([^\"1]++|[\"2]([^\"3]*+|[\"4][\"5])*+[\"6])++/
NON QUOTED \"QUOT\"\"ED\" AFTER \"NOT MATCHED
0: NON QUOTED "QUOT""ED" AFTER
1: AFTER
@@ -9128,9 +9118,9 @@ No match
/(\2)(\1)/
-"Z*(|d*){216}"
+/Z*(|d*){216}/
-"(?1)(?#?'){8}(a)"
+/(?1)(?#?'){8}(a)/
baaaaaaaaac
0: aaaaaaaaa
1: a
@@ -9166,7 +9156,7 @@ No match
6:
7:
-"(?|(\k'Pm')|(?'Pm'))"
+/(?|(\k'Pm')|(?'Pm'))/
abcd
0:
1:
@@ -9322,27 +9312,27 @@ No match
aab
No match
-'(?>ab|abab){1,5}?M'
+/(?>ab|abab){1,5}?M/
abababababababababababM
0: abababababM
-'(?>ab|abab){2}?M'
+/(?>ab|abab){2}?M/
abababM
0: ababM
-'((?(?=(a))a)+k)'
+/((?(?=(a))a)+k)/
bbak
0: ak
1: ak
2: a
-'((?(?=(a))a|)+k)'
+/((?(?=(a))a|)+k)/
bbak
0: ak
1: ak
2: a
-'(?(?!(b))a|b)+k'
+/(?(?!(b))a|b)+k/
ababbalbbadabak
0: abak
1: b
@@ -10165,24 +10155,24 @@ No match
Pack my fox with five dozen liquor jugs.
No match
-"(?<=X(?(DEFINE)(A)))X(*F)"
+/(?<=X(?(DEFINE)(A)))X(*F)/
\= Expect no match
AXYZ
No match
-"(?<=X(?(DEFINE)(A)))."
+/(?<=X(?(DEFINE)(A)))./
AXYZ
0: Y
-"(?<=X(?(DEFINE)(.*))Y)."
+/(?<=X(?(DEFINE)(.*))Y)./
AXYZ
0: Z
-"(?<=X(?(DEFINE)(Y))(?1))."
+/(?<=X(?(DEFINE)(Y))(?1))./
AXYZ
0: Z
-"(?(DEFINE)(?<foo>bar))(?<![-a-z0-9])word"
+/(?(DEFINE)(?<foo>bar))(?<![-a-z0-9])word/
word
0: word
diff --git a/testdata/testoutput10 b/testdata/testoutput10
index 59af535..d408510 100644
--- a/testdata/testoutput10
+++ b/testdata/testoutput10
@@ -1871,4 +1871,14 @@ Subject length lower bound = 1
X\x{e1}Y
1: >\xe1<
+/A/utf,match_invalid_utf,caseless
+ \xe5A
+ 0: A
+
+/\bch\b/utf,match_invalid_utf
+ qchq\=ph
+Partial match:
+ qchq\=ps
+Partial match:
+
# End of testinput10
diff --git a/testdata/testoutput2 b/testdata/testoutput2
index c90efef..dc17011 100644
--- a/testdata/testoutput2
+++ b/testdata/testoutput2
@@ -17597,7 +17597,7 @@ No match
** 'Tables = 3' is invalid: binary tables have not been loaded
École
-#loadtables ./testdata/testbtables
+#loadtables ./testbtables
/^\w+/tables=3
École
@@ -17621,6 +17621,29 @@ Latest Mark: >\x00<
0: AB
MK: >\x00<
+/(?(VERSION=0.0/
+Failed: error 179 at offset 14: syntax error or number too big in (?(VERSION condition
+
+# Perl has made \K in lookarounds an error. At the moment PCRE2 still accepts.
+
+/(?=a\Kb)ab/
+ ab
+ 0: b
+
+/(?!a\Kb)ac/
+ ac
+ 0: ac
+
+/^abc(?<=b\Kc)d/
+ abcd
+ 0: cd
+
+/^abc(?<!b\Kq)d/
+ abcd
+ 0: abcd
+
+# ---------
+
# End of testinput2
Error -70: PCRE2_ERROR_BADDATA (unknown error number)
Error -62: bad serialized data
diff --git a/testdata/testoutput4 b/testdata/testoutput4
index 245a036..f43d940 100644
--- a/testdata/testoutput4
+++ b/testdata/testoutput4
@@ -3,6 +3,10 @@
# some of the property tests may differ because of different versions of
# Unicode in use by PCRE2 and Perl.
+# WARNING: Use only / as the pattern delimiter. Although pcre2test supports
+# a number of delimiters, all those other than / give problems with the
+# perltest.sh script.
+
#newline_default lf anycrlf any
#perltest
@@ -795,7 +799,7 @@ No match
0: \x{1234}
-"(?s)(.{1,5})"utf
+/(?s)(.{1,5})/utf
abcdefg
0: abcde
1: abcde
@@ -3596,7 +3600,7 @@ No match
abcdefghijklmno
0: a
-"[\S\V\H]"utf
+/[\S\V\H]/utf
/[^\p{Any}]*+x/utf
x