8.44
This commit is contained in:
parent
879f7e85aa
commit
c1291d7a6b
@ -8,7 +8,7 @@ Email domain: cam.ac.uk
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England.
|
||||
|
||||
Copyright (c) 1997-2019 University of Cambridge
|
||||
Copyright (c) 1997-2020 University of Cambridge
|
||||
All rights reserved
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2010-2019 Zoltan Herczeg
|
||||
Copyright(c) 2010-2020 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2009-2019 Zoltan Herczeg
|
||||
Copyright(c) 2009-2020 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
|
@ -5,6 +5,35 @@ Note that the PCRE 8.xx series (PCRE1) is now in a bugfix-only state. All
|
||||
development is happening in the PCRE2 10.xx series.
|
||||
|
||||
|
||||
Version 8.44 12 February-2020
|
||||
-----------------------------
|
||||
|
||||
1. Setting --enable-jit=auto for an out-of-tree build failed because the
|
||||
source directory wasn't in the search path for AC_TRY_COMPILE always. Patch
|
||||
from Ross Burton.
|
||||
|
||||
2. Applied a patch from Michael Shigorin to fix 8.43 build on e2k arch
|
||||
with lcc compiler (EDG frontend based); the problem it fixes is:
|
||||
|
||||
lcc: "pcrecpp.cc", line 74: error: declaration aliased to undefined entity
|
||||
"_ZN7pcrecpp2RE6no_argE" [-Werror]
|
||||
|
||||
3. Change 2 for 8.43 omitted (*LF) from the list of start-of-pattern items. Now
|
||||
added.
|
||||
|
||||
4. Fix ARMv5 JIT improper handling of labels right after a constant pool.
|
||||
|
||||
5. Small patch to pcreposix.c to set the erroroffset field to -1 immediately
|
||||
after a successful compile, instead of at the start of matching to avoid a
|
||||
sanitizer complaint (regexec is supposed to be thread safe).
|
||||
|
||||
6. Check the size of the number after (?C as it is read, in order to avoid
|
||||
integer overflow.
|
||||
|
||||
7. Tidy up left shifts to avoid sanitize warnings; also fix one NULL deference
|
||||
in pcretest.
|
||||
|
||||
|
||||
Version 8.43 23-February-2019
|
||||
-----------------------------
|
||||
|
||||
|
@ -25,7 +25,7 @@ Email domain: cam.ac.uk
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England.
|
||||
|
||||
Copyright (c) 1997-2019 University of Cambridge
|
||||
Copyright (c) 1997-2020 University of Cambridge
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Email domain: freemail.hu
|
||||
|
||||
Copyright(c) 2010-2019 Zoltan Herczeg
|
||||
Copyright(c) 2010-2020 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Email domain: freemail.hu
|
||||
|
||||
Copyright(c) 2009-2019 Zoltan Herczeg
|
||||
Copyright(c) 2009-2020 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
|
@ -5,6 +5,12 @@ Note that this library (now called PCRE1) is now being maintained for bug fixes
|
||||
only. New projects are advised to use the new PCRE2 libraries.
|
||||
|
||||
|
||||
Release 8.44 12-February-2020
|
||||
-----------------------------
|
||||
|
||||
This is a bug-fix release.
|
||||
|
||||
|
||||
Release 8.43 23-February-2019
|
||||
-----------------------------
|
||||
|
||||
|
@ -13,9 +13,10 @@ libraries.
|
||||
The latest release of PCRE1 is always available in three alternative formats
|
||||
from:
|
||||
|
||||
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz
|
||||
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.bz2
|
||||
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.zip
|
||||
https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.gz
|
||||
https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.bz2
|
||||
https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.zip
|
||||
|
||||
|
||||
There is a mailing list for discussion about the development of PCRE at
|
||||
pcre-dev@exim.org. You can access the archives and subscribe or manage your
|
||||
@ -999,4 +1000,4 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx.
|
||||
Philip Hazel
|
||||
Email local part: ph10
|
||||
Email domain: cam.ac.uk
|
||||
Last updated: 10 February 2015
|
||||
Last updated: 12 February 2020
|
||||
|
@ -235,7 +235,7 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
#define PACKAGE_NAME "PCRE"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "PCRE 8.43"
|
||||
#define PACKAGE_STRING "PCRE 8.44"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "pcre"
|
||||
@ -244,7 +244,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 "8.43"
|
||||
#define PACKAGE_VERSION "8.44"
|
||||
|
||||
/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
|
||||
parentheses (of any kind) in a pattern. This limits the amount of system
|
||||
@ -336,7 +336,7 @@ sure both macros are undefined; an emulation function will then be used. */
|
||||
/* #undef SUPPORT_VALGRIND */
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "8.43"
|
||||
#define VERSION "8.44"
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
38
pcre/configure
vendored
38
pcre/configure
vendored
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for PCRE 8.43.
|
||||
# Generated by GNU Autoconf 2.69 for PCRE 8.44.
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
|
||||
@ -587,8 +587,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='PCRE'
|
||||
PACKAGE_TARNAME='pcre'
|
||||
PACKAGE_VERSION='8.43'
|
||||
PACKAGE_STRING='PCRE 8.43'
|
||||
PACKAGE_VERSION='8.44'
|
||||
PACKAGE_STRING='PCRE 8.44'
|
||||
PACKAGE_BUGREPORT=''
|
||||
PACKAGE_URL=''
|
||||
|
||||
@ -1418,7 +1418,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 PCRE 8.43 to adapt to many kinds of systems.
|
||||
\`configure' configures PCRE 8.44 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@ -1488,7 +1488,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of PCRE 8.43:";;
|
||||
short | recursive ) echo "Configuration of PCRE 8.44:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@ -1662,7 +1662,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
PCRE configure 8.43
|
||||
PCRE configure 8.44
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@ -2419,7 +2419,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 PCRE $as_me 8.43, which was
|
||||
It was created by PCRE $as_me 8.44, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@ -3283,7 +3283,7 @@ fi
|
||||
|
||||
# Define the identity of the package.
|
||||
PACKAGE='pcre'
|
||||
VERSION='8.43'
|
||||
VERSION='8.44'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
@ -17664,9 +17664,9 @@ _ACEOF
|
||||
# Versioning
|
||||
|
||||
PCRE_MAJOR="8"
|
||||
PCRE_MINOR="43"
|
||||
PCRE_MINOR="44"
|
||||
PCRE_PRERELEASE=""
|
||||
PCRE_DATE="2019-02-23"
|
||||
PCRE_DATE="2020-02-12"
|
||||
|
||||
if test "$PCRE_MINOR" = "08" -o "$PCRE_MINOR" = "09"
|
||||
then
|
||||
@ -17747,6 +17747,8 @@ 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
|
||||
|
||||
SAVE_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS=-I$srcdir
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
@ -17762,6 +17764,7 @@ else
|
||||
enable_jit=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
CPPFLAGS=$SAVE_CPPFLAGS
|
||||
fi
|
||||
|
||||
# Handle --disable-pcregrep-jit (enabled by default)
|
||||
@ -19714,19 +19717,19 @@ esac
|
||||
# (Note: The libpcre*_version bits are m4 variables, assigned above)
|
||||
|
||||
EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \
|
||||
$NO_UNDEFINED -version-info 3:11:2"
|
||||
$NO_UNDEFINED -version-info 3:12:2"
|
||||
|
||||
EXTRA_LIBPCRE16_LDFLAGS="$EXTRA_LIBPCRE16_LDFLAGS \
|
||||
$NO_UNDEFINED -version-info 2:11:2"
|
||||
$NO_UNDEFINED -version-info 2:12:2"
|
||||
|
||||
EXTRA_LIBPCRE32_LDFLAGS="$EXTRA_LIBPCRE32_LDFLAGS \
|
||||
$NO_UNDEFINED -version-info 0:11:0"
|
||||
$NO_UNDEFINED -version-info 0:12:0"
|
||||
|
||||
EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \
|
||||
$NO_UNDEFINED -version-info 0:6:0"
|
||||
$NO_UNDEFINED -version-info 0:7:0"
|
||||
|
||||
EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \
|
||||
$NO_UNDEFINED -version-info 0:1:0 \
|
||||
$NO_UNDEFINED -version-info 0:2:0 \
|
||||
$EXPORT_ALL_SYMBOLS"
|
||||
|
||||
|
||||
@ -20775,7 +20778,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 PCRE $as_me 8.43, which was
|
||||
This file was extended by PCRE $as_me 8.44, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -20841,7 +20844,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="\\
|
||||
PCRE config.status 8.43
|
||||
PCRE config.status 8.44
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@ -22072,7 +22075,6 @@ See \`config.log' for more details" "$LINENO" 5; }
|
||||
cat <<_LT_EOF >> "$cfgfile"
|
||||
#! $SHELL
|
||||
# Generated automatically by $as_me ($PACKAGE) $VERSION
|
||||
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
|
||||
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
|
||||
|
||||
# Provide generalized library-building support services.
|
||||
|
@ -9,19 +9,19 @@ dnl The PCRE_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(pcre_major, [8])
|
||||
m4_define(pcre_minor, [43])
|
||||
m4_define(pcre_minor, [44])
|
||||
m4_define(pcre_prerelease, [])
|
||||
m4_define(pcre_date, [2019-02-23])
|
||||
m4_define(pcre_date, [2020-02-12])
|
||||
|
||||
# NOTE: The CMakeLists.txt file searches for the above variables in the first
|
||||
# 50 lines of this file. Please update that if the variables above are moved.
|
||||
|
||||
# Libtool shared library interface versions (current:revision:age)
|
||||
m4_define(libpcre_version, [3:11:2])
|
||||
m4_define(libpcre16_version, [2:11:2])
|
||||
m4_define(libpcre32_version, [0:11:0])
|
||||
m4_define(libpcreposix_version, [0:6:0])
|
||||
m4_define(libpcrecpp_version, [0:1:0])
|
||||
m4_define(libpcre_version, [3:12:2])
|
||||
m4_define(libpcre16_version, [2:12:2])
|
||||
m4_define(libpcre32_version, [0:12:0])
|
||||
m4_define(libpcreposix_version, [0:7:0])
|
||||
m4_define(libpcrecpp_version, [0:2:0])
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT(PCRE, pcre_major.pcre_minor[]pcre_prerelease, , pcre)
|
||||
@ -159,12 +159,15 @@ AC_ARG_ENABLE(jit,
|
||||
|
||||
if test "$enable_jit" = "auto"; then
|
||||
AC_LANG(C)
|
||||
SAVE_CPPFLAGS=$CPPFLAGS
|
||||
CPPFLAGS=-I$srcdir
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
#define SLJIT_CONFIG_AUTO 1
|
||||
#include "sljit/sljitConfigInternal.h"
|
||||
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||
#error unsupported
|
||||
#endif]])], enable_jit=yes, enable_jit=no)
|
||||
CPPFLAGS=$SAVE_CPPFLAGS
|
||||
fi
|
||||
|
||||
# Handle --disable-pcregrep-jit (enabled by default)
|
||||
|
@ -13,9 +13,10 @@ libraries.
|
||||
The latest release of PCRE1 is always available in three alternative formats
|
||||
from:
|
||||
|
||||
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz
|
||||
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.bz2
|
||||
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.zip
|
||||
https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.gz
|
||||
https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.bz2
|
||||
https://ftp.pcre.org/pub/pcre/pcre-x.xx.tar.zip
|
||||
|
||||
|
||||
There is a mailing list for discussion about the development of PCRE at
|
||||
pcre-dev@exim.org. You can access the archives and subscribe or manage your
|
||||
@ -999,4 +1000,4 @@ pcre_xxx, one with the name pcre16_xx, and a third with the name pcre32_xxx.
|
||||
Philip Hazel
|
||||
Email local part: ph10
|
||||
Email domain: cam.ac.uk
|
||||
Last updated: 10 February 2015
|
||||
Last updated: 12 February 2020
|
||||
|
@ -143,7 +143,7 @@ performance.
|
||||
One way of guarding against this possibility is to use the
|
||||
<b>pcre_fullinfo()</b> function to check the compiled pattern's options for UTF.
|
||||
Alternatively, from release 8.33, you can set the PCRE_NEVER_UTF option at
|
||||
compile time. This causes an compile time error if a pattern contains a
|
||||
compile time. This causes a compile time error if a pattern contains a
|
||||
UTF-setting sequence.
|
||||
</P>
|
||||
<P>
|
||||
|
@ -1246,7 +1246,7 @@ the following negative numbers:
|
||||
PCRE_ERROR_BADOPTION the value of <i>what</i> was invalid
|
||||
PCRE_ERROR_UNSET the requested field is not set
|
||||
</pre>
|
||||
The "magic number" is placed at the start of each compiled pattern as an simple
|
||||
The "magic number" is placed at the start of each compiled pattern as a simple
|
||||
check against passing an arbitrary memory pointer. The endianness error can
|
||||
occur if a compiled pattern is saved and reloaded on a different host. Here is
|
||||
a typical call of <b>pcre_fullinfo()</b>, to obtain the length of the compiled
|
||||
@ -1318,7 +1318,7 @@ returned. For anchored patterns, -2 is returned.
|
||||
</pre>
|
||||
Return the value of the first data unit (non-UTF character) of any matched
|
||||
string in the situation where PCRE_INFO_FIRSTCHARACTERFLAGS returns 1;
|
||||
otherwise return 0. The fourth argument should point to an <b>uint_t</b>
|
||||
otherwise return 0. The fourth argument should point to a <b>uint_t</b>
|
||||
variable.
|
||||
</P>
|
||||
<P>
|
||||
@ -1577,7 +1577,7 @@ returned value 1 (with "z" returned from PCRE_INFO_REQUIREDCHAR), but for
|
||||
</pre>
|
||||
Return the value of the rightmost literal data unit that must exist in any
|
||||
matched string, other than at its start, if such a value has been recorded. The
|
||||
fourth argument should point to an <b>uint32_t</b> variable. If there is no such
|
||||
fourth argument should point to a <b>uint32_t</b> variable. If there is no such
|
||||
value, 0 is returned.
|
||||
</P>
|
||||
<br><a name="SEC16" href="#TOC1">REFERENCE COUNTS</a><br>
|
||||
|
@ -99,23 +99,21 @@ the 16-bit library, or <b>pcre32_xx</b> when using the 32-bit library".
|
||||
<br><a name="SEC4" href="#TOC1">COMMAND LINE OPTIONS</a><br>
|
||||
<P>
|
||||
<b>-8</b>
|
||||
If both the 8-bit library has been built, this option causes the 8-bit library
|
||||
to be used (which is the default); if the 8-bit library has not been built,
|
||||
this option causes an error.
|
||||
If the 8-bit library has been built, this option causes it to be used (this is
|
||||
the default). If the 8-bit library has not been built, this option causes an
|
||||
error.
|
||||
</P>
|
||||
<P>
|
||||
<b>-16</b>
|
||||
If both the 8-bit or the 32-bit, and the 16-bit libraries have been built, this
|
||||
option causes the 16-bit library to be used. If only the 16-bit library has been
|
||||
built, this is the default (so has no effect). If only the 8-bit or the 32-bit
|
||||
library has been built, this option causes an error.
|
||||
If the 16-bit library has been built, this option causes it to be used. If only
|
||||
the 16-bit library has been built, this is the default. If the 16-bit library
|
||||
has not been built, this option causes an error.
|
||||
</P>
|
||||
<P>
|
||||
<b>-32</b>
|
||||
If both the 8-bit or the 16-bit, and the 32-bit libraries have been built, this
|
||||
option causes the 32-bit library to be used. If only the 32-bit library has been
|
||||
built, this is the default (so has no effect). If only the 8-bit or the 16-bit
|
||||
library has been built, this option causes an error.
|
||||
If the 32-bit library has been built, this option causes it to be used. If only
|
||||
the 32-bit library has been built, this is the default. If the 32-bit library
|
||||
has not been built, this option causes an error.
|
||||
</P>
|
||||
<P>
|
||||
<b>-b</b>
|
||||
@ -1154,9 +1152,9 @@ Cambridge CB2 3QH, England.
|
||||
</P>
|
||||
<br><a name="SEC17" href="#TOC1">REVISION</a><br>
|
||||
<P>
|
||||
Last updated: 23 February 2017
|
||||
Last updated: 10 February 2020
|
||||
<br>
|
||||
Copyright © 1997-2017 University of Cambridge.
|
||||
Copyright © 1997-2020 University of Cambridge.
|
||||
<br>
|
||||
<p>
|
||||
Return to the <a href="index.html">PCRE index page</a>.
|
||||
|
@ -16,8 +16,8 @@ DESCRIPTION
|
||||
|
||||
pcre-config returns the configuration of the installed PCRE libraries
|
||||
and the options required to compile a program to use them. Some of the
|
||||
options apply only to the 8-bit, or 16-bit, or 32-bit libraries,
|
||||
respectively, and are not available if only one of those libraries has
|
||||
options apply only to the 8-bit, or 16-bit, or 32-bit libraries, re-
|
||||
spectively, and are not available if only one of those libraries has
|
||||
been built. If an unavailable option is encountered, the "usage" infor-
|
||||
mation is output.
|
||||
|
||||
@ -36,37 +36,37 @@ OPTIONS
|
||||
--version Writes the version number of the installed PCRE libraries to
|
||||
the standard output.
|
||||
|
||||
--libs Writes to the standard output the command line options
|
||||
required to link with the 8-bit PCRE library (-lpcre on many
|
||||
--libs Writes to the standard output the command line options re-
|
||||
quired to link with the 8-bit PCRE library (-lpcre on many
|
||||
systems).
|
||||
|
||||
--libs16 Writes to the standard output the command line options
|
||||
required to link with the 16-bit PCRE library (-lpcre16 on
|
||||
many systems).
|
||||
--libs16 Writes to the standard output the command line options re-
|
||||
quired to link with the 16-bit PCRE library (-lpcre16 on many
|
||||
systems).
|
||||
|
||||
--libs32 Writes to the standard output the command line options
|
||||
required to link with the 32-bit PCRE library (-lpcre32 on
|
||||
many systems).
|
||||
--libs32 Writes to the standard output the command line options re-
|
||||
quired to link with the 32-bit PCRE library (-lpcre32 on many
|
||||
systems).
|
||||
|
||||
--libs-cpp
|
||||
Writes to the standard output the command line options
|
||||
required to link with PCRE's C++ wrapper library (-lpcrecpp
|
||||
Writes to the standard output the command line options re-
|
||||
quired to link with PCRE's C++ wrapper library (-lpcrecpp
|
||||
-lpcre on many systems).
|
||||
|
||||
--libs-posix
|
||||
Writes to the standard output the command line options
|
||||
required to link with PCRE's POSIX API wrapper library
|
||||
Writes to the standard output the command line options re-
|
||||
quired to link with PCRE's POSIX API wrapper library
|
||||
(-lpcreposix -lpcre on many systems).
|
||||
|
||||
--cflags Writes to the standard output the command line options
|
||||
required to compile files that use PCRE (this may include
|
||||
some -I options, but is blank on many systems).
|
||||
--cflags Writes to the standard output the command line options re-
|
||||
quired to compile files that use PCRE (this may include some
|
||||
-I options, but is blank on many systems).
|
||||
|
||||
--cflags-posix
|
||||
Writes to the standard output the command line options
|
||||
required to compile files that use PCRE's POSIX API wrapper
|
||||
library (this may include some -I options, but is blank on
|
||||
many systems).
|
||||
Writes to the standard output the command line options re-
|
||||
quired to compile files that use PCRE's POSIX API wrapper li-
|
||||
brary (this may include some -I options, but is blank on many
|
||||
systems).
|
||||
|
||||
|
||||
SEE ALSO
|
||||
|
@ -146,7 +146,7 @@ performance.
|
||||
One way of guarding against this possibility is to use the
|
||||
\fBpcre_fullinfo()\fP function to check the compiled pattern's options for UTF.
|
||||
Alternatively, from release 8.33, you can set the PCRE_NEVER_UTF option at
|
||||
compile time. This causes an compile time error if a pattern contains a
|
||||
compile time. This causes a compile time error if a pattern contains a
|
||||
UTF-setting sequence.
|
||||
.P
|
||||
If your application is one that supports UTF, be aware that validity checking
|
||||
|
1557
pcre/doc/pcre.txt
1557
pcre/doc/pcre.txt
File diff suppressed because it is too large
Load Diff
@ -1227,7 +1227,7 @@ the following negative numbers:
|
||||
PCRE_ERROR_BADOPTION the value of \fIwhat\fP was invalid
|
||||
PCRE_ERROR_UNSET the requested field is not set
|
||||
.sp
|
||||
The "magic number" is placed at the start of each compiled pattern as an simple
|
||||
The "magic number" is placed at the start of each compiled pattern as a simple
|
||||
check against passing an arbitrary memory pointer. The endianness error can
|
||||
occur if a compiled pattern is saved and reloaded on a different host. Here is
|
||||
a typical call of \fBpcre_fullinfo()\fP, to obtain the length of the compiled
|
||||
@ -1294,7 +1294,7 @@ returned. For anchored patterns, -2 is returned.
|
||||
.sp
|
||||
Return the value of the first data unit (non-UTF character) of any matched
|
||||
string in the situation where PCRE_INFO_FIRSTCHARACTERFLAGS returns 1;
|
||||
otherwise return 0. The fourth argument should point to an \fBuint_t\fP
|
||||
otherwise return 0. The fourth argument should point to a \fBuint_t\fP
|
||||
variable.
|
||||
.P
|
||||
In the 8-bit library, the value is always less than 256. In the 16-bit library
|
||||
@ -1560,7 +1560,7 @@ returned value 1 (with "z" returned from PCRE_INFO_REQUIREDCHAR), but for
|
||||
.sp
|
||||
Return the value of the rightmost literal data unit that must exist in any
|
||||
matched string, other than at its start, if such a value has been recorded. The
|
||||
fourth argument should point to an \fBuint32_t\fP variable. If there is no such
|
||||
fourth argument should point to a \fBuint32_t\fP variable. If there is no such
|
||||
value, 0 is returned.
|
||||
.
|
||||
.
|
||||
|
@ -26,8 +26,8 @@ DESCRIPTION
|
||||
If you attempt to use delimiters (for example, by surrounding a pattern
|
||||
with slashes, as is common in Perl scripts), they are interpreted as
|
||||
part of the pattern. Quotes can of course be used to delimit patterns
|
||||
on the command line because they are interpreted by the shell, and
|
||||
indeed quotes are required if a pattern contains white space or shell
|
||||
on the command line because they are interpreted by the shell, and in-
|
||||
deed quotes are required if a pattern contains white space or shell
|
||||
metacharacters.
|
||||
|
||||
The first argument that follows any option settings is treated as the
|
||||
@ -37,8 +37,8 @@ DESCRIPTION
|
||||
or an argument pattern must be provided.
|
||||
|
||||
If no files are specified, pcregrep reads the standard input. The stan-
|
||||
dard input can also be referenced by a name consisting of a single
|
||||
hyphen. For example:
|
||||
dard input can also be referenced by a name consisting of a single hy-
|
||||
phen. For example:
|
||||
|
||||
pcregrep some-pattern /file1 - /file3
|
||||
|
||||
@ -47,8 +47,8 @@ DESCRIPTION
|
||||
the start of each line, followed by a colon. However, there are options
|
||||
that can change how pcregrep behaves. In particular, the -M option
|
||||
makes it possible to search for patterns that span line boundaries.
|
||||
What defines a line boundary is controlled by the -N (--newline)
|
||||
option.
|
||||
What defines a line boundary is controlled by the -N (--newline) op-
|
||||
tion.
|
||||
|
||||
The amount of memory used for buffering files that are being scanned is
|
||||
controlled by a parameter that can be set by the --buffer-size option.
|
||||
@ -66,12 +66,12 @@ DESCRIPTION
|
||||
By default, as soon as one pattern matches a line, no further patterns
|
||||
are considered. However, if --colour (or --color) is used to colour the
|
||||
matching substrings, or if --only-matching, --file-offsets, or --line-
|
||||
offsets is used to output only the part of the line that matched
|
||||
(either shown literally, or as an offset), scanning resumes immediately
|
||||
offsets is used to output only the part of the line that matched (ei-
|
||||
ther 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.
|
||||
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.
|
||||
|
||||
This behaviour means that the order in which multiple patterns are
|
||||
specified can affect the output when one of the above options is used.
|
||||
@ -80,11 +80,11 @@ DESCRIPTION
|
||||
overlap).
|
||||
|
||||
Patterns that can match an empty string are accepted, but empty string
|
||||
matches are never recognized. An example is the pattern
|
||||
"(super)?(man)?", in which all components are optional. This pattern
|
||||
finds all occurrences of both "super" and "man"; the output differs
|
||||
from matching with "super|man" when only the matching substrings are
|
||||
being shown.
|
||||
matches are never recognized. An example is the pattern "(su-
|
||||
per)?(man)?", in which all components are optional. This pattern finds
|
||||
all occurrences of both "super" and "man"; the output differs from
|
||||
matching with "super|man" when only the matching substrings are being
|
||||
shown.
|
||||
|
||||
If the LC_ALL or LC_CTYPE environment variable is set, pcregrep uses
|
||||
the value to set a locale when calling the PCRE library. The --locale
|
||||
@ -105,9 +105,9 @@ 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 also identifies binary files in this manner.) See the
|
||||
--binary-files option for a means of changing the way binary files are
|
||||
handled.
|
||||
(GNU grep also identifies binary files in this manner.) See the --bi-
|
||||
nary-files option for a means of changing the way binary files are han-
|
||||
dled.
|
||||
|
||||
|
||||
OPTIONS
|
||||
@ -151,16 +151,16 @@ OPTIONS
|
||||
|
||||
--binary-files=word
|
||||
Specify how binary files are to be processed. If the word is
|
||||
"binary" (the default), pattern matching is performed on
|
||||
binary files, but the only output is "Binary file <name>
|
||||
"binary" (the default), pattern matching is performed on bi-
|
||||
nary files, but the only output is "Binary file <name>
|
||||
matches" when a match succeeds. If the word is "text", which
|
||||
is equivalent to the -a or --text option, binary files are
|
||||
processed in the same way as any other file. In this case,
|
||||
when a match succeeds, the output may be binary garbage,
|
||||
which can have nasty effects if sent to a terminal. If the
|
||||
word is "without-match", which is equivalent to the -I
|
||||
option, binary files are not processed at all; they are
|
||||
assumed not to be of interest.
|
||||
word is "without-match", which is equivalent to the -I op-
|
||||
tion, binary files are not processed at all; they are assumed
|
||||
not to be of interest.
|
||||
|
||||
--buffer-size=number
|
||||
Set the parameter that controls how much memory is used for
|
||||
@ -201,15 +201,15 @@ OPTIONS
|
||||
ronment variable PCREGREP_COLOUR or PCREGREP_COLOR. The value
|
||||
of this variable should be a string of two numbers, separated
|
||||
by a semicolon. They are copied directly into the control
|
||||
string for setting colour on a terminal, so it is your
|
||||
responsibility to ensure that they make sense. If neither of
|
||||
string for setting colour on a terminal, so it is your re-
|
||||
sponsibility to ensure that they make sense. If neither of
|
||||
the environment variables is set, the default is "1;31",
|
||||
which gives red.
|
||||
|
||||
-D action, --devices=action
|
||||
If an input path is not a regular file or a directory,
|
||||
"action" specifies how it is to be processed. Valid values
|
||||
are "read" (the default) or "skip" (silently skip the path).
|
||||
If an input path is not a regular file or a directory, "ac-
|
||||
tion" specifies how it is to be processed. Valid values are
|
||||
"read" (the default) or "skip" (silently skip the path).
|
||||
|
||||
-d action, --directories=action
|
||||
If an input path is a directory, "action" specifies how it is
|
||||
@ -218,8 +218,8 @@ OPTIONS
|
||||
"recurse" (equivalent to the -r option), or "skip" (silently
|
||||
skip the path, the default in Windows environments). In the
|
||||
"read" case, directories are read as if they were ordinary
|
||||
files. In some operating systems the effect of reading a
|
||||
directory like this is an immediate end-of-file; in others it
|
||||
files. In some operating systems the effect of reading a di-
|
||||
rectory like this is an immediate end-of-file; in others it
|
||||
may provoke an error.
|
||||
|
||||
-e pattern, --regex=pattern, --regexp=pattern
|
||||
@ -249,8 +249,8 @@ OPTIONS
|
||||
whether listed on the command line, obtained from --file-
|
||||
list, or by scanning a directory. The pattern is a PCRE regu-
|
||||
lar 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
|
||||
the file name, not the entire path. The -F, -w, and -x op-
|
||||
tions do not apply to this pattern. The option may be given
|
||||
any number of times in order to specify multiple patterns. If
|
||||
a file name matches both an --include and an --exclude pat-
|
||||
tern, it is excluded. There is no short form for this option.
|
||||
@ -264,29 +264,29 @@ OPTIONS
|
||||
|
||||
--exclude-dir=pattern
|
||||
Directories whose names match the pattern are skipped without
|
||||
being processed, whatever the setting of the --recursive
|
||||
option. This applies to all directories, whether listed on
|
||||
the command line, obtained from --file-list, or by scanning a
|
||||
being processed, whatever the setting of the --recursive op-
|
||||
tion. This applies to all directories, whether listed on the
|
||||
command line, obtained from --file-list, or by scanning a
|
||||
parent directory. The pattern is a PCRE regular expression,
|
||||
and is matched against the final component of the directory
|
||||
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 in order to specify more than one pattern. If a direc-
|
||||
tory matches both --include-dir and --exclude-dir, it is
|
||||
excluded. There is no short form for this option.
|
||||
tory matches both --include-dir and --exclude-dir, it is ex-
|
||||
cluded. There is no short form for this option.
|
||||
|
||||
-F, --fixed-strings
|
||||
Interpret each data-matching pattern as a list of fixed
|
||||
strings, separated by newlines, instead of as a regular
|
||||
expression. What constitutes a newline for this purpose is
|
||||
controlled by the --newline option. The -w (match as a word)
|
||||
and -x (match whole line) options can be used with -F. They
|
||||
apply to each of the fixed strings. A line is selected if any
|
||||
strings, separated by newlines, instead of as a regular ex-
|
||||
pression. What constitutes a newline for this purpose is con-
|
||||
trolled by the --newline option. The -w (match as a word) and
|
||||
-x (match whole line) options can be used with -F. They ap-
|
||||
ply to each of the fixed strings. A line is selected if any
|
||||
of the fixed strings are found in it (subject to -w or -x, if
|
||||
present). This option applies only to the patterns that are
|
||||
matched against the contents of files; it does not apply to
|
||||
patterns specified by any of the --include or --exclude
|
||||
options.
|
||||
patterns specified by any of the --include or --exclude op-
|
||||
tions.
|
||||
|
||||
-f filename, --file=filename
|
||||
Read patterns from the file, one per line, and match them
|
||||
@ -358,16 +358,16 @@ 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
|
||||
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 PCRE 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
|
||||
--exclude pattern, it is excluded. There is no short form
|
||||
for this option.
|
||||
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 PCRE 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.
|
||||
|
||||
--include-from=filename
|
||||
Treat each non-empty line of the file as the data for an
|
||||
@ -381,8 +381,8 @@ OPTIONS
|
||||
tories that are processed are those that 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
|
||||
directory. The pattern is a PCRE regular expression, and is
|
||||
line, obtained from --file-list, or by scanning a parent di-
|
||||
rectory. The pattern is a PCRE regular expression, and is
|
||||
matched against the final component of the directory 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.
|
||||
@ -413,9 +413,9 @@ OPTIONS
|
||||
|
||||
--line-buffered
|
||||
When this option is given, 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 pcregrep can
|
||||
determine that it is reading from a terminal (which is cur-
|
||||
by line, and the output is flushed after each write. By de-
|
||||
fault, input is read in large chunks, unless pcregrep can de-
|
||||
termine that it is reading from a terminal (which is cur-
|
||||
rently possible only in Unix-like environments). Output to
|
||||
terminal is normally automatically flushed by the operating
|
||||
system. This option can be useful when the input or output is
|
||||
@ -437,9 +437,9 @@ OPTIONS
|
||||
--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 PCRE
|
||||
library's default (usually the "C" locale) is used. There is
|
||||
no short form for this option.
|
||||
ronment variables. If no locale is specified, the PCRE li-
|
||||
brary's default (usually the "C" locale) is used. There is no
|
||||
short form for this option.
|
||||
|
||||
--match-limit=number
|
||||
Processing some regular expression patterns can require a
|
||||
@ -447,26 +447,26 @@ OPTIONS
|
||||
gram crash if not enough is available. Other patterns may
|
||||
take a very long time to search for all possible matching
|
||||
strings. The pcre_exec() function that is called by pcregrep
|
||||
to do the matching has two parameters that can limit the
|
||||
resources that it uses.
|
||||
to do the matching has two parameters that can limit the re-
|
||||
sources that it uses.
|
||||
|
||||
The --match-limit option provides a means of limiting
|
||||
resource usage when processing patterns that are not going to
|
||||
The --match-limit option provides a means of limiting re-
|
||||
source usage 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 nested unlimited repeats. Internally, PCRE uses a func-
|
||||
tion called match() which it calls repeatedly (sometimes
|
||||
recursively). The limit set by --match-limit is imposed on
|
||||
the number of times this function is called during a match,
|
||||
which has the effect of limiting the amount of backtracking
|
||||
that can take place.
|
||||
tion called match() which it calls repeatedly (sometimes re-
|
||||
cursively). The limit set by --match-limit is imposed on the
|
||||
number of times this function is called during a match, which
|
||||
has the effect of limiting the amount of backtracking that
|
||||
can take place.
|
||||
|
||||
The --recursion-limit option is similar to --match-limit, but
|
||||
instead of limiting the total number of times that match() is
|
||||
called, it limits the depth of recursive calls, which in turn
|
||||
limits the amount of memory that can be used. The recursion
|
||||
depth is a smaller number than the total number of calls,
|
||||
because not all calls to match() are recursive. This limit is
|
||||
depth is a smaller number than the total number of calls, be-
|
||||
cause not all calls to match() are recursive. This limit is
|
||||
of use only if it is set smaller than --match-limit.
|
||||
|
||||
There are no short forms for these options. The default set-
|
||||
@ -494,30 +494,30 @@ OPTIONS
|
||||
is read line by line (see --line-buffered.)
|
||||
|
||||
-N newline-type, --newline=newline-type
|
||||
The PCRE library supports five different conventions for
|
||||
indicating the ends of lines. They are the single-character
|
||||
sequences CR (carriage return) and LF (linefeed), the two-
|
||||
character sequence CRLF, an "anycrlf" convention, which rec-
|
||||
ognizes any of the preceding three types, and an "any" con-
|
||||
vention, in which any Unicode line ending sequence is assumed
|
||||
to end a line. The Unicode sequences are the three just men-
|
||||
The PCRE library supports five different conventions for in-
|
||||
dicating the ends of lines. They are the single-character se-
|
||||
quences CR (carriage return) and LF (linefeed), the two-char-
|
||||
acter sequence CRLF, an "anycrlf" convention, which recog-
|
||||
nizes any of the preceding three types, and an "any" conven-
|
||||
tion, in which any Unicode line ending sequence is assumed to
|
||||
end a line. The Unicode sequences are the three just men-
|
||||
tioned, plus VT (vertical tab, U+000B), FF (form feed,
|
||||
U+000C), NEL (next line, U+0085), LS (line separator,
|
||||
U+2028), and PS (paragraph separator, U+2029).
|
||||
|
||||
When the PCRE library is built, a default line-ending
|
||||
sequence is specified. This is normally the standard
|
||||
sequence for the operating system. Unless otherwise specified
|
||||
by this option, pcregrep uses the library's default. The
|
||||
possible values for this option are CR, LF, CRLF, ANYCRLF, or
|
||||
ANY. This makes it possible to use pcregrep to scan files
|
||||
that have come from other environments without having to mod-
|
||||
ify their line endings. If the data that is being scanned
|
||||
does not agree with the convention set by this option, pcre-
|
||||
grep may behave in strange ways. Note that this option does
|
||||
not apply to files specified by the -f, --exclude-from, or
|
||||
--include-from options, which are expected to use the operat-
|
||||
ing system's standard newline sequence.
|
||||
When the PCRE library is built, a default line-ending se-
|
||||
quence is specified. This is normally the standard sequence
|
||||
for the operating system. Unless otherwise specified by this
|
||||
option, pcregrep uses the library's default. The possible
|
||||
values for this option are CR, LF, CRLF, ANYCRLF, or ANY.
|
||||
This makes it possible to use pcregrep to scan files that
|
||||
have come from other environments without having to modify
|
||||
their line endings. If the data that is being scanned does
|
||||
not agree with the convention set by this option, pcregrep
|
||||
may behave in strange ways. Note that this option does not
|
||||
apply to files specified by the -f, --exclude-from, or --in-
|
||||
clude-from options, which are expected to use the operating
|
||||
system's standard newline sequence.
|
||||
|
||||
-n, --line-number
|
||||
Precede each output line by its line number in the file, fol-
|
||||
@ -538,12 +538,12 @@ OPTIONS
|
||||
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.
|
||||
If -o is combined with -v (invert the sense of the match to
|
||||
find non-matching lines), no output is generated, but the
|
||||
return code is set appropriately. 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 --file-offsets and --line-offsets.
|
||||
find non-matching lines), no output is generated, but the re-
|
||||
turn code is set appropriately. 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
|
||||
--file-offsets and --line-offsets.
|
||||
|
||||
-onumber, --only-matching=number
|
||||
Show only the part of the line that matched the capturing
|
||||
@ -579,8 +579,8 @@ OPTIONS
|
||||
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
|
||||
"recurse".
|
||||
This option is a shorthand for setting the -d option to "re-
|
||||
curse".
|
||||
|
||||
--recursion-limit=number
|
||||
See --match-limit above.
|
||||
@ -626,10 +626,10 @@ OPTIONS
|
||||
|
||||
ENVIRONMENT VARIABLES
|
||||
|
||||
The environment variables LC_ALL and LC_CTYPE are examined, in that
|
||||
order, for a locale. The first one that is set is used. This can be
|
||||
overridden by the --locale option. If no locale is set, the PCRE
|
||||
library's default (usually the "C" locale) is used.
|
||||
The environment variables LC_ALL and LC_CTYPE are examined, in that or-
|
||||
der, for a locale. The first one that is set is used. This can be over-
|
||||
ridden by the --locale option. If no locale is set, the PCRE library's
|
||||
default (usually the "C" locale) is used.
|
||||
|
||||
|
||||
NEWLINES
|
||||
@ -640,8 +640,8 @@ NEWLINES
|
||||
ever newline sequences they have in the input. However, the setting of
|
||||
this option does not affect the interpretation of files specified by
|
||||
the -f, --exclude-from, or --include-from options, which are assumed to
|
||||
use the operating system's standard newline sequence, nor does it
|
||||
affect the way in which pcregrep writes informational messages to the
|
||||
use the operating system's standard newline sequence, nor does it af-
|
||||
fect the way in which pcregrep writes informational messages to the
|
||||
standard error and output streams. For these it uses the string "\n" to
|
||||
indicate newlines, relying on the C I/O library to convert this to an
|
||||
appropriate sequence.
|
||||
@ -687,13 +687,13 @@ OPTIONS WITH DATA
|
||||
--file /some/file
|
||||
|
||||
Note, however, that if you want to supply a file name beginning with ~
|
||||
as data in a shell command, and have the shell expand ~ to a home
|
||||
directory, you must separate the file name from the option, because the
|
||||
as data in a shell command, and have the shell expand ~ to a home di-
|
||||
rectory, you must separate the file name from the option, because the
|
||||
shell does not treat ~ specially unless it is at the start of an item.
|
||||
|
||||
The exceptions to the above are the --colour (or --color) and --only-
|
||||
matching options, for which the data is optional. If one of these
|
||||
options does have data, it must be given in the first form, using an
|
||||
matching options, for which the data is optional. If one of these op-
|
||||
tions does have data, it must be given in the first form, using an
|
||||
equals character. Otherwise pcregrep will assume that it has no data.
|
||||
|
||||
|
||||
@ -702,14 +702,14 @@ MATCHING ERRORS
|
||||
It is possible to supply a regular expression that takes a very long
|
||||
time to fail to match certain lines. Such patterns normally involve
|
||||
nested indefinite repeats, for example: (a+)*\d when matched against a
|
||||
line of a's with no final digit. The PCRE matching function has a
|
||||
resource limit that causes it to abort in these circumstances. If this
|
||||
line of a's with no final digit. The PCRE matching function has a re-
|
||||
source limit that causes it to abort in these circumstances. If this
|
||||
happens, pcregrep outputs an error message and the line that caused the
|
||||
problem to the standard error stream. If there are more than 20 such
|
||||
errors, pcregrep gives up.
|
||||
|
||||
The --match-limit option of pcregrep can be used to set the overall
|
||||
resource limit; there is a second option called --recursion-limit that
|
||||
The --match-limit option of pcregrep can be used to set the overall re-
|
||||
source limit; there is a second option called --recursion-limit that
|
||||
sets a limit on the amount of memory (usually stack) that is used (see
|
||||
the discussion of these options above).
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH PCRETEST 1 "23 February 2017" "PCRE 8.41"
|
||||
.TH PCRETEST 1 "10 February 2020" "PCRE 8.44"
|
||||
.SH NAME
|
||||
pcretest - a program for testing Perl-compatible regular expressions.
|
||||
.SH SYNOPSIS
|
||||
@ -78,21 +78,19 @@ the 16-bit library, or \fBpcre32_xx\fP when using the 32-bit library".
|
||||
.rs
|
||||
.TP 10
|
||||
\fB-8\fP
|
||||
If both the 8-bit library has been built, this option causes the 8-bit library
|
||||
to be used (which is the default); if the 8-bit library has not been built,
|
||||
this option causes an error.
|
||||
If the 8-bit library has been built, this option causes it to be used (this is
|
||||
the default). If the 8-bit library has not been built, this option causes an
|
||||
error.
|
||||
.TP 10
|
||||
\fB-16\fP
|
||||
If both the 8-bit or the 32-bit, and the 16-bit libraries have been built, this
|
||||
option causes the 16-bit library to be used. If only the 16-bit library has been
|
||||
built, this is the default (so has no effect). If only the 8-bit or the 32-bit
|
||||
library has been built, this option causes an error.
|
||||
If the 16-bit library has been built, this option causes it to be used. If only
|
||||
the 16-bit library has been built, this is the default. If the 16-bit library
|
||||
has not been built, this option causes an error.
|
||||
.TP 10
|
||||
\fB-32\fP
|
||||
If both the 8-bit or the 16-bit, and the 32-bit libraries have been built, this
|
||||
option causes the 32-bit library to be used. If only the 32-bit library has been
|
||||
built, this is the default (so has no effect). If only the 8-bit or the 16-bit
|
||||
library has been built, this option causes an error.
|
||||
If the 32-bit library has been built, this option causes it to be used. If only
|
||||
the 32-bit library has been built, this is the default. If the 32-bit library
|
||||
has not been built, this option causes an error.
|
||||
.TP 10
|
||||
\fB-b\fP
|
||||
Behave as if each pattern has the \fB/B\fP (show byte code) modifier; the
|
||||
@ -1155,6 +1153,6 @@ Cambridge CB2 3QH, England.
|
||||
.rs
|
||||
.sp
|
||||
.nf
|
||||
Last updated: 23 February 2017
|
||||
Copyright (c) 1997-2017 University of Cambridge.
|
||||
Last updated: 10 February 2020
|
||||
Copyright (c) 1997-2020 University of Cambridge.
|
||||
.fi
|
||||
|
@ -47,15 +47,15 @@ INPUT DATA FORMAT
|
||||
PCRE's 8-BIT, 16-BIT AND 32-BIT LIBRARIES
|
||||
|
||||
From release 8.30, two separate PCRE libraries can be built. The origi-
|
||||
nal one supports 8-bit character strings, whereas the newer 16-bit
|
||||
library supports character strings encoded in 16-bit units. From
|
||||
release 8.32, a third library can be built, supporting character
|
||||
strings encoded in 32-bit units. The pcretest program can be used to
|
||||
test all three libraries. However, it is itself still an 8-bit program,
|
||||
reading 8-bit input and writing 8-bit output. When testing the 16-bit
|
||||
or 32-bit library, the patterns and data strings are converted to 16-
|
||||
or 32-bit format before being passed to the PCRE library functions.
|
||||
Results are converted to 8-bit for output.
|
||||
nal one supports 8-bit character strings, whereas the newer 16-bit li-
|
||||
brary supports character strings encoded in 16-bit units. From release
|
||||
8.32, a third library can be built, supporting character strings en-
|
||||
coded in 32-bit units. The pcretest program can be used to test all
|
||||
three libraries. However, it is itself still an 8-bit program, reading
|
||||
8-bit input and writing 8-bit output. When testing the 16-bit or
|
||||
32-bit library, the patterns and data strings are converted to 16- or
|
||||
32-bit format before being passed to the PCRE library functions. Re-
|
||||
sults are converted to 8-bit for output.
|
||||
|
||||
References to functions and structures of the form pcre[16|32]_xx below
|
||||
mean "pcre_xx when using the 8-bit library, pcre16_xx when using the
|
||||
@ -64,30 +64,27 @@ PCRE's 8-BIT, 16-BIT AND 32-BIT LIBRARIES
|
||||
|
||||
COMMAND LINE OPTIONS
|
||||
|
||||
-8 If both the 8-bit library has been built, this option causes
|
||||
the 8-bit library to be used (which is the default); if the
|
||||
8-bit library has not been built, this option causes an
|
||||
error.
|
||||
-8 If the 8-bit library has been built, this option causes it to
|
||||
be used (this is the default). If the 8-bit library has not
|
||||
been built, this option causes an error.
|
||||
|
||||
-16 If both the 8-bit or the 32-bit, and the 16-bit libraries
|
||||
have been built, this option causes the 16-bit library to be
|
||||
used. If only the 16-bit library has been built, this is the
|
||||
default (so has no effect). If only the 8-bit or the 32-bit
|
||||
library has been built, this option causes an error.
|
||||
-16 If the 16-bit library has been built, this option causes it
|
||||
to be used. If only the 16-bit library has been built, this
|
||||
is the default. If the 16-bit library has not been built,
|
||||
this option causes an error.
|
||||
|
||||
-32 If both the 8-bit or the 16-bit, and the 32-bit libraries
|
||||
have been built, this option causes the 32-bit library to be
|
||||
used. If only the 32-bit library has been built, this is the
|
||||
default (so has no effect). If only the 8-bit or the 16-bit
|
||||
library has been built, this option causes an error.
|
||||
-32 If the 32-bit library has been built, this option causes it
|
||||
to be used. If only the 32-bit library has been built, this
|
||||
is the default. If the 32-bit library has not been built,
|
||||
this option causes an error.
|
||||
|
||||
-b Behave as if each pattern has the /B (show byte code) modi-
|
||||
fier; the internal form is output after compilation.
|
||||
|
||||
-C Output the version number of the PCRE library, and all avail-
|
||||
able information about the optional features that are
|
||||
included, and then exit with zero exit code. All other
|
||||
options are ignored.
|
||||
able information about the optional features that are in-
|
||||
cluded, and then exit with zero exit code. All other options
|
||||
are ignored.
|
||||
|
||||
-C option Output information about a specific build-time option, then
|
||||
exit. This functionality is intended for use in scripts such
|
||||
@ -142,8 +139,8 @@ COMMAND LINE OPTIONS
|
||||
repeatedly with different limits.
|
||||
|
||||
-m Output the size of each compiled pattern after it has been
|
||||
compiled. This is equivalent to adding /M to each regular
|
||||
expression. The size is given in bytes for both libraries.
|
||||
compiled. This is equivalent to adding /M to each regular ex-
|
||||
pression. The size is given in bytes for both libraries.
|
||||
|
||||
-O Behave as if each pattern has the /O modifier, that is dis-
|
||||
able auto-possessification for all patterns.
|
||||
@ -188,22 +185,22 @@ COMMAND LINE OPTIONS
|
||||
after a match or no match when JIT-compiled code was actually
|
||||
used.
|
||||
|
||||
Note that there are pattern options that can override -s,
|
||||
either specifying no studying at all, or suppressing JIT com-
|
||||
pilation.
|
||||
Note that there are pattern options that can override -s, ei-
|
||||
ther specifying no studying at all, or suppressing JIT compi-
|
||||
lation.
|
||||
|
||||
If the /I or /D option is present on a pattern (requesting
|
||||
output about the compiled pattern), information about the
|
||||
result of studying is not included when studying is caused
|
||||
only by -s and neither -i nor -d is present on the command
|
||||
line. This behaviour means that the output from tests that
|
||||
are run with and without -s should be identical, except when
|
||||
options that output information about the actual running of a
|
||||
match are set.
|
||||
output about the compiled pattern), information about the re-
|
||||
sult of studying is not included when studying is caused only
|
||||
by -s and neither -i nor -d is present on the command line.
|
||||
This behaviour means that the output from tests that are run
|
||||
with and without -s should be identical, except when options
|
||||
that output information about the actual running of a match
|
||||
are set.
|
||||
|
||||
The -M, -t, and -tm options, which give information about
|
||||
resources used, are likely to produce different output with
|
||||
and without -s. Output may also differ if the /C option is
|
||||
The -M, -t, and -tm options, which give information about re-
|
||||
sources used, are likely to produce different output with and
|
||||
without -s. Output may also differ if the /C option is
|
||||
present on an individual pattern. This uses callouts to trace
|
||||
the the matching process, and this may be different between
|
||||
studied and non-studied patterns. If the pattern contains
|
||||
@ -397,9 +394,9 @@ PATTERN MODIFIERS
|
||||
/^abc/m<CRLF>
|
||||
|
||||
As well as turning on the PCRE_UTF8/16/32 option, the /8 modifier
|
||||
causes all non-printing characters in output strings to be printed
|
||||
using the \x{hh...} notation. Otherwise, those less than 0x100 are out-
|
||||
put in hex without the curly brackets.
|
||||
causes all non-printing characters in output strings to be printed us-
|
||||
ing the \x{hh...} notation. Otherwise, those less than 0x100 are output
|
||||
in hex without the curly brackets.
|
||||
|
||||
Full details of the PCRE options are given in the pcreapi documenta-
|
||||
tion.
|
||||
@ -410,11 +407,11 @@ PATTERN MODIFIERS
|
||||
requested by the /g or /G modifier. After finding a match, PCRE is
|
||||
called again to search the remainder of the subject string. The differ-
|
||||
ence between /g and /G is that the former uses the startoffset argument
|
||||
to pcre[16|32]_exec() to start searching at a new point within the
|
||||
entire string (which is in effect what Perl does), whereas the latter
|
||||
to pcre[16|32]_exec() to start searching at a new point within the en-
|
||||
tire string (which is in effect what Perl does), whereas the latter
|
||||
passes over a shortened substring. This makes a difference to the
|
||||
matching process if the pattern begins with a lookbehind assertion
|
||||
(including \b or \B).
|
||||
matching process if the pattern begins with a lookbehind assertion (in-
|
||||
cluding \b or \B).
|
||||
|
||||
If any call to pcre[16|32]_exec() in a /g or /G sequence matches an
|
||||
empty string, the next call is done with the PCRE_NOTEMPTY_ATSTART and
|
||||
@ -431,11 +428,11 @@ PATTERN MODIFIERS
|
||||
There are yet more modifiers for controlling the way pcretest operates.
|
||||
|
||||
The /+ modifier requests that as well as outputting the substring that
|
||||
matched the entire pattern, pcretest 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. If the + modi-
|
||||
fier appears twice, the same action is taken for captured substrings.
|
||||
In each case the remainder is output on the following line with a plus
|
||||
matched the entire pattern, pcretest should in addition output the re-
|
||||
mainder of the subject string. This is useful for tests where the sub-
|
||||
ject contains multiple copies of the same substring. If the + modifier
|
||||
appears twice, the same action is taken for captured substrings. In
|
||||
each case the remainder is output on the following line with a plus
|
||||
character following the capture number. Note that this modifier must
|
||||
not immediately follow the /S modifier because /S+ and /S++ have other
|
||||
meanings.
|
||||
@ -471,13 +468,13 @@ PATTERN MODIFIERS
|
||||
and so on). It does this by calling pcre[16|32]_fullinfo() after com-
|
||||
piling a pattern. If the pattern is studied, the results of that are
|
||||
also output. In this output, the word "char" means a non-UTF character,
|
||||
that is, the value of a single data item (8-bit, 16-bit, or 32-bit,
|
||||
depending on the library that is being tested).
|
||||
that is, the value of a single data item (8-bit, 16-bit, or 32-bit, de-
|
||||
pending on the library that is being tested).
|
||||
|
||||
The /K modifier requests pcretest to show names from backtracking con-
|
||||
trol verbs that are returned from calls to pcre[16|32]_exec(). It
|
||||
causes pcretest to create a pcre[16|32]_extra block if one has not
|
||||
already been created by a call to pcre[16|32]_study(), and to set the
|
||||
causes pcretest to create a pcre[16|32]_extra block if one has not al-
|
||||
ready been created by a call to pcre[16|32]_study(), and to set the
|
||||
PCRE_EXTRA_MARK flag and the mark field within it, every time that
|
||||
pcre[16|32]_exec() is called. If the variable that the mark field
|
||||
points to is non-NULL for a match, non-match, or partial match,
|
||||
@ -494,8 +491,8 @@ PATTERN MODIFIERS
|
||||
pcre[16|32]_maketables() is called to build a set of character tables
|
||||
for the locale, and this is then passed to pcre[16|32]_compile() when
|
||||
compiling the regular expression. Without an /L (or /T) modifier, NULL
|
||||
is passed as the tables pointer; that is, /L applies only to the
|
||||
expression on which it appears.
|
||||
is passed as the tables pointer; that is, /L applies only to the ex-
|
||||
pression on which it appears.
|
||||
|
||||
The /M modifier causes the size in bytes of the memory block used to
|
||||
hold the compiled pattern to be output. This does not include the size
|
||||
@ -508,9 +505,9 @@ PATTERN MODIFIERS
|
||||
external function that is passed to PCRE and used for stack checking
|
||||
during compilation (see the pcreapi documentation for details).
|
||||
|
||||
The /S modifier causes pcre[16|32]_study() to be called after the
|
||||
expression has been compiled, and the results used when the expression
|
||||
is matched. There are a number of qualifying characters that may follow
|
||||
The /S modifier causes pcre[16|32]_study() to be called after the ex-
|
||||
pression has been compiled, and the results used when the expression is
|
||||
matched. There are a number of qualifying characters that may follow
|
||||
/S. They may appear in any order.
|
||||
|
||||
If /S is followed by an exclamation mark, pcre[16|32]_study() is called
|
||||
@ -582,8 +579,8 @@ PATTERN MODIFIERS
|
||||
/W REG_UCP ) the POSIX standard
|
||||
/8 REG_UTF8 )
|
||||
|
||||
The /+ modifier works as described above. All other modifiers are
|
||||
ignored.
|
||||
The /+ modifier works as described above. All other modifiers are ig-
|
||||
nored.
|
||||
|
||||
Locking out certain modifiers
|
||||
|
||||
@ -611,10 +608,10 @@ PATTERN MODIFIERS
|
||||
< forbid <JS><cr>
|
||||
|
||||
There must be a single space between < and "forbid" for this feature to
|
||||
be recognised. If there is not, the line is interpreted either as a
|
||||
request to re-load a pre-compiled pattern (see "SAVING AND RELOADING
|
||||
COMPILED PATTERNS" below) or, if there is a another < character, as a
|
||||
pattern that uses < as its delimiter.
|
||||
be recognised. If there is not, the line is interpreted either as a re-
|
||||
quest to re-load a pre-compiled pattern (see "SAVING AND RELOADING COM-
|
||||
PILED PATTERNS" below) or, if there is a another < character, as a pat-
|
||||
tern that uses < as its delimiter.
|
||||
|
||||
|
||||
DATA LINES
|
||||
@ -726,8 +723,8 @@ DATA LINES
|
||||
makes it possible to construct invalid UTF-32 sequences for testing
|
||||
purposes.
|
||||
|
||||
The escapes that specify line ending sequences are literal strings,
|
||||
exactly as shown. No more than one newline setting should be present in
|
||||
The escapes that specify line ending sequences are literal strings, ex-
|
||||
actly as shown. No more than one newline setting should be present in
|
||||
any data line.
|
||||
|
||||
A backslash followed by anything else just escapes the anything else.
|
||||
@ -744,8 +741,8 @@ DATA LINES
|
||||
different values in the match_limit and match_limit_recursion fields of
|
||||
the pcre[16|32]_extra data structure, until it finds the minimum num-
|
||||
bers for each parameter that allow pcre[16|32]_exec() to complete with-
|
||||
out error. Because this is testing a specific feature of the normal
|
||||
interpretive pcre[16|32]_exec() execution, the use of any JIT optimiza-
|
||||
out error. Because this is testing a specific feature of the normal in-
|
||||
terpretive pcre[16|32]_exec() execution, the use of any JIT optimiza-
|
||||
tion that might have been set up by the /S+ qualifier of -s+ option is
|
||||
disabled.
|
||||
|
||||
@ -755,27 +752,27 @@ DATA LINES
|
||||
numbers of matching possibilities, it can become large very quickly
|
||||
with increasing length of subject string. The match_limit_recursion
|
||||
number is a measure of how much stack (or, if PCRE is compiled with
|
||||
NO_RECURSE, how much heap) memory is needed to complete the match
|
||||
attempt.
|
||||
NO_RECURSE, how much heap) memory is needed to complete the match at-
|
||||
tempt.
|
||||
|
||||
When \O is used, the value specified may be higher or lower than the
|
||||
size set by the -O command line option (or defaulted to 45); \O applies
|
||||
only to the call of pcre[16|32]_exec() for the line in which it
|
||||
appears.
|
||||
only to the call of pcre[16|32]_exec() for the line in which it ap-
|
||||
pears.
|
||||
|
||||
If the /P modifier was present on the pattern, causing the POSIX wrap-
|
||||
per API to be used, the only option-setting sequences that have any
|
||||
effect are \B, \N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and
|
||||
REG_NOTEOL, respectively, to be passed to regexec().
|
||||
per API to be used, the only option-setting sequences that have any ef-
|
||||
fect are \B, \N, and \Z, causing REG_NOTBOL, REG_NOTEMPTY, and REG_NO-
|
||||
TEOL, respectively, to be passed to regexec().
|
||||
|
||||
|
||||
THE ALTERNATIVE MATCHING FUNCTION
|
||||
|
||||
By default, pcretest uses the standard PCRE matching function,
|
||||
pcre[16|32]_exec() to match each data line. PCRE also supports an
|
||||
alternative matching function, pcre[16|32]_dfa_test(), which operates
|
||||
in a different way, and has some restrictions. The differences between
|
||||
the two functions are described in the pcrematching documentation.
|
||||
pcre[16|32]_exec() to match each data line. PCRE also supports an al-
|
||||
ternative matching function, pcre[16|32]_dfa_test(), which operates in
|
||||
a different way, and has some restrictions. The differences between the
|
||||
two functions are described in the pcrematching documentation.
|
||||
|
||||
If a data line contains the \D escape sequence, or if the command line
|
||||
contains the -dfa option, the alternative matching function is used.
|
||||
@ -793,16 +790,15 @@ DEFAULT OUTPUT FROM PCRETEST
|
||||
that pcre[16|32]_exec() returns, starting with number 0 for the string
|
||||
that matched the whole pattern. Otherwise, it outputs "No match" when
|
||||
the return is PCRE_ERROR_NOMATCH, and "Partial match:" followed by the
|
||||
partially matching substring when pcre[16|32]_exec() returns
|
||||
PCRE_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, pcretest outputs the PCRE negative
|
||||
error number and a short descriptive phrase. If the error is a failed
|
||||
UTF string check, the offset of the start of the failing character and
|
||||
the reason code are also output, provided that the size of the output
|
||||
vector is at least two. Here is an example of an interactive pcretest
|
||||
run.
|
||||
partially matching substring when pcre[16|32]_exec() returns PCRE_ER-
|
||||
ROR_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, pcretest outputs the PCRE negative error number and a
|
||||
short descriptive phrase. If the error is a failed UTF string check,
|
||||
the offset of the start of the failing character and the reason code
|
||||
are also output, provided that the size of the output vector is at
|
||||
least two. Here is an example of an interactive pcretest run.
|
||||
|
||||
$ pcretest
|
||||
PCRE version 8.13 2011-04-30
|
||||
@ -892,9 +888,9 @@ OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
|
||||
(Using the normal matching function on this data finds only "tang".)
|
||||
The longest matching string is always given first (and numbered zero).
|
||||
After a PCRE_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 characters before the actual match start if a lookbehind asser-
|
||||
lowed by the partially matching substring. (Note that this is the en-
|
||||
tire substring that was inspected during the partial match; it may in-
|
||||
clude characters before the actual match start if a lookbehind asser-
|
||||
tion, \K, \b, or \B was involved.)
|
||||
|
||||
If /g is present on the pattern, the search for further matches resumes
|
||||
@ -909,9 +905,9 @@ OUTPUT FROM THE ALTERNATIVE MATCHING FUNCTION
|
||||
1: tan
|
||||
0: tan
|
||||
|
||||
Since the matching function does not support substring capture, the
|
||||
escape sequences that are concerned with captured substrings are not
|
||||
relevant.
|
||||
Since the matching function does not support substring capture, the es-
|
||||
cape sequences that are concerned with captured substrings are not rel-
|
||||
evant.
|
||||
|
||||
|
||||
RESTARTING AFTER A PARTIAL MATCH
|
||||
@ -942,9 +938,9 @@ CALLOUTS
|
||||
--->pqrabcdef
|
||||
0 ^ ^ \d
|
||||
|
||||
This output indicates that callout number 0 occurred for a match
|
||||
attempt starting at the fourth character of the subject string, when
|
||||
the pointer was at the seventh character of the data, and when the next
|
||||
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 of the data, and when the next
|
||||
pattern item was \d. Just one circumflex is output if the start and
|
||||
current positions are the same.
|
||||
|
||||
@ -963,8 +959,8 @@ CALLOUTS
|
||||
0: E*
|
||||
|
||||
If a pattern contains (*MARK) items, an additional line is output when-
|
||||
ever a change of latest mark is passed to the callout function. For
|
||||
example:
|
||||
ever a change of latest mark is passed to the callout function. For ex-
|
||||
ample:
|
||||
|
||||
re> /a(*MARK:X)bc/C
|
||||
data> abc
|
||||
@ -999,8 +995,8 @@ NON-PRINTING CHARACTERS
|
||||
|
||||
When pcretest 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 /L modifier). In this case, the
|
||||
isprint() function to distinguish printing and non-printing characters.
|
||||
set for the pattern (using the /L modifier). In this case, the is-
|
||||
print() function to distinguish printing and non-printing characters.
|
||||
|
||||
|
||||
SAVING AND RELOADING COMPILED PATTERNS
|
||||
@ -1020,14 +1016,14 @@ SAVING AND RELOADING COMPILED PATTERNS
|
||||
studied with JIT optimization, the JIT data cannot be saved.
|
||||
|
||||
The data that is written is binary. The first eight bytes are the
|
||||
length of the compiled pattern data followed by the length of the
|
||||
optional study data, each written as four bytes in big-endian order
|
||||
(most significant byte first). If there is no study data (either the
|
||||
pattern was not studied, or studying did not return any data), the sec-
|
||||
ond length is zero. The lengths are followed by an exact copy of the
|
||||
compiled pattern. If there is additional study data, this (excluding
|
||||
any JIT data) follows immediately after the compiled pattern. After
|
||||
writing the file, pcretest expects to read a new pattern.
|
||||
length of the compiled pattern data followed by the length of the op-
|
||||
tional study data, each written as four bytes in big-endian order (most
|
||||
significant byte first). If there is no study data (either the pattern
|
||||
was not studied, or studying did not return any data), the second
|
||||
length is zero. The lengths are followed by an exact copy of the com-
|
||||
piled pattern. If there is additional study data, this (excluding any
|
||||
JIT data) follows immediately after the compiled pattern. After writing
|
||||
the file, pcretest expects to read a new pattern.
|
||||
|
||||
A saved pattern can be reloaded into pcretest by specifying < and a
|
||||
file name instead of a pattern. There must be no space between < and
|
||||
@ -1066,10 +1062,10 @@ SAVING AND RELOADING COMPILED PATTERNS
|
||||
ing and experimentation. It is not intended for production use because
|
||||
only a single pattern can be written to a file. Furthermore, there is
|
||||
no facility for supplying custom character tables for use with a
|
||||
reloaded pattern. If the original pattern was compiled with custom
|
||||
tables, an attempt to match a subject string using a reloaded pattern
|
||||
is likely to cause pcretest to crash. Finally, if you attempt to load
|
||||
a file that is not in the correct format, the result is undefined.
|
||||
reloaded pattern. If the original pattern was compiled with custom ta-
|
||||
bles, an attempt to match a subject string using a reloaded pattern is
|
||||
likely to cause pcretest to crash. Finally, if you attempt to load a
|
||||
file that is not in the correct format, the result is undefined.
|
||||
|
||||
|
||||
SEE ALSO
|
||||
@ -1087,5 +1083,5 @@ AUTHOR
|
||||
|
||||
REVISION
|
||||
|
||||
Last updated: 23 February 2017
|
||||
Copyright (c) 1997-2017 University of Cambridge.
|
||||
Last updated: 10 February 2020
|
||||
Copyright (c) 1997-2020 University of Cambridge.
|
||||
|
1
pcre/m4/libtool.m4
vendored
1
pcre/m4/libtool.m4
vendored
@ -728,7 +728,6 @@ _LT_CONFIG_SAVE_COMMANDS([
|
||||
cat <<_LT_EOF >> "$cfgfile"
|
||||
#! $SHELL
|
||||
# Generated automatically by $as_me ($PACKAGE) $VERSION
|
||||
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
|
||||
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
|
||||
|
||||
# Provide generalized library-building support services.
|
||||
|
@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
/* The current PCRE version information. */
|
||||
|
||||
#define PCRE_MAJOR 8
|
||||
#define PCRE_MINOR 43
|
||||
#define PCRE_MINOR 44
|
||||
#define PCRE_PRERELEASE
|
||||
#define PCRE_DATE 2019-02-23
|
||||
#define PCRE_DATE 2020-02-12
|
||||
|
||||
/* When an application links to a PCRE DLL in Windows, the symbols that are
|
||||
imported have to be identified as such. When building PCRE, the appropriate
|
||||
|
@ -6,7 +6,7 @@
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2018 University of Cambridge
|
||||
Copyright (c) 1997-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -68,7 +68,7 @@ COMPILE_PCREx macro will already be appropriately set. */
|
||||
|
||||
/* Macro for setting individual bits in class bitmaps. */
|
||||
|
||||
#define SETBIT(a,b) a[(b)/8] |= (1 << ((b)&7))
|
||||
#define SETBIT(a,b) a[(b)/8] |= (1U << ((b)&7))
|
||||
|
||||
/* Maximum length value to check against when making sure that the integer that
|
||||
holds the compiled pattern length does not overflow. We make it a bit less than
|
||||
@ -129,8 +129,8 @@ overrun before it actually does run off the end of the data block. */
|
||||
|
||||
/* Private flags added to firstchar and reqchar. */
|
||||
|
||||
#define REQ_CASELESS (1 << 0) /* Indicates caselessness */
|
||||
#define REQ_VARY (1 << 1) /* Reqchar followed non-literal item */
|
||||
#define REQ_CASELESS (1U << 0) /* Indicates caselessness */
|
||||
#define REQ_VARY (1U << 1) /* Reqchar followed non-literal item */
|
||||
/* Negative values for the firstchar and reqchar flags */
|
||||
#define REQ_UNSET (-2)
|
||||
#define REQ_NONE (-1)
|
||||
@ -3611,7 +3611,7 @@ for(;;)
|
||||
if (chr > 255) break;
|
||||
class_bitset = (pcre_uint8 *)
|
||||
((list_ptr == list ? code : base_end) - list_ptr[2]);
|
||||
if ((class_bitset[chr >> 3] & (1 << (chr & 7))) != 0) return FALSE;
|
||||
if ((class_bitset[chr >> 3] & (1U << (chr & 7))) != 0) return FALSE;
|
||||
break;
|
||||
|
||||
#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
|
||||
@ -7130,17 +7130,19 @@ for (;; ptr++)
|
||||
int n = 0;
|
||||
ptr++;
|
||||
while(IS_DIGIT(*ptr))
|
||||
n = n * 10 + *ptr++ - CHAR_0;
|
||||
if (*ptr != CHAR_RIGHT_PARENTHESIS)
|
||||
{
|
||||
*errorcodeptr = ERR39;
|
||||
goto FAILED;
|
||||
}
|
||||
n = n * 10 + *ptr++ - CHAR_0;
|
||||
if (n > 255)
|
||||
{
|
||||
*errorcodeptr = ERR38;
|
||||
goto FAILED;
|
||||
}
|
||||
}
|
||||
if (*ptr != CHAR_RIGHT_PARENTHESIS)
|
||||
{
|
||||
*errorcodeptr = ERR39;
|
||||
goto FAILED;
|
||||
}
|
||||
*code++ = n;
|
||||
PUT(code, 0, (int)(ptr - cd->start_pattern + 1)); /* Pattern offset */
|
||||
PUT(code, LINK_SIZE, 0); /* Default length */
|
||||
@ -7456,7 +7458,7 @@ for (;; ptr++)
|
||||
{
|
||||
open_capitem *oc;
|
||||
recno = GET2(slot, 0);
|
||||
cd->backref_map |= (recno < 32)? (1 << recno) : 1;
|
||||
cd->backref_map |= (recno < 32)? (1U << recno) : 1;
|
||||
if (recno > cd->top_backref) cd->top_backref = recno;
|
||||
|
||||
/* Check to see if this back reference is recursive, that it, it
|
||||
@ -8067,7 +8069,7 @@ for (;; ptr++)
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
|
||||
PUT2INC(code, 0, recno);
|
||||
cd->backref_map |= (recno < 32)? (1 << recno) : 1;
|
||||
cd->backref_map |= (recno < 32)? (1U << recno) : 1;
|
||||
if (recno > cd->top_backref) cd->top_backref = recno;
|
||||
|
||||
/* Check to see if this back reference is recursive, that it, it
|
||||
@ -8680,7 +8682,7 @@ do {
|
||||
op == OP_SCBRA || op == OP_SCBRAPOS)
|
||||
{
|
||||
int n = GET2(scode, 1+LINK_SIZE);
|
||||
int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
|
||||
int new_map = bracket_map | ((n < 32)? (1U << n) : 1);
|
||||
if (!is_anchored(scode, new_map, cd, atomcount)) return FALSE;
|
||||
}
|
||||
|
||||
@ -8808,7 +8810,7 @@ do {
|
||||
op == OP_SCBRA || op == OP_SCBRAPOS)
|
||||
{
|
||||
int n = GET2(scode, 1+LINK_SIZE);
|
||||
int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
|
||||
int new_map = bracket_map | ((n < 32)? (1U << n) : 1);
|
||||
if (!is_startline(scode, new_map, cd, atomcount, inassert)) return FALSE;
|
||||
}
|
||||
|
||||
|
@ -3938,10 +3938,10 @@ static sljit_s32 character_to_int32(pcre_uchar chr)
|
||||
sljit_s32 value = (sljit_s32)chr;
|
||||
#if defined COMPILE_PCRE8
|
||||
#define SSE2_COMPARE_TYPE_INDEX 0
|
||||
return (value << 24) | (value << 16) | (value << 8) | value;
|
||||
return ((unsigned int)value << 24) | ((unsigned int)value << 16) | ((unsigned int)value << 8) | (unsigned int)value;
|
||||
#elif defined COMPILE_PCRE16
|
||||
#define SSE2_COMPARE_TYPE_INDEX 1
|
||||
return (value << 16) | value;
|
||||
return ((unsigned int)value << 16) | value;
|
||||
#elif defined COMPILE_PCRE32
|
||||
#define SSE2_COMPARE_TYPE_INDEX 2
|
||||
return value;
|
||||
@ -8507,7 +8507,7 @@ if (opcode == OP_ONCE)
|
||||
/* We temporarily encode the needs_control_head in the lowest bit.
|
||||
Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns
|
||||
the same value for small signed numbers (including negative numbers). */
|
||||
BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
|
||||
BACKTRACK_AS(bracket_backtrack)->u.framesize = ((unsigned int)BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
|
||||
}
|
||||
return cc + repeat_length;
|
||||
}
|
||||
|
@ -66,7 +66,8 @@ Arg RE::no_arg((void*)NULL);
|
||||
// inclusive test if we ever needed it. (Note that not only the
|
||||
// __attribute__ syntax, but also __USER_LABEL_PREFIX__, are
|
||||
// gnu-specific.)
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3 && defined(__ELF__) && !defined(__INTEL_COMPILER)
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3 && defined(__ELF__) \
|
||||
&& !defined(__INTEL_COMPILER) && !defined(__LCC__)
|
||||
# define ULP_AS_STRING(x) ULP_AS_STRING_INTERNAL(x)
|
||||
# define ULP_AS_STRING_INTERNAL(x) #x
|
||||
# define USER_LABEL_PREFIX_STR ULP_AS_STRING(__USER_LABEL_PREFIX__)
|
||||
@ -91,6 +92,7 @@ static const char *start_options[] = {
|
||||
"(*LIMIT_RECURSION=",
|
||||
"(*LIMIT_MATCH=",
|
||||
"(*CRLF)",
|
||||
"(*LF)",
|
||||
"(*CR)",
|
||||
"(*BSR_UNICODE)",
|
||||
"(*BSR_ANYCRLF)",
|
||||
|
@ -6,7 +6,7 @@
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2018 University of Cambridge
|
||||
Copyright (c) 1997-2020 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -298,6 +298,7 @@ if (preg->re_pcre == NULL)
|
||||
(void)pcre_fullinfo((const pcre *)preg->re_pcre, NULL, PCRE_INFO_CAPTURECOUNT,
|
||||
&re_nsub);
|
||||
preg->re_nsub = (size_t)re_nsub;
|
||||
preg->re_erroffset = (size_t)(-1); /* No meaning after successful compile */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -335,8 +336,6 @@ if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
|
||||
if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;
|
||||
if ((eflags & REG_NOTEMPTY) != 0) options |= PCRE_NOTEMPTY;
|
||||
|
||||
((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */
|
||||
|
||||
/* When no string data is being returned, or no vector has been passed in which
|
||||
to put it, ensure that nmatch is zero. Otherwise, ensure the vector for holding
|
||||
the return data is large enough. */
|
||||
|
@ -500,7 +500,7 @@ enum {
|
||||
#if (defined (SUPPORT_PCRE8) + defined (SUPPORT_PCRE16) + \
|
||||
defined (SUPPORT_PCRE32)) >= 2
|
||||
|
||||
#define CHAR_SIZE (1 << pcre_mode)
|
||||
#define CHAR_SIZE (1U << pcre_mode)
|
||||
|
||||
/* There doesn't seem to be an easy way of writing these macros that can cope
|
||||
with the 3 pairs of bit sizes plus all three bit sizes. So just handle all the
|
||||
@ -4443,7 +4443,7 @@ while (!done)
|
||||
|
||||
/* If there is study data, write it. */
|
||||
|
||||
if (extra != NULL)
|
||||
if (extra != NULL && (extra->flags & PCRE_EXTRA_STUDY_DATA) != 0)
|
||||
{
|
||||
if (fwrite(extra->study_data, 1, true_study_size, f) <
|
||||
true_study_size)
|
||||
@ -4735,7 +4735,7 @@ while (!done)
|
||||
if (isdigit(*p)) /* Set copy string */
|
||||
{
|
||||
while(isdigit(*p)) n = n * 10 + *p++ - '0';
|
||||
copystrings |= 1 << n;
|
||||
copystrings |= 1U << n;
|
||||
}
|
||||
else if (isalnum(*p))
|
||||
{
|
||||
@ -4798,7 +4798,7 @@ while (!done)
|
||||
if (isdigit(*p))
|
||||
{
|
||||
while(isdigit(*p)) n = n * 10 + *p++ - '0';
|
||||
getstrings |= 1 << n;
|
||||
getstrings |= 1U << n;
|
||||
}
|
||||
else if (isalnum(*p))
|
||||
{
|
||||
@ -5335,7 +5335,7 @@ while (!done)
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if ((copystrings & (1 << i)) != 0)
|
||||
if ((copystrings & (1U << i)) != 0)
|
||||
{
|
||||
int rc;
|
||||
char copybuffer[256];
|
||||
@ -5400,7 +5400,7 @@ while (!done)
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if ((getstrings & (1 << i)) != 0)
|
||||
if ((getstrings & (1U << i)) != 0)
|
||||
{
|
||||
int rc;
|
||||
const char *substring;
|
||||
|
@ -214,6 +214,10 @@
|
||||
#define SLJIT_MEMCPY(dest, src, len) memcpy(dest, src, len)
|
||||
#endif
|
||||
|
||||
#ifndef SLJIT_MEMMOVE
|
||||
#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len)
|
||||
#endif
|
||||
|
||||
#ifndef SLJIT_ZEROMEM
|
||||
#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len)
|
||||
#endif
|
||||
|
@ -118,10 +118,20 @@ static SLJIT_INLINE int get_map_jit_flag()
|
||||
if (map_jit_flag == -1) {
|
||||
struct utsname name;
|
||||
|
||||
map_jit_flag = 0;
|
||||
uname(&name);
|
||||
|
||||
/* Kernel version for 10.14.0 (Mojave) */
|
||||
map_jit_flag = (atoi(name.release) >= 18) ? MAP_JIT : 0;
|
||||
if (atoi(name.release) >= 18) {
|
||||
/* Only use MAP_JIT if a hardened runtime is used, because MAP_JIT is incompatible with fork(). */
|
||||
void *ptr = mmap(NULL, getpagesize(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
|
||||
if (ptr == MAP_FAILED) {
|
||||
map_jit_flag = MAP_JIT;
|
||||
} else {
|
||||
munmap(ptr, getpagesize());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return map_jit_flag;
|
||||
@ -137,6 +147,7 @@ static SLJIT_INLINE int get_map_jit_flag()
|
||||
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
||||
{
|
||||
void *retval;
|
||||
const int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
|
||||
|
||||
#ifdef MAP_ANON
|
||||
|
||||
@ -146,16 +157,25 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
|
||||
flags |= get_map_jit_flag();
|
||||
#endif
|
||||
|
||||
retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, flags, -1, 0);
|
||||
retval = mmap(NULL, size, prot, flags, -1, 0);
|
||||
#else /* !MAP_ANON */
|
||||
if (dev_zero < 0) {
|
||||
if (open_dev_zero())
|
||||
return NULL;
|
||||
}
|
||||
retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0);
|
||||
retval = mmap(NULL, size, prot, MAP_PRIVATE, dev_zero, 0);
|
||||
#endif /* MAP_ANON */
|
||||
|
||||
return (retval != MAP_FAILED) ? retval : NULL;
|
||||
if (retval == MAP_FAILED)
|
||||
retval = NULL;
|
||||
else {
|
||||
if (mprotect(retval, size, prot) < 0) {
|
||||
munmap(retval, size);
|
||||
retval = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
|
||||
|
@ -144,6 +144,7 @@
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
# define PATCH_MD 0x10
|
||||
#endif
|
||||
# define TYPE_SHIFT 13
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
||||
@ -201,15 +202,16 @@
|
||||
# define IS_CALL 0x010
|
||||
# define IS_BIT26_COND 0x020
|
||||
# define IS_BIT16_COND 0x040
|
||||
# define IS_BIT23_COND 0x080
|
||||
|
||||
# define IS_COND (IS_BIT26_COND | IS_BIT16_COND)
|
||||
# define IS_COND (IS_BIT26_COND | IS_BIT16_COND | IS_BIT23_COND)
|
||||
|
||||
# define PATCH_B 0x080
|
||||
# define PATCH_J 0x100
|
||||
# define PATCH_B 0x100
|
||||
# define PATCH_J 0x200
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
# define PATCH_ABS32 0x200
|
||||
# define PATCH_ABS48 0x400
|
||||
# define PATCH_ABS32 0x400
|
||||
# define PATCH_ABS48 0x800
|
||||
#endif
|
||||
|
||||
/* instruction types */
|
||||
@ -520,6 +522,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw
|
||||
}
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label)
|
||||
{
|
||||
if (SLJIT_LIKELY(!!put_label))
|
||||
put_label->label = label;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
@ -619,6 +627,30 @@ static SLJIT_INLINE sljit_s32 get_arg_count(sljit_s32 arg_types)
|
||||
return arg_count;
|
||||
}
|
||||
|
||||
#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
|
||||
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)
|
||||
{
|
||||
sljit_uw result = ~(sljit_uw)0;
|
||||
|
||||
if (label)
|
||||
result = label->size;
|
||||
|
||||
if (jump && jump->addr < result)
|
||||
result = jump->addr;
|
||||
|
||||
if (const_ && const_->addr < result)
|
||||
result = const_->addr;
|
||||
|
||||
if (put_label && put_label->addr < result)
|
||||
result = put_label->addr;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* !SLJIT_CONFIG_X86 */
|
||||
|
||||
static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
@ -686,6 +718,19 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp
|
||||
compiler->last_const = const_;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void set_put_label(struct sljit_put_label *put_label, struct sljit_compiler *compiler, sljit_uw offset)
|
||||
{
|
||||
put_label->next = NULL;
|
||||
put_label->label = NULL;
|
||||
put_label->addr = compiler->size - offset;
|
||||
put_label->flags = 0;
|
||||
if (compiler->last_put_label)
|
||||
compiler->last_put_label->next = put_label;
|
||||
else
|
||||
compiler->put_labels = put_label;
|
||||
compiler->last_put_label = put_label;
|
||||
}
|
||||
|
||||
#define ADDRESSING_DEPENDS_ON(exp, reg) \
|
||||
(((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))
|
||||
|
||||
@ -1904,6 +1949,21 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
FUNCTION_CHECK_DST(dst, dstw, 0);
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
||||
fprintf(compiler->verbose, " put_label ");
|
||||
sljit_verbose_param(compiler, dst, dstw);
|
||||
fprintf(compiler->verbose, "\n");
|
||||
}
|
||||
#endif
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */
|
||||
|
||||
#define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \
|
||||
@ -2580,6 +2640,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(dst);
|
||||
SLJIT_UNUSED_ARG(dstw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(addr);
|
||||
@ -2596,4 +2664,4 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
||||
SLJIT_UNREACHABLE();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* !SLJIT_CONFIG_UNSUPPORTED */
|
||||
|
@ -348,13 +348,20 @@ struct sljit_label {
|
||||
struct sljit_jump {
|
||||
struct sljit_jump *next;
|
||||
sljit_uw addr;
|
||||
sljit_sw flags;
|
||||
sljit_uw flags;
|
||||
union {
|
||||
sljit_uw target;
|
||||
struct sljit_label* label;
|
||||
struct sljit_label *label;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct sljit_put_label {
|
||||
struct sljit_put_label *next;
|
||||
struct sljit_label *label;
|
||||
sljit_uw addr;
|
||||
sljit_uw flags;
|
||||
};
|
||||
|
||||
struct sljit_const {
|
||||
struct sljit_const *next;
|
||||
sljit_uw addr;
|
||||
@ -366,10 +373,12 @@ struct sljit_compiler {
|
||||
|
||||
struct sljit_label *labels;
|
||||
struct sljit_jump *jumps;
|
||||
struct sljit_put_label *put_labels;
|
||||
struct sljit_const *consts;
|
||||
struct sljit_label *last_label;
|
||||
struct sljit_jump *last_jump;
|
||||
struct sljit_const *last_const;
|
||||
struct sljit_put_label *last_put_label;
|
||||
|
||||
void *allocator_data;
|
||||
struct sljit_memory_fragment *buf;
|
||||
@ -1314,10 +1323,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil
|
||||
Flags: - (may destroy flags) */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset);
|
||||
|
||||
/* The constant can be changed runtime (see: sljit_set_const)
|
||||
/* Store a value that can be changed runtime (see: sljit_get_const_addr / sljit_set_const)
|
||||
Flags: - (does not modify flags) */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value);
|
||||
|
||||
/* Store the value of a label (see: sljit_set_put_label)
|
||||
Flags: - (does not modify flags) */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
|
||||
|
||||
/* Set the value stored by put_label to this label. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label);
|
||||
|
||||
/* After the code generation the address for label, jump and const instructions
|
||||
are computed. Since these structures are freed by sljit_free_compiler, the
|
||||
addresses must be preserved by the user program elsewere. */
|
||||
|
@ -583,8 +583,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
sljit_uw *buf_end;
|
||||
sljit_uw size;
|
||||
sljit_uw word_count;
|
||||
sljit_uw next_addr;
|
||||
sljit_sw executable_offset;
|
||||
sljit_sw jump_addr;
|
||||
sljit_sw addr;
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
sljit_uw cpool_size;
|
||||
sljit_uw cpool_skip_alignment;
|
||||
@ -597,6 +598,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
struct sljit_label *label;
|
||||
struct sljit_jump *jump;
|
||||
struct sljit_const *const_;
|
||||
struct sljit_put_label *put_label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
@ -625,11 +627,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
code_ptr = code;
|
||||
word_count = 0;
|
||||
next_addr = 1;
|
||||
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||
|
||||
label = compiler->labels;
|
||||
jump = compiler->jumps;
|
||||
const_ = compiler->consts;
|
||||
put_label = compiler->put_labels;
|
||||
|
||||
if (label && label->size == 0) {
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
|
||||
@ -662,6 +666,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
label = label->next;
|
||||
|
||||
next_addr = compute_next_addr(label, jump, const_, put_label);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -669,10 +675,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {
|
||||
#endif
|
||||
*code_ptr = *buf_ptr++;
|
||||
/* These structures are ordered by their address. */
|
||||
if (next_addr == word_count) {
|
||||
SLJIT_ASSERT(!label || label->size >= word_count);
|
||||
SLJIT_ASSERT(!jump || jump->addr >= word_count);
|
||||
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
||||
SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
|
||||
|
||||
/* These structures are ordered by their address. */
|
||||
if (jump && jump->addr == word_count) {
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
if (detect_jump_type(jump, code_ptr, code, executable_offset))
|
||||
@ -699,6 +708,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
#endif
|
||||
const_ = const_->next;
|
||||
}
|
||||
if (put_label && put_label->addr == word_count) {
|
||||
SLJIT_ASSERT(put_label->label);
|
||||
put_label->addr = (sljit_uw)code_ptr;
|
||||
put_label = put_label->next;
|
||||
}
|
||||
next_addr = compute_next_addr(label, jump, const_, put_label);
|
||||
}
|
||||
code_ptr++;
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
}
|
||||
@ -725,6 +741,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_ASSERT(!label);
|
||||
SLJIT_ASSERT(!jump);
|
||||
SLJIT_ASSERT(!const_);
|
||||
SLJIT_ASSERT(!put_label);
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
SLJIT_ASSERT(cpool_size == 0);
|
||||
@ -755,15 +772,15 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
buf_ptr = (sljit_uw *)jump->addr;
|
||||
|
||||
if (jump->flags & PATCH_B) {
|
||||
jump_addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);
|
||||
addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);
|
||||
if (!(jump->flags & JUMP_ADDR)) {
|
||||
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
|
||||
SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - jump_addr) >= -0x02000000);
|
||||
*buf_ptr |= (((sljit_sw)jump->u.label->addr - jump_addr) >> 2) & 0x00ffffff;
|
||||
SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - addr) >= -0x02000000);
|
||||
*buf_ptr |= (((sljit_sw)jump->u.label->addr - addr) >> 2) & 0x00ffffff;
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(((sljit_sw)jump->u.target - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - jump_addr) >= -0x02000000);
|
||||
*buf_ptr |= (((sljit_sw)jump->u.target - jump_addr) >> 2) & 0x00ffffff;
|
||||
SLJIT_ASSERT(((sljit_sw)jump->u.target - addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - addr) >= -0x02000000);
|
||||
*buf_ptr |= (((sljit_sw)jump->u.target - addr) >> 2) & 0x00ffffff;
|
||||
}
|
||||
}
|
||||
else if (jump->flags & SLJIT_REWRITABLE_JUMP) {
|
||||
@ -813,6 +830,22 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
}
|
||||
#endif
|
||||
|
||||
put_label = compiler->put_labels;
|
||||
while (put_label) {
|
||||
addr = put_label->label->addr;
|
||||
buf_ptr = (sljit_uw*)put_label->addr;
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
SLJIT_ASSERT((buf_ptr[0] & 0xffff0000) == 0xe59f0000);
|
||||
buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr;
|
||||
#else
|
||||
SLJIT_ASSERT((buf_ptr[-1] & 0xfff00000) == MOVW && (buf_ptr[0] & 0xfff00000) == MOVT);
|
||||
buf_ptr[-1] |= ((addr << 4) & 0xf0000) | (addr & 0xfff);
|
||||
buf_ptr[0] |= ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff);
|
||||
#endif
|
||||
put_label = put_label->next;
|
||||
}
|
||||
|
||||
SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size);
|
||||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
@ -2639,23 +2672,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
|
||||
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;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
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_);
|
||||
|
||||
reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
|
||||
dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG2;
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), init_value));
|
||||
PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), init_value));
|
||||
compiler->patches++;
|
||||
#else
|
||||
PTR_FAIL_IF(emit_imm(compiler, reg, init_value));
|
||||
PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value));
|
||||
#endif
|
||||
|
||||
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
|
||||
PTR_FAIL_IF(!const_);
|
||||
set_const(const_, compiler);
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
@ -2663,6 +2696,33 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||
return const_;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
struct sljit_put_label *put_label;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG2;
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
|
||||
PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), 0));
|
||||
compiler->patches++;
|
||||
#else
|
||||
PTR_FAIL_IF(emit_imm(compiler, dst_r, 0));
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));
|
||||
return put_label;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
|
||||
{
|
||||
inline_set_jump_addr(addr, executable_offset, new_target, 1);
|
||||
|
@ -161,7 +161,7 @@ static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm)
|
||||
inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
|
||||
static SLJIT_INLINE sljit_sw detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_sw diff;
|
||||
sljit_uw target_addr;
|
||||
@ -196,14 +196,14 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (target_addr <= 0xffffffffl) {
|
||||
if (target_addr < 0x100000000l) {
|
||||
if (jump->flags & IS_COND)
|
||||
code_ptr[-5] -= (2 << 5);
|
||||
code_ptr[-2] = code_ptr[0];
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (target_addr <= 0xffffffffffffl) {
|
||||
if (target_addr < 0x1000000000000l) {
|
||||
if (jump->flags & IS_COND)
|
||||
code_ptr[-5] -= (1 << 5);
|
||||
jump->flags |= PATCH_ABS48;
|
||||
@ -215,6 +215,22 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
|
||||
{
|
||||
if (max_label < 0x100000000l) {
|
||||
put_label->flags = 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (max_label < 0x1000000000000l) {
|
||||
put_label->flags = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
put_label->flags = 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
|
||||
{
|
||||
struct sljit_memory_fragment *buf;
|
||||
@ -223,6 +239,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
sljit_ins *buf_ptr;
|
||||
sljit_ins *buf_end;
|
||||
sljit_uw word_count;
|
||||
sljit_uw next_addr;
|
||||
sljit_sw executable_offset;
|
||||
sljit_uw addr;
|
||||
sljit_s32 dst;
|
||||
@ -230,6 +247,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
struct sljit_label *label;
|
||||
struct sljit_jump *jump;
|
||||
struct sljit_const *const_;
|
||||
struct sljit_put_label *put_label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
@ -241,21 +259,26 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
code_ptr = code;
|
||||
word_count = 0;
|
||||
next_addr = 0;
|
||||
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||
|
||||
label = compiler->labels;
|
||||
jump = compiler->jumps;
|
||||
const_ = compiler->consts;
|
||||
put_label = compiler->put_labels;
|
||||
|
||||
do {
|
||||
buf_ptr = (sljit_ins*)buf->memory;
|
||||
buf_end = buf_ptr + (buf->used_size >> 2);
|
||||
do {
|
||||
*code_ptr = *buf_ptr++;
|
||||
/* These structures are ordered by their address. */
|
||||
if (next_addr == word_count) {
|
||||
SLJIT_ASSERT(!label || label->size >= word_count);
|
||||
SLJIT_ASSERT(!jump || jump->addr >= word_count);
|
||||
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
||||
SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
|
||||
|
||||
/* These structures are ordered by their address. */
|
||||
if (label && label->size == word_count) {
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
@ -270,6 +293,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
const_->addr = (sljit_uw)code_ptr;
|
||||
const_ = const_->next;
|
||||
}
|
||||
if (put_label && put_label->addr == word_count) {
|
||||
SLJIT_ASSERT(put_label->label);
|
||||
put_label->addr = (sljit_uw)(code_ptr - 3);
|
||||
code_ptr -= put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
|
||||
put_label = put_label->next;
|
||||
}
|
||||
next_addr = compute_next_addr(label, jump, const_, put_label);
|
||||
}
|
||||
code_ptr ++;
|
||||
word_count ++;
|
||||
} while (buf_ptr < buf_end);
|
||||
@ -286,6 +317,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_ASSERT(!label);
|
||||
SLJIT_ASSERT(!jump);
|
||||
SLJIT_ASSERT(!const_);
|
||||
SLJIT_ASSERT(!put_label);
|
||||
SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
|
||||
|
||||
jump = compiler->jumps;
|
||||
@ -323,6 +355,23 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
jump = jump->next;
|
||||
}
|
||||
|
||||
put_label = compiler->put_labels;
|
||||
while (put_label) {
|
||||
addr = put_label->label->addr;
|
||||
buf_ptr = (sljit_ins *)put_label->addr;
|
||||
|
||||
buf_ptr[0] |= (addr & 0xffff) << 5;
|
||||
buf_ptr[1] |= ((addr >> 16) & 0xffff) << 5;
|
||||
|
||||
if (put_label->flags >= 1)
|
||||
buf_ptr[2] |= ((addr >> 32) & 0xffff) << 5;
|
||||
|
||||
if (put_label->flags >= 2)
|
||||
buf_ptr[3] |= ((addr >> 48) & 0xffff) << 5;
|
||||
|
||||
put_label = put_label->next;
|
||||
}
|
||||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||
@ -1947,6 +1996,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||
return const_;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
struct sljit_put_label *put_label;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
|
||||
PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, 0));
|
||||
|
||||
put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
|
||||
PTR_FAIL_IF(!put_label);
|
||||
set_put_label(put_label, compiler, 1);
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
|
||||
|
||||
return put_label;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -365,11 +365,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
sljit_u16 *buf_ptr;
|
||||
sljit_u16 *buf_end;
|
||||
sljit_uw half_count;
|
||||
sljit_uw next_addr;
|
||||
sljit_sw executable_offset;
|
||||
|
||||
struct sljit_label *label;
|
||||
struct sljit_jump *jump;
|
||||
struct sljit_const *const_;
|
||||
struct sljit_put_label *put_label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
@ -381,21 +383,26 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
code_ptr = code;
|
||||
half_count = 0;
|
||||
next_addr = 0;
|
||||
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||
|
||||
label = compiler->labels;
|
||||
jump = compiler->jumps;
|
||||
const_ = compiler->consts;
|
||||
put_label = compiler->put_labels;
|
||||
|
||||
do {
|
||||
buf_ptr = (sljit_u16*)buf->memory;
|
||||
buf_end = buf_ptr + (buf->used_size >> 1);
|
||||
do {
|
||||
*code_ptr = *buf_ptr++;
|
||||
/* These structures are ordered by their address. */
|
||||
if (next_addr == half_count) {
|
||||
SLJIT_ASSERT(!label || label->size >= half_count);
|
||||
SLJIT_ASSERT(!jump || jump->addr >= half_count);
|
||||
SLJIT_ASSERT(!const_ || const_->addr >= half_count);
|
||||
SLJIT_ASSERT(!put_label || put_label->addr >= half_count);
|
||||
|
||||
/* These structures are ordered by their address. */
|
||||
if (label && label->size == half_count) {
|
||||
label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
|
||||
label->size = code_ptr - code;
|
||||
@ -410,6 +417,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
const_->addr = (sljit_uw)code_ptr;
|
||||
const_ = const_->next;
|
||||
}
|
||||
if (put_label && put_label->addr == half_count) {
|
||||
SLJIT_ASSERT(put_label->label);
|
||||
put_label->addr = (sljit_uw)code_ptr;
|
||||
put_label = put_label->next;
|
||||
}
|
||||
next_addr = compute_next_addr(label, jump, const_, put_label);
|
||||
}
|
||||
code_ptr ++;
|
||||
half_count ++;
|
||||
} while (buf_ptr < buf_end);
|
||||
@ -426,6 +440,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_ASSERT(!label);
|
||||
SLJIT_ASSERT(!jump);
|
||||
SLJIT_ASSERT(!const_);
|
||||
SLJIT_ASSERT(!put_label);
|
||||
SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
|
||||
|
||||
jump = compiler->jumps;
|
||||
@ -434,6 +449,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
jump = jump->next;
|
||||
}
|
||||
|
||||
put_label = compiler->put_labels;
|
||||
while (put_label) {
|
||||
modify_imm32_const((sljit_u16 *)put_label->addr, put_label->label->addr);
|
||||
put_label = put_label->next;
|
||||
}
|
||||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16);
|
||||
@ -2311,6 +2332,27 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||
return const_;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
struct sljit_put_label *put_label;
|
||||
sljit_s32 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) ? dst : TMP_REG1;
|
||||
PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, 0));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
|
||||
return put_label;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -368,16 +368,21 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
SLJIT_ASSERT(!(flags & SRC2_IMM));
|
||||
|
||||
if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
|
||||
#else
|
||||
#else /* !SLJIT_MIPS_R1 && !SLJIT_MIPS_R6 */
|
||||
FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
|
||||
return push_inst(compiler, MFLO | D(dst), DR(dst));
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_R1 || SLJIT_MIPS_R6 */
|
||||
}
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
FAIL_IF(push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)));
|
||||
FAIL_IF(push_inst(compiler, MUH | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
FAIL_IF(push_inst(compiler, SRA | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
|
||||
return push_inst(compiler, SUBU | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
|
||||
|
||||
@ -420,6 +425,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
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);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
@ -430,6 +436,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
||||
{
|
||||
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);
|
||||
|
@ -459,19 +459,26 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
SLJIT_ASSERT(!(flags & SRC2_IMM));
|
||||
|
||||
if (GET_FLAG_TYPE(op) != SLJIT_MUL_OVERFLOW) {
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst));
|
||||
#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
if (op & SLJIT_I32_OP)
|
||||
return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
|
||||
FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
|
||||
return push_inst(compiler, MFLO | D(dst), DR(dst));
|
||||
#else
|
||||
#else /* !SLJIT_MIPS_R6 && !SLJIT_MIPS_R1 */
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
|
||||
return push_inst(compiler, MFLO | D(dst), DR(dst));
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
}
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)));
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DMUH, MUH) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, MFHI | DA(EQUAL_FLAG), EQUAL_FLAG));
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(OTHER_FLAG) | SH_IMM(31), OTHER_FLAG));
|
||||
return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(EQUAL_FLAG) | TA(OTHER_FLAG) | DA(OTHER_FLAG), OTHER_FLAG);
|
||||
|
||||
|
@ -27,17 +27,31 @@
|
||||
/* Latest MIPS architecture. */
|
||||
/* Automatically detect SLJIT_MIPS_R1 */
|
||||
|
||||
#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6)
|
||||
#define SLJIT_MIPS_R6 1
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
{
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
return "MIPS32-R6" SLJIT_CPUINFO;
|
||||
#else /* !SLJIT_CONFIG_MIPS_32 */
|
||||
return "MIPS64-R6" SLJIT_CPUINFO;
|
||||
#endif /* SLJIT_CONFIG_MIPS_32 */
|
||||
|
||||
#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
return "MIPS32-R1" SLJIT_CPUINFO;
|
||||
#else
|
||||
#else /* !SLJIT_CONFIG_MIPS_32 */
|
||||
return "MIPS64-R1" SLJIT_CPUINFO;
|
||||
#endif
|
||||
#endif /* SLJIT_CONFIG_MIPS_32 */
|
||||
|
||||
#else /* SLJIT_MIPS_R1 */
|
||||
return "MIPS III" SLJIT_CPUINFO;
|
||||
#endif
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
}
|
||||
|
||||
/* Length of an instruction word
|
||||
@ -62,6 +76,7 @@ typedef sljit_u32 sljit_ins;
|
||||
|
||||
#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
|
||||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
|
||||
#define TMP_FREG3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3)
|
||||
|
||||
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31
|
||||
@ -69,14 +84,14 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
0, 0, 14, 2, 4, 6, 8, 12, 10
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
||||
0, 0, 14, 2, 4, 6, 8, 12, 10, 16
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
0, 0, 13, 14, 15, 16, 17, 12, 18
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
|
||||
0, 0, 13, 14, 15, 16, 17, 12, 18, 10
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -102,6 +117,11 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
#define FR(dr) (freg_map[dr])
|
||||
#define HI(opcode) ((opcode) << 26)
|
||||
#define LO(opcode) (opcode)
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
/* CMP.cond.fmt */
|
||||
/* S = (20 << 21) D = (21 << 21) */
|
||||
#define CMP_FMT_S (20 << 21)
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
/* S = (16 << 21) D = (17 << 21) */
|
||||
#define FMT_S (16 << 21)
|
||||
#define FMT_D (17 << 21)
|
||||
@ -114,8 +134,13 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
#define ANDI (HI(12))
|
||||
#define B (HI(4))
|
||||
#define BAL (HI(1) | (17 << 16))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#define BC1EQZ (HI(17) | (9 << 21) | FT(TMP_FREG3))
|
||||
#define BC1NEZ (HI(17) | (13 << 21) | FT(TMP_FREG3))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#define BC1F (HI(17) | (8 << 21))
|
||||
#define BC1T (HI(17) | (8 << 21) | (1 << 16))
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#define BEQ (HI(4))
|
||||
#define BGEZ (HI(1) | (1 << 16))
|
||||
#define BGTZ (HI(7))
|
||||
@ -124,20 +149,42 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
#define BNE (HI(5))
|
||||
#define BREAK (HI(0) | LO(13))
|
||||
#define CFC1 (HI(17) | (2 << 21))
|
||||
#define C_UN_S (HI(17) | FMT_S | LO(49))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#define C_UEQ_S (HI(17) | CMP_FMT_S | LO(3))
|
||||
#define C_ULE_S (HI(17) | CMP_FMT_S | LO(7))
|
||||
#define C_ULT_S (HI(17) | CMP_FMT_S | LO(5))
|
||||
#define C_UN_S (HI(17) | CMP_FMT_S | LO(1))
|
||||
#define C_FD (FD(TMP_FREG3))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#define C_UEQ_S (HI(17) | FMT_S | LO(51))
|
||||
#define C_ULE_S (HI(17) | FMT_S | LO(55))
|
||||
#define C_ULT_S (HI(17) | FMT_S | LO(53))
|
||||
#define C_UN_S (HI(17) | FMT_S | LO(49))
|
||||
#define C_FD (0)
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#define CVT_S_S (HI(17) | FMT_S | LO(32))
|
||||
#define DADDIU (HI(25))
|
||||
#define DADDU (HI(0) | LO(45))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#define DDIV (HI(0) | (2 << 6) | LO(30))
|
||||
#define DDIVU (HI(0) | (2 << 6) | LO(31))
|
||||
#define DMOD (HI(0) | (3 << 6) | LO(30))
|
||||
#define DMODU (HI(0) | (3 << 6) | LO(31))
|
||||
#define DIV (HI(0) | (2 << 6) | LO(26))
|
||||
#define DIVU (HI(0) | (2 << 6) | LO(27))
|
||||
#define DMUH (HI(0) | (3 << 6) | LO(28))
|
||||
#define DMUHU (HI(0) | (3 << 6) | LO(29))
|
||||
#define DMUL (HI(0) | (2 << 6) | LO(28))
|
||||
#define DMULU (HI(0) | (2 << 6) | LO(29))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#define DDIV (HI(0) | LO(30))
|
||||
#define DDIVU (HI(0) | LO(31))
|
||||
#define DIV (HI(0) | LO(26))
|
||||
#define DIVU (HI(0) | LO(27))
|
||||
#define DIV_S (HI(17) | FMT_S | LO(3))
|
||||
#define DMULT (HI(0) | LO(28))
|
||||
#define DMULTU (HI(0) | LO(29))
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#define DIV_S (HI(17) | FMT_S | LO(3))
|
||||
#define DSLL (HI(0) | LO(56))
|
||||
#define DSLL32 (HI(0) | LO(60))
|
||||
#define DSLLV (HI(0) | LO(20))
|
||||
@ -151,18 +198,34 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
#define J (HI(2))
|
||||
#define JAL (HI(3))
|
||||
#define JALR (HI(0) | LO(9))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#define JR (HI(0) | LO(9))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#define JR (HI(0) | LO(8))
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#define LD (HI(55))
|
||||
#define LUI (HI(15))
|
||||
#define LW (HI(35))
|
||||
#define MFC1 (HI(17))
|
||||
#if !(defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#define MFHI (HI(0) | LO(16))
|
||||
#define MFLO (HI(0) | LO(18))
|
||||
#else /* SLJIT_MIPS_R6 */
|
||||
#define MOD (HI(0) | (3 << 6) | LO(26))
|
||||
#define MODU (HI(0) | (3 << 6) | LO(27))
|
||||
#endif /* !SLJIT_MIPS_R6 */
|
||||
#define MOV_S (HI(17) | FMT_S | LO(6))
|
||||
#define MTC1 (HI(17) | (4 << 21))
|
||||
#define MUL_S (HI(17) | FMT_S | LO(2))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#define MUH (HI(0) | (3 << 6) | LO(24))
|
||||
#define MUHU (HI(0) | (3 << 6) | LO(25))
|
||||
#define MUL (HI(0) | (2 << 6) | LO(24))
|
||||
#define MULU (HI(0) | (2 << 6) | LO(25))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#define MULT (HI(0) | LO(24))
|
||||
#define MULTU (HI(0) | LO(25))
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#define MUL_S (HI(17) | FMT_S | LO(2))
|
||||
#define NEG_S (HI(17) | FMT_S | LO(7))
|
||||
#define NOP (HI(0) | LO(0))
|
||||
#define NOR (HI(0) | LO(39))
|
||||
@ -188,14 +251,18 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
#define XOR (HI(0) | LO(38))
|
||||
#define XORI (HI(14))
|
||||
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#define CLZ (HI(28) | LO(32))
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#define DCLZ (LO(18))
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#define DCLZ (HI(28) | LO(36))
|
||||
#define MOVF (HI(0) | (0 << 16) | LO(1))
|
||||
#define MOVN (HI(0) | LO(11))
|
||||
#define MOVT (HI(0) | (1 << 16) | LO(1))
|
||||
#define MOVZ (HI(0) | LO(10))
|
||||
#define MUL (HI(28) | LO(2))
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
#define PREF (HI(51))
|
||||
#define PREFX (HI(19) | LO(15))
|
||||
#define SEB (HI(31) | (16 << 6) | LO(32))
|
||||
@ -234,7 +301,13 @@ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit
|
||||
|
||||
static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags)
|
||||
{
|
||||
return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16);
|
||||
if (flags & IS_BIT26_COND)
|
||||
return (1 << 26);
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
if (flags & IS_BIT23_COND)
|
||||
return (1 << 23);
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
return (1 << 16);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
|
||||
@ -376,6 +449,55 @@ static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
|
||||
static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
|
||||
{
|
||||
if (max_label < 0x80000000l) {
|
||||
put_label->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (max_label < 0x800000000000l) {
|
||||
put_label->flags = 1;
|
||||
return 3;
|
||||
}
|
||||
|
||||
put_label->flags = 2;
|
||||
return 5;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label)
|
||||
{
|
||||
sljit_uw addr = put_label->label->addr;
|
||||
sljit_ins *inst = (sljit_ins *)put_label->addr;
|
||||
sljit_s32 reg = *inst;
|
||||
|
||||
if (put_label->flags == 0) {
|
||||
SLJIT_ASSERT(addr < 0x80000000l);
|
||||
inst[0] = LUI | T(reg) | IMM(addr >> 16);
|
||||
}
|
||||
else if (put_label->flags == 1) {
|
||||
SLJIT_ASSERT(addr < 0x800000000000l);
|
||||
inst[0] = LUI | T(reg) | IMM(addr >> 32);
|
||||
inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
|
||||
inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
|
||||
inst += 2;
|
||||
}
|
||||
else {
|
||||
inst[0] = LUI | T(reg) | IMM(addr >> 48);
|
||||
inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);
|
||||
inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
|
||||
inst[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
|
||||
inst[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);
|
||||
inst += 4;
|
||||
}
|
||||
|
||||
inst[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
|
||||
{
|
||||
struct sljit_memory_fragment *buf;
|
||||
@ -384,12 +506,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
sljit_ins *buf_ptr;
|
||||
sljit_ins *buf_end;
|
||||
sljit_uw word_count;
|
||||
sljit_uw next_addr;
|
||||
sljit_sw executable_offset;
|
||||
sljit_uw addr;
|
||||
|
||||
struct sljit_label *label;
|
||||
struct sljit_jump *jump;
|
||||
struct sljit_const *const_;
|
||||
struct sljit_put_label *put_label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
@ -401,20 +525,25 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
code_ptr = code;
|
||||
word_count = 0;
|
||||
next_addr = 0;
|
||||
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||
|
||||
label = compiler->labels;
|
||||
jump = compiler->jumps;
|
||||
const_ = compiler->consts;
|
||||
put_label = compiler->put_labels;
|
||||
|
||||
do {
|
||||
buf_ptr = (sljit_ins*)buf->memory;
|
||||
buf_end = buf_ptr + (buf->used_size >> 2);
|
||||
do {
|
||||
*code_ptr = *buf_ptr++;
|
||||
if (next_addr == word_count) {
|
||||
SLJIT_ASSERT(!label || label->size >= word_count);
|
||||
SLJIT_ASSERT(!jump || jump->addr >= word_count);
|
||||
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
||||
SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
|
||||
|
||||
/* These structures are ordered by their address. */
|
||||
if (label && label->size == word_count) {
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
@ -431,10 +560,20 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
jump = jump->next;
|
||||
}
|
||||
if (const_ && const_->addr == word_count) {
|
||||
/* Just recording the address. */
|
||||
const_->addr = (sljit_uw)code_ptr;
|
||||
const_ = const_->next;
|
||||
}
|
||||
if (put_label && put_label->addr == word_count) {
|
||||
SLJIT_ASSERT(put_label->label);
|
||||
put_label->addr = (sljit_uw)code_ptr;
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
|
||||
word_count += 5;
|
||||
#endif
|
||||
put_label = put_label->next;
|
||||
}
|
||||
next_addr = compute_next_addr(label, jump, const_, put_label);
|
||||
}
|
||||
code_ptr ++;
|
||||
word_count ++;
|
||||
} while (buf_ptr < buf_end);
|
||||
@ -451,6 +590,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_ASSERT(!label);
|
||||
SLJIT_ASSERT(!jump);
|
||||
SLJIT_ASSERT(!const_);
|
||||
SLJIT_ASSERT(!put_label);
|
||||
SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
|
||||
|
||||
jump = compiler->jumps;
|
||||
@ -498,6 +638,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
jump = jump->next;
|
||||
}
|
||||
|
||||
put_label = compiler->put_labels;
|
||||
while (put_label) {
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
addr = put_label->label->addr;
|
||||
buf_ptr = (sljit_ins *)put_label->addr;
|
||||
|
||||
SLJIT_ASSERT((buf_ptr[0] & 0xffe00000) == LUI && (buf_ptr[1] & 0xfc000000) == ORI);
|
||||
buf_ptr[0] |= (addr >> 16) & 0xffff;
|
||||
buf_ptr[1] |= addr & 0xffff;
|
||||
#else
|
||||
put_label_set(put_label);
|
||||
#endif
|
||||
put_label = put_label->next;
|
||||
}
|
||||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||
@ -1075,34 +1230,62 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
case SLJIT_LMUL_UW:
|
||||
case SLJIT_LMUL_SW:
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULU : DMUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMUHU : DMUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
|
||||
#else /* !SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULU : MUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MUHU : MUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
|
||||
#endif /* SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? DMULTU : DMULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
#else
|
||||
#else /* !SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
#endif
|
||||
#endif /* SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
case SLJIT_DIVMOD_UW:
|
||||
case SLJIT_DIVMOD_SW:
|
||||
case SLJIT_DIV_UW:
|
||||
case SLJIT_DIV_SW:
|
||||
SLJIT_COMPILE_ASSERT((SLJIT_DIVMOD_UW & 0x2) == 0 && SLJIT_DIV_UW - 0x2 == SLJIT_DIVMOD_UW, bad_div_opcode_assignments);
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if (int_op) {
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
|
||||
}
|
||||
else {
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DMODU : DMOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
|
||||
}
|
||||
#else /* !SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3)));
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1)));
|
||||
#endif /* SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | TA(0) | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, ADDU_W | S(TMP_REG1) | TA(0) | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
#if !(defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1)
|
||||
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
#endif
|
||||
|
||||
#endif /* !SLJIT_MIPS_R1 */
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if (int_op)
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
#else
|
||||
#else /* !SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS));
|
||||
#endif
|
||||
|
||||
#endif /* SLJIT_CONFIG_MIPS_64 */
|
||||
FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_R0), DR(SLJIT_R0)));
|
||||
return (op >= SLJIT_DIV_UW) ? SLJIT_SUCCESS : push_inst(compiler, MFHI | D(SLJIT_R1), DR(SLJIT_R1));
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
@ -1408,8 +1591,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile
|
||||
inst = C_UN_S;
|
||||
break;
|
||||
}
|
||||
|
||||
return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS);
|
||||
return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1) | C_FD, UNMOVABLE_INS);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
@ -1608,16 +1790,30 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
flags = IS_BIT26_COND; \
|
||||
delay_check = src;
|
||||
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
|
||||
#define BR_T() \
|
||||
inst = BC1NEZ; \
|
||||
flags = IS_BIT23_COND; \
|
||||
delay_check = FCSR_FCC;
|
||||
#define BR_F() \
|
||||
inst = BC1EQZ; \
|
||||
flags = IS_BIT23_COND; \
|
||||
delay_check = FCSR_FCC;
|
||||
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
|
||||
#define BR_T() \
|
||||
inst = BC1T | JUMP_LENGTH; \
|
||||
flags = IS_BIT16_COND; \
|
||||
delay_check = FCSR_FCC;
|
||||
|
||||
#define BR_F() \
|
||||
inst = BC1F | JUMP_LENGTH; \
|
||||
flags = IS_BIT16_COND; \
|
||||
delay_check = FCSR_FCC;
|
||||
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
@ -1927,7 +2123,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
||||
case SLJIT_GREATER_EQUAL_F64:
|
||||
case SLJIT_UNORDERED_F64:
|
||||
case SLJIT_ORDERED_F64:
|
||||
#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6)
|
||||
FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar));
|
||||
#else /* !SLJIT_MIPS_R6 */
|
||||
FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar));
|
||||
#endif /* SLJIT_MIPS_R6 */
|
||||
FAIL_IF(push_inst(compiler, SRL | TA(dst_ar) | DA(dst_ar) | SH_IMM(23), dst_ar));
|
||||
FAIL_IF(push_inst(compiler, ANDI | SA(dst_ar) | TA(dst_ar) | IMM(1), dst_ar));
|
||||
src_ar = dst_ar;
|
||||
@ -2039,7 +2239,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
||||
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;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
@ -2049,11 +2249,38 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||
PTR_FAIL_IF(!const_);
|
||||
set_const(const_, compiler);
|
||||
|
||||
reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
|
||||
|
||||
PTR_FAIL_IF(emit_const(compiler, reg, init_value));
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
|
||||
PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
|
||||
|
||||
return const_;
|
||||
}
|
||||
|
||||
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_s32 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) ? dst : TMP_REG2;
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
|
||||
#else
|
||||
PTR_FAIL_IF(push_inst(compiler, dst_r, UNMOVABLE_INS));
|
||||
compiler->size += 5;
|
||||
#endif
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
|
||||
|
||||
return put_label;
|
||||
}
|
||||
|
@ -259,6 +259,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
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);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
@ -269,6 +270,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
||||
{
|
||||
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);
|
||||
|
@ -35,9 +35,6 @@
|
||||
#error "Must implement count leading zeroes"
|
||||
#endif
|
||||
|
||||
#define RLDI(dst, src, sh, mb, type) \
|
||||
(HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20))
|
||||
|
||||
#define PUSH_RLDICR(reg, shift) \
|
||||
push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1))
|
||||
|
||||
|
@ -231,6 +231,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
#define SIMM_MIN (-0x8000)
|
||||
#define UIMM_MAX (0xffff)
|
||||
|
||||
#define RLDI(dst, src, sh, mb, type) \
|
||||
(HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20))
|
||||
|
||||
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func)
|
||||
{
|
||||
@ -324,6 +327,55 @@ keep_address:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
|
||||
static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
|
||||
{
|
||||
if (max_label < 0x100000000l) {
|
||||
put_label->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (max_label < 0x1000000000000l) {
|
||||
put_label->flags = 1;
|
||||
return 3;
|
||||
}
|
||||
|
||||
put_label->flags = 2;
|
||||
return 4;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label)
|
||||
{
|
||||
sljit_uw addr = put_label->label->addr;
|
||||
sljit_ins *inst = (sljit_ins *)put_label->addr;
|
||||
sljit_s32 reg = *inst;
|
||||
|
||||
if (put_label->flags == 0) {
|
||||
SLJIT_ASSERT(addr < 0x100000000l);
|
||||
inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 16);
|
||||
}
|
||||
else {
|
||||
if (put_label->flags == 1) {
|
||||
SLJIT_ASSERT(addr < 0x1000000000000l);
|
||||
inst[0] = ORI | S(TMP_ZERO) | A(reg) | IMM(addr >> 32);
|
||||
}
|
||||
else {
|
||||
inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 48);
|
||||
inst[1] = ORI | S(reg) | A(reg) | IMM((addr >> 32) & 0xffff);
|
||||
inst ++;
|
||||
}
|
||||
|
||||
inst[1] = RLDI(reg, reg, 32, 31, 1);
|
||||
inst[2] = ORIS | S(reg) | A(reg) | IMM((addr >> 16) & 0xffff);
|
||||
inst += 2;
|
||||
}
|
||||
|
||||
inst[1] = ORI | S(reg) | A(reg) | IMM(addr & 0xffff);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
|
||||
{
|
||||
struct sljit_memory_fragment *buf;
|
||||
@ -332,12 +384,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
sljit_ins *buf_ptr;
|
||||
sljit_ins *buf_end;
|
||||
sljit_uw word_count;
|
||||
sljit_uw next_addr;
|
||||
sljit_sw executable_offset;
|
||||
sljit_uw addr;
|
||||
|
||||
struct sljit_label *label;
|
||||
struct sljit_jump *jump;
|
||||
struct sljit_const *const_;
|
||||
struct sljit_put_label *put_label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
@ -356,20 +410,25 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
code_ptr = code;
|
||||
word_count = 0;
|
||||
next_addr = 0;
|
||||
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||
|
||||
label = compiler->labels;
|
||||
jump = compiler->jumps;
|
||||
const_ = compiler->consts;
|
||||
put_label = compiler->put_labels;
|
||||
|
||||
do {
|
||||
buf_ptr = (sljit_ins*)buf->memory;
|
||||
buf_end = buf_ptr + (buf->used_size >> 2);
|
||||
do {
|
||||
*code_ptr = *buf_ptr++;
|
||||
if (next_addr == word_count) {
|
||||
SLJIT_ASSERT(!label || label->size >= word_count);
|
||||
SLJIT_ASSERT(!jump || jump->addr >= word_count);
|
||||
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
||||
SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
|
||||
|
||||
/* These structures are ordered by their address. */
|
||||
if (label && label->size == word_count) {
|
||||
/* Just recording the address. */
|
||||
@ -422,6 +481,17 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
const_->addr = (sljit_uw)code_ptr;
|
||||
const_ = const_->next;
|
||||
}
|
||||
if (put_label && put_label->addr == word_count) {
|
||||
SLJIT_ASSERT(put_label->label);
|
||||
put_label->addr = (sljit_uw)code_ptr;
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
|
||||
code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
|
||||
word_count += 4;
|
||||
#endif
|
||||
put_label = put_label->next;
|
||||
}
|
||||
next_addr = compute_next_addr(label, jump, const_, put_label);
|
||||
}
|
||||
code_ptr ++;
|
||||
word_count ++;
|
||||
} while (buf_ptr < buf_end);
|
||||
@ -438,6 +508,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_ASSERT(!label);
|
||||
SLJIT_ASSERT(!jump);
|
||||
SLJIT_ASSERT(!const_);
|
||||
SLJIT_ASSERT(!put_label);
|
||||
|
||||
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
|
||||
SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins)));
|
||||
#else
|
||||
@ -503,6 +575,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
jump = jump->next;
|
||||
}
|
||||
|
||||
put_label = compiler->put_labels;
|
||||
while (put_label) {
|
||||
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
|
||||
addr = put_label->label->addr;
|
||||
buf_ptr = (sljit_ins *)put_label->addr;
|
||||
|
||||
SLJIT_ASSERT((buf_ptr[0] & 0xfc1f0000) == ADDIS && (buf_ptr[1] & 0xfc000000) == ORI);
|
||||
buf_ptr[0] |= (addr >> 16) & 0xffff;
|
||||
buf_ptr[1] |= addr & 0xffff;
|
||||
#else
|
||||
put_label_set(put_label);
|
||||
#endif
|
||||
put_label = put_label->next;
|
||||
}
|
||||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
|
||||
@ -2261,7 +2348,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil
|
||||
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;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
@ -2271,11 +2358,38 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||
PTR_FAIL_IF(!const_);
|
||||
set_const(const_, compiler);
|
||||
|
||||
reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
|
||||
|
||||
PTR_FAIL_IF(emit_const(compiler, reg, init_value));
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
|
||||
PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
|
||||
|
||||
return const_;
|
||||
}
|
||||
|
||||
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_s32 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) ? dst : TMP_REG2;
|
||||
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
|
||||
PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
|
||||
#else
|
||||
PTR_FAIL_IF(push_inst(compiler, dst_r));
|
||||
compiler->size += 4;
|
||||
#endif
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
|
||||
|
||||
return put_label;
|
||||
}
|
||||
|
@ -267,6 +267,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
|
||||
{
|
||||
sljit_ins *inst = (sljit_ins *)addr;
|
||||
|
||||
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);
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
@ -277,6 +278,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
||||
{
|
||||
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);
|
||||
|
@ -298,12 +298,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
sljit_ins *buf_ptr;
|
||||
sljit_ins *buf_end;
|
||||
sljit_uw word_count;
|
||||
sljit_uw next_addr;
|
||||
sljit_sw executable_offset;
|
||||
sljit_uw addr;
|
||||
|
||||
struct sljit_label *label;
|
||||
struct sljit_jump *jump;
|
||||
struct sljit_const *const_;
|
||||
struct sljit_put_label *put_label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
@ -315,20 +317,25 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
code_ptr = code;
|
||||
word_count = 0;
|
||||
next_addr = 0;
|
||||
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||
|
||||
label = compiler->labels;
|
||||
jump = compiler->jumps;
|
||||
const_ = compiler->consts;
|
||||
put_label = compiler->put_labels;
|
||||
|
||||
do {
|
||||
buf_ptr = (sljit_ins*)buf->memory;
|
||||
buf_end = buf_ptr + (buf->used_size >> 2);
|
||||
do {
|
||||
*code_ptr = *buf_ptr++;
|
||||
if (next_addr == word_count) {
|
||||
SLJIT_ASSERT(!label || label->size >= word_count);
|
||||
SLJIT_ASSERT(!jump || jump->addr >= word_count);
|
||||
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
|
||||
SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
|
||||
|
||||
/* These structures are ordered by their address. */
|
||||
if (label && label->size == word_count) {
|
||||
/* Just recording the address. */
|
||||
@ -350,6 +357,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
const_->addr = (sljit_uw)code_ptr;
|
||||
const_ = const_->next;
|
||||
}
|
||||
if (put_label && put_label->addr == word_count) {
|
||||
SLJIT_ASSERT(put_label->label);
|
||||
put_label->addr = (sljit_uw)code_ptr;
|
||||
put_label = put_label->next;
|
||||
}
|
||||
next_addr = compute_next_addr(label, jump, const_, put_label);
|
||||
}
|
||||
code_ptr ++;
|
||||
word_count ++;
|
||||
} while (buf_ptr < buf_end);
|
||||
@ -366,6 +380,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_ASSERT(!label);
|
||||
SLJIT_ASSERT(!jump);
|
||||
SLJIT_ASSERT(!const_);
|
||||
SLJIT_ASSERT(!put_label);
|
||||
SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size);
|
||||
|
||||
jump = compiler->jumps;
|
||||
@ -389,8 +404,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
/* Set the fields of immediate loads. */
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff);
|
||||
buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff);
|
||||
SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000));
|
||||
buf_ptr[0] |= (addr >> 10) & 0x3fffff;
|
||||
buf_ptr[1] |= addr & 0x3ff;
|
||||
#else
|
||||
#error "Implementation required"
|
||||
#endif
|
||||
@ -398,6 +414,20 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
jump = jump->next;
|
||||
}
|
||||
|
||||
put_label = compiler->put_labels;
|
||||
while (put_label) {
|
||||
addr = put_label->label->addr;
|
||||
buf_ptr = (sljit_ins *)put_label->addr;
|
||||
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000));
|
||||
buf_ptr[0] |= (addr >> 10) & 0x3fffff;
|
||||
buf_ptr[1] |= addr & 0x3ff;
|
||||
#else
|
||||
#error "Implementation required"
|
||||
#endif
|
||||
put_label = put_label->next;
|
||||
}
|
||||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
@ -1465,8 +1495,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
|
||||
{
|
||||
sljit_s32 reg;
|
||||
struct sljit_const *const_;
|
||||
sljit_s32 dst_r;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
|
||||
@ -1476,11 +1506,31 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||
PTR_FAIL_IF(!const_);
|
||||
set_const(const_, compiler);
|
||||
|
||||
reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
|
||||
|
||||
PTR_FAIL_IF(emit_const(compiler, reg, init_value));
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
|
||||
PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
|
||||
return const_;
|
||||
}
|
||||
|
||||
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_s32 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) ? dst : TMP_REG2;
|
||||
PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
|
||||
return put_label;
|
||||
}
|
||||
|
@ -38,8 +38,10 @@ static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, s
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset)
|
||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_s32 type = jump->flags >> TYPE_SHIFT;
|
||||
|
||||
if (type == SLJIT_JUMP) {
|
||||
*code_ptr++ = JMP_i32;
|
||||
jump->addr++;
|
||||
|
@ -39,8 +39,10 @@ static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg,
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type)
|
||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr)
|
||||
{
|
||||
sljit_s32 type = jump->flags >> TYPE_SHIFT;
|
||||
|
||||
int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && !(jump->flags & JUMP_LABEL) && (jump->u.target <= 0xffffffff);
|
||||
|
||||
/* The relative jump below specialized for this case. */
|
||||
@ -72,6 +74,56 @@ static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_
|
||||
return code_ptr;
|
||||
}
|
||||
|
||||
static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label)
|
||||
{
|
||||
if (max_label > HALFWORD_MAX) {
|
||||
put_label->addr -= put_label->flags;
|
||||
put_label->flags = PATCH_MD;
|
||||
return code_ptr;
|
||||
}
|
||||
|
||||
if (put_label->flags == 0) {
|
||||
/* Destination is register. */
|
||||
code_ptr = (sljit_u8*)put_label->addr - 2 - sizeof(sljit_uw);
|
||||
|
||||
SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
|
||||
SLJIT_ASSERT((code_ptr[1] & 0xf8) == MOV_r_i32);
|
||||
|
||||
if ((code_ptr[0] & 0x07) != 0) {
|
||||
code_ptr[0] = (sljit_u8)(code_ptr[0] & ~0x08);
|
||||
code_ptr += 2 + sizeof(sljit_s32);
|
||||
}
|
||||
else {
|
||||
code_ptr[0] = code_ptr[1];
|
||||
code_ptr += 1 + sizeof(sljit_s32);
|
||||
}
|
||||
|
||||
put_label->addr = (sljit_uw)code_ptr;
|
||||
return code_ptr;
|
||||
}
|
||||
|
||||
code_ptr -= put_label->flags + (2 + sizeof(sljit_uw));
|
||||
SLJIT_MEMMOVE(code_ptr, code_ptr + (2 + sizeof(sljit_uw)), put_label->flags);
|
||||
|
||||
SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
|
||||
|
||||
if ((code_ptr[1] & 0xf8) == MOV_r_i32) {
|
||||
code_ptr += 2 + sizeof(sljit_uw);
|
||||
SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
|
||||
}
|
||||
|
||||
SLJIT_ASSERT(code_ptr[1] == MOV_rm_r);
|
||||
|
||||
code_ptr[0] = (sljit_u8)(code_ptr[0] & ~0x4);
|
||||
code_ptr[1] = MOV_rm_i32;
|
||||
code_ptr[2] = (sljit_u8)(code_ptr[2] & ~(0x7 << 3));
|
||||
|
||||
code_ptr = (sljit_u8*)(put_label->addr - (2 + sizeof(sljit_uw)) + sizeof(sljit_s32));
|
||||
put_label->addr = (sljit_uw)code_ptr;
|
||||
put_label->flags = 0;
|
||||
return code_ptr;
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -428,13 +428,15 @@ static sljit_u8 get_jump_code(sljit_s32 type)
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset);
|
||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset);
|
||||
#else
|
||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type);
|
||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr);
|
||||
static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label);
|
||||
#endif
|
||||
|
||||
static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_s32 type, sljit_sw executable_offset)
|
||||
static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset)
|
||||
{
|
||||
sljit_s32 type = jump->flags >> TYPE_SHIFT;
|
||||
sljit_s32 short_jump;
|
||||
sljit_uw label_addr;
|
||||
|
||||
@ -447,7 +449,7 @@ static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN)
|
||||
return generate_far_jump_code(jump, code_ptr, type);
|
||||
return generate_far_jump_code(jump, code_ptr);
|
||||
#endif
|
||||
|
||||
if (type == SLJIT_JUMP) {
|
||||
@ -497,6 +499,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
struct sljit_label *label;
|
||||
struct sljit_jump *jump;
|
||||
struct sljit_const *const_;
|
||||
struct sljit_put_label *put_label;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_generate_code(compiler));
|
||||
@ -511,6 +514,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
label = compiler->labels;
|
||||
jump = compiler->jumps;
|
||||
const_ = compiler->consts;
|
||||
put_label = compiler->put_labels;
|
||||
executable_offset = SLJIT_EXEC_OFFSET(code);
|
||||
|
||||
do {
|
||||
@ -525,27 +529,38 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
buf_ptr += len;
|
||||
}
|
||||
else {
|
||||
if (*buf_ptr >= 2) {
|
||||
switch (*buf_ptr) {
|
||||
case 0:
|
||||
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
|
||||
label->size = code_ptr - code;
|
||||
label = label->next;
|
||||
break;
|
||||
case 1:
|
||||
jump->addr = (sljit_uw)code_ptr;
|
||||
if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
|
||||
code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 2, executable_offset);
|
||||
code_ptr = generate_near_jump_code(jump, code_ptr, code, executable_offset);
|
||||
else {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2, executable_offset);
|
||||
code_ptr = generate_far_jump_code(jump, code_ptr, executable_offset);
|
||||
#else
|
||||
code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2);
|
||||
code_ptr = generate_far_jump_code(jump, code_ptr);
|
||||
#endif
|
||||
}
|
||||
jump = jump->next;
|
||||
}
|
||||
else if (*buf_ptr == 0) {
|
||||
label->addr = ((sljit_uw)code_ptr) + executable_offset;
|
||||
label->size = code_ptr - code;
|
||||
label = label->next;
|
||||
}
|
||||
else { /* *buf_ptr is 1 */
|
||||
break;
|
||||
case 2:
|
||||
const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);
|
||||
const_ = const_->next;
|
||||
break;
|
||||
default:
|
||||
SLJIT_ASSERT(*buf_ptr == 3);
|
||||
SLJIT_ASSERT(put_label->label);
|
||||
put_label->addr = (sljit_uw)code_ptr;
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
|
||||
#endif
|
||||
put_label = put_label->next;
|
||||
break;
|
||||
}
|
||||
buf_ptr++;
|
||||
}
|
||||
@ -557,6 +572,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
SLJIT_ASSERT(!label);
|
||||
SLJIT_ASSERT(!jump);
|
||||
SLJIT_ASSERT(!const_);
|
||||
SLJIT_ASSERT(!put_label);
|
||||
SLJIT_ASSERT(code_ptr <= code + compiler->size);
|
||||
|
||||
jump = compiler->jumps;
|
||||
while (jump) {
|
||||
@ -591,8 +608,24 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
jump = jump->next;
|
||||
}
|
||||
|
||||
/* Some space may be wasted because of short jumps. */
|
||||
SLJIT_ASSERT(code_ptr <= code + compiler->size);
|
||||
put_label = compiler->put_labels;
|
||||
while (put_label) {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr);
|
||||
#else
|
||||
if (put_label->flags & PATCH_MD) {
|
||||
SLJIT_ASSERT(put_label->label->addr > HALFWORD_MAX);
|
||||
sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr);
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(put_label->label->addr <= HALFWORD_MAX);
|
||||
sljit_unaligned_store_s32((void*)(put_label->addr - sizeof(sljit_s32)), (sljit_s32)put_label->label->addr);
|
||||
}
|
||||
#endif
|
||||
|
||||
put_label = put_label->next;
|
||||
}
|
||||
|
||||
compiler->error = SLJIT_ERR_COMPILED;
|
||||
compiler->executable_offset = executable_offset;
|
||||
compiler->executable_size = code_ptr - code;
|
||||
@ -2481,7 +2514,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
PTR_FAIL_IF_NULL(jump);
|
||||
set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
|
||||
set_jump(jump, compiler, (type & SLJIT_REWRITABLE_JUMP) | ((type & 0xff) << TYPE_SHIFT));
|
||||
type &= 0xff;
|
||||
|
||||
/* Worst case size. */
|
||||
@ -2495,7 +2528,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
PTR_FAIL_IF_NULL(inst);
|
||||
|
||||
*inst++ = 0;
|
||||
*inst++ = type + 2;
|
||||
*inst++ = 1;
|
||||
return jump;
|
||||
}
|
||||
|
||||
@ -2513,7 +2546,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
||||
if (src == SLJIT_IMM) {
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
FAIL_IF_NULL(jump);
|
||||
set_jump(jump, compiler, JUMP_ADDR);
|
||||
set_jump(jump, compiler, JUMP_ADDR | (type << TYPE_SHIFT));
|
||||
jump->u.target = srcw;
|
||||
|
||||
/* Worst case size. */
|
||||
@ -2527,7 +2560,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
||||
FAIL_IF_NULL(inst);
|
||||
|
||||
*inst++ = 0;
|
||||
*inst++ = type + 2;
|
||||
*inst++ = 1;
|
||||
}
|
||||
else {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
@ -2831,7 +2864,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||
PTR_FAIL_IF(!inst);
|
||||
|
||||
*inst++ = 0;
|
||||
*inst++ = 1;
|
||||
*inst++ = 2;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (dst & SLJIT_MEM)
|
||||
@ -2842,6 +2875,54 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
|
||||
return const_;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
struct sljit_put_label *put_label;
|
||||
sljit_u8 *inst;
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
sljit_s32 reg;
|
||||
sljit_uw start_size;
|
||||
#endif
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
|
||||
ADJUST_LOCAL_OFFSET(dst, dstw);
|
||||
|
||||
CHECK_EXTRA_REGS(dst, dstw, (void)0);
|
||||
|
||||
put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
|
||||
PTR_FAIL_IF(!put_label);
|
||||
set_put_label(put_label, compiler, 0);
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
compiler->mode32 = 0;
|
||||
reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
|
||||
|
||||
if (emit_load_imm64(compiler, reg, 0))
|
||||
return NULL;
|
||||
#else
|
||||
if (emit_mov(compiler, dst, dstw, SLJIT_IMM, 0))
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (dst & SLJIT_MEM) {
|
||||
start_size = compiler->size;
|
||||
if (emit_mov(compiler, dst, dstw, TMP_REG1, 0))
|
||||
return NULL;
|
||||
put_label->flags = compiler->size - start_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 2);
|
||||
PTR_FAIL_IF(!inst);
|
||||
|
||||
*inst++ = 0;
|
||||
*inst++ = 3;
|
||||
|
||||
return put_label;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -154,7 +154,13 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
|
||||
#include "windows.h"
|
||||
#else
|
||||
/* Provides mmap function. */
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#ifndef MAP_ANON
|
||||
#ifdef MAP_ANONYMOUS
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
#endif
|
||||
/* For detecting the page size. */
|
||||
#include <unistd.h>
|
||||
|
||||
|
2
pcre/testdata/testinput2
vendored
2
pcre/testdata/testinput2
vendored
@ -1380,7 +1380,7 @@
|
||||
1X
|
||||
123456\P
|
||||
|
||||
//KF>testsavedregex
|
||||
//S-KF>testsavedregex
|
||||
|
||||
/abc/IS>testsavedregex
|
||||
<testsavedregex
|
||||
|
3
pcre/testdata/testoutput2
vendored
3
pcre/testdata/testoutput2
vendored
@ -5614,9 +5614,8 @@ No match
|
||||
123456\P
|
||||
No match
|
||||
|
||||
//KF>testsavedregex
|
||||
//S-KF>testsavedregex
|
||||
Compiled pattern written to testsavedregex
|
||||
Study data written to testsavedregex
|
||||
|
||||
/abc/IS>testsavedregex
|
||||
Capturing subpattern count = 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user