8.42
This commit is contained in:
parent
dba454ef54
commit
cf242aded5
@ -8,7 +8,7 @@ Email domain: cam.ac.uk
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England.
|
||||
|
||||
Copyright (c) 1997-2017 University of Cambridge
|
||||
Copyright (c) 1997-2018 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-2017 Zoltan Herczeg
|
||||
Copyright(c) 2010-2018 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2009-2017 Zoltan Herczeg
|
||||
Copyright(c) 2009-2018 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
|
@ -4,6 +4,59 @@ ChangeLog for PCRE
|
||||
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.42 20-March-2018
|
||||
--------------------------
|
||||
|
||||
1. Fixed a MIPS issue in the JIT compiler reported by Joshua Kinard.
|
||||
|
||||
2. Fixed outdated real_pcre definitions in pcre.h.in (patch by Evgeny Kotkov).
|
||||
|
||||
3. pcregrep was truncating components of file names to 128 characters when
|
||||
processing files with the -r option, and also (some very odd code) truncating
|
||||
path names to 512 characters. There is now a check on the absolute length of
|
||||
full path file names, which may be up to 2047 characters long.
|
||||
|
||||
4. Using pcre_dfa_exec(), in UTF mode when UCP support was not defined, there
|
||||
was the possibility of a false positive match when caselessly matching a "not
|
||||
this character" item such as [^\x{1234}] (with a code point greater than 127)
|
||||
because the "other case" variable was not being initialized.
|
||||
|
||||
5. Although pcre_jit_exec checks whether the pattern is compiled
|
||||
in a given mode, it was also expected that at least one mode is available.
|
||||
This is fixed and pcre_jit_exec returns with PCRE_ERROR_JIT_BADOPTION
|
||||
when the pattern is not optimized by JIT at all.
|
||||
|
||||
6. The line number and related variables such as match counts in pcregrep
|
||||
were all int variables, causing overflow when files with more than 2147483647
|
||||
lines were processed (assuming 32-bit ints). They have all been changed to
|
||||
unsigned long ints.
|
||||
|
||||
7. If a backreference with a minimum repeat count of zero was first in a
|
||||
pattern, apart from assertions, an incorrect first matching character could be
|
||||
recorded. For example, for the pattern /(?=(a))\1?b/, "b" was incorrectly set
|
||||
as the first character of a match.
|
||||
|
||||
8. Fix out-of-bounds read for partial matching of /./ against an empty string
|
||||
when the newline type is CRLF.
|
||||
|
||||
9. When matching using the the REG_STARTEND feature of the POSIX API with a
|
||||
non-zero starting offset, unset capturing groups with lower numbers than a
|
||||
group that did capture something were not being correctly returned as "unset"
|
||||
(that is, with offset values of -1).
|
||||
|
||||
10. Matching the pattern /(*UTF)\C[^\v]+\x80/ against an 8-bit string
|
||||
containing multi-code-unit characters caused bad behaviour and possibly a
|
||||
crash. This issue was fixed for other kinds of repeat in release 8.37 by change
|
||||
38, but repeating character classes were overlooked.
|
||||
|
||||
11. A small fix to pcregrep to avoid compiler warnings for -Wformat-overflow=2.
|
||||
|
||||
12. Added --enable-jit=auto support to configure.ac.
|
||||
|
||||
13. Fix misleading error message in configure.ac.
|
||||
|
||||
|
||||
Version 8.41 05-July-2017
|
||||
-------------------------
|
||||
|
||||
|
316
pcre/INSTALL
316
pcre/INSTALL
@ -1,8 +1,8 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
|
||||
Inc.
|
||||
Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
|
||||
Foundation, Inc.
|
||||
|
||||
Copying and distribution of this file, with or without modification,
|
||||
are permitted in any medium without royalty provided the copyright
|
||||
@ -12,97 +12,96 @@ without warranty of any kind.
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
Briefly, the shell command `./configure && make && make install'
|
||||
Briefly, the shell command './configure && make && make install'
|
||||
should configure, build, and install this package. The following
|
||||
more-detailed instructions are generic; see the `README' file for
|
||||
more-detailed instructions are generic; see the 'README' file for
|
||||
instructions specific to this package. Some packages provide this
|
||||
`INSTALL' file but do not implement all of the features documented
|
||||
'INSTALL' file but do not implement all of the features documented
|
||||
below. The lack of an optional feature in a given package is not
|
||||
necessarily a bug. More recommendations for GNU packages can be found
|
||||
in *note Makefile Conventions: (standards)Makefile Conventions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
The 'configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
those values to create a 'Makefile' in each directory of the package.
|
||||
It may also create one or more '.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script 'config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
file 'config.log' containing compiler output (useful mainly for
|
||||
debugging 'configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.
|
||||
It can also use an optional file (typically called 'config.cache' and
|
||||
enabled with '--cache-file=config.cache' or simply '-C') that saves the
|
||||
results of its tests to speed up reconfiguring. Caching is disabled by
|
||||
default to prevent problems with accidental use of stale cache files.
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
to figure out how 'configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the 'README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
some point 'config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||
you want to change it or regenerate `configure' using a newer version
|
||||
of `autoconf'.
|
||||
The file 'configure.ac' (or 'configure.in') is used to create
|
||||
'configure' by a program called 'autoconf'. You need 'configure.ac' if
|
||||
you want to change it or regenerate 'configure' using a newer version of
|
||||
'autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system.
|
||||
1. 'cd' to the directory containing the package's source code and type
|
||||
'./configure' to configure the package for your system.
|
||||
|
||||
Running `configure' might take a while. While running, it prints
|
||||
Running 'configure' might take a while. While running, it prints
|
||||
some messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
2. Type 'make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
3. Optionally, type 'make check' to run any self-tests that come with
|
||||
the package, generally using the just-built uninstalled binaries.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
4. Type 'make install' to install the programs and any data files and
|
||||
documentation. When installing into a prefix owned by root, it is
|
||||
recommended that the package be configured and built as a regular
|
||||
user, and only the `make install' phase executed with root
|
||||
user, and only the 'make install' phase executed with root
|
||||
privileges.
|
||||
|
||||
5. Optionally, type `make installcheck' to repeat any self-tests, but
|
||||
5. Optionally, type 'make installcheck' to repeat any self-tests, but
|
||||
this time using the binaries in their final installed location.
|
||||
This target does not install anything. Running this target as a
|
||||
regular user, particularly if the prior `make install' required
|
||||
regular user, particularly if the prior 'make install' required
|
||||
root privileges, verifies that the installation completed
|
||||
correctly.
|
||||
|
||||
6. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
source code directory by typing 'make clean'. To also remove the
|
||||
files that 'configure' created (so you can compile the package for
|
||||
a different kind of computer), type 'make distclean'. There is
|
||||
also a 'make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
7. Often, you can also type `make uninstall' to remove the installed
|
||||
7. Often, you can also type 'make uninstall' to remove the installed
|
||||
files again. In practice, not all packages have tested that
|
||||
uninstallation works correctly, even though it is required by the
|
||||
GNU Coding Standards.
|
||||
|
||||
8. Some packages, particularly those that use Automake, provide `make
|
||||
8. Some packages, particularly those that use Automake, provide 'make
|
||||
distcheck', which can by used by developers to test that all other
|
||||
targets like `make install' and `make uninstall' work correctly.
|
||||
targets like 'make install' and 'make uninstall' work correctly.
|
||||
This target is generally not run by end users.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. Run `./configure --help'
|
||||
the 'configure' script does not know about. Run './configure --help'
|
||||
for details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
You can give 'configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here is
|
||||
an example:
|
||||
|
||||
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||
|
||||
@ -113,21 +112,21 @@ Compiling For Multiple Architectures
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||
own directory. To do this, you can use GNU 'make'. 'cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'. This
|
||||
is known as a "VPATH" build.
|
||||
the 'configure' script. 'configure' automatically checks for the source
|
||||
code in the directory that 'configure' is in and in '..'. This is known
|
||||
as a "VPATH" build.
|
||||
|
||||
With a non-GNU `make', it is safer to compile the package for one
|
||||
With a non-GNU 'make', it is safer to compile the package for one
|
||||
architecture at a time in the source code directory. After you have
|
||||
installed the package for one architecture, use `make distclean' before
|
||||
installed the package for one architecture, use 'make distclean' before
|
||||
reconfiguring for another architecture.
|
||||
|
||||
On MacOS X 10.5 and later systems, you can create libraries and
|
||||
executables that work on multiple system types--known as "fat" or
|
||||
"universal" binaries--by specifying multiple `-arch' options to the
|
||||
compiler but only a single `-arch' option to the preprocessor. Like
|
||||
"universal" binaries--by specifying multiple '-arch' options to the
|
||||
compiler but only a single '-arch' option to the preprocessor. Like
|
||||
this:
|
||||
|
||||
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
|
||||
@ -136,105 +135,104 @@ this:
|
||||
|
||||
This is not guaranteed to produce working output in all cases, you
|
||||
may have to build one architecture at a time and combine the results
|
||||
using the `lipo' tool if you have problems.
|
||||
using the 'lipo' tool if you have problems.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX', where PREFIX must be an
|
||||
By default, 'make install' installs the package's commands under
|
||||
'/usr/local/bin', include files under '/usr/local/include', etc. You
|
||||
can specify an installation prefix other than '/usr/local' by giving
|
||||
'configure' the option '--prefix=PREFIX', where PREFIX must be an
|
||||
absolute file name.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them. In general, the
|
||||
default for these options is expressed in terms of `${prefix}', so that
|
||||
specifying just `--prefix' will affect all of the other directory
|
||||
options like '--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run 'configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them. In general, the default
|
||||
for these options is expressed in terms of '${prefix}', so that
|
||||
specifying just '--prefix' will affect all of the other directory
|
||||
specifications that were not explicitly provided.
|
||||
|
||||
The most portable way to affect installation locations is to pass the
|
||||
correct locations to `configure'; however, many packages provide one or
|
||||
correct locations to 'configure'; however, many packages provide one or
|
||||
both of the following shortcuts of passing variable assignments to the
|
||||
`make install' command line to change installation locations without
|
||||
'make install' command line to change installation locations without
|
||||
having to reconfigure or recompile.
|
||||
|
||||
The first method involves providing an override variable for each
|
||||
affected directory. For example, `make install
|
||||
affected directory. For example, 'make install
|
||||
prefix=/alternate/directory' will choose an alternate location for all
|
||||
directory configuration variables that were expressed in terms of
|
||||
`${prefix}'. Any directories that were specified during `configure',
|
||||
but not in terms of `${prefix}', must each be overridden at install
|
||||
time for the entire installation to be relocated. The approach of
|
||||
makefile variable overrides for each directory variable is required by
|
||||
the GNU Coding Standards, and ideally causes no recompilation.
|
||||
However, some platforms have known limitations with the semantics of
|
||||
shared libraries that end up requiring recompilation when using this
|
||||
method, particularly noticeable in packages that use GNU Libtool.
|
||||
'${prefix}'. Any directories that were specified during 'configure',
|
||||
but not in terms of '${prefix}', must each be overridden at install time
|
||||
for the entire installation to be relocated. The approach of makefile
|
||||
variable overrides for each directory variable is required by the GNU
|
||||
Coding Standards, and ideally causes no recompilation. However, some
|
||||
platforms have known limitations with the semantics of shared libraries
|
||||
that end up requiring recompilation when using this method, particularly
|
||||
noticeable in packages that use GNU Libtool.
|
||||
|
||||
The second method involves providing the `DESTDIR' variable. For
|
||||
example, `make install DESTDIR=/alternate/directory' will prepend
|
||||
`/alternate/directory' before all installation names. The approach of
|
||||
`DESTDIR' overrides is not required by the GNU Coding Standards, and
|
||||
The second method involves providing the 'DESTDIR' variable. For
|
||||
example, 'make install DESTDIR=/alternate/directory' will prepend
|
||||
'/alternate/directory' before all installation names. The approach of
|
||||
'DESTDIR' overrides is not required by the GNU Coding Standards, and
|
||||
does not work on platforms that have drive letters. On the other hand,
|
||||
it does better at avoiding recompilation issues, and works well even
|
||||
when some directory options were not specified in terms of `${prefix}'
|
||||
at `configure' time.
|
||||
when some directory options were not specified in terms of '${prefix}'
|
||||
at 'configure' time.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
with an extra prefix or suffix on their names by giving 'configure' the
|
||||
option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
Some packages pay attention to '--enable-FEATURE' options to
|
||||
'configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to '--with-PACKAGE' options, where PACKAGE
|
||||
is something like 'gnu-as' or 'x' (for the X Window System). The
|
||||
'README' should mention any '--enable-' and '--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
For packages that use the X Window System, 'configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
you can use the 'configure' options '--x-includes=DIR' and
|
||||
'--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Some packages offer the ability to configure how verbose the
|
||||
execution of `make' will be. For these packages, running `./configure
|
||||
execution of 'make' will be. For these packages, running './configure
|
||||
--enable-silent-rules' sets the default to minimal output, which can be
|
||||
overridden with `make V=1'; while running `./configure
|
||||
overridden with 'make V=1'; while running './configure
|
||||
--disable-silent-rules' sets the default to verbose, which can be
|
||||
overridden with `make V=0'.
|
||||
overridden with 'make V=0'.
|
||||
|
||||
Particular systems
|
||||
==================
|
||||
|
||||
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
|
||||
CC is not installed, it is recommended to use the following options in
|
||||
On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC
|
||||
is not installed, it is recommended to use the following options in
|
||||
order to use an ANSI C compiler:
|
||||
|
||||
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
|
||||
|
||||
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
|
||||
|
||||
HP-UX `make' updates targets which have the same time stamps as
|
||||
their prerequisites, which makes it generally unusable when shipped
|
||||
generated files such as `configure' are involved. Use GNU `make'
|
||||
instead.
|
||||
HP-UX 'make' updates targets which have the same time stamps as their
|
||||
prerequisites, which makes it generally unusable when shipped generated
|
||||
files such as 'configure' are involved. Use GNU 'make' instead.
|
||||
|
||||
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
|
||||
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
|
||||
a workaround. If GNU CC is not installed, it is therefore recommended
|
||||
to try
|
||||
parse its '<wchar.h>' header file. The option '-nodtk' can be used as a
|
||||
workaround. If GNU CC is not installed, it is therefore recommended to
|
||||
try
|
||||
|
||||
./configure CC="cc"
|
||||
|
||||
@ -242,26 +240,26 @@ and if that doesn't work, try
|
||||
|
||||
./configure CC="cc -nodtk"
|
||||
|
||||
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
|
||||
On Solaris, don't put '/usr/ucb' early in your 'PATH'. This
|
||||
directory contains several dysfunctional programs; working variants of
|
||||
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
|
||||
in your `PATH', put it _after_ `/usr/bin'.
|
||||
these programs are available in '/usr/bin'. So, if you need '/usr/ucb'
|
||||
in your 'PATH', put it _after_ '/usr/bin'.
|
||||
|
||||
On Haiku, software installed for all users goes in `/boot/common',
|
||||
not `/usr/local'. It is recommended to use the following options:
|
||||
On Haiku, software installed for all users goes in '/boot/common',
|
||||
not '/usr/local'. It is recommended to use the following options:
|
||||
|
||||
./configure --prefix=/boot/common
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out
|
||||
There may be some features 'configure' cannot figure out
|
||||
automatically, but needs to determine by the type of machine the package
|
||||
will run on. Usually, assuming the package is built to be run on the
|
||||
_same_ architectures, `configure' can figure that out, but if it prints
|
||||
_same_ architectures, 'configure' can figure that out, but if it prints
|
||||
a message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
'--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as 'sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
@ -270,101 +268,101 @@ where SYSTEM can have one of these forms:
|
||||
OS
|
||||
KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
See the file 'config.sub' for the possible values of each field. If
|
||||
'config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
use the option '--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
eventually be run) with '--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
If you want to set default values for 'configure' scripts to share,
|
||||
you can create a site shell script called 'config.site' that gives
|
||||
default values for variables like 'CC', 'cache_file', and 'prefix'.
|
||||
'configure' looks for 'PREFIX/share/config.site' if it exists, then
|
||||
'PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
'CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all 'configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
environment passed to 'configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
them in the 'configure' command line, using 'VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
causes the specified 'gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script).
|
||||
|
||||
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||
an Autoconf limitation. Until the limitation is lifted, you can use
|
||||
this workaround:
|
||||
Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
|
||||
Autoconf limitation. Until the limitation is lifted, you can use this
|
||||
workaround:
|
||||
|
||||
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
`configure' Invocation
|
||||
'configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
'configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of all of the options to `configure', and exit.
|
||||
'--help'
|
||||
'-h'
|
||||
Print a summary of all of the options to 'configure', and exit.
|
||||
|
||||
`--help=short'
|
||||
`--help=recursive'
|
||||
'--help=short'
|
||||
'--help=recursive'
|
||||
Print a summary of the options unique to this package's
|
||||
`configure', and exit. The `short' variant lists options used
|
||||
only in the top level, while the `recursive' variant lists options
|
||||
also present in any nested packages.
|
||||
'configure', and exit. The 'short' variant lists options used only
|
||||
in the top level, while the 'recursive' variant lists options also
|
||||
present in any nested packages.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
'--version'
|
||||
'-V'
|
||||
Print the version of Autoconf used to generate the 'configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
'--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
traditionally 'config.cache'. FILE defaults to '/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
'--config-cache'
|
||||
'-C'
|
||||
Alias for '--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
'--quiet'
|
||||
'--silent'
|
||||
'-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
suppress all normal output, redirect it to '/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
'--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
'configure' can determine that directory automatically.
|
||||
|
||||
`--prefix=DIR'
|
||||
Use DIR as the installation prefix. *note Installation Names::
|
||||
for more details, including other options available for fine-tuning
|
||||
the installation locations.
|
||||
'--prefix=DIR'
|
||||
Use DIR as the installation prefix. *note Installation Names:: for
|
||||
more details, including other options available for fine-tuning the
|
||||
installation locations.
|
||||
|
||||
`--no-create'
|
||||
`-n'
|
||||
'--no-create'
|
||||
'-n'
|
||||
Run the configure checks, but stop before creating any output
|
||||
files.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
'configure' also accepts some other, not widely useful, options. Run
|
||||
'configure --help' for more details.
|
||||
|
@ -25,7 +25,7 @@ Email domain: cam.ac.uk
|
||||
University of Cambridge Computing Service,
|
||||
Cambridge, England.
|
||||
|
||||
Copyright (c) 1997-2017 University of Cambridge
|
||||
Copyright (c) 1997-2018 University of Cambridge
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2010-2017 Zoltan Herczeg
|
||||
Copyright(c) 2010-2018 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ Written by: Zoltan Herczeg
|
||||
Email local part: hzmester
|
||||
Emain domain: freemail.hu
|
||||
|
||||
Copyright(c) 2009-2017 Zoltan Herczeg
|
||||
Copyright(c) 2009-2018 Zoltan Herczeg
|
||||
All rights reserved.
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Makefile.in generated by automake 1.15 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.15.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2017 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -251,7 +251,7 @@ libpcre_la_OBJECTS = $(am_libpcre_la_OBJECTS) \
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
am__v_lt_0 = --silent
|
||||
am__v_lt_1 =
|
||||
am__v_lt_1 =
|
||||
libpcre_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libpcre_la_CFLAGS) \
|
||||
$(CFLAGS) $(libpcre_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
@ -449,11 +449,11 @@ am__v_P_1 = :
|
||||
AM_V_GEN = $(am__v_GEN_@AM_V@)
|
||||
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
|
||||
am__v_GEN_0 = @echo " GEN " $@;
|
||||
am__v_GEN_1 =
|
||||
am__v_GEN_1 =
|
||||
AM_V_at = $(am__v_at_@AM_V@)
|
||||
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
|
||||
am__v_at_0 = @
|
||||
am__v_at_1 =
|
||||
am__v_at_1 =
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
@ -467,7 +467,7 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
AM_V_CC = $(am__v_CC_@AM_V@)
|
||||
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
am__v_CC_1 =
|
||||
am__v_CC_1 =
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
@ -475,7 +475,7 @@ LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
|
||||
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_CCLD_1 =
|
||||
am__v_CCLD_1 =
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
@ -485,7 +485,7 @@ LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
AM_V_CXX = $(am__v_CXX_@AM_V@)
|
||||
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
|
||||
am__v_CXX_0 = @echo " CXX " $@;
|
||||
am__v_CXX_1 =
|
||||
am__v_CXX_1 =
|
||||
CXXLD = $(CXX)
|
||||
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
|
||||
@ -493,7 +493,7 @@ CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
|
||||
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
|
||||
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
|
||||
am__v_CXXLD_0 = @echo " CXXLD " $@;
|
||||
am__v_CXXLD_1 =
|
||||
am__v_CXXLD_1 =
|
||||
SOURCES = $(libpcre_la_SOURCES) $(nodist_libpcre_la_SOURCES) \
|
||||
$(libpcre16_la_SOURCES) $(nodist_libpcre16_la_SOURCES) \
|
||||
$(libpcre32_la_SOURCES) $(nodist_libpcre32_la_SOURCES) \
|
||||
@ -988,7 +988,7 @@ dist_noinst_DATA = $(pcrecpp_html)
|
||||
# The Libtool libraries to install. We'll add to this later.
|
||||
lib_LTLIBRARIES = $(am__append_4) $(am__append_5) $(am__append_6) \
|
||||
$(am__append_20) $(am__append_22)
|
||||
check_SCRIPTS =
|
||||
check_SCRIPTS =
|
||||
dist_noinst_SCRIPTS = RunTest $(am__append_39)
|
||||
|
||||
# Additional files to delete on 'make clean' and 'make maintainer-clean'.
|
||||
@ -1110,7 +1110,7 @@ BUILT_SOURCES = pcre_chartables.c
|
||||
|
||||
@WITH_PCRE8_TRUE@libpcre_la_CFLAGS = $(VISIBILITY_CFLAGS) $(AM_CFLAGS) \
|
||||
@WITH_PCRE8_TRUE@ $(am__append_7) $(am__append_10)
|
||||
@WITH_PCRE8_TRUE@libpcre_la_LIBADD =
|
||||
@WITH_PCRE8_TRUE@libpcre_la_LIBADD =
|
||||
@WITH_PCRE8_TRUE@nodist_libpcre_la_SOURCES = \
|
||||
@WITH_PCRE8_TRUE@ pcre_chartables.c
|
||||
|
||||
@ -1141,7 +1141,7 @@ BUILT_SOURCES = pcre_chartables.c
|
||||
@WITH_PCRE16_TRUE@libpcre16_la_CFLAGS = $(VISIBILITY_CFLAGS) \
|
||||
@WITH_PCRE16_TRUE@ $(AM_CFLAGS) $(am__append_8) \
|
||||
@WITH_PCRE16_TRUE@ $(am__append_11)
|
||||
@WITH_PCRE16_TRUE@libpcre16_la_LIBADD =
|
||||
@WITH_PCRE16_TRUE@libpcre16_la_LIBADD =
|
||||
@WITH_PCRE16_TRUE@nodist_libpcre16_la_SOURCES = \
|
||||
@WITH_PCRE16_TRUE@ pcre_chartables.c
|
||||
|
||||
@ -1172,7 +1172,7 @@ BUILT_SOURCES = pcre_chartables.c
|
||||
@WITH_PCRE32_TRUE@libpcre32_la_CFLAGS = $(VISIBILITY_CFLAGS) \
|
||||
@WITH_PCRE32_TRUE@ $(AM_CFLAGS) $(am__append_9) \
|
||||
@WITH_PCRE32_TRUE@ $(am__append_12)
|
||||
@WITH_PCRE32_TRUE@libpcre32_la_LIBADD =
|
||||
@WITH_PCRE32_TRUE@libpcre32_la_LIBADD =
|
||||
@WITH_PCRE32_TRUE@nodist_libpcre32_la_SOURCES = \
|
||||
@WITH_PCRE32_TRUE@ pcre_chartables.c
|
||||
|
||||
@ -1313,8 +1313,8 @@ pcrecpp_man = doc/pcrecpp.3
|
||||
@WITH_GCOV_TRUE@COVERAGE_NAME = $(PACKAGE)-$(VERSION)
|
||||
@WITH_GCOV_TRUE@COVERAGE_OUTPUT_FILE = $(COVERAGE_NAME)-coverage.info
|
||||
@WITH_GCOV_TRUE@COVERAGE_OUTPUT_DIR = $(COVERAGE_NAME)-coverage
|
||||
@WITH_GCOV_TRUE@COVERAGE_LCOV_EXTRA_FLAGS =
|
||||
@WITH_GCOV_TRUE@COVERAGE_GENHTML_EXTRA_FLAGS =
|
||||
@WITH_GCOV_TRUE@COVERAGE_LCOV_EXTRA_FLAGS =
|
||||
@WITH_GCOV_TRUE@COVERAGE_GENHTML_EXTRA_FLAGS =
|
||||
@WITH_GCOV_TRUE@coverage_quiet = $(coverage_quiet_$(V))
|
||||
@WITH_GCOV_TRUE@coverage_quiet_ = $(coverage_quiet_$(AM_DEFAULT_VERBOSITY))
|
||||
@WITH_GCOV_TRUE@coverage_quiet_0 = --quiet
|
||||
@ -1364,7 +1364,7 @@ config.h: stamp-h1
|
||||
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
|
||||
@rm -f stamp-h1
|
||||
cd $(top_builddir) && $(SHELL) ./config.status config.h
|
||||
$(srcdir)/config.h.in: $(am__configure_deps)
|
||||
$(srcdir)/config.h.in: $(am__configure_deps)
|
||||
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
|
||||
rm -f stamp-h1
|
||||
touch $@
|
||||
@ -1425,19 +1425,19 @@ clean-libLTLIBRARIES:
|
||||
rm -f $${locs}; \
|
||||
}
|
||||
|
||||
libpcre.la: $(libpcre_la_OBJECTS) $(libpcre_la_DEPENDENCIES) $(EXTRA_libpcre_la_DEPENDENCIES)
|
||||
libpcre.la: $(libpcre_la_OBJECTS) $(libpcre_la_DEPENDENCIES) $(EXTRA_libpcre_la_DEPENDENCIES)
|
||||
$(AM_V_CCLD)$(libpcre_la_LINK) $(am_libpcre_la_rpath) $(libpcre_la_OBJECTS) $(libpcre_la_LIBADD) $(LIBS)
|
||||
|
||||
libpcre16.la: $(libpcre16_la_OBJECTS) $(libpcre16_la_DEPENDENCIES) $(EXTRA_libpcre16_la_DEPENDENCIES)
|
||||
libpcre16.la: $(libpcre16_la_OBJECTS) $(libpcre16_la_DEPENDENCIES) $(EXTRA_libpcre16_la_DEPENDENCIES)
|
||||
$(AM_V_CCLD)$(libpcre16_la_LINK) $(am_libpcre16_la_rpath) $(libpcre16_la_OBJECTS) $(libpcre16_la_LIBADD) $(LIBS)
|
||||
|
||||
libpcre32.la: $(libpcre32_la_OBJECTS) $(libpcre32_la_DEPENDENCIES) $(EXTRA_libpcre32_la_DEPENDENCIES)
|
||||
libpcre32.la: $(libpcre32_la_OBJECTS) $(libpcre32_la_DEPENDENCIES) $(EXTRA_libpcre32_la_DEPENDENCIES)
|
||||
$(AM_V_CCLD)$(libpcre32_la_LINK) $(am_libpcre32_la_rpath) $(libpcre32_la_OBJECTS) $(libpcre32_la_LIBADD) $(LIBS)
|
||||
|
||||
libpcrecpp.la: $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_DEPENDENCIES) $(EXTRA_libpcrecpp_la_DEPENDENCIES)
|
||||
libpcrecpp.la: $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_DEPENDENCIES) $(EXTRA_libpcrecpp_la_DEPENDENCIES)
|
||||
$(AM_V_CXXLD)$(libpcrecpp_la_LINK) $(am_libpcrecpp_la_rpath) $(libpcrecpp_la_OBJECTS) $(libpcrecpp_la_LIBADD) $(LIBS)
|
||||
|
||||
libpcreposix.la: $(libpcreposix_la_OBJECTS) $(libpcreposix_la_DEPENDENCIES) $(EXTRA_libpcreposix_la_DEPENDENCIES)
|
||||
libpcreposix.la: $(libpcreposix_la_OBJECTS) $(libpcreposix_la_DEPENDENCIES) $(EXTRA_libpcreposix_la_DEPENDENCIES)
|
||||
$(AM_V_CCLD)$(libpcreposix_la_LINK) $(am_libpcreposix_la_rpath) $(libpcreposix_la_OBJECTS) $(libpcreposix_la_LIBADD) $(LIBS)
|
||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
@$(NORMAL_INSTALL)
|
||||
@ -1498,31 +1498,31 @@ clean-noinstPROGRAMS:
|
||||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
|
||||
dftables$(EXEEXT): $(dftables_OBJECTS) $(dftables_DEPENDENCIES) $(EXTRA_dftables_DEPENDENCIES)
|
||||
dftables$(EXEEXT): $(dftables_OBJECTS) $(dftables_DEPENDENCIES) $(EXTRA_dftables_DEPENDENCIES)
|
||||
@rm -f dftables$(EXEEXT)
|
||||
$(AM_V_CCLD)$(LINK) $(dftables_OBJECTS) $(dftables_LDADD) $(LIBS)
|
||||
|
||||
pcre_jit_test$(EXEEXT): $(pcre_jit_test_OBJECTS) $(pcre_jit_test_DEPENDENCIES) $(EXTRA_pcre_jit_test_DEPENDENCIES)
|
||||
pcre_jit_test$(EXEEXT): $(pcre_jit_test_OBJECTS) $(pcre_jit_test_DEPENDENCIES) $(EXTRA_pcre_jit_test_DEPENDENCIES)
|
||||
@rm -f pcre_jit_test$(EXEEXT)
|
||||
$(AM_V_CCLD)$(pcre_jit_test_LINK) $(pcre_jit_test_OBJECTS) $(pcre_jit_test_LDADD) $(LIBS)
|
||||
|
||||
pcre_scanner_unittest$(EXEEXT): $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_DEPENDENCIES) $(EXTRA_pcre_scanner_unittest_DEPENDENCIES)
|
||||
pcre_scanner_unittest$(EXEEXT): $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_DEPENDENCIES) $(EXTRA_pcre_scanner_unittest_DEPENDENCIES)
|
||||
@rm -f pcre_scanner_unittest$(EXEEXT)
|
||||
$(AM_V_CXXLD)$(pcre_scanner_unittest_LINK) $(pcre_scanner_unittest_OBJECTS) $(pcre_scanner_unittest_LDADD) $(LIBS)
|
||||
|
||||
pcre_stringpiece_unittest$(EXEEXT): $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_DEPENDENCIES) $(EXTRA_pcre_stringpiece_unittest_DEPENDENCIES)
|
||||
pcre_stringpiece_unittest$(EXEEXT): $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_DEPENDENCIES) $(EXTRA_pcre_stringpiece_unittest_DEPENDENCIES)
|
||||
@rm -f pcre_stringpiece_unittest$(EXEEXT)
|
||||
$(AM_V_CXXLD)$(pcre_stringpiece_unittest_LINK) $(pcre_stringpiece_unittest_OBJECTS) $(pcre_stringpiece_unittest_LDADD) $(LIBS)
|
||||
|
||||
pcrecpp_unittest$(EXEEXT): $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_DEPENDENCIES) $(EXTRA_pcrecpp_unittest_DEPENDENCIES)
|
||||
pcrecpp_unittest$(EXEEXT): $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_DEPENDENCIES) $(EXTRA_pcrecpp_unittest_DEPENDENCIES)
|
||||
@rm -f pcrecpp_unittest$(EXEEXT)
|
||||
$(AM_V_CXXLD)$(pcrecpp_unittest_LINK) $(pcrecpp_unittest_OBJECTS) $(pcrecpp_unittest_LDADD) $(LIBS)
|
||||
|
||||
pcregrep$(EXEEXT): $(pcregrep_OBJECTS) $(pcregrep_DEPENDENCIES) $(EXTRA_pcregrep_DEPENDENCIES)
|
||||
pcregrep$(EXEEXT): $(pcregrep_OBJECTS) $(pcregrep_DEPENDENCIES) $(EXTRA_pcregrep_DEPENDENCIES)
|
||||
@rm -f pcregrep$(EXEEXT)
|
||||
$(AM_V_CCLD)$(pcregrep_LINK) $(pcregrep_OBJECTS) $(pcregrep_LDADD) $(LIBS)
|
||||
|
||||
pcretest$(EXEEXT): $(pcretest_OBJECTS) $(pcretest_DEPENDENCIES) $(EXTRA_pcretest_DEPENDENCIES)
|
||||
pcretest$(EXEEXT): $(pcretest_OBJECTS) $(pcretest_DEPENDENCIES) $(EXTRA_pcretest_DEPENDENCIES)
|
||||
@rm -f pcretest$(EXEEXT)
|
||||
$(AM_V_CCLD)$(pcretest_LINK) $(pcretest_OBJECTS) $(pcretest_LDADD) $(LIBS)
|
||||
install-binSCRIPTS: $(bin_SCRIPTS)
|
||||
@ -3003,8 +3003,8 @@ maintainer-clean-generic:
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
@WITH_GCOV_FALSE@distclean-local:
|
||||
@WITH_GCOV_FALSE@clean-local:
|
||||
@WITH_GCOV_FALSE@distclean-local:
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
|
||||
|
@ -1,6 +1,12 @@
|
||||
News about PCRE releases
|
||||
------------------------
|
||||
|
||||
Release 8.42 20-March-2018
|
||||
--------------------------
|
||||
|
||||
This is a bug-fix release.
|
||||
|
||||
|
||||
Release 8.41 13-June-2017
|
||||
-------------------------
|
||||
|
||||
|
@ -760,13 +760,14 @@ The character code used is EBCDIC, not ASCII or Unicode. In z/OS, UNIX APIs and
|
||||
applications can be supported through UNIX System Services, and in such an
|
||||
environment PCRE can be built in the same way as in other systems. However, in
|
||||
native z/OS (without UNIX System Services) and in z/VM, special ports are
|
||||
required. For details, please see this web site:
|
||||
required. PCRE1 version 8.39 is available in file 882 on this site:
|
||||
|
||||
http://www.zaconsultants.net
|
||||
http://www.cbttape.org
|
||||
|
||||
You may download PCRE from WWW.CBTTAPE.ORG, file 882. Everything, source and
|
||||
executable, is in EBCDIC and native z/OS file formats and this is the
|
||||
recommended download site.
|
||||
Everything, source and executable, is in EBCDIC and native z/OS file formats.
|
||||
However, this software is not maintained and will not be upgraded. If you are
|
||||
new to PCRE you should be looking at PCRE2 (version 10.30 or later).
|
||||
|
||||
==========================
|
||||
Last Updated: 25 June 2015
|
||||
===============================
|
||||
Last Updated: 13 September 2017
|
||||
===============================
|
||||
|
46
pcre/aclocal.m4
vendored
46
pcre/aclocal.m4
vendored
@ -1,6 +1,6 @@
|
||||
# generated automatically by aclocal 1.15 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -296,7 +296,7 @@ AS_VAR_COPY([$1], [pkg_cv_][$1])
|
||||
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
||||
])dnl PKG_CHECK_VAR
|
||||
|
||||
# Copyright (C) 2002-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2002-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -311,7 +311,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||
[am__api_version='1.15'
|
||||
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||
dnl require some minimum version. Point them to the right macro.
|
||||
m4_if([$1], [1.15], [],
|
||||
m4_if([$1], [1.15.1], [],
|
||||
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||
])
|
||||
|
||||
@ -327,12 +327,12 @@ m4_define([_AM_AUTOCONF_VERSION], [])
|
||||
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.15])dnl
|
||||
[AM_AUTOMAKE_VERSION([1.15.1])dnl
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||
|
||||
# Copyright (C) 2011-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -394,7 +394,7 @@ AC_SUBST([AR])dnl
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -446,7 +446,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -477,7 +477,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -668,7 +668,7 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl
|
||||
|
||||
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -744,7 +744,7 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
|
||||
# Do all the work for Automake. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -941,7 +941,7 @@ for _am_header in $config_headers :; do
|
||||
done
|
||||
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -962,7 +962,7 @@ if test x"${install_sh+set}" != xset; then
|
||||
fi
|
||||
AC_SUBST([install_sh])])
|
||||
|
||||
# Copyright (C) 2003-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2003-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -983,7 +983,7 @@ AC_SUBST([am__leading_dot])])
|
||||
|
||||
# Check to see how 'make' treats includes. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -1033,7 +1033,7 @@ rm -f confinc confmf
|
||||
|
||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -1072,7 +1072,7 @@ fi
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -1101,7 +1101,7 @@ AC_DEFUN([_AM_SET_OPTIONS],
|
||||
AC_DEFUN([_AM_IF_OPTION],
|
||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||
|
||||
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -1148,7 +1148,7 @@ AC_LANG_POP([C])])
|
||||
# For backward compatibility.
|
||||
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -1167,7 +1167,7 @@ AC_DEFUN([AM_RUN_LOG],
|
||||
|
||||
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -1248,7 +1248,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||
rm -f conftest.file
|
||||
])
|
||||
|
||||
# Copyright (C) 2009-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -1308,7 +1308,7 @@ AC_SUBST([AM_BACKSLASH])dnl
|
||||
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
|
||||
])
|
||||
|
||||
# Copyright (C) 2001-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -1336,7 +1336,7 @@ fi
|
||||
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||
|
||||
# Copyright (C) 2006-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2006-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -1355,7 +1355,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||
|
||||
# Check how to create a tarball. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2004-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2004-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
@ -4,7 +4,7 @@
|
||||
me=ar-lib
|
||||
scriptversion=2012-03-01.08; # UTC
|
||||
|
||||
# Copyright (C) 2010-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2010-2017 Free Software Foundation, Inc.
|
||||
# Written by Peter Rosin <peda@lysator.liu.se>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
@ -1,9 +1,9 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand '-c -o'.
|
||||
|
||||
scriptversion=2012-10-14.11; # UTC
|
||||
scriptversion=2016-01-11.22; # UTC
|
||||
|
||||
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@ -255,7 +255,8 @@ EOF
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
|
||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
|
||||
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
|
||||
func_cl_wrapper "$@" # Doesn't return...
|
||||
;;
|
||||
esac
|
||||
@ -342,6 +343,6 @@ exit $ret
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
|
188
pcre/config.guess
vendored
188
pcre/config.guess
vendored
@ -1,8 +1,8 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2014 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2017 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2014-11-04'
|
||||
timestamp='2017-05-27'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@ -27,7 +27,7 @@ timestamp='2014-11-04'
|
||||
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
|
||||
#
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
|
||||
#
|
||||
# Please send patches to <config-patches@gnu.org>.
|
||||
|
||||
@ -50,7 +50,7 @@ version="\
|
||||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright 1992-2014 Free Software Foundation, Inc.
|
||||
Copyright 1992-2017 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@ -168,19 +168,29 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# Note: NetBSD doesn't particularly care about the vendor
|
||||
# portion of the name. We always set it to "unknown".
|
||||
sysctl="sysctl -n hw.machine_arch"
|
||||
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
|
||||
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
|
||||
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
|
||||
/sbin/$sysctl 2>/dev/null || \
|
||||
/usr/sbin/$sysctl 2>/dev/null || \
|
||||
echo unknown)`
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
armeb) machine=armeb-unknown ;;
|
||||
arm*) machine=arm-unknown ;;
|
||||
sh3el) machine=shl-unknown ;;
|
||||
sh3eb) machine=sh-unknown ;;
|
||||
sh5el) machine=sh5le-unknown ;;
|
||||
earmv*)
|
||||
arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
|
||||
endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
|
||||
machine=${arch}${endian}-unknown
|
||||
;;
|
||||
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
||||
esac
|
||||
# The Operating System including object format, if it has switched
|
||||
# to ELF recently, or will in the future.
|
||||
# to ELF recently (or will in the future) and ABI.
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
earm*)
|
||||
os=netbsdelf
|
||||
;;
|
||||
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||
eval $set_cc_for_build
|
||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
@ -197,6 +207,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
os=netbsd
|
||||
;;
|
||||
esac
|
||||
# Determine ABI tags.
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
earm*)
|
||||
expr='s/^earmv[0-9]/-eabi/;s/eb$//'
|
||||
abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
|
||||
;;
|
||||
esac
|
||||
# The OS release
|
||||
# Debian GNU/NetBSD machines have a different userland, and
|
||||
# thus, need a distinct triplet. However, they do not need
|
||||
@ -207,13 +224,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
release='-gnu'
|
||||
;;
|
||||
*)
|
||||
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
|
||||
;;
|
||||
esac
|
||||
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
|
||||
# contains redundant information, the shorter form:
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||
echo "${machine}-${os}${release}"
|
||||
echo "${machine}-${os}${release}${abi}"
|
||||
exit ;;
|
||||
*:Bitrig:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
|
||||
@ -223,6 +240,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
|
||||
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:LibertyBSD:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
|
||||
echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:ekkoBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@ -235,6 +256,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
*:MirBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:Sortix:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-sortix
|
||||
exit ;;
|
||||
alpha:OSF1:*:*)
|
||||
case $UNAME_RELEASE in
|
||||
*4.0)
|
||||
@ -251,42 +275,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
|
||||
case "$ALPHA_CPU_TYPE" in
|
||||
"EV4 (21064)")
|
||||
UNAME_MACHINE="alpha" ;;
|
||||
UNAME_MACHINE=alpha ;;
|
||||
"EV4.5 (21064)")
|
||||
UNAME_MACHINE="alpha" ;;
|
||||
UNAME_MACHINE=alpha ;;
|
||||
"LCA4 (21066/21068)")
|
||||
UNAME_MACHINE="alpha" ;;
|
||||
UNAME_MACHINE=alpha ;;
|
||||
"EV5 (21164)")
|
||||
UNAME_MACHINE="alphaev5" ;;
|
||||
UNAME_MACHINE=alphaev5 ;;
|
||||
"EV5.6 (21164A)")
|
||||
UNAME_MACHINE="alphaev56" ;;
|
||||
UNAME_MACHINE=alphaev56 ;;
|
||||
"EV5.6 (21164PC)")
|
||||
UNAME_MACHINE="alphapca56" ;;
|
||||
UNAME_MACHINE=alphapca56 ;;
|
||||
"EV5.7 (21164PC)")
|
||||
UNAME_MACHINE="alphapca57" ;;
|
||||
UNAME_MACHINE=alphapca57 ;;
|
||||
"EV6 (21264)")
|
||||
UNAME_MACHINE="alphaev6" ;;
|
||||
UNAME_MACHINE=alphaev6 ;;
|
||||
"EV6.7 (21264A)")
|
||||
UNAME_MACHINE="alphaev67" ;;
|
||||
UNAME_MACHINE=alphaev67 ;;
|
||||
"EV6.8CB (21264C)")
|
||||
UNAME_MACHINE="alphaev68" ;;
|
||||
UNAME_MACHINE=alphaev68 ;;
|
||||
"EV6.8AL (21264B)")
|
||||
UNAME_MACHINE="alphaev68" ;;
|
||||
UNAME_MACHINE=alphaev68 ;;
|
||||
"EV6.8CX (21264D)")
|
||||
UNAME_MACHINE="alphaev68" ;;
|
||||
UNAME_MACHINE=alphaev68 ;;
|
||||
"EV6.9A (21264/EV69A)")
|
||||
UNAME_MACHINE="alphaev69" ;;
|
||||
UNAME_MACHINE=alphaev69 ;;
|
||||
"EV7 (21364)")
|
||||
UNAME_MACHINE="alphaev7" ;;
|
||||
UNAME_MACHINE=alphaev7 ;;
|
||||
"EV7.9 (21364A)")
|
||||
UNAME_MACHINE="alphaev79" ;;
|
||||
UNAME_MACHINE=alphaev79 ;;
|
||||
esac
|
||||
# A Pn.n version is a patched version.
|
||||
# A Vn.n version is a released version.
|
||||
# A Tn.n version is a released field test version.
|
||||
# A Xn.n version is an unreleased experimental baselevel.
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
|
||||
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
|
||||
exitcode=$?
|
||||
trap '' 0
|
||||
@ -359,16 +383,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
exit ;;
|
||||
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
||||
eval $set_cc_for_build
|
||||
SUN_ARCH="i386"
|
||||
SUN_ARCH=i386
|
||||
# If there is a compiler, see if it is configured for 64-bit objects.
|
||||
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
|
||||
# This test works for both compilers.
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
|
||||
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
SUN_ARCH="x86_64"
|
||||
SUN_ARCH=x86_64
|
||||
fi
|
||||
fi
|
||||
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
@ -393,7 +417,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
exit ;;
|
||||
sun*:*:4.2BSD:*)
|
||||
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
|
||||
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
|
||||
test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
|
||||
case "`/bin/arch`" in
|
||||
sun3)
|
||||
echo m68k-sun-sunos${UNAME_RELEASE}
|
||||
@ -618,13 +642,13 @@ EOF
|
||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
||||
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
|
||||
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
|
||||
532) # CPU_PA_RISC2_0
|
||||
case "${sc_kernel_bits}" in
|
||||
32) HP_ARCH="hppa2.0n" ;;
|
||||
64) HP_ARCH="hppa2.0w" ;;
|
||||
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
|
||||
32) HP_ARCH=hppa2.0n ;;
|
||||
64) HP_ARCH=hppa2.0w ;;
|
||||
'') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
|
||||
esac ;;
|
||||
esac
|
||||
fi
|
||||
@ -663,11 +687,11 @@ EOF
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
||||
(CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
||||
test -z "$HP_ARCH" && HP_ARCH=hppa
|
||||
fi ;;
|
||||
esac
|
||||
if [ ${HP_ARCH} = "hppa2.0w" ]
|
||||
if [ ${HP_ARCH} = hppa2.0w ]
|
||||
then
|
||||
eval $set_cc_for_build
|
||||
|
||||
@ -680,12 +704,12 @@ EOF
|
||||
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
|
||||
# => hppa64-hp-hpux11.23
|
||||
|
||||
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
|
||||
if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
|
||||
grep -q __LP64__
|
||||
then
|
||||
HP_ARCH="hppa2.0w"
|
||||
HP_ARCH=hppa2.0w
|
||||
else
|
||||
HP_ARCH="hppa64"
|
||||
HP_ARCH=hppa64
|
||||
fi
|
||||
fi
|
||||
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
|
||||
@ -790,14 +814,14 @@ EOF
|
||||
echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit ;;
|
||||
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
||||
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
|
||||
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
5000:UNIX_System_V:4.*:*)
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
|
||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
||||
@ -813,10 +837,11 @@ EOF
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
case ${UNAME_PROCESSOR} in
|
||||
amd64)
|
||||
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
*)
|
||||
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
UNAME_PROCESSOR=x86_64 ;;
|
||||
i386)
|
||||
UNAME_PROCESSOR=i586 ;;
|
||||
esac
|
||||
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit ;;
|
||||
i*:CYGWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-cygwin
|
||||
@ -879,7 +904,7 @@ EOF
|
||||
exit ;;
|
||||
*:GNU/*:*:*)
|
||||
# other systems with GNU libc and userland
|
||||
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
|
||||
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
|
||||
exit ;;
|
||||
i*86:Minix:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-minix
|
||||
@ -902,7 +927,7 @@ EOF
|
||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep -q ld.so.1
|
||||
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
|
||||
if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
arc:Linux:*:* | arceb:Linux:*:*)
|
||||
@ -933,6 +958,9 @@ EOF
|
||||
crisv32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||||
exit ;;
|
||||
e2k:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
@ -945,6 +973,9 @@ EOF
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
k1om:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
@ -970,6 +1001,9 @@ EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
|
||||
;;
|
||||
mips64el:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
openrisc*:Linux:*:*)
|
||||
echo or1k-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
@ -1002,6 +1036,9 @@ EOF
|
||||
ppcle:Linux:*:*)
|
||||
echo powerpcle-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
riscv32:Linux:*:* | riscv64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
s390:Linux:*:* | s390x:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
|
||||
exit ;;
|
||||
@ -1021,7 +1058,7 @@ EOF
|
||||
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
|
||||
exit ;;
|
||||
x86_64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
|
||||
exit ;;
|
||||
xtensa*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
@ -1100,7 +1137,7 @@ EOF
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i586.
|
||||
# Note: whatever this is, it MUST be the same as what config.sub
|
||||
# prints for the "djgpp" host, or else GDB configury will decide that
|
||||
# prints for the "djgpp" host, or else GDB configure will decide that
|
||||
# this is a cross-build.
|
||||
echo i586-pc-msdosdjgpp
|
||||
exit ;;
|
||||
@ -1249,6 +1286,9 @@ EOF
|
||||
SX-8R:SUPER-UX:*:*)
|
||||
echo sx8r-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SX-ACE:SUPER-UX:*:*)
|
||||
echo sxace-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
Power*:Rhapsody:*:*)
|
||||
echo powerpc-apple-rhapsody${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@ -1262,16 +1302,23 @@ EOF
|
||||
UNAME_PROCESSOR=powerpc
|
||||
fi
|
||||
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
|
||||
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
case $UNAME_PROCESSOR in
|
||||
i386) UNAME_PROCESSOR=x86_64 ;;
|
||||
powerpc) UNAME_PROCESSOR=powerpc64 ;;
|
||||
esac
|
||||
fi
|
||||
# On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
|
||||
if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
|
||||
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_PPC >/dev/null
|
||||
then
|
||||
UNAME_PROCESSOR=powerpc
|
||||
fi
|
||||
fi
|
||||
elif test "$UNAME_PROCESSOR" = i386 ; then
|
||||
# Avoid executing cc on OS X 10.9, as it ships with a stub
|
||||
@ -1286,7 +1333,7 @@ EOF
|
||||
exit ;;
|
||||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||||
UNAME_PROCESSOR=`uname -p`
|
||||
if test "$UNAME_PROCESSOR" = "x86"; then
|
||||
if test "$UNAME_PROCESSOR" = x86; then
|
||||
UNAME_PROCESSOR=i386
|
||||
UNAME_MACHINE=pc
|
||||
fi
|
||||
@ -1295,15 +1342,18 @@ EOF
|
||||
*:QNX:*:4*)
|
||||
echo i386-pc-qnx
|
||||
exit ;;
|
||||
NEO-?:NONSTOP_KERNEL:*:*)
|
||||
NEO-*:NONSTOP_KERNEL:*:*)
|
||||
echo neo-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSE-*:NONSTOP_KERNEL:*:*)
|
||||
echo nse-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSR-?:NONSTOP_KERNEL:*:*)
|
||||
NSR-*:NONSTOP_KERNEL:*:*)
|
||||
echo nsr-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSX-*:NONSTOP_KERNEL:*:*)
|
||||
echo nsx-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:NonStop-UX:*:*)
|
||||
echo mips-compaq-nonstopux
|
||||
exit ;;
|
||||
@ -1317,7 +1367,7 @@ EOF
|
||||
# "uname -m" is not consistent, so use $cputype instead. 386
|
||||
# is converted to i386 for consistency with other x86
|
||||
# operating systems.
|
||||
if test "$cputype" = "386"; then
|
||||
if test "$cputype" = 386; then
|
||||
UNAME_MACHINE=i386
|
||||
else
|
||||
UNAME_MACHINE="$cputype"
|
||||
@ -1359,7 +1409,7 @@ EOF
|
||||
echo i386-pc-xenix
|
||||
exit ;;
|
||||
i*86:skyos:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
|
||||
echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
|
||||
exit ;;
|
||||
i*86:rdos:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-rdos
|
||||
@ -1370,23 +1420,25 @@ EOF
|
||||
x86_64:VMkernel:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-esx
|
||||
exit ;;
|
||||
amd64:Isilon\ OneFS:*:*)
|
||||
echo x86_64-unknown-onefs
|
||||
exit ;;
|
||||
esac
|
||||
|
||||
cat >&2 <<EOF
|
||||
$0: unable to guess system type
|
||||
|
||||
This script, last modified $timestamp, has failed to recognize
|
||||
the operating system you are using. It is advised that you
|
||||
download the most up to date version of the config scripts from
|
||||
This script (version $timestamp), has failed to recognize the
|
||||
operating system you are using. If your script is old, overwrite
|
||||
config.guess and config.sub with the latest versions from:
|
||||
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
|
||||
and
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
|
||||
|
||||
If the version you run ($0) is already up to date, please
|
||||
send the following data and any information you think might be
|
||||
pertinent to <config-patches@gnu.org> in order to provide the needed
|
||||
information to handle your system.
|
||||
If $0 has already been updated, send the following data and any
|
||||
information you think might be pertinent to config-patches@gnu.org to
|
||||
provide the necessary information to handle your system.
|
||||
|
||||
config.guess timestamp = $timestamp
|
||||
|
||||
|
@ -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.41"
|
||||
#define PACKAGE_STRING "PCRE 8.42"
|
||||
|
||||
/* 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.41"
|
||||
#define PACKAGE_VERSION "8.42"
|
||||
|
||||
/* 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.41"
|
||||
#define VERSION "8.42"
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
73
pcre/config.sub
vendored
73
pcre/config.sub
vendored
@ -1,8 +1,8 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2014 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2017 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2014-12-03'
|
||||
timestamp='2017-04-02'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@ -33,7 +33,7 @@ timestamp='2014-12-03'
|
||||
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
|
||||
|
||||
# This file is supposed to be the same for all GNU packages
|
||||
# and recognize all the CPU types, system types and aliases
|
||||
@ -53,8 +53,7 @@ timestamp='2014-12-03'
|
||||
me=`echo "$0" | sed -e 's,.*/,,'`
|
||||
|
||||
usage="\
|
||||
Usage: $0 [OPTION] CPU-MFR-OPSYS
|
||||
$0 [OPTION] ALIAS
|
||||
Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
|
||||
|
||||
Canonicalize a configuration name.
|
||||
|
||||
@ -68,7 +67,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright 1992-2014 Free Software Foundation, Inc.
|
||||
Copyright 1992-2017 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@ -117,8 +116,8 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
kopensolaris*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
|
||||
kopensolaris*-gnu* | cloudabi*-eabi* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
@ -255,15 +254,16 @@ case $basic_machine in
|
||||
| arc | arceb \
|
||||
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
||||
| avr | avr32 \
|
||||
| ba \
|
||||
| be32 | be64 \
|
||||
| bfin \
|
||||
| c4x | c8051 | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| epiphany \
|
||||
| fido | fr30 | frv \
|
||||
| e2k | epiphany \
|
||||
| fido | fr30 | frv | ft32 \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| hexagon \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| i370 | i860 | i960 | ia16 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| k1om \
|
||||
| le32 | le64 \
|
||||
@ -301,11 +301,12 @@ case $basic_machine in
|
||||
| open8 | or1k | or1knd | or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
||||
| pru \
|
||||
| pyramid \
|
||||
| riscv32 | riscv64 \
|
||||
| rl78 | rx \
|
||||
| score \
|
||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||
@ -314,6 +315,7 @@ case $basic_machine in
|
||||
| ubicom32 \
|
||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
||||
| visium \
|
||||
| wasm32 \
|
||||
| we32k \
|
||||
| x86 | xc16x | xstormy16 | xtensa \
|
||||
| z8k | z80)
|
||||
@ -376,17 +378,18 @@ case $basic_machine in
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* | avr32-* \
|
||||
| ba-* \
|
||||
| be32-* | be64-* \
|
||||
| bfin-* | bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
||||
| c8051-* | clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| e2k-* | elxsi-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| hexagon-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| k1om-* \
|
||||
| le32-* | le64-* \
|
||||
@ -427,13 +430,15 @@ case $basic_machine in
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
||||
| pru-* \
|
||||
| pyramid-* \
|
||||
| riscv32-* | riscv64-* \
|
||||
| rl78-* | romp-* | rs6000-* | rx-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||
| sparclite-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
|
||||
| tahoe-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||
| tile*-* \
|
||||
@ -442,6 +447,7 @@ case $basic_machine in
|
||||
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
||||
| vax-* \
|
||||
| visium-* \
|
||||
| wasm32-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
@ -518,6 +524,9 @@ case $basic_machine in
|
||||
basic_machine=i386-pc
|
||||
os=-aros
|
||||
;;
|
||||
asmjs)
|
||||
basic_machine=asmjs-unknown
|
||||
;;
|
||||
aux)
|
||||
basic_machine=m68k-apple
|
||||
os=-aux
|
||||
@ -638,6 +647,14 @@ case $basic_machine in
|
||||
basic_machine=m68k-bull
|
||||
os=-sysv3
|
||||
;;
|
||||
e500v[12])
|
||||
basic_machine=powerpc-unknown
|
||||
os=$os"spe"
|
||||
;;
|
||||
e500v[12]-*)
|
||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=$os"spe"
|
||||
;;
|
||||
ebmon29k)
|
||||
basic_machine=a29k-amd
|
||||
os=-ebmon
|
||||
@ -933,6 +950,9 @@ case $basic_machine in
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
nsx-tandem)
|
||||
basic_machine=nsx-tandem
|
||||
;;
|
||||
op50n-* | op60c-*)
|
||||
basic_machine=hppa1.1-oki
|
||||
os=-proelf
|
||||
@ -1017,7 +1037,7 @@ case $basic_machine in
|
||||
ppc-* | ppcbe-*)
|
||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
ppcle | powerpclittle)
|
||||
basic_machine=powerpcle-unknown
|
||||
;;
|
||||
ppcle-* | powerpclittle-*)
|
||||
@ -1027,7 +1047,7 @@ case $basic_machine in
|
||||
;;
|
||||
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
|
||||
ppc64le | powerpc64little)
|
||||
basic_machine=powerpc64le-unknown
|
||||
;;
|
||||
ppc64le-* | powerpc64little-*)
|
||||
@ -1228,6 +1248,9 @@ case $basic_machine in
|
||||
basic_machine=a29k-wrs
|
||||
os=-vxworks
|
||||
;;
|
||||
wasm32)
|
||||
basic_machine=wasm32-unknown
|
||||
;;
|
||||
w65*)
|
||||
basic_machine=w65-wdc
|
||||
os=-none
|
||||
@ -1373,18 +1396,18 @@ case $os in
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
||||
| -sym* | -kopensolaris* | -plan9* \
|
||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
| -aos* | -aros* \
|
||||
| -aos* | -aros* | -cloudabi* | -sortix* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
| -bitrig* | -openbsd* | -solidbsd* \
|
||||
| -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
|
||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
|
||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||
| -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
@ -1393,7 +1416,8 @@ case $os in
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
|
||||
| -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@ -1525,6 +1549,8 @@ case $os in
|
||||
;;
|
||||
-nacl*)
|
||||
;;
|
||||
-ios)
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
@ -1620,6 +1646,9 @@ case $basic_machine in
|
||||
sparc-* | *-sun)
|
||||
os=-sunos4.1.1
|
||||
;;
|
||||
pru-*)
|
||||
os=-elf
|
||||
;;
|
||||
*-be)
|
||||
os=-beos
|
||||
;;
|
||||
|
145
pcre/configure
vendored
145
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.41.
|
||||
# Generated by GNU Autoconf 2.69 for PCRE 8.42.
|
||||
#
|
||||
#
|
||||
# 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.41'
|
||||
PACKAGE_STRING='PCRE 8.41'
|
||||
PACKAGE_VERSION='8.42'
|
||||
PACKAGE_STRING='PCRE 8.42'
|
||||
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.41 to adapt to many kinds of systems.
|
||||
\`configure' configures PCRE 8.42 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.41:";;
|
||||
short | recursive ) echo "Configuration of PCRE 8.42:";;
|
||||
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.41
|
||||
PCRE configure 8.42
|
||||
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.41, which was
|
||||
It was created by PCRE $as_me 8.42, 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.41'
|
||||
VERSION='8.42'
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
@ -6608,8 +6608,8 @@ esac
|
||||
|
||||
|
||||
|
||||
macro_version='2.4.6'
|
||||
macro_revision='2.4.6'
|
||||
macro_version='2.4.6.40-6ca5-dirty'
|
||||
macro_revision='2.4.6.40'
|
||||
|
||||
|
||||
|
||||
@ -8064,13 +8064,29 @@ esac
|
||||
fi
|
||||
|
||||
: ${AR=ar}
|
||||
: ${AR_FLAGS=cru}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Use ARFLAGS variable as AR's operation code to sync the variable naming with
|
||||
# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
|
||||
# higher priority because thats what people were doing historically (setting
|
||||
# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS
|
||||
# variable obsoleted/removed.
|
||||
|
||||
test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
|
||||
lt_ar_flags=$AR_FLAGS
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override
|
||||
# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
|
||||
|
||||
|
||||
|
||||
|
||||
@ -9788,8 +9804,8 @@ int forced_loaded() { return 2;}
|
||||
_LT_EOF
|
||||
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
|
||||
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
|
||||
echo "$AR cru libconftest.a conftest.o" >&5
|
||||
$AR cru libconftest.a conftest.o 2>&5
|
||||
echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5
|
||||
$AR $AR_FLAGS libconftest.a conftest.o 2>&5
|
||||
echo "$RANLIB libconftest.a" >&5
|
||||
$RANLIB libconftest.a 2>&5
|
||||
cat > conftest.c << _LT_EOF
|
||||
@ -11293,6 +11309,7 @@ _LT_EOF
|
||||
emximp -o $lib $output_objdir/$libname.def'
|
||||
old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
|
||||
enable_shared_with_static_runtimes=yes
|
||||
file_list_spec='@'
|
||||
;;
|
||||
|
||||
interix[3-9]*)
|
||||
@ -11510,7 +11527,7 @@ _LT_EOF
|
||||
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
|
||||
export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
|
||||
else
|
||||
export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
fi
|
||||
aix_use_runtimelinking=no
|
||||
|
||||
@ -12147,6 +12164,7 @@ $as_echo "$lt_cv_irix_exported_symbol" >&6; }
|
||||
emximp -o $lib $output_objdir/$libname.def'
|
||||
old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
|
||||
enable_shared_with_static_runtimes=yes
|
||||
file_list_spec='@'
|
||||
;;
|
||||
|
||||
osf3*)
|
||||
@ -14090,30 +14108,41 @@ striplib=
|
||||
old_striplib=
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
|
||||
$as_echo_n "checking whether stripping libraries is possible... " >&6; }
|
||||
if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
|
||||
test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
|
||||
test -z "$striplib" && striplib="$STRIP --strip-unneeded"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
if test -z "$STRIP"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
else
|
||||
# FIXME - insert some real tests, host_os isn't really good enough
|
||||
case $host_os in
|
||||
darwin*)
|
||||
if test -n "$STRIP"; then
|
||||
if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
|
||||
old_striplib="$STRIP --strip-debug"
|
||||
striplib="$STRIP --strip-unneeded"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
case $host_os in
|
||||
darwin*)
|
||||
# FIXME - insert some real tests, host_os isn't really good enough
|
||||
striplib="$STRIP -x"
|
||||
old_striplib="$STRIP -S"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
;;
|
||||
freebsd*)
|
||||
if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
|
||||
old_striplib="$STRIP --strip-debug"
|
||||
striplib="$STRIP --strip-unneeded"
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@ -15012,6 +15041,7 @@ fi
|
||||
emximp -o $lib $output_objdir/$libname.def'
|
||||
old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
|
||||
enable_shared_with_static_runtimes_CXX=yes
|
||||
file_list_spec_CXX='@'
|
||||
;;
|
||||
|
||||
dgux*)
|
||||
@ -16447,7 +16477,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
|
||||
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
|
||||
export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
|
||||
else
|
||||
export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
fi
|
||||
;;
|
||||
pw32*)
|
||||
@ -17634,9 +17664,9 @@ _ACEOF
|
||||
# Versioning
|
||||
|
||||
PCRE_MAJOR="8"
|
||||
PCRE_MINOR="41"
|
||||
PCRE_MINOR="42"
|
||||
PCRE_PRERELEASE=""
|
||||
PCRE_DATE="2017-07-05"
|
||||
PCRE_DATE="2018-03-20"
|
||||
|
||||
if test "$PCRE_MINOR" = "08" -o "$PCRE_MINOR" = "09"
|
||||
then
|
||||
@ -17708,6 +17738,32 @@ else
|
||||
fi
|
||||
|
||||
|
||||
# This code enables JIT if the hardware supports it.
|
||||
|
||||
if test "$enable_jit" = "auto"; then
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#define SLJIT_CONFIG_AUTO 1
|
||||
#include "sljit/sljitConfigInternal.h"
|
||||
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||
#error unsupported
|
||||
#endif
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
enable_jit=yes
|
||||
else
|
||||
enable_jit=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
# Handle --disable-pcregrep-jit (enabled by default)
|
||||
# Check whether --enable-pcregrep-jit was given.
|
||||
if test "${enable_pcregrep_jit+set}" = set; then :
|
||||
@ -18204,7 +18260,7 @@ pcre_have_type_traits="0"
|
||||
pcre_have_bits_type_traits="0"
|
||||
|
||||
if test "x$enable_cpp" = "xyes" -a -z "$CXX"; then
|
||||
as_fn_error $? "You need a C++ compiler for C++ support." "$LINENO" 5
|
||||
as_fn_error $? "Invalid C++ compiler or C++ compiler flags" "$LINENO" 5
|
||||
fi
|
||||
|
||||
if test "x$enable_cpp" = "xyes" -a -n "$CXX"
|
||||
@ -19658,16 +19714,16 @@ esac
|
||||
# (Note: The libpcre*_version bits are m4 variables, assigned above)
|
||||
|
||||
EXTRA_LIBPCRE_LDFLAGS="$EXTRA_LIBPCRE_LDFLAGS \
|
||||
$NO_UNDEFINED -version-info 3:9:2"
|
||||
$NO_UNDEFINED -version-info 3:10:2"
|
||||
|
||||
EXTRA_LIBPCRE16_LDFLAGS="$EXTRA_LIBPCRE16_LDFLAGS \
|
||||
$NO_UNDEFINED -version-info 2:9:2"
|
||||
$NO_UNDEFINED -version-info 2:10:2"
|
||||
|
||||
EXTRA_LIBPCRE32_LDFLAGS="$EXTRA_LIBPCRE32_LDFLAGS \
|
||||
$NO_UNDEFINED -version-info 0:9:0"
|
||||
$NO_UNDEFINED -version-info 0:10:0"
|
||||
|
||||
EXTRA_LIBPCREPOSIX_LDFLAGS="$EXTRA_LIBPCREPOSIX_LDFLAGS \
|
||||
$NO_UNDEFINED -version-info 0:5:0"
|
||||
$NO_UNDEFINED -version-info 0:6:0"
|
||||
|
||||
EXTRA_LIBPCRECPP_LDFLAGS="$EXTRA_LIBPCRECPP_LDFLAGS \
|
||||
$NO_UNDEFINED -version-info 0:1:0 \
|
||||
@ -20719,7 +20775,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.41, which was
|
||||
This file was extended by PCRE $as_me 8.42, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@ -20785,7 +20841,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.41
|
||||
PCRE config.status 8.42
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
@ -20957,6 +21013,7 @@ file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
|
||||
want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
|
||||
sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
|
||||
AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
|
||||
lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`'
|
||||
AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
|
||||
archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
|
||||
STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
|
||||
@ -21140,7 +21197,6 @@ file_magic_glob \
|
||||
want_nocaseglob \
|
||||
sharedlib_from_linklib_cmd \
|
||||
AR \
|
||||
AR_FLAGS \
|
||||
archiver_list_spec \
|
||||
STRIP \
|
||||
RANLIB \
|
||||
@ -22162,8 +22218,11 @@ sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
|
||||
# The archiver.
|
||||
AR=$lt_AR
|
||||
|
||||
# Flags to create an archive (by configure).
|
||||
lt_ar_flags=$lt_ar_flags
|
||||
|
||||
# Flags to create an archive.
|
||||
AR_FLAGS=$lt_AR_FLAGS
|
||||
AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"}
|
||||
|
||||
# How to feed a file listing to the archiver.
|
||||
archiver_list_spec=$lt_archiver_list_spec
|
||||
|
@ -9,18 +9,18 @@ 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, [41])
|
||||
m4_define(pcre_minor, [42])
|
||||
m4_define(pcre_prerelease, [])
|
||||
m4_define(pcre_date, [2017-07-05])
|
||||
m4_define(pcre_date, [2018-03-20])
|
||||
|
||||
# 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:9:2])
|
||||
m4_define(libpcre16_version, [2:9:2])
|
||||
m4_define(libpcre32_version, [0:9:0])
|
||||
m4_define(libpcreposix_version, [0:5:0])
|
||||
m4_define(libpcre_version, [3:10:2])
|
||||
m4_define(libpcre16_version, [2:10:2])
|
||||
m4_define(libpcre32_version, [0:10:0])
|
||||
m4_define(libpcreposix_version, [0:6:0])
|
||||
m4_define(libpcrecpp_version, [0:1:0])
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
@ -155,6 +155,18 @@ AC_ARG_ENABLE(jit,
|
||||
[enable Just-In-Time compiling support]),
|
||||
, enable_jit=no)
|
||||
|
||||
# This code enables JIT if the hardware supports it.
|
||||
|
||||
if test "$enable_jit" = "auto"; then
|
||||
AC_LANG(C)
|
||||
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)
|
||||
fi
|
||||
|
||||
# Handle --disable-pcregrep-jit (enabled by default)
|
||||
AC_ARG_ENABLE(pcregrep-jit,
|
||||
AS_HELP_STRING([--disable-pcregrep-jit],
|
||||
@ -469,7 +481,7 @@ pcre_have_type_traits="0"
|
||||
pcre_have_bits_type_traits="0"
|
||||
|
||||
if test "x$enable_cpp" = "xyes" -a -z "$CXX"; then
|
||||
AC_MSG_ERROR([You need a C++ compiler for C++ support.])
|
||||
AC_MSG_ERROR([Invalid C++ compiler or C++ compiler flags])
|
||||
fi
|
||||
|
||||
if test "x$enable_cpp" = "xyes" -a -n "$CXX"
|
||||
|
@ -1,9 +1,9 @@
|
||||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2013-05-30.07; # UTC
|
||||
scriptversion=2016-01-11.22; # UTC
|
||||
|
||||
# Copyright (C) 1999-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -786,6 +786,6 @@ exit 0
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
|
@ -760,13 +760,14 @@ The character code used is EBCDIC, not ASCII or Unicode. In z/OS, UNIX APIs and
|
||||
applications can be supported through UNIX System Services, and in such an
|
||||
environment PCRE can be built in the same way as in other systems. However, in
|
||||
native z/OS (without UNIX System Services) and in z/VM, special ports are
|
||||
required. For details, please see this web site:
|
||||
required. PCRE1 version 8.39 is available in file 882 on this site:
|
||||
|
||||
http://www.zaconsultants.net
|
||||
http://www.cbttape.org
|
||||
|
||||
You may download PCRE from WWW.CBTTAPE.ORG, file 882. Everything, source and
|
||||
executable, is in EBCDIC and native z/OS file formats and this is the
|
||||
recommended download site.
|
||||
Everything, source and executable, is in EBCDIC and native z/OS file formats.
|
||||
However, this software is not maintained and will not be upgraded. If you are
|
||||
new to PCRE you should be looking at PCRE2 (version 10.30 or later).
|
||||
|
||||
==========================
|
||||
Last Updated: 25 June 2015
|
||||
===============================
|
||||
Last Updated: 13 September 2017
|
||||
===============================
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# install - install a program, script, or datafile
|
||||
|
||||
scriptversion=2013-12-25.23; # UTC
|
||||
scriptversion=2016-01-11.22; # UTC
|
||||
|
||||
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||
@ -496,6 +496,6 @@ done
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
|
768
pcre/ltmain.sh
768
pcre/ltmain.sh
File diff suppressed because it is too large
Load Diff
69
pcre/m4/libtool.m4
vendored
69
pcre/m4/libtool.m4
vendored
@ -1,6 +1,6 @@
|
||||
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2001, 2003-2017 Free Software Foundation, Inc.
|
||||
# Written by Gordon Matzigkeit, 1996
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
@ -1042,8 +1042,8 @@ int forced_loaded() { return 2;}
|
||||
_LT_EOF
|
||||
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
|
||||
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
|
||||
$AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
|
||||
$AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
|
||||
$RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
|
||||
cat > conftest.c << _LT_EOF
|
||||
@ -1493,9 +1493,22 @@ need_locks=$enable_libtool_lock
|
||||
m4_defun([_LT_PROG_AR],
|
||||
[AC_CHECK_TOOLS(AR, [ar], false)
|
||||
: ${AR=ar}
|
||||
: ${AR_FLAGS=cru}
|
||||
_LT_DECL([], [AR], [1], [The archiver])
|
||||
_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
|
||||
|
||||
# Use ARFLAGS variable as AR's operation code to sync the variable naming with
|
||||
# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
|
||||
# higher priority because thats what people were doing historically (setting
|
||||
# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS
|
||||
# variable obsoleted/removed.
|
||||
|
||||
test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
|
||||
lt_ar_flags=$AR_FLAGS
|
||||
_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)])
|
||||
|
||||
# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override
|
||||
# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
|
||||
_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}],
|
||||
[Flags to create an archive])
|
||||
|
||||
AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
|
||||
[lt_cv_ar_at_file=no
|
||||
@ -2207,26 +2220,35 @@ m4_defun([_LT_CMD_STRIPLIB],
|
||||
striplib=
|
||||
old_striplib=
|
||||
AC_MSG_CHECKING([whether stripping libraries is possible])
|
||||
if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
|
||||
test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
|
||||
test -z "$striplib" && striplib="$STRIP --strip-unneeded"
|
||||
AC_MSG_RESULT([yes])
|
||||
if test -z "$STRIP"; then
|
||||
AC_MSG_RESULT([no])
|
||||
else
|
||||
# FIXME - insert some real tests, host_os isn't really good enough
|
||||
case $host_os in
|
||||
darwin*)
|
||||
if test -n "$STRIP"; then
|
||||
if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
|
||||
old_striplib="$STRIP --strip-debug"
|
||||
striplib="$STRIP --strip-unneeded"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
case $host_os in
|
||||
darwin*)
|
||||
# FIXME - insert some real tests, host_os isn't really good enough
|
||||
striplib="$STRIP -x"
|
||||
old_striplib="$STRIP -S"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
;;
|
||||
freebsd*)
|
||||
if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
|
||||
old_striplib="$STRIP --strip-debug"
|
||||
striplib="$STRIP --strip-unneeded"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([no])
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
|
||||
_LT_DECL([], [striplib], [1])
|
||||
@ -4919,7 +4941,7 @@ m4_if([$1], [CXX], [
|
||||
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
|
||||
else
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
fi
|
||||
;;
|
||||
pw32*)
|
||||
@ -5156,6 +5178,7 @@ _LT_EOF
|
||||
emximp -o $lib $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
|
||||
_LT_TAGVAR(file_list_spec, $1)='@'
|
||||
;;
|
||||
|
||||
interix[[3-9]]*)
|
||||
@ -5373,7 +5396,7 @@ _LT_EOF
|
||||
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
|
||||
else
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
fi
|
||||
aix_use_runtimelinking=no
|
||||
|
||||
@ -5861,6 +5884,7 @@ _LT_EOF
|
||||
emximp -o $lib $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
|
||||
_LT_TAGVAR(file_list_spec, $1)='@'
|
||||
;;
|
||||
|
||||
osf3*)
|
||||
@ -6730,6 +6754,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
emximp -o $lib $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
|
||||
_LT_TAGVAR(file_list_spec, $1)='@'
|
||||
;;
|
||||
|
||||
dgux*)
|
||||
|
2
pcre/m4/ltoptions.m4
vendored
2
pcre/m4/ltoptions.m4
vendored
@ -1,6 +1,6 @@
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
|
||||
# Copyright (C) 2004-2005, 2007-2009, 2011-2017 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
|
2
pcre/m4/ltsugar.m4
vendored
2
pcre/m4/ltsugar.m4
vendored
@ -1,6 +1,6 @@
|
||||
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
|
||||
# Copyright (C) 2004-2005, 2007-2008, 2011-2017 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
|
12
pcre/m4/ltversion.m4
vendored
12
pcre/m4/ltversion.m4
vendored
@ -1,6 +1,6 @@
|
||||
# ltversion.m4 -- version numbers -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2004, 2011-2017 Free Software Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
@ -9,15 +9,15 @@
|
||||
|
||||
# @configure_input@
|
||||
|
||||
# serial 4179 ltversion.m4
|
||||
# serial 4219 ltversion.m4
|
||||
# This file is part of GNU Libtool
|
||||
|
||||
m4_define([LT_PACKAGE_VERSION], [2.4.6])
|
||||
m4_define([LT_PACKAGE_REVISION], [2.4.6])
|
||||
m4_define([LT_PACKAGE_VERSION], [2.4.6.40-6ca5-dirty])
|
||||
m4_define([LT_PACKAGE_REVISION], [2.4.6.40])
|
||||
|
||||
AC_DEFUN([LTVERSION_VERSION],
|
||||
[macro_version='2.4.6'
|
||||
macro_revision='2.4.6'
|
||||
[macro_version='2.4.6.40-6ca5-dirty'
|
||||
macro_revision='2.4.6.40'
|
||||
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
|
||||
_LT_DECL(, macro_revision, 0)
|
||||
])
|
||||
|
2
pcre/m4/lt~obsolete.m4
vendored
2
pcre/m4/lt~obsolete.m4
vendored
@ -1,6 +1,6 @@
|
||||
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
|
||||
# Copyright (C) 2004-2005, 2007, 2009, 2011-2017 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004.
|
||||
#
|
||||
|
@ -1,9 +1,9 @@
|
||||
#! /bin/sh
|
||||
# Common wrapper for a few potentially missing GNU programs.
|
||||
|
||||
scriptversion=2013-10-28.13; # UTC
|
||||
scriptversion=2016-01-11.22; # UTC
|
||||
|
||||
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
# Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@ -210,6 +210,6 @@ exit $st
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
|
@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
/* The current PCRE version information. */
|
||||
|
||||
#define PCRE_MAJOR 8
|
||||
#define PCRE_MINOR 41
|
||||
#define PCRE_MINOR 42
|
||||
#define PCRE_PRERELEASE
|
||||
#define PCRE_DATE 2017-07-05
|
||||
#define PCRE_DATE 2018-03-20
|
||||
|
||||
/* 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
|
||||
@ -321,11 +321,11 @@ these bits, just add new ones on the end, in order to remain compatible. */
|
||||
|
||||
/* Types */
|
||||
|
||||
struct real_pcre; /* declaration; the definition is private */
|
||||
typedef struct real_pcre pcre;
|
||||
struct real_pcre8_or_16; /* declaration; the definition is private */
|
||||
typedef struct real_pcre8_or_16 pcre;
|
||||
|
||||
struct real_pcre16; /* declaration; the definition is private */
|
||||
typedef struct real_pcre16 pcre16;
|
||||
struct real_pcre8_or_16; /* declaration; the definition is private */
|
||||
typedef struct real_pcre8_or_16 pcre16;
|
||||
|
||||
struct real_pcre32; /* declaration; the definition is private */
|
||||
typedef struct real_pcre32 pcre32;
|
||||
|
@ -321,11 +321,11 @@ these bits, just add new ones on the end, in order to remain compatible. */
|
||||
|
||||
/* Types */
|
||||
|
||||
struct real_pcre; /* declaration; the definition is private */
|
||||
typedef struct real_pcre pcre;
|
||||
struct real_pcre8_or_16; /* declaration; the definition is private */
|
||||
typedef struct real_pcre8_or_16 pcre;
|
||||
|
||||
struct real_pcre16; /* declaration; the definition is private */
|
||||
typedef struct real_pcre16 pcre16;
|
||||
struct real_pcre8_or_16; /* declaration; the definition is private */
|
||||
typedef struct real_pcre8_or_16 pcre16;
|
||||
|
||||
struct real_pcre32; /* declaration; the definition is private */
|
||||
typedef struct real_pcre32 pcre32;
|
||||
|
@ -8060,7 +8060,7 @@ for (;; ptr++)
|
||||
single group (i.e. not to a duplicated name. */
|
||||
|
||||
HANDLE_REFERENCE:
|
||||
if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE;
|
||||
if (firstcharflags == REQ_UNSET) zerofirstcharflags = firstcharflags = REQ_NONE;
|
||||
previous = code;
|
||||
item_hwm_offset = cd->hwm - cd->start_workspace;
|
||||
*code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF;
|
||||
|
@ -2287,12 +2287,14 @@ for (;;)
|
||||
case OP_NOTI:
|
||||
if (clen > 0)
|
||||
{
|
||||
unsigned int otherd;
|
||||
pcre_uint32 otherd;
|
||||
#ifdef SUPPORT_UTF
|
||||
if (utf && d >= 128)
|
||||
{
|
||||
#ifdef SUPPORT_UCP
|
||||
otherd = UCD_OTHERCASE(d);
|
||||
#else
|
||||
otherd = d;
|
||||
#endif /* SUPPORT_UCP */
|
||||
}
|
||||
else
|
||||
|
@ -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-2014 University of Cambridge
|
||||
Copyright (c) 1997-2018 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -2305,7 +2305,7 @@ for (;;)
|
||||
case OP_ANY:
|
||||
if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
|
||||
if (md->partial != 0 &&
|
||||
eptr + 1 >= md->end_subject &&
|
||||
eptr == md->end_subject - 1 &&
|
||||
NLBLOCK->nltype == NLTYPE_FIXED &&
|
||||
NLBLOCK->nllen == 2 &&
|
||||
UCHAR21TEST(eptr) == NLBLOCK->nl[0])
|
||||
@ -3053,7 +3053,7 @@ for (;;)
|
||||
{
|
||||
RMATCH(eptr, ecode, offset_top, md, eptrb, RM18);
|
||||
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
|
||||
if (eptr-- == pp) break; /* Stop if tried at original pos */
|
||||
if (eptr-- <= pp) break; /* Stop if tried at original pos */
|
||||
BACKCHAR(eptr);
|
||||
}
|
||||
}
|
||||
@ -3210,7 +3210,7 @@ for (;;)
|
||||
{
|
||||
RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
|
||||
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
|
||||
if (eptr-- == pp) break; /* Stop if tried at original pos */
|
||||
if (eptr-- <= pp) break; /* Stop if tried at original pos */
|
||||
#ifdef SUPPORT_UTF
|
||||
if (utf) BACKCHAR(eptr);
|
||||
#endif
|
||||
|
@ -164,7 +164,6 @@ typedef struct jit_arguments {
|
||||
const pcre_uchar *begin;
|
||||
const pcre_uchar *end;
|
||||
int *offsets;
|
||||
pcre_uchar *uchar_ptr;
|
||||
pcre_uchar *mark_ptr;
|
||||
void *callout_data;
|
||||
/* Everything else after. */
|
||||
@ -214,7 +213,7 @@ enum control_types {
|
||||
type_then_trap = 1
|
||||
};
|
||||
|
||||
typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
|
||||
typedef int (SLJIT_FUNC *jit_function)(jit_arguments *args);
|
||||
|
||||
/* The following structure is the key data type for the recursive
|
||||
code generator. It is allocated by compile_matchingpath, and contains
|
||||
@ -489,9 +488,24 @@ typedef struct compare_context {
|
||||
/* Used for accessing the elements of the stack. */
|
||||
#define STACK(i) ((i) * (int)sizeof(sljit_sw))
|
||||
|
||||
#ifdef SLJIT_PREF_SHIFT_REG
|
||||
#if SLJIT_PREF_SHIFT_REG == SLJIT_R2
|
||||
/* Nothing. */
|
||||
#elif SLJIT_PREF_SHIFT_REG == SLJIT_R3
|
||||
#define SHIFT_REG_IS_R3
|
||||
#else
|
||||
#error "Unsupported shift register"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define TMP1 SLJIT_R0
|
||||
#ifdef SHIFT_REG_IS_R3
|
||||
#define TMP2 SLJIT_R3
|
||||
#define TMP3 SLJIT_R2
|
||||
#else
|
||||
#define TMP2 SLJIT_R2
|
||||
#define TMP3 SLJIT_R3
|
||||
#endif
|
||||
#define STR_PTR SLJIT_S0
|
||||
#define STR_END SLJIT_S1
|
||||
#define STACK_TOP SLJIT_R1
|
||||
@ -520,13 +534,10 @@ the start pointers when the end of the capturing group has not yet reached. */
|
||||
|
||||
#if defined COMPILE_PCRE8
|
||||
#define MOV_UCHAR SLJIT_MOV_U8
|
||||
#define MOVU_UCHAR SLJIT_MOVU_U8
|
||||
#elif defined COMPILE_PCRE16
|
||||
#define MOV_UCHAR SLJIT_MOV_U16
|
||||
#define MOVU_UCHAR SLJIT_MOVU_U16
|
||||
#elif defined COMPILE_PCRE32
|
||||
#define MOV_UCHAR SLJIT_MOV_U32
|
||||
#define MOVU_UCHAR SLJIT_MOVU_U32
|
||||
#else
|
||||
#error Unsupported compiling mode
|
||||
#endif
|
||||
@ -2383,12 +2394,25 @@ if (length < 8)
|
||||
}
|
||||
else
|
||||
{
|
||||
GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
|
||||
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
|
||||
loop = LABEL();
|
||||
OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw), SLJIT_R0, 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
|
||||
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||
if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw)) == SLJIT_SUCCESS)
|
||||
{
|
||||
GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START);
|
||||
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
|
||||
loop = LABEL();
|
||||
sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, SLJIT_R0, SLJIT_MEM1(SLJIT_R1), sizeof(sljit_sw));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
|
||||
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||
}
|
||||
else
|
||||
{
|
||||
GET_LOCAL_BASE(SLJIT_R1, 0, OVECTOR_START + sizeof(sljit_sw));
|
||||
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, length - 1);
|
||||
loop = LABEL();
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), 0, SLJIT_R0, 0);
|
||||
OP2(SLJIT_ADD, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, sizeof(sljit_sw));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, 1);
|
||||
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2421,12 +2445,25 @@ if (length < 8)
|
||||
}
|
||||
else
|
||||
{
|
||||
GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
|
||||
loop = LABEL();
|
||||
OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
|
||||
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||
if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw)) == SLJIT_SUCCESS)
|
||||
{
|
||||
GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
|
||||
loop = LABEL();
|
||||
sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_STORE | SLJIT_MEM_PRE, TMP1, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
|
||||
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||
}
|
||||
else
|
||||
{
|
||||
GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + 2 * sizeof(sljit_sw));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
|
||||
loop = LABEL();
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, TMP1, 0);
|
||||
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(sljit_sw));
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
|
||||
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||
}
|
||||
}
|
||||
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
|
||||
@ -2436,10 +2473,10 @@ if (common->control_head_ptr != 0)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, end));
|
||||
}
|
||||
|
||||
static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
|
||||
static sljit_sw SLJIT_FUNC do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
|
||||
{
|
||||
while (current != NULL)
|
||||
{
|
||||
@ -2460,7 +2497,7 @@ while (current != NULL)
|
||||
SLJIT_ASSERT(current[0] == 0 || current < (sljit_sw*)current[0]);
|
||||
current = (sljit_sw*)current[0];
|
||||
}
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
|
||||
@ -2468,6 +2505,7 @@ static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
|
||||
DEFINE_COMPILER;
|
||||
struct sljit_label *loop;
|
||||
struct sljit_jump *early_quit;
|
||||
BOOL has_pre;
|
||||
|
||||
/* At this point we can freely use all registers. */
|
||||
OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
|
||||
@ -2481,17 +2519,30 @@ if (common->mark_ptr != 0)
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
|
||||
OP2(SLJIT_SUB, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
|
||||
OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin));
|
||||
GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START);
|
||||
|
||||
has_pre = sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw)) == SLJIT_SUCCESS;
|
||||
GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START - (has_pre ? sizeof(sljit_sw) : 0));
|
||||
|
||||
/* Unlikely, but possible */
|
||||
early_quit = CMP(SLJIT_EQUAL, SLJIT_R1, 0, SLJIT_IMM, 0);
|
||||
loop = LABEL();
|
||||
OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0, SLJIT_R0, 0);
|
||||
OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
|
||||
|
||||
if (has_pre)
|
||||
sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw));
|
||||
else
|
||||
{
|
||||
OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_S0), 0);
|
||||
OP2(SLJIT_ADD, SLJIT_S0, 0, SLJIT_S0, 0, SLJIT_IMM, sizeof(sljit_sw));
|
||||
}
|
||||
|
||||
OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, sizeof(int));
|
||||
OP2(SLJIT_SUB, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_R0, 0);
|
||||
/* Copy the integer value to the output buffer */
|
||||
#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
|
||||
OP2(SLJIT_ASHR, SLJIT_S1, 0, SLJIT_S1, 0, SLJIT_IMM, UCHAR_SHIFT);
|
||||
#endif
|
||||
OP1(SLJIT_MOVU_S32, SLJIT_MEM1(SLJIT_R2), sizeof(int), SLJIT_S1, 0);
|
||||
|
||||
OP1(SLJIT_MOV_S32, SLJIT_MEM1(SLJIT_R2), 0, SLJIT_S1, 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
|
||||
JUMPTO(SLJIT_NOT_ZERO, loop);
|
||||
JUMPHERE(early_quit);
|
||||
@ -2499,14 +2550,29 @@ JUMPHERE(early_quit);
|
||||
/* Calculate the return value, which is the maximum ovector value. */
|
||||
if (topbracket > 1)
|
||||
{
|
||||
GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
|
||||
OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
|
||||
if (sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw))) == SLJIT_SUCCESS)
|
||||
{
|
||||
GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
|
||||
OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
|
||||
|
||||
/* OVECTOR(0) is never equal to SLJIT_S2. */
|
||||
loop = LABEL();
|
||||
OP1(SLJIT_MOVU, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
|
||||
OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
|
||||
CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
|
||||
/* OVECTOR(0) is never equal to SLJIT_S2. */
|
||||
loop = LABEL();
|
||||
sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_PRE, SLJIT_R2, SLJIT_MEM1(SLJIT_R0), -(2 * (sljit_sw)sizeof(sljit_sw)));
|
||||
OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
|
||||
CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
|
||||
}
|
||||
else
|
||||
{
|
||||
GET_LOCAL_BASE(SLJIT_R0, 0, OVECTOR_START + (topbracket - 1) * 2 * sizeof(sljit_sw));
|
||||
OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_IMM, topbracket + 1);
|
||||
|
||||
/* OVECTOR(0) is never equal to SLJIT_S2. */
|
||||
loop = LABEL();
|
||||
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), 0);
|
||||
OP2(SLJIT_SUB, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 2 * (sljit_sw)sizeof(sljit_sw));
|
||||
OP2(SLJIT_SUB, SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1);
|
||||
CMPTO(SLJIT_EQUAL, SLJIT_R2, 0, SLJIT_S2, 0, loop);
|
||||
}
|
||||
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_R1, 0);
|
||||
}
|
||||
else
|
||||
@ -5167,93 +5233,190 @@ OP_FLAGS(SLJIT_OR | SLJIT_SET_Z, TMP2, 0, SLJIT_EQUAL);
|
||||
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
|
||||
}
|
||||
|
||||
#define CHAR1 STR_END
|
||||
#define CHAR2 STACK_TOP
|
||||
|
||||
static void do_casefulcmp(compiler_common *common)
|
||||
{
|
||||
DEFINE_COMPILER;
|
||||
struct sljit_jump *jump;
|
||||
struct sljit_label *label;
|
||||
int char1_reg;
|
||||
int char2_reg;
|
||||
|
||||
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
|
||||
if (sljit_get_register_index(TMP3) < 0)
|
||||
{
|
||||
char1_reg = STR_END;
|
||||
char2_reg = STACK_TOP;
|
||||
}
|
||||
else
|
||||
{
|
||||
char1_reg = TMP3;
|
||||
char2_reg = RETURN_ADDR;
|
||||
}
|
||||
|
||||
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
|
||||
OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR2, 0);
|
||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
|
||||
label = LABEL();
|
||||
OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
||||
OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
||||
jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
JUMPTO(SLJIT_NOT_ZERO, label);
|
||||
if (char1_reg == STR_END)
|
||||
{
|
||||
OP1(SLJIT_MOV, TMP3, 0, char1_reg, 0);
|
||||
OP1(SLJIT_MOV, RETURN_ADDR, 0, char2_reg, 0);
|
||||
}
|
||||
|
||||
JUMPHERE(jump);
|
||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
|
||||
OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
|
||||
if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
|
||||
{
|
||||
label = LABEL();
|
||||
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
||||
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
||||
jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
JUMPTO(SLJIT_NOT_ZERO, label);
|
||||
|
||||
JUMPHERE(jump);
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
}
|
||||
else if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
|
||||
{
|
||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
|
||||
label = LABEL();
|
||||
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
||||
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
||||
jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
JUMPTO(SLJIT_NOT_ZERO, label);
|
||||
|
||||
JUMPHERE(jump);
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
label = LABEL();
|
||||
OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
|
||||
OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
|
||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
JUMPTO(SLJIT_NOT_ZERO, label);
|
||||
|
||||
JUMPHERE(jump);
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
}
|
||||
|
||||
if (char1_reg == STR_END)
|
||||
{
|
||||
OP1(SLJIT_MOV, char1_reg, 0, TMP3, 0);
|
||||
OP1(SLJIT_MOV, char2_reg, 0, RETURN_ADDR, 0);
|
||||
}
|
||||
|
||||
sljit_emit_fast_return(compiler, TMP1, 0);
|
||||
}
|
||||
|
||||
#define LCC_TABLE STACK_LIMIT
|
||||
|
||||
static void do_caselesscmp(compiler_common *common)
|
||||
{
|
||||
DEFINE_COMPILER;
|
||||
struct sljit_jump *jump;
|
||||
struct sljit_label *label;
|
||||
int char1_reg = STR_END;
|
||||
int char2_reg;
|
||||
int lcc_table;
|
||||
int opt_type = 0;
|
||||
|
||||
sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
|
||||
if (sljit_get_register_index(TMP3) < 0)
|
||||
{
|
||||
char2_reg = STACK_TOP;
|
||||
lcc_table = STACK_LIMIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
char2_reg = RETURN_ADDR;
|
||||
lcc_table = TMP3;
|
||||
}
|
||||
|
||||
if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
|
||||
opt_type = 1;
|
||||
else if (sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1)) == SLJIT_SUCCESS)
|
||||
opt_type = 2;
|
||||
|
||||
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
|
||||
|
||||
OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, CHAR1, 0);
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, CHAR2, 0);
|
||||
OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
|
||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, char1_reg, 0);
|
||||
|
||||
if (char2_reg == STACK_TOP)
|
||||
{
|
||||
OP1(SLJIT_MOV, TMP3, 0, char2_reg, 0);
|
||||
OP1(SLJIT_MOV, RETURN_ADDR, 0, lcc_table, 0);
|
||||
}
|
||||
|
||||
OP1(SLJIT_MOV, lcc_table, 0, SLJIT_IMM, common->lcc);
|
||||
|
||||
if (opt_type == 1)
|
||||
{
|
||||
label = LABEL();
|
||||
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
||||
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_POST, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
||||
}
|
||||
else if (opt_type == 2)
|
||||
{
|
||||
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
|
||||
label = LABEL();
|
||||
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char1_reg, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
||||
sljit_emit_mem(compiler, MOV_UCHAR | SLJIT_MEM_PRE, char2_reg, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
label = LABEL();
|
||||
OP1(MOV_UCHAR, char1_reg, 0, SLJIT_MEM1(TMP1), 0);
|
||||
OP1(MOV_UCHAR, char2_reg, 0, SLJIT_MEM1(STR_PTR), 0);
|
||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
}
|
||||
|
||||
label = LABEL();
|
||||
OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
|
||||
OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
|
||||
#ifndef COMPILE_PCRE8
|
||||
jump = CMP(SLJIT_GREATER, CHAR1, 0, SLJIT_IMM, 255);
|
||||
jump = CMP(SLJIT_GREATER, char1_reg, 0, SLJIT_IMM, 255);
|
||||
#endif
|
||||
OP1(SLJIT_MOV_U8, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
|
||||
OP1(SLJIT_MOV_U8, char1_reg, 0, SLJIT_MEM2(lcc_table, char1_reg), 0);
|
||||
#ifndef COMPILE_PCRE8
|
||||
JUMPHERE(jump);
|
||||
jump = CMP(SLJIT_GREATER, CHAR2, 0, SLJIT_IMM, 255);
|
||||
jump = CMP(SLJIT_GREATER, char2_reg, 0, SLJIT_IMM, 255);
|
||||
#endif
|
||||
OP1(SLJIT_MOV_U8, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
|
||||
OP1(SLJIT_MOV_U8, char2_reg, 0, SLJIT_MEM2(lcc_table, char2_reg), 0);
|
||||
#ifndef COMPILE_PCRE8
|
||||
JUMPHERE(jump);
|
||||
#endif
|
||||
jump = CMP(SLJIT_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
|
||||
|
||||
if (opt_type == 0)
|
||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
|
||||
jump = CMP(SLJIT_NOT_EQUAL, char1_reg, 0, char2_reg, 0);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
JUMPTO(SLJIT_NOT_ZERO, label);
|
||||
|
||||
JUMPHERE(jump);
|
||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
|
||||
OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
|
||||
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
|
||||
}
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
|
||||
#undef LCC_TABLE
|
||||
#undef CHAR1
|
||||
#undef CHAR2
|
||||
if (opt_type == 2)
|
||||
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
|
||||
|
||||
if (char2_reg == STACK_TOP)
|
||||
{
|
||||
OP1(SLJIT_MOV, char2_reg, 0, TMP3, 0);
|
||||
OP1(SLJIT_MOV, lcc_table, 0, RETURN_ADDR, 0);
|
||||
}
|
||||
|
||||
OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
|
||||
sljit_emit_fast_return(compiler, TMP1, 0);
|
||||
}
|
||||
|
||||
#if defined SUPPORT_UTF && defined SUPPORT_UCP
|
||||
|
||||
static const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
|
||||
static const pcre_uchar * SLJIT_FUNC do_utf_caselesscmp(pcre_uchar *src1, pcre_uchar *src2, pcre_uchar *end1, pcre_uchar *end2)
|
||||
{
|
||||
/* This function would be ineffective to do in JIT level. */
|
||||
sljit_u32 c1, c2;
|
||||
const pcre_uchar *src2 = args->uchar_ptr;
|
||||
const pcre_uchar *end2 = args->end;
|
||||
const ucd_record *ur;
|
||||
const sljit_u32 *pp;
|
||||
|
||||
@ -6776,32 +6939,37 @@ else
|
||||
#if defined SUPPORT_UTF && defined SUPPORT_UCP
|
||||
if (common->utf && *cc == OP_REFI)
|
||||
{
|
||||
SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1 && TMP2 == SLJIT_R2);
|
||||
SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1);
|
||||
if (ref)
|
||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
|
||||
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
|
||||
else
|
||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
|
||||
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
|
||||
|
||||
if (withchecks)
|
||||
jump = CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0);
|
||||
jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_R2, 0);
|
||||
|
||||
/* Needed to save important temporary registers. */
|
||||
/* No free saved registers so save data on stack. */
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
||||
OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
|
||||
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
|
||||
OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0);
|
||||
OP1(SLJIT_MOV, SLJIT_R3, 0, STR_END, 0);
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
|
||||
|
||||
if (common->mode == JIT_COMPILE)
|
||||
add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
|
||||
else
|
||||
{
|
||||
add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
|
||||
nopartial = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
|
||||
|
||||
add_jump(compiler, backtracks, JUMP(SLJIT_LESS));
|
||||
|
||||
nopartial = JUMP(SLJIT_NOT_EQUAL);
|
||||
OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
|
||||
check_partial(common, FALSE);
|
||||
add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
|
||||
JUMPHERE(nopartial);
|
||||
}
|
||||
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
|
||||
}
|
||||
else
|
||||
#endif /* SUPPORT_UTF && SUPPORT_UCP */
|
||||
@ -7125,7 +7293,7 @@ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IM
|
||||
return cc + 1 + LINK_SIZE;
|
||||
}
|
||||
|
||||
static int SLJIT_CALL do_callout(struct jit_arguments *arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
|
||||
static sljit_s32 SLJIT_FUNC do_callout(struct jit_arguments *arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
|
||||
{
|
||||
const pcre_uchar *begin = arguments->begin;
|
||||
int *offset_vector = arguments->offsets;
|
||||
@ -7207,18 +7375,17 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
||||
/* SLJIT_R0 = arguments */
|
||||
OP1(SLJIT_MOV, SLJIT_R1, 0, STACK_TOP, 0);
|
||||
GET_LOCAL_BASE(SLJIT_R2, 0, OVECTOR_START);
|
||||
sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
|
||||
OP1(SLJIT_MOV_S32, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(S32) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
|
||||
|
||||
/* Check return value. */
|
||||
OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
||||
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER));
|
||||
OP2(SLJIT_SUB32 | SLJIT_SET_Z | SLJIT_SET_SIG_GREATER, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
||||
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_SIG_GREATER32));
|
||||
if (common->forced_quit_label == NULL)
|
||||
add_jump(compiler, &common->forced_quit, JUMP(SLJIT_NOT_EQUAL) /* SIG_LESS */);
|
||||
add_jump(compiler, &common->forced_quit, JUMP(SLJIT_NOT_EQUAL32) /* SIG_LESS */);
|
||||
else
|
||||
JUMPTO(SLJIT_NOT_EQUAL /* SIG_LESS */, common->forced_quit_label);
|
||||
JUMPTO(SLJIT_NOT_EQUAL32 /* SIG_LESS */, common->forced_quit_label);
|
||||
return cc + 2 + 2 * LINK_SIZE;
|
||||
}
|
||||
|
||||
@ -10439,11 +10606,11 @@ if (opcode == OP_SKIP_ARG)
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STACK_TOP, 0);
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
|
||||
sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
|
||||
OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
|
||||
add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
|
||||
add_jump(compiler, &common->reset_match, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -11031,7 +11198,7 @@ if (!compiler)
|
||||
common->compiler = compiler;
|
||||
|
||||
/* Main pcre_jit_exec entry. */
|
||||
sljit_emit_enter(compiler, 0, 1, 5, 5, 0, 0, private_data_size);
|
||||
sljit_emit_enter(compiler, 0, SLJIT_ARG1(SW), 5, 5, 0, 0, private_data_size);
|
||||
|
||||
/* Register init. */
|
||||
reset_ovector(common, (re->top_bracket + 1) * 2);
|
||||
@ -11044,8 +11211,8 @@ OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str))
|
||||
OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
|
||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||
OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
|
||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, end));
|
||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, start));
|
||||
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LIMIT_MATCH, TMP1, 0);
|
||||
|
||||
@ -11251,20 +11418,22 @@ common->quit_label = quit_label;
|
||||
set_jumps(common->stackalloc, LABEL());
|
||||
/* RETURN_ADDR is not a saved register. */
|
||||
sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0);
|
||||
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top), STACK_TOP, 0);
|
||||
OP2(SLJIT_SUB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
|
||||
|
||||
sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
|
||||
jump = CMP(SLJIT_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
||||
OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
|
||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit));
|
||||
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
|
||||
sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
SLJIT_ASSERT(TMP1 == SLJIT_R0 && STACK_TOP == SLJIT_R1);
|
||||
|
||||
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STACK_TOP, 0);
|
||||
OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
|
||||
OP2(SLJIT_SUB, SLJIT_R1, 0, STACK_LIMIT, 0, SLJIT_IMM, STACK_GROWTH_RATE);
|
||||
OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, stack));
|
||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, TMP2, 0);
|
||||
|
||||
sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
|
||||
jump = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
|
||||
OP1(SLJIT_MOV, TMP2, 0, STACK_LIMIT, 0);
|
||||
OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_RETURN_REG, 0);
|
||||
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
|
||||
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
|
||||
sljit_emit_fast_return(compiler, TMP1, 0);
|
||||
|
||||
/* Allocation failed. */
|
||||
JUMPHERE(jump);
|
||||
@ -11409,9 +11578,9 @@ union {
|
||||
sljit_u8 local_space[MACHINE_STACK_SIZE];
|
||||
struct sljit_stack local_stack;
|
||||
|
||||
local_stack.max_limit = local_space;
|
||||
local_stack.limit = local_space;
|
||||
local_stack.base = local_space + MACHINE_STACK_SIZE;
|
||||
local_stack.min_start = local_space;
|
||||
local_stack.start = local_space;
|
||||
local_stack.end = local_space + MACHINE_STACK_SIZE;
|
||||
local_stack.top = local_space + MACHINE_STACK_SIZE;
|
||||
arguments->stack = &local_stack;
|
||||
convert_executable_func.executable_func = executable_func;
|
||||
@ -11529,7 +11698,7 @@ if ((options & PCRE_PARTIAL_HARD) != 0)
|
||||
else if ((options & PCRE_PARTIAL_SOFT) != 0)
|
||||
mode = JIT_PARTIAL_SOFT_COMPILE;
|
||||
|
||||
if (functions->executable_funcs[mode] == NULL)
|
||||
if (functions == NULL || functions->executable_funcs[mode] == NULL)
|
||||
return PCRE_ERROR_JIT_BADOPTION;
|
||||
|
||||
/* Sanity checks should be handled by pcre_exec. */
|
||||
|
@ -1387,8 +1387,8 @@ Returns: nothing
|
||||
*/
|
||||
|
||||
static void
|
||||
do_after_lines(int lastmatchnumber, char *lastmatchrestart, char *endptr,
|
||||
char *printname)
|
||||
do_after_lines(unsigned long int lastmatchnumber, char *lastmatchrestart,
|
||||
char *endptr, char *printname)
|
||||
{
|
||||
if (after_context > 0 && lastmatchnumber > 0)
|
||||
{
|
||||
@ -1398,7 +1398,7 @@ if (after_context > 0 && lastmatchnumber > 0)
|
||||
int ellength;
|
||||
char *pp = lastmatchrestart;
|
||||
if (printname != NULL) fprintf(stdout, "%s-", printname);
|
||||
if (number) fprintf(stdout, "%d-", lastmatchnumber++);
|
||||
if (number) fprintf(stdout, "%lu-", lastmatchnumber++);
|
||||
pp = end_of_line(pp, endptr, &ellength);
|
||||
FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
|
||||
lastmatchrestart = pp;
|
||||
@ -1502,11 +1502,11 @@ static int
|
||||
pcregrep(void *handle, int frtype, char *filename, char *printname)
|
||||
{
|
||||
int rc = 1;
|
||||
int linenumber = 1;
|
||||
int lastmatchnumber = 0;
|
||||
int count = 0;
|
||||
int filepos = 0;
|
||||
int offsets[OFFSET_SIZE];
|
||||
unsigned long int linenumber = 1;
|
||||
unsigned long int lastmatchnumber = 0;
|
||||
unsigned long int count = 0;
|
||||
char *lastmatchrestart = NULL;
|
||||
char *ptr = main_buffer;
|
||||
char *endptr;
|
||||
@ -1609,7 +1609,7 @@ while (ptr < endptr)
|
||||
|
||||
if (endlinelength == 0 && t == main_buffer + bufsize)
|
||||
{
|
||||
fprintf(stderr, "pcregrep: line %d%s%s is too long for the internal buffer\n"
|
||||
fprintf(stderr, "pcregrep: line %lu%s%s is too long for the internal buffer\n"
|
||||
"pcregrep: check the --buffer-size option\n",
|
||||
linenumber,
|
||||
(filename == NULL)? "" : " of file ",
|
||||
@ -1747,7 +1747,7 @@ while (ptr < endptr)
|
||||
prevoffsets[1] = offsets[1];
|
||||
|
||||
if (printname != NULL) fprintf(stdout, "%s:", printname);
|
||||
if (number) fprintf(stdout, "%d:", linenumber);
|
||||
if (number) fprintf(stdout, "%lu:", linenumber);
|
||||
|
||||
/* Handle --line-offsets */
|
||||
|
||||
@ -1862,7 +1862,7 @@ while (ptr < endptr)
|
||||
{
|
||||
char *pp = lastmatchrestart;
|
||||
if (printname != NULL) fprintf(stdout, "%s-", printname);
|
||||
if (number) fprintf(stdout, "%d-", lastmatchnumber++);
|
||||
if (number) fprintf(stdout, "%lu-", lastmatchnumber++);
|
||||
pp = end_of_line(pp, endptr, &ellength);
|
||||
FWRITE(lastmatchrestart, 1, pp - lastmatchrestart, stdout);
|
||||
lastmatchrestart = pp;
|
||||
@ -1902,7 +1902,7 @@ while (ptr < endptr)
|
||||
int ellength;
|
||||
char *pp = p;
|
||||
if (printname != NULL) fprintf(stdout, "%s-", printname);
|
||||
if (number) fprintf(stdout, "%d-", linenumber - linecount--);
|
||||
if (number) fprintf(stdout, "%lu-", linenumber - linecount--);
|
||||
pp = end_of_line(pp, endptr, &ellength);
|
||||
FWRITE(p, 1, pp - p, stdout);
|
||||
p = pp;
|
||||
@ -1916,7 +1916,7 @@ while (ptr < endptr)
|
||||
endhyphenpending = TRUE;
|
||||
|
||||
if (printname != NULL) fprintf(stdout, "%s:", printname);
|
||||
if (number) fprintf(stdout, "%d:", linenumber);
|
||||
if (number) fprintf(stdout, "%lu:", linenumber);
|
||||
|
||||
/* In multiline mode, we want to print to the end of the line in which
|
||||
the end of the matched string is found, so we adjust linelength and the
|
||||
@ -2112,7 +2112,7 @@ if (count_only && !quiet)
|
||||
{
|
||||
if (printname != NULL && filenames != FN_NONE)
|
||||
fprintf(stdout, "%s:", printname);
|
||||
fprintf(stdout, "%d\n", count);
|
||||
fprintf(stdout, "%lu\n", count);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2234,7 +2234,7 @@ if (isdirectory(pathname))
|
||||
|
||||
if (dee_action == dee_RECURSE)
|
||||
{
|
||||
char buffer[1024];
|
||||
char buffer[2048];
|
||||
char *nextfile;
|
||||
directory_type *dir = opendirectory(pathname);
|
||||
|
||||
@ -2249,7 +2249,14 @@ if (isdirectory(pathname))
|
||||
while ((nextfile = readdirectory(dir)) != NULL)
|
||||
{
|
||||
int frc;
|
||||
sprintf(buffer, "%.512s%c%.128s", pathname, FILESEP, nextfile);
|
||||
int fnlength = strlen(pathname) + strlen(nextfile) + 2;
|
||||
if (fnlength > 2048)
|
||||
{
|
||||
fprintf(stderr, "pcre2grep: recursive filename is too long\n");
|
||||
rc = 2;
|
||||
break;
|
||||
}
|
||||
sprintf(buffer, "%s%c%s", pathname, FILESEP, nextfile);
|
||||
frc = grep_or_recurse(buffer, dir_recurse, FALSE);
|
||||
if (frc > 1) rc = frc;
|
||||
else if (frc == 0 && rc == 1) rc = 0;
|
||||
@ -2520,7 +2527,14 @@ if ((popts & PO_FIXED_STRINGS) != 0)
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(buffer, "%s%.*s%s", prefix[popts], patlen, ps, suffix[popts]);
|
||||
if (snprintf(buffer, PATBUFSIZE, "%s%.*s%s", prefix[popts], patlen, ps,
|
||||
suffix[popts]) > PATBUFSIZE)
|
||||
{
|
||||
fprintf(stderr, "pcregrep: Buffer overflow while compiling \"%s\"\n",
|
||||
ps);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
p->compiled = pcre_compile(buffer, options, &error, &errptr, pcretables);
|
||||
if (p->compiled != NULL) return TRUE;
|
||||
|
||||
@ -2756,8 +2770,15 @@ for (i = 1; i < argc; i++)
|
||||
int arglen = (argequals == NULL || equals == NULL)?
|
||||
(int)strlen(arg) : (int)(argequals - arg);
|
||||
|
||||
sprintf(buff1, "%.*s", baselen, op->long_name);
|
||||
sprintf(buff2, "%s%.*s", buff1, fulllen - baselen - 2, opbra + 1);
|
||||
if (snprintf(buff1, sizeof(buff1), "%.*s", baselen, op->long_name) >
|
||||
(int)sizeof(buff1) ||
|
||||
snprintf(buff2, sizeof(buff2), "%s%.*s", buff1,
|
||||
fulllen - baselen - 2, opbra + 1) > (int)sizeof(buff2))
|
||||
{
|
||||
fprintf(stderr, "pcregrep: Buffer overflow when parsing %s option\n",
|
||||
op->long_name);
|
||||
pcregrep_exit(2);
|
||||
}
|
||||
|
||||
if (strncmp(arg, buff1, arglen) == 0 ||
|
||||
strncmp(arg, buff2, arglen) == 0)
|
||||
|
@ -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-2017 University of Cambridge
|
||||
Copyright (c) 1997-2018 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -389,8 +389,8 @@ if (rc >= 0)
|
||||
{
|
||||
for (i = 0; i < (size_t)rc; i++)
|
||||
{
|
||||
pmatch[i].rm_so = ovector[i*2] + so;
|
||||
pmatch[i].rm_eo = ovector[i*2+1] + so;
|
||||
pmatch[i].rm_so = (ovector[i*2] < 0)? -1 : ovector[i*2] + so;
|
||||
pmatch[i].rm_eo = (ovector[i*2+1] < 0)? -1: ovector[i*2+1] + so;
|
||||
}
|
||||
if (allocated_ovector) free(ovector);
|
||||
for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
|
||||
|
@ -108,8 +108,10 @@
|
||||
|
||||
/* Force cdecl calling convention even if a better calling
|
||||
convention (e.g. fastcall) is supported by the C compiler.
|
||||
If this option is enabled, C functions without
|
||||
SLJIT_CALL can also be called from JIT code. */
|
||||
If this option is disabled (this is the default), functions
|
||||
called from JIT should be defined with SLJIT_FUNC attribute.
|
||||
Standard C functions can still be called by using the
|
||||
SLJIT_CALL_CDECL jump type. */
|
||||
#ifndef SLJIT_USE_CDECL_CALLING_CONVENTION
|
||||
/* Disabled by default */
|
||||
#define SLJIT_USE_CDECL_CALLING_CONVENTION 0
|
||||
|
@ -60,11 +60,13 @@
|
||||
a single precision floating point array by index
|
||||
SLJIT_F64_SHIFT : the shift required to apply when accessing
|
||||
a double precision floating point array by index
|
||||
SLJIT_PREF_SHIFT_REG : x86 systems prefers ecx for shifting by register
|
||||
the scratch register index of ecx is stored in this variable
|
||||
SLJIT_LOCALS_OFFSET : local space starting offset (SLJIT_SP + SLJIT_LOCALS_OFFSET)
|
||||
SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address
|
||||
|
||||
Other macros:
|
||||
SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT
|
||||
SLJIT_FUNC : calling convention attribute for both calling JIT form C and C calling back from JIT
|
||||
SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper)
|
||||
*/
|
||||
|
||||
@ -145,17 +147,23 @@
|
||||
#define SLJIT_CONFIG_UNSUPPORTED 1
|
||||
#endif
|
||||
|
||||
#else /* !_WIN32 */
|
||||
#else /* _WIN32 */
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
#define SLJIT_CONFIG_X86_64 1
|
||||
#elif (defined(_M_ARM) && _M_ARM >= 7 && defined(_M_ARMT)) || defined(__thumb2__)
|
||||
#define SLJIT_CONFIG_ARM_THUMB2 1
|
||||
#elif (defined(_M_ARM) && _M_ARM >= 7)
|
||||
#define SLJIT_CONFIG_ARM_V7 1
|
||||
#elif defined(_ARM_)
|
||||
#define SLJIT_CONFIG_ARM_V5 1
|
||||
#elif defined(_M_ARM64) || defined(__aarch64__)
|
||||
#define SLJIT_CONFIG_ARM_64 1
|
||||
#else
|
||||
#define SLJIT_CONFIG_X86_32 1
|
||||
#endif
|
||||
|
||||
#endif /* !WIN32 */
|
||||
#endif /* !_WIN32 */
|
||||
#endif /* SLJIT_CONFIG_AUTO */
|
||||
|
||||
#if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)
|
||||
@ -322,6 +330,11 @@
|
||||
sparc_cache_flush((from), (to))
|
||||
#define SLJIT_CACHE_FLUSH_OWN_IMPL 1
|
||||
|
||||
#elif defined _WIN32
|
||||
|
||||
#define SLJIT_CACHE_FLUSH(from, to) \
|
||||
FlushInstructionCache(GetCurrentProcess(), (char*)(from), (char*)(to) - (char*)(from))
|
||||
|
||||
#else
|
||||
|
||||
/* Calls __ARM_NR_cacheflush on ARM-Linux. */
|
||||
@ -369,12 +382,18 @@ typedef int sljit_sw;
|
||||
#define SLJIT_64BIT_ARCHITECTURE 1
|
||||
#define SLJIT_WORD_SHIFT 3
|
||||
#ifdef _WIN32
|
||||
#ifdef __GNUC__
|
||||
/* These types do not require windows.h */
|
||||
typedef unsigned long long sljit_uw;
|
||||
typedef long long sljit_sw;
|
||||
#else
|
||||
typedef unsigned __int64 sljit_uw;
|
||||
typedef __int64 sljit_sw;
|
||||
#else
|
||||
#endif
|
||||
#else /* !_WIN32 */
|
||||
typedef unsigned long int sljit_uw;
|
||||
typedef long int sljit_sw;
|
||||
#endif
|
||||
#endif /* _WIN32 */
|
||||
#endif
|
||||
|
||||
typedef sljit_uw sljit_p;
|
||||
@ -471,44 +490,44 @@ typedef double sljit_f64;
|
||||
/* Calling convention of functions generated by SLJIT or called from the generated code. */
|
||||
/*****************************************************************************************/
|
||||
|
||||
#ifndef SLJIT_CALL
|
||||
#ifndef SLJIT_FUNC
|
||||
|
||||
#if (defined SLJIT_USE_CDECL_CALLING_CONVENTION && SLJIT_USE_CDECL_CALLING_CONVENTION)
|
||||
|
||||
/* Force cdecl. */
|
||||
#define SLJIT_CALL
|
||||
#define SLJIT_FUNC
|
||||
|
||||
#elif (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
|
||||
#if defined(__GNUC__) && !defined(__APPLE__)
|
||||
|
||||
#define SLJIT_CALL __attribute__ ((fastcall))
|
||||
#define SLJIT_FUNC __attribute__ ((fastcall))
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
#define SLJIT_CALL __fastcall
|
||||
#define SLJIT_FUNC __fastcall
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
|
||||
#elif defined(__BORLANDC__)
|
||||
|
||||
#define SLJIT_CALL __msfastcall
|
||||
#define SLJIT_FUNC __msfastcall
|
||||
#define SLJIT_X86_32_FASTCALL 1
|
||||
|
||||
#else /* Unknown compiler. */
|
||||
|
||||
/* The cdecl attribute is the default. */
|
||||
#define SLJIT_CALL
|
||||
#define SLJIT_FUNC
|
||||
|
||||
#endif
|
||||
|
||||
#else /* Non x86-32 architectures. */
|
||||
|
||||
#define SLJIT_CALL
|
||||
#define SLJIT_FUNC
|
||||
|
||||
#endif /* SLJIT_CONFIG_X86_32 */
|
||||
|
||||
#endif /* !SLJIT_CALL */
|
||||
#endif /* !SLJIT_FUNC */
|
||||
|
||||
#ifndef SLJIT_INDIRECT_CALL
|
||||
#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)) \
|
||||
@ -557,24 +576,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 12
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 9
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (compiler->locals_offset)
|
||||
#else
|
||||
/* Maximum 3 arguments are passed on the stack, +1 for double alignment. */
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (compiler->locals_offset)
|
||||
#endif /* SLJIT_X86_32_FASTCALL */
|
||||
#define SLJIT_PREF_SHIFT_REG SLJIT_R2
|
||||
|
||||
#elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
|
||||
#ifndef _WIN64
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 13
|
||||
#ifndef _WIN64
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 6
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
#else
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 13
|
||||
#else /* _WIN64 */
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 8
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (compiler->locals_offset)
|
||||
#endif /* _WIN64 */
|
||||
#endif /* !_WIN64 */
|
||||
#define SLJIT_PREF_SHIFT_REG SLJIT_R3
|
||||
|
||||
#elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
|
||||
|
||||
@ -590,13 +605,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
||||
|
||||
#elif (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 25
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 26
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 10
|
||||
#define SLJIT_LOCALS_OFFSET_BASE (2 * sizeof(sljit_sw))
|
||||
#define SLJIT_LOCALS_OFFSET_BASE 0
|
||||
|
||||
#elif (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
||||
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 22
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 23
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 17
|
||||
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX)
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * sizeof(sljit_sw))
|
||||
@ -622,8 +637,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void* ptr);
|
||||
#define SLJIT_NUMBER_OF_REGISTERS 18
|
||||
#define SLJIT_NUMBER_OF_SAVED_REGISTERS 14
|
||||
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
|
||||
/* Add +1 for double alignment. */
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((23 + 1) * sizeof(sljit_sw))
|
||||
/* saved registers (16), return struct pointer (1), space for 6 argument words (1),
|
||||
4th double arg (2), double alignment (1). */
|
||||
#define SLJIT_LOCALS_OFFSET_BASE ((16 + 1 + 6 + 2 + 1) * sizeof(sljit_sw))
|
||||
#endif
|
||||
|
||||
#elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
|
||||
|
@ -26,6 +26,13 @@
|
||||
|
||||
#include "sljitLir.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* For SLJIT_CACHE_FLUSH, which can expand to FlushInstructionCache. */
|
||||
#include <windows.h>
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#if !(defined SLJIT_STD_MACROS_DEFINED && SLJIT_STD_MACROS_DEFINED)
|
||||
|
||||
/* These libraries are needed for the macros below. */
|
||||
@ -97,8 +104,13 @@
|
||||
#define GET_ALL_FLAGS(op) \
|
||||
((op) & (SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
|
||||
|
||||
#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
|
||||
#define TYPE_CAST_NEEDED(op) \
|
||||
(((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16) || ((op) >= SLJIT_MOVU_U8 && (op) <= SLJIT_MOVU_S16))
|
||||
((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S32)
|
||||
#else
|
||||
#define TYPE_CAST_NEEDED(op) \
|
||||
((op) >= SLJIT_MOV_U8 && (op) <= SLJIT_MOV_S16)
|
||||
#endif
|
||||
|
||||
#define BUF_SIZE 4096
|
||||
|
||||
@ -118,16 +130,19 @@
|
||||
/* When reg can be unused. */
|
||||
#define SLOW_IS_REG(reg) ((reg) > 0 && (reg) <= REG_MASK)
|
||||
|
||||
/* Mask for argument types. */
|
||||
#define SLJIT_DEF_MASK ((1 << SLJIT_DEF_SHIFT) - 1)
|
||||
|
||||
/* Jump flags. */
|
||||
#define JUMP_LABEL 0x1
|
||||
#define JUMP_ADDR 0x2
|
||||
/* SLJIT_REWRITABLE_JUMP is 0x1000. */
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
# define PATCH_MB 0x4
|
||||
# define PATCH_MW 0x8
|
||||
# define PATCH_MB 0x4
|
||||
# define PATCH_MW 0x8
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
# define PATCH_MD 0x10
|
||||
# define PATCH_MD 0x10
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -591,6 +606,19 @@ static SLJIT_INLINE void reverse_buf(struct sljit_compiler *compiler)
|
||||
compiler->buf = prev;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 get_arg_count(sljit_s32 arg_types)
|
||||
{
|
||||
sljit_s32 arg_count = 0;
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
while (arg_types) {
|
||||
arg_count++;
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
return arg_count;
|
||||
}
|
||||
|
||||
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)
|
||||
@ -664,80 +692,106 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
|
||||
#define FUNCTION_CHECK_IS_REG(r) \
|
||||
(((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \
|
||||
((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
|
||||
(((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) \
|
||||
|| ((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
|
||||
|
||||
#define FUNCTION_CHECK_IS_REG_OR_UNUSED(r) \
|
||||
((r) == SLJIT_UNUSED || \
|
||||
((r) >= SLJIT_R0 && (r) < (SLJIT_R0 + compiler->scratches)) || \
|
||||
((r) > (SLJIT_S0 - compiler->saveds) && (r) <= SLJIT_S0))
|
||||
#define FUNCTION_CHECK_IS_FREG(fr) \
|
||||
(((fr) >= SLJIT_FR0 && (fr) < (SLJIT_FR0 + compiler->fscratches)) \
|
||||
|| ((fr) > (SLJIT_FS0 - compiler->fsaveds) && (fr) <= SLJIT_FS0))
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
#define CHECK_NOT_VIRTUAL_REGISTER(p) \
|
||||
CHECK_ARGUMENT((p) < SLJIT_R3 || (p) > SLJIT_R6);
|
||||
#define CHECK_IF_VIRTUAL_REGISTER(p) ((p) <= SLJIT_S3 && (p) >= SLJIT_S8)
|
||||
#else
|
||||
#define CHECK_NOT_VIRTUAL_REGISTER(p)
|
||||
#define CHECK_IF_VIRTUAL_REGISTER(p) 0
|
||||
#endif
|
||||
|
||||
#define FUNCTION_CHECK_SRC(p, i) \
|
||||
CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \
|
||||
if (FUNCTION_CHECK_IS_REG(p)) \
|
||||
CHECK_ARGUMENT((i) == 0); \
|
||||
else if ((p) == SLJIT_IMM) \
|
||||
; \
|
||||
else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
|
||||
CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
|
||||
else { \
|
||||
CHECK_ARGUMENT((p) & SLJIT_MEM); \
|
||||
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
|
||||
CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
|
||||
if ((p) & OFFS_REG_MASK) { \
|
||||
CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
|
||||
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
|
||||
CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
|
||||
CHECK_ARGUMENT(!((i) & ~0x3)); \
|
||||
} \
|
||||
CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | REG_MASK | OFFS_REG_MASK))); \
|
||||
static sljit_s32 function_check_src_mem(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
|
||||
{
|
||||
if (compiler->scratches == -1 || compiler->saveds == -1)
|
||||
return 0;
|
||||
|
||||
if (!(p & SLJIT_MEM))
|
||||
return 0;
|
||||
|
||||
if (!((p & REG_MASK) == SLJIT_UNUSED || FUNCTION_CHECK_IS_REG(p & REG_MASK)))
|
||||
return 0;
|
||||
|
||||
if (CHECK_IF_VIRTUAL_REGISTER(p & REG_MASK))
|
||||
return 0;
|
||||
|
||||
if (p & OFFS_REG_MASK) {
|
||||
if ((p & REG_MASK) == SLJIT_UNUSED)
|
||||
return 0;
|
||||
|
||||
if (!(FUNCTION_CHECK_IS_REG(OFFS_REG(p))))
|
||||
return 0;
|
||||
|
||||
if (CHECK_IF_VIRTUAL_REGISTER(OFFS_REG(p)))
|
||||
return 0;
|
||||
|
||||
if ((i & ~0x3) != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (p & ~(SLJIT_MEM | REG_MASK | OFFS_REG_MASK)) == 0;
|
||||
}
|
||||
|
||||
#define FUNCTION_CHECK_SRC_MEM(p, i) \
|
||||
CHECK_ARGUMENT(function_check_src_mem(compiler, p, i));
|
||||
|
||||
static sljit_s32 function_check_src(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
|
||||
{
|
||||
if (compiler->scratches == -1 || compiler->saveds == -1)
|
||||
return 0;
|
||||
|
||||
if (FUNCTION_CHECK_IS_REG(p))
|
||||
return (i == 0);
|
||||
|
||||
if (p == SLJIT_IMM)
|
||||
return 1;
|
||||
|
||||
if (p == SLJIT_MEM1(SLJIT_SP))
|
||||
return (i >= 0 && i < compiler->logical_local_size);
|
||||
|
||||
return function_check_src_mem(compiler, p, i);
|
||||
}
|
||||
|
||||
#define FUNCTION_CHECK_SRC(p, i) \
|
||||
CHECK_ARGUMENT(function_check_src(compiler, p, i));
|
||||
|
||||
static sljit_s32 function_check_dst(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i, sljit_s32 unused)
|
||||
{
|
||||
if (compiler->scratches == -1 || compiler->saveds == -1)
|
||||
return 0;
|
||||
|
||||
if (FUNCTION_CHECK_IS_REG(p) || ((unused) && (p) == SLJIT_UNUSED))
|
||||
return (i == 0);
|
||||
|
||||
if (p == SLJIT_MEM1(SLJIT_SP))
|
||||
return (i >= 0 && i < compiler->logical_local_size);
|
||||
|
||||
return function_check_src_mem(compiler, p, i);
|
||||
}
|
||||
|
||||
#define FUNCTION_CHECK_DST(p, i, unused) \
|
||||
CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1); \
|
||||
if (FUNCTION_CHECK_IS_REG(p) || ((unused) && (p) == SLJIT_UNUSED)) \
|
||||
CHECK_ARGUMENT((i) == 0); \
|
||||
else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
|
||||
CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
|
||||
else { \
|
||||
CHECK_ARGUMENT((p) & SLJIT_MEM); \
|
||||
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
|
||||
CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
|
||||
if ((p) & OFFS_REG_MASK) { \
|
||||
CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
|
||||
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
|
||||
CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
|
||||
CHECK_ARGUMENT(!((i) & ~0x3)); \
|
||||
} \
|
||||
CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | REG_MASK | OFFS_REG_MASK))); \
|
||||
}
|
||||
CHECK_ARGUMENT(function_check_dst(compiler, p, i, unused));
|
||||
|
||||
static sljit_s32 function_fcheck(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
|
||||
{
|
||||
if (compiler->scratches == -1 || compiler->saveds == -1)
|
||||
return 0;
|
||||
|
||||
if (FUNCTION_CHECK_IS_FREG(p))
|
||||
return (i == 0);
|
||||
|
||||
if (p == SLJIT_MEM1(SLJIT_SP))
|
||||
return (i >= 0 && i < compiler->logical_local_size);
|
||||
|
||||
return function_check_src_mem(compiler, p, i);
|
||||
}
|
||||
|
||||
#define FUNCTION_FCHECK(p, i) \
|
||||
CHECK_ARGUMENT(compiler->fscratches != -1 && compiler->fsaveds != -1); \
|
||||
if (((p) >= SLJIT_FR0 && (p) < (SLJIT_FR0 + compiler->fscratches)) || \
|
||||
((p) > (SLJIT_FS0 - compiler->fsaveds) && (p) <= SLJIT_FS0)) \
|
||||
CHECK_ARGUMENT(i == 0); \
|
||||
else if ((p) == (SLJIT_MEM1(SLJIT_SP))) \
|
||||
CHECK_ARGUMENT((i) >= 0 && (i) < compiler->logical_local_size); \
|
||||
else { \
|
||||
CHECK_ARGUMENT((p) & SLJIT_MEM); \
|
||||
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG_OR_UNUSED((p) & REG_MASK)); \
|
||||
CHECK_NOT_VIRTUAL_REGISTER((p) & REG_MASK); \
|
||||
if ((p) & OFFS_REG_MASK) { \
|
||||
CHECK_ARGUMENT(((p) & REG_MASK) != SLJIT_UNUSED); \
|
||||
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(OFFS_REG(p))); \
|
||||
CHECK_NOT_VIRTUAL_REGISTER(OFFS_REG(p)); \
|
||||
CHECK_ARGUMENT(((p) & OFFS_REG_MASK) != TO_OFFS_REG(SLJIT_SP) && !(i & ~0x3)); \
|
||||
} \
|
||||
CHECK_ARGUMENT(!((p) & ~(SLJIT_MEM | REG_MASK | OFFS_REG_MASK))); \
|
||||
}
|
||||
CHECK_ARGUMENT(function_fcheck(compiler, p, i));
|
||||
|
||||
#endif /* SLJIT_ARGUMENT_CHECKS */
|
||||
|
||||
@ -758,64 +812,72 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *comp
|
||||
# define SLJIT_PRINT_D ""
|
||||
#endif
|
||||
|
||||
#define sljit_verbose_reg(compiler, r) \
|
||||
do { \
|
||||
if ((r) < (SLJIT_R0 + compiler->scratches)) \
|
||||
fprintf(compiler->verbose, "r%d", (r) - SLJIT_R0); \
|
||||
else if ((r) != SLJIT_SP) \
|
||||
fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - (r)); \
|
||||
else \
|
||||
fprintf(compiler->verbose, "sp"); \
|
||||
} while (0)
|
||||
static void sljit_verbose_reg(struct sljit_compiler *compiler, sljit_s32 r)
|
||||
{
|
||||
if (r < (SLJIT_R0 + compiler->scratches))
|
||||
fprintf(compiler->verbose, "r%d", r - SLJIT_R0);
|
||||
else if (r != SLJIT_SP)
|
||||
fprintf(compiler->verbose, "s%d", SLJIT_NUMBER_OF_REGISTERS - r);
|
||||
else
|
||||
fprintf(compiler->verbose, "sp");
|
||||
}
|
||||
|
||||
#define sljit_verbose_param(compiler, p, i) \
|
||||
if ((p) & SLJIT_IMM) \
|
||||
fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i)); \
|
||||
else if ((p) & SLJIT_MEM) { \
|
||||
if ((p) & REG_MASK) { \
|
||||
fputc('[', compiler->verbose); \
|
||||
sljit_verbose_reg(compiler, (p) & REG_MASK); \
|
||||
if ((p) & OFFS_REG_MASK) { \
|
||||
fprintf(compiler->verbose, " + "); \
|
||||
sljit_verbose_reg(compiler, OFFS_REG(p)); \
|
||||
if (i) \
|
||||
fprintf(compiler->verbose, " * %d", 1 << (i)); \
|
||||
} \
|
||||
else if (i) \
|
||||
fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i)); \
|
||||
fputc(']', compiler->verbose); \
|
||||
} \
|
||||
else \
|
||||
fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \
|
||||
} else if (p) \
|
||||
sljit_verbose_reg(compiler, p); \
|
||||
else \
|
||||
static void sljit_verbose_freg(struct sljit_compiler *compiler, sljit_s32 r)
|
||||
{
|
||||
if (r < (SLJIT_FR0 + compiler->fscratches))
|
||||
fprintf(compiler->verbose, "fr%d", r - SLJIT_FR0);
|
||||
else
|
||||
fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - r);
|
||||
}
|
||||
|
||||
static void sljit_verbose_param(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
|
||||
{
|
||||
if ((p) & SLJIT_IMM)
|
||||
fprintf(compiler->verbose, "#%" SLJIT_PRINT_D "d", (i));
|
||||
else if ((p) & SLJIT_MEM) {
|
||||
if ((p) & REG_MASK) {
|
||||
fputc('[', compiler->verbose);
|
||||
sljit_verbose_reg(compiler, (p) & REG_MASK);
|
||||
if ((p) & OFFS_REG_MASK) {
|
||||
fprintf(compiler->verbose, " + ");
|
||||
sljit_verbose_reg(compiler, OFFS_REG(p));
|
||||
if (i)
|
||||
fprintf(compiler->verbose, " * %d", 1 << (i));
|
||||
}
|
||||
else if (i)
|
||||
fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i));
|
||||
fputc(']', compiler->verbose);
|
||||
}
|
||||
else
|
||||
fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i));
|
||||
} else if (p)
|
||||
sljit_verbose_reg(compiler, p);
|
||||
else
|
||||
fprintf(compiler->verbose, "unused");
|
||||
}
|
||||
|
||||
#define sljit_verbose_fparam(compiler, p, i) \
|
||||
if ((p) & SLJIT_MEM) { \
|
||||
if ((p) & REG_MASK) { \
|
||||
fputc('[', compiler->verbose); \
|
||||
sljit_verbose_reg(compiler, (p) & REG_MASK); \
|
||||
if ((p) & OFFS_REG_MASK) { \
|
||||
fprintf(compiler->verbose, " + "); \
|
||||
sljit_verbose_reg(compiler, OFFS_REG(p)); \
|
||||
if (i) \
|
||||
fprintf(compiler->verbose, "%d", 1 << (i)); \
|
||||
} \
|
||||
else if (i) \
|
||||
fprintf(compiler->verbose, "%" SLJIT_PRINT_D "d", (i)); \
|
||||
fputc(']', compiler->verbose); \
|
||||
} \
|
||||
else \
|
||||
fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i)); \
|
||||
} \
|
||||
else { \
|
||||
if ((p) < (SLJIT_FR0 + compiler->fscratches)) \
|
||||
fprintf(compiler->verbose, "fr%d", (p) - SLJIT_FR0); \
|
||||
else \
|
||||
fprintf(compiler->verbose, "fs%d", SLJIT_NUMBER_OF_FLOAT_REGISTERS - (p)); \
|
||||
static void sljit_verbose_fparam(struct sljit_compiler *compiler, sljit_s32 p, sljit_sw i)
|
||||
{
|
||||
if ((p) & SLJIT_MEM) {
|
||||
if ((p) & REG_MASK) {
|
||||
fputc('[', compiler->verbose);
|
||||
sljit_verbose_reg(compiler, (p) & REG_MASK);
|
||||
if ((p) & OFFS_REG_MASK) {
|
||||
fprintf(compiler->verbose, " + ");
|
||||
sljit_verbose_reg(compiler, OFFS_REG(p));
|
||||
if (i)
|
||||
fprintf(compiler->verbose, "%d", 1 << (i));
|
||||
}
|
||||
else if (i)
|
||||
fprintf(compiler->verbose, " + %" SLJIT_PRINT_D "d", (i));
|
||||
fputc(']', compiler->verbose);
|
||||
}
|
||||
else
|
||||
fprintf(compiler->verbose, "[#%" SLJIT_PRINT_D "d]", (i));
|
||||
}
|
||||
else
|
||||
sljit_verbose_freg(compiler, p);
|
||||
}
|
||||
|
||||
static const char* op0_names[] = {
|
||||
(char*)"breakpoint", (char*)"nop", (char*)"lmul.uw", (char*)"lmul.sw",
|
||||
@ -864,7 +926,11 @@ static char* jump_names[] = {
|
||||
(char*)"greater", (char*)"less_equal",
|
||||
(char*)"unordered", (char*)"ordered",
|
||||
(char*)"jump", (char*)"fast_call",
|
||||
(char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
|
||||
(char*)"call", (char*)"call.cdecl"
|
||||
};
|
||||
|
||||
static char* call_arg_names[] = {
|
||||
(char*)"void", (char*)"sw", (char*)"uw", (char*)"s32", (char*)"u32", (char*)"f32", (char*)"f64"
|
||||
};
|
||||
|
||||
#endif /* SLJIT_VERBOSE */
|
||||
@ -897,53 +963,104 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_com
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
sljit_s32 types, arg_count, curr_type;
|
||||
#endif
|
||||
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
CHECK_ARGUMENT(!(options & ~SLJIT_F64_ALIGNMENT));
|
||||
CHECK_ARGUMENT(args >= 0 && args <= 3);
|
||||
CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
|
||||
CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS);
|
||||
CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
|
||||
CHECK_ARGUMENT(args <= saveds);
|
||||
CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
|
||||
CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
|
||||
CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
|
||||
CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
|
||||
CHECK_ARGUMENT((arg_types & SLJIT_DEF_MASK) == 0);
|
||||
|
||||
types = (arg_types >> SLJIT_DEF_SHIFT);
|
||||
arg_count = 0;
|
||||
while (types != 0 && arg_count < 3) {
|
||||
curr_type = (types & SLJIT_DEF_MASK);
|
||||
CHECK_ARGUMENT(curr_type == SLJIT_ARG_TYPE_SW || curr_type == SLJIT_ARG_TYPE_UW);
|
||||
arg_count++;
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
CHECK_ARGUMENT(arg_count <= saveds && types == 0);
|
||||
|
||||
compiler->last_flags = 0;
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose))
|
||||
fprintf(compiler->verbose, " enter options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
|
||||
args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
||||
fprintf(compiler->verbose, " enter options:%s args[", (options & SLJIT_F64_ALIGNMENT) ? "f64_align" : "");
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
while (arg_types) {
|
||||
fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
if (arg_types)
|
||||
fprintf(compiler->verbose, ",");
|
||||
}
|
||||
|
||||
fprintf(compiler->verbose, "] scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
|
||||
scratches, saveds, fscratches, fsaveds, local_size);
|
||||
}
|
||||
#endif
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
sljit_s32 types, arg_count, curr_type;
|
||||
#endif
|
||||
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
CHECK_ARGUMENT(!(options & ~SLJIT_F64_ALIGNMENT));
|
||||
CHECK_ARGUMENT(args >= 0 && args <= 3);
|
||||
CHECK_ARGUMENT(scratches >= 0 && scratches <= SLJIT_NUMBER_OF_REGISTERS);
|
||||
CHECK_ARGUMENT(saveds >= 0 && saveds <= SLJIT_NUMBER_OF_REGISTERS);
|
||||
CHECK_ARGUMENT(scratches + saveds <= SLJIT_NUMBER_OF_REGISTERS);
|
||||
CHECK_ARGUMENT(args <= saveds);
|
||||
CHECK_ARGUMENT(fscratches >= 0 && fscratches <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
|
||||
CHECK_ARGUMENT(fsaveds >= 0 && fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
|
||||
CHECK_ARGUMENT(fscratches + fsaveds <= SLJIT_NUMBER_OF_FLOAT_REGISTERS);
|
||||
CHECK_ARGUMENT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE);
|
||||
|
||||
types = (arg_types >> SLJIT_DEF_SHIFT);
|
||||
arg_count = 0;
|
||||
while (types != 0 && arg_count < 3) {
|
||||
curr_type = (types & SLJIT_DEF_MASK);
|
||||
CHECK_ARGUMENT(curr_type == SLJIT_ARG_TYPE_SW || curr_type == SLJIT_ARG_TYPE_UW);
|
||||
arg_count++;
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
CHECK_ARGUMENT(arg_count <= saveds && types == 0);
|
||||
|
||||
compiler->last_flags = 0;
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose))
|
||||
fprintf(compiler->verbose, " set_context options:none args:%d scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
|
||||
args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
||||
fprintf(compiler->verbose, " set_context options:%s args[", (options & SLJIT_F64_ALIGNMENT) ? "f64_align" : "");
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
while (arg_types) {
|
||||
fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
if (arg_types)
|
||||
fprintf(compiler->verbose, ",");
|
||||
}
|
||||
|
||||
fprintf(compiler->verbose, "] scratches:%d saveds:%d fscratches:%d fsaveds:%d local_size:%d\n",
|
||||
scratches, saveds, fscratches, fsaveds, local_size);
|
||||
}
|
||||
#endif
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
@ -994,6 +1111,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fast_return(struct sljit_
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
FUNCTION_CHECK_SRC(src, srcw);
|
||||
CHECK_ARGUMENT(src != SLJIT_IMM);
|
||||
compiler->last_flags = 0;
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
@ -1052,9 +1170,6 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_P:
|
||||
case SLJIT_MOVU:
|
||||
case SLJIT_MOVU_U32:
|
||||
case SLJIT_MOVU_P:
|
||||
/* Nothing allowed */
|
||||
CHECK_ARGUMENT(!(op & (SLJIT_I32_OP | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
|
||||
break;
|
||||
@ -1067,28 +1182,17 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler
|
||||
FUNCTION_CHECK_DST(dst, dstw, 1);
|
||||
FUNCTION_CHECK_SRC(src, srcw);
|
||||
|
||||
if (GET_OPCODE(op) >= SLJIT_NOT)
|
||||
if (GET_OPCODE(op) >= SLJIT_NOT) {
|
||||
CHECK_ARGUMENT(src != SLJIT_IMM);
|
||||
compiler->last_flags = GET_FLAG_TYPE(op) | (op & (SLJIT_I32_OP | SLJIT_SET_Z));
|
||||
else if (GET_OPCODE(op) >= SLJIT_MOVU) {
|
||||
CHECK_ARGUMENT(!(src & SLJIT_MEM) || (src & REG_MASK) != SLJIT_SP);
|
||||
CHECK_ARGUMENT(!(dst & SLJIT_MEM) || (dst & REG_MASK) != SLJIT_SP);
|
||||
if ((src & REG_MASK) != SLJIT_UNUSED) {
|
||||
CHECK_ARGUMENT((src & REG_MASK) != (dst & REG_MASK) && (src & REG_MASK) != OFFS_REG(dst));
|
||||
CHECK_ARGUMENT((src & OFFS_REG_MASK) == SLJIT_UNUSED || srcw == 0);
|
||||
}
|
||||
if ((dst & REG_MASK) != SLJIT_UNUSED) {
|
||||
CHECK_ARGUMENT((dst & REG_MASK) != OFFS_REG(src));
|
||||
CHECK_ARGUMENT((dst & OFFS_REG_MASK) == SLJIT_UNUSED || dstw == 0);
|
||||
}
|
||||
compiler->last_flags = 0;
|
||||
}
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
||||
if (GET_OPCODE(op) <= SLJIT_MOVU_P)
|
||||
if (GET_OPCODE(op) <= SLJIT_MOV_P)
|
||||
{
|
||||
fprintf(compiler->verbose, " mov%s%s%s ", (GET_OPCODE(op) >= SLJIT_MOVU) ? "u" : "",
|
||||
!(op & SLJIT_I32_OP) ? "" : "32", (op != SLJIT_MOV32 && op != SLJIT_MOVU32) ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : "");
|
||||
fprintf(compiler->verbose, " mov%s%s ", !(op & SLJIT_I32_OP) ? "" : "32",
|
||||
(op != SLJIT_MOV32) ? op1_names[GET_OPCODE(op) - SLJIT_OP1_BASE] : "");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1417,9 +1521,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compile
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_I32_OP)));
|
||||
CHECK_ARGUMENT((type & 0xff) != GET_FLAG_TYPE(SLJIT_SET_CARRY) && (type & 0xff) != (GET_FLAG_TYPE(SLJIT_SET_CARRY) + 1));
|
||||
CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_CALL3);
|
||||
CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_FAST_CALL);
|
||||
CHECK_ARGUMENT((type & 0xff) < SLJIT_JUMP || !(type & SLJIT_I32_OP));
|
||||
CHECK_ARGUMENT((type & 0xff) <= SLJIT_CALL0 || ((type & 0xff) - SLJIT_CALL0) <= compiler->scratches);
|
||||
|
||||
if ((type & 0xff) < SLJIT_JUMP) {
|
||||
if ((type & 0xff) <= SLJIT_NOT_ZERO)
|
||||
@ -1439,6 +1542,63 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_jump(struct sljit_compile
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types)
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
sljit_s32 i, types, curr_type, scratches, fscratches;
|
||||
|
||||
CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP)));
|
||||
CHECK_ARGUMENT((type & 0xff) == SLJIT_CALL || (type & 0xff) == SLJIT_CALL_CDECL);
|
||||
|
||||
types = arg_types;
|
||||
scratches = 0;
|
||||
fscratches = 0;
|
||||
for (i = 0; i < 5; i++) {
|
||||
curr_type = (types & SLJIT_DEF_MASK);
|
||||
CHECK_ARGUMENT(curr_type <= SLJIT_ARG_TYPE_F64);
|
||||
if (i > 0) {
|
||||
if (curr_type == 0) {
|
||||
break;
|
||||
}
|
||||
if (curr_type >= SLJIT_ARG_TYPE_F32)
|
||||
fscratches++;
|
||||
else
|
||||
scratches++;
|
||||
} else {
|
||||
if (curr_type >= SLJIT_ARG_TYPE_F32) {
|
||||
CHECK_ARGUMENT(compiler->fscratches > 0);
|
||||
} else if (curr_type >= SLJIT_ARG_TYPE_SW) {
|
||||
CHECK_ARGUMENT(compiler->scratches > 0);
|
||||
}
|
||||
}
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
CHECK_ARGUMENT(compiler->scratches >= scratches);
|
||||
CHECK_ARGUMENT(compiler->fscratches >= fscratches);
|
||||
CHECK_ARGUMENT(types == 0);
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
||||
fprintf(compiler->verbose, " %s%s ret[%s", jump_names[type & 0xff],
|
||||
!(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", call_arg_names[arg_types & SLJIT_DEF_MASK]);
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
if (arg_types) {
|
||||
fprintf(compiler->verbose, "], args[");
|
||||
do {
|
||||
fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
if (arg_types)
|
||||
fprintf(compiler->verbose, ",");
|
||||
} while (arg_types);
|
||||
}
|
||||
fprintf(compiler->verbose, "]\n");
|
||||
}
|
||||
#endif
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
@ -1488,20 +1648,16 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compile
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->last_flags = 0;
|
||||
#endif
|
||||
|
||||
if (SLJIT_UNLIKELY(compiler->skip_checks)) {
|
||||
compiler->skip_checks = 0;
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_CALL3);
|
||||
CHECK_ARGUMENT(type <= SLJIT_CALL0 || (type - SLJIT_CALL0) <= compiler->scratches);
|
||||
CHECK_ARGUMENT(type >= SLJIT_JUMP && type <= SLJIT_FAST_CALL);
|
||||
FUNCTION_CHECK_SRC(src, srcw);
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
@ -1514,6 +1670,66 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compil
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
sljit_s32 i, types, curr_type, scratches, fscratches;
|
||||
|
||||
CHECK_ARGUMENT(type == SLJIT_CALL || type == SLJIT_CALL_CDECL);
|
||||
FUNCTION_CHECK_SRC(src, srcw);
|
||||
|
||||
types = arg_types;
|
||||
scratches = 0;
|
||||
fscratches = 0;
|
||||
for (i = 0; i < 5; i++) {
|
||||
curr_type = (types & SLJIT_DEF_MASK);
|
||||
CHECK_ARGUMENT(curr_type <= SLJIT_ARG_TYPE_F64);
|
||||
if (i > 0) {
|
||||
if (curr_type == 0) {
|
||||
break;
|
||||
}
|
||||
if (curr_type >= SLJIT_ARG_TYPE_F32)
|
||||
fscratches++;
|
||||
else
|
||||
scratches++;
|
||||
} else {
|
||||
if (curr_type >= SLJIT_ARG_TYPE_F32) {
|
||||
CHECK_ARGUMENT(compiler->fscratches > 0);
|
||||
} else if (curr_type >= SLJIT_ARG_TYPE_SW) {
|
||||
CHECK_ARGUMENT(compiler->scratches > 0);
|
||||
}
|
||||
}
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
CHECK_ARGUMENT(compiler->scratches >= scratches);
|
||||
CHECK_ARGUMENT(compiler->fscratches >= fscratches);
|
||||
CHECK_ARGUMENT(types == 0);
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
||||
fprintf(compiler->verbose, " i%s%s ret[%s", jump_names[type & 0xff],
|
||||
!(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", call_arg_names[arg_types & SLJIT_DEF_MASK]);
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
if (arg_types) {
|
||||
fprintf(compiler->verbose, "], args[");
|
||||
do {
|
||||
fprintf(compiler->verbose, "%s", call_arg_names[arg_types & SLJIT_DEF_MASK]);
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
if (arg_types)
|
||||
fprintf(compiler->verbose, ",");
|
||||
} while (arg_types);
|
||||
}
|
||||
fprintf(compiler->verbose, "], ");
|
||||
sljit_verbose_param(compiler, src, srcw);
|
||||
fprintf(compiler->verbose, "\n");
|
||||
}
|
||||
#endif
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 type)
|
||||
@ -1558,9 +1774,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmov(struct sljit_compile
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_I32_OP)));
|
||||
CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_ORDERED_F64);
|
||||
|
||||
CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1);
|
||||
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_I32_OP));
|
||||
if (src != SLJIT_IMM) {
|
||||
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src));
|
||||
CHECK_ARGUMENT(srcw == 0);
|
||||
}
|
||||
|
||||
if ((type & 0xff) <= SLJIT_NOT_ZERO)
|
||||
@ -1573,7 +1792,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmov(struct sljit_compile
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
|
||||
fprintf(compiler->verbose, " cmov%s %s%s, ",
|
||||
!(dst_reg & SLJIT_I32_OP) ? "" : ".i",
|
||||
!(dst_reg & SLJIT_I32_OP) ? "" : "32",
|
||||
jump_names[type & 0xff], JUMP_POSTFIX(type));
|
||||
sljit_verbose_reg(compiler, dst_reg & ~SLJIT_I32_OP);
|
||||
fprintf(compiler->verbose, ", ");
|
||||
@ -1584,8 +1803,75 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmov(struct sljit_compile
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 reg,
|
||||
sljit_s32 mem, sljit_sw memw)
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
CHECK_ARGUMENT((type & 0xff) >= SLJIT_MOV && (type & 0xff) <= SLJIT_MOV_P);
|
||||
CHECK_ARGUMENT(!(type & SLJIT_I32_OP) || ((type & 0xff) != SLJIT_MOV && (type & 0xff) != SLJIT_MOV_U32 && (type & 0xff) != SLJIT_MOV_P));
|
||||
CHECK_ARGUMENT((type & SLJIT_MEM_PRE) || (type & SLJIT_MEM_POST));
|
||||
CHECK_ARGUMENT((type & (SLJIT_MEM_PRE | SLJIT_MEM_POST)) != (SLJIT_MEM_PRE | SLJIT_MEM_POST));
|
||||
CHECK_ARGUMENT((type & ~(0xff | SLJIT_I32_OP | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_PRE | SLJIT_MEM_POST)) == 0);
|
||||
|
||||
FUNCTION_CHECK_SRC_MEM(mem, memw);
|
||||
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(reg));
|
||||
|
||||
CHECK_ARGUMENT((mem & REG_MASK) != SLJIT_UNUSED && (mem & REG_MASK) != reg);
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (!(type & SLJIT_MEM_SUPP) && SLJIT_UNLIKELY(!!compiler->verbose)) {
|
||||
if (sljit_emit_mem(compiler, type | SLJIT_MEM_SUPP, reg, mem, memw) == SLJIT_ERR_UNSUPPORTED)
|
||||
fprintf(compiler->verbose, " //");
|
||||
|
||||
fprintf(compiler->verbose, " mem%s.%s%s%s ",
|
||||
!(type & SLJIT_I32_OP) ? "" : "32",
|
||||
(type & SLJIT_MEM_STORE) ? "st" : "ld",
|
||||
op1_names[(type & 0xff) - SLJIT_OP1_BASE],
|
||||
(type & SLJIT_MEM_PRE) ? ".pre" : ".post");
|
||||
sljit_verbose_reg(compiler, reg);
|
||||
fprintf(compiler->verbose, ", ");
|
||||
sljit_verbose_param(compiler, mem, memw);
|
||||
fprintf(compiler->verbose, "\n");
|
||||
}
|
||||
#endif
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 freg,
|
||||
sljit_s32 mem, sljit_sw memw)
|
||||
{
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
CHECK_ARGUMENT((type & 0xff) == SLJIT_MOV_F64);
|
||||
CHECK_ARGUMENT((type & SLJIT_MEM_PRE) || (type & SLJIT_MEM_POST));
|
||||
CHECK_ARGUMENT((type & (SLJIT_MEM_PRE | SLJIT_MEM_POST)) != (SLJIT_MEM_PRE | SLJIT_MEM_POST));
|
||||
CHECK_ARGUMENT((type & ~(0xff | SLJIT_I32_OP | SLJIT_MEM_STORE | SLJIT_MEM_SUPP | SLJIT_MEM_PRE | SLJIT_MEM_POST)) == 0);
|
||||
|
||||
FUNCTION_CHECK_SRC_MEM(mem, memw);
|
||||
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg));
|
||||
#endif
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
|
||||
if (!(type & SLJIT_MEM_SUPP) && SLJIT_UNLIKELY(!!compiler->verbose)) {
|
||||
if (sljit_emit_fmem(compiler, type | SLJIT_MEM_SUPP, freg, mem, memw) == SLJIT_ERR_UNSUPPORTED)
|
||||
fprintf(compiler->verbose, " //");
|
||||
|
||||
fprintf(compiler->verbose, " fmem.%s%s%s ",
|
||||
(type & SLJIT_MEM_STORE) ? "st" : "ld",
|
||||
!(type & SLJIT_I32_OP) ? ".f64" : ".f32",
|
||||
(type & SLJIT_MEM_PRE) ? ".pre" : ".post");
|
||||
sljit_verbose_freg(compiler, freg);
|
||||
fprintf(compiler->verbose, ", ");
|
||||
sljit_verbose_param(compiler, mem, memw);
|
||||
fprintf(compiler->verbose, "\n");
|
||||
}
|
||||
#endif
|
||||
CHECK_RETURN_OK;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
|
||||
{
|
||||
/* Any offset is allowed. */
|
||||
SLJIT_UNUSED_ARG(offset);
|
||||
|
||||
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
@ -1856,7 +2142,51 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile
|
||||
return sljit_emit_jump(compiler, type);
|
||||
}
|
||||
|
||||
#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
#if !(defined SLJIT_CONFIG_ARM_32 && SLJIT_CONFIG_ARM_32) \
|
||||
&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|
||||
&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 reg,
|
||||
sljit_s32 mem, sljit_sw memw)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(type);
|
||||
SLJIT_UNUSED_ARG(reg);
|
||||
SLJIT_UNUSED_ARG(mem);
|
||||
SLJIT_UNUSED_ARG(memw);
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
|
||||
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|
||||
&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 freg,
|
||||
sljit_s32 mem, sljit_sw memw)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(type);
|
||||
SLJIT_UNUSED_ARG(freg);
|
||||
SLJIT_UNUSED_ARG(mem);
|
||||
SLJIT_UNUSED_ARG(memw);
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_fmem(compiler, type, freg, mem, memw));
|
||||
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
|
||||
&& !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
|
||||
{
|
||||
@ -1941,12 +2271,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code)
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(options);
|
||||
SLJIT_UNUSED_ARG(args);
|
||||
SLJIT_UNUSED_ARG(arg_types);
|
||||
SLJIT_UNUSED_ARG(scratches);
|
||||
SLJIT_UNUSED_ARG(saveds);
|
||||
SLJIT_UNUSED_ARG(fscratches);
|
||||
@ -1957,12 +2287,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(options);
|
||||
SLJIT_UNUSED_ARG(args);
|
||||
SLJIT_UNUSED_ARG(arg_types);
|
||||
SLJIT_UNUSED_ARG(scratches);
|
||||
SLJIT_UNUSED_ARG(saveds);
|
||||
SLJIT_UNUSED_ARG(fscratches);
|
||||
@ -2107,6 +2437,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(type);
|
||||
SLJIT_UNUSED_ARG(arg_types);
|
||||
SLJIT_UNREACHABLE();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
@ -2159,6 +2499,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(type);
|
||||
SLJIT_UNUSED_ARG(arg_types);
|
||||
SLJIT_UNUSED_ARG(src);
|
||||
SLJIT_UNUSED_ARG(srcw);
|
||||
SLJIT_UNREACHABLE();
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 type)
|
||||
@ -2185,6 +2538,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 reg, sljit_s32 mem, sljit_sw memw)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(type);
|
||||
SLJIT_UNUSED_ARG(reg);
|
||||
SLJIT_UNUSED_ARG(mem);
|
||||
SLJIT_UNUSED_ARG(memw);
|
||||
SLJIT_UNREACHABLE();
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 freg, sljit_s32 mem, sljit_sw memw)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
SLJIT_UNUSED_ARG(type);
|
||||
SLJIT_UNUSED_ARG(freg);
|
||||
SLJIT_UNUSED_ARG(mem);
|
||||
SLJIT_UNUSED_ARG(memw);
|
||||
SLJIT_UNREACHABLE();
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(compiler);
|
||||
|
@ -153,8 +153,8 @@ of sljitConfigInternal.h */
|
||||
is not available at all.
|
||||
*/
|
||||
|
||||
/* When SLJIT_UNUSED is specified as the destination of sljit_emit_op1 and
|
||||
and sljit_emit_op2 operations the result is discarded. If no status
|
||||
/* When SLJIT_UNUSED is specified as the destination of sljit_emit_op1
|
||||
or sljit_emit_op2 operations the result is discarded. If no status
|
||||
flags are set, no instructions are emitted for these operations. Data
|
||||
prefetch is a special exception, see SLJIT_MOV operation. Other SLJIT
|
||||
operations do not support SLJIT_UNUSED as a destination operand. */
|
||||
@ -213,14 +213,6 @@ of sljitConfigInternal.h */
|
||||
|
||||
#define SLJIT_RETURN_REG SLJIT_R0
|
||||
|
||||
/* x86 prefers specific registers for special purposes. In case of shift
|
||||
by register it supports only SLJIT_R2 for shift argument
|
||||
(which is the src2 argument of sljit_emit_op2). If another register is
|
||||
used, sljit must exchange data between registers which cause a minor
|
||||
slowdown. Other architectures has no such limitation. */
|
||||
|
||||
#define SLJIT_PREF_SHIFT_REG SLJIT_R2
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Floating point registers */
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -257,6 +249,79 @@ of sljitConfigInternal.h */
|
||||
/* Float registers >= SLJIT_FIRST_SAVED_FLOAT_REG are saved registers. */
|
||||
#define SLJIT_FIRST_SAVED_FLOAT_REG (SLJIT_FS0 - SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS + 1)
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Argument type definitions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/* Argument type definitions.
|
||||
Used by SLJIT_[DEF_]ARGx and SLJIT_[DEF]_RET macros. */
|
||||
|
||||
#define SLJIT_ARG_TYPE_VOID 0
|
||||
#define SLJIT_ARG_TYPE_SW 1
|
||||
#define SLJIT_ARG_TYPE_UW 2
|
||||
#define SLJIT_ARG_TYPE_S32 3
|
||||
#define SLJIT_ARG_TYPE_U32 4
|
||||
#define SLJIT_ARG_TYPE_F32 5
|
||||
#define SLJIT_ARG_TYPE_F64 6
|
||||
|
||||
/* The following argument type definitions are used by sljit_emit_enter,
|
||||
sljit_set_context, sljit_emit_call, and sljit_emit_icall functions.
|
||||
The following return type definitions are used by sljit_emit_call
|
||||
and sljit_emit_icall functions.
|
||||
|
||||
When a function is called, the first integer argument must be placed
|
||||
in SLJIT_R0, the second in SLJIT_R1, and so on. Similarly the first
|
||||
floating point argument must be placed in SLJIT_FR0, the second in
|
||||
SLJIT_FR1, and so on.
|
||||
|
||||
Example function definition:
|
||||
sljit_f32 SLJIT_FUNC example_c_callback(sljit_sw arg_a,
|
||||
sljit_f64 arg_b, sljit_u32 arg_c, sljit_f32 arg_d);
|
||||
|
||||
Argument type definition:
|
||||
SLJIT_DEF_RET(SLJIT_ARG_TYPE_F32)
|
||||
| SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_SW) | SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_F64)
|
||||
| SLJIT_DEF_ARG3(SLJIT_ARG_TYPE_U32) | SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_F32)
|
||||
|
||||
Short form of argument type definition:
|
||||
SLJIT_RET(F32) | SLJIT_ARG1(SW) | SLJIT_ARG2(F64)
|
||||
| SLJIT_ARG3(S32) | SLJIT_ARG4(F32)
|
||||
|
||||
Argument passing:
|
||||
arg_a must be placed in SLJIT_R0
|
||||
arg_c must be placed in SLJIT_R1
|
||||
arg_b must be placed in SLJIT_FR0
|
||||
arg_d must be placed in SLJIT_FR1
|
||||
|
||||
Note:
|
||||
The SLJIT_ARG_TYPE_VOID type is only supported by
|
||||
SLJIT_DEF_RET, and SLJIT_ARG_TYPE_VOID is also the
|
||||
default value when SLJIT_DEF_RET is not specified. */
|
||||
#define SLJIT_DEF_SHIFT 4
|
||||
#define SLJIT_DEF_RET(type) (type)
|
||||
#define SLJIT_DEF_ARG1(type) ((type) << SLJIT_DEF_SHIFT)
|
||||
#define SLJIT_DEF_ARG2(type) ((type) << (2 * SLJIT_DEF_SHIFT))
|
||||
#define SLJIT_DEF_ARG3(type) ((type) << (3 * SLJIT_DEF_SHIFT))
|
||||
#define SLJIT_DEF_ARG4(type) ((type) << (4 * SLJIT_DEF_SHIFT))
|
||||
|
||||
/* Short form of the macros above.
|
||||
|
||||
For example the following definition:
|
||||
SLJIT_DEF_RET(SLJIT_ARG_TYPE_SW) | SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_F32)
|
||||
|
||||
can be shortened to:
|
||||
SLJIT_RET(SW) | SLJIT_ARG1(F32)
|
||||
|
||||
Note:
|
||||
The VOID type is only supported by SLJIT_RET, and
|
||||
VOID is also the default value when SLJIT_RET is
|
||||
not specified. */
|
||||
#define SLJIT_RET(type) SLJIT_DEF_RET(SLJIT_ARG_TYPE_ ## type)
|
||||
#define SLJIT_ARG1(type) SLJIT_DEF_ARG1(SLJIT_ARG_TYPE_ ## type)
|
||||
#define SLJIT_ARG2(type) SLJIT_DEF_ARG2(SLJIT_ARG_TYPE_ ## type)
|
||||
#define SLJIT_ARG3(type) SLJIT_DEF_ARG3(SLJIT_ARG_TYPE_ ## type)
|
||||
#define SLJIT_ARG4(type) SLJIT_DEF_ARG4(SLJIT_ARG_TYPE_ ## type)
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Main structures and functions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -331,6 +396,7 @@ struct sljit_compiler {
|
||||
sljit_s32 args;
|
||||
sljit_s32 locals_offset;
|
||||
sljit_s32 saveds_offset;
|
||||
sljit_s32 stack_tmp_size;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
@ -356,15 +422,8 @@ struct sljit_compiler {
|
||||
sljit_uw shift_imm;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
|
||||
sljit_s32 cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
|
||||
sljit_sw imm;
|
||||
sljit_s32 cache_arg;
|
||||
sljit_sw cache_argw;
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
|
||||
@ -499,14 +558,10 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler
|
||||
#define SLJIT_HAS_FPU 0
|
||||
/* [Limitation] Some registers are virtual registers. */
|
||||
#define SLJIT_HAS_VIRTUAL_REGISTERS 1
|
||||
/* [Emulated] Some forms of move with pre update is supported. */
|
||||
#define SLJIT_HAS_PRE_UPDATE 2
|
||||
/* [Emulated] Count leading zero is supported. */
|
||||
#define SLJIT_HAS_CLZ 3
|
||||
#define SLJIT_HAS_CLZ 2
|
||||
/* [Emulated] Conditional move is supported. */
|
||||
#define SLJIT_HAS_CMOV 4
|
||||
/* [Limitation] [Emulated] Shifting with register is limited to SLJIT_PREF_SHIFT_REG. */
|
||||
#define SLJIT_HAS_PREF_SHIFT_REG 5
|
||||
#define SLJIT_HAS_CMOV 3
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
|
||||
/* [Not emulated] SSE2 support is available on x86. */
|
||||
@ -519,27 +574,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
error, they return with SLJIT_SUCCESS. */
|
||||
|
||||
/*
|
||||
The executable code is a function call from the viewpoint of the C
|
||||
The executable code is a function from the viewpoint of the C
|
||||
language. The function calls must obey to the ABI (Application
|
||||
Binary Interface) of the platform, which specify the purpose of
|
||||
all machine registers and stack handling among other things. The
|
||||
machine registers and stack handling among other things. The
|
||||
sljit_emit_enter function emits the necessary instructions for
|
||||
setting up a new context for the executable code and moves function
|
||||
arguments to the saved registers. Furthermore the options argument
|
||||
can be used to pass configuration options to the compiler. The
|
||||
available options are listed before sljit_emit_enter.
|
||||
|
||||
The number of sljit_sw arguments passed to the generated function
|
||||
are specified in the "args" parameter. The number of arguments must
|
||||
be less than or equal to 3. The first argument goes to SLJIT_S0,
|
||||
the second goes to SLJIT_S1 and so on. The register set used by
|
||||
the function must be declared as well. The number of scratch and
|
||||
saved registers used by the function must be passed to sljit_emit_enter.
|
||||
Only R registers between R0 and "scratches" argument can be used
|
||||
later. E.g. if "scratches" is set to 2, the register set will be
|
||||
limited to R0 and R1. The S registers and the floating point
|
||||
The function argument list is the combination of SLJIT_ARGx
|
||||
(SLJIT_DEF_ARG1) macros. Currently maximum 3 SW / UW
|
||||
(SLJIT_ARG_TYPE_SW / LJIT_ARG_TYPE_UW) arguments are supported.
|
||||
The first argument goes to SLJIT_S0, the second goes to SLJIT_S1
|
||||
and so on. The register set used by the function must be declared
|
||||
as well. The number of scratch and saved registers used by the
|
||||
function must be passed to sljit_emit_enter. Only R registers
|
||||
between R0 and "scratches" argument can be used later. E.g. if
|
||||
"scratches" is set to 2, the scratch register set will be limited
|
||||
to SLJIT_R0 and SLJIT_R1. The S registers and the floating point
|
||||
registers ("fscratches" and "fsaveds") are specified in a similar
|
||||
way. The sljit_emit_enter is also capable of allocating a stack
|
||||
manner. The sljit_emit_enter is also capable of allocating a stack
|
||||
space for local variables. The "local_size" argument contains the
|
||||
size in bytes of this local area and its staring address is stored
|
||||
in SLJIT_SP. The memory area between SLJIT_SP (inclusive) and
|
||||
@ -566,7 +622,7 @@ offset 0 is aligned to sljit_f64. Otherwise it is aligned to sljit_sw. */
|
||||
#define SLJIT_MAX_LOCAL_SIZE 65536
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
|
||||
|
||||
/* The machine code has a context (which contains the local stack space size,
|
||||
@ -580,7 +636,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
the previous context. */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size);
|
||||
|
||||
/* Return from machine code. The op argument can be SLJIT_UNUSED which means the
|
||||
@ -592,26 +648,31 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/* Fast calling mechanism for utility functions (see SLJIT_FAST_CALL). All registers and
|
||||
even the stack frame is passed to the callee. The return address is preserved in
|
||||
dst/dstw by sljit_emit_fast_enter (the type of the value stored by this function
|
||||
is sljit_p), and sljit_emit_fast_return can use this as a return value later. */
|
||||
/* Generating entry and exit points for fast call functions (see SLJIT_FAST_CALL).
|
||||
Both sljit_emit_fast_enter and sljit_emit_fast_return functions preserve the
|
||||
values of all registers and stack frame. The return address is stored in the
|
||||
dst argument of sljit_emit_fast_enter, and this return address can be passed
|
||||
to sljit_emit_fast_return to continue the execution after the fast call.
|
||||
|
||||
/* Note: only for sljit specific, non ABI compilant calls. Fast, since only a few machine
|
||||
instructions are needed. Excellent for small uility functions, where saving registers
|
||||
and setting up a new stack frame would cost too much performance. However, it is still
|
||||
possible to return to the address of the caller (or anywhere else). */
|
||||
Fast calls are cheap operations (usually only a single call instruction is
|
||||
emitted) but they do not preserve any registers. However the callee function
|
||||
can freely use / update any registers and stack values which can be
|
||||
efficiently exploited by various optimizations. Registers can be saved
|
||||
manually by the callee function if needed.
|
||||
|
||||
/* Note: may destroy flags. */
|
||||
Although returning to different address by sljit_emit_fast_return is possible,
|
||||
this address usually cannot be predicted by the return address predictor of
|
||||
modern CPUs which may reduce performance. Furthermore using sljit_emit_ijump
|
||||
to return is also inefficient since return address prediction is usually
|
||||
triggered by a specific form of ijump.
|
||||
|
||||
/* Note: although sljit_emit_fast_return could be replaced by an ijump, it is not suggested,
|
||||
since many architectures do clever branch prediction on call / return instruction pairs. */
|
||||
Flags: - (does not modify flags). */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/*
|
||||
Source and destination values for arithmetical instructions
|
||||
Source and destination operands for arithmetical instructions
|
||||
imm - a simple immediate value (cannot be used as a destination)
|
||||
reg - any of the registers (immediate argument must be 0)
|
||||
[imm] - absolute immediate memory address
|
||||
@ -652,6 +713,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
arm-t2: [reg+imm], -255 <= imm <= 4095
|
||||
[reg+(reg<<imm)] is supported
|
||||
Write back is supported only for [reg+imm], where -255 <= imm <= 255
|
||||
arm64: [reg+imm], -256 <= imm <= 255, 0 <= aligned imm <= 4095 * alignment
|
||||
[reg+(reg<<imm)] is supported
|
||||
Write back is supported only for [reg+imm], where -256 <= imm <= 255
|
||||
ppc: [reg+imm], -65536 <= imm <= 65535. 64 bit loads/stores and 32 bit
|
||||
signed load on 64 bit requires immediates divisible by 4.
|
||||
[reg+imm] is not supported for signed 8 bit values.
|
||||
@ -663,8 +727,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
[reg+reg] is supported
|
||||
*/
|
||||
|
||||
/* Register output: simply the name of the register.
|
||||
For destination, you can use SLJIT_UNUSED as well. */
|
||||
/* Macros for specifying operand types. */
|
||||
#define SLJIT_MEM 0x80
|
||||
#define SLJIT_MEM0() (SLJIT_MEM)
|
||||
#define SLJIT_MEM1(r1) (SLJIT_MEM | (r1))
|
||||
@ -833,43 +896,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
S32 - signed int (32 bit) data transfer
|
||||
P - pointer (sljit_p) data transfer
|
||||
|
||||
U = move with update (pre form). If source or destination defined as
|
||||
SLJIT_MEM1(r1) or SLJIT_MEM2(r1, r2), r1 is increased by the
|
||||
offset part of the address.
|
||||
|
||||
Register arguments and base registers can only be used once for move
|
||||
with update instructions. The shift value of SLJIT_MEM2 addressing
|
||||
mode must also be 0. Reason: SLJIT_MOVU instructions are expected to
|
||||
be in high-performance loops where complex instruction emulation
|
||||
would be too costly.
|
||||
|
||||
Examples for invalid move with update instructions:
|
||||
|
||||
sljit_emit_op1(..., SLJIT_MOVU_U8,
|
||||
SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), 8);
|
||||
sljit_emit_op1(..., SLJIT_MOVU_U8,
|
||||
SLJIT_MEM2(SLJIT_R1, SLJIT_R0), 0, SLJIT_R0, 0);
|
||||
sljit_emit_op1(..., SLJIT_MOVU_U8,
|
||||
SLJIT_MEM2(SLJIT_R0, SLJIT_R1), 0, SLJIT_MEM1(SLJIT_R0), 8);
|
||||
sljit_emit_op1(..., SLJIT_MOVU_U8,
|
||||
SLJIT_MEM2(SLJIT_R0, SLJIT_R1), 0, SLJIT_MEM2(SLJIT_R1, SLJIT_R0), 0);
|
||||
sljit_emit_op1(..., SLJIT_MOVU_U8,
|
||||
SLJIT_R2, 0, SLJIT_MEM2(SLJIT_R0, SLJIT_R1), 1);
|
||||
|
||||
The following example is valid, since only the offset register is
|
||||
used multiple times:
|
||||
|
||||
sljit_emit_op1(..., SLJIT_MOVU_U8,
|
||||
SLJIT_MEM2(SLJIT_R0, SLJIT_R2), 0, SLJIT_MEM2(SLJIT_R1, SLJIT_R2), 0);
|
||||
|
||||
If the destination of a MOV without update instruction is SLJIT_UNUSED
|
||||
and the source operand is a memory address the compiler emits a prefetch
|
||||
instruction if this instruction is supported by the current CPU.
|
||||
Higher data sizes bring the data closer to the core: a MOV with word
|
||||
size loads the data into a higher level cache than a byte size. Otherwise
|
||||
the type does not affect the prefetch instruction. Furthermore a prefetch
|
||||
instruction never fails, so it can be used to prefetch a data from an
|
||||
address and check whether that address is NULL afterwards.
|
||||
If the destination of a MOV instruction is SLJIT_UNUSED and the source
|
||||
operand is a memory address the compiler emits a prefetch instruction
|
||||
if this instruction is supported by the current CPU. Higher data sizes
|
||||
bring the data closer to the core: a MOV with word size loads the data
|
||||
into a higher level cache than a byte size. Otherwise the type does not
|
||||
affect the prefetch instruction. Furthermore a prefetch instruction
|
||||
never fails, so it can be used to prefetch a data from an address and
|
||||
check whether that address is NULL afterwards.
|
||||
*/
|
||||
|
||||
/* Flags: - (does not modify flags) */
|
||||
@ -894,41 +928,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
#define SLJIT_MOV_S32 (SLJIT_OP1_BASE + 6)
|
||||
/* Flags: - (does not modify flags) */
|
||||
#define SLJIT_MOV32 (SLJIT_MOV_S32 | SLJIT_I32_OP)
|
||||
/* Flags: - (does not modify flags) */
|
||||
/* Flags: - (does not modify flags)
|
||||
Note: load a pointer sized data, useful on x32 (a 32 bit mode on x86-64
|
||||
where all x64 features are available, e.g. 16 register) or similar
|
||||
compiling modes */
|
||||
#define SLJIT_MOV_P (SLJIT_OP1_BASE + 7)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_MOVU (SLJIT_OP1_BASE + 8)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_MOVU_U8 (SLJIT_OP1_BASE + 9)
|
||||
#define SLJIT_MOVU32_U8 (SLJIT_MOVU_U8 | SLJIT_I32_OP)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_MOVU_S8 (SLJIT_OP1_BASE + 10)
|
||||
#define SLJIT_MOVU32_S8 (SLJIT_MOVU_S8 | SLJIT_I32_OP)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_MOVU_U16 (SLJIT_OP1_BASE + 11)
|
||||
#define SLJIT_MOVU32_U16 (SLJIT_MOVU_U16 | SLJIT_I32_OP)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_MOVU_S16 (SLJIT_OP1_BASE + 12)
|
||||
#define SLJIT_MOVU32_S16 (SLJIT_MOVU_S16 | SLJIT_I32_OP)
|
||||
/* Flags: - (may destroy flags)
|
||||
Note: no SLJIT_MOVU32_U32 form, since it is the same as SLJIT_MOVU32 */
|
||||
#define SLJIT_MOVU_U32 (SLJIT_OP1_BASE + 13)
|
||||
/* Flags: - (may destroy flags)
|
||||
Note: no SLJIT_MOVU32_S32 form, since it is the same as SLJIT_MOVU32 */
|
||||
#define SLJIT_MOVU_S32 (SLJIT_OP1_BASE + 14)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_MOVU32 (SLJIT_MOVU_S32 | SLJIT_I32_OP)
|
||||
/* Flags: - (may destroy flags) */
|
||||
#define SLJIT_MOVU_P (SLJIT_OP1_BASE + 15)
|
||||
/* Flags: Z */
|
||||
#define SLJIT_NOT (SLJIT_OP1_BASE + 16)
|
||||
/* Flags: Z
|
||||
Note: immediate source argument is not supported */
|
||||
#define SLJIT_NOT (SLJIT_OP1_BASE + 8)
|
||||
#define SLJIT_NOT32 (SLJIT_NOT | SLJIT_I32_OP)
|
||||
/* Flags: Z | OVERFLOW */
|
||||
#define SLJIT_NEG (SLJIT_OP1_BASE + 17)
|
||||
/* Flags: Z | OVERFLOW
|
||||
Note: immediate source argument is not supported */
|
||||
#define SLJIT_NEG (SLJIT_OP1_BASE + 9)
|
||||
#define SLJIT_NEG32 (SLJIT_NEG | SLJIT_I32_OP)
|
||||
/* Count leading zeroes
|
||||
Flags: - (may destroy flags) */
|
||||
#define SLJIT_CLZ (SLJIT_OP1_BASE + 18)
|
||||
Flags: - (may destroy flags)
|
||||
Note: immediate source argument is not supported */
|
||||
#define SLJIT_CLZ (SLJIT_OP1_BASE + 10)
|
||||
#define SLJIT_CLZ32 (SLJIT_CLZ | SLJIT_I32_OP)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
@ -1136,25 +1152,32 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
|
||||
|
||||
/* Unconditional jump types. */
|
||||
#define SLJIT_JUMP 24
|
||||
/* Fast calling method. See sljit_emit_fast_enter / sljit_emit_fast_return. */
|
||||
#define SLJIT_FAST_CALL 25
|
||||
#define SLJIT_CALL0 26
|
||||
#define SLJIT_CALL1 27
|
||||
#define SLJIT_CALL2 28
|
||||
#define SLJIT_CALL3 29
|
||||
|
||||
/* Fast calling method. See sljit_emit_fast_enter / sljit_emit_fast_return. */
|
||||
/* Called function must be declared with the SLJIT_FUNC attribute. */
|
||||
#define SLJIT_CALL 26
|
||||
/* Called function must be decalred with cdecl attribute.
|
||||
This is the default attribute for C functions. */
|
||||
#define SLJIT_CALL_CDECL 27
|
||||
|
||||
/* The target can be changed during runtime (see: sljit_set_jump_addr). */
|
||||
#define SLJIT_REWRITABLE_JUMP 0x1000
|
||||
|
||||
/* Emit a jump instruction. The destination is not set, only the type of the jump.
|
||||
type must be between SLJIT_EQUAL and SLJIT_CALL3
|
||||
type must be between SLJIT_EQUAL and SLJIT_FAST_CALL
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
|
||||
Flags: does not modify flags for conditional and unconditional
|
||||
jumps but destroy all flags for calls. */
|
||||
Flags: does not modify flags. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type);
|
||||
|
||||
/* Emit a C compiler (ABI) compatible function call.
|
||||
type must be SLJIT_CALL or SLJIT_CALL_CDECL
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
arg_types is the combination of SLJIT_RET / SLJIT_ARGx (SLJIT_DEF_RET / SLJIT_DEF_ARGx) macros
|
||||
|
||||
Flags: destroy all flags. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types);
|
||||
|
||||
/* Basic arithmetic comparison. In most architectures it is implemented as
|
||||
an SLJIT_SUB operation (with SLJIT_UNUSED destination and setting
|
||||
appropriate flags) followed by a sljit_emit_jump. However some
|
||||
@ -1162,6 +1185,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
It is suggested to use this comparison form when appropriate.
|
||||
type must be between SLJIT_EQUAL and SLJIT_I_SIG_LESS_EQUAL
|
||||
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
|
||||
|
||||
Flags: may destroy flags. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
@ -1186,15 +1210,23 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sl
|
||||
/* Set the destination address of the jump to this label. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target);
|
||||
|
||||
/* Call function or jump anywhere. Both direct and indirect form
|
||||
type must be between SLJIT_JUMP and SLJIT_CALL3
|
||||
Direct form: set src to SLJIT_IMM() and srcw to the address
|
||||
Indirect form: any other valid addressing mode
|
||||
/* Emit an indirect jump or fast call. Both direct and indirect form
|
||||
Direct form: set src to SLJIT_IMM() and srcw to the address
|
||||
Indirect form: any other valid addressing mode
|
||||
type must be between SLJIT_JUMP and SLJIT_FAST_CALL
|
||||
|
||||
Flags: does not modify flags for unconditional jumps but
|
||||
destroy all flags for calls. */
|
||||
Flags: does not modify flags. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/* Emit a C compiler (ABI) compatible function call.
|
||||
Direct form: set src to SLJIT_IMM() and srcw to the address
|
||||
Indirect form: any other valid addressing mode
|
||||
type must be SLJIT_CALL or SLJIT_CALL_CDECL
|
||||
arg_types is the combination of SLJIT_RET / SLJIT_ARGx (SLJIT_DEF_RET / SLJIT_DEF_ARGx) macros
|
||||
|
||||
Flags: destroy all flags. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types, sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/* Perform the operation using the conditional flags as the second argument.
|
||||
Type must always be between SLJIT_EQUAL and SLJIT_ORDERED_F64. The value
|
||||
represented by the type is 1, if the condition represented by the type
|
||||
@ -1213,7 +1245,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
||||
|
||||
/* Emit a conditional mov instruction which moves source to destination,
|
||||
if the condition is satisfied. Unlike other arithmetic operations this
|
||||
instruction does not support memory accesses.
|
||||
instruction does not support memory access.
|
||||
|
||||
type must be between SLJIT_EQUAL and SLJIT_ORDERED_F64
|
||||
dst_reg must be a valid register and it can be combined
|
||||
@ -1225,7 +1257,60 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
||||
sljit_s32 dst_reg,
|
||||
sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
/* Copies the base address of SLJIT_SP + offset to dst.
|
||||
/* The following flags are used by sljit_emit_mem() and sljit_emit_fmem(). */
|
||||
|
||||
/* When SLJIT_MEM_SUPP is passed, no instructions are emitted.
|
||||
Instead the function returns with SLJIT_SUCCESS if the instruction
|
||||
form is supported and SLJIT_ERR_UNSUPPORTED otherwise. This flag
|
||||
allows runtime checking of available instruction forms. */
|
||||
#define SLJIT_MEM_SUPP 0x0200
|
||||
/* Memory load operation. This is the default. */
|
||||
#define SLJIT_MEM_LOAD 0x0000
|
||||
/* Memory store operation. */
|
||||
#define SLJIT_MEM_STORE 0x0400
|
||||
/* Base register is updated before the memory access. */
|
||||
#define SLJIT_MEM_PRE 0x0800
|
||||
/* Base register is updated after the memory access. */
|
||||
#define SLJIT_MEM_POST 0x1000
|
||||
|
||||
/* Emit a single memory load or store with update instruction. When the
|
||||
requested instruction from is not supported by the CPU, it returns
|
||||
with SLJIT_ERR_UNSUPPORTED instead of emulating the instruction. This
|
||||
allows specializing tight loops based on the supported instruction
|
||||
forms (see SLJIT_MEM_SUPP flag).
|
||||
|
||||
type must be between SLJIT_MOV and SLJIT_MOV_P and can be
|
||||
combined with SLJIT_MEM_* flags. Either SLJIT_MEM_PRE
|
||||
or SLJIT_MEM_POST must be specified.
|
||||
reg is the source or destination register, and must be
|
||||
different from the base register of the mem operand
|
||||
mem must be a SLJIT_MEM1() or SLJIT_MEM2() operand
|
||||
|
||||
Flags: - (does not modify flags) */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 reg,
|
||||
sljit_s32 mem, sljit_sw memw);
|
||||
|
||||
/* Same as sljit_emit_mem except the followings:
|
||||
|
||||
type must be SLJIT_MOV_F64 or SLJIT_MOV_F32 and can be
|
||||
combined with SLJIT_MEM_* flags. Either SLJIT_MEM_PRE
|
||||
or SLJIT_MEM_POST must be specified.
|
||||
freg is the source or destination floating point register */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 freg,
|
||||
sljit_s32 mem, sljit_sw memw);
|
||||
|
||||
/* Copies the base address of SLJIT_SP + offset to dst. The offset can be
|
||||
anything to negate the effect of relative addressing. For example if an
|
||||
array of sljit_sw values is stored on the stack from offset 0x40, and R0
|
||||
contains the offset of an array item plus 0x120, this item can be
|
||||
overwritten by two SLJIT instructions:
|
||||
|
||||
sljit_get_local_base(compiler, SLJIT_R1, 0, 0x40 - 0x120);
|
||||
sljit_emit_op1(compiler, SLJIT_MOV, SLJIT_MEM2(SLJIT_R1, SLJIT_R0), 0, SLJIT_IMM, 0x5);
|
||||
|
||||
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);
|
||||
|
||||
@ -1262,58 +1347,58 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void);
|
||||
|
||||
#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
|
||||
/* This global lock is useful to compile common functions. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void);
|
||||
#endif
|
||||
|
||||
#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK)
|
||||
|
||||
/* The sljit_stack is a utility extension of sljit, which provides
|
||||
a top-down stack. The stack starts at base and goes down to
|
||||
max_limit, so the memory region for this stack is between
|
||||
max_limit (inclusive) and base (exclusive). However the
|
||||
application can only use the region between limit (inclusive)
|
||||
and base (exclusive). The sljit_stack_resize can be used to
|
||||
extend this region up to max_limit.
|
||||
/* The sljit_stack structure and its manipulation functions provides
|
||||
an implementation for a top-down stack. The stack top is stored
|
||||
in the end field of the sljit_stack structure and the stack goes
|
||||
down to the min_start field, so the memory region reserved for
|
||||
this stack is between min_start (inclusive) and end (exclusive)
|
||||
fields. However the application can only use the region between
|
||||
start (inclusive) and end (exclusive) fields. The sljit_stack_resize
|
||||
function can be used to extend this region up to min_start.
|
||||
|
||||
This feature uses the "address space reserve" feature of modern
|
||||
operating systems, so instead of allocating a huge memory block
|
||||
applications can allocate a small region and extend it later
|
||||
without moving the memory area. Hence pointers can be stored
|
||||
in this area. */
|
||||
operating systems. Instead of allocating a large memory block
|
||||
applications can allocate a small memory region and extend it
|
||||
later without moving the content of the memory area. Therefore
|
||||
after a successful resize by sljit_stack_resize all pointers into
|
||||
this region are still valid.
|
||||
|
||||
/* Note: base and max_limit fields are aligned to PAGE_SIZE bytes
|
||||
(usually 4 Kbyte or more).
|
||||
Note: stack should grow in larger steps, e.g. 4Kbyte, 16Kbyte or more.
|
||||
Note: this structure may not be supported by all operating systems.
|
||||
Some kind of fallback mechanism is suggested when SLJIT_UTIL_STACK
|
||||
is not defined. */
|
||||
Note:
|
||||
this structure may not be supported by all operating systems.
|
||||
end and max_limit fields are aligned to PAGE_SIZE bytes (usually
|
||||
4 Kbyte or more).
|
||||
stack should grow in larger steps, e.g. 4Kbyte, 16Kbyte or more. */
|
||||
|
||||
struct sljit_stack {
|
||||
/* User data, anything can be stored here.
|
||||
Starting with the same value as base. */
|
||||
Initialized to the same value as the end field. */
|
||||
sljit_u8 *top;
|
||||
/* These members are read only. */
|
||||
sljit_u8 *base;
|
||||
sljit_u8 *limit;
|
||||
sljit_u8 *max_limit;
|
||||
/* These members are read only. */
|
||||
/* End address of the stack */
|
||||
sljit_u8 *end;
|
||||
/* Current start address of the stack. */
|
||||
sljit_u8 *start;
|
||||
/* Lowest start address of the stack. */
|
||||
sljit_u8 *min_start;
|
||||
};
|
||||
|
||||
/* Returns NULL if unsuccessful.
|
||||
Note: max_limit contains the maximum stack size in bytes.
|
||||
Note: limit contains the starting stack size in bytes.
|
||||
Note: the top field is initialized to base.
|
||||
/* Allocates a new stack. Returns NULL if unsuccessful.
|
||||
Note: see sljit_create_compiler for the explanation of allocator_data. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack *stack, void *allocator_data);
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data);
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data);
|
||||
|
||||
/* Can be used to increase (allocate) or decrease (free) the memory area.
|
||||
Returns with a non-zero value if unsuccessful. If new_limit is greater than
|
||||
max_limit, it will fail. It is very easy to implement a stack data structure,
|
||||
since the growth ratio can be added to the current limit, and sljit_stack_resize
|
||||
will do all the necessary checks. The fields of the stack are not changed if
|
||||
sljit_stack_resize fails. */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_limit);
|
||||
/* Can be used to increase (extend) or decrease (shrink) the stack
|
||||
memory area. Returns with new_start if successful and NULL otherwise.
|
||||
It always fails if new_start is less than min_start or greater or equal
|
||||
than end fields. The fields of the stack are not changed if the returned
|
||||
value is NULL (the current memory content is never lost). */
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start);
|
||||
|
||||
#endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,11 @@
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
{
|
||||
return "ARM-Thumb2" SLJIT_CPUINFO;
|
||||
#ifdef __SOFTFP__
|
||||
return "ARM-Thumb2" SLJIT_CPUINFO " ABI:softfp";
|
||||
#else
|
||||
return "ARM-Thumb2" SLJIT_CPUINFO " ABI:hardfp";
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Length of an instruction word. */
|
||||
@ -37,12 +41,16 @@ typedef sljit_u32 sljit_ins;
|
||||
#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
|
||||
#define TMP_PC (SLJIT_NUMBER_OF_REGISTERS + 4)
|
||||
|
||||
#define TMP_FREG1 (0)
|
||||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
|
||||
#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
|
||||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
|
||||
|
||||
/* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */
|
||||
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
0, 0, 1, 2, 12, 11, 10, 9, 8, 7, 6, 5, 4, 13, 3, 14, 15
|
||||
0, 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4, 13, 12, 14, 15
|
||||
};
|
||||
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
0, 0, 1, 2, 3, 4, 5, 6, 7
|
||||
};
|
||||
|
||||
#define COPY_BITS(src, from, to, bits) \
|
||||
@ -69,9 +77,9 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
#define RN4(rn) (reg_map[rn] << 16)
|
||||
#define RM4(rm) (reg_map[rm])
|
||||
#define RT4(rt) (reg_map[rt] << 12)
|
||||
#define DD4(dd) ((dd) << 12)
|
||||
#define DN4(dn) ((dn) << 16)
|
||||
#define DM4(dm) (dm)
|
||||
#define DD4(dd) (freg_map[dd] << 12)
|
||||
#define DN4(dn) (freg_map[dn] << 16)
|
||||
#define DM4(dm) (freg_map[dm])
|
||||
#define IMM5(imm) \
|
||||
(COPY_BITS(imm, 2, 12, 3) | ((imm & 0x3) << 6))
|
||||
#define IMM12(imm) \
|
||||
@ -102,6 +110,7 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
#define ASRSI 0x1000
|
||||
#define ASR_W 0xfa40f000
|
||||
#define ASR_WI 0xea4f0020
|
||||
#define BCC 0xd000
|
||||
#define BICI 0xf0200000
|
||||
#define BKPT 0xbe00
|
||||
#define BLX 0x4780
|
||||
@ -117,6 +126,7 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
#define EORS 0x4040
|
||||
#define EOR_W 0xea800000
|
||||
#define IT 0xbf00
|
||||
#define LDRI 0xf8500800
|
||||
#define LSLS 0x4080
|
||||
#define LSLSI 0x0000
|
||||
#define LSL_W 0xfa00f000
|
||||
@ -150,6 +160,7 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
#define SBCI 0xf1600000
|
||||
#define SBCS 0x4180
|
||||
#define SBC_W 0xeb600000
|
||||
#define SDIV 0xfb90f0f0
|
||||
#define SMULL 0xfb800000
|
||||
#define STR_SP 0x9000
|
||||
#define SUBS 0x1a00
|
||||
@ -164,6 +175,7 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
#define SXTH 0xb200
|
||||
#define SXTH_W 0xfa0ff080
|
||||
#define TST 0x4200
|
||||
#define UDIV 0xfbb0f0f0
|
||||
#define UMULL 0xfba00000
|
||||
#define UXTB 0xb2c0
|
||||
#define UXTB_W 0xfa5ff080
|
||||
@ -178,6 +190,7 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
#define VDIV_F32 0xee800a00
|
||||
#define VMOV_F32 0xeeb00a40
|
||||
#define VMOV 0xee000a10
|
||||
#define VMOV2 0xec400a10
|
||||
#define VMRS 0xeef1fa10
|
||||
#define VMUL_F32 0xee200a00
|
||||
#define VNEG_F32 0xeeb10a40
|
||||
@ -208,10 +221,10 @@ static sljit_s32 push_inst32(struct sljit_compiler *compiler, sljit_ins inst)
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_imm32_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_uw imm)
|
||||
{
|
||||
FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) |
|
||||
COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
|
||||
return push_inst32(compiler, MOVT | RD4(dst) |
|
||||
COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
|
||||
FAIL_IF(push_inst32(compiler, MOVW | RD4(dst)
|
||||
| COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
|
||||
return push_inst32(compiler, MOVT | RD4(dst)
|
||||
| COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
|
||||
}
|
||||
|
||||
static SLJIT_INLINE void modify_imm32_const(sljit_u16 *inst, sljit_uw new_imm)
|
||||
@ -330,8 +343,8 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump, sljit_sw
|
||||
|
||||
/* Really complex instruction form for branches. */
|
||||
s = (diff >> 23) & 0x1;
|
||||
j1 = (~(diff >> 21) ^ s) & 0x1;
|
||||
j2 = (~(diff >> 22) ^ s) & 0x1;
|
||||
j1 = (~(diff >> 22) ^ s) & 0x1;
|
||||
j2 = (~(diff >> 21) ^ s) & 0x1;
|
||||
jump_inst[0] = 0xf000 | (s << 10) | COPY_BITS(diff, 11, 0, 10);
|
||||
jump_inst[1] = (j1 << 13) | (j2 << 11) | (diff & 0x7ff);
|
||||
|
||||
@ -444,7 +457,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
case SLJIT_HAS_PRE_UPDATE:
|
||||
case SLJIT_HAS_CLZ:
|
||||
case SLJIT_HAS_CMOV:
|
||||
return 1;
|
||||
@ -512,6 +524,8 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst,
|
||||
{
|
||||
sljit_uw tmp;
|
||||
|
||||
/* MOVS cannot be used since it destroy flags. */
|
||||
|
||||
if (imm >= 0x10000) {
|
||||
tmp = get_imm(imm);
|
||||
if (tmp != INVALID_IMM)
|
||||
@ -522,13 +536,13 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst,
|
||||
}
|
||||
|
||||
/* set low 16 bits, set hi 16 bits to 0. */
|
||||
FAIL_IF(push_inst32(compiler, MOVW | RD4(dst) |
|
||||
COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
|
||||
FAIL_IF(push_inst32(compiler, MOVW | RD4(dst)
|
||||
| COPY_BITS(imm, 12, 16, 4) | COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)));
|
||||
|
||||
/* set hi 16 bit if needed. */
|
||||
if (imm >= 0x10000)
|
||||
return push_inst32(compiler, MOVT | RD4(dst) |
|
||||
COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
|
||||
return push_inst32(compiler, MOVT | RD4(dst)
|
||||
| COPY_BITS(imm, 12 + 16, 16, 4) | COPY_BITS(imm, 11 + 16, 26, 1) | COPY_BITS(imm, 8 + 16, 12, 3) | ((imm & 0xff0000) >> 16));
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -729,34 +743,26 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOV_P:
|
||||
case SLJIT_MOVU:
|
||||
case SLJIT_MOVU_U32:
|
||||
case SLJIT_MOVU_S32:
|
||||
case SLJIT_MOVU_P:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
|
||||
if (dst == arg2)
|
||||
return SLJIT_SUCCESS;
|
||||
return push_inst16(compiler, MOV | SET_REGS44(dst, arg2));
|
||||
case SLJIT_MOV_U8:
|
||||
case SLJIT_MOVU_U8:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
|
||||
if (IS_2_LO_REGS(dst, arg2))
|
||||
return push_inst16(compiler, UXTB | RD3(dst) | RN3(arg2));
|
||||
return push_inst32(compiler, UXTB_W | RD4(dst) | RM4(arg2));
|
||||
case SLJIT_MOV_S8:
|
||||
case SLJIT_MOVU_S8:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
|
||||
if (IS_2_LO_REGS(dst, arg2))
|
||||
return push_inst16(compiler, SXTB | RD3(dst) | RN3(arg2));
|
||||
return push_inst32(compiler, SXTB_W | RD4(dst) | RM4(arg2));
|
||||
case SLJIT_MOV_U16:
|
||||
case SLJIT_MOVU_U16:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
|
||||
if (IS_2_LO_REGS(dst, arg2))
|
||||
return push_inst16(compiler, UXTH | RD3(dst) | RN3(arg2));
|
||||
return push_inst32(compiler, UXTH_W | RD4(dst) | RM4(arg2));
|
||||
case SLJIT_MOV_S16:
|
||||
case SLJIT_MOVU_S16:
|
||||
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG2);
|
||||
if (IS_2_LO_REGS(dst, arg2))
|
||||
return push_inst16(compiler, SXTH | RD3(dst) | RN3(arg2));
|
||||
@ -840,8 +846,6 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
|
||||
#define HALF_SIZE 0x08
|
||||
#define PRELOAD 0x0c
|
||||
|
||||
#define UPDATE 0x10
|
||||
|
||||
#define IS_WORD_SIZE(flags) (!(flags & (BYTE_SIZE | HALF_SIZE)))
|
||||
#define OFFSET_CHECK(imm, shift) (!(argw & ~(imm << shift)))
|
||||
|
||||
@ -940,12 +944,10 @@ static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit
|
||||
sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg)
|
||||
{
|
||||
sljit_s32 other_r;
|
||||
sljit_s32 update = flags & UPDATE;
|
||||
sljit_uw tmp;
|
||||
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
SLJIT_ASSERT((arg & REG_MASK) != tmp_reg);
|
||||
flags &= ~UPDATE;
|
||||
arg &= ~SLJIT_MEM;
|
||||
|
||||
if (SLJIT_UNLIKELY(!(arg & REG_MASK))) {
|
||||
@ -961,63 +963,6 @@ static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit
|
||||
return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(tmp_reg));
|
||||
}
|
||||
|
||||
if (SLJIT_UNLIKELY(update)) {
|
||||
SLJIT_ASSERT(reg != arg);
|
||||
|
||||
if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
|
||||
other_r = OFFS_REG(arg);
|
||||
arg &= 0xf;
|
||||
|
||||
if (IS_3_LO_REGS(reg, arg, other_r))
|
||||
FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(other_r)));
|
||||
else
|
||||
FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(other_r)));
|
||||
return push_inst16(compiler, ADD | SET_REGS44(arg, other_r));
|
||||
}
|
||||
|
||||
if (argw > 0xff) {
|
||||
tmp = get_imm(argw & ~0xff);
|
||||
if (tmp != INVALID_IMM) {
|
||||
push_inst32(compiler, ADD_WI | RD4(arg) | RN4(arg) | tmp);
|
||||
argw = argw & 0xff;
|
||||
}
|
||||
}
|
||||
else if (argw < -0xff) {
|
||||
tmp = get_imm(-argw & ~0xff);
|
||||
if (tmp != INVALID_IMM) {
|
||||
push_inst32(compiler, SUB_WI | RD4(arg) | RN4(arg) | tmp);
|
||||
argw = -(-argw & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
if (argw == 0) {
|
||||
if (IS_2_LO_REGS(reg, arg) && sljit_mem16_imm5[flags])
|
||||
return push_inst16(compiler, sljit_mem16_imm5[flags] | RD3(reg) | RN3(arg));
|
||||
return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(arg));
|
||||
}
|
||||
|
||||
if (argw <= 0xff && argw >= -0xff) {
|
||||
if (argw >= 0)
|
||||
argw |= 0x200;
|
||||
else {
|
||||
argw = -argw;
|
||||
}
|
||||
|
||||
SLJIT_ASSERT(argw >= 0 && (argw & 0xff) <= 0xff);
|
||||
return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM8 | RT4(reg) | RN4(arg) | 0x100 | argw);
|
||||
}
|
||||
|
||||
FAIL_IF(load_immediate(compiler, tmp_reg, argw));
|
||||
|
||||
SLJIT_ASSERT(reg != tmp_reg);
|
||||
|
||||
if (IS_3_LO_REGS(reg, arg, tmp_reg))
|
||||
FAIL_IF(push_inst16(compiler, sljit_mem16[flags] | RD3(reg) | RN3(arg) | RM3(tmp_reg)));
|
||||
else
|
||||
FAIL_IF(push_inst32(compiler, sljit_mem32[flags] | RT4(reg) | RN4(arg) | RM4(tmp_reg)));
|
||||
return push_inst16(compiler, ADD | SET_REGS44(arg, tmp_reg));
|
||||
}
|
||||
|
||||
if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
|
||||
argw &= 0x3;
|
||||
other_r = OFFS_REG(arg);
|
||||
@ -1088,15 +1033,18 @@ static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_s32 size, i, tmp;
|
||||
sljit_s32 args, size, i, tmp;
|
||||
sljit_ins push = 0;
|
||||
#ifdef _WIN32
|
||||
sljit_uw imm;
|
||||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
for (i = SLJIT_S0; i >= tmp; i--)
|
||||
@ -1113,12 +1061,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
||||
local_size = ((size + local_size + 7) & ~7) - size;
|
||||
compiler->local_size = local_size;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (local_size >= 256) {
|
||||
if (local_size > 4096)
|
||||
imm = get_imm(4096);
|
||||
else
|
||||
imm = get_imm(local_size & ~0xff);
|
||||
|
||||
SLJIT_ASSERT(imm != INVALID_IMM);
|
||||
FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(SLJIT_SP) | imm));
|
||||
}
|
||||
#else
|
||||
if (local_size > 0) {
|
||||
if (local_size <= (127 << 2))
|
||||
FAIL_IF(push_inst16(compiler, SUB_SP | (local_size >> 2)));
|
||||
else
|
||||
FAIL_IF(emit_op_imm(compiler, SLJIT_SUB | ARG2_IMM, SLJIT_SP, SLJIT_SP, local_size));
|
||||
}
|
||||
#endif
|
||||
|
||||
args = get_arg_count(arg_types);
|
||||
|
||||
if (args >= 1)
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S0, SLJIT_R0)));
|
||||
@ -1127,18 +1090,73 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
if (args >= 3)
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_S2, SLJIT_R2)));
|
||||
|
||||
#ifdef _WIN32
|
||||
if (local_size >= 256) {
|
||||
if (local_size > 4096) {
|
||||
imm = get_imm(4096);
|
||||
SLJIT_ASSERT(imm != INVALID_IMM);
|
||||
|
||||
if (local_size < 4 * 4096) {
|
||||
if (local_size > 2 * 4096) {
|
||||
FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1)));
|
||||
FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm));
|
||||
local_size -= 4096;
|
||||
}
|
||||
|
||||
if (local_size > 2 * 4096) {
|
||||
FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1)));
|
||||
FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm));
|
||||
local_size -= 4096;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1)));
|
||||
local_size -= 4096;
|
||||
|
||||
SLJIT_ASSERT(local_size > 0);
|
||||
}
|
||||
else {
|
||||
FAIL_IF(load_immediate(compiler, SLJIT_R3, (local_size >> 12) - 1));
|
||||
FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1)));
|
||||
FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm));
|
||||
SLJIT_ASSERT(reg_map[SLJIT_R3] < 7);
|
||||
FAIL_IF(push_inst16(compiler, SUBSI8 | RDN3(SLJIT_R3) | 1));
|
||||
FAIL_IF(push_inst16(compiler, BCC | (0x1 << 8) /* not-equal */ | (-7 & 0xff)));
|
||||
|
||||
local_size &= 0xfff;
|
||||
|
||||
if (local_size != 0)
|
||||
FAIL_IF(push_inst32(compiler, LDRI | 0x400 | RT4(TMP_REG2) | RN4(TMP_REG1)));
|
||||
}
|
||||
|
||||
if (local_size >= 256) {
|
||||
imm = get_imm(local_size & ~0xff);
|
||||
SLJIT_ASSERT(imm != INVALID_IMM);
|
||||
|
||||
FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(TMP_REG1) | imm));
|
||||
}
|
||||
}
|
||||
|
||||
local_size &= 0xff;
|
||||
FAIL_IF(push_inst32(compiler, LDRI | 0x400 | (local_size > 0 ? 0x100 : 0) | RT4(TMP_REG2) | RN4(TMP_REG1) | local_size));
|
||||
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SP, TMP_REG1)));
|
||||
}
|
||||
else if (local_size > 0)
|
||||
FAIL_IF(push_inst32(compiler, LDRI | 0x500 | RT4(TMP_REG1) | RN4(SLJIT_SP) | local_size));
|
||||
#endif
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_s32 size;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
size = GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1);
|
||||
compiler->local_size = ((size + local_size + 7) & ~7) - size;
|
||||
@ -1178,11 +1196,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp
|
||||
/* Operators */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#ifdef _WIN32
|
||||
extern unsigned long long __rt_udiv(unsigned int denominator, unsigned int numerator);
|
||||
extern long long __rt_sdiv(int denominator, int numerator);
|
||||
#elif defined(__GNUC__)
|
||||
extern unsigned int __aeabi_uidivmod(unsigned int numerator, int unsigned denominator);
|
||||
extern int __aeabi_idivmod(int numerator, int denominator);
|
||||
#else
|
||||
@ -1193,10 +1216,14 @@ extern int __aeabi_idivmod(int numerator, int denominator);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !__ARM_FEATURE_IDIV && !__ARM_ARCH_EXT_IDIV__ */
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op)
|
||||
{
|
||||
#if !(defined __ARM_FEATURE_IDIV) && !(defined __ARM_ARCH_EXT_IDIV__)
|
||||
sljit_sw saved_reg_list[3];
|
||||
sljit_sw saved_reg_count;
|
||||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_op0(compiler, op));
|
||||
@ -1214,16 +1241,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
| (reg_map[SLJIT_R0] << 12)
|
||||
| (reg_map[SLJIT_R0] << 16)
|
||||
| reg_map[SLJIT_R1]);
|
||||
#if (defined __ARM_FEATURE_IDIV) || (defined __ARM_ARCH_EXT_IDIV__)
|
||||
case SLJIT_DIVMOD_UW:
|
||||
case SLJIT_DIVMOD_SW:
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, SLJIT_R0)));
|
||||
FAIL_IF(push_inst32(compiler, (op == SLJIT_DIVMOD_UW ? UDIV : SDIV) | RD4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1)));
|
||||
FAIL_IF(push_inst32(compiler, MUL | RD4(SLJIT_R1) | RN4(SLJIT_R0) | RM4(SLJIT_R1)));
|
||||
return push_inst32(compiler, SUB_W | RD4(SLJIT_R1) | RN4(TMP_REG1) | RM4(SLJIT_R1));
|
||||
case SLJIT_DIV_UW:
|
||||
case SLJIT_DIV_SW:
|
||||
return push_inst32(compiler, (op == SLJIT_DIV_UW ? UDIV : SDIV) | RD4(SLJIT_R0) | RN4(SLJIT_R0) | RM4(SLJIT_R1));
|
||||
#else /* !__ARM_FEATURE_IDIV && !__ARM_ARCH_EXT_IDIV__ */
|
||||
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);
|
||||
SLJIT_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 12);
|
||||
SLJIT_ASSERT(reg_map[2] == 1 && reg_map[3] == 2 && reg_map[4] == 3);
|
||||
|
||||
saved_reg_count = 0;
|
||||
if (compiler->scratches >= 4)
|
||||
saved_reg_list[saved_reg_count++] = 12;
|
||||
saved_reg_list[saved_reg_count++] = 3;
|
||||
if (compiler->scratches >= 3)
|
||||
saved_reg_list[saved_reg_count++] = 2;
|
||||
if (op >= SLJIT_DIV_UW)
|
||||
@ -1242,7 +1280,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#ifdef _WIN32
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, SLJIT_R0)));
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_R0, SLJIT_R1)));
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_R1, TMP_REG1)));
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
|
||||
((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__rt_udiv) : SLJIT_FUNC_OFFSET(__rt_sdiv))));
|
||||
#elif defined(__GNUC__)
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM,
|
||||
((op | 0x2) == SLJIT_DIV_UW ? SLJIT_FUNC_OFFSET(__aeabi_uidivmod) : SLJIT_FUNC_OFFSET(__aeabi_idivmod))));
|
||||
#else
|
||||
@ -1262,6 +1306,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
|
||||
| (saved_reg_list[0] << 12) /* ldr rX, [sp], #8/16 */);
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
#endif /* __ARM_FEATURE_IDIV || __ARM_ARCH_EXT_IDIV__ */
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
@ -1289,7 +1334,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
|
||||
switch (op) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_U32:
|
||||
@ -1317,32 +1362,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_s16)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU:
|
||||
case SLJIT_MOVU_U32:
|
||||
case SLJIT_MOVU_S32:
|
||||
case SLJIT_MOVU_P:
|
||||
flags = WORD_SIZE | UPDATE;
|
||||
break;
|
||||
case SLJIT_MOVU_U8:
|
||||
flags = BYTE_SIZE | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_u8)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU_S8:
|
||||
flags = BYTE_SIZE | SIGNED | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_s8)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU_U16:
|
||||
flags = HALF_SIZE | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_u16)srcw;
|
||||
break;
|
||||
case SLJIT_MOVU_S16:
|
||||
flags = HALF_SIZE | SIGNED | UPDATE;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_s16)srcw;
|
||||
break;
|
||||
default:
|
||||
SLJIT_UNREACHABLE();
|
||||
flags = 0;
|
||||
@ -1352,7 +1371,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
if (src & SLJIT_IMM)
|
||||
FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG2, srcw));
|
||||
else if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem(compiler, flags, dst_r, src, srcw, ((flags & UPDATE) && dst_r == TMP_REG1) ? TMP_REG2 : TMP_REG1));
|
||||
FAIL_IF(emit_op_mem(compiler, flags, dst_r, src, srcw, TMP_REG1));
|
||||
} else {
|
||||
if (dst_r != TMP_REG1)
|
||||
return emit_op_imm(compiler, op, dst_r, TMP_REG2, src);
|
||||
@ -1362,7 +1381,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
if (!(dst & SLJIT_MEM))
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, (dst_r == TMP_REG1) ? TMP_REG2 : TMP_REG1);
|
||||
return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2);
|
||||
}
|
||||
|
||||
if (op == SLJIT_NEG) {
|
||||
@ -1375,20 +1394,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
|
||||
flags = HAS_FLAGS(op_flags) ? SET_FLAGS : 0;
|
||||
|
||||
if (src & SLJIT_IMM)
|
||||
flags |= ARG2_IMM;
|
||||
else if (src & SLJIT_MEM) {
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
|
||||
srcw = TMP_REG1;
|
||||
src = TMP_REG1;
|
||||
}
|
||||
else
|
||||
srcw = src;
|
||||
|
||||
emit_op_imm(compiler, flags | op, dst_r, TMP_REG2, srcw);
|
||||
emit_op_imm(compiler, flags | op, dst_r, TMP_REG2, src);
|
||||
|
||||
if (!(dst & SLJIT_MEM))
|
||||
return SLJIT_SUCCESS;
|
||||
return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2);
|
||||
if (SLJIT_UNLIKELY(dst & SLJIT_MEM))
|
||||
return emit_op_mem(compiler, flags | STORE, dst_r, dst, dstw, TMP_REG2);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
@ -1448,7 +1463,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg << 1;
|
||||
return (freg_map[reg] << 1);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
@ -1702,11 +1717,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src)));
|
||||
else if (src & SLJIT_MEM) {
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2));
|
||||
}
|
||||
else if (src & SLJIT_IMM)
|
||||
FAIL_IF(load_immediate(compiler, TMP_REG2, srcw));
|
||||
|
||||
return push_inst16(compiler, BX | RN3(TMP_REG2));
|
||||
}
|
||||
|
||||
@ -1798,7 +1811,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
|
||||
type &= 0xff;
|
||||
|
||||
/* In ARM, we don't need to touch the arguments. */
|
||||
PTR_FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
|
||||
if (type < SLJIT_JUMP) {
|
||||
jump->flags |= IS_COND;
|
||||
@ -1818,6 +1830,241 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
return jump;
|
||||
}
|
||||
|
||||
#ifdef __SOFTFP__
|
||||
|
||||
static sljit_s32 softfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)
|
||||
{
|
||||
sljit_s32 stack_offset = 0;
|
||||
sljit_s32 arg_count = 0;
|
||||
sljit_s32 word_arg_offset = 0;
|
||||
sljit_s32 float_arg_count = 0;
|
||||
sljit_s32 types = 0;
|
||||
sljit_s32 src_offset = 4 * sizeof(sljit_sw);
|
||||
sljit_u8 offsets[4];
|
||||
|
||||
if (src && FAST_IS_REG(*src))
|
||||
src_offset = reg_map[*src] * sizeof(sljit_sw);
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
|
||||
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
offsets[arg_count] = (sljit_u8)stack_offset;
|
||||
stack_offset += sizeof(sljit_f32);
|
||||
arg_count++;
|
||||
float_arg_count++;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (stack_offset & 0x7)
|
||||
stack_offset += sizeof(sljit_sw);
|
||||
offsets[arg_count] = (sljit_u8)stack_offset;
|
||||
stack_offset += sizeof(sljit_f64);
|
||||
arg_count++;
|
||||
float_arg_count++;
|
||||
break;
|
||||
default:
|
||||
offsets[arg_count] = (sljit_u8)stack_offset;
|
||||
stack_offset += sizeof(sljit_sw);
|
||||
arg_count++;
|
||||
word_arg_offset += sizeof(sljit_sw);
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
if (stack_offset > 16)
|
||||
FAIL_IF(push_inst16(compiler, SUB_SP | (((stack_offset - 16) + 0x7) & ~0x7) >> 2));
|
||||
|
||||
SLJIT_ASSERT(reg_map[TMP_REG1] == 12);
|
||||
|
||||
/* Process arguments in reversed direction. */
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
arg_count--;
|
||||
float_arg_count--;
|
||||
stack_offset = offsets[arg_count];
|
||||
|
||||
if (stack_offset < 16) {
|
||||
if (src_offset == stack_offset) {
|
||||
FAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));
|
||||
*src = TMP_REG1;
|
||||
}
|
||||
FAIL_IF(push_inst32(compiler, VMOV | 0x100000 | (float_arg_count << 16) | (stack_offset << 10)));
|
||||
} else
|
||||
FAIL_IF(push_inst32(compiler, VSTR_F32 | 0x800000 | RN4(SLJIT_SP) | (float_arg_count << 12) | ((stack_offset - 16) >> 2)));
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
arg_count--;
|
||||
float_arg_count--;
|
||||
stack_offset = offsets[arg_count];
|
||||
|
||||
SLJIT_ASSERT((stack_offset & 0x7) == 0);
|
||||
|
||||
if (stack_offset < 16) {
|
||||
if (src_offset == stack_offset || src_offset == stack_offset + sizeof(sljit_sw)) {
|
||||
FAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));
|
||||
*src = TMP_REG1;
|
||||
}
|
||||
FAIL_IF(push_inst32(compiler, VMOV2 | 0x100000 | (stack_offset << 10) | ((stack_offset + sizeof(sljit_sw)) << 14) | float_arg_count));
|
||||
} else
|
||||
FAIL_IF(push_inst32(compiler, VSTR_F32 | 0x800100 | RN4(SLJIT_SP) | (float_arg_count << 12) | ((stack_offset - 16) >> 2)));
|
||||
break;
|
||||
default:
|
||||
arg_count--;
|
||||
word_arg_offset -= sizeof(sljit_sw);
|
||||
stack_offset = offsets[arg_count];
|
||||
|
||||
SLJIT_ASSERT(stack_offset >= word_arg_offset);
|
||||
|
||||
if (stack_offset != word_arg_offset) {
|
||||
if (stack_offset < 16) {
|
||||
if (src_offset == stack_offset) {
|
||||
FAIL_IF(push_inst16(compiler, MOV | (src_offset << 1) | 4 | (1 << 7)));
|
||||
*src = TMP_REG1;
|
||||
}
|
||||
else if (src_offset == word_arg_offset) {
|
||||
*src = 1 + (stack_offset >> 2);
|
||||
src_offset = stack_offset;
|
||||
}
|
||||
FAIL_IF(push_inst16(compiler, MOV | (stack_offset >> 2) | (word_arg_offset << 1)));
|
||||
} else
|
||||
FAIL_IF(push_inst16(compiler, STR_SP | (word_arg_offset << 6) | ((stack_offset - 16) >> 2)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_s32 softfloat_post_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
|
||||
{
|
||||
sljit_s32 stack_size = 0;
|
||||
|
||||
if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F32)
|
||||
FAIL_IF(push_inst32(compiler, VMOV | (0 << 16) | (0 << 12)));
|
||||
if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F64)
|
||||
FAIL_IF(push_inst32(compiler, VMOV2 | (1 << 16) | (0 << 12) | 0));
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
stack_size += sizeof(sljit_f32);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (stack_size & 0x7)
|
||||
stack_size += sizeof(sljit_sw);
|
||||
stack_size += sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
stack_size += sizeof(sljit_sw);
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
if (stack_size <= 16)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
return push_inst16(compiler, ADD_SP | ((((stack_size - 16) + 0x7) & ~0x7) >> 2));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static sljit_s32 hardfloat_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
|
||||
{
|
||||
sljit_u32 remap = 0;
|
||||
sljit_u32 offset = 0;
|
||||
sljit_u32 new_offset, mask;
|
||||
|
||||
/* Remove return value. */
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F32) {
|
||||
new_offset = 0;
|
||||
mask = 1;
|
||||
|
||||
while (remap & mask) {
|
||||
new_offset++;
|
||||
mask <<= 1;
|
||||
}
|
||||
remap |= mask;
|
||||
|
||||
if (offset != new_offset)
|
||||
FAIL_IF(push_inst32(compiler, VMOV_F32 | DD4((new_offset >> 1) + 1)
|
||||
| ((new_offset & 0x1) ? 0x400000 : 0) | DM4((offset >> 1) + 1)));
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
else if ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F64) {
|
||||
new_offset = 0;
|
||||
mask = 3;
|
||||
|
||||
while (remap & mask) {
|
||||
new_offset += 2;
|
||||
mask <<= 2;
|
||||
}
|
||||
remap |= mask;
|
||||
|
||||
if (offset != new_offset)
|
||||
FAIL_IF(push_inst32(compiler, VMOV_F32 | SLJIT_F32_OP | DD4((new_offset >> 1) + 1) | DM4((offset >> 1) + 1)));
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types)
|
||||
{
|
||||
#ifdef __SOFTFP__
|
||||
struct sljit_jump *jump;
|
||||
#endif
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
|
||||
|
||||
#ifdef __SOFTFP__
|
||||
PTR_FAIL_IF(softfloat_call_with_args(compiler, arg_types, NULL));
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
|
||||
jump = sljit_emit_jump(compiler, type);
|
||||
PTR_FAIL_IF(jump == NULL);
|
||||
|
||||
PTR_FAIL_IF(softfloat_post_call_with_args(compiler, arg_types));
|
||||
return jump;
|
||||
#else
|
||||
PTR_FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
|
||||
return sljit_emit_jump(compiler, type);
|
||||
#endif
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
@ -1826,16 +2073,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
||||
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
/* In ARM, we don't need to touch the arguments. */
|
||||
SLJIT_ASSERT(reg_map[TMP_REG1] != 14);
|
||||
|
||||
if (!(src & SLJIT_IMM)) {
|
||||
if (FAST_IS_REG(src))
|
||||
if (FAST_IS_REG(src)) {
|
||||
SLJIT_ASSERT(reg_map[src] != 14);
|
||||
return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src));
|
||||
}
|
||||
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw, TMP_REG1));
|
||||
if (type >= SLJIT_FAST_CALL)
|
||||
return push_inst16(compiler, BLX | RN3(TMP_REG1));
|
||||
}
|
||||
|
||||
/* These jumps are converted to jump/call instructions when possible. */
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
FAIL_IF(!jump);
|
||||
set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
|
||||
@ -1846,6 +2097,41 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
||||
return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1));
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
|
||||
|
||||
#ifdef __SOFTFP__
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
|
||||
src = TMP_REG1;
|
||||
}
|
||||
|
||||
FAIL_IF(softfloat_call_with_args(compiler, arg_types, &src));
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
|
||||
FAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));
|
||||
|
||||
return softfloat_post_call_with_args(compiler, arg_types);
|
||||
#else /* !__SOFTFP__ */
|
||||
FAIL_IF(hardfloat_call_with_args(compiler, arg_types));
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
|
||||
return sljit_emit_ijump(compiler, type, src, srcw);
|
||||
#endif /* __SOFTFP__ */
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 type)
|
||||
@ -1896,8 +2182,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
/* The condition must always be set, even if the ORR/EORI is not executed above. */
|
||||
if (reg_map[dst_r] <= 7)
|
||||
return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst_r));
|
||||
return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst_r));
|
||||
}
|
||||
|
||||
@ -1924,8 +2208,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
||||
if (tmp < 0x10000) {
|
||||
/* set low 16 bits, set hi 16 bits to 0. */
|
||||
FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
|
||||
return push_inst32(compiler, MOVW | RD4(dst_reg) |
|
||||
COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff));
|
||||
return push_inst32(compiler, MOVW | RD4(dst_reg)
|
||||
| COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff));
|
||||
}
|
||||
|
||||
tmp = get_imm(srcw);
|
||||
@ -1943,10 +2227,67 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
|
||||
FAIL_IF(push_inst16(compiler, IT | (cc << 4) | ((cc & 0x1) << 3) | 0x4));
|
||||
|
||||
tmp = (sljit_uw) srcw;
|
||||
FAIL_IF(push_inst32(compiler, MOVW | RD4(dst_reg) |
|
||||
COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff)));
|
||||
return push_inst32(compiler, MOVT | RD4(dst_reg) |
|
||||
COPY_BITS(tmp, 12 + 16, 16, 4) | COPY_BITS(tmp, 11 + 16, 26, 1) | COPY_BITS(tmp, 8 + 16, 12, 3) | ((tmp & 0xff0000) >> 16));
|
||||
FAIL_IF(push_inst32(compiler, MOVW | RD4(dst_reg)
|
||||
| COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff)));
|
||||
return push_inst32(compiler, MOVT | RD4(dst_reg)
|
||||
| COPY_BITS(tmp, 12 + 16, 16, 4) | COPY_BITS(tmp, 11 + 16, 26, 1) | COPY_BITS(tmp, 8 + 16, 12, 3) | ((tmp & 0xff0000) >> 16));
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 reg,
|
||||
sljit_s32 mem, sljit_sw memw)
|
||||
{
|
||||
sljit_s32 flags;
|
||||
sljit_ins inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_mem(compiler, type, reg, mem, memw));
|
||||
|
||||
if ((mem & OFFS_REG_MASK) || (memw > 255 && memw < -255))
|
||||
return SLJIT_ERR_UNSUPPORTED;
|
||||
|
||||
if (type & SLJIT_MEM_SUPP)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
switch (type & 0xff) {
|
||||
case SLJIT_MOV:
|
||||
case SLJIT_MOV_U32:
|
||||
case SLJIT_MOV_S32:
|
||||
case SLJIT_MOV_P:
|
||||
flags = WORD_SIZE;
|
||||
break;
|
||||
case SLJIT_MOV_U8:
|
||||
flags = BYTE_SIZE;
|
||||
break;
|
||||
case SLJIT_MOV_S8:
|
||||
flags = BYTE_SIZE | SIGNED;
|
||||
break;
|
||||
case SLJIT_MOV_U16:
|
||||
flags = HALF_SIZE;
|
||||
break;
|
||||
case SLJIT_MOV_S16:
|
||||
flags = HALF_SIZE | SIGNED;
|
||||
break;
|
||||
default:
|
||||
SLJIT_UNREACHABLE();
|
||||
flags = WORD_SIZE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (type & SLJIT_MEM_STORE)
|
||||
flags |= STORE;
|
||||
|
||||
inst = sljit_mem32[flags] | 0x900;
|
||||
|
||||
if (type & SLJIT_MEM_PRE)
|
||||
inst |= 0x400;
|
||||
|
||||
if (memw >= 0)
|
||||
inst |= 0x200;
|
||||
else
|
||||
memw = -memw;
|
||||
|
||||
return push_inst32(compiler, inst | RT4(reg) | RN4(mem & REG_MASK) | memw);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
|
||||
|
@ -435,3 +435,232 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 2);
|
||||
}
|
||||
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
|
||||
{
|
||||
sljit_s32 stack_offset = 0;
|
||||
sljit_s32 arg_count = 0;
|
||||
sljit_s32 float_arg_count = 0;
|
||||
sljit_s32 word_arg_count = 0;
|
||||
sljit_s32 types = 0;
|
||||
sljit_s32 arg_count_save, types_save;
|
||||
sljit_ins prev_ins = NOP;
|
||||
sljit_ins ins = NOP;
|
||||
sljit_u8 offsets[4];
|
||||
|
||||
SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12);
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
|
||||
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
offsets[arg_count] = (sljit_u8)stack_offset;
|
||||
|
||||
if (word_arg_count == 0 && arg_count <= 1)
|
||||
offsets[arg_count] = 254 + arg_count;
|
||||
|
||||
stack_offset += sizeof(sljit_f32);
|
||||
arg_count++;
|
||||
float_arg_count++;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (stack_offset & 0x7)
|
||||
stack_offset += sizeof(sljit_sw);
|
||||
offsets[arg_count] = (sljit_u8)stack_offset;
|
||||
|
||||
if (word_arg_count == 0 && arg_count <= 1)
|
||||
offsets[arg_count] = 254 + arg_count;
|
||||
|
||||
stack_offset += sizeof(sljit_f64);
|
||||
arg_count++;
|
||||
float_arg_count++;
|
||||
break;
|
||||
default:
|
||||
offsets[arg_count] = (sljit_u8)stack_offset;
|
||||
stack_offset += sizeof(sljit_sw);
|
||||
arg_count++;
|
||||
word_arg_count++;
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
/* Stack is aligned to 16 bytes, max two doubles can be placed on the stack. */
|
||||
if (stack_offset > 16)
|
||||
FAIL_IF(push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-16), DR(SLJIT_SP)));
|
||||
|
||||
types_save = types;
|
||||
arg_count_save = arg_count;
|
||||
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
arg_count--;
|
||||
if (offsets[arg_count] < 254)
|
||||
ins = SWC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(offsets[arg_count]);
|
||||
float_arg_count--;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
arg_count--;
|
||||
if (offsets[arg_count] < 254)
|
||||
ins = SDC1 | S(SLJIT_SP) | FT(float_arg_count) | IMM(offsets[arg_count]);
|
||||
float_arg_count--;
|
||||
break;
|
||||
default:
|
||||
if (offsets[arg_count - 1] >= 16)
|
||||
ins = SW | S(SLJIT_SP) | T(word_arg_count) | IMM(offsets[arg_count - 1]);
|
||||
else if (arg_count != word_arg_count)
|
||||
ins = ADDU | S(word_arg_count) | TA(0) | DA(4 + (offsets[arg_count - 1] >> 2));
|
||||
else if (arg_count == 1)
|
||||
ins = ADDU | S(SLJIT_R0) | TA(0) | DA(4);
|
||||
|
||||
arg_count--;
|
||||
word_arg_count--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ins != NOP) {
|
||||
if (prev_ins != NOP)
|
||||
FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
|
||||
prev_ins = ins;
|
||||
ins = NOP;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
types = types_save;
|
||||
arg_count = arg_count_save;
|
||||
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
arg_count--;
|
||||
if (offsets[arg_count] == 254)
|
||||
ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
|
||||
else if (offsets[arg_count] < 16)
|
||||
ins = LW | S(SLJIT_SP) | TA(4 + (offsets[arg_count] >> 2)) | IMM(offsets[arg_count]);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
arg_count--;
|
||||
if (offsets[arg_count] == 254)
|
||||
ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1);
|
||||
else if (offsets[arg_count] < 16) {
|
||||
if (prev_ins != NOP)
|
||||
FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
|
||||
prev_ins = LW | S(SLJIT_SP) | TA(4 + (offsets[arg_count] >> 2)) | IMM(offsets[arg_count]);
|
||||
ins = LW | S(SLJIT_SP) | TA(5 + (offsets[arg_count] >> 2)) | IMM(offsets[arg_count] + sizeof(sljit_sw));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
arg_count--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ins != NOP) {
|
||||
if (prev_ins != NOP)
|
||||
FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
|
||||
prev_ins = ins;
|
||||
ins = NOP;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
*ins_ptr = prev_ins;
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_s32 post_call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types)
|
||||
{
|
||||
sljit_s32 stack_offset = 0;
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
stack_offset += sizeof(sljit_f32);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (stack_offset & 0x7)
|
||||
stack_offset += sizeof(sljit_sw);
|
||||
stack_offset += sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
stack_offset += sizeof(sljit_sw);
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
/* Stack is aligned to 16 bytes, max two doubles can be placed on the stack. */
|
||||
if (stack_offset > 16)
|
||||
return push_inst(compiler, ADDIU | S(SLJIT_SP) | T(SLJIT_SP) | IMM(16), DR(SLJIT_SP));
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
sljit_ins ins;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
|
||||
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
PTR_FAIL_IF(!jump);
|
||||
set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
|
||||
type &= 0xff;
|
||||
|
||||
PTR_FAIL_IF(call_with_args(compiler, arg_types, &ins));
|
||||
|
||||
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
|
||||
|
||||
PTR_FAIL_IF(emit_const(compiler, PIC_ADDR_REG, 0));
|
||||
|
||||
jump->flags |= IS_JAL | IS_CALL;
|
||||
PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
jump->addr = compiler->size;
|
||||
PTR_FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
|
||||
|
||||
PTR_FAIL_IF(post_call_with_args(compiler, arg_types));
|
||||
|
||||
return jump;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_ins ins;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
|
||||
|
||||
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
|
||||
|
||||
if (src & SLJIT_IMM)
|
||||
FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
|
||||
else if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, ADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
|
||||
else if (src & SLJIT_MEM) {
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
|
||||
}
|
||||
|
||||
FAIL_IF(call_with_args(compiler, arg_types, &ins));
|
||||
|
||||
/* Register input. */
|
||||
FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
|
||||
return post_call_with_args(compiler, arg_types);
|
||||
}
|
||||
|
@ -537,3 +537,132 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
|
||||
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
|
||||
SLJIT_CACHE_FLUSH(inst, inst + 6);
|
||||
}
|
||||
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
|
||||
{
|
||||
sljit_s32 arg_count = 0;
|
||||
sljit_s32 word_arg_count = 0;
|
||||
sljit_s32 float_arg_count = 0;
|
||||
sljit_s32 types = 0;
|
||||
sljit_ins prev_ins = NOP;
|
||||
sljit_ins ins = NOP;
|
||||
|
||||
SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12);
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
|
||||
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
arg_count++;
|
||||
float_arg_count++;
|
||||
break;
|
||||
default:
|
||||
arg_count++;
|
||||
word_arg_count++;
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
if (arg_count != float_arg_count)
|
||||
ins = MOV_S | FMT_S | FS(float_arg_count) | FD(arg_count);
|
||||
else if (arg_count == 1)
|
||||
ins = MOV_S | FMT_S | FS(SLJIT_FR0) | FD(TMP_FREG1);
|
||||
arg_count--;
|
||||
float_arg_count--;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (arg_count != float_arg_count)
|
||||
ins = MOV_S | FMT_D | FS(float_arg_count) | FD(arg_count);
|
||||
else if (arg_count == 1)
|
||||
ins = MOV_S | FMT_D | FS(SLJIT_FR0) | FD(TMP_FREG1);
|
||||
arg_count--;
|
||||
float_arg_count--;
|
||||
break;
|
||||
default:
|
||||
if (arg_count != word_arg_count)
|
||||
ins = DADDU | S(word_arg_count) | TA(0) | D(arg_count);
|
||||
else if (arg_count == 1)
|
||||
ins = DADDU | S(SLJIT_R0) | TA(0) | DA(4);
|
||||
arg_count--;
|
||||
word_arg_count--;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ins != NOP) {
|
||||
if (prev_ins != NOP)
|
||||
FAIL_IF(push_inst(compiler, prev_ins, MOVABLE_INS));
|
||||
prev_ins = ins;
|
||||
ins = NOP;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
*ins_ptr = prev_ins;
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
sljit_ins ins;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
|
||||
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
PTR_FAIL_IF(!jump);
|
||||
set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
|
||||
type &= 0xff;
|
||||
|
||||
PTR_FAIL_IF(call_with_args(compiler, arg_types, &ins));
|
||||
|
||||
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
|
||||
|
||||
PTR_FAIL_IF(emit_const(compiler, PIC_ADDR_REG, 0));
|
||||
|
||||
jump->flags |= IS_JAL | IS_CALL;
|
||||
PTR_FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
jump->addr = compiler->size;
|
||||
PTR_FAIL_IF(push_inst(compiler, ins, UNMOVABLE_INS));
|
||||
|
||||
return jump;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_ins ins;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
|
||||
|
||||
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
|
||||
|
||||
if (src & SLJIT_IMM)
|
||||
FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
|
||||
else if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, DADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
|
||||
else if (src & SLJIT_MEM) {
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
|
||||
}
|
||||
|
||||
FAIL_IF(call_with_args(compiler, arg_types, &ins));
|
||||
|
||||
/* Register input. */
|
||||
FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
return push_inst(compiler, ins, UNMOVABLE_INS);
|
||||
}
|
||||
|
@ -57,16 +57,30 @@ typedef sljit_u32 sljit_ins;
|
||||
#define RETURN_ADDR_REG 31
|
||||
|
||||
/* Flags are kept in volatile registers. */
|
||||
#define EQUAL_FLAG 31
|
||||
#define EQUAL_FLAG 3
|
||||
#define OTHER_FLAG 1
|
||||
|
||||
#define TMP_FREG1 (0)
|
||||
#define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1)
|
||||
#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
|
||||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
|
||||
|
||||
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, 3, 25, 4
|
||||
0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31
|
||||
};
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
0, 0, 14, 2, 4, 6, 8, 12, 10
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
0, 0, 13, 14, 15, 16, 17, 12, 18
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Instrucion forms */
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -74,21 +88,23 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
#define S(s) (reg_map[s] << 21)
|
||||
#define T(t) (reg_map[t] << 16)
|
||||
#define D(d) (reg_map[d] << 11)
|
||||
#define FT(t) (freg_map[t] << 16)
|
||||
#define FS(s) (freg_map[s] << 11)
|
||||
#define FD(d) (freg_map[d] << 6)
|
||||
/* Absolute registers. */
|
||||
#define SA(s) ((s) << 21)
|
||||
#define TA(t) ((t) << 16)
|
||||
#define DA(d) ((d) << 11)
|
||||
#define FT(t) ((t) << 16)
|
||||
#define FS(s) ((s) << 11)
|
||||
#define FD(d) ((d) << 6)
|
||||
#define IMM(imm) ((imm) & 0xffff)
|
||||
#define SH_IMM(imm) ((imm) << 6)
|
||||
|
||||
#define DR(dr) (reg_map[dr])
|
||||
#define FR(dr) (freg_map[dr])
|
||||
#define HI(opcode) ((opcode) << 26)
|
||||
#define LO(opcode) (opcode)
|
||||
/* S = (16 << 21) D = (17 << 21) */
|
||||
#define FMT_S (16 << 21)
|
||||
#define FMT_D (17 << 21)
|
||||
|
||||
#define ABS_S (HI(17) | FMT_S | LO(5))
|
||||
#define ADD_S (HI(17) | FMT_S | LO(0))
|
||||
@ -153,6 +169,7 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
#define OR (HI(0) | LO(37))
|
||||
#define ORI (HI(13))
|
||||
#define SD (HI(63))
|
||||
#define SDC1 (HI(61))
|
||||
#define SLT (HI(0) | LO(42))
|
||||
#define SLTI (HI(10))
|
||||
#define SLTIU (HI(11))
|
||||
@ -166,6 +183,7 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
|
||||
#define SUB_S (HI(17) | FMT_S | LO(1))
|
||||
#define SUBU (HI(0) | LO(35))
|
||||
#define SW (HI(43))
|
||||
#define SWC1 (HI(57))
|
||||
#define TRUNC_W_S (HI(17) | FMT_S | LO(13))
|
||||
#define XOR (HI(0) | LO(38))
|
||||
#define XORI (HI(14))
|
||||
@ -498,12 +516,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
{
|
||||
sljit_sw fir = 0;
|
||||
|
||||
switch (feature_type) {
|
||||
case SLJIT_HAS_FPU:
|
||||
#ifdef SLJIT_IS_FPU_AVAILABLE
|
||||
return SLJIT_IS_FPU_AVAILABLE;
|
||||
#elif defined(__GNUC__)
|
||||
sljit_sw fir;
|
||||
asm ("cfc1 %0, $0" : "=r"(fir));
|
||||
return (fir >> 22) & 0x1;
|
||||
#else
|
||||
@ -517,7 +536,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
#endif
|
||||
|
||||
default:
|
||||
return 0;
|
||||
return fir;
|
||||
}
|
||||
}
|
||||
|
||||
@ -539,21 +558,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
|
||||
#define MEM_MASK 0x1f
|
||||
|
||||
#define WRITE_BACK 0x00020
|
||||
#define ARG_TEST 0x00040
|
||||
#define ALT_KEEP_CACHE 0x00080
|
||||
#define CUMULATIVE_OP 0x00100
|
||||
#define LOGICAL_OP 0x00200
|
||||
#define IMM_OP 0x00400
|
||||
#define SRC2_IMM 0x00800
|
||||
#define ARG_TEST 0x00020
|
||||
#define ALT_KEEP_CACHE 0x00040
|
||||
#define CUMULATIVE_OP 0x00080
|
||||
#define LOGICAL_OP 0x00100
|
||||
#define IMM_OP 0x00200
|
||||
#define SRC2_IMM 0x00400
|
||||
|
||||
#define UNUSED_DEST 0x01000
|
||||
#define REG_DEST 0x02000
|
||||
#define REG1_SOURCE 0x04000
|
||||
#define REG2_SOURCE 0x08000
|
||||
#define SLOW_SRC1 0x10000
|
||||
#define SLOW_SRC2 0x20000
|
||||
#define SLOW_DEST 0x40000
|
||||
#define UNUSED_DEST 0x00800
|
||||
#define REG_DEST 0x01000
|
||||
#define REG1_SOURCE 0x02000
|
||||
#define REG2_SOURCE 0x04000
|
||||
#define SLOW_SRC1 0x08000
|
||||
#define SLOW_SRC2 0x10000
|
||||
#define SLOW_DEST 0x20000
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
#define STACK_STORE SW
|
||||
@ -563,6 +581,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
#define STACK_LOAD LD
|
||||
#endif
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw);
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
#include "sljitNativeMIPS_32.c"
|
||||
#else
|
||||
@ -570,15 +590,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_ins base;
|
||||
sljit_s32 i, tmp, offs;
|
||||
sljit_s32 args, i, tmp, offs;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
@ -592,16 +612,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
/* Frequent case. */
|
||||
FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));
|
||||
base = S(SLJIT_SP);
|
||||
offs = local_size - (sljit_sw)sizeof(sljit_sw);
|
||||
}
|
||||
else {
|
||||
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size));
|
||||
FAIL_IF(load_immediate(compiler, DR(OTHER_FLAG), local_size));
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
|
||||
FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(TMP_REG1) | D(SLJIT_SP), DR(SLJIT_SP)));
|
||||
FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));
|
||||
base = S(TMP_REG2);
|
||||
local_size = 0;
|
||||
offs = -(sljit_sw)sizeof(sljit_sw);
|
||||
}
|
||||
|
||||
offs = local_size - (sljit_sw)(sizeof(sljit_sw));
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(offs), MOVABLE_INS));
|
||||
|
||||
tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
|
||||
@ -615,6 +636,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
FAIL_IF(push_inst(compiler, STACK_STORE | base | T(i) | IMM(offs), MOVABLE_INS));
|
||||
}
|
||||
|
||||
args = get_arg_count(arg_types);
|
||||
|
||||
if (args >= 1)
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_S0), DR(SLJIT_S0)));
|
||||
if (args >= 2)
|
||||
@ -626,12 +649,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
local_size += GET_SAVED_REGISTERS_SIZE(scratches, saveds, 1) + SLJIT_LOCALS_OFFSET;
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
@ -733,7 +756,7 @@ static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flag
|
||||
{
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
|
||||
if ((!(flags & WRITE_BACK) || !(arg & REG_MASK)) && !(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
|
||||
if (!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN) {
|
||||
/* Works for both absoulte and relative addresses. */
|
||||
if (SLJIT_UNLIKELY(flags & ARG_TEST))
|
||||
return 1;
|
||||
@ -783,19 +806,14 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
|
||||
if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
|
||||
tmp_ar = reg_ar;
|
||||
delay_slot = reg_ar;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
tmp_ar = DR(TMP_REG1);
|
||||
delay_slot = MOVABLE_INS;
|
||||
}
|
||||
base = arg & REG_MASK;
|
||||
|
||||
if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
|
||||
if (SLJIT_UNLIKELY(flags & WRITE_BACK)) {
|
||||
SLJIT_ASSERT(argw == 0);
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | D(base), DR(base)));
|
||||
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot);
|
||||
}
|
||||
|
||||
argw &= 0x3;
|
||||
|
||||
/* Using the cache. */
|
||||
@ -832,29 +850,6 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
|
||||
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
|
||||
}
|
||||
|
||||
if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) {
|
||||
if (argw <= SIMM_MAX && argw >= SIMM_MIN) {
|
||||
if (argw)
|
||||
FAIL_IF(push_inst(compiler, ADDIU_W | S(base) | T(base) | IMM(argw), DR(base)));
|
||||
}
|
||||
else {
|
||||
if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
|
||||
if (argw != compiler->cache_argw) {
|
||||
FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
|
||||
compiler->cache_argw = argw;
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
|
||||
}
|
||||
else {
|
||||
compiler->cache_arg = SLJIT_MEM;
|
||||
compiler->cache_argw = argw;
|
||||
FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw));
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(base), DR(base)));
|
||||
}
|
||||
}
|
||||
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot);
|
||||
}
|
||||
|
||||
if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) {
|
||||
if (argw != compiler->cache_argw) {
|
||||
FAIL_IF(push_inst(compiler, ADDIU_W | S(TMP_REG3) | T(TMP_REG3) | IMM(argw - compiler->cache_argw), DR(TMP_REG3)));
|
||||
@ -888,11 +883,39 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
|
||||
{
|
||||
sljit_s32 tmp_ar, base, delay_slot;
|
||||
|
||||
if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
|
||||
return compiler->error;
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0);
|
||||
|
||||
if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
|
||||
tmp_ar = reg_ar;
|
||||
delay_slot = reg_ar;
|
||||
}
|
||||
else {
|
||||
tmp_ar = DR(TMP_REG1);
|
||||
delay_slot = MOVABLE_INS;
|
||||
}
|
||||
base = arg & REG_MASK;
|
||||
|
||||
if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
|
||||
argw &= 0x3;
|
||||
|
||||
if (SLJIT_UNLIKELY(argw)) {
|
||||
FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | DA(tmp_ar) | SH_IMM(argw), tmp_ar));
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | TA(tmp_ar) | DA(tmp_ar), tmp_ar));
|
||||
}
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | DA(tmp_ar), tmp_ar));
|
||||
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
|
||||
}
|
||||
|
||||
FAIL_IF(load_immediate(compiler, tmp_ar, argw));
|
||||
|
||||
if (base != 0)
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | TA(tmp_ar) | DA(tmp_ar), tmp_ar));
|
||||
|
||||
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
|
||||
@ -928,7 +951,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
||||
else if (FAST_IS_REG(dst)) {
|
||||
dst_r = dst;
|
||||
flags |= REG_DEST;
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
|
||||
sugg_src2_r = dst_r;
|
||||
}
|
||||
else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw))
|
||||
@ -982,7 +1005,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
||||
if (FAST_IS_REG(src2)) {
|
||||
src2_r = src2;
|
||||
flags |= REG2_SOURCE;
|
||||
if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
|
||||
if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
|
||||
dst_r = src2_r;
|
||||
}
|
||||
else if (src2 & SLJIT_IMM) {
|
||||
@ -993,7 +1016,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
||||
}
|
||||
else {
|
||||
src2_r = 0;
|
||||
if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM))
|
||||
if ((op >= SLJIT_MOV && op <= SLJIT_MOV_P) && (dst & SLJIT_MEM))
|
||||
dst_r = 0;
|
||||
}
|
||||
}
|
||||
@ -1132,11 +1155,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
|
||||
if ((op & SLJIT_I32_OP) && GET_OPCODE(op) >= SLJIT_NOT) {
|
||||
if ((op & SLJIT_I32_OP) && GET_OPCODE(op) >= SLJIT_NOT)
|
||||
flags |= INT_DATA | SIGNED_DATA;
|
||||
if (src & SLJIT_IMM)
|
||||
srcw = (sljit_s32)srcw;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
@ -1170,36 +1190,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
case SLJIT_MOV_S16:
|
||||
return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU:
|
||||
case SLJIT_MOVU_P:
|
||||
return emit_op(compiler, SLJIT_MOV, WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOVU_U32:
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
#else
|
||||
return emit_op(compiler, SLJIT_MOV_U32, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u32)srcw : srcw);
|
||||
#endif
|
||||
|
||||
case SLJIT_MOVU_S32:
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
#else
|
||||
return emit_op(compiler, SLJIT_MOV_S32, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s32)srcw : srcw);
|
||||
#endif
|
||||
|
||||
case SLJIT_MOVU_U8:
|
||||
return emit_op(compiler, SLJIT_MOV_U8, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU_S8:
|
||||
return emit_op(compiler, SLJIT_MOV_S8, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU_U16:
|
||||
return emit_op(compiler, SLJIT_MOV_U16, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU_S16:
|
||||
return emit_op(compiler, SLJIT_MOV_S16, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
|
||||
|
||||
case SLJIT_NOT:
|
||||
return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
@ -1210,6 +1200,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
}
|
||||
|
||||
SLJIT_UNREACHABLE();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
@ -1281,6 +1272,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
|
||||
}
|
||||
|
||||
SLJIT_UNREACHABLE();
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
@ -1297,7 +1289,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg << 1;
|
||||
return FR(reg);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
@ -1327,11 +1319,9 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp
|
||||
#endif
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
|
||||
src = TMP_FREG1;
|
||||
}
|
||||
else
|
||||
src <<= 1;
|
||||
|
||||
FAIL_IF(push_inst(compiler, (TRUNC_W_S ^ (flags >> 19)) | FMT(op) | FS(src) | FD(TMP_FREG1), MOVABLE_INS));
|
||||
|
||||
@ -1339,7 +1329,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp
|
||||
return push_inst(compiler, MFC1 | flags | T(dst) | FS(TMP_FREG1), MOVABLE_INS);
|
||||
|
||||
/* Store the integer value from a VFP register. */
|
||||
return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, TMP_FREG1, dst, dstw, 0, 0);
|
||||
return emit_op_mem2(compiler, flags ? DOUBLE_DATA : SINGLE_DATA, FR(TMP_FREG1), dst, dstw, 0, 0);
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
# undef is_long
|
||||
@ -1356,13 +1346,13 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp
|
||||
sljit_s32 flags = (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_SW) << 21;
|
||||
#endif
|
||||
|
||||
sljit_s32 dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
|
||||
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, MTC1 | flags | T(src) | FS(TMP_FREG1), MOVABLE_INS));
|
||||
else if (src & SLJIT_MEM) {
|
||||
/* Load the integer value into a VFP register. */
|
||||
FAIL_IF(emit_op_mem2(compiler, ((flags) ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
|
||||
FAIL_IF(emit_op_mem2(compiler, ((flags) ? DOUBLE_DATA : SINGLE_DATA) | LOAD_DATA, FR(TMP_FREG1), src, srcw, dst, dstw));
|
||||
}
|
||||
else {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
@ -1376,7 +1366,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp
|
||||
FAIL_IF(push_inst(compiler, CVT_S_S | flags | (4 << 21) | (((op & SLJIT_F32_OP) ^ SLJIT_F32_OP) >> 8) | FS(TMP_FREG1) | FD(dst_r), MOVABLE_INS));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
|
||||
return emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG1), dst, dstw, 0, 0);
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
|
||||
@ -1391,18 +1381,14 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile
|
||||
sljit_ins inst;
|
||||
|
||||
if (src1 & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
|
||||
src1 = TMP_FREG1;
|
||||
}
|
||||
else
|
||||
src1 <<= 1;
|
||||
|
||||
if (src2 & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, 0, 0));
|
||||
src2 = TMP_FREG2;
|
||||
}
|
||||
else
|
||||
src2 <<= 1;
|
||||
|
||||
switch (GET_FLAG_TYPE(op)) {
|
||||
case SLJIT_EQUAL_F64:
|
||||
@ -1442,14 +1428,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
||||
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
|
||||
op ^= SLJIT_F32_OP;
|
||||
|
||||
dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(dst_r), src, srcw, dst, dstw));
|
||||
src = dst_r;
|
||||
}
|
||||
else
|
||||
src <<= 1;
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOV_F64:
|
||||
@ -1473,7 +1457,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
||||
}
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_op_mem2(compiler, FLOAT_DATA(op), dst_r, dst, dstw, 0, 0);
|
||||
return emit_op_mem2(compiler, FLOAT_DATA(op), FR(dst_r), dst, dstw, 0, 0);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1493,42 +1477,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
|
||||
dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
|
||||
|
||||
if (src1 & SLJIT_MEM) {
|
||||
if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
|
||||
if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w)) {
|
||||
FAIL_IF(compiler->error);
|
||||
src1 = TMP_FREG1;
|
||||
} else
|
||||
flags |= SLOW_SRC1;
|
||||
}
|
||||
else
|
||||
src1 <<= 1;
|
||||
|
||||
if (src2 & SLJIT_MEM) {
|
||||
if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
|
||||
if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w)) {
|
||||
FAIL_IF(compiler->error);
|
||||
src2 = TMP_FREG2;
|
||||
} else
|
||||
flags |= SLOW_SRC2;
|
||||
}
|
||||
else
|
||||
src2 <<= 1;
|
||||
|
||||
if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
|
||||
if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, src1, src1w));
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, src1, src1w));
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
|
||||
}
|
||||
else {
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, src2, src2w));
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
|
||||
}
|
||||
}
|
||||
else if (flags & SLOW_SRC1)
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw));
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG1), src1, src1w, dst, dstw));
|
||||
else if (flags & SLOW_SRC2)
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw));
|
||||
FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, FR(TMP_FREG2), src2, src2w, dst, dstw));
|
||||
|
||||
if (flags & SLOW_SRC1)
|
||||
src1 = TMP_FREG1;
|
||||
@ -1554,7 +1534,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
|
||||
}
|
||||
|
||||
if (dst_r == TMP_FREG2)
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0));
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), FR(TMP_FREG2), dst, dstw, 0, 0));
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
@ -1584,10 +1564,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
|
||||
else if (src & SLJIT_MEM)
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
|
||||
else if (src & SLJIT_IMM)
|
||||
FAIL_IF(load_immediate(compiler, RETURN_ADDR_REG, srcw));
|
||||
|
||||
FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
@ -1704,19 +1682,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
PTR_FAIL_IF(push_inst(compiler, inst, UNMOVABLE_INS));
|
||||
|
||||
PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
|
||||
if (type <= SLJIT_JUMP) {
|
||||
|
||||
if (type <= SLJIT_JUMP)
|
||||
PTR_FAIL_IF(push_inst(compiler, JR | S(TMP_REG2), UNMOVABLE_INS));
|
||||
jump->addr = compiler->size;
|
||||
PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
} else {
|
||||
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
|
||||
/* Cannot be optimized out if type is >= CALL0. */
|
||||
jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? IS_CALL : 0);
|
||||
else {
|
||||
jump->flags |= IS_JAL;
|
||||
PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
jump->addr = compiler->size;
|
||||
/* A NOP if type < CALL1. */
|
||||
PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), UNMOVABLE_INS));
|
||||
}
|
||||
|
||||
jump->addr = compiler->size;
|
||||
PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
return jump;
|
||||
}
|
||||
|
||||
@ -1872,41 +1847,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_s32 src_r = TMP_REG2;
|
||||
struct sljit_jump *jump = NULL;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if (FAST_IS_REG(src)) {
|
||||
if (DR(src) != 4)
|
||||
src_r = src;
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
|
||||
}
|
||||
|
||||
if (type >= SLJIT_CALL0) {
|
||||
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
|
||||
if (src & (SLJIT_IMM | SLJIT_MEM)) {
|
||||
if (src & SLJIT_IMM)
|
||||
FAIL_IF(load_immediate(compiler, DR(PIC_ADDR_REG), srcw));
|
||||
else {
|
||||
SLJIT_ASSERT(src_r == TMP_REG2 && (src & SLJIT_MEM));
|
||||
FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
|
||||
}
|
||||
FAIL_IF(push_inst(compiler, JALR | S(PIC_ADDR_REG) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
/* We need an extra instruction in any case. */
|
||||
return push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), UNMOVABLE_INS);
|
||||
}
|
||||
|
||||
/* Register input. */
|
||||
if (type >= SLJIT_CALL1)
|
||||
FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_R0) | TA(0) | DA(4), 4));
|
||||
FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
|
||||
return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | D(PIC_ADDR_REG), UNMOVABLE_INS);
|
||||
}
|
||||
|
||||
if (src & SLJIT_IMM) {
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
FAIL_IF(!jump);
|
||||
@ -1917,11 +1863,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
||||
jump->flags |= IS_MOVABLE;
|
||||
|
||||
FAIL_IF(emit_const(compiler, TMP_REG2, 0));
|
||||
src = TMP_REG2;
|
||||
}
|
||||
else if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), src, srcw));
|
||||
src = TMP_REG2;
|
||||
}
|
||||
else if (src & SLJIT_MEM)
|
||||
FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw));
|
||||
|
||||
FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
|
||||
if (jump)
|
||||
jump->addr = compiler->size;
|
||||
FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
|
@ -413,6 +413,61 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)
|
||||
{
|
||||
sljit_s32 arg_count = 0;
|
||||
sljit_s32 word_arg_count = 0;
|
||||
sljit_s32 types = 0;
|
||||
sljit_s32 reg = 0;
|
||||
|
||||
if (src)
|
||||
reg = *src & REG_MASK;
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
|
||||
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
arg_count++;
|
||||
break;
|
||||
default:
|
||||
arg_count++;
|
||||
word_arg_count++;
|
||||
|
||||
if (arg_count != word_arg_count && arg_count == reg) {
|
||||
FAIL_IF(push_inst(compiler, OR | S(reg) | A(TMP_CALL_REG) | B(reg)));
|
||||
*src = TMP_CALL_REG;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
arg_count--;
|
||||
break;
|
||||
default:
|
||||
if (arg_count != word_arg_count)
|
||||
FAIL_IF(push_inst(compiler, OR | S(word_arg_count) | A(arg_count) | B(word_arg_count)));
|
||||
|
||||
arg_count--;
|
||||
word_arg_count--;
|
||||
break;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 reg, sljit_sw init_value)
|
||||
{
|
||||
FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48)));
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -138,6 +138,125 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src)
|
||||
{
|
||||
sljit_s32 reg_index = 8;
|
||||
sljit_s32 word_reg_index = 8;
|
||||
sljit_s32 float_arg_index = 1;
|
||||
sljit_s32 double_arg_count = 0;
|
||||
sljit_s32 float_offset = (16 + 6) * sizeof(sljit_sw);
|
||||
sljit_s32 types = 0;
|
||||
sljit_s32 reg = 0;
|
||||
sljit_s32 move_to_tmp2 = 0;
|
||||
|
||||
if (src)
|
||||
reg = reg_map[*src & REG_MASK];
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
|
||||
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
float_arg_index++;
|
||||
if (reg_index == reg)
|
||||
move_to_tmp2 = 1;
|
||||
reg_index++;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
float_arg_index++;
|
||||
double_arg_count++;
|
||||
if (reg_index == reg || reg_index + 1 == reg)
|
||||
move_to_tmp2 = 1;
|
||||
reg_index += 2;
|
||||
break;
|
||||
default:
|
||||
if (reg_index != word_reg_index && reg_index < 14 && reg_index == reg)
|
||||
move_to_tmp2 = 1;
|
||||
reg_index++;
|
||||
word_reg_index++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (move_to_tmp2) {
|
||||
move_to_tmp2 = 0;
|
||||
if (reg < 14)
|
||||
FAIL_IF(push_inst(compiler, OR | D(TMP_REG1) | S1(0) | S2A(reg), DR(TMP_REG1)));
|
||||
*src = TMP_REG1;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
arg_types = types;
|
||||
|
||||
while (arg_types) {
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
float_arg_index--;
|
||||
FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
|
||||
float_offset -= sizeof(sljit_f64);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
float_arg_index--;
|
||||
if (float_arg_index == 4 && double_arg_count == 4) {
|
||||
FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | S1(SLJIT_SP) | IMM((16 + 7) * sizeof(sljit_sw)), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, STF | FD(float_arg_index) | (1 << 25) | S1(SLJIT_SP) | IMM((16 + 8) * sizeof(sljit_sw)), MOVABLE_INS));
|
||||
}
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, STDF | FD(float_arg_index) | S1(SLJIT_SP) | IMM(float_offset), MOVABLE_INS));
|
||||
float_offset -= sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
float_offset = (16 + 6) * sizeof(sljit_sw);
|
||||
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
reg_index--;
|
||||
if (reg_index < 14)
|
||||
FAIL_IF(push_inst(compiler, LDUW | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
|
||||
float_offset -= sizeof(sljit_f64);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
reg_index -= 2;
|
||||
if (reg_index < 14) {
|
||||
if ((reg_index & 0x1) != 0) {
|
||||
FAIL_IF(push_inst(compiler, LDUW | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
|
||||
if (reg_index < 13)
|
||||
FAIL_IF(push_inst(compiler, LDUW | DA(reg_index + 1) | S1(SLJIT_SP) | IMM(float_offset + sizeof(sljit_sw)), reg_index + 1));
|
||||
}
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, LDD | DA(reg_index) | S1(SLJIT_SP) | IMM(float_offset), reg_index));
|
||||
}
|
||||
float_offset -= sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
reg_index--;
|
||||
word_reg_index--;
|
||||
|
||||
if (reg_index != word_reg_index) {
|
||||
if (reg_index < 14)
|
||||
FAIL_IF(push_inst(compiler, OR | DA(reg_index) | S1(0) | S2A(word_reg_index), reg_index));
|
||||
else
|
||||
FAIL_IF(push_inst(compiler, STW | DA(word_reg_index) | S1(SLJIT_SP) | IMM(92), word_reg_index));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw init_value)
|
||||
{
|
||||
FAIL_IF(push_inst(compiler, SETHI | D(dst) | ((init_value >> 10) & 0x3fffff), DR(dst)));
|
||||
|
@ -90,13 +90,19 @@ static void sparc_cache_flush(sljit_ins *from, sljit_ins *to)
|
||||
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
|
||||
#define TMP_REG2 (SLJIT_NUMBER_OF_REGISTERS + 3)
|
||||
#define TMP_REG3 (SLJIT_NUMBER_OF_REGISTERS + 4)
|
||||
/* This register is modified by calls, which affects the instruction
|
||||
in the delay slot if it is used as a source register. */
|
||||
#define TMP_LINK (SLJIT_NUMBER_OF_REGISTERS + 5)
|
||||
|
||||
#define TMP_FREG1 (0)
|
||||
#define TMP_FREG2 ((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) << 1)
|
||||
#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
|
||||
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)
|
||||
|
||||
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
0, 8, 9, 10, 13, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 11, 12, 15
|
||||
0, 8, 9, 10, 11, 29, 28, 27, 23, 22, 21, 20, 19, 18, 17, 16, 26, 25, 24, 14, 1, 12, 13, 15
|
||||
};
|
||||
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
|
||||
0, 0, 2, 4, 6, 8, 10, 12, 14
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
@ -104,10 +110,15 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define D(d) (reg_map[d] << 25)
|
||||
#define FD(d) (freg_map[d] << 25)
|
||||
#define FDN(d) ((freg_map[d] | 0x1) << 25)
|
||||
#define DA(d) ((d) << 25)
|
||||
#define S1(s1) (reg_map[s1] << 14)
|
||||
#define S2(s2) (reg_map[s2])
|
||||
#define FS1(s1) (freg_map[s1] << 14)
|
||||
#define S1A(s1) ((s1) << 14)
|
||||
#define S2(s2) (reg_map[s2])
|
||||
#define FS2(s2) (freg_map[s2])
|
||||
#define FS2N(s2) (freg_map[s2] | 0x1)
|
||||
#define S2A(s2) (s2)
|
||||
#define IMM_ARG 0x2000
|
||||
#define DOP(op) ((op) << 5)
|
||||
@ -144,6 +155,8 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
#define FSUBD (OPC1(0x2) | OPC3(0x34) | DOP(0x46))
|
||||
#define FSUBS (OPC1(0x2) | OPC3(0x34) | DOP(0x45))
|
||||
#define JMPL (OPC1(0x2) | OPC3(0x38))
|
||||
#define LDD (OPC1(0x3) | OPC3(0x03))
|
||||
#define LDUW (OPC1(0x3) | OPC3(0x00))
|
||||
#define NOP (OPC1(0x0) | OPC2(0x04))
|
||||
#define OR (OPC1(0x2) | OPC3(0x02))
|
||||
#define ORN (OPC1(0x2) | OPC3(0x06))
|
||||
@ -157,6 +170,9 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 6] = {
|
||||
#define SRAX (OPC1(0x2) | OPC3(0x27) | (1 << 12))
|
||||
#define SRL (OPC1(0x2) | OPC3(0x26))
|
||||
#define SRLX (OPC1(0x2) | OPC3(0x26) | (1 << 12))
|
||||
#define STDF (OPC1(0x3) | OPC3(0x27))
|
||||
#define STF (OPC1(0x3) | OPC3(0x24))
|
||||
#define STW (OPC1(0x3) | OPC3(0x04))
|
||||
#define SUB (OPC1(0x2) | OPC3(0x04))
|
||||
#define SUBC (OPC1(0x2) | OPC3(0x0c))
|
||||
#define TA (OPC1(0x2) | OPC3(0x3a) | (8 << 25))
|
||||
@ -433,18 +449,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
|
||||
#define MEM_MASK 0x1f
|
||||
|
||||
#define WRITE_BACK 0x00020
|
||||
#define ARG_TEST 0x00040
|
||||
#define ALT_KEEP_CACHE 0x00080
|
||||
#define CUMULATIVE_OP 0x00100
|
||||
#define IMM_OP 0x00200
|
||||
#define SRC2_IMM 0x00400
|
||||
#define ARG_TEST 0x00020
|
||||
#define ALT_KEEP_CACHE 0x00040
|
||||
#define CUMULATIVE_OP 0x00080
|
||||
#define IMM_OP 0x00100
|
||||
#define SRC2_IMM 0x00200
|
||||
|
||||
#define REG_DEST 0x00800
|
||||
#define REG2_SOURCE 0x01000
|
||||
#define SLOW_SRC1 0x02000
|
||||
#define SLOW_SRC2 0x04000
|
||||
#define SLOW_DEST 0x08000
|
||||
#define REG_DEST 0x00400
|
||||
#define REG2_SOURCE 0x00800
|
||||
#define SLOW_SRC1 0x01000
|
||||
#define SLOW_SRC2 0x02000
|
||||
#define SLOW_DEST 0x04000
|
||||
|
||||
/* SET_FLAGS (0x10 << 19) also belong here! */
|
||||
|
||||
@ -455,12 +470,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
|
||||
compiler->local_size = local_size;
|
||||
@ -479,12 +494,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
compiler->local_size = (local_size + SLJIT_LOCALS_OFFSET + 7) & ~0x7;
|
||||
return SLJIT_SUCCESS;
|
||||
@ -546,18 +561,16 @@ static sljit_s32 getput_arg_fast(struct sljit_compiler *compiler, sljit_s32 flag
|
||||
{
|
||||
SLJIT_ASSERT(arg & SLJIT_MEM);
|
||||
|
||||
if (!(flags & WRITE_BACK) || !(arg & REG_MASK)) {
|
||||
if ((!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN)
|
||||
|| ((arg & OFFS_REG_MASK) && (argw & 0x3) == 0)) {
|
||||
/* Works for both absoulte and relative addresses (immediate case). */
|
||||
if (SLJIT_UNLIKELY(flags & ARG_TEST))
|
||||
return 1;
|
||||
FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK]
|
||||
| ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg))
|
||||
| S1(arg & REG_MASK) | ((arg & OFFS_REG_MASK) ? S2(OFFS_REG(arg)) : IMM(argw)),
|
||||
((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS));
|
||||
return -1;
|
||||
}
|
||||
if ((!(arg & OFFS_REG_MASK) && argw <= SIMM_MAX && argw >= SIMM_MIN)
|
||||
|| ((arg & OFFS_REG_MASK) && (argw & 0x3) == 0)) {
|
||||
/* Works for both absoulte and relative addresses (immediate case). */
|
||||
if (SLJIT_UNLIKELY(flags & ARG_TEST))
|
||||
return 1;
|
||||
FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK]
|
||||
| ((flags & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))
|
||||
| S1(arg & REG_MASK) | ((arg & OFFS_REG_MASK) ? S2(OFFS_REG(arg)) : IMM(argw)),
|
||||
((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -638,14 +651,11 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
|
||||
}
|
||||
}
|
||||
|
||||
dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : DA(reg));
|
||||
dest = ((flags & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg));
|
||||
delay_slot = ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? DR(reg) : MOVABLE_INS;
|
||||
if (!base)
|
||||
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(arg2) | IMM(0), delay_slot);
|
||||
if (!(flags & WRITE_BACK))
|
||||
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot);
|
||||
FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot));
|
||||
return push_inst(compiler, ADD | D(base) | S1(base) | S2(arg2), DR(base));
|
||||
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | dest | S1(base) | S2(arg2), delay_slot);
|
||||
}
|
||||
|
||||
static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg, sljit_sw argw)
|
||||
@ -687,7 +697,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
||||
if (FAST_IS_REG(dst)) {
|
||||
dst_r = dst;
|
||||
flags |= REG_DEST;
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOV_P)
|
||||
sugg_src2_r = dst_r;
|
||||
}
|
||||
else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, TMP_REG1, dst, dstw))
|
||||
@ -738,7 +748,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
||||
if (FAST_IS_REG(src2)) {
|
||||
src2_r = src2;
|
||||
flags |= REG2_SOURCE;
|
||||
if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_S32)
|
||||
if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOV_P)
|
||||
dst_r = src2_r;
|
||||
}
|
||||
else if (src2 & SLJIT_IMM) {
|
||||
@ -749,7 +759,7 @@ static sljit_s32 emit_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s3
|
||||
}
|
||||
else {
|
||||
src2_r = 0;
|
||||
if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_S32) && (dst & SLJIT_MEM))
|
||||
if ((op >= SLJIT_MOV && op <= SLJIT_MOV_P) && (dst & SLJIT_MEM))
|
||||
dst_r = 0;
|
||||
}
|
||||
}
|
||||
@ -875,28 +885,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
case SLJIT_MOV_S16:
|
||||
return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU:
|
||||
case SLJIT_MOVU_P:
|
||||
return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOVU_U32:
|
||||
return emit_op(compiler, SLJIT_MOV_U32, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOVU_S32:
|
||||
return emit_op(compiler, SLJIT_MOV_S32, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
|
||||
case SLJIT_MOVU_U8:
|
||||
return emit_op(compiler, SLJIT_MOV_U8, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU_S8:
|
||||
return emit_op(compiler, SLJIT_MOV_S8, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s8)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU_U16:
|
||||
return emit_op(compiler, SLJIT_MOV_U16, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_u16)srcw : srcw);
|
||||
|
||||
case SLJIT_MOVU_S16:
|
||||
return emit_op(compiler, SLJIT_MOV_S16, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_s16)srcw : srcw);
|
||||
|
||||
case SLJIT_NOT:
|
||||
case SLJIT_CLZ:
|
||||
return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
|
||||
@ -962,7 +950,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
return reg << 1;
|
||||
return freg_map[reg];
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
@ -990,10 +978,8 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
|
||||
src = TMP_FREG1;
|
||||
}
|
||||
else
|
||||
src <<= 1;
|
||||
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOI, FDTOI) | DA(TMP_FREG1) | S2A(src), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOI, FDTOI) | FD(TMP_FREG1) | FS2(src), MOVABLE_INS));
|
||||
|
||||
if (FAST_IS_REG(dst)) {
|
||||
FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA, TMP_FREG1, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET, SLJIT_MEM1(SLJIT_SP), FLOAT_TMP_MEM_OFFSET));
|
||||
@ -1008,7 +994,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_s32 dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
|
||||
sljit_s32 dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (src & SLJIT_IMM) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
@ -1027,7 +1013,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp
|
||||
}
|
||||
|
||||
FAIL_IF(emit_op_mem2(compiler, SINGLE_DATA | LOAD_DATA, TMP_FREG1, src, srcw, dst, dstw));
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FITOS, FITOD) | DA(dst_r) | S2A(TMP_FREG1), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FITOS, FITOD) | FD(dst_r) | FS2(TMP_FREG1), MOVABLE_INS));
|
||||
|
||||
if (dst & SLJIT_MEM)
|
||||
return emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG1, dst, dstw, 0, 0);
|
||||
@ -1042,17 +1028,13 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w));
|
||||
src1 = TMP_FREG1;
|
||||
}
|
||||
else
|
||||
src1 <<= 1;
|
||||
|
||||
if (src2 & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0));
|
||||
src2 = TMP_FREG2;
|
||||
}
|
||||
else
|
||||
src2 <<= 1;
|
||||
|
||||
return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | S1A(src1) | S2A(src2), FCC_IS_SET | MOVABLE_INS);
|
||||
return push_inst(compiler, SELECT_FOP(op, FCMPS, FCMPD) | FS1(src1) | FS2(src2), FCC_IS_SET | MOVABLE_INS);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
@ -1071,39 +1053,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
|
||||
if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_F32)
|
||||
op ^= SLJIT_F32_OP;
|
||||
|
||||
dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG1;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG1;
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_r, src, srcw, dst, dstw));
|
||||
src = dst_r;
|
||||
}
|
||||
else
|
||||
src <<= 1;
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_MOV_F64:
|
||||
if (src != dst_r) {
|
||||
if (dst_r != TMP_FREG1) {
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, FMOVS | FD(dst_r) | FS2(src), MOVABLE_INS));
|
||||
if (!(op & SLJIT_F32_OP))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
|
||||
}
|
||||
else
|
||||
dst_r = src;
|
||||
}
|
||||
break;
|
||||
case SLJIT_NEG_F64:
|
||||
FAIL_IF(push_inst(compiler, FNEGS | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, FNEGS | FD(dst_r) | FS2(src), MOVABLE_INS));
|
||||
if (dst_r != src && !(op & SLJIT_F32_OP))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
|
||||
break;
|
||||
case SLJIT_ABS_F64:
|
||||
FAIL_IF(push_inst(compiler, FABSS | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, FABSS | FD(dst_r) | FS2(src), MOVABLE_INS));
|
||||
if (dst_r != src && !(op & SLJIT_F32_OP))
|
||||
FAIL_IF(push_inst(compiler, FMOVS | DA(dst_r | 1) | S2A(src | 1), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, FMOVS | FDN(dst_r) | FS2N(src), MOVABLE_INS));
|
||||
break;
|
||||
case SLJIT_CONV_F64_FROM_F32:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | DA(dst_r) | S2A(src), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSTOD, FDTOS) | FD(dst_r) | FS2(src), MOVABLE_INS));
|
||||
op ^= SLJIT_F32_OP;
|
||||
break;
|
||||
}
|
||||
@ -1129,7 +1109,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
|
||||
compiler->cache_arg = 0;
|
||||
compiler->cache_argw = 0;
|
||||
|
||||
dst_r = FAST_IS_REG(dst) ? (dst << 1) : TMP_FREG2;
|
||||
dst_r = FAST_IS_REG(dst) ? dst : TMP_FREG2;
|
||||
|
||||
if (src1 & SLJIT_MEM) {
|
||||
if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) {
|
||||
@ -1138,8 +1118,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
|
||||
} else
|
||||
flags |= SLOW_SRC1;
|
||||
}
|
||||
else
|
||||
src1 <<= 1;
|
||||
|
||||
if (src2 & SLJIT_MEM) {
|
||||
if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) {
|
||||
@ -1148,8 +1126,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
|
||||
} else
|
||||
flags |= SLOW_SRC2;
|
||||
}
|
||||
else
|
||||
src2 <<= 1;
|
||||
|
||||
if ((flags & (SLOW_SRC1 | SLOW_SRC2)) == (SLOW_SRC1 | SLOW_SRC2)) {
|
||||
if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) {
|
||||
@ -1173,19 +1149,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop2(struct sljit_compiler *compil
|
||||
|
||||
switch (GET_OPCODE(op)) {
|
||||
case SLJIT_ADD_F64:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADDD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
|
||||
break;
|
||||
|
||||
case SLJIT_SUB_F64:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUBD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
|
||||
break;
|
||||
|
||||
case SLJIT_MUL_F64:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMULD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
|
||||
break;
|
||||
|
||||
case SLJIT_DIV_F64:
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | DA(dst_r) | S1A(src1) | S2A(src2), MOVABLE_INS));
|
||||
FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIVD) | FD(dst_r) | FS1(src1) | FS2(src2), MOVABLE_INS));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1223,10 +1199,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
|
||||
if (FAST_IS_REG(src))
|
||||
FAIL_IF(push_inst(compiler, OR | D(TMP_LINK) | S1(0) | S2(src), DR(TMP_LINK)));
|
||||
else if (src & SLJIT_MEM)
|
||||
else
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_LINK, src, srcw));
|
||||
else if (src & SLJIT_IMM)
|
||||
FAIL_IF(load_immediate(compiler, TMP_LINK, srcw));
|
||||
|
||||
FAIL_IF(push_inst(compiler, JMPL | D(0) | S1(TMP_LINK) | IMM(8), UNMOVABLE_INS));
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
@ -1339,21 +1313,38 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
#else
|
||||
#error "Implementation required"
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
|
||||
jump->flags |= IS_MOVABLE;
|
||||
if (type >= SLJIT_FAST_CALL)
|
||||
jump->flags |= IS_CALL;
|
||||
}
|
||||
|
||||
PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0));
|
||||
PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(TMP_REG2) | IMM(0), UNMOVABLE_INS));
|
||||
PTR_FAIL_IF(emit_const(compiler, TMP_REG1, 0));
|
||||
PTR_FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(TMP_REG1) | IMM(0), UNMOVABLE_INS));
|
||||
jump->addr = compiler->size;
|
||||
PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
|
||||
|
||||
return jump;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types)
|
||||
{
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
|
||||
|
||||
PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL));
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
|
||||
return sljit_emit_jump(compiler, type);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
struct sljit_jump *jump = NULL;
|
||||
@ -1370,17 +1361,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
||||
FAIL_IF(!jump);
|
||||
set_jump(jump, compiler, JUMP_ADDR);
|
||||
jump->u.target = srcw;
|
||||
|
||||
if ((compiler->delay_slot & DST_INS_MASK) != UNMOVABLE_INS)
|
||||
jump->flags |= IS_MOVABLE;
|
||||
if (type >= SLJIT_FAST_CALL)
|
||||
jump->flags |= IS_CALL;
|
||||
|
||||
FAIL_IF(emit_const(compiler, TMP_REG2, 0));
|
||||
src_r = TMP_REG2;
|
||||
FAIL_IF(emit_const(compiler, TMP_REG1, 0));
|
||||
src_r = TMP_REG1;
|
||||
}
|
||||
else {
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw));
|
||||
src_r = TMP_REG2;
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));
|
||||
src_r = TMP_REG1;
|
||||
}
|
||||
|
||||
FAIL_IF(push_inst(compiler, JMPL | D(type >= SLJIT_FAST_CALL ? TMP_LINK : 0) | S1(src_r) | IMM(0), UNMOVABLE_INS));
|
||||
@ -1389,6 +1381,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
||||
return push_inst(compiler, NOP, UNMOVABLE_INS);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));
|
||||
src = TMP_REG1;
|
||||
}
|
||||
|
||||
FAIL_IF(call_with_args(compiler, arg_types, &src));
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
|
||||
return sljit_emit_ijump(compiler, type, src, srcw);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 type)
|
||||
|
@ -64,29 +64,28 @@ static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_s32 size;
|
||||
sljit_s32 args, size;
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
args = get_arg_count(arg_types);
|
||||
compiler->args = args;
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
/* [esp+0] for saving temporaries and third argument for calls. */
|
||||
compiler->saveds_offset = 1 * sizeof(sljit_sw);
|
||||
#else
|
||||
/* [esp+0] for saving temporaries and space for maximum three arguments. */
|
||||
if (scratches <= 1)
|
||||
compiler->saveds_offset = 1 * sizeof(sljit_sw);
|
||||
else
|
||||
compiler->saveds_offset = ((scratches == 2) ? 2 : 3) * sizeof(sljit_sw);
|
||||
/* [esp+0] for saving temporaries and function calls. */
|
||||
compiler->stack_tmp_size = 2 * sizeof(sljit_sw);
|
||||
|
||||
#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (scratches > 3)
|
||||
compiler->stack_tmp_size = 3 * sizeof(sljit_sw);
|
||||
#endif
|
||||
|
||||
compiler->saveds_offset = compiler->stack_tmp_size;
|
||||
if (scratches > 3)
|
||||
compiler->saveds_offset += ((scratches > (3 + 6)) ? 6 : (scratches - 3)) * sizeof(sljit_sw);
|
||||
|
||||
@ -124,34 +123,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (args > 0) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | reg_map[SLJIT_R2];
|
||||
inst[0] = MOV_r_rm;
|
||||
inst[1] = MOD_REG | (reg_map[SLJIT_S0] << 3) | reg_map[SLJIT_R2];
|
||||
inst += 2;
|
||||
}
|
||||
if (args > 1) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | reg_map[SLJIT_R1];
|
||||
inst[0] = MOV_r_rm;
|
||||
inst[1] = MOD_REG | (reg_map[SLJIT_S1] << 3) | reg_map[SLJIT_R1];
|
||||
inst += 2;
|
||||
}
|
||||
if (args > 2) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | 0x4 /* esp */;
|
||||
*inst++ = 0x24;
|
||||
*inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */
|
||||
inst[0] = MOV_r_rm;
|
||||
inst[1] = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | 0x4 /* esp */;
|
||||
inst[2] = 0x24;
|
||||
inst[3] = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */
|
||||
}
|
||||
#else
|
||||
if (args > 0) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_S0] << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = sizeof(sljit_sw) * 2;
|
||||
inst[0] = MOV_r_rm;
|
||||
inst[1] = MOD_DISP8 | (reg_map[SLJIT_S0] << 3) | reg_map[TMP_REG1];
|
||||
inst[2] = sizeof(sljit_sw) * 2;
|
||||
inst += 3;
|
||||
}
|
||||
if (args > 1) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_S1] << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = sizeof(sljit_sw) * 3;
|
||||
inst[0] = MOV_r_rm;
|
||||
inst[1] = MOD_DISP8 | (reg_map[SLJIT_S1] << 3) | reg_map[TMP_REG1];
|
||||
inst[2] = sizeof(sljit_sw) * 3;
|
||||
inst += 3;
|
||||
}
|
||||
if (args > 2) {
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | reg_map[TMP_REG1];
|
||||
*inst++ = sizeof(sljit_sw) * 4;
|
||||
inst[0] = MOV_r_rm;
|
||||
inst[1] = MOD_DISP8 | (reg_map[SLJIT_S2] << 3) | reg_map[TMP_REG1];
|
||||
inst[2] = sizeof(sljit_sw) * 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -171,17 +174,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
compiler->local_size = local_size;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (local_size > 1024) {
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size));
|
||||
#else
|
||||
/* Space for a single argument. This amount is excluded when the stack is allocated below. */
|
||||
local_size -= sizeof(sljit_sw);
|
||||
FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_R0], local_size));
|
||||
FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, sizeof(sljit_sw)));
|
||||
#endif
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
|
||||
if (local_size > 0) {
|
||||
if (local_size <= 4 * 4096) {
|
||||
if (local_size > 4096)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096);
|
||||
if (local_size > 2 * 4096)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 2);
|
||||
if (local_size > 3 * 4096)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 3);
|
||||
}
|
||||
else {
|
||||
EMIT_MOV(compiler, SLJIT_R0, 0, SLJIT_SP, 0);
|
||||
EMIT_MOV(compiler, SLJIT_R1, 0, SLJIT_IMM, (local_size - 1) >> 12);
|
||||
|
||||
SLJIT_ASSERT (reg_map[SLJIT_R0] == 0);
|
||||
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_R0), -4096);
|
||||
FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
|
||||
SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 4096));
|
||||
FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
|
||||
SLJIT_R1, 0, SLJIT_R1, 0, SLJIT_IMM, 1));
|
||||
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(2);
|
||||
inst[0] = JNE_i8;
|
||||
inst[1] = (sljit_s8) -16;
|
||||
}
|
||||
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -local_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -192,12 +214,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_SP, 0);
|
||||
|
||||
/* Some space might allocated during sljit_grow_stack() above on WIN32. */
|
||||
FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
|
||||
FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size + sizeof(sljit_sw)));
|
||||
|
||||
#if defined _WIN32 && !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (compiler->local_size > 1024)
|
||||
FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
|
||||
FAIL_IF(emit_cum_binary(compiler, BINARY_OPCODE(ADD),
|
||||
TMP_REG1, 0, TMP_REG1, 0, SLJIT_IMM, sizeof(sljit_sw)));
|
||||
#endif
|
||||
|
||||
@ -213,31 +235,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), compiler->local_size, TMP_REG1, 0);
|
||||
}
|
||||
#endif
|
||||
return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
|
||||
return emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
compiler->args = args;
|
||||
compiler->args = get_arg_count(arg_types);
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
/* [esp+0] for saving temporaries and third argument for calls. */
|
||||
compiler->saveds_offset = 1 * sizeof(sljit_sw);
|
||||
#else
|
||||
/* [esp+0] for saving temporaries and space for maximum three arguments. */
|
||||
if (scratches <= 1)
|
||||
compiler->saveds_offset = 1 * sizeof(sljit_sw);
|
||||
else
|
||||
compiler->saveds_offset = ((scratches == 2) ? 2 : 3) * sizeof(sljit_sw);
|
||||
/* [esp+0] for saving temporaries and function calls. */
|
||||
compiler->stack_tmp_size = 2 * sizeof(sljit_sw);
|
||||
|
||||
#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (scratches > 3)
|
||||
compiler->stack_tmp_size = 3 * sizeof(sljit_sw);
|
||||
#endif
|
||||
|
||||
compiler->saveds_offset = compiler->stack_tmp_size;
|
||||
if (scratches > 3)
|
||||
compiler->saveds_offset += ((scratches > (3 + 6)) ? 6 : (scratches - 3)) * sizeof(sljit_sw);
|
||||
|
||||
@ -278,10 +298,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp
|
||||
if (compiler->options & SLJIT_F64_ALIGNMENT)
|
||||
EMIT_MOV(compiler, SLJIT_SP, 0, SLJIT_MEM1(SLJIT_SP), compiler->local_size)
|
||||
else
|
||||
FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
|
||||
FAIL_IF(emit_cum_binary(compiler, BINARY_OPCODE(ADD),
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
|
||||
#else
|
||||
FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
|
||||
FAIL_IF(emit_cum_binary(compiler, BINARY_OPCODE(ADD),
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));
|
||||
#endif
|
||||
|
||||
@ -418,7 +438,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32
|
||||
if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
|
||||
*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
|
||||
|
||||
if ((a & SLJIT_IMM) || (a == 0))
|
||||
if (a & SLJIT_IMM)
|
||||
*buf_ptr = 0;
|
||||
else if (!(flags & EX86_SSE2_OP1))
|
||||
*buf_ptr = reg_map[a] << 3;
|
||||
@ -490,42 +510,324 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32
|
||||
/* Call / return instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static SLJIT_INLINE sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type)
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
|
||||
static sljit_s32 c_fast_call_get_stack_size(sljit_s32 arg_types, sljit_s32 *word_arg_count_ptr)
|
||||
{
|
||||
sljit_s32 stack_size = 0;
|
||||
sljit_s32 word_arg_count = 0;
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
stack_size += sizeof(sljit_f32);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
stack_size += sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
word_arg_count++;
|
||||
if (word_arg_count > 2)
|
||||
stack_size += sizeof(sljit_sw);
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
if (word_arg_count_ptr)
|
||||
*word_arg_count_ptr = word_arg_count;
|
||||
|
||||
return stack_size;
|
||||
}
|
||||
|
||||
static sljit_s32 c_fast_call_with_args(struct sljit_compiler *compiler,
|
||||
sljit_s32 arg_types, sljit_s32 stack_size, sljit_s32 word_arg_count, sljit_s32 swap_args)
|
||||
{
|
||||
sljit_u8 *inst;
|
||||
sljit_s32 float_arg_count;
|
||||
|
||||
if (stack_size == sizeof(sljit_sw) && word_arg_count == 3) {
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
PUSH_REG(reg_map[SLJIT_R2]);
|
||||
}
|
||||
else if (stack_size > 0) {
|
||||
if (word_arg_count >= 4)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), compiler->saveds_offset - sizeof(sljit_sw));
|
||||
|
||||
FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, stack_size));
|
||||
|
||||
stack_size = 0;
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
word_arg_count = 0;
|
||||
float_arg_count = 0;
|
||||
while (arg_types) {
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
float_arg_count++;
|
||||
FAIL_IF(emit_sse2_store(compiler, 1, SLJIT_MEM1(SLJIT_SP), stack_size, float_arg_count));
|
||||
stack_size += sizeof(sljit_f32);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
float_arg_count++;
|
||||
FAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), stack_size, float_arg_count));
|
||||
stack_size += sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
word_arg_count++;
|
||||
if (word_arg_count == 3) {
|
||||
EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), stack_size, SLJIT_R2, 0);
|
||||
stack_size += sizeof(sljit_sw);
|
||||
}
|
||||
else if (word_arg_count == 4) {
|
||||
EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), stack_size, TMP_REG1, 0);
|
||||
stack_size += sizeof(sljit_sw);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
if (word_arg_count > 0) {
|
||||
if (swap_args) {
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
|
||||
*inst++ = XCHG_EAX_r | reg_map[SLJIT_R2];
|
||||
}
|
||||
else {
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(2);
|
||||
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0];
|
||||
}
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static sljit_s32 cdecl_call_get_stack_size(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *word_arg_count_ptr)
|
||||
{
|
||||
sljit_s32 stack_size = 0;
|
||||
sljit_s32 word_arg_count = 0;
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
stack_size += sizeof(sljit_f32);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
stack_size += sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
word_arg_count++;
|
||||
stack_size += sizeof(sljit_sw);
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
if (word_arg_count_ptr)
|
||||
*word_arg_count_ptr = word_arg_count;
|
||||
|
||||
if (stack_size <= compiler->stack_tmp_size)
|
||||
return 0;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
return ((stack_size - compiler->stack_tmp_size + 15) & ~15);
|
||||
#else
|
||||
return stack_size - compiler->stack_tmp_size;
|
||||
#endif
|
||||
}
|
||||
|
||||
static sljit_s32 cdecl_call_with_args(struct sljit_compiler *compiler,
|
||||
sljit_s32 arg_types, sljit_s32 stack_size, sljit_s32 word_arg_count)
|
||||
{
|
||||
sljit_s32 float_arg_count = 0;
|
||||
|
||||
if (word_arg_count >= 4)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), compiler->saveds_offset - sizeof(sljit_sw));
|
||||
|
||||
if (stack_size > 0)
|
||||
FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, stack_size));
|
||||
|
||||
stack_size = 0;
|
||||
word_arg_count = 0;
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
float_arg_count++;
|
||||
FAIL_IF(emit_sse2_store(compiler, 1, SLJIT_MEM1(SLJIT_SP), stack_size, float_arg_count));
|
||||
stack_size += sizeof(sljit_f32);
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
float_arg_count++;
|
||||
FAIL_IF(emit_sse2_store(compiler, 0, SLJIT_MEM1(SLJIT_SP), stack_size, float_arg_count));
|
||||
stack_size += sizeof(sljit_f64);
|
||||
break;
|
||||
default:
|
||||
word_arg_count++;
|
||||
EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), stack_size, (word_arg_count >= 4) ? TMP_REG1 : word_arg_count, 0);
|
||||
stack_size += sizeof(sljit_sw);
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
static sljit_s32 post_call_with_args(struct sljit_compiler *compiler,
|
||||
sljit_s32 arg_types, sljit_s32 stack_size)
|
||||
{
|
||||
sljit_u8 *inst;
|
||||
sljit_s32 single;
|
||||
|
||||
if (stack_size > 0)
|
||||
FAIL_IF(emit_cum_binary(compiler, BINARY_OPCODE(ADD),
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, stack_size));
|
||||
|
||||
if ((arg_types & SLJIT_DEF_MASK) < SLJIT_ARG_TYPE_F32)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
single = ((arg_types & SLJIT_DEF_MASK) == SLJIT_ARG_TYPE_F32);
|
||||
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 3);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(3);
|
||||
inst[0] = single ? FSTPS : FSTPD;
|
||||
inst[1] = (0x03 << 3) | 0x04;
|
||||
inst[2] = (0x04 << 3) | reg_map[SLJIT_SP];
|
||||
|
||||
return emit_sse2_load(compiler, single, SLJIT_FR0, SLJIT_MEM1(SLJIT_SP), 0);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types)
|
||||
{
|
||||
struct sljit_jump *jump;
|
||||
sljit_s32 stack_size = 0;
|
||||
sljit_s32 word_arg_count;
|
||||
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
inst = (sljit_u8*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2);
|
||||
if ((type & 0xff) == SLJIT_CALL) {
|
||||
stack_size = c_fast_call_get_stack_size(arg_types, &word_arg_count);
|
||||
PTR_FAIL_IF(c_fast_call_with_args(compiler, arg_types, stack_size, word_arg_count, 0));
|
||||
|
||||
if (type >= SLJIT_CALL3)
|
||||
PUSH_REG(reg_map[SLJIT_R2]);
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_R2] << 3) | reg_map[SLJIT_R0];
|
||||
#else
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4 * (type - SLJIT_CALL0));
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
|
||||
*inst++ = MOV_rm_r;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_R0] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
|
||||
*inst++ = 0;
|
||||
if (type >= SLJIT_CALL2) {
|
||||
*inst++ = MOV_rm_r;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_R1] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
|
||||
*inst++ = sizeof(sljit_sw);
|
||||
}
|
||||
if (type >= SLJIT_CALL3) {
|
||||
*inst++ = MOV_rm_r;
|
||||
*inst++ = MOD_DISP8 | (reg_map[SLJIT_R2] << 3) | 0x4 /* SIB */;
|
||||
*inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_SP];
|
||||
*inst++ = 2 * sizeof(sljit_sw);
|
||||
jump = sljit_emit_jump(compiler, type);
|
||||
PTR_FAIL_IF(jump == NULL);
|
||||
|
||||
PTR_FAIL_IF(post_call_with_args(compiler, arg_types, 0));
|
||||
return jump;
|
||||
}
|
||||
#endif
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
stack_size = cdecl_call_get_stack_size(compiler, arg_types, &word_arg_count);
|
||||
PTR_FAIL_IF(cdecl_call_with_args(compiler, arg_types, stack_size, word_arg_count));
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
|
||||
jump = sljit_emit_jump(compiler, type);
|
||||
PTR_FAIL_IF(jump == NULL);
|
||||
|
||||
PTR_FAIL_IF(post_call_with_args(compiler, arg_types, stack_size));
|
||||
return jump;
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_s32 stack_size = 0;
|
||||
sljit_s32 word_arg_count;
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
sljit_s32 swap_args;
|
||||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
|
||||
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
SLJIT_ASSERT(reg_map[SLJIT_R0] == 0 && reg_map[SLJIT_R2] == 1 && SLJIT_R0 == 1 && SLJIT_R2 == 3);
|
||||
|
||||
if ((type & 0xff) == SLJIT_CALL) {
|
||||
stack_size = c_fast_call_get_stack_size(arg_types, &word_arg_count);
|
||||
swap_args = 0;
|
||||
|
||||
if (word_arg_count > 0) {
|
||||
if ((src & REG_MASK) == SLJIT_R2 || OFFS_REG(src) == SLJIT_R2) {
|
||||
swap_args = 1;
|
||||
if (((src & REG_MASK) | 0x2) == SLJIT_R2)
|
||||
src ^= 0x2;
|
||||
if ((OFFS_REG(src) | 0x2) == SLJIT_R2)
|
||||
src ^= TO_OFFS_REG(0x2);
|
||||
}
|
||||
}
|
||||
|
||||
FAIL_IF(c_fast_call_with_args(compiler, arg_types, stack_size, word_arg_count, swap_args));
|
||||
|
||||
compiler->saveds_offset += stack_size;
|
||||
compiler->locals_offset += stack_size;
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
FAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));
|
||||
|
||||
compiler->saveds_offset -= stack_size;
|
||||
compiler->locals_offset -= stack_size;
|
||||
|
||||
return post_call_with_args(compiler, arg_types, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
stack_size = cdecl_call_get_stack_size(compiler, arg_types, &word_arg_count);
|
||||
FAIL_IF(cdecl_call_with_args(compiler, arg_types, stack_size, word_arg_count));
|
||||
|
||||
compiler->saveds_offset += stack_size;
|
||||
compiler->locals_offset += stack_size;
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
FAIL_IF(sljit_emit_ijump(compiler, type, src, srcw));
|
||||
|
||||
compiler->saveds_offset -= stack_size;
|
||||
compiler->locals_offset -= stack_size;
|
||||
|
||||
return post_call_with_args(compiler, arg_types, stack_size);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
@ -576,7 +878,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
INC_SIZE(1 + 1);
|
||||
PUSH_REG(reg_map[src]);
|
||||
}
|
||||
else if (src & SLJIT_MEM) {
|
||||
else {
|
||||
inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
|
||||
FAIL_IF(!inst);
|
||||
*inst++ = GROUP_FF;
|
||||
@ -586,16 +888,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
}
|
||||
else {
|
||||
/* SLJIT_IMM. */
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(5 + 1);
|
||||
*inst++ = PUSH_i32;
|
||||
sljit_unaligned_store_sw(inst, srcw);
|
||||
inst += sizeof(sljit_sw);
|
||||
}
|
||||
|
||||
RET();
|
||||
return SLJIT_SUCCESS;
|
||||
|
@ -41,24 +41,31 @@ static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg,
|
||||
|
||||
static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type)
|
||||
{
|
||||
int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && !(jump->flags & JUMP_LABEL) && (jump->u.target <= 0xffffffff);
|
||||
|
||||
/* The relative jump below specialized for this case. */
|
||||
SLJIT_ASSERT(reg_map[TMP_REG2] >= 8);
|
||||
|
||||
if (type < SLJIT_JUMP) {
|
||||
/* Invert type. */
|
||||
*code_ptr++ = get_jump_code(type ^ 0x1) - 0x10;
|
||||
*code_ptr++ = 10 + 3;
|
||||
*code_ptr++ = short_addr ? (6 + 3) : (10 + 3);
|
||||
}
|
||||
|
||||
*code_ptr++ = REX_W | ((reg_map[TMP_REG2] <= 7) ? 0 : REX_B);
|
||||
*code_ptr++ = short_addr ? REX_B : (REX_W | REX_B);
|
||||
*code_ptr++ = MOV_r_i32 | reg_lmap[TMP_REG2];
|
||||
jump->addr = (sljit_uw)code_ptr;
|
||||
|
||||
if (jump->flags & JUMP_LABEL)
|
||||
jump->flags |= PATCH_MD;
|
||||
else if (short_addr)
|
||||
sljit_unaligned_store_s32(code_ptr, (sljit_s32)jump->u.target);
|
||||
else
|
||||
sljit_unaligned_store_sw(code_ptr, jump->u.target);
|
||||
|
||||
code_ptr += sizeof(sljit_sw);
|
||||
if (reg_map[TMP_REG2] >= 8)
|
||||
*code_ptr++ = REX_B;
|
||||
code_ptr += short_addr ? sizeof(sljit_s32) : sizeof(sljit_sw);
|
||||
|
||||
*code_ptr++ = REX_B;
|
||||
*code_ptr++ = GROUP_FF;
|
||||
*code_ptr++ = MOD_REG | (type >= SLJIT_FAST_CALL ? CALL_rm : JMP_rm) | reg_lmap[TMP_REG2];
|
||||
|
||||
@ -66,15 +73,17 @@ static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_s32 i, tmp, size, saved_register_size;
|
||||
sljit_s32 args, i, tmp, size, saved_register_size;
|
||||
sljit_u8 *inst;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK(check_sljit_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_emit_enter(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
compiler->mode32 = 0;
|
||||
|
||||
#ifdef _WIN64
|
||||
/* Two/four register slots for parameters plus space for xmm6 register if needed. */
|
||||
@ -108,6 +117,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
PUSH_REG(reg_lmap[i]);
|
||||
}
|
||||
|
||||
args = get_arg_count(arg_types);
|
||||
|
||||
if (args > 0) {
|
||||
size = args * 3;
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
|
||||
@ -117,35 +128,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
|
||||
#ifndef _WIN64
|
||||
if (args > 0) {
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x7 /* rdi */;
|
||||
inst[0] = REX_W;
|
||||
inst[1] = MOV_r_rm;
|
||||
inst[2] = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x7 /* rdi */;
|
||||
inst += 3;
|
||||
}
|
||||
if (args > 1) {
|
||||
*inst++ = REX_W | REX_R;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_lmap[SLJIT_S1] << 3) | 0x6 /* rsi */;
|
||||
inst[0] = REX_W | REX_R;
|
||||
inst[1] = MOV_r_rm;
|
||||
inst[2] = MOD_REG | (reg_lmap[SLJIT_S1] << 3) | 0x6 /* rsi */;
|
||||
inst += 3;
|
||||
}
|
||||
if (args > 2) {
|
||||
*inst++ = REX_W | REX_R;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_lmap[SLJIT_S2] << 3) | 0x2 /* rdx */;
|
||||
inst[0] = REX_W | REX_R;
|
||||
inst[1] = MOV_r_rm;
|
||||
inst[2] = MOD_REG | (reg_lmap[SLJIT_S2] << 3) | 0x2 /* rdx */;
|
||||
}
|
||||
#else
|
||||
if (args > 0) {
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x1 /* rcx */;
|
||||
inst[0] = REX_W;
|
||||
inst[1] = MOV_r_rm;
|
||||
inst[2] = MOD_REG | (reg_map[SLJIT_S0] << 3) | 0x1 /* rcx */;
|
||||
inst += 3;
|
||||
}
|
||||
if (args > 1) {
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S1] << 3) | 0x2 /* rdx */;
|
||||
inst[0] = REX_W;
|
||||
inst[1] = MOV_r_rm;
|
||||
inst[2] = MOD_REG | (reg_map[SLJIT_S1] << 3) | 0x2 /* rdx */;
|
||||
inst += 3;
|
||||
}
|
||||
if (args > 2) {
|
||||
*inst++ = REX_W | REX_B;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (reg_map[SLJIT_S2] << 3) | 0x0 /* r8 */;
|
||||
inst[0] = REX_W | REX_B;
|
||||
inst[1] = MOV_r_rm;
|
||||
inst[2] = MOD_REG | (reg_map[SLJIT_S2] << 3) | 0x0 /* r8 */;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -154,58 +169,42 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
compiler->local_size = local_size;
|
||||
|
||||
#ifdef _WIN64
|
||||
if (local_size > 1024) {
|
||||
/* Allocate stack for the callback, which grows the stack. */
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_s32)));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4 + (3 + sizeof(sljit_s32)));
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_83;
|
||||
*inst++ = MOD_REG | SUB | reg_map[SLJIT_SP];
|
||||
/* Allocated size for registers must be divisible by 8. */
|
||||
SLJIT_ASSERT(!(saved_register_size & 0x7));
|
||||
/* Aligned to 16 byte. */
|
||||
if (saved_register_size & 0x8) {
|
||||
*inst++ = 5 * sizeof(sljit_sw);
|
||||
local_size -= 5 * sizeof(sljit_sw);
|
||||
} else {
|
||||
*inst++ = 4 * sizeof(sljit_sw);
|
||||
local_size -= 4 * sizeof(sljit_sw);
|
||||
if (local_size > 0) {
|
||||
if (local_size <= 4 * 4096) {
|
||||
if (local_size > 4096)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096);
|
||||
if (local_size > 2 * 4096)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 2);
|
||||
if (local_size > 3 * 4096)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -4096 * 3);
|
||||
}
|
||||
/* Second instruction */
|
||||
SLJIT_ASSERT(reg_map[SLJIT_R0] < 8);
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_rm_i32;
|
||||
*inst++ = MOD_REG | reg_lmap[SLJIT_R0];
|
||||
sljit_unaligned_store_s32(inst, local_size);
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
|
||||
else {
|
||||
EMIT_MOV(compiler, SLJIT_R0, 0, SLJIT_SP, 0);
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, (local_size - 1) >> 12);
|
||||
|
||||
SLJIT_ASSERT (reg_map[SLJIT_R0] == 0);
|
||||
|
||||
EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_MEM1(SLJIT_R0), -4096);
|
||||
FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
|
||||
SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, 4096));
|
||||
FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
|
||||
TMP_REG1, 0, TMP_REG1, 0, SLJIT_IMM, 1));
|
||||
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(2);
|
||||
inst[0] = JNE_i8;
|
||||
inst[1] = (sljit_s8) -19;
|
||||
}
|
||||
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_MEM1(SLJIT_SP), -local_size);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (local_size > 0) {
|
||||
if (local_size <= 127) {
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(4);
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_83;
|
||||
*inst++ = MOD_REG | SUB | reg_map[SLJIT_SP];
|
||||
*inst++ = local_size;
|
||||
}
|
||||
else {
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 7);
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(7);
|
||||
*inst++ = REX_W;
|
||||
*inst++ = GROUP_BINARY_81;
|
||||
*inst++ = MOD_REG | SUB | reg_map[SLJIT_SP];
|
||||
sljit_unaligned_store_s32(inst, local_size);
|
||||
inst += sizeof(sljit_s32);
|
||||
}
|
||||
FAIL_IF(emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
|
||||
SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, local_size));
|
||||
}
|
||||
|
||||
#ifdef _WIN64
|
||||
@ -223,14 +222,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *compiler,
|
||||
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
|
||||
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
|
||||
{
|
||||
sljit_s32 saved_register_size;
|
||||
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, args, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
CHECK(check_sljit_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size));
|
||||
set_set_context(compiler, options, arg_types, scratches, saveds, fscratches, fsaveds, local_size);
|
||||
|
||||
#ifdef _WIN64
|
||||
/* Two/four register slots for parameters plus space for xmm6 register if needed. */
|
||||
@ -414,7 +413,11 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(flags & EX86_SSE2_OP2) && reg_map[b] >= 8)
|
||||
else if (!(flags & EX86_SSE2_OP2)) {
|
||||
if (reg_map[b] >= 8)
|
||||
rex |= REX_B;
|
||||
}
|
||||
else if (freg_map[b] >= 8)
|
||||
rex |= REX_B;
|
||||
|
||||
if (a & SLJIT_IMM) {
|
||||
@ -441,7 +444,11 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32
|
||||
else {
|
||||
SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG);
|
||||
/* reg_map[SLJIT_PREF_SHIFT_REG] is less than 8. */
|
||||
if (!(flags & EX86_SSE2_OP1) && reg_map[a] >= 8)
|
||||
if (!(flags & EX86_SSE2_OP1)) {
|
||||
if (reg_map[a] >= 8)
|
||||
rex |= REX_R;
|
||||
}
|
||||
else if (freg_map[a] >= 8)
|
||||
rex |= REX_R;
|
||||
}
|
||||
|
||||
@ -468,12 +475,12 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32
|
||||
if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM))
|
||||
*inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81;
|
||||
|
||||
if ((a & SLJIT_IMM) || (a == 0))
|
||||
if (a & SLJIT_IMM)
|
||||
*buf_ptr = 0;
|
||||
else if (!(flags & EX86_SSE2_OP1))
|
||||
*buf_ptr = reg_lmap[a] << 3;
|
||||
else
|
||||
*buf_ptr = a << 3;
|
||||
*buf_ptr = freg_lmap[a] << 3;
|
||||
}
|
||||
else {
|
||||
if (a & SLJIT_IMM) {
|
||||
@ -487,7 +494,7 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32
|
||||
}
|
||||
|
||||
if (!(b & SLJIT_MEM))
|
||||
*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_lmap[b] : b);
|
||||
*buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2_OP2)) ? reg_lmap[b] : freg_lmap[b]);
|
||||
else if ((b & REG_MASK) != SLJIT_UNUSED) {
|
||||
if ((b & OFFS_REG_MASK) == SLJIT_UNUSED || (b & OFFS_REG_MASK) == TO_OFFS_REG(SLJIT_SP)) {
|
||||
if (immb != 0 || reg_lmap[b & REG_MASK] == 5) {
|
||||
@ -545,45 +552,161 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_s32
|
||||
/* Call / return instructions */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 type)
|
||||
{
|
||||
sljit_u8 *inst;
|
||||
|
||||
/* After any change update IS_REG_CHANGED_BY_CALL as well. */
|
||||
#ifndef _WIN64
|
||||
SLJIT_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8 && reg_map[TMP_REG1] == 2);
|
||||
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
|
||||
if (type >= SLJIT_CALL3) {
|
||||
/* Move third argument to TMP_REG1. */
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_R2];
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src_ptr, sljit_sw srcw)
|
||||
{
|
||||
sljit_s32 src = src_ptr ? (*src_ptr) : 0;
|
||||
sljit_s32 word_arg_count = 0;
|
||||
|
||||
SLJIT_ASSERT(reg_map[SLJIT_R1] == 6 && reg_map[SLJIT_R3] == 1 && reg_map[TMP_REG1] == 2);
|
||||
|
||||
compiler->mode32 = 0;
|
||||
|
||||
/* Remove return value. */
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
if ((arg_types & SLJIT_DEF_MASK) < SLJIT_ARG_TYPE_F32)
|
||||
word_arg_count++;
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_R0];
|
||||
|
||||
if (word_arg_count == 0)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
EMIT_MOV(compiler, TMP_REG2, 0, src, srcw);
|
||||
*src_ptr = TMP_REG2;
|
||||
}
|
||||
else if (src == SLJIT_R2 && word_arg_count >= SLJIT_R2)
|
||||
*src_ptr = TMP_REG1;
|
||||
|
||||
if (word_arg_count >= 3)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R2, 0);
|
||||
return emit_mov(compiler, SLJIT_R2, 0, SLJIT_R0, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
SLJIT_ASSERT(reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R0] < 8 && reg_map[SLJIT_R2] < 8 && reg_map[TMP_REG1] == 8);
|
||||
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6));
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE((type < SLJIT_CALL3) ? 3 : 6);
|
||||
if (type >= SLJIT_CALL3) {
|
||||
/* Move third argument to TMP_REG1. */
|
||||
*inst++ = REX_W | REX_R;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_R2];
|
||||
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_s32 *src_ptr, sljit_sw srcw)
|
||||
{
|
||||
sljit_s32 src = src_ptr ? (*src_ptr) : 0;
|
||||
sljit_s32 arg_count = 0;
|
||||
sljit_s32 word_arg_count = 0;
|
||||
sljit_s32 float_arg_count = 0;
|
||||
sljit_s32 types = 0;
|
||||
sljit_s32 data_trandfer = 0;
|
||||
static sljit_u8 word_arg_regs[5] = { 0, SLJIT_R3, SLJIT_R1, SLJIT_R2, TMP_REG1 };
|
||||
|
||||
SLJIT_ASSERT(reg_map[SLJIT_R3] == 1 && reg_map[SLJIT_R1] == 2 && reg_map[SLJIT_R2] == 8 && reg_map[TMP_REG1] == 9);
|
||||
|
||||
compiler->mode32 = 0;
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
|
||||
while (arg_types) {
|
||||
types = (types << SLJIT_DEF_SHIFT) | (arg_types & SLJIT_DEF_MASK);
|
||||
|
||||
switch (arg_types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
arg_count++;
|
||||
float_arg_count++;
|
||||
|
||||
if (arg_count != float_arg_count)
|
||||
data_trandfer = 1;
|
||||
break;
|
||||
default:
|
||||
arg_count++;
|
||||
word_arg_count++;
|
||||
|
||||
if (arg_count != word_arg_count || arg_count != word_arg_regs[arg_count]) {
|
||||
data_trandfer = 1;
|
||||
|
||||
if (src == word_arg_regs[arg_count]) {
|
||||
EMIT_MOV(compiler, TMP_REG2, 0, src, 0);
|
||||
*src_ptr = TMP_REG2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
arg_types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
*inst++ = REX_W;
|
||||
*inst++ = MOV_r_rm;
|
||||
*inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_R0];
|
||||
#endif
|
||||
|
||||
if (!data_trandfer)
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
if (src & SLJIT_MEM) {
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
EMIT_MOV(compiler, TMP_REG2, 0, src, srcw);
|
||||
*src_ptr = TMP_REG2;
|
||||
}
|
||||
|
||||
while (types) {
|
||||
switch (types & SLJIT_DEF_MASK) {
|
||||
case SLJIT_ARG_TYPE_F32:
|
||||
if (arg_count != float_arg_count)
|
||||
FAIL_IF(emit_sse2_load(compiler, 1, arg_count, float_arg_count, 0));
|
||||
arg_count--;
|
||||
float_arg_count--;
|
||||
break;
|
||||
case SLJIT_ARG_TYPE_F64:
|
||||
if (arg_count != float_arg_count)
|
||||
FAIL_IF(emit_sse2_load(compiler, 0, arg_count, float_arg_count, 0));
|
||||
arg_count--;
|
||||
float_arg_count--;
|
||||
break;
|
||||
default:
|
||||
if (arg_count != word_arg_count || arg_count != word_arg_regs[arg_count])
|
||||
EMIT_MOV(compiler, word_arg_regs[arg_count], 0, word_arg_count, 0);
|
||||
arg_count--;
|
||||
word_arg_count--;
|
||||
break;
|
||||
}
|
||||
|
||||
types >>= SLJIT_DEF_SHIFT;
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types)
|
||||
{
|
||||
CHECK_ERROR_PTR();
|
||||
CHECK_PTR(check_sljit_emit_call(compiler, type, arg_types));
|
||||
|
||||
PTR_FAIL_IF(call_with_args(compiler, arg_types, NULL, 0));
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
|
||||
return sljit_emit_jump(compiler, type);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
|
||||
sljit_s32 arg_types,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
CHECK_ERROR();
|
||||
CHECK(check_sljit_emit_icall(compiler, type, arg_types, src, srcw));
|
||||
|
||||
FAIL_IF(call_with_args(compiler, arg_types, &src, srcw));
|
||||
|
||||
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
|
||||
|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
|
||||
compiler->skip_checks = 1;
|
||||
#endif
|
||||
|
||||
return sljit_emit_ijump(compiler, type, src, srcw);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
|
||||
{
|
||||
sljit_u8 *inst;
|
||||
@ -629,11 +752,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) {
|
||||
FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw));
|
||||
src = TMP_REG1;
|
||||
}
|
||||
|
||||
if (FAST_IS_REG(src)) {
|
||||
if (reg_map[src] < 8) {
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
|
||||
@ -651,7 +769,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
PUSH_REG(reg_lmap[src]);
|
||||
}
|
||||
}
|
||||
else if (src & SLJIT_MEM) {
|
||||
else {
|
||||
/* REX_W is not necessary (src is not immediate). */
|
||||
compiler->mode32 = 1;
|
||||
inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
|
||||
@ -663,23 +781,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler
|
||||
FAIL_IF(!inst);
|
||||
INC_SIZE(1);
|
||||
}
|
||||
else {
|
||||
SLJIT_ASSERT(IS_HALFWORD(srcw));
|
||||
/* SLJIT_IMM. */
|
||||
inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1);
|
||||
FAIL_IF(!inst);
|
||||
|
||||
INC_SIZE(5 + 1);
|
||||
*inst++ = PUSH_i32;
|
||||
sljit_unaligned_store_s32(inst, srcw);
|
||||
inst += sizeof(sljit_s32);
|
||||
}
|
||||
|
||||
RET();
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/* Extend input */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
@ -26,7 +26,11 @@
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
{
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
return "x86" SLJIT_CPUINFO " ABI:fastcall";
|
||||
#else
|
||||
return "x86" SLJIT_CPUINFO;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -35,7 +39,7 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
1 - ECX
|
||||
2 - EDX
|
||||
3 - EBX
|
||||
4 - none
|
||||
4 - ESP
|
||||
5 - EBP
|
||||
6 - ESI
|
||||
7 - EDI
|
||||
@ -47,7 +51,7 @@ SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
|
||||
1 - RCX
|
||||
2 - RDX
|
||||
3 - RBX
|
||||
4 - none
|
||||
4 - RSP
|
||||
5 - RBP
|
||||
6 - RSI
|
||||
7 - RDI
|
||||
@ -92,23 +96,32 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 3] = {
|
||||
#ifndef _WIN64
|
||||
/* Args: rdi(=7), rsi(=6), rdx(=2), rcx(=1), r8, r9. Scratches: rax(=0), r10, r11 */
|
||||
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
|
||||
0, 0, 6, 1, 7, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 9
|
||||
0, 0, 6, 7, 1, 8, 11, 10, 12, 5, 13, 14, 15, 3, 4, 2, 9
|
||||
};
|
||||
/* low-map. reg_map & 0x7. */
|
||||
static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = {
|
||||
0, 0, 6, 1, 7, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 1
|
||||
0, 0, 6, 7, 1, 0, 3, 2, 4, 5, 5, 6, 7, 3, 4, 2, 1
|
||||
};
|
||||
#else
|
||||
/* Args: rcx(=1), rdx(=2), r8, r9. Scratches: rax(=0), r10, r11 */
|
||||
static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 4] = {
|
||||
0, 0, 2, 1, 10, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 8, 9
|
||||
0, 0, 2, 8, 1, 11, 12, 5, 13, 14, 15, 7, 6, 3, 4, 9, 10
|
||||
};
|
||||
/* low-map. reg_map & 0x7. */
|
||||
static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = {
|
||||
0, 0, 2, 1, 2, 3, 4, 5, 5, 6, 7, 7, 6, 3, 4, 0, 1
|
||||
0, 0, 2, 0, 1, 3, 4, 5, 5, 6, 7, 7, 6, 3, 4, 1, 2
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Args: xmm0-xmm3 */
|
||||
static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
|
||||
4, 0, 1, 2, 3, 5, 6
|
||||
};
|
||||
/* low-map. freg_map & 0x7. */
|
||||
static const sljit_u8 freg_lmap[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1] = {
|
||||
4, 0, 1, 2, 3, 5, 6
|
||||
};
|
||||
|
||||
#define REX_W 0x48
|
||||
#define REX_R 0x44
|
||||
#define REX_X 0x42
|
||||
@ -178,6 +191,8 @@ static const sljit_u8 reg_lmap[SLJIT_NUMBER_OF_REGISTERS + 4] = {
|
||||
#define CVTTSD2SI_r_xm 0x2c
|
||||
#define DIV (/* GROUP_F7 */ 6 << 3)
|
||||
#define DIVSD_x_xm 0x5e
|
||||
#define FSTPS 0xd9
|
||||
#define FSTPD 0xdd
|
||||
#define INT3 0xcc
|
||||
#define IDIV (/* GROUP_F7 */ 7 << 3)
|
||||
#define IMUL (/* GROUP_F7 */ 5 << 3)
|
||||
@ -462,11 +477,7 @@ static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code
|
||||
code_ptr += sizeof(sljit_s8);
|
||||
} else {
|
||||
jump->flags |= PATCH_MW;
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
code_ptr += sizeof(sljit_sw);
|
||||
#else
|
||||
code_ptr += sizeof(sljit_s32);
|
||||
#endif
|
||||
}
|
||||
|
||||
return code_ptr;
|
||||
@ -613,9 +624,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
get_cpu_features();
|
||||
return cpu_has_cmov;
|
||||
|
||||
case SLJIT_HAS_PREF_SHIFT_REG:
|
||||
return 1;
|
||||
|
||||
case SLJIT_HAS_SSE2:
|
||||
#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
|
||||
if (cpu_has_sse2 == -1)
|
||||
@ -634,14 +642,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
|
||||
/* Operators */
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define BINARY_OPCODE(opcode) (((opcode ## _EAX_i32) << 24) | ((opcode ## _r_rm) << 16) | ((opcode ## _rm_r) << 8) | (opcode))
|
||||
|
||||
static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler,
|
||||
sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
|
||||
sljit_u32 op_types,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w);
|
||||
|
||||
static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler,
|
||||
sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
|
||||
sljit_u32 op_types,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w);
|
||||
@ -653,22 +663,11 @@ static sljit_s32 emit_mov(struct sljit_compiler *compiler,
|
||||
#define EMIT_MOV(compiler, dst, dstw, src, srcw) \
|
||||
FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw));
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <malloc.h>
|
||||
static SLJIT_INLINE sljit_s32 emit_sse2_store(struct sljit_compiler *compiler,
|
||||
sljit_s32 single, sljit_s32 dst, sljit_sw dstw, sljit_s32 src);
|
||||
|
||||
static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size)
|
||||
{
|
||||
/* Workaround for calling the internal _chkstk() function on Windows.
|
||||
This function touches all 4k pages belongs to the requested stack space,
|
||||
which size is passed in local_size. This is necessary on Windows where
|
||||
the stack can only grow in 4k steps. However, this function just burn
|
||||
CPU cycles if the stack is large enough. However, you don't know it in
|
||||
advance, so it must always be called. I think this is a bad design in
|
||||
general even if it has some reasons. */
|
||||
*(volatile sljit_s32*)alloca(local_size) = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
static SLJIT_INLINE sljit_s32 emit_sse2_load(struct sljit_compiler *compiler,
|
||||
sljit_s32 single, sljit_s32 dst, sljit_s32 src, sljit_sw srcw);
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
#include "sljitNativeX86_32.c"
|
||||
@ -1115,7 +1114,7 @@ static sljit_s32 emit_unary(struct sljit_compiler *compiler, sljit_u8 opcode,
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED))
|
||||
dst = TMP_REG1;
|
||||
|
||||
if (FAST_IS_REG(dst)) {
|
||||
@ -1182,12 +1181,6 @@ static sljit_s32 emit_clz(struct sljit_compiler *compiler, sljit_s32 op_flags,
|
||||
|
||||
SLJIT_UNUSED_ARG(op_flags);
|
||||
|
||||
if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw);
|
||||
src = TMP_REG1;
|
||||
srcw = 0;
|
||||
}
|
||||
|
||||
if (cpu_has_cmov == -1)
|
||||
get_cpu_features();
|
||||
|
||||
@ -1242,13 +1235,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_s32 update = 0;
|
||||
sljit_s32 op_flags = GET_ALL_FLAGS(op);
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
sljit_s32 dst_is_ereg = 0;
|
||||
sljit_s32 src_is_ereg = 0;
|
||||
#else
|
||||
# define src_is_ereg 0
|
||||
#endif
|
||||
|
||||
CHECK_ERROR();
|
||||
@ -1257,7 +1246,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
ADJUST_LOCAL_OFFSET(src, srcw);
|
||||
|
||||
CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
|
||||
CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
|
||||
CHECK_EXTRA_REGS(src, srcw, (void)0);
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
compiler->mode32 = op_flags & SLJIT_I32_OP;
|
||||
#endif
|
||||
@ -1270,32 +1259,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
|
||||
op = GET_OPCODE(op);
|
||||
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
|
||||
if (op >= SLJIT_MOV && op <= SLJIT_MOV_P) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
compiler->mode32 = 0;
|
||||
#endif
|
||||
|
||||
if (op_flags & SLJIT_I32_OP) {
|
||||
if (FAST_IS_REG(src) && src == dst) {
|
||||
if (!TYPE_CAST_NEEDED(op))
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (op == SLJIT_MOV_S32 && (src & SLJIT_MEM))
|
||||
op = SLJIT_MOV_U32;
|
||||
if (op == SLJIT_MOVU_S32 && (src & SLJIT_MEM))
|
||||
op = SLJIT_MOVU_U32;
|
||||
if (op == SLJIT_MOV_U32 && (src & SLJIT_IMM))
|
||||
op = SLJIT_MOV_S32;
|
||||
if (op == SLJIT_MOVU_U32 && (src & SLJIT_IMM))
|
||||
op = SLJIT_MOVU_S32;
|
||||
#endif
|
||||
if (FAST_IS_REG(src) && src == dst) {
|
||||
if (!TYPE_CAST_NEEDED(op))
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
SLJIT_COMPILE_ASSERT(SLJIT_MOV + 8 == SLJIT_MOVU, movu_offset);
|
||||
if (op >= SLJIT_MOVU) {
|
||||
update = 1;
|
||||
op -= 8;
|
||||
if (op_flags & SLJIT_I32_OP) {
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
if (src & SLJIT_MEM) {
|
||||
if (op == SLJIT_MOV_S32)
|
||||
op = SLJIT_MOV_U32;
|
||||
}
|
||||
else if (src & SLJIT_IMM) {
|
||||
if (op == SLJIT_MOV_U32)
|
||||
op = SLJIT_MOV_S32;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (src & SLJIT_IMM) {
|
||||
@ -1369,28 +1353,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
if (SLJIT_UNLIKELY(dst_is_ereg) && dst == TMP_REG1)
|
||||
return emit_mov(compiler, SLJIT_MEM1(SLJIT_SP), dstw, TMP_REG1, 0);
|
||||
#endif
|
||||
|
||||
if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & REG_MASK)) {
|
||||
if ((src & OFFS_REG_MASK) != 0) {
|
||||
FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
|
||||
(src & REG_MASK), 0, (src & REG_MASK), 0, OFFS_REG(dst), 0));
|
||||
}
|
||||
else if (srcw != 0) {
|
||||
FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
|
||||
(src & REG_MASK), 0, (src & REG_MASK), 0, SLJIT_IMM, srcw));
|
||||
}
|
||||
}
|
||||
|
||||
if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & REG_MASK)) {
|
||||
if ((dst & OFFS_REG_MASK) != 0) {
|
||||
FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
|
||||
(dst & REG_MASK), 0, (dst & REG_MASK), 0, OFFS_REG(dst), 0));
|
||||
}
|
||||
else if (dstw != 0) {
|
||||
FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
|
||||
(dst & REG_MASK), 0, (dst & REG_MASK), 0, SLJIT_IMM, dstw));
|
||||
}
|
||||
}
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -1408,10 +1370,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
# undef src_is_ereg
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
@ -1445,12 +1403,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
|
||||
#endif
|
||||
|
||||
static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler,
|
||||
sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
|
||||
sljit_u32 op_types,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_u8* inst;
|
||||
sljit_u8 op_eax_imm = (op_types >> 24);
|
||||
sljit_u8 op_rm = (op_types >> 16) & 0xff;
|
||||
sljit_u8 op_mr = (op_types >> 8) & 0xff;
|
||||
sljit_u8 op_imm = op_types & 0xff;
|
||||
|
||||
if (dst == SLJIT_UNUSED) {
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
|
||||
@ -1561,12 +1523,16 @@ static sljit_s32 emit_cum_binary(struct sljit_compiler *compiler,
|
||||
}
|
||||
|
||||
static sljit_s32 emit_non_cum_binary(struct sljit_compiler *compiler,
|
||||
sljit_u8 op_rm, sljit_u8 op_mr, sljit_u8 op_imm, sljit_u8 op_eax_imm,
|
||||
sljit_u32 op_types,
|
||||
sljit_s32 dst, sljit_sw dstw,
|
||||
sljit_s32 src1, sljit_sw src1w,
|
||||
sljit_s32 src2, sljit_sw src2w)
|
||||
{
|
||||
sljit_u8* inst;
|
||||
sljit_u8 op_eax_imm = (op_types >> 24);
|
||||
sljit_u8 op_rm = (op_types >> 16) & 0xff;
|
||||
sljit_u8 op_mr = (op_types >> 8) & 0xff;
|
||||
sljit_u8 op_imm = op_types & 0xff;
|
||||
|
||||
if (dst == SLJIT_UNUSED) {
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
|
||||
@ -2044,7 +2010,7 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler,
|
||||
*inst |= mode;
|
||||
EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
|
||||
}
|
||||
else if (FAST_IS_REG(dst) && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
|
||||
else if (SLOW_IS_REG(dst) && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) {
|
||||
if (src1 != dst)
|
||||
EMIT_MOV(compiler, dst, 0, src1, src1w);
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_PREF_SHIFT_REG, 0);
|
||||
@ -2057,27 +2023,24 @@ static sljit_s32 emit_shift(struct sljit_compiler *compiler,
|
||||
else {
|
||||
/* This case is complex since ecx itself may be used for
|
||||
addressing, and this case must be supported as well. */
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_PREF_SHIFT_REG, 0);
|
||||
EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
|
||||
inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
|
||||
FAIL_IF(!inst);
|
||||
*inst |= mode;
|
||||
EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_SP), 0);
|
||||
EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
|
||||
#else
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
|
||||
EMIT_MOV(compiler, TMP_REG2, 0, src2, src2w);
|
||||
inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
|
||||
FAIL_IF(!inst);
|
||||
*inst = XCHG_r_rm;
|
||||
EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
|
||||
EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
|
||||
inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REG1, 0);
|
||||
FAIL_IF(!inst);
|
||||
*inst |= mode;
|
||||
EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
|
||||
EMIT_MOV(compiler, dst, dstw, TMP_REG1, 0);
|
||||
#endif
|
||||
if (dst != SLJIT_UNUSED)
|
||||
return emit_mov(compiler, dst, dstw, TMP_REG1, 0);
|
||||
}
|
||||
|
||||
return SLJIT_SUCCESS;
|
||||
@ -2101,7 +2064,7 @@ static sljit_s32 emit_shift_with_flags(struct sljit_compiler *compiler,
|
||||
if (!set_flags)
|
||||
return emit_mov(compiler, dst, dstw, src1, src1w);
|
||||
/* OR dst, src, 0 */
|
||||
return emit_cum_binary(compiler, OR_r_rm, OR_rm_r, OR, OR_EAX_i32,
|
||||
return emit_cum_binary(compiler, BINARY_OPCODE(OR),
|
||||
dst, dstw, src1, src1w, SLJIT_IMM, 0);
|
||||
}
|
||||
|
||||
@ -2111,10 +2074,10 @@ static sljit_s32 emit_shift_with_flags(struct sljit_compiler *compiler,
|
||||
if (!FAST_IS_REG(dst))
|
||||
FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0));
|
||||
|
||||
FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w));
|
||||
FAIL_IF(emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w));
|
||||
|
||||
if (FAST_IS_REG(dst))
|
||||
return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
|
||||
return emit_cmp_binary(compiler, (dst == SLJIT_UNUSED) ? TMP_REG1 : dst, dstw, SLJIT_IMM, 0);
|
||||
return SLJIT_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2145,10 +2108,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
|
||||
return compiler->error;
|
||||
}
|
||||
return emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
|
||||
return emit_cum_binary(compiler, BINARY_OPCODE(ADD),
|
||||
dst, dstw, src1, src1w, src2, src2w);
|
||||
case SLJIT_ADDC:
|
||||
return emit_cum_binary(compiler, ADC_r_rm, ADC_rm_r, ADC, ADC_EAX_i32,
|
||||
return emit_cum_binary(compiler, BINARY_OPCODE(ADC),
|
||||
dst, dstw, src1, src1w, src2, src2w);
|
||||
case SLJIT_SUB:
|
||||
if (!HAS_FLAGS(op)) {
|
||||
@ -2158,23 +2121,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
|
||||
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return emit_cmp_binary(compiler, src1, src1w, src2, src2w);
|
||||
return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
|
||||
return emit_non_cum_binary(compiler, BINARY_OPCODE(SUB),
|
||||
dst, dstw, src1, src1w, src2, src2w);
|
||||
case SLJIT_SUBC:
|
||||
return emit_non_cum_binary(compiler, SBB_r_rm, SBB_rm_r, SBB, SBB_EAX_i32,
|
||||
return emit_non_cum_binary(compiler, BINARY_OPCODE(SBB),
|
||||
dst, dstw, src1, src1w, src2, src2w);
|
||||
case SLJIT_MUL:
|
||||
return emit_mul(compiler, dst, dstw, src1, src1w, src2, src2w);
|
||||
case SLJIT_AND:
|
||||
if (dst == SLJIT_UNUSED)
|
||||
return emit_test_binary(compiler, src1, src1w, src2, src2w);
|
||||
return emit_cum_binary(compiler, AND_r_rm, AND_rm_r, AND, AND_EAX_i32,
|
||||
return emit_cum_binary(compiler, BINARY_OPCODE(AND),
|
||||
dst, dstw, src1, src1w, src2, src2w);
|
||||
case SLJIT_OR:
|
||||
return emit_cum_binary(compiler, OR_r_rm, OR_rm_r, OR, OR_EAX_i32,
|
||||
return emit_cum_binary(compiler, BINARY_OPCODE(OR),
|
||||
dst, dstw, src1, src1w, src2, src2w);
|
||||
case SLJIT_XOR:
|
||||
return emit_cum_binary(compiler, XOR_r_rm, XOR_rm_r, XOR, XOR_EAX_i32,
|
||||
return emit_cum_binary(compiler, BINARY_OPCODE(XOR),
|
||||
dst, dstw, src1, src1w, src2, src2w);
|
||||
case SLJIT_SHL:
|
||||
return emit_shift_with_flags(compiler, SHL, HAS_FLAGS(op),
|
||||
@ -2203,7 +2166,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_register_index(sljit_s32 reg)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_float_register_index(sljit_s32 reg)
|
||||
{
|
||||
CHECK_REG_INDEX(check_sljit_get_float_register_index(reg));
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
return reg;
|
||||
#else
|
||||
return freg_map[reg];
|
||||
#endif
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *compiler,
|
||||
@ -2345,6 +2312,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile
|
||||
FAIL_IF(emit_sse2_load(compiler, op & SLJIT_F32_OP, TMP_FREG, src1, src1w));
|
||||
src1 = TMP_FREG;
|
||||
}
|
||||
|
||||
return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_F32_OP), src1, src2, src2w);
|
||||
}
|
||||
|
||||
@ -2516,9 +2484,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
|
||||
type &= 0xff;
|
||||
|
||||
if (type >= SLJIT_CALL1)
|
||||
PTR_FAIL_IF(call_with_args(compiler, type));
|
||||
|
||||
/* Worst case size. */
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
compiler->size += (type >= SLJIT_JUMP) ? 5 : 6;
|
||||
@ -2534,14 +2499,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
|
||||
return jump;
|
||||
}
|
||||
|
||||
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
|
||||
#ifndef _WIN64
|
||||
#define IS_REG_CHANGED_BY_CALL(src, type) ((src) == SLJIT_R3)
|
||||
#else
|
||||
#define IS_REG_CHANGED_BY_CALL(src, type) ((src) == SLJIT_R2)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
|
||||
{
|
||||
sljit_u8 *inst;
|
||||
@ -2553,25 +2510,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
|
||||
|
||||
CHECK_EXTRA_REGS(src, srcw, (void)0);
|
||||
|
||||
if (type >= SLJIT_CALL1) {
|
||||
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
|
||||
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
|
||||
if (src == SLJIT_R2) {
|
||||
EMIT_MOV(compiler, TMP_REG1, 0, src, 0);
|
||||
src = TMP_REG1;
|
||||
}
|
||||
if (src == SLJIT_MEM1(SLJIT_SP) && type >= SLJIT_CALL3)
|
||||
srcw += sizeof(sljit_sw);
|
||||
#endif
|
||||
#else
|
||||
if ((src & SLJIT_MEM) || IS_REG_CHANGED_BY_CALL(src, type)) {
|
||||
EMIT_MOV(compiler, TMP_REG2, 0, src, srcw);
|
||||
src = TMP_REG2;
|
||||
}
|
||||
#endif
|
||||
FAIL_IF(call_with_args(compiler, type));
|
||||
}
|
||||
|
||||
if (src == SLJIT_IMM) {
|
||||
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
|
||||
FAIL_IF_NULL(jump);
|
||||
|
@ -48,12 +48,12 @@ static SLJIT_INLINE void allocator_release_lock(void)
|
||||
|
||||
#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
|
||||
{
|
||||
/* Always successful. */
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
|
||||
{
|
||||
/* Always successful. */
|
||||
}
|
||||
@ -88,7 +88,7 @@ static SLJIT_INLINE void allocator_release_lock(void)
|
||||
|
||||
static HANDLE global_mutex = 0;
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
|
||||
{
|
||||
/* No idea what to do if an error occures. Static mutexes should never fail... */
|
||||
if (!global_mutex)
|
||||
@ -97,7 +97,7 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
|
||||
WaitForSingleObject(global_mutex, INFINITE);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
|
||||
{
|
||||
ReleaseMutex(global_mutex);
|
||||
}
|
||||
@ -130,12 +130,12 @@ static SLJIT_INLINE void allocator_release_lock(void)
|
||||
|
||||
static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_grab_lock(void)
|
||||
{
|
||||
pthread_mutex_lock(&global_mutex);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
|
||||
{
|
||||
pthread_mutex_unlock(&global_mutex);
|
||||
}
|
||||
@ -203,7 +203,7 @@ static SLJIT_INLINE sljit_s32 open_dev_zero(void)
|
||||
/* Planning to make it even more clever in the future. */
|
||||
static sljit_sw sljit_page_align = 0;
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit, void *allocator_data)
|
||||
SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_FUNC sljit_allocate_stack(sljit_uw start_size, sljit_uw max_size, void *allocator_data)
|
||||
{
|
||||
struct sljit_stack *stack;
|
||||
void *ptr;
|
||||
@ -212,7 +212,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj
|
||||
#endif
|
||||
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
if (limit > max_limit || limit < 1)
|
||||
if (start_size > max_size || start_size < 1)
|
||||
return NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -234,25 +234,27 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj
|
||||
if (!stack)
|
||||
return NULL;
|
||||
|
||||
/* Align max_limit. */
|
||||
max_limit = (max_limit + sljit_page_align) & ~sljit_page_align;
|
||||
/* Align max_size. */
|
||||
max_size = (max_size + sljit_page_align) & ~sljit_page_align;
|
||||
|
||||
#ifdef _WIN32
|
||||
ptr = VirtualAlloc(NULL, max_limit, MEM_RESERVE, PAGE_READWRITE);
|
||||
ptr = VirtualAlloc(NULL, max_size, MEM_RESERVE, PAGE_READWRITE);
|
||||
if (!ptr) {
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
return NULL;
|
||||
}
|
||||
stack->max_limit = (sljit_u8 *)ptr;
|
||||
stack->base = stack->max_limit + max_limit;
|
||||
stack->limit = stack->base;
|
||||
if (sljit_stack_resize(stack, stack->base - limit)) {
|
||||
|
||||
stack->min_start = (sljit_u8 *)ptr;
|
||||
stack->end = stack->min_start + max_size;
|
||||
stack->start = stack->end;
|
||||
|
||||
if (sljit_stack_resize(stack, stack->end - start_size) == NULL) {
|
||||
sljit_free_stack(stack, allocator_data);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
#ifdef MAP_ANON
|
||||
ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
#else
|
||||
if (dev_zero < 0) {
|
||||
if (open_dev_zero()) {
|
||||
@ -260,73 +262,70 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
|
||||
ptr = mmap(NULL, max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0);
|
||||
#endif
|
||||
if (ptr == MAP_FAILED) {
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
return NULL;
|
||||
}
|
||||
stack->max_limit = (sljit_u8 *)ptr;
|
||||
stack->base = stack->max_limit + max_limit;
|
||||
stack->limit = stack->base - limit;
|
||||
stack->min_start = (sljit_u8 *)ptr;
|
||||
stack->end = stack->min_start + max_size;
|
||||
stack->start = stack->end - start_size;
|
||||
#endif
|
||||
stack->top = stack->base;
|
||||
stack->top = stack->end;
|
||||
return stack;
|
||||
}
|
||||
|
||||
#undef PAGE_ALIGN
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
|
||||
SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_free_stack(struct sljit_stack *stack, void *allocator_data)
|
||||
{
|
||||
SLJIT_UNUSED_ARG(allocator_data);
|
||||
#ifdef _WIN32
|
||||
VirtualFree((void*)stack->max_limit, 0, MEM_RELEASE);
|
||||
VirtualFree((void*)stack->min_start, 0, MEM_RELEASE);
|
||||
#else
|
||||
munmap((void*)stack->max_limit, stack->base - stack->max_limit);
|
||||
munmap((void*)stack->min_start, stack->end - stack->min_start);
|
||||
#endif
|
||||
SLJIT_FREE(stack, allocator_data);
|
||||
}
|
||||
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_limit)
|
||||
SLJIT_API_FUNC_ATTRIBUTE sljit_u8 *SLJIT_FUNC sljit_stack_resize(struct sljit_stack *stack, sljit_u8 *new_start)
|
||||
{
|
||||
sljit_uw aligned_old_limit;
|
||||
sljit_uw aligned_new_limit;
|
||||
sljit_uw aligned_old_start;
|
||||
sljit_uw aligned_new_start;
|
||||
|
||||
if ((new_start < stack->min_start) || (new_start >= stack->end))
|
||||
return NULL;
|
||||
|
||||
if ((new_limit < stack->max_limit) || (new_limit >= stack->base))
|
||||
return -1;
|
||||
#ifdef _WIN32
|
||||
aligned_new_limit = (sljit_uw)new_limit & ~sljit_page_align;
|
||||
aligned_old_limit = ((sljit_uw)stack->limit) & ~sljit_page_align;
|
||||
if (aligned_new_limit != aligned_old_limit) {
|
||||
if (aligned_new_limit < aligned_old_limit) {
|
||||
if (!VirtualAlloc((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MEM_COMMIT, PAGE_READWRITE))
|
||||
return -1;
|
||||
aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
|
||||
aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
|
||||
if (aligned_new_start != aligned_old_start) {
|
||||
if (aligned_new_start < aligned_old_start) {
|
||||
if (!VirtualAlloc((void*)aligned_new_start, aligned_old_start - aligned_new_start, MEM_COMMIT, PAGE_READWRITE))
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
if (!VirtualFree((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MEM_DECOMMIT))
|
||||
return -1;
|
||||
if (!VirtualFree((void*)aligned_old_start, aligned_new_start - aligned_old_start, MEM_DECOMMIT))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
stack->limit = new_limit;
|
||||
return 0;
|
||||
#else
|
||||
if (new_limit <= stack->limit) {
|
||||
stack->limit = new_limit;
|
||||
return 0;
|
||||
}
|
||||
aligned_new_limit = (sljit_uw)new_limit & ~sljit_page_align;
|
||||
aligned_old_limit = ((sljit_uw)stack->limit) & ~sljit_page_align;
|
||||
/* If madvise is available, we release the unnecessary space. */
|
||||
if (stack->start < new_start) {
|
||||
aligned_new_start = (sljit_uw)new_start & ~sljit_page_align;
|
||||
aligned_old_start = ((sljit_uw)stack->start) & ~sljit_page_align;
|
||||
/* If madvise is available, we release the unnecessary space. */
|
||||
#if defined(MADV_DONTNEED)
|
||||
if (aligned_new_limit > aligned_old_limit)
|
||||
madvise((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, MADV_DONTNEED);
|
||||
if (aligned_new_start > aligned_old_start)
|
||||
madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, MADV_DONTNEED);
|
||||
#elif defined(POSIX_MADV_DONTNEED)
|
||||
if (aligned_new_limit > aligned_old_limit)
|
||||
posix_madvise((void*)aligned_old_limit, aligned_new_limit - aligned_old_limit, POSIX_MADV_DONTNEED);
|
||||
if (aligned_new_start > aligned_old_start)
|
||||
posix_madvise((void*)aligned_old_start, aligned_new_start - aligned_old_start, POSIX_MADV_DONTNEED);
|
||||
#endif
|
||||
stack->limit = new_limit;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
stack->start = new_start;
|
||||
return new_start;
|
||||
}
|
||||
|
||||
#endif /* SLJIT_UTIL_STACK */
|
||||
|
@ -1,9 +1,9 @@
|
||||
#! /bin/sh
|
||||
# test-driver - basic testsuite driver script.
|
||||
|
||||
scriptversion=2013-07-13.22; # UTC
|
||||
scriptversion=2016-01-11.22; # UTC
|
||||
|
||||
# Copyright (C) 2011-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -143,6 +143,6 @@ echo ":copy-in-global-log: $gcopy" >> $trs_file
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
|
8
pcre/testdata/testinput2
vendored
8
pcre/testdata/testinput2
vendored
@ -4249,4 +4249,12 @@ backtracking verbs. --/
|
||||
|
||||
/(?=.*[A-Z])/I
|
||||
|
||||
"(?<=(a))\1?b"
|
||||
ab
|
||||
aaab
|
||||
|
||||
"(?=(a))\1?b"
|
||||
ab
|
||||
aaab
|
||||
|
||||
/-- End of testinput2 --/
|
||||
|
6
pcre/testdata/testinput5
vendored
6
pcre/testdata/testinput5
vendored
@ -798,4 +798,10 @@
|
||||
/(?<=\K\x{17f})/8G+
|
||||
\x{17f}\x{17f}\x{17f}\x{17f}\x{17f}
|
||||
|
||||
/\C[^\v]+\x80/8
|
||||
[AΏBŀC]
|
||||
|
||||
/\C[^\d]+\x80/8
|
||||
[AΏBŀC]
|
||||
|
||||
/-- End of testinput5 --/
|
||||
|
16
pcre/testdata/testoutput2
vendored
16
pcre/testdata/testoutput2
vendored
@ -14705,4 +14705,20 @@ No options
|
||||
No first char
|
||||
No need char
|
||||
|
||||
"(?<=(a))\1?b"
|
||||
ab
|
||||
0: b
|
||||
1: a
|
||||
aaab
|
||||
0: ab
|
||||
1: a
|
||||
|
||||
"(?=(a))\1?b"
|
||||
ab
|
||||
0: ab
|
||||
1: a
|
||||
aaab
|
||||
0: ab
|
||||
1: a
|
||||
|
||||
/-- End of testinput2 --/
|
||||
|
8
pcre/testdata/testoutput5
vendored
8
pcre/testdata/testoutput5
vendored
@ -1942,4 +1942,12 @@ Need char = 'z'
|
||||
0: \x{17f}
|
||||
0+
|
||||
|
||||
/\C[^\v]+\x80/8
|
||||
[AΏBŀC]
|
||||
No match
|
||||
|
||||
/\C[^\d]+\x80/8
|
||||
[AΏBŀC]
|
||||
No match
|
||||
|
||||
/-- End of testinput5 --/
|
||||
|
Loading…
x
Reference in New Issue
Block a user