diff --git a/harbour/ChangeLog.txt b/harbour/ChangeLog.txt index 69d6bc978f..eb48213fc7 100644 --- a/harbour/ChangeLog.txt +++ b/harbour/ChangeLog.txt @@ -10,6 +10,35 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2012-12-16 05:33 UTC+0100 Viktor Szakats (harbour syenar.net) + * config/darwin/clang.mk + + use 'clang++' in C++ mode + + * include/hbcomp.h + * include/hbmacro.h + * include/hbsetup.h + % deleted redundant and/or unnecessary C RTL headers + + + config/win/clang.mk + * utils/hbmk2/hbmk2.prg + * utils/hbmk2/hbmk2.*.po + * README.txt + + added very experimental clang support to the build + systems. Very lightly tested. + ! fixed entry function detection not being enabled with clang + ! fixed .res files not being added on os2/gcc[omf] from .hbc/sources= directive + + added recently added new filter 'allbcc' to help text + ! synced compiler list per platform in help/readme to reality + + * ChangeLog.txt + + updated 2012-12-16 00:17 UTC+0100 with the first DONE item. + + * src/3rd/pcre/* + - reverted to 8.31 until all the breakage in configurability + is fixed either in pcre or by redesigning our way of + configuring it. Command-line configuration -DHAVE_*=0 + doesn't seem to work anymore. + 2012-12-16 03:07 UTC+0100 Viktor Szakats (harbour syenar.net) + config/win/bcc64.mk * config/global.mk @@ -65,6 +94,7 @@ VAR, PVAR -> [P]HB_HVAR _FUNC, PFUNCTION -> [P]HB_HFUNC _FUNCALL, PFUNCALL -> [P]HB_HFUNCALL + _INLINE, PINLINE [P]HB_HINLINE [DONE] _EXTERN, PEXTERN -> [P]HB_HEXTERN AUTOOPEN, PAUTOOPEN -> [P]HB_HAUTOOPEN FUNCTIONS -> HB_HFUNCTION_LIST diff --git a/harbour/README.txt b/harbour/README.txt index 4fc531bff0..a823ee2470 100644 --- a/harbour/README.txt +++ b/harbour/README.txt @@ -578,24 +578,22 @@ TABLE OF CONTENT linux ----- gcc - GNU C - clang - Clang compiler frontend + clang - Clang watcom - Open Watcom C/C++ icc - Intel(R) C/C++ sunpro - Sun Studio C/C++ open64 - Open64 C/C++ - pcc - Portable C Compiler (experimental) darwin ------ gcc - GNU C - clang - Clang compiler frontend + clang - Clang icc - Intel(R) C/C++ - pcc - Portable C Compiler (experimental) bsd --- gcc - GNU C - clang - Clang compiler frontend + clang - Clang pcc - Portable C Compiler (experimental) hpux @@ -627,8 +625,8 @@ TABLE OF CONTENT minix ----- gcc - GNU C + clang - Clang ack - Amsterdam Compiler Kit (does not work yet) - pcc - Portable C Compiler (experimental) aix --- @@ -642,7 +640,6 @@ TABLE OF CONTENT ----- gcc - GNU C sunpro - Sun Studio C/C++ - pcc - Portable C Compiler (experimental) win --- @@ -654,6 +651,7 @@ TABLE OF CONTENT Also supported, some features may be missing: + clang - Clang watcom - Open Watcom C/C++ bcc - Borland/CodeGear/Embarcadero C++ 4.x and above bcc64 - Embarcadero C++ 6.5 and above diff --git a/harbour/config/darwin/clang.mk b/harbour/config/darwin/clang.mk index 2b8544acc9..fa9a823259 100644 --- a/harbour/config/darwin/clang.mk +++ b/harbour/config/darwin/clang.mk @@ -3,8 +3,13 @@ # ifeq ($(HB_BUILD_MODE),cpp) - # -ccc-clang-cxx - HB_CMP := clang + ifneq ($(findstring clang$(subst x, ,x)version$(subst x, ,x)1,$(shell clang --version)),) + HB_BUILD_MODE := c + endif +endif + +ifeq ($(HB_BUILD_MODE),cpp) + HB_CMP := clang++ else HB_CMP := clang endif diff --git a/harbour/config/win/clang.mk b/harbour/config/win/clang.mk new file mode 100644 index 0000000000..d00cf06756 --- /dev/null +++ b/harbour/config/win/clang.mk @@ -0,0 +1,59 @@ +# +# $Id$ +# + +ifeq ($(HB_BUILD_MODE),cpp) + HB_CMP := clang++ +else + HB_CMP := clang +endif + +OBJ_EXT := .o +LIB_PREF := lib +LIB_EXT := .a + +HB_DYN_COPT := -DHB_DYNLIB + +CC := $(HB_CCPATH)$(HB_CMP)$(HB_CCPOSTFIX) +ifneq ($(filter --analyze, $(HB_USER_CFLAGS)),) + CC_IN := +else + CC_IN := -c +endif +CC_OUT := -o + +CFLAGS += -I. -I$(HB_HOST_INC) + +ifneq ($(HB_BUILD_WARN),no) + CFLAGS += -W -Wall +else + CFLAGS += -W +endif + +ifneq ($(HB_BUILD_OPTIM),no) + CFLAGS += -O3 +endif + +ifeq ($(HB_BUILD_DEBUG),yes) + CFLAGS += -g +endif + +LD := $(CC) +LD_OUT := -o + +LIBPATHS := $(foreach dir,$(LIB_DIR) $(SYSLIBPATHS),-L$(dir)) +LDLIBS := $(foreach lib,$(HB_USER_LIBS) $(LIBS) $(SYSLIBS),-l$(lib)) + +LDFLAGS += $(LIBPATHS) + +AR := $(HB_CCPREFIX)ar +AR_RULE = ( $(AR) $(ARFLAGS) $(HB_AFLAGS) $(HB_USER_AFLAGS) rcs $(LIB_DIR)/$@ $(^F) $(ARSTRIP) ) || ( $(RM) $(LIB_DIR)/$@ && $(FALSE) ) + +DY := $(CC) +DFLAGS += -shared $(LIBPATHS) +DY_OUT := -o$(subst x,x, ) +DLIBS := $(foreach lib,$(HB_USER_LIBS) $(SYSLIBS),-l$(lib)) + +DY_RULE = $(DY) $(DFLAGS) -Wl,-soname,$(DYN_NAME_CPT) $(HB_USER_DFLAGS) $(DY_OUT)$(DYN_DIR)/$@ $^ $(DLIBS) $(DYSTRIP) && $(LN) $(@F) $(DYN_FILE_NVR) && $(LN) $(@F) $(DYN_FILE_CPT) + +include $(TOP)$(ROOT)config/rules.mk diff --git a/harbour/include/hbcomp.h b/harbour/include/hbcomp.h index a59c448569..505b1d3d63 100644 --- a/harbour/include/hbcomp.h +++ b/harbour/include/hbcomp.h @@ -53,11 +53,6 @@ #ifndef HB_COMP_H_ #define HB_COMP_H_ -#include -#include -#include -#include - #include "hbmacro.ch" #include "hbapi.h" #include "hberrors.h" diff --git a/harbour/include/hbmacro.h b/harbour/include/hbmacro.h index d165d609d9..352acaafc4 100644 --- a/harbour/include/hbmacro.h +++ b/harbour/include/hbmacro.h @@ -53,12 +53,6 @@ #ifndef HB_MACRO_H_ #define HB_MACRO_H_ -#include -#include -#include -#include -#include - #include "hbcompdf.h" #include "hbapi.h" #include "hbapiitm.h" diff --git a/harbour/include/hbsetup.h b/harbour/include/hbsetup.h index b57d218262..90e0ae02bd 100644 --- a/harbour/include/hbsetup.h +++ b/harbour/include/hbsetup.h @@ -54,8 +54,6 @@ #ifndef HB_SETUP_H_ #define HB_SETUP_H_ -#include - /* *********************************************************************** * Include settings common for .prg and .c files */ diff --git a/harbour/src/3rd/pcre/Makefile b/harbour/src/3rd/pcre/Makefile index 5c7097c60e..971b1fe488 100644 --- a/harbour/src/3rd/pcre/Makefile +++ b/harbour/src/3rd/pcre/Makefile @@ -77,8 +77,8 @@ else endif # ORIGIN http://www.pcre.org/ -# VER 8.32 -# URL ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.32.tar.gz +# VER 8.31 +# URL ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.31.tar.gz # DIFF pcre.dif # # MAP LICENCE diff --git a/harbour/src/3rd/pcre/config.h b/harbour/src/3rd/pcre/config.h index 98801a8104..b5be736eac 100644 --- a/harbour/src/3rd/pcre/config.h +++ b/harbour/src/3rd/pcre/config.h @@ -1,17 +1,17 @@ /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ -/* PCRE is written in Standard C, but there are a few non-standard things it -can cope with, allowing it to run on SunOS4 and other "close to standard" -systems. -In environments that support the facilities, config.h.in is converted by -"configure", or config-cmake.h.in is converted by CMake, into config.h. If you -are going to build PCRE "by hand" without using "configure" or CMake, you -should copy the distributed config.h.generic to config.h, and then edit the -macro definitions to be the way you need them. You must then add --DHAVE_CONFIG_H to all of your compile commands, so that config.h is included -at the start of every source. +/* On Unix-like systems config.h.in is converted by "configure" into config.h. +Some other environments also support the use of "configure". PCRE is written in +Standard C, but there are a few non-standard things it can cope with, allowing +it to run on SunOS4 and other "close to standard" systems. + +If you are going to build PCRE "by hand" on a system without "configure" you +should copy the distributed config.h.generic to config.h, and then set up the +macro definitions the way you need them. You must then add -DHAVE_CONFIG_H to +all of your compile commands, so that config.h is included at the start of +every source. Alternatively, you can avoid editing by using -D on the compiler command line to set the macro values. In this case, you do not have to set -DHAVE_CONFIG_H. @@ -21,28 +21,20 @@ HAVE_BCOPY is set to 1. If your system has neither bcopy() nor memmove(), set them both to 0; an emulation function will be used. */ /* By default, the \R escape sequence matches any Unicode line ending - character or sequence of characters. If BSR_ANYCRLF is defined (to any - value), this is changed so that backslash-R matches only CR, LF, or CRLF. - The build-time default can be overridden by the user of PCRE at runtime. */ + character or sequence of characters. If BSR_ANYCRLF is defined, this is + changed so that backslash-R matches only CR, LF, or CRLF. The build- time + default can be overridden by the user of PCRE at runtime. On systems that + support it, "configure" can be used to override the default. */ /* #undef BSR_ANYCRLF */ /* If you are compiling for a system that uses EBCDIC instead of ASCII - character codes, define this macro to any value. You must also edit the - NEWLINE macro below to set a suitable EBCDIC newline, commonly 21 (0x15). - On systems that can use "configure" or CMake to set EBCDIC, NEWLINE is - automatically adjusted. When EBCDIC is set, PCRE assumes that all input - strings are in EBCDIC. If you do not define this macro, PCRE will assume - input strings are ASCII or UTF-8/16/32 Unicode. It is not possible to build - a version of PCRE that supports both EBCDIC and UTF-8/16/32. */ + character codes, define this macro as 1. On systems that can use + "configure", this can be done via --enable-ebcdic. PCRE will then assume + that all input strings are in EBCDIC. If you do not define this macro, PCRE + will assume input strings are ASCII or UTF-8/16 Unicode. It is not possible + to build a version of PCRE that supports both EBCDIC and UTF-8/16. */ /* #undef EBCDIC */ -/* In an EBCDIC environment, define this macro to any value to arrange for the - NL character to be 0x25 instead of the default 0x15. NL plays the role that - LF does in an ASCII/Unicode environment. The value must also be set in the - NEWLINE macro below. On systems that can use "configure" or CMake to set - EBCDIC_NL25, the adjustment of NEWLINE is automatic. */ -/* #undef EBCDIC_NL25 */ - /* Define to 1 if you have the `bcopy' function. */ #ifndef HAVE_BCOPY #define HAVE_BCOPY 1 @@ -97,12 +89,6 @@ them both to 0; an emulation function will be used. */ #define HAVE_MEMORY_H 1 #endif -/* Define if you have POSIX threads libraries and header files. */ -/* #undef HAVE_PTHREAD */ - -/* Have PTHREAD_PRIO_INHERIT. */ -/* #undef HAVE_PTHREAD_PRIO_INHERIT */ - /* Define to 1 if you have the header file. */ /* #undef HAVE_READLINE_HISTORY_H */ @@ -173,12 +159,6 @@ them both to 0; an emulation function will be used. */ #define HAVE_UNSIGNED_LONG_LONG 1 #endif -/* Define to 1 or 0, depending whether the compiler supports simple visibility - declarations. */ -#ifndef HAVE_VISIBILITY -#define HAVE_VISIBILITY 1 -#endif - /* Define to 1 if you have the header file. */ /* #undef HAVE_WINDOWS_H */ @@ -194,7 +174,8 @@ them both to 0; an emulation function will be used. */ as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows - for longer patterns in extreme cases. */ + for longer patterns in extreme cases. On systems that support it, + "configure" can be used to override this default. */ #ifndef LINK_SIZE #define LINK_SIZE 2 #endif @@ -210,7 +191,8 @@ them both to 0; an emulation function will be used. */ pcre_exec(). There is a runtime interface for setting a different limit. The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large - so that it does not accidentally catch legitimate cases. */ + so that it does not accidentally catch legitimate cases. On systems that + support it, "configure" can be used to override this default default. */ #ifndef MATCH_LIMIT #define MATCH_LIMIT 10000000 #endif @@ -222,7 +204,8 @@ them both to 0; an emulation function will be used. */ used. The value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To have any useful effect, it must be less than the value of MATCH_LIMIT. The default is to use the same value as MATCH_LIMIT. There is - a runtime method for setting a different limit. */ + a runtime method for setting a different limit. On systems that support it, + "configure" can be used to override the default. */ #ifndef MATCH_LIMIT_RECURSION #define MATCH_LIMIT_RECURSION MATCH_LIMIT #endif @@ -241,28 +224,22 @@ them both to 0; an emulation function will be used. */ #define MAX_NAME_SIZE 32 #endif -/* The value of NEWLINE determines the default newline character sequence. - PCRE client programs can override this by selecting other values at run - time. In ASCII environments, the value can be 10 (LF), 13 (CR), or 3338 - (CRLF); in EBCDIC environments the value can be 21 or 37 (LF), 13 (CR), or - 3349 or 3365 (CRLF) because there are two alternative codepoints (0x15 and - 0x25) that are used as the NL line terminator that is equivalent to ASCII - LF. In both ASCII and EBCDIC environments the value can also be -1 (ANY), - or -2 (ANYCRLF). */ +/* The value of NEWLINE determines the newline character sequence. On systems + that support it, "configure" can be used to override the default, which is + 10. The possible values are 10 (LF), 13 (CR), 3338 (CRLF), -1 (ANY), or -2 + (ANYCRLF). */ #ifndef NEWLINE #define NEWLINE 10 #endif -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -/* #undef NO_MINUS_C_MINUS_O */ - /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited - size. Define NO_RECURSE to any value to get a version that doesn't use - recursion in the match() function; instead it creates its own stack by - steam using pcre_recurse_malloc() to obtain memory from the heap. For more - detail, see the comments and other stuff just above the match() function. - */ + size. Define NO_RECURSE to get a version that doesn't use recursion in the + match() function; instead it creates its own stack by steam using + pcre_recurse_malloc() to obtain memory from the heap. For more detail, see + the comments and other stuff just above the match() function. On systems + that support it, "configure" can be used to set this in the Makefile (use + --disable-stack-for-recursion). */ /* #undef NO_RECURSE */ /* Name of package */ @@ -275,7 +252,7 @@ them both to 0; an emulation function will be used. */ #define PACKAGE_NAME "PCRE" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "PCRE 8.32" +#define PACKAGE_STRING "PCRE 8.31" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre" @@ -284,29 +261,31 @@ them both to 0; an emulation function will be used. */ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "8.32" +#define PACKAGE_VERSION "8.31" /* The value of PCREGREP_BUFSIZE determines the size of buffer used by - pcregrep to hold parts of the file it is searching. This is also the - minimum value. The actual amount of memory used by pcregrep is three times - this number, because it allows for the buffering of "before" and "after" - lines. */ + pcregrep to hold parts of the file it is searching. On systems that support + it, "configure" can be used to override the default, which is 8192. This is + also the minimum value. The actual amount of memory used by pcregrep is + three times this number, because it allows for the buffering of "before" + and "after" lines. */ #ifndef PCREGREP_BUFSIZE #define PCREGREP_BUFSIZE 20480 #endif + /* If you are compiling for a system other than a Unix-like system or Win32, and it needs some magic to be inserted before the definition of a function that is exported by the library, define this macro to - contain the relevant magic. If you do not define this macro, a suitable - __declspec value is used for Windows systems; in other environments - "extern" is used for a C compiler and "extern C" for a C++ compiler. - This macro apears at the start of every exported function that is part - of the external API. It does not appear on functions that are "external" - in the C sense, but which are internal to the library. */ + contain the relevant magic. If you do not define this macro, it + defaults to "extern" for a C compiler and "extern C" for a C++ + compiler on non-Win32 systems. This macro apears at the start of + every exported function that is part of the external API. It does + not appear on functions that are "external" in the C sense, but + which are internal to the library. */ /* #undef PCRE_EXP_DEFN */ -/* Define to any value if linking statically (TODO: make nice with Libtool) */ +/* Define if linking statically (TODO: make nice with Libtool) */ /* #undef PCRE_STATIC */ /* When calling PCRE via the POSIX interface, additional working storage is @@ -315,70 +294,57 @@ them both to 0; an emulation function will be used. */ only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer - used is defined by POSIX_MALLOC_THRESHOLD. */ + used is defined by POSIX_MALLOC_THRESHOLD. On systems that support it, + "configure" can be used to override this default. */ #ifndef POSIX_MALLOC_THRESHOLD #define POSIX_MALLOC_THRESHOLD 10 #endif -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -/* #undef PTHREAD_CREATE_JOINABLE */ - /* Define to 1 if you have the ANSI C header files. */ #ifndef STDC_HEADERS #define STDC_HEADERS 1 #endif -/* Define to allow pcretest and pcregrep to be linked with gcov, so that they - are able to generate code coverage reports. */ -/* #undef SUPPORT_GCOV */ - -/* Define to any value to enable support for Just-In-Time compiling. */ +/* Define to enable support for Just-In-Time compiling. */ /* #undef SUPPORT_JIT */ -/* Define to any value to allow pcregrep to be linked with libbz2, so that it - is able to handle .bz2 files. */ +/* Define to allow pcregrep to be linked with libbz2, so that it is able to + handle .bz2 files. */ /* #undef SUPPORT_LIBBZ2 */ -/* Define to any value to allow pcretest to be linked with libedit. */ +/* Define to allow pcretest to be linked with libedit. */ /* #undef SUPPORT_LIBEDIT */ -/* Define to any value to allow pcretest to be linked with libreadline. */ +/* Define to allow pcretest to be linked with libreadline. */ /* #undef SUPPORT_LIBREADLINE */ -/* Define to any value to allow pcregrep to be linked with libz, so that it is - able to handle .gz files. */ +/* Define to allow pcregrep to be linked with libz, so that it is able to + handle .gz files. */ /* #undef SUPPORT_LIBZ */ -/* Define to any value to enable the 16 bit PCRE library. */ +/* Define to enable the 16 bit PCRE library. */ /* #undef SUPPORT_PCRE16 */ -/* Define to any value to enable the 32 bit PCRE library. */ -/* #undef SUPPORT_PCRE32 */ - -/* Define to any value to enable the 8 bit PCRE library. */ +/* Define to enable the 8 bit PCRE library. */ #ifndef SUPPORT_PCRE8 #define SUPPORT_PCRE8 /**/ #endif -/* Define to any value to enable JIT support in pcregrep. */ +/* Define to enable JIT support in pcregrep. */ /* #undef SUPPORT_PCREGREP_JIT */ -/* Define to any value to enable support for Unicode properties. */ +/* Define to enable support for Unicode properties. */ /* #undef SUPPORT_UCP */ -/* Define to any value to enable support for the UTF-8/16/32 Unicode encoding. - This will work even in an EBCDIC environment, but it is incompatible with - the EBCDIC macro. That is, PCRE can support *either* EBCDIC code *or* - ASCII/UTF-8/16/32, but not both at once. */ +/* Define to enable support for the UTF-8/16 Unicode encoding. This will work + even in an EBCDIC environment, but it is incompatible with the EBCDIC + macro. That is, PCRE can support *either* EBCDIC code *or* ASCII/UTF-8/16, + but not both at once. */ /* #undef SUPPORT_UTF */ -/* Valgrind support to find invalid memory reads. */ -/* #undef SUPPORT_VALGRIND */ - /* Version number of package */ #ifndef VERSION -#define VERSION "8.32" +#define VERSION "8.31" #endif /* Define to empty if `const' does not conform to ANSI C. */ diff --git a/harbour/src/3rd/pcre/pcre.dif b/harbour/src/3rd/pcre/pcre.dif index 56cb28369e..f38429e762 100644 --- a/harbour/src/3rd/pcre/pcre.dif +++ b/harbour/src/3rd/pcre/pcre.dif @@ -1,6 +1,6 @@ diff -urN pcre.orig\pcrejitc.c pcre\pcrejitc.c ---- pcre.orig\pcrejitc.c Tue Dec 04 22:48:56 2012 -+++ pcre\pcrejitc.c Tue Dec 04 22:48:56 2012 +--- pcre.orig\pcrejitc.c Wed Jul 11 12:26:04 2012 ++++ pcre\pcrejitc.c Wed Jul 11 12:26:05 2012 @@ -59,7 +59,7 @@ #define SLJIT_VERBOSE 0 #define SLJIT_DEBUG 0 @@ -11,9 +11,9 @@ diff -urN pcre.orig\pcrejitc.c pcre\pcrejitc.c #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED #error Unsupported architecture diff -urN pcre.orig\sjconfi.h pcre\sjconfi.h ---- pcre.orig\sjconfi.h Tue Dec 04 22:48:56 2012 -+++ pcre\sjconfi.h Tue Dec 04 22:48:56 2012 -@@ -306,8 +306,12 @@ +--- pcre.orig\sjconfi.h Wed Jul 11 12:26:04 2012 ++++ pcre\sjconfi.h Wed Jul 11 12:26:05 2012 +@@ -282,8 +282,12 @@ #if defined(__GNUC__) @@ -24,5 +24,5 @@ diff -urN pcre.orig\sjconfi.h pcre\sjconfi.h +#define SLJIT_CALL +#endif - #elif defined(_MSC_VER) + #elif defined(_WIN32) diff --git a/harbour/src/3rd/pcre/pcre.h b/harbour/src/3rd/pcre/pcre.h index a6aa4e934b..b71ead37a8 100644 --- a/harbour/src/3rd/pcre/pcre.h +++ b/harbour/src/3rd/pcre/pcre.h @@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE_MAJOR 8 -#define PCRE_MINOR 32 +#define PCRE_MINOR 31 #define PCRE_PRERELEASE -#define PCRE_DATE 2012-11-30 +#define PCRE_DATE 2012-07-06 /* 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 @@ -95,70 +95,54 @@ it is needed here for malloc. */ extern "C" { #endif -/* Public options. Some are compile-time only, some are run-time only, and some -are both, so we keep them all distinct. However, almost all the bits in the -options word are now used. In the long run, we may have to re-use some of the -compile-time only bits for runtime options, or vice versa. Any of the +/* Options. Some are compile-time only, some are run-time only, and some are +both, so we keep them all distinct. However, almost all the bits in the options +word are now used. In the long run, we may have to re-use some of the +compile-time only bits for runtime options, or vice versa. In the comments +below, "compile", "exec", and "DFA exec" mean that the option is permitted to +be set for those functions; "used in" means that an option may be set only for +compile, but is subsequently referenced in exec and/or DFA exec. Any of the compile-time options may be inspected during studying (and therefore JIT -compiling). +compiling). */ -Some options for pcre_compile() change its behaviour but do not affect the -behaviour of the execution functions. Other options are passed through to the -execution functions and affect their behaviour, with or without affecting the -behaviour of pcre_compile(). - -Options that can be passed to pcre_compile() are tagged Cx below, with these -variants: - -C1 Affects compile only -C2 Does not affect compile; affects exec, dfa_exec -C3 Affects compile, exec, dfa_exec -C4 Affects compile, exec, dfa_exec, study -C5 Affects compile, exec, study - -Options that can be set for pcre_exec() and/or pcre_dfa_exec() are flagged with -E and D, respectively. They take precedence over C3, C4, and C5 settings passed -from pcre_compile(). Those that are compatible with JIT execution are flagged -with J. */ - -#define PCRE_CASELESS 0x00000001 /* C1 */ -#define PCRE_MULTILINE 0x00000002 /* C1 */ -#define PCRE_DOTALL 0x00000004 /* C1 */ -#define PCRE_EXTENDED 0x00000008 /* C1 */ -#define PCRE_ANCHORED 0x00000010 /* C4 E D */ -#define PCRE_DOLLAR_ENDONLY 0x00000020 /* C2 */ -#define PCRE_EXTRA 0x00000040 /* C1 */ -#define PCRE_NOTBOL 0x00000080 /* E D J */ -#define PCRE_NOTEOL 0x00000100 /* E D J */ -#define PCRE_UNGREEDY 0x00000200 /* C1 */ -#define PCRE_NOTEMPTY 0x00000400 /* E D J */ -#define PCRE_UTF8 0x00000800 /* C4 ) */ -#define PCRE_UTF16 0x00000800 /* C4 ) Synonyms */ -#define PCRE_UTF32 0x00000800 /* C4 ) */ -#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* C1 */ -#define PCRE_NO_UTF8_CHECK 0x00002000 /* C1 E D J ) */ -#define PCRE_NO_UTF16_CHECK 0x00002000 /* C1 E D J ) Synonyms */ -#define PCRE_NO_UTF32_CHECK 0x00002000 /* C1 E D J ) */ -#define PCRE_AUTO_CALLOUT 0x00004000 /* C1 */ -#define PCRE_PARTIAL_SOFT 0x00008000 /* E D J ) Synonyms */ -#define PCRE_PARTIAL 0x00008000 /* E D J ) */ -#define PCRE_DFA_SHORTEST 0x00010000 /* D */ -#define PCRE_DFA_RESTART 0x00020000 /* D */ -#define PCRE_FIRSTLINE 0x00040000 /* C3 */ -#define PCRE_DUPNAMES 0x00080000 /* C1 */ -#define PCRE_NEWLINE_CR 0x00100000 /* C3 E D */ -#define PCRE_NEWLINE_LF 0x00200000 /* C3 E D */ -#define PCRE_NEWLINE_CRLF 0x00300000 /* C3 E D */ -#define PCRE_NEWLINE_ANY 0x00400000 /* C3 E D */ -#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* C3 E D */ -#define PCRE_BSR_ANYCRLF 0x00800000 /* C3 E D */ -#define PCRE_BSR_UNICODE 0x01000000 /* C3 E D */ -#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* C5 */ -#define PCRE_NO_START_OPTIMIZE 0x04000000 /* C2 E D ) Synonyms */ -#define PCRE_NO_START_OPTIMISE 0x04000000 /* C2 E D ) */ -#define PCRE_PARTIAL_HARD 0x08000000 /* E D J */ -#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* E D J */ -#define PCRE_UCP 0x20000000 /* C3 */ +#define PCRE_CASELESS 0x00000001 /* Compile */ +#define PCRE_MULTILINE 0x00000002 /* Compile */ +#define PCRE_DOTALL 0x00000004 /* Compile */ +#define PCRE_EXTENDED 0x00000008 /* Compile */ +#define PCRE_ANCHORED 0x00000010 /* Compile, exec, DFA exec */ +#define PCRE_DOLLAR_ENDONLY 0x00000020 /* Compile, used in exec, DFA exec */ +#define PCRE_EXTRA 0x00000040 /* Compile */ +#define PCRE_NOTBOL 0x00000080 /* Exec, DFA exec */ +#define PCRE_NOTEOL 0x00000100 /* Exec, DFA exec */ +#define PCRE_UNGREEDY 0x00000200 /* Compile */ +#define PCRE_NOTEMPTY 0x00000400 /* Exec, DFA exec */ +/* The next two are also used in exec and DFA exec */ +#define PCRE_UTF8 0x00000800 /* Compile (same as PCRE_UTF16) */ +#define PCRE_UTF16 0x00000800 /* Compile (same as PCRE_UTF8) */ +#define PCRE_NO_AUTO_CAPTURE 0x00001000 /* Compile */ +/* The next two are also used in exec and DFA exec */ +#define PCRE_NO_UTF8_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF16_CHECK) */ +#define PCRE_NO_UTF16_CHECK 0x00002000 /* Compile (same as PCRE_NO_UTF8_CHECK) */ +#define PCRE_AUTO_CALLOUT 0x00004000 /* Compile */ +#define PCRE_PARTIAL_SOFT 0x00008000 /* Exec, DFA exec */ +#define PCRE_PARTIAL 0x00008000 /* Backwards compatible synonym */ +#define PCRE_DFA_SHORTEST 0x00010000 /* DFA exec */ +#define PCRE_DFA_RESTART 0x00020000 /* DFA exec */ +#define PCRE_FIRSTLINE 0x00040000 /* Compile, used in exec, DFA exec */ +#define PCRE_DUPNAMES 0x00080000 /* Compile */ +#define PCRE_NEWLINE_CR 0x00100000 /* Compile, exec, DFA exec */ +#define PCRE_NEWLINE_LF 0x00200000 /* Compile, exec, DFA exec */ +#define PCRE_NEWLINE_CRLF 0x00300000 /* Compile, exec, DFA exec */ +#define PCRE_NEWLINE_ANY 0x00400000 /* Compile, exec, DFA exec */ +#define PCRE_NEWLINE_ANYCRLF 0x00500000 /* Compile, exec, DFA exec */ +#define PCRE_BSR_ANYCRLF 0x00800000 /* Compile, exec, DFA exec */ +#define PCRE_BSR_UNICODE 0x01000000 /* Compile, exec, DFA exec */ +#define PCRE_JAVASCRIPT_COMPAT 0x02000000 /* Compile, used in exec */ +#define PCRE_NO_START_OPTIMIZE 0x04000000 /* Compile, exec, DFA exec */ +#define PCRE_NO_START_OPTIMISE 0x04000000 /* Synonym */ +#define PCRE_PARTIAL_HARD 0x08000000 /* Exec, DFA exec */ +#define PCRE_NOTEMPTY_ATSTART 0x10000000 /* Exec, DFA exec */ +#define PCRE_UCP 0x20000000 /* Compile, used in exec, DFA exec */ /* Exec-time and get/set-time error codes */ @@ -172,9 +156,8 @@ with J. */ #define PCRE_ERROR_NOSUBSTRING (-7) #define PCRE_ERROR_MATCHLIMIT (-8) #define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ -#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16/32 */ -#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16/32 */ -#define PCRE_ERROR_BADUTF32 (-10) /* Same for 8/16/32 */ +#define PCRE_ERROR_BADUTF8 (-10) /* Same for 8/16 */ +#define PCRE_ERROR_BADUTF16 (-10) /* Same for 8/16 */ #define PCRE_ERROR_BADUTF8_OFFSET (-11) /* Same for 8/16 */ #define PCRE_ERROR_BADUTF16_OFFSET (-11) /* Same for 8/16 */ #define PCRE_ERROR_PARTIAL (-12) @@ -197,8 +180,6 @@ with J. */ #define PCRE_ERROR_BADMODE (-28) #define PCRE_ERROR_BADENDIANNESS (-29) #define PCRE_ERROR_DFA_BADRESTART (-30) -#define PCRE_ERROR_JIT_BADOPTION (-31) -#define PCRE_ERROR_BADLENGTH (-32) /* Specific error codes for UTF-8 validity checks */ @@ -224,7 +205,6 @@ with J. */ #define PCRE_UTF8_ERR19 19 #define PCRE_UTF8_ERR20 20 #define PCRE_UTF8_ERR21 21 -#define PCRE_UTF8_ERR22 22 /* Specific error codes for UTF-16 validity checks */ @@ -234,13 +214,6 @@ with J. */ #define PCRE_UTF16_ERR3 3 #define PCRE_UTF16_ERR4 4 -/* Specific error codes for UTF-32 validity checks */ - -#define PCRE_UTF32_ERR0 0 -#define PCRE_UTF32_ERR1 1 -#define PCRE_UTF32_ERR2 2 -#define PCRE_UTF32_ERR3 3 - /* Request types for pcre_fullinfo() */ #define PCRE_INFO_OPTIONS 0 @@ -263,10 +236,6 @@ with J. */ #define PCRE_INFO_JIT 16 #define PCRE_INFO_JITSIZE 17 #define PCRE_INFO_MAXLOOKBEHIND 18 -#define PCRE_INFO_FIRSTCHARACTER 19 -#define PCRE_INFO_FIRSTCHARACTERFLAGS 20 -#define PCRE_INFO_REQUIREDCHAR 21 -#define PCRE_INFO_REQUIREDCHARFLAGS 22 /* Request types for pcre_config(). Do not re-arrange, in order to remain compatible. */ @@ -283,7 +252,6 @@ compatible. */ #define PCRE_CONFIG_JIT 9 #define PCRE_CONFIG_UTF16 10 #define PCRE_CONFIG_JITTARGET 11 -#define PCRE_CONFIG_UTF32 12 /* Request types for pcre_study(). Do not re-arrange, in order to remain compatible. */ @@ -291,9 +259,8 @@ compatible. */ #define PCRE_STUDY_JIT_COMPILE 0x0001 #define PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE 0x0002 #define PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE 0x0004 -#define PCRE_STUDY_EXTRA_NEEDED 0x0008 -/* Bit flags for the pcre[16|32]_extra structure. Do not re-arrange or redefine +/* Bit flags for the pcre[16]_extra structure. Do not re-arrange or redefine these bits, just add new ones on the end, in order to remain compatible. */ #define PCRE_EXTRA_STUDY_DATA 0x0001 @@ -312,18 +279,12 @@ typedef struct real_pcre pcre; struct real_pcre16; /* declaration; the definition is private */ typedef struct real_pcre16 pcre16; -struct real_pcre32; /* declaration; the definition is private */ -typedef struct real_pcre32 pcre32; - struct real_pcre_jit_stack; /* declaration; the definition is private */ typedef struct real_pcre_jit_stack pcre_jit_stack; struct real_pcre16_jit_stack; /* declaration; the definition is private */ typedef struct real_pcre16_jit_stack pcre16_jit_stack; -struct real_pcre32_jit_stack; /* declaration; the definition is private */ -typedef struct real_pcre32_jit_stack pcre32_jit_stack; - /* If PCRE is compiled with 16 bit character support, PCRE_UCHAR16 must contain a 16 bit wide signed data type. Otherwise it can be a dummy data type since pcre16 functions are not implemented. There is a check for this in pcre_internal.h. */ @@ -335,17 +296,6 @@ pcre16 functions are not implemented. There is a check for this in pcre_internal #define PCRE_SPTR16 const PCRE_UCHAR16 * #endif -/* If PCRE is compiled with 32 bit character support, PCRE_UCHAR32 must contain -a 32 bit wide signed data type. Otherwise it can be a dummy data type since -pcre32 functions are not implemented. There is a check for this in pcre_internal.h. */ -#ifndef PCRE_UCHAR32 -#define PCRE_UCHAR32 unsigned int -#endif - -#ifndef PCRE_SPTR32 -#define PCRE_SPTR32 const PCRE_UCHAR32 * -#endif - /* When PCRE is compiled as a C++ library, the subject pointer type can be replaced with a custom type. For conventional use, the public interface is a const char *. */ @@ -382,19 +332,6 @@ typedef struct pcre16_extra { void *executable_jit; /* Contains a pointer to a compiled jit code */ } pcre16_extra; -/* Same structure as above, but with 32 bit char pointers. */ - -typedef struct pcre32_extra { - unsigned long int flags; /* Bits for which fields are set */ - void *study_data; /* Opaque data from pcre_study() */ - unsigned long int match_limit; /* Maximum number of calls to match() */ - void *callout_data; /* Data passed back in callouts */ - const unsigned char *tables; /* Pointer to character tables */ - unsigned long int match_limit_recursion; /* Max recursive calls to match() */ - PCRE_UCHAR32 **mark; /* For passing back a mark pointer */ - void *executable_jit; /* Contains a pointer to a compiled jit code */ -} pcre32_extra; - /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work @@ -442,28 +379,6 @@ typedef struct pcre16_callout_block { /* ------------------------------------------------------------------ */ } pcre16_callout_block; -/* Same structure as above, but with 32 bit char pointers. */ - -typedef struct pcre32_callout_block { - int version; /* Identifies version of block */ - /* ------------------------ Version 0 ------------------------------- */ - int callout_number; /* Number compiled into pattern */ - int *offset_vector; /* The offset vector */ - PCRE_SPTR32 subject; /* The subject being matched */ - int subject_length; /* The length of the subject */ - int start_match; /* Offset to start of this match attempt */ - int current_position; /* Where we currently are in the subject */ - int capture_top; /* Max current capture */ - int capture_last; /* Most recently closed capture */ - void *callout_data; /* Data passed in with the call */ - /* ------------------- Added for Version 1 -------------------------- */ - int pattern_position; /* Offset to next item in the pattern */ - int next_item_length; /* Length of next item in the pattern */ - /* ------------------- Added for Version 2 -------------------------- */ - const PCRE_UCHAR32 *mark; /* Pointer to current mark or NULL */ - /* ------------------------------------------------------------------ */ -} pcre32_callout_block; - /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function @@ -482,12 +397,6 @@ PCRE_EXP_DECL void (*pcre16_free)(void *); PCRE_EXP_DECL void *(*pcre16_stack_malloc)(size_t); PCRE_EXP_DECL void (*pcre16_stack_free)(void *); PCRE_EXP_DECL int (*pcre16_callout)(pcre16_callout_block *); - -PCRE_EXP_DECL void *(*pcre32_malloc)(size_t); -PCRE_EXP_DECL void (*pcre32_free)(void *); -PCRE_EXP_DECL void *(*pcre32_stack_malloc)(size_t); -PCRE_EXP_DECL void (*pcre32_stack_free)(void *); -PCRE_EXP_DECL int (*pcre32_callout)(pcre32_callout_block *); #else /* VPCOMPAT */ PCRE_EXP_DECL void *pcre_malloc(size_t); PCRE_EXP_DECL void pcre_free(void *); @@ -500,19 +409,12 @@ PCRE_EXP_DECL void pcre16_free(void *); PCRE_EXP_DECL void *pcre16_stack_malloc(size_t); PCRE_EXP_DECL void pcre16_stack_free(void *); PCRE_EXP_DECL int pcre16_callout(pcre16_callout_block *); - -PCRE_EXP_DECL void *pcre32_malloc(size_t); -PCRE_EXP_DECL void pcre32_free(void *); -PCRE_EXP_DECL void *pcre32_stack_malloc(size_t); -PCRE_EXP_DECL void pcre32_stack_free(void *); -PCRE_EXP_DECL int pcre32_callout(pcre32_callout_block *); #endif /* VPCOMPAT */ /* User defined callback which provides a stack just before the match starts. */ typedef pcre_jit_stack *(*pcre_jit_callback)(void *); typedef pcre16_jit_stack *(*pcre16_jit_callback)(void *); -typedef pcre32_jit_stack *(*pcre32_jit_callback)(void *); /* Exported PCRE functions */ @@ -520,131 +422,83 @@ PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre16 *pcre16_compile(PCRE_SPTR16, int, const char **, int *, const unsigned char *); -PCRE_EXP_DECL pcre32 *pcre32_compile(PCRE_SPTR32, int, const char **, int *, - const unsigned char *); PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **, int *, const unsigned char *); PCRE_EXP_DECL pcre16 *pcre16_compile2(PCRE_SPTR16, int, int *, const char **, int *, const unsigned char *); -PCRE_EXP_DECL pcre32 *pcre32_compile2(PCRE_SPTR32, int, int *, const char **, - int *, const unsigned char *); PCRE_EXP_DECL int pcre_config(int, void *); PCRE_EXP_DECL int pcre16_config(int, void *); -PCRE_EXP_DECL int pcre32_config(int, void *); PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); PCRE_EXP_DECL int pcre16_copy_named_substring(const pcre16 *, PCRE_SPTR16, int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, int); -PCRE_EXP_DECL int pcre32_copy_named_substring(const pcre32 *, PCRE_SPTR32, - int *, int, PCRE_SPTR32, PCRE_UCHAR32 *, int); PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *, int); PCRE_EXP_DECL int pcre16_copy_substring(PCRE_SPTR16, int *, int, int, PCRE_UCHAR16 *, int); -PCRE_EXP_DECL int pcre32_copy_substring(PCRE_SPTR32, int *, int, int, - PCRE_UCHAR32 *, int); PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre16_dfa_exec(const pcre16 *, const pcre16_extra *, PCRE_SPTR16, int, int, int, int *, int , int *, int); -PCRE_EXP_DECL int pcre32_dfa_exec(const pcre32 *, const pcre32_extra *, - PCRE_SPTR32, int, int, int, int *, int , int *, int); PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR, int, int, int, int *, int); PCRE_EXP_DECL int pcre16_exec(const pcre16 *, const pcre16_extra *, PCRE_SPTR16, int, int, int, int *, int); -PCRE_EXP_DECL int pcre32_exec(const pcre32 *, const pcre32_extra *, - PCRE_SPTR32, int, int, int, int *, int); -PCRE_EXP_DECL int pcre_jit_exec(const pcre *, const pcre_extra *, - PCRE_SPTR, int, int, int, int *, int, - pcre_jit_stack *); -PCRE_EXP_DECL int pcre16_jit_exec(const pcre16 *, const pcre16_extra *, - PCRE_SPTR16, int, int, int, int *, int, - pcre16_jit_stack *); -PCRE_EXP_DECL int pcre32_jit_exec(const pcre32 *, const pcre32_extra *, - PCRE_SPTR32, int, int, int, int *, int, - pcre32_jit_stack *); PCRE_EXP_DECL void pcre_free_substring(const char *); PCRE_EXP_DECL void pcre16_free_substring(PCRE_SPTR16); -PCRE_EXP_DECL void pcre32_free_substring(PCRE_SPTR32); PCRE_EXP_DECL void pcre_free_substring_list(const char **); PCRE_EXP_DECL void pcre16_free_substring_list(PCRE_SPTR16 *); -PCRE_EXP_DECL void pcre32_free_substring_list(PCRE_SPTR32 *); PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); PCRE_EXP_DECL int pcre16_fullinfo(const pcre16 *, const pcre16_extra *, int, void *); -PCRE_EXP_DECL int pcre32_fullinfo(const pcre32 *, const pcre32_extra *, int, - void *); PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); PCRE_EXP_DECL int pcre16_get_named_substring(const pcre16 *, PCRE_SPTR16, int *, int, PCRE_SPTR16, PCRE_SPTR16 *); -PCRE_EXP_DECL int pcre32_get_named_substring(const pcre32 *, PCRE_SPTR32, - int *, int, PCRE_SPTR32, PCRE_SPTR32 *); PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *); PCRE_EXP_DECL int pcre16_get_stringnumber(const pcre16 *, PCRE_SPTR16); -PCRE_EXP_DECL int pcre32_get_stringnumber(const pcre32 *, PCRE_SPTR32); PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *, char **, char **); PCRE_EXP_DECL int pcre16_get_stringtable_entries(const pcre16 *, PCRE_SPTR16, PCRE_UCHAR16 **, PCRE_UCHAR16 **); -PCRE_EXP_DECL int pcre32_get_stringtable_entries(const pcre32 *, PCRE_SPTR32, - PCRE_UCHAR32 **, PCRE_UCHAR32 **); PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int, const char **); PCRE_EXP_DECL int pcre16_get_substring(PCRE_SPTR16, int *, int, int, PCRE_SPTR16 *); -PCRE_EXP_DECL int pcre32_get_substring(PCRE_SPTR32, int *, int, int, - PCRE_SPTR32 *); PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int, const char ***); PCRE_EXP_DECL int pcre16_get_substring_list(PCRE_SPTR16, int *, int, PCRE_SPTR16 **); -PCRE_EXP_DECL int pcre32_get_substring_list(PCRE_SPTR32, int *, int, - PCRE_SPTR32 **); PCRE_EXP_DECL const unsigned char *pcre_maketables(void); PCRE_EXP_DECL const unsigned char *pcre16_maketables(void); -PCRE_EXP_DECL const unsigned char *pcre32_maketables(void); PCRE_EXP_DECL int pcre_refcount(pcre *, int); PCRE_EXP_DECL int pcre16_refcount(pcre16 *, int); -PCRE_EXP_DECL int pcre32_refcount(pcre32 *, int); PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **); PCRE_EXP_DECL pcre16_extra *pcre16_study(const pcre16 *, int, const char **); -PCRE_EXP_DECL pcre32_extra *pcre32_study(const pcre32 *, int, const char **); PCRE_EXP_DECL void pcre_free_study(pcre_extra *); PCRE_EXP_DECL void pcre16_free_study(pcre16_extra *); -PCRE_EXP_DECL void pcre32_free_study(pcre32_extra *); PCRE_EXP_DECL const char *pcre_version(void); PCRE_EXP_DECL const char *pcre16_version(void); -PCRE_EXP_DECL const char *pcre32_version(void); /* Utility functions for byte order swaps. */ PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *, pcre_extra *, const unsigned char *); PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *, const unsigned char *); -PCRE_EXP_DECL int pcre32_pattern_to_host_byte_order(pcre32 *, pcre32_extra *, - const unsigned char *); PCRE_EXP_DECL int pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *, PCRE_SPTR16, int, int *, int); -PCRE_EXP_DECL int pcre32_utf32_to_host_byte_order(PCRE_UCHAR32 *, - PCRE_SPTR32, int, int *, int); /* JIT compiler related functions. */ PCRE_EXP_DECL pcre_jit_stack *pcre_jit_stack_alloc(int, int); PCRE_EXP_DECL pcre16_jit_stack *pcre16_jit_stack_alloc(int, int); -PCRE_EXP_DECL pcre32_jit_stack *pcre32_jit_stack_alloc(int, int); PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *); PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *); -PCRE_EXP_DECL void pcre32_jit_stack_free(pcre32_jit_stack *); PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *, pcre_jit_callback, void *); PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *, pcre16_jit_callback, void *); -PCRE_EXP_DECL void pcre32_assign_jit_stack(pcre32_extra *, - pcre32_jit_callback, void *); #ifdef __cplusplus } /* extern "C" */ diff --git a/harbour/src/3rd/pcre/pcrebyte.c b/harbour/src/3rd/pcre/pcrebyte.c index 4f1cffaeff..2ada8f79f0 100644 --- a/harbour/src/3rd/pcre/pcrebyte.c +++ b/harbour/src/3rd/pcre/pcrebyte.c @@ -95,15 +95,12 @@ Arguments: Returns: 0 if the swap is successful, negative on error */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DECL int pcre_pattern_to_host_byte_order(pcre *argument_re, pcre_extra *extra_data, const unsigned char *tables) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DECL int pcre16_pattern_to_host_byte_order(pcre16 *argument_re, pcre16_extra *extra_data, const unsigned char *tables) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DECL int pcre32_pattern_to_host_byte_order(pcre32 *argument_re, - pcre32_extra *extra_data, const unsigned char *tables) #endif { REAL_PCRE *re = (REAL_PCRE *)argument_re; @@ -111,10 +108,10 @@ pcre_study_data *study; #ifndef COMPILE_PCRE8 pcre_uchar *ptr; int length; -#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +#ifdef SUPPORT_UTF BOOL utf; BOOL utf16_char; -#endif /* SUPPORT_UTF && COMPILE_PCRE16 */ +#endif /* SUPPORT_UTF */ #endif /* !COMPILE_PCRE8 */ if (re == NULL) return PCRE_ERROR_NULL; @@ -134,22 +131,13 @@ re->options = swap_uint32(re->options); re->flags = swap_uint16(re->flags); re->top_bracket = swap_uint16(re->top_bracket); re->top_backref = swap_uint16(re->top_backref); -#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 re->first_char = swap_uint16(re->first_char); re->req_char = swap_uint16(re->req_char); -#elif defined COMPILE_PCRE32 -re->first_char = swap_uint32(re->first_char); -re->req_char = swap_uint32(re->req_char); -#endif re->name_table_offset = swap_uint16(re->name_table_offset); re->name_entry_size = swap_uint16(re->name_entry_size); re->name_count = swap_uint16(re->name_count); re->ref_count = swap_uint16(re->ref_count); re->tables = tables; -#ifdef COMPILE_PCRE32 -re->dummy1 = swap_uint16(re->dummy1); -re->dummy2 = swap_uint16(re->dummy2); -#endif if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) { @@ -162,24 +150,20 @@ if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) #ifndef COMPILE_PCRE8 ptr = (pcre_uchar *)re + re->name_table_offset; length = re->name_count * re->name_entry_size; -#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +#ifdef SUPPORT_UTF utf = (re->options & PCRE_UTF16) != 0; utf16_char = FALSE; -#endif /* SUPPORT_UTF && COMPILE_PCRE16 */ +#endif while(TRUE) { /* Swap previous characters. */ while (length-- > 0) { -#if defined COMPILE_PCRE16 *ptr = swap_uint16(*ptr); -#elif defined COMPILE_PCRE32 - *ptr = swap_uint32(*ptr); -#endif ptr++; } -#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +#ifdef SUPPORT_UTF if (utf16_char) { if (HAS_EXTRALEN(ptr[-1])) @@ -194,17 +178,13 @@ while(TRUE) /* Get next opcode. */ length = 0; -#if defined COMPILE_PCRE16 *ptr = swap_uint16(*ptr); -#elif defined COMPILE_PCRE32 - *ptr = swap_uint32(*ptr); -#endif switch (*ptr) { case OP_END: return 0; -#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +#ifdef SUPPORT_UTF case OP_CHAR: case OP_CHARI: case OP_NOT: @@ -279,26 +259,16 @@ while(TRUE) case OP_XCLASS: /* Reverse the size of the XCLASS instance. */ ptr++; -#if defined COMPILE_PCRE16 *ptr = swap_uint16(*ptr); -#elif defined COMPILE_PCRE32 - *ptr = swap_uint32(*ptr); -#endif -#ifndef COMPILE_PCRE32 if (LINK_SIZE > 1) { /* LINK_SIZE can be 1 or 2 in 16 bit mode. */ ptr++; *ptr = swap_uint16(*ptr); } -#endif ptr++; length = (GET(ptr, -LINK_SIZE)) - (1 + LINK_SIZE + 1); -#if defined COMPILE_PCRE16 *ptr = swap_uint16(*ptr); -#elif defined COMPILE_PCRE32 - *ptr = swap_uint32(*ptr); -#endif if ((*ptr & XCL_MAP) != 0) { /* Skip the character bit map. */ @@ -309,7 +279,7 @@ while(TRUE) } ptr++; } -/* Control should never reach here in 16/32 bit mode. */ +/* Control should never reach here in 16 bit mode. */ #endif /* !COMPILE_PCRE8 */ return 0; diff --git a/harbour/src/3rd/pcre/pcrecomp.c b/harbour/src/3rd/pcre/pcrecomp.c index 2fc9392ffb..9896d37e27 100644 --- a/harbour/src/3rd/pcre/pcrecomp.c +++ b/harbour/src/3rd/pcre/pcrecomp.c @@ -53,7 +53,7 @@ supporting internal functions that are not used by other modules. */ #include "pcreinal.h" -/* When PCRE_DEBUG is defined, we need the pcre(16|32)_printint() function, which +/* When PCRE_DEBUG is defined, we need the pcre(16)_printint() function, which is also used by pcretest. PCRE_DEBUG is not defined when building a production library. We do not need to select pcre16_printint.c specially, because the COMPILE_PCREx macro will already be appropriately set. */ @@ -68,7 +68,7 @@ COMPILE_PCREx macro will already be appropriately set. */ /* Macro for setting individual bits in class bitmaps. */ -#define SETBIT(a,b) a[(b)/8] |= (1 << ((b)&7)) +#define SETBIT(a,b) a[b/8] |= (1 << (b%8)) /* Maximum length value to check against when making sure that the integer that holds the compiled pattern length does not overflow. We make it a bit less than @@ -77,18 +77,6 @@ to check them every time. */ #define OFLOW_MAX (INT_MAX - 20) -/* Definitions to allow mutual recursion */ - -static int - add_list_to_class(pcre_uint8 *, pcre_uchar **, int, compile_data *, - const pcre_uint32 *, unsigned int); - -static BOOL - compile_regex(int, pcre_uchar **, const pcre_uchar **, int *, BOOL, BOOL, int, int, - pcre_uint32 *, pcre_int32 *, pcre_uint32 *, pcre_int32 *, branch_chain *, - compile_data *, int *); - - /************************************************* * Code parameters and static tables * @@ -122,11 +110,8 @@ overrun before it actually does run off the end of the data block. */ /* Private flags added to firstchar and reqchar. */ -#define REQ_CASELESS (1 << 0) /* Indicates caselessness */ -#define REQ_VARY (1 << 1) /* Reqchar followed non-literal item */ -/* Negative values for the firstchar and reqchar flags */ -#define REQ_UNSET (-2) -#define REQ_NONE (-1) +#define REQ_CASELESS 0x10000000l /* Indicates caselessness */ +#define REQ_VARY 0x20000000l /* Reqchar followed non-literal item */ /* Repeated character flags. */ @@ -507,7 +492,6 @@ static const char error_texts[] = /* 75 */ "name is too long in (*MARK), (*PRUNE), (*SKIP), or (*THEN)\0" "character value in \\u.... sequence is too large\0" - "invalid UTF-32 string\0" ; /* Table to identify digits and hex digits. This is used when compiling @@ -647,6 +631,13 @@ static const pcre_uint8 ebcdic_chartab[] = { /* chartable partial dup */ #endif +/* Definition to allow mutual recursion */ + +static BOOL + compile_regex(int, pcre_uchar **, const pcre_uchar **, int *, BOOL, BOOL, int, int, + int *, int *, branch_chain *, compile_data *, int *); + + /************************************************* * Find an error text * @@ -667,8 +658,8 @@ find_error_text(int n) const char *s = error_texts; for (; n > 0; n--) { - while (*s++ != CHAR_NULL) {}; - if (*s == CHAR_NULL) return "Error text not found (please report)"; + while (*s++ != 0) {}; + if (*s == 0) return "Error text not found (please report)"; } return s; } @@ -751,36 +742,33 @@ return (*p == CHAR_RIGHT_CURLY_BRACKET); *************************************************/ /* This function is called when a \ has been encountered. It either returns a -positive value for a simple escape such as \n, or 0 for a data character -which will be placed in chptr. A backreference to group n is returned as -negative n. When UTF-8 is enabled, a positive value greater than 255 may -be returned in chptr. -On entry,ptr is pointing at the \. On exit, it is on the final character of the -escape sequence. +positive value for a simple escape such as \n, or a negative value which +encodes one of the more complicated things such as \d. A backreference to group +n is returned as -(ESC_REF + n); ESC_REF is the highest ESC_xxx macro. When +UTF-8 is enabled, a positive value greater than 255 may be returned. On entry, +ptr is pointing at the \. On exit, it is on the final character of the escape +sequence. Arguments: ptrptr points to the pattern position pointer - chptr points to the data character errorcodeptr points to the errorcode variable bracount number of previous extracting brackets options the options bits isclass TRUE if inside a character class -Returns: zero => a data character - positive => a special escape sequence - negative => a back reference +Returns: zero or positive => a data character + negative => a special escape sequence on error, errorcodeptr is set */ static int -check_escape(const pcre_uchar **ptrptr, pcre_uint32 *chptr, int *errorcodeptr, - int bracount, int options, BOOL isclass) +check_escape(const pcre_uchar **ptrptr, int *errorcodeptr, int bracount, + int options, BOOL isclass) { /* PCRE_UTF16 has the same value as PCRE_UTF8. */ BOOL utf = (options & PCRE_UTF8) != 0; const pcre_uchar *ptr = *ptrptr + 1; -pcre_uint32 c; -int escape = 0; +pcre_int32 c; int i; GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */ @@ -788,7 +776,7 @@ ptr--; /* Set pointer back to the last byte */ /* If backslash is at the end of the pattern, it's an error. */ -if (c == CHAR_NULL) *errorcodeptr = ERR1; +if (c == 0) *errorcodeptr = ERR1; /* Non-alphanumerics are literals. For digits or letters, do an initial lookup in a table. A non-zero result is something that can be returned immediately. @@ -797,12 +785,12 @@ Otherwise further processing may be required. */ #ifndef EBCDIC /* ASCII/UTF-8 coding */ /* Not alphanumeric */ else if (c < CHAR_0 || c > CHAR_z) {} -else if ((i = escapes[c - CHAR_0]) != 0) { if (i > 0) c = (pcre_uint32)i; else escape = -i; } +else if ((i = escapes[c - CHAR_0]) != 0) c = i; #else /* EBCDIC coding */ /* Not alphanumeric */ -else if (c < CHAR_a || (!MAX_255(c) || (ebcdic_chartab[c] & 0x0E) == 0)) {} -else if ((i = escapes[c - 0x48]) != 0) { if (i > 0) c = (pcre_uint32)i; else escape = -i; } +else if (c < 'a' || (!MAX_255(c) || (ebcdic_chartab[c] & 0x0E) == 0)) {} +else if ((i = escapes[c - 0x48]) != 0) c = i; #endif /* Escapes that need further processing, or are illegal. */ @@ -810,8 +798,7 @@ else if ((i = escapes[c - 0x48]) != 0) { if (i > 0) c = (pcre_uint32)i; else es else { const pcre_uchar *oldptr; - BOOL braced, negated, overflow; - int s; + BOOL braced, negated; switch (c) { @@ -836,7 +823,7 @@ else c = 0; for (i = 0; i < 4; ++i) { - register pcre_uint32 cc = *(++ptr); + register int cc = *(++ptr); #ifndef EBCDIC /* ASCII/UTF-8 coding */ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); @@ -846,12 +833,12 @@ else #endif } -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 if (c > (utf ? 0x10ffff : 0xff)) -#elif defined COMPILE_PCRE16 +#else +#ifdef COMPILE_PCRE16 if (c > (utf ? 0x10ffff : 0xffff)) -#elif defined COMPILE_PCRE32 - if (utf && c > 0x10ffff) +#endif #endif { *errorcodeptr = ERR76; @@ -883,13 +870,13 @@ else (3) For Oniguruma compatibility we also support \g followed by a name or a number either in angle brackets or in single quotes. However, these are (possibly recursive) subroutine calls, _not_ backreferences. Just return - the ESC_g code (cf \k). */ + the -ESC_g code (cf \k). */ case CHAR_g: if (isclass) break; if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE) { - escape = ESC_g; + c = -ESC_g; break; } @@ -898,11 +885,11 @@ else if (ptr[1] == CHAR_LEFT_CURLY_BRACKET) { const pcre_uchar *p; - for (p = ptr+2; *p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET; p++) + for (p = ptr+2; *p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET; p++) if (*p != CHAR_MINUS && !IS_DIGIT(*p)) break; - if (*p != CHAR_NULL && *p != CHAR_RIGHT_CURLY_BRACKET) + if (*p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET) { - escape = ESC_k; + c = -ESC_k; break; } braced = TRUE; @@ -918,18 +905,17 @@ else else negated = FALSE; /* The integer range is limited by the machine's int representation. */ - s = 0; - overflow = FALSE; + c = 0; while (IS_DIGIT(ptr[1])) { - if (s > INT_MAX / 10 - 1) /* Integer overflow */ + if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */ { - overflow = TRUE; + c = -1; break; } - s = s * 10 + (int)(*(++ptr) - CHAR_0); + c = c * 10 + *(++ptr) - CHAR_0; } - if (overflow) /* Integer overflow */ + if (((unsigned int)c) > INT_MAX) /* Integer overflow */ { while (IS_DIGIT(ptr[1])) ptr++; @@ -943,7 +929,7 @@ else break; } - if (s == 0) + if (c == 0) { *errorcodeptr = ERR58; break; @@ -951,15 +937,15 @@ else if (negated) { - if (s > bracount) + if (c > bracount) { *errorcodeptr = ERR15; break; } - s = bracount - (s - 1); + c = bracount - (c - 1); } - escape = -s; + c = -(ESC_REF + c); break; /* The handling of escape sequences consisting of a string of digits @@ -981,27 +967,26 @@ else { oldptr = ptr; /* The integer range is limited by the machine's int representation. */ - s = (int)(c -CHAR_0); - overflow = FALSE; + c -= CHAR_0; while (IS_DIGIT(ptr[1])) { - if (s > INT_MAX / 10 - 1) /* Integer overflow */ + if (((unsigned int)c) > INT_MAX / 10) /* Integer overflow */ { - overflow = TRUE; + c = -1; break; } - s = s * 10 + (int)(*(++ptr) - CHAR_0); + c = c * 10 + *(++ptr) - CHAR_0; } - if (overflow) /* Integer overflow */ + if (((unsigned int)c) > INT_MAX) /* Integer overflow */ { while (IS_DIGIT(ptr[1])) ptr++; *errorcodeptr = ERR61; break; } - if (s < 10 || s <= bracount) + if (c < 10 || c <= bracount) { - escape = -s; + c = -(ESC_REF + c); break; } ptr = oldptr; /* Put the pointer back and fall through */ @@ -1048,7 +1033,7 @@ else c = 0; for (i = 0; i < 2; ++i) { - register pcre_uint32 cc = *(++ptr); + register int cc = *(++ptr); #ifndef EBCDIC /* ASCII/UTF-8 coding */ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); @@ -1066,16 +1051,11 @@ else const pcre_uchar *pt = ptr + 2; c = 0; - overflow = FALSE; while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) { - register pcre_uint32 cc = *pt++; + register int cc = *pt++; if (c == 0 && cc == CHAR_0) continue; /* Leading zeroes */ -#ifdef COMPILE_PCRE32 - if (c >= 0x10000000l) { overflow = TRUE; break; } -#endif - #ifndef EBCDIC /* ASCII/UTF-8 coding */ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10)); @@ -1084,16 +1064,16 @@ else c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10)); #endif -#if defined COMPILE_PCRE8 - if (c > (utf ? 0x10ffff : 0xff)) { overflow = TRUE; break; } -#elif defined COMPILE_PCRE16 - if (c > (utf ? 0x10ffff : 0xffff)) { overflow = TRUE; break; } -#elif defined COMPILE_PCRE32 - if (utf && c > 0x10ffff) { overflow = TRUE; break; } +#ifdef COMPILE_PCRE8 + if (c > (utf ? 0x10ffff : 0xff)) { c = -1; break; } +#else +#ifdef COMPILE_PCRE16 + if (c > (utf ? 0x10ffff : 0xffff)) { c = -1; break; } +#endif #endif } - if (overflow) + if (c < 0) { while (MAX_255(*pt) && (digitab[*pt] & ctype_xdigit) != 0) pt++; *errorcodeptr = ERR34; @@ -1115,7 +1095,7 @@ else c = 0; while (i++ < 2 && MAX_255(ptr[1]) && (digitab[ptr[1]] & ctype_xdigit) != 0) { - pcre_uint32 cc; /* Some compilers don't like */ + int cc; /* Some compilers don't like */ cc = *(++ptr); /* ++ in initializers */ #ifndef EBCDIC /* ASCII/UTF-8 coding */ if (cc >= CHAR_a) cc -= 32; /* Convert to upper case */ @@ -1134,7 +1114,7 @@ else case CHAR_c: c = *(++ptr); - if (c == CHAR_NULL) + if (c == 0) { *errorcodeptr = ERR2; break; @@ -1174,22 +1154,23 @@ else newline". PCRE does not support \N{name}. However, it does support quantification such as \N{2,3}. */ -if (escape == ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET && +if (c == -ESC_N && ptr[1] == CHAR_LEFT_CURLY_BRACKET && !is_counted_repeat(ptr+2)) *errorcodeptr = ERR37; /* If PCRE_UCP is set, we change the values for \d etc. */ -if ((options & PCRE_UCP) != 0 && escape >= ESC_D && escape <= ESC_w) - escape += (ESC_DU - ESC_D); +if ((options & PCRE_UCP) != 0 && c <= -ESC_D && c >= -ESC_w) + c -= (ESC_DU - ESC_D); /* Set the pointer to the final character before returning. */ *ptrptr = ptr; -*chptr = c; -return escape; +return c; } + + #ifdef SUPPORT_UCP /************************************************* * Handle \P and \p * @@ -1203,24 +1184,21 @@ escape sequence. Argument: ptrptr points to the pattern position pointer negptr points to a boolean that is set TRUE for negation else FALSE - ptypeptr points to an unsigned int that is set to the type value - pdataptr points to an unsigned int that is set to the detailed property value + dptr points to an int that is set to the detailed property value errorcodeptr points to the error code variable -Returns: TRUE if the type value was found, or FALSE for an invalid type +Returns: type value from ucp_type_table, or -1 for an invalid type */ -static BOOL -get_ucp(const pcre_uchar **ptrptr, BOOL *negptr, unsigned int *ptypeptr, - unsigned int *pdataptr, int *errorcodeptr) +static int +get_ucp(const pcre_uchar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr) { -pcre_uchar c; -int i, bot, top; +int c, i, bot, top; const pcre_uchar *ptr = *ptrptr; pcre_uchar name[32]; c = *(++ptr); -if (c == CHAR_NULL) goto ERROR_RETURN; +if (c == 0) goto ERROR_RETURN; *negptr = FALSE; @@ -1237,7 +1215,7 @@ if (c == CHAR_LEFT_CURLY_BRACKET) for (i = 0; i < (int)(sizeof(name) / sizeof(pcre_uchar)) - 1; i++) { c = *(++ptr); - if (c == CHAR_NULL) goto ERROR_RETURN; + if (c == 0) goto ERROR_RETURN; if (c == CHAR_RIGHT_CURLY_BRACKET) break; name[i] = c; } @@ -1262,26 +1240,24 @@ top = PRIV(utt_size); while (bot < top) { - int r; i = (bot + top) >> 1; - r = STRCMP_UC_C8(name, PRIV(utt_names) + PRIV(utt)[i].name_offset); - if (r == 0) + c = STRCMP_UC_C8(name, PRIV(utt_names) + PRIV(utt)[i].name_offset); + if (c == 0) { - *ptypeptr = PRIV(utt)[i].type; - *pdataptr = PRIV(utt)[i].value; - return TRUE; + *dptr = PRIV(utt)[i].value; + return PRIV(utt)[i].type; } - if (r > 0) bot = i + 1; else top = i; + if (c > 0) bot = i + 1; else top = i; } *errorcodeptr = ERR47; *ptrptr = ptr; -return FALSE; +return -1; ERROR_RETURN: *errorcodeptr = ERR46; *ptrptr = ptr; -return FALSE; +return -1; } #endif @@ -1316,7 +1292,7 @@ int max = -1; /* Read the minimum value and do a paranoid check: a negative value indicates an integer overflow. */ -while (IS_DIGIT(*p)) min = min * 10 + (int)(*p++ - CHAR_0); +while (IS_DIGIT(*p)) min = min * 10 + *p++ - CHAR_0; if (min < 0 || min > 65535) { *errorcodeptr = ERR5; @@ -1331,7 +1307,7 @@ if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else if (*(++p) != CHAR_RIGHT_CURLY_BRACKET) { max = 0; - while(IS_DIGIT(*p)) max = max * 10 + (int)(*p++ - CHAR_0); + while(IS_DIGIT(*p)) max = max * 10 + *p++ - CHAR_0; if (max < 0 || max > 65535) { *errorcodeptr = ERR5; @@ -1386,7 +1362,7 @@ Arguments: name name to seek, or NULL if seeking a numbered subpattern lorn name length, or subpattern number if name is NULL xmode TRUE if we are in /x mode - utf TRUE if we are in UTF-8 / UTF-16 / UTF-32 mode + utf TRUE if we are in UTF-8 / UTF-16 mode count pointer to the current capturing subpattern number (updated) Returns: the number of the named subpattern, or -1 if not found @@ -1432,8 +1408,7 @@ if (ptr[0] == CHAR_LEFT_PARENTHESIS) else if (ptr[2] == CHAR_NUMBER_SIGN) { - for (ptr += 3; *ptr != CHAR_NULL; ptr++) - if (*ptr == CHAR_RIGHT_PARENTHESIS) break; + for (ptr += 3; *ptr != 0; ptr++) if (*ptr == CHAR_RIGHT_PARENTHESIS) break; goto FAIL_EXIT; } @@ -1446,8 +1421,8 @@ if (ptr[0] == CHAR_LEFT_PARENTHESIS) ptr += 2; if (ptr[1] != CHAR_QUESTION_MARK) { - while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; - if (*ptr != CHAR_NULL) ptr++; + while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; + if (*ptr != 0) ptr++; } } @@ -1463,7 +1438,7 @@ if (ptr[0] == CHAR_LEFT_PARENTHESIS) if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK && ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE) { - pcre_uchar term; + int term; const pcre_uchar *thisname; *count += 1; if (name == NULL && *count == lorn) return *count; @@ -1471,8 +1446,8 @@ if (ptr[0] == CHAR_LEFT_PARENTHESIS) if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN; thisname = ptr; while (*ptr != term) ptr++; - if (name != NULL && lorn == (int)(ptr - thisname) && - STRNCMP_UC_UC(name, thisname, (unsigned int)lorn) == 0) + if (name != NULL && lorn == ptr - thisname && + STRNCMP_UC_UC(name, thisname, lorn) == 0) return *count; term++; } @@ -1490,11 +1465,11 @@ for (; ptr < cd->end_pattern; ptr++) if (*ptr == CHAR_BACKSLASH) { - if (*(++ptr) == CHAR_NULL) goto FAIL_EXIT; + if (*(++ptr) == 0) goto FAIL_EXIT; if (*ptr == CHAR_Q) for (;;) { - while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {}; - if (*ptr == CHAR_NULL) goto FAIL_EXIT; + while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {}; + if (*ptr == 0) goto FAIL_EXIT; if (*(++ptr) == CHAR_E) break; } continue; @@ -1538,14 +1513,14 @@ for (; ptr < cd->end_pattern; ptr++) while (*(++ptr) != CHAR_RIGHT_SQUARE_BRACKET) { - if (*ptr == CHAR_NULL) return -1; + if (*ptr == 0) return -1; if (*ptr == CHAR_BACKSLASH) { - if (*(++ptr) == CHAR_NULL) goto FAIL_EXIT; + if (*(++ptr) == 0) goto FAIL_EXIT; if (*ptr == CHAR_Q) for (;;) { - while (*(++ptr) != CHAR_NULL && *ptr != CHAR_BACKSLASH) {}; - if (*ptr == CHAR_NULL) goto FAIL_EXIT; + while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {}; + if (*ptr == 0) goto FAIL_EXIT; if (*(++ptr) == CHAR_E) break; } continue; @@ -1559,7 +1534,7 @@ for (; ptr < cd->end_pattern; ptr++) if (xmode && *ptr == CHAR_NUMBER_SIGN) { ptr++; - while (*ptr != CHAR_NULL) + while (*ptr != 0) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } ptr++; @@ -1567,7 +1542,7 @@ for (; ptr < cd->end_pattern; ptr++) if (utf) FORWARDCHAR(ptr); #endif } - if (*ptr == CHAR_NULL) goto FAIL_EXIT; + if (*ptr == 0) goto FAIL_EXIT; continue; } @@ -1577,7 +1552,7 @@ for (; ptr < cd->end_pattern; ptr++) { int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, count); if (rc > 0) return rc; - if (*ptr == CHAR_NULL) goto FAIL_EXIT; + if (*ptr == 0) goto FAIL_EXIT; } else if (*ptr == CHAR_RIGHT_PARENTHESIS) @@ -1621,7 +1596,7 @@ Arguments: name name to seek, or NULL if seeking a numbered subpattern lorn name length, or subpattern number if name is NULL xmode TRUE if we are in /x mode - utf TRUE if we are in UTF-8 / UTF-16 / UTF-32 mode + utf TRUE if we are in UTF-8 / UTF-16 mode Returns: the number of the found subpattern, or -1 if not found */ @@ -1642,7 +1617,7 @@ matching closing parens. That is why we have to have a loop. */ for (;;) { rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf, &count); - if (rc > 0 || *ptr++ == CHAR_NULL) break; + if (rc > 0 || *ptr++ == 0) break; } return rc; @@ -1724,7 +1699,7 @@ and doing the check at the end; a flag specifies which mode we are running in. Arguments: code points to the start of the pattern (the bracket) - utf TRUE in UTF-8 / UTF-16 / UTF-32 mode + utf TRUE in UTF-8 / UTF-16 mode atend TRUE if called when the pattern is complete cd the "compile data" structure @@ -1750,7 +1725,7 @@ for (;;) { int d; pcre_uchar *ce, *cs; - register pcre_uchar op = *cc; + register int op = *cc; switch (op) { @@ -1870,7 +1845,7 @@ for (;;) case OP_EXACTI: case OP_NOTEXACT: case OP_NOTEXACTI: - branchlength += (int)GET2(cc,1); + branchlength += GET2(cc,1); cc += 2 + IMM2_SIZE; #ifdef SUPPORT_UTF if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); @@ -1879,8 +1854,7 @@ for (;;) case OP_TYPEEXACT: branchlength += GET2(cc,1); - if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) - cc += 2; + if (cc[1 + IMM2_SIZE] == OP_PROP || cc[1 + IMM2_SIZE] == OP_NOTPROP) cc += 2; cc += 1 + IMM2_SIZE + 1; break; @@ -1915,19 +1889,15 @@ for (;;) /* Check a class for variable quantification */ +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 + case OP_XCLASS: + cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS]; + /* Fall through */ +#endif + case OP_CLASS: case OP_NCLASS: -#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - case OP_XCLASS: - /* The original code caused an unsigned overflow in 64 bit systems, - so now we use a conditional statement. */ - if (op == OP_XCLASS) - cc += GET(cc, 1); - else - cc += PRIV(OP_lengths)[OP_CLASS]; -#else cc += PRIV(OP_lengths)[OP_CLASS]; -#endif switch (*cc) { @@ -1942,7 +1912,7 @@ for (;;) case OP_CRRANGE: case OP_CRMINRANGE: if (GET2(cc,1) != GET2(cc,1+IMM2_SIZE)) return -1; - branchlength += (int)GET2(cc,1); + branchlength += GET2(cc,1); cc += 1 + 2 * IMM2_SIZE; break; @@ -2058,7 +2028,7 @@ length. Arguments: code points to start of expression - utf TRUE in UTF-8 / UTF-16 / UTF-32 mode + utf TRUE in UTF-8 / UTF-16 mode number the required bracket number or negative to find a lookbehind Returns: pointer to the opcode for the bracket, or NULL if not found @@ -2069,7 +2039,7 @@ PRIV(find_bracket)(const pcre_uchar *code, BOOL utf, int number) { for (;;) { - register pcre_uchar c = *code; + register int c = *code; if (c == OP_END) return NULL; @@ -2092,7 +2062,7 @@ for (;;) else if (c == OP_CBRA || c == OP_SCBRA || c == OP_CBRAPOS || c == OP_SCBRAPOS) { - int n = (int)GET2(code, 1+LINK_SIZE); + int n = GET2(code, 1+LINK_SIZE); if (n == number) return (pcre_uchar *)code; code += PRIV(OP_lengths)[c]; } @@ -2122,8 +2092,8 @@ for (;;) case OP_TYPEMINUPTO: case OP_TYPEEXACT: case OP_TYPEPOSUPTO: - if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) - code += 2; + if (code[1 + IMM2_SIZE] == OP_PROP + || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; case OP_MARK: @@ -2145,7 +2115,7 @@ for (;;) a multi-byte character. The length in the table is a minimum, so we have to arrange to skip the extra bytes. */ -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf) switch(c) { case OP_CHAR: @@ -2197,7 +2167,7 @@ instance of OP_RECURSE. Arguments: code points to start of expression - utf TRUE in UTF-8 / UTF-16 / UTF-32 mode + utf TRUE in UTF-8 / UTF-16 mode Returns: pointer to the opcode for OP_RECURSE, or NULL if not found */ @@ -2207,7 +2177,7 @@ find_recurse(const pcre_uchar *code, BOOL utf) { for (;;) { - register pcre_uchar c = *code; + register int c = *code; if (c == OP_END) return NULL; if (c == OP_RECURSE) return code; @@ -2242,8 +2212,8 @@ for (;;) case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEEXACT: - if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) - code += 2; + if (code[1 + IMM2_SIZE] == OP_PROP + || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; case OP_MARK: @@ -2265,7 +2235,7 @@ for (;;) by a multi-byte character. The length in the table is a minimum, so we have to arrange to skip the extra bytes. */ -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf) switch(c) { case OP_CHAR: @@ -2351,7 +2321,7 @@ bracket whose current branch will already have been scanned. Arguments: code points to start of search endcode points to where to stop - utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode + utf TRUE if in UTF-8 / UTF-16 mode cd contains pointers to tables etc. Returns: TRUE if what is matched could be empty @@ -2361,7 +2331,7 @@ static BOOL could_be_empty_branch(const pcre_uchar *code, const pcre_uchar *endcode, BOOL utf, compile_data *cd) { -register pcre_uchar c; +register int c; for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); code < endcode; code = first_significant_code(code + PRIV(OP_lengths)[c], TRUE)) @@ -2395,7 +2365,7 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); /* Test for forward reference */ for (scode = cd->start_workspace; scode < cd->hwm; scode += LINK_SIZE) - if ((int)GET(scode, 0) == (int)(code + 1 - cd->start_code)) return TRUE; + if (GET(scode, 0) == code + 1 - cd->start_code) return TRUE; /* Not a forward reference, test for completed backward reference */ @@ -2568,8 +2538,8 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) - code += 2; + if (code[1 + IMM2_SIZE] == OP_PROP + || code[1 + IMM2_SIZE] == OP_NOTPROP) code += 2; break; /* End of branch */ @@ -2584,7 +2554,7 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE); /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO, MINUPTO, and POSUPTO may be followed by a multibyte character */ -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF case OP_STAR: case OP_STARI: case OP_MINSTAR: @@ -2650,7 +2620,7 @@ Arguments: code points to start of the recursion endcode points to where to stop (current RECURSE item) bcptr points to the chain of current (unclosed) branch starts - utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode + utf TRUE if in UTF-8 / UTF-16 mode cd pointers to tables etc Returns: TRUE if what is matched could be empty @@ -2716,9 +2686,9 @@ Returns: TRUE or FALSE static BOOL check_posix_syntax(const pcre_uchar *ptr, const pcre_uchar **endptr) { -pcre_uchar terminator; /* Don't combine these lines; the Solaris cc */ +int terminator; /* Don't combine these lines; the Solaris cc */ terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ -for (++ptr; *ptr != CHAR_NULL; ptr++) +for (++ptr; *ptr != 0; ptr++) { if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) ptr++; @@ -2765,7 +2735,7 @@ register int yield = 0; while (posix_name_lengths[yield] != 0) { if (len == posix_name_lengths[yield] && - STRNCMP_UC_C8(ptr, pn, (unsigned int)len) == 0) return yield; + STRNCMP_UC_C8(ptr, pn, len) == 0) return yield; pn += posix_name_lengths[yield] + 1; yield++; } @@ -2797,7 +2767,7 @@ value in the reference (which is a group number). Arguments: group points to the start of the group adjust the amount by which the group is to be moved - utf TRUE in UTF-8 / UTF-16 / UTF-32 mode + utf TRUE in UTF-8 / UTF-16 mode cd contains pointers to tables etc. save_hwm the hwm forward reference pointer at the start of the group @@ -2820,7 +2790,7 @@ while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL) for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE) { - offset = (int)GET(hc, 0); + offset = GET(hc, 0); if (cd->start_code + offset == ptr + 1) { PUT(hc, 0, offset + adjust); @@ -2833,7 +2803,7 @@ while ((ptr = (pcre_uchar *)find_recurse(ptr, utf)) != NULL) if (hc >= cd->hwm) { - offset = (int)GET(ptr, 1); + offset = GET(ptr, 1); if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust); } @@ -2901,10 +2871,9 @@ PUT(previous_callout, 2 + LINK_SIZE, length); *************************************************/ /* This function is passed the start and end of a class range, in UTF-8 mode -with UCP support. It searches up the characters, looking for ranges of +with UCP support. It searches up the characters, looking for internal ranges of characters in the "other" case. Each call returns the next one, updating the -start address. A character with multiple other cases is returned on its own -with a special return value. +start address. Arguments: cptr points to starting character value; updated @@ -2912,34 +2881,19 @@ Arguments: ocptr where to put start of othercase range odptr where to put end of othercase range -Yield: -1 when no more - 0 when a range is returned - >0 the CASESET offset for char with multiple other cases - in this case, ocptr contains the original +Yield: TRUE when range returned; FALSE when no more */ -static int -get_othercase_range(pcre_uint32 *cptr, pcre_uint32 d, pcre_uint32 *ocptr, - pcre_uint32 *odptr) +static BOOL +get_othercase_range(unsigned int *cptr, unsigned int d, unsigned int *ocptr, + unsigned int *odptr) { -pcre_uint32 c, othercase, next; -unsigned int co; - -/* Find the first character that has an other case. If it has multiple other -cases, return its case offset value. */ +unsigned int c, othercase, next; for (c = *cptr; c <= d; c++) - { - if ((co = UCD_CASESET(c)) != 0) - { - *ocptr = c++; /* Character that has the set */ - *cptr = c; /* Rest of input range */ - return (int)co; - } - if ((othercase = UCD_OTHERCASE(c)) != c) break; - } + { if ((othercase = UCD_OTHERCASE(c)) != c) break; } -if (c > d) return -1; /* Reached end of range */ +if (c > d) return FALSE; *ocptr = othercase; next = othercase + 1; @@ -2950,9 +2904,10 @@ for (++c; c <= d; c++) next++; } -*odptr = next - 1; /* End of othercase range */ -*cptr = c; /* Rest of input range */ -return 0; +*odptr = next - 1; +*cptr = c; + +return TRUE; } @@ -2974,14 +2929,9 @@ Returns: TRUE if auto-possessifying is OK */ static BOOL -check_char_prop(pcre_uint32 c, unsigned int ptype, unsigned int pdata, BOOL negated) +check_char_prop(int c, int ptype, int pdata, BOOL negated) { -#ifdef SUPPORT_UCP -const pcre_uint32 *p; -#endif - const ucd_record *prop = GET_UCD(c); - switch(ptype) { case PT_LAMP: @@ -3019,19 +2969,7 @@ switch(ptype) return (PRIV(ucp_gentype)[prop->chartype] == ucp_L || PRIV(ucp_gentype)[prop->chartype] == ucp_N || c == CHAR_UNDERSCORE) == negated; - -#ifdef SUPPORT_UCP - case PT_CLIST: - p = PRIV(ucd_caseless_sets) + prop->caseset; - for (;;) - { - if (c < *p) return !negated; - if (c == *p++) return negated; - } - break; /* Control never reaches here */ -#endif } - return FALSE; } #endif /* SUPPORT_UCP */ @@ -3048,7 +2986,7 @@ sense to automatically possessify the repeated item. Arguments: previous pointer to the repeated opcode - utf TRUE in UTF-8 / UTF-16 / UTF-32 mode + utf TRUE in UTF-8 / UTF-16 mode ptr next character in pattern options options bits cd contains pointers to tables etc. @@ -3060,10 +2998,8 @@ static BOOL check_auto_possessive(const pcre_uchar *previous, BOOL utf, const pcre_uchar *ptr, int options, compile_data *cd) { -pcre_uint32 c = NOTACHAR; -pcre_uint32 next; -int escape; -pcre_uchar op_code = *previous++; +pcre_int32 c, next; +int op_code = *previous++; /* Skip whitespace and comments in extended mode */ @@ -3075,7 +3011,7 @@ if ((options & PCRE_EXTENDED) != 0) if (*ptr == CHAR_NUMBER_SIGN) { ptr++; - while (*ptr != CHAR_NULL) + while (*ptr != 0) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } ptr++; @@ -3094,13 +3030,12 @@ value is a character, a negative value is an escape value. */ if (*ptr == CHAR_BACKSLASH) { int temperrorcode = 0; - escape = check_escape(&ptr, &next, &temperrorcode, cd->bracount, options, FALSE); + next = check_escape(&ptr, &temperrorcode, cd->bracount, options, FALSE); if (temperrorcode != 0) return FALSE; ptr++; /* Point after the escape sequence */ } else if (!MAX_255(*ptr) || (cd->ctypes[*ptr] & ctype_meta) == 0) { - escape = 0; #ifdef SUPPORT_UTF if (utf) { GETCHARINC(next, ptr); } else #endif @@ -3118,7 +3053,7 @@ if ((options & PCRE_EXTENDED) != 0) if (*ptr == CHAR_NUMBER_SIGN) { ptr++; - while (*ptr != CHAR_NULL) + while (*ptr != 0) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; } ptr++; @@ -3137,140 +3072,156 @@ if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK || STRNCMP_UC_C8(ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0) return FALSE; -/* If the previous item is a character, get its value. */ +/* Now compare the next item with the previous opcode. First, handle cases when +the next item is a character. */ -if (op_code == OP_CHAR || op_code == OP_CHARI || - op_code == OP_NOT || op_code == OP_NOTI) +if (next >= 0) switch(op_code) { + case OP_CHAR: #ifdef SUPPORT_UTF GETCHARTEST(c, previous); #else c = *previous; #endif - } + return c != next; -/* Now compare the next item with the previous opcode. First, handle cases when -the next item is a character. */ + /* For CHARI (caseless character) we must check the other case. If we have + Unicode property support, we can use it to test the other case of + high-valued characters. */ -if (escape == 0) - { - /* For a caseless UTF match, the next character may have more than one other - case, which maps to the special PT_CLIST property. Check this first. */ - -#ifdef SUPPORT_UCP - if (utf && c != NOTACHAR && (options & PCRE_CASELESS) != 0) + case OP_CHARI: +#ifdef SUPPORT_UTF + GETCHARTEST(c, previous); +#else + c = *previous; +#endif + if (c == next) return FALSE; +#ifdef SUPPORT_UTF + if (utf) { - unsigned int ocs = UCD_CASESET(next); - if (ocs > 0) return check_char_prop(c, PT_CLIST, ocs, op_code >= OP_NOT); + unsigned int othercase; + if (next < 128) othercase = cd->fcc[next]; else +#ifdef SUPPORT_UCP + othercase = UCD_OTHERCASE((unsigned int)next); +#else + othercase = NOTACHAR; +#endif + return (unsigned int)c != othercase; } -#endif + else +#endif /* SUPPORT_UTF */ + return (c != TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */ - switch(op_code) + case OP_NOT: +#ifdef SUPPORT_UTF + GETCHARTEST(c, previous); +#else + c = *previous; +#endif + return c == next; + + case OP_NOTI: +#ifdef SUPPORT_UTF + GETCHARTEST(c, previous); +#else + c = *previous; +#endif + if (c == next) return TRUE; +#ifdef SUPPORT_UTF + if (utf) { - case OP_CHAR: - return c != next; - - /* For CHARI (caseless character) we must check the other case. If we have - Unicode property support, we can use it to test the other case of - high-valued characters. We know that next can have only one other case, - because multi-other-case characters are dealt with above. */ - - case OP_CHARI: - if (c == next) return FALSE; -#ifdef SUPPORT_UTF - if (utf) - { - pcre_uint32 othercase; - if (next < 128) othercase = cd->fcc[next]; else + unsigned int othercase; + if (next < 128) othercase = cd->fcc[next]; else #ifdef SUPPORT_UCP - othercase = UCD_OTHERCASE(next); + othercase = UCD_OTHERCASE((unsigned int)next); #else - othercase = NOTACHAR; + othercase = NOTACHAR; #endif - return c != othercase; - } - else + return (unsigned int)c == othercase; + } + else #endif /* SUPPORT_UTF */ - return (c != TABLE_GET(next, cd->fcc, next)); /* Not UTF */ + return (c == TABLE_GET((unsigned int)next, cd->fcc, next)); /* Non-UTF-8 mode */ - case OP_NOT: - return c == next; + /* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set. + When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ - case OP_NOTI: - if (c == next) return TRUE; -#ifdef SUPPORT_UTF - if (utf) - { - pcre_uint32 othercase; - if (next < 128) othercase = cd->fcc[next]; else -#ifdef SUPPORT_UCP - othercase = UCD_OTHERCASE(next); -#else - othercase = NOTACHAR; -#endif - return c == othercase; - } - else -#endif /* SUPPORT_UTF */ - return (c == TABLE_GET(next, cd->fcc, next)); /* Not UTF */ + case OP_DIGIT: + return next > 255 || (cd->ctypes[next] & ctype_digit) == 0; - /* Note that OP_DIGIT etc. are generated only when PCRE_UCP is *not* set. - When it is set, \d etc. are converted into OP_(NOT_)PROP codes. */ + case OP_NOT_DIGIT: + return next <= 255 && (cd->ctypes[next] & ctype_digit) != 0; - case OP_DIGIT: - return next > 255 || (cd->ctypes[next] & ctype_digit) == 0; + case OP_WHITESPACE: + return next > 255 || (cd->ctypes[next] & ctype_space) == 0; - case OP_NOT_DIGIT: - return next <= 255 && (cd->ctypes[next] & ctype_digit) != 0; + case OP_NOT_WHITESPACE: + return next <= 255 && (cd->ctypes[next] & ctype_space) != 0; - case OP_WHITESPACE: - return next > 255 || (cd->ctypes[next] & ctype_space) == 0; + case OP_WORDCHAR: + return next > 255 || (cd->ctypes[next] & ctype_word) == 0; - case OP_NOT_WHITESPACE: - return next <= 255 && (cd->ctypes[next] & ctype_space) != 0; - - case OP_WORDCHAR: - return next > 255 || (cd->ctypes[next] & ctype_word) == 0; - - case OP_NOT_WORDCHAR: - return next <= 255 && (cd->ctypes[next] & ctype_word) != 0; - - case OP_HSPACE: - case OP_NOT_HSPACE: - switch(next) - { - HSPACE_CASES: - return op_code == OP_NOT_HSPACE; - - default: - return op_code != OP_NOT_HSPACE; - } - - case OP_ANYNL: - case OP_VSPACE: - case OP_NOT_VSPACE: - switch(next) - { - VSPACE_CASES: - return op_code == OP_NOT_VSPACE; - - default: - return op_code != OP_NOT_VSPACE; - } - -#ifdef SUPPORT_UCP - case OP_PROP: - return check_char_prop(next, previous[0], previous[1], FALSE); - - case OP_NOTPROP: - return check_char_prop(next, previous[0], previous[1], TRUE); -#endif + case OP_NOT_WORDCHAR: + return next <= 255 && (cd->ctypes[next] & ctype_word) != 0; + case OP_HSPACE: + case OP_NOT_HSPACE: + switch(next) + { + case 0x09: + case 0x20: + case 0xa0: + case 0x1680: + case 0x180e: + case 0x2000: + case 0x2001: + case 0x2002: + case 0x2003: + case 0x2004: + case 0x2005: + case 0x2006: + case 0x2007: + case 0x2008: + case 0x2009: + case 0x200A: + case 0x202f: + case 0x205f: + case 0x3000: + return op_code == OP_NOT_HSPACE; default: - return FALSE; + return op_code != OP_NOT_HSPACE; } + + case OP_ANYNL: + case OP_VSPACE: + case OP_NOT_VSPACE: + switch(next) + { + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x85: + case 0x2028: + case 0x2029: + return op_code == OP_NOT_VSPACE; + default: + return op_code != OP_NOT_VSPACE; + } + +#ifdef SUPPORT_UCP + case OP_PROP: + return check_char_prop(next, previous[0], previous[1], FALSE); + + case OP_NOTPROP: + return check_char_prop(next, previous[0], previous[1], TRUE); +#endif + + default: + return FALSE; } + /* Handle the case when the next item is \d, \s, etc. Note that when PCRE_UCP is set, \d turns into ESC_du rather than ESC_d, etc., so ESC_d etc. are generated only when PCRE_UCP is *not* set, that is, when only ASCII @@ -3281,7 +3232,12 @@ switch(op_code) { case OP_CHAR: case OP_CHARI: - switch(escape) +#ifdef SUPPORT_UTF + GETCHARTEST(c, previous); +#else + c = *previous; +#endif + switch(-next) { case ESC_d: return c > 255 || (cd->ctypes[c] & ctype_digit) == 0; @@ -3305,27 +3261,49 @@ switch(op_code) case ESC_H: switch(c) { - HSPACE_CASES: - return escape != ESC_h; - + case 0x09: + case 0x20: + case 0xa0: + case 0x1680: + case 0x180e: + case 0x2000: + case 0x2001: + case 0x2002: + case 0x2003: + case 0x2004: + case 0x2005: + case 0x2006: + case 0x2007: + case 0x2008: + case 0x2009: + case 0x200A: + case 0x202f: + case 0x205f: + case 0x3000: + return -next != ESC_h; default: - return escape == ESC_h; + return -next == ESC_h; } case ESC_v: case ESC_V: switch(c) { - VSPACE_CASES: - return escape != ESC_v; - + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + case 0x85: + case 0x2028: + case 0x2029: + return -next != ESC_v; default: - return escape == ESC_v; + return -next == ESC_v; } /* When PCRE_UCP is set, these values get generated for \d etc. Find their substitutions and process them. The result will always be either - ESC_p or ESC_P. Then fall through to process those values. */ + -ESC_p or -ESC_P. Then fall through to process those values. */ #ifdef SUPPORT_UCP case ESC_du: @@ -3336,8 +3314,8 @@ switch(op_code) case ESC_SU: { int temperrorcode = 0; - ptr = substitutes[escape - ESC_DU]; - escape = check_escape(&ptr, &next, &temperrorcode, 0, options, FALSE); + ptr = substitutes[-next - ESC_DU]; + next = check_escape(&ptr, &temperrorcode, 0, options, FALSE); if (temperrorcode != 0) return FALSE; ptr++; /* For compatibility */ } @@ -3346,13 +3324,12 @@ switch(op_code) case ESC_p: case ESC_P: { - unsigned int ptype = 0, pdata = 0; - int errorcodeptr; + int ptype, pdata, errorcodeptr; BOOL negated; ptr--; /* Make ptr point at the p or P */ - if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcodeptr)) - return FALSE; + ptype = get_ucp(&ptr, &negated, &pdata, &errorcodeptr); + if (ptype < 0) return FALSE; ptr++; /* Point past the final curly ket */ /* If the property item is optional, we have to give up. (When generated @@ -3365,7 +3342,7 @@ switch(op_code) /* Do the property check. */ - return check_char_prop(c, ptype, pdata, (escape == ESC_P) != negated); + return check_char_prop(c, ptype, pdata, (next == -ESC_P) != negated); } #endif @@ -3380,39 +3357,39 @@ switch(op_code) these op-codes are never generated.) */ case OP_DIGIT: - return escape == ESC_D || escape == ESC_s || escape == ESC_W || - escape == ESC_h || escape == ESC_v || escape == ESC_R; + return next == -ESC_D || next == -ESC_s || next == -ESC_W || + next == -ESC_h || next == -ESC_v || next == -ESC_R; case OP_NOT_DIGIT: - return escape == ESC_d; + return next == -ESC_d; case OP_WHITESPACE: - return escape == ESC_S || escape == ESC_d || escape == ESC_w; + return next == -ESC_S || next == -ESC_d || next == -ESC_w; case OP_NOT_WHITESPACE: - return escape == ESC_s || escape == ESC_h || escape == ESC_v || escape == ESC_R; + return next == -ESC_s || next == -ESC_h || next == -ESC_v || next == -ESC_R; case OP_HSPACE: - return escape == ESC_S || escape == ESC_H || escape == ESC_d || - escape == ESC_w || escape == ESC_v || escape == ESC_R; + return next == -ESC_S || next == -ESC_H || next == -ESC_d || + next == -ESC_w || next == -ESC_v || next == -ESC_R; case OP_NOT_HSPACE: - return escape == ESC_h; + return next == -ESC_h; /* Can't have \S in here because VT matches \S (Perl anomaly) */ case OP_ANYNL: case OP_VSPACE: - return escape == ESC_V || escape == ESC_d || escape == ESC_w; + return next == -ESC_V || next == -ESC_d || next == -ESC_w; case OP_NOT_VSPACE: - return escape == ESC_v || escape == ESC_R; + return next == -ESC_v || next == -ESC_R; case OP_WORDCHAR: - return escape == ESC_W || escape == ESC_s || escape == ESC_h || - escape == ESC_v || escape == ESC_R; + return next == -ESC_W || next == -ESC_s || next == -ESC_h || + next == -ESC_v || next == -ESC_R; case OP_NOT_WORDCHAR: - return escape == ESC_w || escape == ESC_d; + return next == -ESC_w || next == -ESC_d; default: return FALSE; @@ -3423,244 +3400,6 @@ switch(op_code) -/************************************************* -* Add a character or range to a class * -*************************************************/ - -/* This function packages up the logic of adding a character or range of -characters to a class. The character values in the arguments will be within the -valid values for the current mode (8-bit, 16-bit, UTF, etc). This function is -mutually recursive with the function immediately below. - -Arguments: - classbits the bit map for characters < 256 - uchardptr points to the pointer for extra data - options the options word - cd contains pointers to tables etc. - start start of range character - end end of range character - -Returns: the number of < 256 characters added - the pointer to extra data is updated -*/ - -static int -add_to_class(pcre_uint8 *classbits, pcre_uchar **uchardptr, int options, - compile_data *cd, pcre_uint32 start, pcre_uint32 end) -{ -pcre_uint32 c; -int n8 = 0; - -/* If caseless matching is required, scan the range and process alternate -cases. In Unicode, there are 8-bit characters that have alternate cases that -are greater than 255 and vice-versa. Sometimes we can just extend the original -range. */ - -if ((options & PCRE_CASELESS) != 0) - { -#ifdef SUPPORT_UCP - if ((options & PCRE_UTF8) != 0) - { - int rc; - pcre_uint32 oc, od; - - options &= ~PCRE_CASELESS; /* Remove for recursive calls */ - c = start; - - while ((rc = get_othercase_range(&c, end, &oc, &od)) >= 0) - { - /* Handle a single character that has more than one other case. */ - - if (rc > 0) n8 += add_list_to_class(classbits, uchardptr, options, cd, - PRIV(ucd_caseless_sets) + rc, oc); - - /* Do nothing if the other case range is within the original range. */ - - else if (oc >= start && od <= end) continue; - - /* Extend the original range if there is overlap, noting that if oc < c, we - can't have od > end because a subrange is always shorter than the basic - range. Otherwise, use a recursive call to add the additional range. */ - - else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */ - else if (od > end && oc <= end + 1) end = od; /* Extend upwards */ - else n8 += add_to_class(classbits, uchardptr, options, cd, oc, od); - } - } - else -#endif /* SUPPORT_UCP */ - - /* Not UTF-mode, or no UCP */ - - for (c = start; c <= end && c < 256; c++) - { - SETBIT(classbits, cd->fcc[c]); - n8++; - } - } - -/* Now handle the original range. Adjust the final value according to the bit -length - this means that the same lists of (e.g.) horizontal spaces can be used -in all cases. */ - -#if defined COMPILE_PCRE8 -#ifdef SUPPORT_UTF - if ((options & PCRE_UTF8) == 0) -#endif - if (end > 0xff) end = 0xff; - -#elif defined COMPILE_PCRE16 -#ifdef SUPPORT_UTF - if ((options & PCRE_UTF16) == 0) -#endif - if (end > 0xffff) end = 0xffff; - -#endif /* COMPILE_PCRE[8|16] */ - -/* If all characters are less than 256, use the bit map. Otherwise use extra -data. */ - -if (end < 0x100) - { - for (c = start; c <= end; c++) - { - n8++; - SETBIT(classbits, c); - } - } - -else - { - pcre_uchar *uchardata = *uchardptr; - -#ifdef SUPPORT_UTF - if ((options & PCRE_UTF8) != 0) /* All UTFs use the same flag bit */ - { - if (start < end) - { - *uchardata++ = XCL_RANGE; - uchardata += PRIV(ord2utf)(start, uchardata); - uchardata += PRIV(ord2utf)(end, uchardata); - } - else if (start == end) - { - *uchardata++ = XCL_SINGLE; - uchardata += PRIV(ord2utf)(start, uchardata); - } - } - else -#endif /* SUPPORT_UTF */ - - /* Without UTF support, character values are constrained by the bit length, - and can only be > 256 for 16-bit and 32-bit libraries. */ - -#ifdef COMPILE_PCRE8 - {} -#else - if (start < end) - { - *uchardata++ = XCL_RANGE; - *uchardata++ = start; - *uchardata++ = end; - } - else if (start == end) - { - *uchardata++ = XCL_SINGLE; - *uchardata++ = start; - } -#endif - - *uchardptr = uchardata; /* Updata extra data pointer */ - } - -return n8; /* Number of 8-bit characters */ -} - - - - -/************************************************* -* Add a list of characters to a class * -*************************************************/ - -/* This function is used for adding a list of case-equivalent characters to a -class, and also for adding a list of horizontal or vertical whitespace. If the -list is in order (which it should be), ranges of characters are detected and -handled appropriately. This function is mutually recursive with the function -above. - -Arguments: - classbits the bit map for characters < 256 - uchardptr points to the pointer for extra data - options the options word - cd contains pointers to tables etc. - p points to row of 32-bit values, terminated by NOTACHAR - except character to omit; this is used when adding lists of - case-equivalent characters to avoid including the one we - already know about - -Returns: the number of < 256 characters added - the pointer to extra data is updated -*/ - -static int -add_list_to_class(pcre_uint8 *classbits, pcre_uchar **uchardptr, int options, - compile_data *cd, const pcre_uint32 *p, unsigned int except) -{ -int n8 = 0; -while (p[0] < NOTACHAR) - { - int n = 0; - if (p[0] != except) - { - while(p[n+1] == p[0] + n + 1) n++; - n8 += add_to_class(classbits, uchardptr, options, cd, p[0], p[n]); - } - p += n + 1; - } -return n8; -} - - - -/************************************************* -* Add characters not in a list to a class * -*************************************************/ - -/* This function is used for adding the complement of a list of horizontal or -vertical whitespace to a class. The list must be in order. - -Arguments: - classbits the bit map for characters < 256 - uchardptr points to the pointer for extra data - options the options word - cd contains pointers to tables etc. - p points to row of 32-bit values, terminated by NOTACHAR - -Returns: the number of < 256 characters added - the pointer to extra data is updated -*/ - -static int -add_not_list_to_class(pcre_uint8 *classbits, pcre_uchar **uchardptr, - int options, compile_data *cd, const pcre_uint32 *p) -{ -BOOL utf = (options & PCRE_UTF8) != 0; -int n8 = 0; -if (p[0] > 0) - n8 += add_to_class(classbits, uchardptr, options, cd, 0, p[0] - 1); -while (p[0] < NOTACHAR) - { - while (p[1] == p[0] + 1) p++; - n8 += add_to_class(classbits, uchardptr, options, cd, p[0] + 1, - (p[1] == NOTACHAR) ? (utf ? 0x10ffffu : 0xffffffffu) : p[1] - 1); - p++; - } -return n8; -} - - - /************************************************* * Compile one branch * *************************************************/ @@ -3676,10 +3415,8 @@ Arguments: codeptr points to the pointer to the current code point ptrptr points to the current pattern pointer errorcodeptr points to error code variable - firstcharptr place to put the first required character - firstcharflagsptr place to put the first character flags, or a negative number - reqcharptr place to put the last required character - reqcharflagsptr place to put the last required character flags, or a negative number + firstcharptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE) + reqcharptr set to the last literal character required, else < 0 bcptr points to current branch chain cond_depth conditional nesting depth cd contains pointers to tables etc. @@ -3692,26 +3429,21 @@ Returns: TRUE on success static BOOL compile_branch(int *optionsptr, pcre_uchar **codeptr, - const pcre_uchar **ptrptr, int *errorcodeptr, - pcre_uint32 *firstcharptr, pcre_int32 *firstcharflagsptr, - pcre_uint32 *reqcharptr, pcre_int32 *reqcharflagsptr, - branch_chain *bcptr, int cond_depth, + const pcre_uchar **ptrptr, int *errorcodeptr, pcre_int32 *firstcharptr, + pcre_int32 *reqcharptr, branch_chain *bcptr, int cond_depth, compile_data *cd, int *lengthptr) { int repeat_type, op_type; int repeat_min = 0, repeat_max = 0; /* To please picky compilers */ int bravalue = 0; int greedy_default, greedy_non_default; -pcre_uint32 firstchar, reqchar; -pcre_int32 firstcharflags, reqcharflags; -pcre_uint32 zeroreqchar, zerofirstchar; -pcre_int32 zeroreqcharflags, zerofirstcharflags; +pcre_int32 firstchar, reqchar; +pcre_int32 zeroreqchar, zerofirstchar; pcre_int32 req_caseopt, reqvary, tempreqvary; int options = *optionsptr; /* May change dynamically */ int after_manual_callout = 0; int length_prevgroup = 0; -register pcre_uint32 c; -int escape; +register int c; register pcre_uchar *code = *codeptr; pcre_uchar *last_code = code; pcre_uchar *orig_code = code; @@ -3731,23 +3463,18 @@ must not do this for other options (e.g. PCRE_EXTENDED) because they may change dynamically as we process the pattern. */ #ifdef SUPPORT_UTF -/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */ +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ BOOL utf = (options & PCRE_UTF8) != 0; -#ifndef COMPILE_PCRE32 pcre_uchar utf_chars[6]; -#endif #else BOOL utf = FALSE; #endif -/* Helper variables for OP_XCLASS opcode (for characters > 255). We define -class_uchardata always so that it can be passed to add_to_class() always, -though it will not be used in non-UTF 8-bit cases. This avoids having to supply -alternative calls for the different cases. */ +/* Helper variables for OP_XCLASS opcode (for characters > 255). */ -pcre_uchar *class_uchardata; #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 BOOL xclass; +pcre_uchar *class_uchardata; pcre_uchar *class_uchardata_base; #endif @@ -3770,8 +3497,7 @@ to take the zero repeat into account. This is implemented by setting them to zerofirstbyte and zeroreqchar when such a repeat is encountered. The individual item types that can be repeated set these backoff variables appropriately. */ -firstchar = reqchar = zerofirstchar = zeroreqchar = 0; -firstcharflags = reqcharflags = zerofirstcharflags = zeroreqcharflags = REQ_UNSET; +firstchar = reqchar = zerofirstchar = zeroreqchar = REQ_UNSET; /* The variable req_caseopt contains either the REQ_CASELESS value or zero, according to the current setting of the caseless flag. The @@ -3792,17 +3518,16 @@ for (;; ptr++) BOOL is_recurse; BOOL reset_bracount; int class_has_8bitchar; - int class_one_char; + int class_single_char; int newoptions; int recno; int refsign; int skipbytes; - pcre_uint32 subreqchar, subfirstchar; - pcre_int32 subreqcharflags, subfirstcharflags; + int subreqchar; + int subfirstchar; int terminator; - unsigned int mclength; - unsigned int tempbracount; - pcre_uint32 ec; + int mclength; + int tempbracount; pcre_uchar mcbuffer[8]; /* Get next character in the pattern */ @@ -3812,7 +3537,7 @@ for (;; ptr++) /* If we are at the end of a nested substitution, revert to the outer level string. Nesting only happens one level deep. */ - if (c == CHAR_NULL && nestptr != NULL) + if (c == 0 && nestptr != NULL) { ptr = nestptr; nestptr = NULL; @@ -3887,7 +3612,7 @@ for (;; ptr++) /* If in \Q...\E, check for the end; if not, we have a literal */ - if (inescq && c != CHAR_NULL) + if (inescq && c != 0) { if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E) { @@ -3935,7 +3660,7 @@ for (;; ptr++) if (c == CHAR_NUMBER_SIGN) { ptr++; - while (*ptr != CHAR_NULL) + while (*ptr != 0) { if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; } ptr++; @@ -3943,7 +3668,7 @@ for (;; ptr++) if (utf) FORWARDCHAR(ptr); #endif } - if (*ptr != CHAR_NULL) continue; + if (*ptr != 0) continue; /* Else fall through to handle end of string */ c = 0; @@ -3965,9 +3690,7 @@ for (;; ptr++) case CHAR_VERTICAL_LINE: /* or | or ) */ case CHAR_RIGHT_PARENTHESIS: *firstcharptr = firstchar; - *firstcharflagsptr = firstcharflags; *reqcharptr = reqchar; - *reqcharflagsptr = reqcharflags; *codeptr = code; *ptrptr = ptr; if (lengthptr != NULL) @@ -3991,7 +3714,7 @@ for (;; ptr++) previous = NULL; if ((options & PCRE_MULTILINE) != 0) { - if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; *code++ = OP_CIRCM; } else *code++ = OP_CIRC; @@ -4006,11 +3729,9 @@ for (;; ptr++) repeats. The value of reqchar doesn't change either. */ case CHAR_DOT: - if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; zerofirstchar = firstchar; - zerofirstcharflags = firstcharflags; zeroreqchar = reqchar; - zeroreqcharflags = reqcharflags; previous = code; *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY; break; @@ -4084,9 +3805,8 @@ for (;; ptr++) (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0) { *code++ = negate_class? OP_ALLANY : OP_FAIL; - if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; zerofirstchar = firstchar; - zerofirstcharflags = firstcharflags; break; } @@ -4096,32 +3816,32 @@ for (;; ptr++) should_flip_negation = FALSE; - /* For optimization purposes, we track some properties of the class: - class_has_8bitchar will be non-zero if the class contains at least one < - 256 character; class_one_char will be 1 if the class contains just one - character. */ + /* For optimization purposes, we track some properties of the class. + class_has_8bitchar will be non-zero, if the class contains at least one + < 256 character. class_single_char will be 1 if the class contains only + a single character. */ class_has_8bitchar = 0; - class_one_char = 0; + class_single_char = 0; /* Initialize the 32-char bit map to all zeros. We build the map in a - temporary bit of memory, in case the class contains fewer than two - 8-bit characters because in that case the compiled code doesn't use the bit - map. */ + temporary bit of memory, in case the class contains only 1 character (less + than 256), because in that case the compiled code doesn't use the bit map. + */ memset(classbits, 0, 32 * sizeof(pcre_uint8)); #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 - xclass = FALSE; - class_uchardata = code + LINK_SIZE + 2; /* For XCLASS items */ - class_uchardata_base = class_uchardata; /* Save the start */ + xclass = FALSE; /* No chars >= 256 */ + class_uchardata = code + LINK_SIZE + 2; /* For UTF-8 items */ + class_uchardata_base = class_uchardata; /* For resetting in pass 1 */ #endif /* Process characters until ] is reached. By writing this as a "do" it means that an initial ] is taken as a data character. At the start of the loop, c contains the first byte of the character. */ - if (c != CHAR_NULL) do + if (c != 0) do { const pcre_uchar *oldptr; @@ -4136,12 +3856,10 @@ for (;; ptr++) /* In the pre-compile phase, accumulate the length of any extra data and reset the pointer. This is so that very large classes that contain a zillion > 255 characters no longer overwrite the work space - (which is on the stack). We have to remember that there was XCLASS data, - however. */ + (which is on the stack). */ - if (lengthptr != NULL && class_uchardata > class_uchardata_base) + if (lengthptr != NULL) { - xclass = TRUE; *lengthptr += class_uchardata - class_uchardata_base; class_uchardata = class_uchardata_base; } @@ -4243,7 +3961,7 @@ for (;; ptr++) for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset]; } - /* Now see if we need to remove any special characters. An option + /* Not see if we need to remove any special characters. An option value of 1 removes vertical space and 2 removes underscore. */ if (tabopt < 0) tabopt = -tabopt; @@ -4259,10 +3977,10 @@ for (;; ptr++) for (c = 0; c < 32; c++) classbits[c] |= pbits[c]; ptr = tempptr + 1; - /* Every class contains at least one < 256 character. */ + /* Every class contains at least one < 256 characters. */ class_has_8bitchar = 1; /* Every class contains at least two characters. */ - class_one_char = 2; + class_single_char = 2; continue; /* End of POSIX syntax handling */ } @@ -4270,26 +3988,23 @@ for (;; ptr++) of the specials, which just set a flag. The sequence \b is a special case. Inside a class (and only there) it is treated as backspace. We assume that other escapes have more than one character in them, so - speculatively set both class_has_8bitchar and class_one_char bigger + speculatively set both class_has_8bitchar and class_single_char bigger than one. Unrecognized escapes fall through and are either treated as literal characters (by default), or are faulted if PCRE_EXTRA is set. */ if (c == CHAR_BACKSLASH) { - escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, TRUE); - + c = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE); if (*errorcodeptr != 0) goto FAILED; - if (escape == 0) - c = ec; - else if (escape == ESC_b) c = CHAR_BS; /* \b is backspace in a class */ - else if (escape == ESC_N) /* \N is not supported in a class */ + if (-c == ESC_b) c = CHAR_BS; /* \b is backspace in a class */ + else if (-c == ESC_N) /* \N is not supported in a class */ { *errorcodeptr = ERR71; goto FAILED; } - else if (escape == ESC_Q) /* Handle start of quoted string */ + else if (-c == ESC_Q) /* Handle start of quoted string */ { if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) { @@ -4298,17 +4013,17 @@ for (;; ptr++) else inescq = TRUE; continue; } - else if (escape == ESC_E) continue; /* Ignore orphan \E */ + else if (-c == ESC_E) continue; /* Ignore orphan \E */ - else + if (c < 0) { register const pcre_uint8 *cbits = cd->cbits; /* Every class contains at least two < 256 characters. */ class_has_8bitchar++; /* Every class contains at least two characters. */ - class_one_char += 2; + class_single_char += 2; - switch (escape) + switch (-c) { #ifdef SUPPORT_UCP case ESC_du: /* These are the values given for \d etc */ @@ -4318,7 +4033,7 @@ for (;; ptr++) case ESC_su: /* of the default ASCII testing. */ case ESC_SU: nestptr = ptr; - ptr = substitutes[escape - ESC_DU] - 1; /* Just before substitute */ + ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */ class_has_8bitchar--; /* Undo! */ continue; #endif @@ -4342,8 +4057,7 @@ for (;; ptr++) /* Perl 5.004 onwards omits VT from \s, but we must preserve it if it was previously set by something earlier in the character - class. Luckily, the value of CHAR_VT is 0x0b in both ASCII and - EBCDIC, so we lazily just adjust the appropriate bit. */ + class. */ case ESC_s: classbits[0] |= cbits[cbit_space]; @@ -4357,26 +4071,180 @@ for (;; ptr++) classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */ continue; - /* The rest apply in both UCP and non-UCP cases. */ - case ESC_h: - (void)add_list_to_class(classbits, &class_uchardata, options, cd, - PRIV(hspace_list), NOTACHAR); + SETBIT(classbits, 0x09); /* VT */ + SETBIT(classbits, 0x20); /* SPACE */ + SETBIT(classbits, 0xa0); /* NSBP */ +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x1680; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x180e; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2000; + *class_uchardata++ = 0x200a; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x202f; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x205f; + *class_uchardata++ = XCL_SINGLE; + *class_uchardata++ = 0x3000; +#elif defined SUPPORT_UTF + if (utf) + { + xclass = TRUE; + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x1680, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x180e, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2000, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x200a, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x202f, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x205f, class_uchardata); + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(0x3000, class_uchardata); + } +#endif continue; case ESC_H: - (void)add_not_list_to_class(classbits, &class_uchardata, options, - cd, PRIV(hspace_list)); + for (c = 0; c < 32; c++) + { + int x = 0xff; + switch (c) + { + case 0x09/8: x ^= 1 << (0x09%8); break; + case 0x20/8: x ^= 1 << (0x20%8); break; + case 0xa0/8: x ^= 1 << (0xa0%8); break; + default: break; + } + classbits[c] |= x; + } +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x0100; + *class_uchardata++ = 0x167f; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x1681; + *class_uchardata++ = 0x180d; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x180f; + *class_uchardata++ = 0x1fff; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x200b; + *class_uchardata++ = 0x202e; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2030; + *class_uchardata++ = 0x205e; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2060; + *class_uchardata++ = 0x2fff; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x3001; +#ifdef SUPPORT_UTF + if (utf) + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); + else +#endif + *class_uchardata++ = 0xffff; +#elif defined SUPPORT_UTF + if (utf) + { + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x167f, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x1681, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x180d, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x180f, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x1fff, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x200b, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x202e, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2030, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x205e, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2060, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x2fff, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x3001, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); + } +#endif continue; case ESC_v: - (void)add_list_to_class(classbits, &class_uchardata, options, cd, - PRIV(vspace_list), NOTACHAR); + SETBIT(classbits, 0x0a); /* LF */ + SETBIT(classbits, 0x0b); /* VT */ + SETBIT(classbits, 0x0c); /* FF */ + SETBIT(classbits, 0x0d); /* CR */ + SETBIT(classbits, 0x85); /* NEL */ +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x2028; + *class_uchardata++ = 0x2029; +#elif defined SUPPORT_UTF + if (utf) + { + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x2028, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x2029, class_uchardata); + } +#endif continue; case ESC_V: - (void)add_not_list_to_class(classbits, &class_uchardata, options, - cd, PRIV(vspace_list)); + for (c = 0; c < 32; c++) + { + int x = 0xff; + switch (c) + { + case 0x0a/8: x ^= 1 << (0x0a%8); + x ^= 1 << (0x0b%8); + x ^= 1 << (0x0c%8); + x ^= 1 << (0x0d%8); + break; + case 0x85/8: x ^= 1 << (0x85%8); break; + default: break; + } + classbits[c] |= x; + } + +#ifndef COMPILE_PCRE8 + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x0100; + *class_uchardata++ = 0x2027; + *class_uchardata++ = XCL_RANGE; + *class_uchardata++ = 0x202a; +#ifdef SUPPORT_UTF + if (utf) + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); + else +#endif + *class_uchardata++ = 0xffff; +#elif defined SUPPORT_UTF + if (utf) + { + xclass = TRUE; + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x0100, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x2027, class_uchardata); + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(0x202a, class_uchardata); + class_uchardata += PRIV(ord2utf)(0x10ffff, class_uchardata); + } +#endif continue; #ifdef SUPPORT_UCP @@ -4384,10 +4252,11 @@ for (;; ptr++) case ESC_P: { BOOL negated; - unsigned int ptype = 0, pdata = 0; - if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr)) - goto FAILED; - *class_uchardata++ = ((escape == ESC_p) != negated)? + int pdata; + int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr); + if (ptype < 0) goto FAILED; + xclass = TRUE; + *class_uchardata++ = ((-c == ESC_p) != negated)? XCL_PROP : XCL_NOTPROP; *class_uchardata++ = ptype; *class_uchardata++ = pdata; @@ -4406,23 +4275,21 @@ for (;; ptr++) goto FAILED; } class_has_8bitchar--; /* Undo the speculative increase. */ - class_one_char -= 2; /* Undo the speculative increase. */ + class_single_char -= 2; /* Undo the speculative increase. */ c = *ptr; /* Get the final character and fall through */ break; } } - /* Fall through if the escape just defined a single character (c >= 0). - This may be greater than 256. */ - - escape = 0; + /* Fall through if we have a single character (c >= 0). This may be + greater than 256. */ } /* End of backslash handling */ - /* A character may be followed by '-' to form a range. However, Perl does - not permit ']' to be the end of the range. A '-' character at the end is - treated as a literal. Perl ignores orphaned \E sequences entirely. The - code for handling \Q and \E is messy. */ + /* A single character may be followed by '-' to form a range. However, + Perl does not permit ']' to be the end of the range. A '-' character + at the end is treated as a literal. Perl ignores orphaned \E sequences + entirely. The code for handling \Q and \E is messy. */ CHECK_RANGE: while (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) @@ -4430,9 +4297,10 @@ for (;; ptr++) inescq = FALSE; ptr += 2; } + oldptr = ptr; - /* Remember if \r or \n were explicitly used */ + /* Remember \r or \n */ if (c == CHAR_CR || c == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF; @@ -4440,7 +4308,7 @@ for (;; ptr++) if (!inescq && ptr[1] == CHAR_MINUS) { - pcre_uint32 d; + int d; ptr += 2; while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) ptr += 2; @@ -4456,17 +4324,12 @@ for (;; ptr++) break; } - /* Minus (hyphen) at the end of a class is treated as a literal, so put - back the pointer and jump to handle the character that preceded it. */ - - if (*ptr == CHAR_NULL || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET)) + if (*ptr == 0 || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET)) { ptr = oldptr; - goto CLASS_SINGLE_CHARACTER; + goto LONE_SINGLE_CHARACTER; } - /* Otherwise, we have a potential range; pick up the next character */ - #ifdef SUPPORT_UTF if (utf) { /* Braces are required because the */ @@ -4482,116 +4345,228 @@ for (;; ptr++) if (!inescq && d == CHAR_BACKSLASH) { - int descape; - descape = check_escape(&ptr, &d, errorcodeptr, cd->bracount, options, TRUE); + d = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE); if (*errorcodeptr != 0) goto FAILED; - /* \b is backspace; any other special means the '-' was literal. */ + /* \b is backspace; any other special means the '-' was literal */ - if (descape != 0) + if (d < 0) { - if (descape == ESC_b) d = CHAR_BS; else + if (d == -ESC_b) d = CHAR_BS; else { ptr = oldptr; - goto CLASS_SINGLE_CHARACTER; /* A few lines below */ + goto LONE_SINGLE_CHARACTER; /* A few lines below */ } } } /* Check that the two values are in the correct order. Optimize - one-character ranges. */ + one-character ranges */ if (d < c) { *errorcodeptr = ERR8; goto FAILED; } - if (d == c) goto CLASS_SINGLE_CHARACTER; /* A few lines below */ - /* We have found a character range, so single character optimizations - cannot be done anymore. Any value greater than 1 indicates that there - is more than one character. */ + if (d == c) goto LONE_SINGLE_CHARACTER; /* A few lines below */ - class_one_char = 2; - - /* Remember an explicit \r or \n, and add the range to the class. */ + /* Remember \r or \n */ if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF; - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cd, c, d); + /* Since we found a character range, single character optimizations + cannot be done anymore. */ + class_single_char = 2; + + /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless + matching, we have to use an XCLASS with extra data items. Caseless + matching for characters > 127 is available only if UCP support is + available. */ + +#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8) + if ((d > 255) || (utf && ((options & PCRE_CASELESS) != 0 && d > 127))) +#elif defined SUPPORT_UTF + if (utf && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127))) +#elif !(defined COMPILE_PCRE8) + if (d > 255) +#endif +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + { + xclass = TRUE; + + /* With UCP support, we can find the other case equivalents of + the relevant characters. There may be several ranges. Optimize how + they fit with the basic range. */ + +#ifdef SUPPORT_UCP +#ifndef COMPILE_PCRE8 + if (utf && (options & PCRE_CASELESS) != 0) +#else + if ((options & PCRE_CASELESS) != 0) +#endif + { + unsigned int occ, ocd; + unsigned int cc = c; + unsigned int origd = d; + while (get_othercase_range(&cc, origd, &occ, &ocd)) + { + if (occ >= (unsigned int)c && + ocd <= (unsigned int)d) + continue; /* Skip embedded ranges */ + + if (occ < (unsigned int)c && + ocd >= (unsigned int)c - 1) /* Extend the basic range */ + { /* if there is overlap, */ + c = occ; /* noting that if occ < c */ + continue; /* we can't have ocd > d */ + } /* because a subrange is */ + if (ocd > (unsigned int)d && + occ <= (unsigned int)d + 1) /* always shorter than */ + { /* the basic range. */ + d = ocd; + continue; + } + + if (occ == ocd) + { + *class_uchardata++ = XCL_SINGLE; + } + else + { + *class_uchardata++ = XCL_RANGE; + class_uchardata += PRIV(ord2utf)(occ, class_uchardata); + } + class_uchardata += PRIV(ord2utf)(ocd, class_uchardata); + } + } +#endif /* SUPPORT_UCP */ + + /* Now record the original range, possibly modified for UCP caseless + overlapping ranges. */ + + *class_uchardata++ = XCL_RANGE; +#ifdef SUPPORT_UTF +#ifndef COMPILE_PCRE8 + if (utf) + { + class_uchardata += PRIV(ord2utf)(c, class_uchardata); + class_uchardata += PRIV(ord2utf)(d, class_uchardata); + } + else + { + *class_uchardata++ = c; + *class_uchardata++ = d; + } +#else + class_uchardata += PRIV(ord2utf)(c, class_uchardata); + class_uchardata += PRIV(ord2utf)(d, class_uchardata); +#endif +#else /* SUPPORT_UTF */ + *class_uchardata++ = c; + *class_uchardata++ = d; +#endif /* SUPPORT_UTF */ + + /* With UCP support, we are done. Without UCP support, there is no + caseless matching for UTF characters > 127; we can use the bit map + for the smaller ones. As for 16 bit characters without UTF, we + can still use */ + +#ifdef SUPPORT_UCP +#ifndef COMPILE_PCRE8 + if (utf) +#endif + continue; /* With next character in the class */ +#endif /* SUPPORT_UCP */ + +#if defined SUPPORT_UTF && !defined(SUPPORT_UCP) && !(defined COMPILE_PCRE8) + if (utf) + { + if ((options & PCRE_CASELESS) == 0 || c > 127) continue; + /* Adjust upper limit and fall through to set up the map */ + d = 127; + } + else + { + if (c > 255) continue; + /* Adjust upper limit and fall through to set up the map */ + d = 255; + } +#elif defined SUPPORT_UTF && !defined(SUPPORT_UCP) + if ((options & PCRE_CASELESS) == 0 || c > 127) continue; + /* Adjust upper limit and fall through to set up the map */ + d = 127; +#else + if (c > 255) continue; + /* Adjust upper limit and fall through to set up the map */ + d = 255; +#endif /* SUPPORT_UTF && !SUPPORT_UCP && !COMPILE_PCRE8 */ + } +#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ + + /* We use the bit map for 8 bit mode, or when the characters fall + partially or entirely to [0-255] ([0-127] for UCP) ranges. */ + + class_has_8bitchar = 1; + + /* We can save a bit of time by skipping this in the pre-compile. */ + + if (lengthptr == NULL) for (; c <= d; c++) + { + classbits[c/8] |= (1 << (c&7)); + if ((options & PCRE_CASELESS) != 0) + { + int uc = cd->fcc[c]; /* flip case */ + classbits[uc/8] |= (1 << (uc&7)); + } + } continue; /* Go get the next char in the class */ } - /* Handle a single character - we can get here for a normal non-escape - char, or after \ that introduces a single character or for an apparent - range that isn't. Only the value 1 matters for class_one_char, so don't - increase it if it is already 2 or more ... just in case there's a class - with a zillion characters in it. */ + /* Handle a lone single character - we can get here for a normal + non-escape char, or after \ that introduces a single character or for an + apparent range that isn't. */ - CLASS_SINGLE_CHARACTER: - if (class_one_char < 2) class_one_char++; + LONE_SINGLE_CHARACTER: - /* If class_one_char is 1, we have the first single character in the - class, and there have been no prior ranges, or XCLASS items generated by - escapes. If this is the final character in the class, we can optimize by - turning the item into a 1-character OP_CHAR[I] if it's positive, or - OP_NOT[I] if it's negative. In the positive case, it can cause firstchar - to be set. Otherwise, there can be no first char if this item is first, - whatever repeat count may follow. In the case of reqchar, save the - previous value for reinstating. */ + /* Only the value of 1 matters for class_single_char. */ - if (class_one_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) + if (class_single_char < 2) class_single_char++; + + /* If class_charcount is 1, we saw precisely one character. As long as + there was no use of \p or \P, in other words, no use of any XCLASS + features, we can optimize. + + The optimization throws away the bit map. We turn the item into a + 1-character OP_CHAR[I] if it's positive, or OP_NOT[I] if it's negative. + In the positive case, it can cause firstchar to be set. Otherwise, there + can be no first char if this item is first, whatever repeat count may + follow. In the case of reqchar, save the previous value for reinstating. */ + + if (class_single_char == 1 && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) { ptr++; zeroreqchar = reqchar; - zeroreqcharflags = reqcharflags; if (negate_class) { -#ifdef SUPPORT_UCP - int d; -#endif - if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; zerofirstchar = firstchar; - zerofirstcharflags = firstcharflags; - - /* For caseless UTF-8 mode when UCP support is available, check - whether this character has more than one other case. If so, generate - a special OP_NOTPROP item instead of OP_NOTI. */ - -#ifdef SUPPORT_UCP - if (utf && (options & PCRE_CASELESS) != 0 && - (d = UCD_CASESET(c)) != 0) - { - *code++ = OP_NOTPROP; - *code++ = PT_CLIST; - *code++ = d; - } + *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT; +#ifdef SUPPORT_UTF + if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) + code += PRIV(ord2utf)(c, code); else #endif - /* Char has only one other case, or UCP not available */ - - { - *code++ = ((options & PCRE_CASELESS) != 0)? OP_NOTI: OP_NOT; -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 - if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) - code += PRIV(ord2utf)(c, code); - else -#endif - *code++ = c; - } - - /* We are finished with this character class */ - - goto END_CLASS; + *code++ = c; + goto NOT_CHAR; } /* For a single, positive character, get the value into mcbuffer, and then we can handle this with the normal one-character code. */ -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) mclength = PRIV(ord2utf)(c, mcbuffer); else @@ -4603,51 +4578,89 @@ for (;; ptr++) goto ONE_CHAR; } /* End of 1-char optimization */ - /* There is more than one character in the class, or an XCLASS item - has been generated. Add this character to the class. */ + /* Handle a character that cannot go in the bit map. */ - class_has_8bitchar += - add_to_class(classbits, &class_uchardata, options, cd, c, c); +#if defined SUPPORT_UTF && !(defined COMPILE_PCRE8) + if ((c > 255) || (utf && ((options & PCRE_CASELESS) != 0 && c > 127))) +#elif defined SUPPORT_UTF + if (utf && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127))) +#elif !(defined COMPILE_PCRE8) + if (c > 255) +#endif + +#if defined SUPPORT_UTF || !(defined COMPILE_PCRE8) + { + xclass = TRUE; + *class_uchardata++ = XCL_SINGLE; +#ifdef SUPPORT_UTF +#ifndef COMPILE_PCRE8 + /* In non 8 bit mode, we can get here even if we are not in UTF mode. */ + if (!utf) + *class_uchardata++ = c; + else +#endif + class_uchardata += PRIV(ord2utf)(c, class_uchardata); +#else /* SUPPORT_UTF */ + *class_uchardata++ = c; +#endif /* SUPPORT_UTF */ + +#ifdef SUPPORT_UCP +#ifdef COMPILE_PCRE8 + if ((options & PCRE_CASELESS) != 0) +#else + /* In non 8 bit mode, we can get here even if we are not in UTF mode. */ + if (utf && (options & PCRE_CASELESS) != 0) +#endif + { + unsigned int othercase; + if ((int)(othercase = UCD_OTHERCASE(c)) != c) + { + *class_uchardata++ = XCL_SINGLE; + class_uchardata += PRIV(ord2utf)(othercase, class_uchardata); + } + } +#endif /* SUPPORT_UCP */ + + } + else +#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ + + /* Handle a single-byte character */ + { + class_has_8bitchar = 1; + classbits[c/8] |= (1 << (c&7)); + if ((options & PCRE_CASELESS) != 0) + { + c = cd->fcc[c]; /* flip case */ + classbits[c/8] |= (1 << (c&7)); + } + } } /* Loop until ']' reached. This "while" is the end of the "do" far above. If we are at the end of an internal nested string, revert to the outer string. */ - while (((c = *(++ptr)) != CHAR_NULL || + while (((c = *(++ptr)) != 0 || (nestptr != NULL && - (ptr = nestptr, nestptr = NULL, c = *(++ptr)) != CHAR_NULL)) && + (ptr = nestptr, nestptr = NULL, c = *(++ptr)) != 0)) && (c != CHAR_RIGHT_SQUARE_BRACKET || inescq)); /* Check for missing terminating ']' */ - if (c == CHAR_NULL) + if (c == 0) { *errorcodeptr = ERR6; goto FAILED; } - /* We will need an XCLASS if data has been placed in class_uchardata. In - the second phase this is a sufficient test. However, in the pre-compile - phase, class_uchardata gets emptied to prevent workspace overflow, so it - only if the very last character in the class needs XCLASS will it contain - anything at this point. For this reason, xclass gets set TRUE above when - uchar_classdata is emptied, and that's why this code is the way it is here - instead of just doing a test on class_uchardata below. */ - -#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 - if (class_uchardata > class_uchardata_base) xclass = TRUE; -#endif - /* If this is the first thing in the branch, there can be no first char setting, whatever the repeat count. Any reqchar setting must remain unchanged after any kind of repeat. */ - if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; zerofirstchar = firstchar; - zerofirstcharflags = firstcharflags; zeroreqchar = reqchar; - zeroreqcharflags = reqcharflags; /* If there are characters with values > 255, we have to compile an extended class, with its own opcode, unless there was a negated special @@ -4703,8 +4716,7 @@ for (;; ptr++) memcpy(code, classbits, 32); } code += 32 / sizeof(pcre_uchar); - - END_CLASS: + NOT_CHAR: break; @@ -4742,9 +4754,7 @@ for (;; ptr++) if (repeat_min == 0) { firstchar = zerofirstchar; /* Adjust for zero repeat */ - firstcharflags = zerofirstcharflags; reqchar = zeroreqchar; /* Ditto */ - reqcharflags = zeroreqcharflags; } /* Remember whether this is a variable length repeat */ @@ -4830,7 +4840,7 @@ for (;; ptr++) hold the length of the character in bytes, plus UTF_LENGTH to flag that it's a length rather than a small character. */ -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf && NOT_FIRSTCHAR(code[-1])) { pcre_uchar *lastchar = code - 1; @@ -4847,10 +4857,7 @@ for (;; ptr++) { c = code[-1]; if (*previous <= OP_CHARI && repeat_min > 1) - { - reqchar = c; - reqcharflags = req_caseopt | cd->req_varyopt; - } + reqchar = c | req_caseopt | cd->req_varyopt; } /* If the repetition is unlimited, it pays to see if the next thing on @@ -4969,7 +4976,7 @@ for (;; ptr++) if (repeat_max < 0) { -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf && (c & UTF_LENGTH) != 0) { memcpy(code, utf_chars, IN_UCHARS(c & 7)); @@ -4994,7 +5001,7 @@ for (;; ptr++) else if (repeat_max != repeat_min) { -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf && (c & UTF_LENGTH) != 0) { memcpy(code, utf_chars, IN_UCHARS(c & 7)); @@ -5024,7 +5031,7 @@ for (;; ptr++) /* The character or character type itself comes last in all cases. */ -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf && (c & UTF_LENGTH) != 0) { memcpy(code, utf_chars, IN_UCHARS(c & 7)); @@ -5232,11 +5239,7 @@ for (;; ptr++) else { - if (groupsetfirstchar && reqcharflags < 0) - { - reqchar = firstchar; - reqcharflags = firstcharflags; - } + if (groupsetfirstchar && reqchar < 0) reqchar = firstchar; for (i = 1; i < repeat_min; i++) { @@ -5611,9 +5614,9 @@ for (;; ptr++) if (*ptr == CHAR_COLON) { arg = ++ptr; - while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; + while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; arglen = (int)(ptr - arg); - if ((unsigned int)arglen > MAX_MARK) + if (arglen > (int)MAX_MARK) { *errorcodeptr = ERR75; goto FAILED; @@ -5633,8 +5636,6 @@ for (;; ptr++) if (namelen == verbs[i].len && STRNCMP_UC_C8(name, vn, namelen) == 0) { - int setverb; - /* Check for open captures before ACCEPT and convert it to ASSERT_ACCEPT if in an assertion. */ @@ -5652,11 +5653,10 @@ for (;; ptr++) *code++ = OP_CLOSE; PUT2INC(code, 0, oc->number); } - setverb = *code++ = - (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; + *code++ = (cd->assert_depth > 0)? OP_ASSERT_ACCEPT : OP_ACCEPT; /* Do not set firstchar after *ACCEPT */ - if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; } /* Handle other cases with/without an argument */ @@ -5668,7 +5668,8 @@ for (;; ptr++) *errorcodeptr = ERR66; goto FAILED; } - setverb = *code++ = verbs[i].op; + *code = verbs[i].op; + if (*code++ == OP_THEN) cd->external_flags |= PCRE_HASTHEN; } else @@ -5678,28 +5679,14 @@ for (;; ptr++) *errorcodeptr = ERR59; goto FAILED; } - setverb = *code++ = verbs[i].op_arg; + *code = verbs[i].op_arg; + if (*code++ == OP_THEN_ARG) cd->external_flags |= PCRE_HASTHEN; *code++ = arglen; memcpy(code, arg, IN_UCHARS(arglen)); code += arglen; *code++ = 0; } - switch (setverb) - { - case OP_THEN: - case OP_THEN_ARG: - cd->external_flags |= PCRE_HASTHEN; - break; - - case OP_PRUNE: - case OP_PRUNE_ARG: - case OP_SKIP: - case OP_SKIP_ARG: - cd->had_pruneorskip = TRUE; - break; - } - break; /* Found verb, exit loop */ } @@ -5725,8 +5712,8 @@ for (;; ptr++) { case CHAR_NUMBER_SIGN: /* Comment; skip to ket */ ptr++; - while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; - if (*ptr == CHAR_NULL) + while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++; + if (*ptr == 0) { *errorcodeptr = ERR18; goto FAILED; @@ -5802,7 +5789,7 @@ for (;; ptr++) } else { - terminator = CHAR_NULL; + terminator = 0; if (ptr[1] == CHAR_MINUS || ptr[1] == CHAR_PLUS) refsign = *(++ptr); } @@ -5822,12 +5809,12 @@ for (;; ptr++) while (MAX_255(*ptr) && (cd->ctypes[*ptr] & ctype_word) != 0) { if (recno >= 0) - recno = (IS_DIGIT(*ptr))? recno * 10 + (int)(*ptr - CHAR_0) : -1; + recno = (IS_DIGIT(*ptr))? recno * 10 + *ptr - CHAR_0 : -1; ptr++; } namelen = (int)(ptr - name); - if ((terminator > 0 && *ptr++ != (pcre_uchar)terminator) || + if ((terminator > 0 && *ptr++ != terminator) || *ptr++ != CHAR_RIGHT_PARENTHESIS) { ptr--; /* Error offset */ @@ -5892,13 +5879,13 @@ for (;; ptr++) code[1+LINK_SIZE]++; } - /* If terminator == CHAR_NULL it means that the name followed directly - after the opening parenthesis [e.g. (?(abc)...] and in this case there - are some further alternatives to try. For the cases where terminator != - 0 [things like (?(... or (?('name')... or (?(R&name)... ] we have + /* If terminator == 0 it means that the name followed directly after + the opening parenthesis [e.g. (?(abc)...] and in this case there are + some further alternatives to try. For the cases where terminator != 0 + [things like (?(... or (?('name')... or (?(R&name)... ] we have now checked all the possibilities, so give an error. */ - else if (terminator != CHAR_NULL) + else if (terminator != 0) { *errorcodeptr = ERR15; goto FAILED; @@ -6067,7 +6054,7 @@ for (;; ptr++) if (lengthptr != NULL) { - if (*ptr != (pcre_uchar)terminator) + if (*ptr != terminator) { *errorcodeptr = ERR42; goto FAILED; @@ -6209,7 +6196,7 @@ for (;; ptr++) *errorcodeptr = ERR62; goto FAILED; } - if (*ptr != (pcre_uchar)terminator) + if (*ptr != terminator) { *errorcodeptr = ERR42; goto FAILED; @@ -6315,7 +6302,7 @@ for (;; ptr++) while(IS_DIGIT(*ptr)) recno = recno * 10 + *ptr++ - CHAR_0; - if (*ptr != (pcre_uchar)terminator) + if (*ptr != terminator) { *errorcodeptr = ERR29; goto FAILED; @@ -6419,7 +6406,7 @@ for (;; ptr++) /* Can't determine a first byte now */ - if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; continue; @@ -6553,9 +6540,7 @@ for (;; ptr++) cond_depth + ((bravalue == OP_COND)?1:0), /* Depth of condition subpatterns */ &subfirstchar, /* For possible first char */ - &subfirstcharflags, &subreqchar, /* For possible last char */ - &subreqcharflags, bcptr, /* Current branch chain */ cd, /* Tables block */ (lengthptr == NULL)? NULL : /* Actual compile phase */ @@ -6616,7 +6601,7 @@ for (;; ptr++) *errorcodeptr = ERR27; goto FAILED; } - if (condcount == 1) subfirstcharflags = subreqcharflags = REQ_NONE; + if (condcount == 1) subfirstchar = subreqchar = REQ_NONE; } } @@ -6665,9 +6650,7 @@ for (;; ptr++) back off. */ zeroreqchar = reqchar; - zeroreqcharflags = reqcharflags; zerofirstchar = firstchar; - zerofirstcharflags = firstcharflags; groupsetfirstchar = FALSE; if (bravalue >= OP_ONCE) @@ -6678,36 +6661,28 @@ for (;; ptr++) no firstchar, set "none" for the whole branch. In both cases, a zero repeat forces firstchar to "none". */ - if (firstcharflags == REQ_UNSET) + if (firstchar == REQ_UNSET) { - if (subfirstcharflags >= 0) + if (subfirstchar >= 0) { firstchar = subfirstchar; - firstcharflags = subfirstcharflags; groupsetfirstchar = TRUE; } - else firstcharflags = REQ_NONE; - zerofirstcharflags = REQ_NONE; + else firstchar = REQ_NONE; + zerofirstchar = REQ_NONE; } /* If firstchar was previously set, convert the subpattern's firstchar into reqchar if there wasn't one, using the vary flag that was in existence beforehand. */ - else if (subfirstcharflags >= 0 && subreqcharflags < 0) - { - subreqchar = subfirstchar; - subreqcharflags = subfirstcharflags | tempreqvary; - } + else if (subfirstchar >= 0 && subreqchar < 0) + subreqchar = subfirstchar | tempreqvary; /* If the subpattern set a required byte (or set a first byte that isn't really the first byte - see above), set it. */ - if (subreqcharflags >= 0) - { - reqchar = subreqchar; - reqcharflags = subreqcharflags; - } + if (subreqchar >= 0) reqchar = subreqchar; } /* For a forward assertion, we take the reqchar, if set. This can be @@ -6718,11 +6693,7 @@ for (;; ptr++) of a firstchar. This is overcome by a scan at the end if there's no firstchar, looking for an asserted first char. */ - else if (bravalue == OP_ASSERT && subreqcharflags >= 0) - { - reqchar = subreqchar; - reqcharflags = subreqcharflags; - } + else if (bravalue == OP_ASSERT && subreqchar >= 0) reqchar = subreqchar; break; /* End of processing '(' */ @@ -6730,22 +6701,19 @@ for (;; ptr++) /* Handle metasequences introduced by \. For ones like \d, the ESC_ values are arranged to be the negation of the corresponding OP_values in the default case when PCRE_UCP is not set. For the back references, the values - are negative the reference number. Only back references and those types + are ESC_REF plus the reference number. Only back references and those types that consume a character may be repeated. We can test for values between ESC_b and ESC_Z for the latter; this may have to change if any new ones are ever created. */ case CHAR_BACKSLASH: tempptr = ptr; - escape = check_escape(&ptr, &ec, errorcodeptr, cd->bracount, options, FALSE); - + c = check_escape(&ptr, errorcodeptr, cd->bracount, options, FALSE); if (*errorcodeptr != 0) goto FAILED; - if (escape == 0) - c = ec; - else + if (c < 0) { - if (escape == ESC_Q) /* Handle start of quoted string */ + if (-c == ESC_Q) /* Handle start of quoted string */ { if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E) ptr += 2; /* avoid empty string */ @@ -6753,29 +6721,27 @@ for (;; ptr++) continue; } - if (escape == ESC_E) continue; /* Perl ignores an orphan \E */ + if (-c == ESC_E) continue; /* Perl ignores an orphan \E */ /* For metasequences that actually match a character, we disable the setting of a first character if it hasn't already been set. */ - if (firstcharflags == REQ_UNSET && escape > ESC_b && escape < ESC_Z) - firstcharflags = REQ_NONE; + if (firstchar == REQ_UNSET && -c > ESC_b && -c < ESC_Z) + firstchar = REQ_NONE; /* Set values to reset to if this is followed by a zero repeat. */ zerofirstchar = firstchar; - zerofirstcharflags = firstcharflags; zeroreqchar = reqchar; - zeroreqcharflags = reqcharflags; /* \g or \g'name' is a subroutine call by name and \g or \g'n' is a subroutine call by number (Oniguruma syntax). In fact, the value - ESC_g is returned only for these cases. So we don't need to check for < - or ' if the value is ESC_g. For the Perl syntax \g{n} the value is - -n, and for the Perl syntax \g{name} the result is ESC_k (as + -ESC_g is returned only for these cases. So we don't need to check for < + or ' if the value is -ESC_g. For the Perl syntax \g{n} the value is + -ESC_REF+n, and for the Perl syntax \g{name} the result is -ESC_k (as that is a synonym for a named back reference). */ - if (escape == ESC_g) + if (-c == ESC_g) { const pcre_uchar *p; save_hwm = cd->hwm; /* Normally this is set when '(' is read */ @@ -6795,13 +6761,13 @@ for (;; ptr++) if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS) { BOOL is_a_number = TRUE; - for (p = ptr + 1; *p != CHAR_NULL && *p != (pcre_uchar)terminator; p++) + for (p = ptr + 1; *p != 0 && *p != terminator; p++) { if (!MAX_255(*p)) { is_a_number = FALSE; break; } if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE; if ((cd->ctypes[*p] & ctype_word) == 0) break; } - if (*p != (pcre_uchar)terminator) + if (*p != terminator) { *errorcodeptr = ERR57; break; @@ -6819,7 +6785,7 @@ for (;; ptr++) p = ptr + 2; while (IS_DIGIT(*p)) p++; - if (*p != (pcre_uchar)terminator) + if (*p != terminator) { *errorcodeptr = ERR57; break; @@ -6831,7 +6797,7 @@ for (;; ptr++) /* \k or \k'name' is a back reference by name (Perl syntax). We also support \k{name} (.NET syntax). */ - if (escape == ESC_k) + if (-c == ESC_k) { if ((ptr[1] != CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_APOSTROPHE && ptr[1] != CHAR_LEFT_CURLY_BRACKET)) @@ -6850,13 +6816,13 @@ for (;; ptr++) not set to cope with cases like (?=(\w+))\1: which would otherwise set ':' later. */ - if (escape < 0) + if (-c >= ESC_REF) { open_capitem *oc; - recno = -escape; + recno = -c - ESC_REF; HANDLE_REFERENCE: /* Come here from named backref handling */ - if (firstcharflags == REQ_UNSET) firstcharflags = REQ_NONE; + if (firstchar == REQ_UNSET) firstchar = REQ_NONE; previous = code; *code++ = ((options & PCRE_CASELESS) != 0)? OP_REFI : OP_REF; PUT2INC(code, 0, recno); @@ -6880,14 +6846,14 @@ for (;; ptr++) /* So are Unicode property matches, if supported. */ #ifdef SUPPORT_UCP - else if (escape == ESC_P || escape == ESC_p) + else if (-c == ESC_P || -c == ESC_p) { BOOL negated; - unsigned int ptype = 0, pdata = 0; - if (!get_ucp(&ptr, &negated, &ptype, &pdata, errorcodeptr)) - goto FAILED; + int pdata; + int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr); + if (ptype < 0) goto FAILED; previous = code; - *code++ = ((escape == ESC_p) != negated)? OP_PROP : OP_NOTPROP; + *code++ = ((-c == ESC_p) != negated)? OP_PROP : OP_NOTPROP; *code++ = ptype; *code++ = pdata; } @@ -6896,7 +6862,7 @@ for (;; ptr++) /* If Unicode properties are not supported, \X, \P, and \p are not allowed. */ - else if (escape == ESC_X || escape == ESC_P || escape == ESC_p) + else if (-c == ESC_X || -c == ESC_P || -c == ESC_p) { *errorcodeptr = ERR45; goto FAILED; @@ -6911,13 +6877,13 @@ for (;; ptr++) else { - if ((escape == ESC_b || escape == ESC_B) && cd->max_lookbehind == 0) + if ((-c == ESC_b || -c == ESC_B) && cd->max_lookbehind == 0) cd->max_lookbehind = 1; #ifdef SUPPORT_UCP - if (escape >= ESC_DU && escape <= ESC_wu) + if (-c >= ESC_DU && -c <= ESC_wu) { nestptr = ptr + 1; /* Where to resume */ - ptr = substitutes[escape - ESC_DU] - 1; /* Just before substitute */ + ptr = substitutes[-c - ESC_DU] - 1; /* Just before substitute */ } else #endif @@ -6925,8 +6891,8 @@ for (;; ptr++) so that it works in DFA mode and in lookbehinds. */ { - previous = (escape > ESC_b && escape < ESC_Z)? code : NULL; - *code++ = (!utf && escape == ESC_C)? OP_ALLANY : escape; + previous = (-c > ESC_b && -c < ESC_Z)? code : NULL; + *code++ = (!utf && c == -ESC_C)? OP_ALLANY : -c; } } continue; @@ -6936,7 +6902,7 @@ for (;; ptr++) a value > 127. We set its representation in the length/buffer, and then handle it as a data character. */ -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf && c > MAX_VALUE_FOR_SINGLE_CHAR) mclength = PRIV(ord2utf)(c, mcbuffer); else @@ -6969,28 +6935,6 @@ for (;; ptr++) ONE_CHAR: previous = code; - - /* For caseless UTF-8 mode when UCP support is available, check whether - this character has more than one other case. If so, generate a special - OP_PROP item instead of OP_CHARI. */ - -#ifdef SUPPORT_UCP - if (utf && (options & PCRE_CASELESS) != 0) - { - GETCHAR(c, mcbuffer); - if ((c = UCD_CASESET(c)) != 0) - { - *code++ = OP_PROP; - *code++ = PT_CLIST; - *code++ = c; - if (firstcharflags == REQ_UNSET) firstcharflags = zerofirstcharflags = REQ_NONE; - break; - } - } -#endif - - /* Caseful matches, or not one of the multicase characters. */ - *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARI : OP_CHAR; for (c = 0; c < mclength; c++) *code++ = mcbuffer[c]; @@ -7004,11 +6948,10 @@ for (;; ptr++) Otherwise, leave the firstchar value alone, and don't change it on a zero repeat. */ - if (firstcharflags == REQ_UNSET) + if (firstchar == REQ_UNSET) { - zerofirstcharflags = REQ_NONE; + zerofirstchar = REQ_NONE; zeroreqchar = reqchar; - zeroreqcharflags = reqcharflags; /* If the character is more than one byte long, we can set firstchar only if it is not to be matched caselessly. */ @@ -7016,16 +6959,9 @@ for (;; ptr++) if (mclength == 1 || req_caseopt == 0) { firstchar = mcbuffer[0] | req_caseopt; - firstchar = mcbuffer[0]; - firstcharflags = req_caseopt; - - if (mclength != 1) - { - reqchar = code[-1]; - reqcharflags = cd->req_varyopt; - } + if (mclength != 1) reqchar = code[-1] | cd->req_varyopt; } - else firstcharflags = reqcharflags = REQ_NONE; + else firstchar = reqchar = REQ_NONE; } /* firstchar was previously set; we can set reqchar only if the length is @@ -7034,14 +6970,9 @@ for (;; ptr++) else { zerofirstchar = firstchar; - zerofirstcharflags = firstcharflags; zeroreqchar = reqchar; - zeroreqcharflags = reqcharflags; if (mclength == 1 || req_caseopt == 0) - { - reqchar = code[-1]; - reqcharflags = req_caseopt | cd->req_varyopt; - } + reqchar = code[-1] | req_caseopt | cd->req_varyopt; } break; /* End of literal character handling */ @@ -7060,6 +6991,7 @@ return FALSE; + /************************************************* * Compile sequence of alternatives * *************************************************/ @@ -7080,10 +7012,8 @@ Arguments: reset_bracount TRUE to reset the count for each branch skipbytes skip this many bytes at start (for brackets and OP_COND) cond_depth depth of nesting for conditional subpatterns - firstcharptr place to put the first required character - firstcharflagsptr place to put the first character flags, or a negative number - reqcharptr place to put the last required character - reqcharflagsptr place to put the last required character flags, or a negative number + firstcharptr place to put the first required character, or a negative number + reqcharptr place to put the last required character, or a negative number bcptr pointer to the chain of currently open branches cd points to the data block with tables pointers etc. lengthptr NULL during the real compile phase @@ -7095,9 +7025,7 @@ Returns: TRUE on success static BOOL compile_regex(int options, pcre_uchar **codeptr, const pcre_uchar **ptrptr, int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes, - int cond_depth, - pcre_uint32 *firstcharptr, pcre_int32 *firstcharflagsptr, - pcre_uint32 *reqcharptr, pcre_int32 *reqcharflagsptr, + int cond_depth, pcre_int32 *firstcharptr, pcre_int32 *reqcharptr, branch_chain *bcptr, compile_data *cd, int *lengthptr) { const pcre_uchar *ptr = *ptrptr; @@ -7107,20 +7035,17 @@ pcre_uchar *start_bracket = code; pcre_uchar *reverse_count = NULL; open_capitem capitem; int capnumber = 0; -pcre_uint32 firstchar, reqchar; -pcre_int32 firstcharflags, reqcharflags; -pcre_uint32 branchfirstchar, branchreqchar; -pcre_int32 branchfirstcharflags, branchreqcharflags; +pcre_int32 firstchar, reqchar; +pcre_int32 branchfirstchar, branchreqchar; int length; -unsigned int orig_bracount; -unsigned int max_bracount; +int orig_bracount; +int max_bracount; branch_chain bc; bc.outer = bcptr; bc.current_branch = code; -firstchar = reqchar = 0; -firstcharflags = reqcharflags = REQ_UNSET; +firstchar = reqchar = REQ_UNSET; /* Accumulate the length for use in the pre-compile phase. Start with the length of the BRA and KET and any extra bytes that are required at the @@ -7180,8 +7105,8 @@ for (;;) into the length. */ if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstchar, - &branchfirstcharflags, &branchreqchar, &branchreqcharflags, &bc, - cond_depth, cd, (lengthptr == NULL)? NULL : &length)) + &branchreqchar, &bc, cond_depth, cd, + (lengthptr == NULL)? NULL : &length)) { *ptrptr = ptr; return FALSE; @@ -7202,9 +7127,7 @@ for (;;) if (*last_branch != OP_ALT) { firstchar = branchfirstchar; - firstcharflags = branchfirstcharflags; reqchar = branchreqchar; - reqcharflags = branchreqcharflags; } /* If this is not the first branch, the first char and reqchar have to @@ -7218,36 +7141,23 @@ for (;;) we have to abandon the firstchar for the regex, but if there was previously no reqchar, it takes on the value of the old firstchar. */ - if (firstcharflags >= 0 && - (firstcharflags != branchfirstcharflags || firstchar != branchfirstchar)) + if (firstchar >= 0 && firstchar != branchfirstchar) { - if (reqcharflags < 0) - { - reqchar = firstchar; - reqcharflags = firstcharflags; - } - firstcharflags = REQ_NONE; + if (reqchar < 0) reqchar = firstchar; + firstchar = REQ_NONE; } /* If we (now or from before) have no firstchar, a firstchar from the branch becomes a reqchar if there isn't a branch reqchar. */ - if (firstcharflags < 0 && branchfirstcharflags >= 0 && branchreqcharflags < 0) - { - branchreqchar = branchfirstchar; - branchreqcharflags = branchfirstcharflags; - } + if (firstchar < 0 && branchfirstchar >= 0 && branchreqchar < 0) + branchreqchar = branchfirstchar; /* Now ensure that the reqchars match */ - if (((reqcharflags & ~REQ_VARY) != (branchreqcharflags & ~REQ_VARY)) || - reqchar != branchreqchar) - reqcharflags = REQ_NONE; - else - { - reqchar = branchreqchar; - reqcharflags |= branchreqcharflags; /* To "or" REQ_VARY */ - } + if ((reqchar & ~REQ_VARY) != (branchreqchar & ~REQ_VARY)) + reqchar = REQ_NONE; + else reqchar |= branchreqchar; /* To "or" REQ_VARY */ } /* If lookbehind, check that this branch matches a fixed-length string, and @@ -7343,9 +7253,7 @@ for (;;) *codeptr = code; *ptrptr = ptr; *firstcharptr = firstchar; - *firstcharflagsptr = firstcharflags; *reqcharptr = reqchar; - *reqcharflagsptr = reqcharflags; if (lengthptr != NULL) { if (OFLOW_MAX - *lengthptr < length) @@ -7415,23 +7323,19 @@ and the highest back reference was greater than or equal to that level. However, by keeping a bitmap of the first 31 back references, we can catch some of the more common cases more precisely. -... A second exception is when the .* appears inside an atomic group, because -this prevents the number of characters it matches from being adjusted. - Arguments: code points to start of expression (the bracket) bracket_map a bitmap of which brackets we are inside while testing; this handles up to substring 31; after that we just have to take the less precise approach - cd points to the compile data block - atomcount atomic group level + backref_map the back reference bitmap Returns: TRUE or FALSE */ static BOOL is_anchored(register const pcre_uchar *code, unsigned int bracket_map, - compile_data *cd, int atomcount) + unsigned int backref_map) { do { const pcre_uchar *scode = first_significant_code( @@ -7443,7 +7347,7 @@ do { if (op == OP_BRA || op == OP_BRAPOS || op == OP_SBRA || op == OP_SBRAPOS) { - if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE; + if (!is_anchored(scode, bracket_map, backref_map)) return FALSE; } /* Capturing brackets */ @@ -7453,40 +7357,30 @@ do { { int n = GET2(scode, 1+LINK_SIZE); int new_map = bracket_map | ((n < 32)? (1 << n) : 1); - if (!is_anchored(scode, new_map, cd, atomcount)) return FALSE; + if (!is_anchored(scode, new_map, backref_map)) return FALSE; } - /* Positive forward assertions and conditions */ + /* Other brackets */ - else if (op == OP_ASSERT || op == OP_COND) + else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC || + op == OP_COND) { - if (!is_anchored(scode, bracket_map, cd, atomcount)) return FALSE; - } - - /* Atomic groups */ - - else if (op == OP_ONCE || op == OP_ONCE_NC) - { - if (!is_anchored(scode, bracket_map, cd, atomcount + 1)) - return FALSE; + if (!is_anchored(scode, bracket_map, backref_map)) return FALSE; } /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and - it isn't in brackets that are or may be referenced or inside an atomic - group. */ + it isn't in brackets that are or may be referenced. */ else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR)) { - if (scode[1] != OP_ALLANY || (bracket_map & cd->backref_map) != 0 || - atomcount > 0 || cd->had_pruneorskip) + if (scode[1] != OP_ALLANY || (bracket_map & backref_map) != 0) return FALSE; } /* Check for explicit anchoring */ else if (op != OP_SOD && op != OP_SOM && op != OP_CIRC) return FALSE; - code += GET(code, 1); } while (*code == OP_ALT); /* Loop for each alternative */ @@ -7504,24 +7398,21 @@ return TRUE; matching and for non-DOTALL patterns that start with .* (which must start at the beginning or after \n). As in the case of is_anchored() (see above), we have to take account of back references to capturing brackets that contain .* -because in that case we can't make the assumption. Also, the appearance of .* -inside atomic brackets or in a pattern that contains *PRUNE or *SKIP does not -count, because once again the assumption no longer holds. +because in that case we can't make the assumption. Arguments: code points to start of expression (the bracket) bracket_map a bitmap of which brackets we are inside while testing; this handles up to substring 31; after that we just have to take the less precise approach - cd points to the compile data - atomcount atomic group level + backref_map the back reference bitmap Returns: TRUE or FALSE */ static BOOL is_startline(const pcre_uchar *code, unsigned int bracket_map, - compile_data *cd, int atomcount) + unsigned int backref_map) { do { const pcre_uchar *scode = first_significant_code( @@ -7547,7 +7438,7 @@ do { return FALSE; default: /* Assertion */ - if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE; + if (!is_startline(scode, bracket_map, backref_map)) return FALSE; do scode += GET(scode, 1); while (*scode == OP_ALT); scode += 1 + LINK_SIZE; break; @@ -7561,7 +7452,7 @@ do { if (op == OP_BRA || op == OP_BRAPOS || op == OP_SBRA || op == OP_SBRAPOS) { - if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE; + if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } /* Capturing brackets */ @@ -7571,40 +7462,25 @@ do { { int n = GET2(scode, 1+LINK_SIZE); int new_map = bracket_map | ((n < 32)? (1 << n) : 1); - if (!is_startline(scode, new_map, cd, atomcount)) return FALSE; + if (!is_startline(scode, new_map, backref_map)) return FALSE; } - /* Positive forward assertions */ + /* Other brackets */ - else if (op == OP_ASSERT) + else if (op == OP_ASSERT || op == OP_ONCE || op == OP_ONCE_NC) { - if (!is_startline(scode, bracket_map, cd, atomcount)) return FALSE; + if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } - /* Atomic brackets */ - - else if (op == OP_ONCE || op == OP_ONCE_NC) - { - if (!is_startline(scode, bracket_map, cd, atomcount + 1)) return FALSE; - } - - /* .* means "start at start or after \n" if it isn't in atomic brackets or - brackets that may be referenced, as long as the pattern does not contain - *PRUNE or *SKIP, because these break the feature. Consider, for example, - /.*?a(*PRUNE)b/ with the subject "aab", which matches "ab", i.e. not at the - start of a line. */ + /* .* means "start at start or after \n" if it isn't in brackets that + may be referenced. */ else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR) { - if (scode[1] != OP_ANY || (bracket_map & cd->backref_map) != 0 || - atomcount > 0 || cd->had_pruneorskip) - return FALSE; + if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE; } - /* Check for explicit circumflex; anything else gives a FALSE result. Note - in particular that this includes atomic brackets OP_ONCE and OP_ONCE_NC - because the number of characters matched by .* cannot be adjusted inside - them. */ + /* Check for explicit circumflex */ else if (op != OP_CIRC && op != OP_CIRCM) return FALSE; @@ -7632,33 +7508,27 @@ we return that char, otherwise -1. Arguments: code points to start of expression (the bracket) - flags points to the first char flags, or to REQ_NONE inassert TRUE if in an assertion -Returns: the fixed first char, or 0 with REQ_NONE in flags +Returns: -1 or the fixed first char */ -static pcre_uint32 -find_firstassertedchar(const pcre_uchar *code, pcre_int32 *flags, - BOOL inassert) +static int +find_firstassertedchar(const pcre_uchar *code, BOOL inassert) { -register pcre_uint32 c = 0; -int cflags = REQ_NONE; - -*flags = REQ_NONE; +register int c = -1; do { - pcre_uint32 d; - int dflags; + int d; int xl = (*code == OP_CBRA || *code == OP_SCBRA || *code == OP_CBRAPOS || *code == OP_SCBRAPOS)? IMM2_SIZE:0; const pcre_uchar *scode = first_significant_code(code + 1+LINK_SIZE + xl, TRUE); - register pcre_uchar op = *scode; + register int op = *scode; switch(op) { default: - return 0; + return -1; case OP_BRA: case OP_BRAPOS: @@ -7670,10 +7540,9 @@ do { case OP_ONCE: case OP_ONCE_NC: case OP_COND: - d = find_firstassertedchar(scode, &dflags, op == OP_ASSERT); - if (dflags < 0) - return 0; - if (cflags < 0) { c = d; cflags = dflags; } else if (c != d || cflags != dflags) return 0; + if ((d = find_firstassertedchar(scode, op == OP_ASSERT)) < 0) + return -1; + if (c < 0) c = d; else if (c != d) return -1; break; case OP_EXACT: @@ -7684,9 +7553,9 @@ do { case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: - if (!inassert) return 0; - if (cflags < 0) { c = scode[1]; cflags = 0; } - else if (c != scode[1]) return 0; + if (!inassert) return -1; + if (c < 0) c = scode[1]; + else if (c != scode[1]) return -1; break; case OP_EXACTI: @@ -7697,17 +7566,15 @@ do { case OP_PLUSI: case OP_MINPLUSI: case OP_POSPLUSI: - if (!inassert) return 0; - if (cflags < 0) { c = scode[1]; cflags = REQ_CASELESS; } - else if (c != scode[1]) return 0; + if (!inassert) return -1; + if (c < 0) c = scode[1] | REQ_CASELESS; + else if (c != scode[1]) return -1; break; } code += GET(code, 1); } while (*code == OP_ALT); - -*flags = cflags; return c; } @@ -7735,48 +7602,37 @@ Returns: pointer to compiled data block, or NULL on error, with errorptr and erroroffset set */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION pcre_compile(const char *pattern, int options, const char **errorptr, int *erroroffset, const unsigned char *tables) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION pcre16_compile(PCRE_SPTR16 pattern, int options, const char **errorptr, int *erroroffset, const unsigned char *tables) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN pcre32 * PCRE_CALL_CONVENTION -pcre32_compile(PCRE_SPTR32 pattern, int options, const char **errorptr, - int *erroroffset, const unsigned char *tables) #endif { -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables); -#elif defined COMPILE_PCRE16 +#else return pcre16_compile2(pattern, options, NULL, errorptr, erroroffset, tables); -#elif defined COMPILE_PCRE32 -return pcre32_compile2(pattern, options, NULL, errorptr, erroroffset, tables); #endif } -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION pcre_compile2(const char *pattern, int options, int *errorcodeptr, const char **errorptr, int *erroroffset, const unsigned char *tables) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN pcre16 * PCRE_CALL_CONVENTION pcre16_compile2(PCRE_SPTR16 pattern, int options, int *errorcodeptr, const char **errorptr, int *erroroffset, const unsigned char *tables) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN pcre32 * PCRE_CALL_CONVENTION -pcre32_compile2(PCRE_SPTR32 pattern, int options, int *errorcodeptr, - const char **errorptr, int *erroroffset, const unsigned char *tables) #endif { REAL_PCRE *re; int length = 1; /* For final END opcode */ -pcre_uint32 firstchar, reqchar; -pcre_int32 firstcharflags, reqcharflags; +pcre_int32 firstchar, reqchar; int newline; int errorcode = 0; int skipatstart = 0; @@ -7849,25 +7705,14 @@ while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS && int newnl = 0; int newbsr = 0; -/* For completeness and backward compatibility, (*UTFn) is supported in the -relevant libraries, but (*UTF) is generic and always supported. Note that -PCRE_UTF8 == PCRE_UTF16 == PCRE_UTF32. */ - #ifdef COMPILE_PCRE8 - if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF8_RIGHTPAR, 5) == 0) + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 5) == 0) { skipatstart += 7; options |= PCRE_UTF8; continue; } #endif #ifdef COMPILE_PCRE16 - if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF16_RIGHTPAR, 6) == 0) + if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 6) == 0) { skipatstart += 8; options |= PCRE_UTF16; continue; } #endif -#ifdef COMPILE_PCRE32 - if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF32_RIGHTPAR, 6) == 0) - { skipatstart += 8; options |= PCRE_UTF32; continue; } -#endif - - else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UTF_RIGHTPAR, 4) == 0) - { skipatstart += 6; options |= PCRE_UTF8; continue; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_UCP_RIGHTPAR, 4) == 0) { skipatstart += 6; options |= PCRE_UCP; continue; } else if (STRNCMP_UC_C8(ptr+skipatstart+2, STRING_NO_START_OPT_RIGHTPAR, 13) == 0) @@ -7896,7 +7741,7 @@ PCRE_UTF8 == PCRE_UTF16 == PCRE_UTF32. */ else break; } -/* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */ +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ utf = (options & PCRE_UTF8) != 0; /* Can't support UTF unless PCRE has been compiled to include the code. The @@ -7908,12 +7753,10 @@ not used here. */ if (utf && (options & PCRE_NO_UTF8_CHECK) == 0 && (errorcode = PRIV(valid_utf)((PCRE_PUCHAR)pattern, -1, erroroffset)) != 0) { -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 errorcode = ERR44; -#elif defined COMPILE_PCRE16 +#else errorcode = ERR74; -#elif defined COMPILE_PCRE32 - errorcode = ERR77; #endif goto PCRE_EARLY_ERROR_RETURN2; } @@ -8033,8 +7876,7 @@ ptr += skipatstart; code = cworkspace; *code = OP_BRA; (void)compile_regex(cd->external_options, &code, &ptr, &errorcode, FALSE, - FALSE, 0, 0, &firstchar, &firstcharflags, &reqchar, &reqcharflags, NULL, - cd, &length); + FALSE, 0, 0, &firstchar, &reqchar, NULL, cd, &length); if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN; DPRINTF(("end pre-compile: length=%d workspace=%d\n", length, @@ -8078,9 +7920,6 @@ re->name_count = cd->names_found; re->ref_count = 0; re->tables = (tables == PRIV(default_tables))? NULL : tables; re->nullpad = NULL; -#ifdef COMPILE_PCRE32 -re->dummy1 = re->dummy2 = 0; -#endif /* The starting points of the name/number translation table and of the code are passed around in the compile data block. The start/end pattern and initial @@ -8100,7 +7939,6 @@ cd->start_code = codestart; cd->hwm = (pcre_uchar *)(cd->start_workspace); cd->req_varyopt = 0; cd->had_accept = FALSE; -cd->had_pruneorskip = FALSE; cd->check_lookbehind = FALSE; cd->open_caps = NULL; @@ -8112,21 +7950,17 @@ ptr = (const pcre_uchar *)pattern + skipatstart; code = (pcre_uchar *)codestart; *code = OP_BRA; (void)compile_regex(re->options, &code, &ptr, &errorcode, FALSE, FALSE, 0, 0, - &firstchar, &firstcharflags, &reqchar, &reqcharflags, NULL, cd, NULL); + &firstchar, &reqchar, NULL, cd, NULL); re->top_bracket = cd->bracount; re->top_backref = cd->top_backref; re->max_lookbehind = cd->max_lookbehind; re->flags = cd->external_flags | PCRE_MODE; -if (cd->had_accept) - { - reqchar = 0; /* Must disable after (*ACCEPT) */ - reqcharflags = REQ_NONE; - } +if (cd->had_accept) reqchar = REQ_NONE; /* Must disable after (*ACCEPT) */ /* If not reached end of pattern on success, there's an excess bracket. */ -if (errorcode == 0 && *ptr != CHAR_NULL) errorcode = ERR22; +if (errorcode == 0 && *ptr != 0) errorcode = ERR22; /* Fill in the terminating state and check for disastrous overflow, but if debugging, leave the test till after things are printed out. */ @@ -8137,13 +7971,6 @@ if debugging, leave the test till after things are printed out. */ if (code - codestart > length) errorcode = ERR23; #endif -#ifdef SUPPORT_VALGRIND -/* If the estimated length exceeds the really used length, mark the extra -allocated memory as unadressable, so that any out-of-bound reads can be -detected. */ -VALGRIND_MAKE_MEM_NOACCESS(code, (length - (code - codestart)) * sizeof(pcre_uchar)); -#endif - /* Fill in any forward references that are required. There may be repeated references; optimize for them, as searching a large regex takes time. */ @@ -8179,7 +8006,7 @@ if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15; /* If there were any lookbehind assertions that contained OP_RECURSE (recursions or subroutine calls), a flag is set for them to be checked here, -because they may contain forward references. Actual recursions cannot be fixed +because they may contain forward references. Actual recursions can't be fixed length, but subroutine calls can. It is done like this so that those without OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The exceptional ones forgo this. We scan the pattern to check that they are fixed @@ -8235,33 +8062,33 @@ if (errorcode != 0) } /* If the anchored option was not passed, set the flag if we can determine that -the pattern is anchored by virtue of ^ characters or \A or anything else, such -as starting with non-atomic .* when DOTALL is set and there are no occurrences -of *PRUNE or *SKIP. +the pattern is anchored by virtue of ^ characters or \A or anything else (such +as starting with .* when DOTALL is set). Otherwise, if we know what the first byte has to be, save it, because that speeds up unanchored matches no end. If not, see if we can set the PCRE_STARTLINE flag. This is helpful for multiline matches when all branches -start with ^. and also when all branches start with non-atomic .* for -non-DOTALL matches when *PRUNE and SKIP are not present. */ +start with ^. and also when all branches start with .* for non-DOTALL matches. +*/ if ((re->options & PCRE_ANCHORED) == 0) { - if (is_anchored(codestart, 0, cd, 0)) re->options |= PCRE_ANCHORED; + if (is_anchored(codestart, 0, cd->backref_map)) + re->options |= PCRE_ANCHORED; else { - if (firstcharflags < 0) - firstchar = find_firstassertedchar(codestart, &firstcharflags, FALSE); - if (firstcharflags >= 0) /* Remove caseless flag for non-caseable chars */ + if (firstchar < 0) + firstchar = find_firstassertedchar(codestart, FALSE); + if (firstchar >= 0) /* Remove caseless flag for non-caseable chars */ { -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 re->first_char = firstchar & 0xff; -#elif defined COMPILE_PCRE16 +#else +#ifdef COMPILE_PCRE16 re->first_char = firstchar & 0xffff; -#elif defined COMPILE_PCRE32 - re->first_char = firstchar; #endif - if ((firstcharflags & REQ_CASELESS) != 0) +#endif + if ((firstchar & REQ_CASELESS) != 0) { #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) /* We ignore non-ASCII first chars in 8 bit mode. */ @@ -8284,8 +8111,8 @@ if ((re->options & PCRE_ANCHORED) == 0) re->flags |= PCRE_FIRSTSET; } - - else if (is_startline(codestart, 0, cd, 0)) re->flags |= PCRE_STARTLINE; + else if (is_startline(codestart, 0, cd->backref_map)) + re->flags |= PCRE_STARTLINE; } } @@ -8293,17 +8120,17 @@ if ((re->options & PCRE_ANCHORED) == 0) variable length item in the regex. Remove the caseless flag for non-caseable bytes. */ -if (reqcharflags >= 0 && - ((re->options & PCRE_ANCHORED) == 0 || (reqcharflags & REQ_VARY) != 0)) +if (reqchar >= 0 && + ((re->options & PCRE_ANCHORED) == 0 || (reqchar & REQ_VARY) != 0)) { -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 re->req_char = reqchar & 0xff; -#elif defined COMPILE_PCRE16 +#else +#ifdef COMPILE_PCRE16 re->req_char = reqchar & 0xffff; -#elif defined COMPILE_PCRE32 - re->req_char = reqchar; #endif - if ((reqcharflags & REQ_CASELESS) != 0) +#endif + if ((reqchar & REQ_CASELESS) != 0) { #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8) /* We ignore non-ASCII first chars in 8 bit mode. */ @@ -8353,12 +8180,10 @@ if ((re->flags & PCRE_REQCHSET) != 0) else printf("Req char = \\x%02x%s\n", ch, caseless); } -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 pcre_printint((pcre *)re, stdout, TRUE); -#elif defined COMPILE_PCRE16 +#else pcre16_printint((pcre *)re, stdout, TRUE); -#elif defined COMPILE_PCRE32 -pcre32_printint((pcre *)re, stdout, TRUE); #endif /* This check is done here in the debugging case so that the code that @@ -8374,12 +8199,10 @@ if (code - codestart > length) } #endif /* PCRE_DEBUG */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 return (pcre *)re; -#elif defined COMPILE_PCRE16 +#else return (pcre16 *)re; -#elif defined COMPILE_PCRE32 -return (pcre32 *)re; #endif } diff --git a/harbour/src/3rd/pcre/pcreconf.c b/harbour/src/3rd/pcre/pcreconf.c index 4cf008e8a3..8d4a7f078e 100644 --- a/harbour/src/3rd/pcre/pcreconf.c +++ b/harbour/src/3rd/pcre/pcreconf.c @@ -65,21 +65,18 @@ Arguments: Returns: 0 if data returned, negative on error */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_config(int what, void *where) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_config(int what, void *where) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_config(int what, void *where) #endif { switch (what) { case PCRE_CONFIG_UTF8: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#if defined COMPILE_PCRE16 *((int *)where) = 0; return PCRE_ERROR_BADOPTION; #else @@ -92,20 +89,7 @@ switch (what) #endif case PCRE_CONFIG_UTF16: -#if defined COMPILE_PCRE8 || defined COMPILE_PCRE32 - *((int *)where) = 0; - return PCRE_ERROR_BADOPTION; -#else -#if defined SUPPORT_UTF - *((int *)where) = 1; -#else - *((int *)where) = 0; -#endif - break; -#endif - - case PCRE_CONFIG_UTF32: -#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 +#if defined COMPILE_PCRE8 *((int *)where) = 0; return PCRE_ERROR_BADOPTION; #else diff --git a/harbour/src/3rd/pcre/pcredfa.c b/harbour/src/3rd/pcre/pcredfa.c index 60fba7828e..509e1ce6c3 100644 --- a/harbour/src/3rd/pcre/pcredfa.c +++ b/harbour/src/3rd/pcre/pcredfa.c @@ -302,13 +302,13 @@ Returns: nothing static void pchars(const pcre_uchar *p, int length, FILE *f) { -pcre_uint32 c; +int c; while (length-- > 0) { if (isprint(c = *(p++))) fprintf(f, "%c", c); else - fprintf(f, "\\x{%02x}", c); + fprintf(f, "\\x%02x", c); } } #endif @@ -571,7 +571,7 @@ for (;;) { int i, j; int clen, dlen; - pcre_uint32 c, d; + unsigned int c, d; int forced_fail = 0; BOOL partial_newline = FALSE; BOOL could_continue = reset_could_continue; @@ -613,10 +613,9 @@ for (;;) { clen = 1; /* Number of data items in the character */ #ifdef SUPPORT_UTF - GETCHARLENTEST(c, ptr, clen); -#else - c = *ptr; + if (utf) { GETCHARLEN(c, ptr, clen); } else #endif /* SUPPORT_UTF */ + c = *ptr; } else { @@ -635,8 +634,7 @@ for (;;) BOOL caseless = FALSE; const pcre_uchar *code; int state_offset = current_state->offset; - int codevalue, rrc; - unsigned int count; + int count, codevalue, rrc; #ifdef PCRE_DEBUG printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset); @@ -1009,7 +1007,7 @@ for (;;) { const pcre_uchar *temp = ptr - 1; if (temp < md->start_used_ptr) md->start_used_ptr = temp; -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf) { BACKCHAR(temp); } #endif GETCHARTEST(d, temp); @@ -1062,7 +1060,6 @@ for (;;) if (clen > 0) { BOOL OK; - const pcre_uint32 *cp; const ucd_record * prop = GET_UCD(c); switch(code[1]) { @@ -1111,15 +1108,6 @@ for (;;) c == CHAR_UNDERSCORE; break; - case PT_CLIST: - cp = PRIV(ucd_caseless_sets) + code[2]; - for (;;) - { - if (c < *cp) { OK = FALSE; break; } - if (c == *cp++) { OK = TRUE; break; } - } - break; - /* Should never occur, but keep compilers from grumbling. */ default: @@ -1306,7 +1294,6 @@ for (;;) if (clen > 0) { BOOL OK; - const pcre_uint32 *cp; const ucd_record * prop = GET_UCD(c); switch(code[2]) { @@ -1355,15 +1342,6 @@ for (;;) c == CHAR_UNDERSCORE; break; - case PT_CLIST: - cp = PRIV(ucd_caseless_sets) + code[3]; - for (;;) - { - if (c < *cp) { OK = FALSE; break; } - if (c == *cp++) { OK = TRUE; break; } - } - break; - /* Should never occur, but keep compilers from grumbling. */ default: @@ -1390,9 +1368,8 @@ for (;;) case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS: count = current_state->count; /* Already matched */ if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); } - if (clen > 0) + if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { - int lgb, rgb; const pcre_uchar *nptr = ptr + clen; int ncount = 0; if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS) @@ -1400,16 +1377,14 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - lgb = UCD_GRAPHBREAK(c); while (nptr < end_subject) { - dlen = 1; - if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } - rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + int nd; + int ndlen = 1; + GETCHARLEN(nd, nptr, ndlen); + if (UCD_CATEGORY(nd) != ucp_M) break; ncount++; - lgb = rgb; - nptr += dlen; + nptr += ndlen; } count++; ADD_NEW_DATA(-state_offset, count, ncount); @@ -1428,22 +1403,20 @@ for (;;) int ncount = 0; switch (c) { - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC + case 0x000b: + case 0x000c: + case 0x0085: case 0x2028: case 0x2029: -#endif /* Not EBCDIC */ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; goto ANYNL01; - case CHAR_CR: - if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1; + case 0x000d: + if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1; /* Fall through */ ANYNL01: - case CHAR_LF: + case 0x000a: if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS) { active_count--; /* Remove non-match possibility */ @@ -1470,7 +1443,13 @@ for (;;) BOOL OK; switch (c) { - VSPACE_CASES: + case 0x000a: + case 0x000b: + case 0x000c: + case 0x000d: + case 0x0085: + case 0x2028: + case 0x2029: OK = TRUE; break; @@ -1503,7 +1482,25 @@ for (;;) BOOL OK; switch (c) { - HSPACE_CASES: + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ OK = TRUE; break; @@ -1544,7 +1541,6 @@ for (;;) if (clen > 0) { BOOL OK; - const pcre_uint32 *cp; const ucd_record * prop = GET_UCD(c); switch(code[2]) { @@ -1593,15 +1589,6 @@ for (;;) c == CHAR_UNDERSCORE; break; - case PT_CLIST: - cp = PRIV(ucd_caseless_sets) + code[3]; - for (;;) - { - if (c < *cp) { OK = FALSE; break; } - if (c == *cp++) { OK = TRUE; break; } - } - break; - /* Should never occur, but keep compilers from grumbling. */ default: @@ -1637,9 +1624,8 @@ for (;;) QS2: ADD_ACTIVE(state_offset + 2, 0); - if (clen > 0) + if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { - int lgb, rgb; const pcre_uchar *nptr = ptr + clen; int ncount = 0; if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR || @@ -1648,16 +1634,14 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - lgb = UCD_GRAPHBREAK(c); while (nptr < end_subject) { - dlen = 1; - if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } - rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + int nd; + int ndlen = 1; + GETCHARLEN(nd, nptr, ndlen); + if (UCD_CATEGORY(nd) != ucp_M) break; ncount++; - lgb = rgb; - nptr += dlen; + nptr += ndlen; } ADD_NEW_DATA(-(state_offset + count), 0, ncount); } @@ -1683,22 +1667,20 @@ for (;;) int ncount = 0; switch (c) { - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC + case 0x000b: + case 0x000c: + case 0x0085: case 0x2028: case 0x2029: -#endif /* Not EBCDIC */ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; goto ANYNL02; - case CHAR_CR: - if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1; + case 0x000d: + if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1; /* Fall through */ ANYNL02: - case CHAR_LF: + case 0x000a: if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR || codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY) { @@ -1733,7 +1715,13 @@ for (;;) BOOL OK; switch (c) { - VSPACE_CASES: + case 0x000a: + case 0x000b: + case 0x000c: + case 0x000d: + case 0x0085: + case 0x2028: + case 0x2029: OK = TRUE; break; @@ -1773,7 +1761,25 @@ for (;;) BOOL OK; switch (c) { - HSPACE_CASES: + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ OK = TRUE; break; @@ -1807,7 +1813,6 @@ for (;;) if (clen > 0) { BOOL OK; - const pcre_uint32 *cp; const ucd_record * prop = GET_UCD(c); switch(code[1 + IMM2_SIZE + 1]) { @@ -1856,15 +1861,6 @@ for (;;) c == CHAR_UNDERSCORE; break; - case PT_CLIST: - cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2]; - for (;;) - { - if (c < *cp) { OK = FALSE; break; } - if (c == *cp++) { OK = TRUE; break; } - } - break; - /* Should never occur, but keep compilers from grumbling. */ default: @@ -1895,9 +1891,8 @@ for (;;) if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT) { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); } count = current_state->count; /* Number already matched */ - if (clen > 0) + if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { - int lgb, rgb; const pcre_uchar *nptr = ptr + clen; int ncount = 0; if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO) @@ -1905,16 +1900,14 @@ for (;;) active_count--; /* Remove non-match possibility */ next_active_state--; } - lgb = UCD_GRAPHBREAK(c); while (nptr < end_subject) { - dlen = 1; - if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } - rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + int nd; + int ndlen = 1; + GETCHARLEN(nd, nptr, ndlen); + if (UCD_CATEGORY(nd) != ucp_M) break; ncount++; - lgb = rgb; - nptr += dlen; + nptr += ndlen; } if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0) reset_could_continue = TRUE; @@ -1939,22 +1932,20 @@ for (;;) int ncount = 0; switch (c) { - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC + case 0x000b: + case 0x000c: + case 0x0085: case 0x2028: case 0x2029: -#endif /* Not EBCDIC */ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; goto ANYNL03; - case CHAR_CR: - if (ptr + 1 < end_subject && RAWUCHARTEST(ptr + 1) == CHAR_LF) ncount = 1; + case 0x000d: + if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1; /* Fall through */ ANYNL03: - case CHAR_LF: + case 0x000a: if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO) { active_count--; /* Remove non-match possibility */ @@ -1985,7 +1976,13 @@ for (;;) BOOL OK; switch (c) { - VSPACE_CASES: + case 0x000a: + case 0x000b: + case 0x000c: + case 0x000d: + case 0x0085: + case 0x2028: + case 0x2029: OK = TRUE; break; @@ -2021,7 +2018,25 @@ for (;;) BOOL OK; switch (c) { - HSPACE_CASES: + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ OK = TRUE; break; @@ -2097,21 +2112,17 @@ for (;;) to wait for them to pass before continuing. */ case OP_EXTUNI: - if (clen > 0) + if (clen > 0 && UCD_CATEGORY(c) != ucp_M) { - int lgb, rgb; const pcre_uchar *nptr = ptr + clen; int ncount = 0; - lgb = UCD_GRAPHBREAK(c); while (nptr < end_subject) { - dlen = 1; - if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); } - rgb = UCD_GRAPHBREAK(d); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + int nclen = 1; + GETCHARLEN(c, nptr, nclen); + if (UCD_CATEGORY(c) != ucp_M) break; ncount++; - lgb = rgb; - nptr += dlen; + nptr += nclen; } if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0) reset_could_continue = TRUE; @@ -2128,27 +2139,25 @@ for (;;) case OP_ANYNL: if (clen > 0) switch(c) { - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC + case 0x000b: + case 0x000c: + case 0x0085: case 0x2028: case 0x2029: -#endif /* Not EBCDIC */ if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break; - case CHAR_LF: + case 0x000a: ADD_NEW(state_offset + 1, 0); break; - case CHAR_CR: + case 0x000d: if (ptr + 1 >= end_subject) { ADD_NEW(state_offset + 1, 0); if ((md->moptions & PCRE_PARTIAL_HARD) != 0) reset_could_continue = TRUE; } - else if (RAWUCHARTEST(ptr + 1) == CHAR_LF) + else if (ptr[1] == 0x0a) { ADD_NEW_DATA(-(state_offset + 1), 0, 1); } @@ -2164,7 +2173,13 @@ for (;;) case OP_NOT_VSPACE: if (clen > 0) switch(c) { - VSPACE_CASES: + case 0x000a: + case 0x000b: + case 0x000c: + case 0x000d: + case 0x0085: + case 0x2028: + case 0x2029: break; default: @@ -2177,12 +2192,17 @@ for (;;) case OP_VSPACE: if (clen > 0) switch(c) { - VSPACE_CASES: + case 0x000a: + case 0x000b: + case 0x000c: + case 0x000d: + case 0x0085: + case 0x2028: + case 0x2029: ADD_NEW(state_offset + 1, 0); break; - default: - break; + default: break; } break; @@ -2190,7 +2210,25 @@ for (;;) case OP_NOT_HSPACE: if (clen > 0) switch(c) { - HSPACE_CASES: + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ break; default: @@ -2203,12 +2241,27 @@ for (;;) case OP_HSPACE: if (clen > 0) switch(c) { - HSPACE_CASES: + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ ADD_NEW(state_offset + 1, 0); break; - - default: - break; } break; @@ -2262,7 +2315,7 @@ for (;;) if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); } if (clen > 0) { - pcre_uint32 otherd = NOTACHAR; + unsigned int otherd = NOTACHAR; if (caseless) { #ifdef SUPPORT_UTF @@ -2309,7 +2362,7 @@ for (;;) ADD_ACTIVE(state_offset + dlen + 1, 0); if (clen > 0) { - pcre_uint32 otherd = NOTACHAR; + unsigned int otherd = NOTACHAR; if (caseless) { #ifdef SUPPORT_UTF @@ -2354,7 +2407,7 @@ for (;;) ADD_ACTIVE(state_offset + dlen + 1, 0); if (clen > 0) { - pcre_uint32 otherd = NOTACHAR; + unsigned int otherd = NOTACHAR; if (caseless) { #ifdef SUPPORT_UTF @@ -2391,7 +2444,7 @@ for (;;) count = current_state->count; /* Number already matched */ if (clen > 0) { - pcre_uint32 otherd = NOTACHAR; + unsigned int otherd = NOTACHAR; if (caseless) { #ifdef SUPPORT_UTF @@ -2435,7 +2488,7 @@ for (;;) count = current_state->count; /* Number already matched */ if (clen > 0) { - pcre_uint32 otherd = NOTACHAR; + unsigned int otherd = NOTACHAR; if (caseless) { #ifdef SUPPORT_UTF @@ -2533,7 +2586,7 @@ for (;;) { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } if (isinclass) { - unsigned int max = GET2(ecode, 1 + IMM2_SIZE); + int max = GET2(ecode, 1 + IMM2_SIZE); if (++count >= max && max != 0) /* Max 0 => no limit */ { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); } else @@ -2609,12 +2662,10 @@ for (;;) cb.version = 1; /* Version 1 of the callout block */ cb.callout_number = code[LINK_SIZE+2]; cb.offset_vector = offsets; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)start_subject; -#elif defined COMPILE_PCRE16 +#else cb.subject = (PCRE_SPTR16)start_subject; -#elif defined COMPILE_PCRE32 - cb.subject = (PCRE_SPTR32)start_subject; #endif cb.subject_length = (int)(end_subject - start_subject); cb.start_match = (int)(current_subject - start_subject); @@ -2745,7 +2796,7 @@ for (;;) for (rc = rc*2 - 2; rc >= 0; rc -= 2) { int charcount = local_offsets[rc+1] - local_offsets[rc]; -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf) { const pcre_uchar *p = start_subject + local_offsets[rc]; @@ -2849,7 +2900,7 @@ for (;;) const pcre_uchar *p = ptr; const pcre_uchar *pp = local_ptr; charcount = (int)(pp - p); -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf) while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--; #endif ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1)); @@ -2931,7 +2982,7 @@ for (;;) } else { -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (utf) { const pcre_uchar *p = start_subject + local_offsets[0]; @@ -2960,12 +3011,10 @@ for (;;) cb.version = 1; /* Version 1 of the callout block */ cb.callout_number = code[1]; cb.offset_vector = offsets; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)start_subject; -#elif defined COMPILE_PCRE16 +#else cb.subject = (PCRE_SPTR16)start_subject; -#elif defined COMPILE_PCRE32 - cb.subject = (PCRE_SPTR32)start_subject; #endif cb.subject_length = (int)(end_subject - start_subject); cb.start_match = (int)(current_subject - start_subject); @@ -3081,21 +3130,16 @@ Returns: > 0 => number of match offset pairs placed in offsets < -1 => some kind of unexpected problem */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data, const char *subject, int length, int start_offset, int options, int *offsets, int offsetcount, int *workspace, int wscount) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets, int offsetcount, int *workspace, int wscount) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_dfa_exec(const pcre32 *argument_re, const pcre32_extra *extra_data, - PCRE_SPTR32 subject, int length, int start_offset, int options, int *offsets, - int offsetcount, int *workspace, int wscount) #endif { REAL_PCRE *re = (REAL_PCRE *)argument_re; @@ -3122,7 +3166,6 @@ if (re == NULL || subject == NULL || workspace == NULL || (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE; -if (length < 0) return PCRE_ERROR_BADLENGTH; if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; /* Check that the first field in the block is the magic number. If it is not, @@ -3171,7 +3214,7 @@ end_subject = (const pcre_uchar *)subject + length; req_char_ptr = current_subject - 1; #ifdef SUPPORT_UTF -/* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */ +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ utf = (re->options & PCRE_UTF8) != 0; #else utf = FALSE; @@ -3257,21 +3300,12 @@ if (utf && (options & PCRE_NO_UTF8_CHECK) == 0) offsets[0] = erroroffset; offsets[1] = errorcode; } -#if defined COMPILE_PCRE8 - return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0) ? + return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)? PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; -#elif defined COMPILE_PCRE16 - return (errorcode <= PCRE_UTF16_ERR1 && (options & PCRE_PARTIAL_HARD) != 0) ? - PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16; -#elif defined COMPILE_PCRE32 - return PCRE_ERROR_BADUTF32; -#endif } -#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 if (start_offset > 0 && start_offset < length && NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset])) return PCRE_ERROR_BADUTF8_OFFSET; -#endif } #endif @@ -3381,15 +3415,12 @@ for (;;) if (has_first_char) { if (first_char != first_char2) - { - pcre_uchar csc; while (current_subject < end_subject && - (csc = RAWUCHARTEST(current_subject)) != first_char && csc != first_char2) + *current_subject != first_char && *current_subject != first_char2) current_subject++; - } else while (current_subject < end_subject && - RAWUCHARTEST(current_subject) != first_char) + *current_subject != first_char) current_subject++; } @@ -3419,10 +3450,10 @@ for (;;) ANYCRLF, and we are now at a LF, advance the match position by one more character. */ - if (RAWUCHARTEST(current_subject - 1) == CHAR_CR && + if (current_subject[-1] == CHAR_CR && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) && current_subject < end_subject && - RAWUCHARTEST(current_subject) == CHAR_NL) + *current_subject == CHAR_NL) current_subject++; } } @@ -3433,7 +3464,7 @@ for (;;) { while (current_subject < end_subject) { - register pcre_uint32 c = RAWUCHARTEST(current_subject); + register unsigned int c = *current_subject; #ifndef COMPILE_PCRE8 if (c > 255) c = 255; #endif @@ -3499,7 +3530,7 @@ for (;;) { while (p < end_subject) { - register pcre_uint32 pp = RAWUCHARINCTEST(p); + register int pp = *p++; if (pp == req_char || pp == req_char2) { p--; break; } } } @@ -3507,7 +3538,7 @@ for (;;) { while (p < end_subject) { - if (RAWUCHARINCTEST(p) == req_char) { p--; break; } + if (*p++ == req_char) { p--; break; } } } @@ -3565,9 +3596,9 @@ for (;;) not contain any explicit matches for \r or \n, and the newline option is CRLF or ANY or ANYCRLF, advance the match position by one more character. */ - if (RAWUCHARTEST(current_subject - 1) == CHAR_CR && + if (current_subject[-1] == CHAR_CR && current_subject < end_subject && - RAWUCHARTEST(current_subject) == CHAR_NL && + *current_subject == CHAR_NL && (re->flags & PCRE_HASCRORLF) == 0 && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF || diff --git a/harbour/src/3rd/pcre/pcreexec.c b/harbour/src/3rd/pcre/pcreexec.c index e7deb617b9..67c8afefa3 100644 --- a/harbour/src/3rd/pcre/pcreexec.c +++ b/harbour/src/3rd/pcre/pcreexec.c @@ -92,6 +92,8 @@ because the offset vector is always a multiple of 3 long. */ static const char rep_min[] = { 0, 0, 1, 1, 0, 0 }; static const char rep_max[] = { 0, 0, 0, 0, 1, 1 }; + + #ifdef PCRE_DEBUG /************************************************* * Debugging function to print chars * @@ -112,11 +114,10 @@ Returns: nothing static void pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md) { -pcre_uint32 c; -BOOL utf = md->utf; +unsigned int c; if (is_subject && length > md->end_subject - p) length = md->end_subject - p; while (length-- > 0) - if (isprint(c = RAWUCHARINCTEST(p))) printf("%c", (char)c); else printf("\\x{%02x}", c); + if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c); } #endif @@ -149,9 +150,6 @@ match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md, { PCRE_PUCHAR eptr_start = eptr; register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset]; -#ifdef SUPPORT_UTF -BOOL utf = md->utf; -#endif #ifdef PCRE_DEBUG if (eptr >= md->end_subject) @@ -179,35 +177,24 @@ if (caseless) { #ifdef SUPPORT_UTF #ifdef SUPPORT_UCP - if (utf) + if (md->utf) { /* Match characters up to the end of the reference. NOTE: the number of - data units matched may differ, because in UTF-8 there are some characters - whose upper and lower case versions code have different numbers of bytes. - For example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65 - (3 bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a - sequence of two of the latter. It is important, therefore, to check the - length along the reference, not along the subject (earlier code did this - wrong). */ + bytes matched may differ, because there are some characters whose upper and + lower case versions code as different numbers of bytes. For example, U+023A + (2 bytes in UTF-8) is the upper case version of U+2C65 (3 bytes in UTF-8); + a sequence of 3 of the former uses 6 bytes, as does a sequence of two of + the latter. It is important, therefore, to check the length along the + reference, not along the subject (earlier code did this wrong). */ PCRE_PUCHAR endptr = p + length; while (p < endptr) { - pcre_uint32 c, d; - const ucd_record *ur; + int c, d; if (eptr >= md->end_subject) return -2; /* Partial match */ GETCHARINC(c, eptr); GETCHARINC(d, p); - ur = GET_UCD(d); - if (c != d && c != d + ur->other_case) - { - const pcre_uint32 *pp = PRIV(ucd_caseless_sets) + ur->caseset; - for (;;) - { - if (c < *pp) return -1; - if (c == *pp++) break; - } - } + if (c != d && c != UCD_OTHERCASE(d)) return -1; } } else @@ -219,11 +206,8 @@ if (caseless) { while (length-- > 0) { - pcre_uchar cc, cp; if (eptr >= md->end_subject) return -2; /* Partial match */ - cc = RAWUCHARTEST(eptr); - cp = RAWUCHARTEST(p); - if (TABLE_GET(cp, md->lcc, cp) != TABLE_GET(cc, md->lcc, cc)) return -1; + if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1; p++; eptr++; } @@ -238,7 +222,7 @@ else while (length-- > 0) { if (eptr >= md->end_subject) return -2; /* Partial match */ - if (RAWUCHARINCTEST(p) != RAWUCHARINCTEST(eptr)) return -1; + if (*p++ != *eptr++) return -1; } } @@ -294,7 +278,7 @@ enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10, RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40, RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50, RM51, RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60, - RM61, RM62, RM63, RM64, RM65, RM66, RM67 }; + RM61, RM62, RM63, RM64, RM65, RM66 }; /* These versions of the macros use the stack, as normal. There are debugging versions and production versions. Note that the "rw" argument of RMATCH isn't @@ -312,7 +296,7 @@ actually used in this definition. */ } #define RRETURN(ra) \ { \ - printf("match() returned %d from line %d\n", ra, __LINE__); \ + printf("match() returned %d from line %d ", ra, __LINE__); \ return ra; \ } #else @@ -403,7 +387,7 @@ typedef struct heapframe { #ifdef SUPPORT_UCP int Xprop_type; - unsigned int Xprop_value; + int Xprop_value; int Xprop_fail_result; int Xoclength; pcre_uchar Xocchars[6]; @@ -504,7 +488,7 @@ so they can be ordinary variables in all cases. Mark some of them with register int rrc; /* Returns from recursive calls */ register int i; /* Used for loops not involving calls to RMATCH() */ -register pcre_uint32 c; /* Character values not kept over RMATCH() calls */ +register unsigned int c; /* Character values not kept over RMATCH() calls */ register BOOL utf; /* Local copy of UTF flag for speed */ BOOL minimize, possessive; /* Quantifier options */ @@ -621,7 +605,7 @@ BOOL prev_is_word; #ifdef SUPPORT_UCP int prop_type; -unsigned int prop_value; +int prop_value; int prop_fail_result; int oclength; pcre_uchar occhars[6]; @@ -632,9 +616,9 @@ int ctype; int length; int max; int min; -unsigned int number; +int number; int offset; -pcre_uchar op; +int op; int save_capture_last; int save_offset1, save_offset2, save_offset3; int stacksave[REC_STACK_SAVE_MAX]; @@ -753,7 +737,7 @@ for (;;) unaltered. */ else if (rrc == MATCH_SKIP_ARG && - STRCMP_UC_UC_TEST(ecode + 2, md->start_match_ptr) == 0) + STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0) { md->start_match_ptr = eptr; RRETURN(MATCH_SKIP); @@ -1278,12 +1262,10 @@ for (;;) cb.version = 2; /* Version 1 of the callout block */ cb.callout_number = ecode[LINK_SIZE+2]; cb.offset_vector = md->offset_vector; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)md->start_subject; -#elif defined COMPILE_PCRE16 +#else cb.subject = (PCRE_SPTR16)md->start_subject; -#elif defined COMPILE_PCRE32 - cb.subject = (PCRE_SPTR32)md->start_subject; #endif cb.subject_length = (int)(md->end_subject - md->start_subject); cb.start_match = (int)(mstart - md->start_subject); @@ -1313,7 +1295,7 @@ for (;;) } else { - unsigned int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/ + int recno = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/ condition = (recno == RREF_ANY || recno == md->recursive->group_num); /* If the test is for recursion into a specific subpattern, and it is @@ -1385,7 +1367,7 @@ for (;;) if (!condition && condcode == OP_NCREF) { - unsigned int refno = offset >> 1; + int refno = offset >> 1; pcre_uchar *slotA = md->name_table; for (i = 0; i < md->name_count; i++) @@ -1703,12 +1685,10 @@ for (;;) cb.version = 2; /* Version 1 of the callout block */ cb.callout_number = ecode[1]; cb.offset_vector = md->offset_vector; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 cb.subject = (PCRE_SPTR)md->start_subject; -#elif defined COMPILE_PCRE16 +#else cb.subject = (PCRE_SPTR16)md->start_subject; -#elif defined COMPILE_PCRE32 - cb.subject = (PCRE_SPTR32)md->start_subject; #endif cb.subject_length = (int)(md->end_subject - md->start_subject); cb.start_match = (int)(mstart - md->start_subject); @@ -1745,7 +1725,7 @@ for (;;) case OP_RECURSE: { recursion_info *ri; - unsigned int recno; + int recno; callpat = md->start_code + GET(ecode, 1); recno = (callpat == md->start_code)? 0 : @@ -2099,7 +2079,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHARTEST(eptr) == NLBLOCK->nl[0]) + *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -2143,7 +2123,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHARTEST(eptr) == NLBLOCK->nl[0]) + *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -2286,7 +2266,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHARTEST(eptr) == NLBLOCK->nl[0]) + *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -2435,24 +2415,22 @@ for (;;) { default: RRETURN(MATCH_NOMATCH); - case CHAR_CR: + case 0x000d: if (eptr >= md->end_subject) { SCHECK_PARTIAL(); } - else if (RAWUCHARTEST(eptr) == CHAR_LF) eptr++; + else if (*eptr == 0x0a) eptr++; break; - case CHAR_LF: + case 0x000a: break; - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC + case 0x000b: + case 0x000c: + case 0x0085: case 0x2028: case 0x2029: -#endif /* Not EBCDIC */ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } @@ -2468,8 +2446,27 @@ for (;;) GETCHARINCTEST(c, eptr); switch(c) { - HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */ default: break; + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ + RRETURN(MATCH_NOMATCH); } ecode++; break; @@ -2483,8 +2480,27 @@ for (;;) GETCHARINCTEST(c, eptr); switch(c) { - HSPACE_CASES: break; /* Byte and multibyte cases */ default: RRETURN(MATCH_NOMATCH); + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ + break; } ecode++; break; @@ -2498,8 +2514,15 @@ for (;;) GETCHARINCTEST(c, eptr); switch(c) { - VSPACE_CASES: RRETURN(MATCH_NOMATCH); default: break; + case 0x0a: /* LF */ + case 0x0b: /* VT */ + case 0x0c: /* FF */ + case 0x0d: /* CR */ + case 0x85: /* NEL */ + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ + RRETURN(MATCH_NOMATCH); } ecode++; break; @@ -2513,8 +2536,15 @@ for (;;) GETCHARINCTEST(c, eptr); switch(c) { - VSPACE_CASES: break; default: RRETURN(MATCH_NOMATCH); + case 0x0a: /* LF */ + case 0x0b: /* VT */ + case 0x0c: /* FF */ + case 0x0d: /* CR */ + case 0x85: /* NEL */ + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ + break; } ecode++; break; @@ -2532,7 +2562,6 @@ for (;;) } GETCHARINCTEST(c, eptr); { - const pcre_uint32 *cp; const ucd_record *prop = GET_UCD(c); switch(ecode[1]) @@ -2593,17 +2622,6 @@ for (;;) RRETURN(MATCH_NOMATCH); break; - case PT_CLIST: - cp = PRIV(ucd_caseless_sets) + ecode[2]; - for (;;) - { - if (c < *cp) - { if (op == OP_PROP) { RRETURN(MATCH_NOMATCH); } else break; } - if (c == *cp++) - { if (op == OP_PROP) break; else { RRETURN(MATCH_NOMATCH); } } - } - break; - /* This should never occur */ default: @@ -2623,25 +2641,19 @@ for (;;) SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - else + GETCHARINCTEST(c, eptr); + if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); + while (eptr < md->end_subject) { - int lgb, rgb; - GETCHARINCTEST(c, eptr); - lgb = UCD_GRAPHBREAK(c); - while (eptr < md->end_subject) - { - int len = 1; - if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } - rgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - lgb = rgb; - eptr += len; - } + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; + eptr += len; } CHECK_PARTIAL(); ecode++; break; -#endif /* SUPPORT_UCP */ +#endif /* Match a back reference, possibly repeatedly. Look past the end of the @@ -3150,7 +3162,7 @@ for (;;) CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */ RRETURN(MATCH_NOMATCH); } - while (length-- > 0) if (*ecode++ != RAWUCHARINC(eptr)) RRETURN(MATCH_NOMATCH); + while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH); } else #endif @@ -3190,8 +3202,8 @@ for (;;) if (fc < 128) { - pcre_uchar cc = RAWUCHAR(eptr); - if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH); + if (md->lcc[fc] + != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH); ecode++; eptr++; } @@ -3202,7 +3214,7 @@ for (;;) else { - pcre_uint32 dc; + unsigned int dc; GETCHARINC(dc, eptr); ecode += length; @@ -3312,7 +3324,7 @@ for (;;) if (length > 1) { #ifdef SUPPORT_UCP - pcre_uint32 othercase; + unsigned int othercase; if (op >= OP_STARI && /* Caseless */ (othercase = UCD_OTHERCASE(fc)) != fc) oclength = PRIV(ord2utf)(othercase, occhars); @@ -3439,15 +3451,12 @@ for (;;) for (i = 1; i <= min; i++) { - pcre_uchar cc; - if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHARTEST(eptr); - if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH); + if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH); eptr++; } if (min == max) continue; @@ -3455,8 +3464,6 @@ for (;;) { for (fi = min;; fi++) { - pcre_uchar cc; - RMATCH(eptr, ecode, offset_top, md, eptrb, RM24); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max) RRETURN(MATCH_NOMATCH); @@ -3465,8 +3472,7 @@ for (;;) SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHARTEST(eptr); - if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH); + if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH); eptr++; } /* Control never gets here */ @@ -3476,15 +3482,12 @@ for (;;) pp = eptr; for (i = min; i < max; i++) { - pcre_uchar cc; - if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } - cc = RAWUCHARTEST(eptr); - if (fc != cc && foc != cc) break; + if (fc != *eptr && foc != *eptr) break; eptr++; } @@ -3512,7 +3515,7 @@ for (;;) SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH); + if (fc != *eptr++) RRETURN(MATCH_NOMATCH); } if (min == max) continue; @@ -3529,7 +3532,7 @@ for (;;) SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH); + if (fc != *eptr++) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } @@ -3543,7 +3546,7 @@ for (;;) SCHECK_PARTIAL(); break; } - if (fc != RAWUCHARTEST(eptr)) break; + if (fc != *eptr) break; eptr++; } if (possessive) continue; @@ -3572,7 +3575,7 @@ for (;;) #ifdef SUPPORT_UTF if (utf) { - register pcre_uint32 ch, och; + register unsigned int ch, och; ecode++; GETCHARINC(ch, ecode); @@ -3599,7 +3602,7 @@ for (;;) else #endif { - register pcre_uint32 ch = ecode[1]; + register unsigned int ch = ecode[1]; c = *eptr++; if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c)) RRETURN(MATCH_NOMATCH); @@ -3713,7 +3716,7 @@ for (;;) #ifdef SUPPORT_UTF if (utf) { - register pcre_uint32 d; + register unsigned int d; for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) @@ -3748,7 +3751,7 @@ for (;;) #ifdef SUPPORT_UTF if (utf) { - register pcre_uint32 d; + register unsigned int d; for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM28); @@ -3793,7 +3796,7 @@ for (;;) #ifdef SUPPORT_UTF if (utf) { - register pcre_uint32 d; + register unsigned int d; for (i = min; i < max; i++) { int len = 1; @@ -3850,7 +3853,7 @@ for (;;) #ifdef SUPPORT_UTF if (utf) { - register pcre_uint32 d; + register unsigned int d; for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) @@ -3884,7 +3887,7 @@ for (;;) #ifdef SUPPORT_UTF if (utf) { - register pcre_uint32 d; + register unsigned int d; for (fi = min;; fi++) { RMATCH(eptr, ecode, offset_top, md, eptrb, RM32); @@ -3928,7 +3931,7 @@ for (;;) #ifdef SUPPORT_UTF if (utf) { - register pcre_uint32 d; + register unsigned int d; for (i = min; i < max; i++) { int len = 1; @@ -4204,27 +4207,6 @@ for (;;) } break; - case PT_CLIST: - for (i = 1; i <= min; i++) - { - const pcre_uint32 *cp; - if (eptr >= md->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - cp = PRIV(ucd_caseless_sets) + prop_value; - for (;;) - { - if (c < *cp) - { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } } - if (c == *cp++) - { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; } - } - } - break; - /* This should not occur */ default: @@ -4244,20 +4226,14 @@ for (;;) SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - else + GETCHARINCTEST(c, eptr); + if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); + while (eptr < md->end_subject) { - int lgb, rgb; - GETCHARINCTEST(c, eptr); - lgb = UCD_GRAPHBREAK(c); - while (eptr < md->end_subject) - { - int len = 1; - if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } - rgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - lgb = rgb; - eptr += len; - } + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; + eptr += len; } CHECK_PARTIAL(); } @@ -4284,7 +4260,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHAR(eptr) == NLBLOCK->nl[0]) + *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -4325,20 +4301,18 @@ for (;;) { default: RRETURN(MATCH_NOMATCH); - case CHAR_CR: - if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++; + case 0x000d: + if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; - case CHAR_LF: + case 0x000a: break; - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC + case 0x000b: + case 0x000c: + case 0x0085: case 0x2028: case 0x2029: -#endif /* Not EBCDIC */ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } @@ -4356,8 +4330,27 @@ for (;;) GETCHARINC(c, eptr); switch(c) { - HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */ default: break; + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ + RRETURN(MATCH_NOMATCH); } } break; @@ -4373,8 +4366,27 @@ for (;;) GETCHARINC(c, eptr); switch(c) { - HSPACE_CASES: break; /* Byte and multibyte cases */ default: RRETURN(MATCH_NOMATCH); + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ + break; } } break; @@ -4390,8 +4402,15 @@ for (;;) GETCHARINC(c, eptr); switch(c) { - VSPACE_CASES: RRETURN(MATCH_NOMATCH); default: break; + case 0x0a: /* LF */ + case 0x0b: /* VT */ + case 0x0c: /* FF */ + case 0x0d: /* CR */ + case 0x85: /* NEL */ + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ + RRETURN(MATCH_NOMATCH); } } break; @@ -4407,8 +4426,15 @@ for (;;) GETCHARINC(c, eptr); switch(c) { - VSPACE_CASES: break; default: RRETURN(MATCH_NOMATCH); + case 0x0a: /* LF */ + case 0x0b: /* VT */ + case 0x0c: /* FF */ + case 0x0d: /* CR */ + case 0x85: /* NEL */ + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ + break; } } break; @@ -4430,15 +4456,12 @@ for (;;) case OP_DIGIT: for (i = 1; i <= min; i++) { - pcre_uchar cc; - if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHAR(eptr); - if (cc >= 128 || (md->ctypes[cc] & ctype_digit) == 0) + if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ @@ -4448,15 +4471,12 @@ for (;;) case OP_NOT_WHITESPACE: for (i = 1; i <= min; i++) { - pcre_uchar cc; - if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHAR(eptr); - if (cc < 128 && (md->ctypes[cc] & ctype_space) != 0) + if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); eptr++; ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); @@ -4466,15 +4486,12 @@ for (;;) case OP_WHITESPACE: for (i = 1; i <= min; i++) { - pcre_uchar cc; - if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHAR(eptr); - if (cc >= 128 || (md->ctypes[cc] & ctype_space) == 0) + if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ @@ -4484,15 +4501,12 @@ for (;;) case OP_NOT_WORDCHAR: for (i = 1; i <= min; i++) { - pcre_uchar cc; - if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHAR(eptr); - if (cc < 128 && (md->ctypes[cc] & ctype_word) != 0) + if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); eptr++; ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++); @@ -4502,15 +4516,12 @@ for (;;) case OP_WORDCHAR: for (i = 1; i <= min; i++) { - pcre_uchar cc; - if (eptr >= md->end_subject) { SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - cc = RAWUCHAR(eptr); - if (cc >= 128 || (md->ctypes[cc] & ctype_word) == 0) + if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); eptr++; /* No need to skip more bytes - we know it's a 1-byte character */ @@ -4581,17 +4592,17 @@ for (;;) { default: RRETURN(MATCH_NOMATCH); - case CHAR_CR: - if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++; + case 0x000d: + if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; - case CHAR_LF: + case 0x000a: break; - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + case 0x000b: + case 0x000c: + case 0x0085: +#ifdef COMPILE_PCRE16 case 0x2028: case 0x2029: #endif @@ -4612,9 +4623,26 @@ for (;;) switch(*eptr++) { default: break; - HSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - HSPACE_MULTIBYTE_CASES: + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ #endif RRETURN(MATCH_NOMATCH); } @@ -4632,9 +4660,26 @@ for (;;) switch(*eptr++) { default: RRETURN(MATCH_NOMATCH); - HSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - HSPACE_MULTIBYTE_CASES: + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ #endif break; } @@ -4651,12 +4696,17 @@ for (;;) } switch(*eptr++) { - VSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - VSPACE_MULTIBYTE_CASES: + default: break; + case 0x0a: /* LF */ + case 0x0b: /* VT */ + case 0x0c: /* FF */ + case 0x0d: /* CR */ + case 0x85: /* NEL */ +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ #endif RRETURN(MATCH_NOMATCH); - default: break; } } break; @@ -4672,9 +4722,14 @@ for (;;) switch(*eptr++) { default: RRETURN(MATCH_NOMATCH); - VSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - VSPACE_MULTIBYTE_CASES: + case 0x0a: /* LF */ + case 0x0b: /* VT */ + case 0x0c: /* FF */ + case 0x0d: /* CR */ + case 0x85: /* NEL */ +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ #endif break; } @@ -4952,31 +5007,8 @@ for (;;) } /* Control never gets here */ - case PT_CLIST: - for (fi = min;; fi++) - { - const pcre_uint32 *cp; - RMATCH(eptr, ecode, offset_top, md, eptrb, RM67); - if (rrc != MATCH_NOMATCH) RRETURN(rrc); - if (fi >= max) RRETURN(MATCH_NOMATCH); - if (eptr >= md->end_subject) - { - SCHECK_PARTIAL(); - RRETURN(MATCH_NOMATCH); - } - GETCHARINCTEST(c, eptr); - cp = PRIV(ucd_caseless_sets) + prop_value; - for (;;) - { - if (c < *cp) - { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } } - if (c == *cp++) - { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; } - } - } - /* Control never gets here */ - /* This should never occur */ + default: RRETURN(PCRE_ERROR_INTERNAL); } @@ -4997,20 +5029,14 @@ for (;;) SCHECK_PARTIAL(); RRETURN(MATCH_NOMATCH); } - else + GETCHARINCTEST(c, eptr); + if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH); + while (eptr < md->end_subject) { - int lgb, rgb; - GETCHARINCTEST(c, eptr); - lgb = UCD_GRAPHBREAK(c); - while (eptr < md->end_subject) - { - int len = 1; - if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } - rgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - lgb = rgb; - eptr += len; - } + int len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; + eptr += len; } CHECK_PARTIAL(); } @@ -5056,20 +5082,17 @@ for (;;) switch(c) { default: RRETURN(MATCH_NOMATCH); - case CHAR_CR: - if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++; + case 0x000d: + if (eptr < md->end_subject && *eptr == 0x0a) eptr++; + break; + case 0x000a: break; - case CHAR_LF: - break; - - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#ifndef EBCDIC + case 0x000b: + case 0x000c: + case 0x0085: case 0x2028: case 0x2029: -#endif /* Not EBCDIC */ if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH); break; } @@ -5078,32 +5101,84 @@ for (;;) case OP_NOT_HSPACE: switch(c) { - HSPACE_CASES: RRETURN(MATCH_NOMATCH); default: break; + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ + RRETURN(MATCH_NOMATCH); } break; case OP_HSPACE: switch(c) { - HSPACE_CASES: break; default: RRETURN(MATCH_NOMATCH); + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ + break; } break; case OP_NOT_VSPACE: switch(c) { - VSPACE_CASES: RRETURN(MATCH_NOMATCH); default: break; + case 0x0a: /* LF */ + case 0x0b: /* VT */ + case 0x0c: /* FF */ + case 0x0d: /* CR */ + case 0x85: /* NEL */ + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ + RRETURN(MATCH_NOMATCH); } break; case OP_VSPACE: switch(c) { - VSPACE_CASES: break; default: RRETURN(MATCH_NOMATCH); + case 0x0a: /* LF */ + case 0x0b: /* VT */ + case 0x0c: /* FF */ + case 0x0d: /* CR */ + case 0x85: /* NEL */ + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ + break; } break; @@ -5181,17 +5256,17 @@ for (;;) switch(c) { default: RRETURN(MATCH_NOMATCH); - case CHAR_CR: - if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++; + case 0x000d: + if (eptr < md->end_subject && *eptr == 0x0a) eptr++; break; - case CHAR_LF: + case 0x000a: break; - case CHAR_VT: - case CHAR_FF: - case CHAR_NEL: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + case 0x000b: + case 0x000c: + case 0x0085: +#ifdef COMPILE_PCRE16 case 0x2028: case 0x2029: #endif @@ -5204,9 +5279,26 @@ for (;;) switch(c) { default: break; - HSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - HSPACE_MULTIBYTE_CASES: + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ #endif RRETURN(MATCH_NOMATCH); } @@ -5216,9 +5308,26 @@ for (;;) switch(c) { default: RRETURN(MATCH_NOMATCH); - HSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - HSPACE_MULTIBYTE_CASES: + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ +#ifdef COMPILE_PCRE16 + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ #endif break; } @@ -5228,9 +5337,14 @@ for (;;) switch(c) { default: break; - VSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - VSPACE_MULTIBYTE_CASES: + case 0x0a: /* LF */ + case 0x0b: /* VT */ + case 0x0c: /* FF */ + case 0x0d: /* CR */ + case 0x85: /* NEL */ +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ #endif RRETURN(MATCH_NOMATCH); } @@ -5240,9 +5354,14 @@ for (;;) switch(c) { default: RRETURN(MATCH_NOMATCH); - VSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - VSPACE_MULTIBYTE_CASES: + case 0x0a: /* LF */ + case 0x0b: /* VT */ + case 0x0c: /* FF */ + case 0x0d: /* CR */ + case 0x85: /* NEL */ +#ifdef COMPILE_PCRE16 + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ #endif break; } @@ -5446,30 +5565,6 @@ for (;;) } break; - case PT_CLIST: - for (i = min; i < max; i++) - { - const pcre_uint32 *cp; - int len = 1; - if (eptr >= md->end_subject) - { - SCHECK_PARTIAL(); - break; - } - GETCHARLENTEST(c, eptr, len); - cp = PRIV(ucd_caseless_sets) + prop_value; - for (;;) - { - if (c < *cp) - { if (prop_fail_result) break; else goto GOT_MAX; } - if (c == *cp++) - { if (prop_fail_result) goto GOT_MAX; else break; } - } - eptr += len; - } - GOT_MAX: - break; - default: RRETURN(PCRE_ERROR_INTERNAL); } @@ -5493,25 +5588,21 @@ for (;;) { for (i = min; i < max; i++) { + int len = 1; if (eptr >= md->end_subject) { SCHECK_PARTIAL(); break; } - else + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) == ucp_M) break; + eptr += len; + while (eptr < md->end_subject) { - int lgb, rgb; - GETCHARINCTEST(c, eptr); - lgb = UCD_GRAPHBREAK(c); - while (eptr < md->end_subject) - { - int len = 1; - if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } - rgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; - lgb = rgb; - eptr += len; - } + len = 1; + if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } + if (UCD_CATEGORY(c) != ucp_M) break; + eptr += len; } CHECK_PARTIAL(); } @@ -5561,7 +5652,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHAR(eptr) == NLBLOCK->nl[0]) + *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -5587,7 +5678,7 @@ for (;;) eptr + 1 >= md->end_subject && NLBLOCK->nltype == NLTYPE_FIXED && NLBLOCK->nllen == 2 && - RAWUCHAR(eptr) == NLBLOCK->nl[0]) + *eptr == NLBLOCK->nl[0]) { md->hitend = TRUE; if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); @@ -5641,20 +5732,17 @@ for (;;) break; } GETCHARLEN(c, eptr, len); - if (c == CHAR_CR) + if (c == 0x000d) { if (++eptr >= md->end_subject) break; - if (RAWUCHAR(eptr) == CHAR_LF) eptr++; + if (*eptr == 0x000a) eptr++; } else { - if (c != CHAR_LF && + if (c != 0x000a && (md->bsr_anycrlf || - (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL -#ifndef EBCDIC - && c != 0x2028 && c != 0x2029 -#endif /* Not EBCDIC */ - ))) + (c != 0x000b && c != 0x000c && + c != 0x0085 && c != 0x2028 && c != 0x2029))) break; eptr += len; } @@ -5675,8 +5763,28 @@ for (;;) GETCHARLEN(c, eptr, len); switch(c) { - HSPACE_CASES: gotspace = TRUE; break; default: gotspace = FALSE; break; + case 0x09: /* HT */ + case 0x20: /* SPACE */ + case 0xa0: /* NBSP */ + case 0x1680: /* OGHAM SPACE MARK */ + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ + case 0x2000: /* EN QUAD */ + case 0x2001: /* EM QUAD */ + case 0x2002: /* EN SPACE */ + case 0x2003: /* EM SPACE */ + case 0x2004: /* THREE-PER-EM SPACE */ + case 0x2005: /* FOUR-PER-EM SPACE */ + case 0x2006: /* SIX-PER-EM SPACE */ + case 0x2007: /* FIGURE SPACE */ + case 0x2008: /* PUNCTUATION SPACE */ + case 0x2009: /* THIN SPACE */ + case 0x200A: /* HAIR SPACE */ + case 0x202f: /* NARROW NO-BREAK SPACE */ + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ + case 0x3000: /* IDEOGRAPHIC SPACE */ + gotspace = TRUE; + break; } if (gotspace == (ctype == OP_NOT_HSPACE)) break; eptr += len; @@ -5697,8 +5805,16 @@ for (;;) GETCHARLEN(c, eptr, len); switch(c) { - VSPACE_CASES: gotspace = TRUE; break; default: gotspace = FALSE; break; + case 0x0a: /* LF */ + case 0x0b: /* VT */ + case 0x0c: /* FF */ + case 0x0d: /* CR */ + case 0x85: /* NEL */ + case 0x2028: /* LINE SEPARATOR */ + case 0x2029: /* PARAGRAPH SEPARATOR */ + gotspace = TRUE; + break; } if (gotspace == (ctype == OP_NOT_VSPACE)) break; eptr += len; @@ -5812,8 +5928,8 @@ for (;;) if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); - if (ctype == OP_ANYNL && eptr > pp && RAWUCHAR(eptr) == CHAR_NL && - RAWUCHAR(eptr - 1) == CHAR_CR) eptr--; + if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' && + eptr[-1] == '\r') eptr--; } } else @@ -5864,19 +5980,19 @@ for (;;) break; } c = *eptr; - if (c == CHAR_CR) + if (c == 0x000d) { if (++eptr >= md->end_subject) break; - if (*eptr == CHAR_LF) eptr++; + if (*eptr == 0x000a) eptr++; } else { - if (c != CHAR_LF && (md->bsr_anycrlf || - (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - && c != 0x2028 && c != 0x2029 + if (c != 0x000a && (md->bsr_anycrlf || + (c != 0x000b && c != 0x000c && c != 0x0085 +#ifdef COMPILE_PCRE16 + && c != 0x2028 && c != 0x2029 #endif - ))) break; + ))) break; eptr++; } } @@ -5890,17 +6006,15 @@ for (;;) SCHECK_PARTIAL(); break; } - switch(*eptr) - { - default: eptr++; break; - HSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - HSPACE_MULTIBYTE_CASES: + c = *eptr; + if (c == 0x09 || c == 0x20 || c == 0xa0 +#ifdef COMPILE_PCRE16 + || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A) + || c == 0x202f || c == 0x205f || c == 0x3000 #endif - goto ENDLOOP00; - } + ) break; + eptr++; } - ENDLOOP00: break; case OP_HSPACE: @@ -5911,17 +6025,15 @@ for (;;) SCHECK_PARTIAL(); break; } - switch(*eptr) - { - default: goto ENDLOOP01; - HSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - HSPACE_MULTIBYTE_CASES: + c = *eptr; + if (c != 0x09 && c != 0x20 && c != 0xa0 +#ifdef COMPILE_PCRE16 + && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A) + && c != 0x202f && c != 0x205f && c != 0x3000 #endif - eptr++; break; - } + ) break; + eptr++; } - ENDLOOP01: break; case OP_NOT_VSPACE: @@ -5932,17 +6044,14 @@ for (;;) SCHECK_PARTIAL(); break; } - switch(*eptr) - { - default: eptr++; break; - VSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - VSPACE_MULTIBYTE_CASES: + c = *eptr; + if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85 +#ifdef COMPILE_PCRE16 + || c == 0x2028 || c == 0x2029 #endif - goto ENDLOOP02; - } + ) break; + eptr++; } - ENDLOOP02: break; case OP_VSPACE: @@ -5953,17 +6062,14 @@ for (;;) SCHECK_PARTIAL(); break; } - switch(*eptr) - { - default: goto ENDLOOP03; - VSPACE_BYTE_CASES: -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - VSPACE_MULTIBYTE_CASES: + c = *eptr; + if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85 +#ifdef COMPILE_PCRE16 + && c != 0x2028 && c != 0x2029 #endif - eptr++; break; - } + ) break; + eptr++; } - ENDLOOP03: break; case OP_NOT_DIGIT: @@ -6060,8 +6166,8 @@ for (;;) RMATCH(eptr, ecode, offset_top, md, eptrb, RM47); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; - if (ctype == OP_ANYNL && eptr > pp && *eptr == CHAR_LF && - eptr[-1] == CHAR_CR) eptr--; + if (ctype == OP_ANYNL && eptr > pp && *eptr == '\n' && + eptr[-1] == '\r') eptr--; } } @@ -6111,11 +6217,14 @@ switch (frame->Xwhere) LBL(32) LBL(34) LBL(42) LBL(46) #ifdef SUPPORT_UCP LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45) - LBL(59) LBL(60) LBL(61) LBL(62) LBL(67) + LBL(59) LBL(60) LBL(61) LBL(62) #endif /* SUPPORT_UCP */ #endif /* SUPPORT_UTF */ default: DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere)); + +printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere); + return PCRE_ERROR_INTERNAL; } #undef LBL @@ -6227,21 +6336,16 @@ Returns: > 0 => success; value is the number of elements filled in < -1 => some kind of unexpected problem */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_exec(const pcre *argument_re, const pcre_extra *extra_data, PCRE_SPTR subject, int length, int start_offset, int options, int *offsets, int offsetcount) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets, int offsetcount) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_exec(const pcre32 *argument_re, const pcre32_extra *extra_data, - PCRE_SPTR32 subject, int length, int start_offset, int options, int *offsets, - int offsetcount) #endif { int rc, ocount, arg_offset_max; @@ -6295,7 +6399,6 @@ if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; -if (length < 0) return PCRE_ERROR_BADLENGTH; if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET; /* Check that the first field in the block is the magic number. If it is not, @@ -6333,22 +6436,19 @@ if (utf && (options & PCRE_NO_UTF8_CHECK) == 0) offsets[0] = erroroffset; offsets[1] = errorcode; } -#if defined COMPILE_PCRE8 - return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)? - PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; -#elif defined COMPILE_PCRE16 +#ifdef COMPILE_PCRE16 return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)? PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16; -#elif defined COMPILE_PCRE32 - return PCRE_ERROR_BADUTF32; +#else + return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)? + PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8; #endif } -#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 + /* Check that a start_offset points to the start of a UTF character. */ if (start_offset > 0 && start_offset < length && NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset])) return PCRE_ERROR_BADUTF8_OFFSET; -#endif } #endif @@ -6362,15 +6462,17 @@ if (extra_data != NULL && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT | PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT && extra_data->executable_jit != NULL - && (options & ~PUBLIC_JIT_EXEC_OPTIONS) == 0) + && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL | + PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART | + PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0) { - rc = PRIV(jit_exec)(extra_data, (const pcre_uchar *)subject, length, + rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length, start_offset, options, offsets, offsetcount); /* PCRE_ERROR_NULL means that the selected normal or partial matching mode is not compiled. In this case we simply fallback to interpreter. */ - if (rc != PCRE_ERROR_JIT_BADOPTION) return rc; + if (rc != PCRE_ERROR_NULL) return rc; } #endif @@ -6654,14 +6756,12 @@ for(;;) if (has_first_char) { - pcre_uchar smc; - if (first_char != first_char2) while (start_match < end_subject && - (smc = RAWUCHARTEST(start_match)) != first_char && smc != first_char2) + *start_match != first_char && *start_match != first_char2) start_match++; else - while (start_match < end_subject && RAWUCHARTEST(start_match) != first_char) + while (start_match < end_subject && *start_match != first_char) start_match++; } @@ -6693,7 +6793,7 @@ for(;;) if (start_match[-1] == CHAR_CR && (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) && start_match < end_subject && - RAWUCHARTEST(start_match) == CHAR_NL) + *start_match == CHAR_NL) start_match++; } } @@ -6704,7 +6804,7 @@ for(;;) { while (start_match < end_subject) { - register pcre_uint32 c = RAWUCHARTEST(start_match); + register unsigned int c = *start_match; #ifndef COMPILE_PCRE8 if (c > 255) c = 255; #endif @@ -6772,7 +6872,7 @@ for(;;) { while (p < end_subject) { - register pcre_uint32 pp = RAWUCHARINCTEST(p); + register int pp = *p++; if (pp == req_char || pp == req_char2) { p--; break; } } } @@ -6780,7 +6880,7 @@ for(;;) { while (p < end_subject) { - if (RAWUCHARINCTEST(p) == req_char) { p--; break; } + if (*p++ == req_char) { p--; break; } } } diff --git a/harbour/src/3rd/pcre/pcrefinf.c b/harbour/src/3rd/pcre/pcrefinf.c index 519102fe64..0f0beba1d1 100644 --- a/harbour/src/3rd/pcre/pcrefinf.c +++ b/harbour/src/3rd/pcre/pcrefinf.c @@ -65,18 +65,14 @@ Arguments: Returns: 0 if data returned, negative on error */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what, void *where) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_fullinfo(const pcre16 *argument_re, const pcre16_extra *extra_data, int what, void *where) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_fullinfo(const pcre32 *argument_re, const pcre32_extra *extra_data, - int what, void *where) #endif { const REAL_PCRE *re = (const REAL_PCRE *)argument_re; @@ -136,21 +132,10 @@ switch (what) case PCRE_INFO_FIRSTBYTE: *((int *)where) = - ((re->flags & PCRE_FIRSTSET) != 0)? (int)re->first_char : + ((re->flags & PCRE_FIRSTSET) != 0)? re->first_char : ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2; break; - case PCRE_INFO_FIRSTCHARACTER: - *((pcre_uint32 *)where) = - (re->flags & PCRE_FIRSTSET) != 0 ? re->first_char : 0; - break; - - case PCRE_INFO_FIRSTCHARACTERFLAGS: - *((int *)where) = - ((re->flags & PCRE_FIRSTSET) != 0) ? 1 : - ((re->flags & PCRE_STARTLINE) != 0) ? 2 : 0; - break; - /* Make sure we pass back the pointer to the bit vector in the external block, not the internal copy (with flipped integer fields). */ @@ -174,19 +159,9 @@ switch (what) case PCRE_INFO_LASTLITERAL: *((int *)where) = - ((re->flags & PCRE_REQCHSET) != 0)? (int)re->req_char : -1; + ((re->flags & PCRE_REQCHSET) != 0)? re->req_char : -1; break; - case PCRE_INFO_REQUIREDCHAR: - *((pcre_uint32 *)where) = - ((re->flags & PCRE_REQCHSET) != 0) ? re->req_char : 0; - break; - - case PCRE_INFO_REQUIREDCHARFLAGS: - *((int *)where) = - ((re->flags & PCRE_REQCHSET) != 0); - break; - case PCRE_INFO_NAMEENTRYSIZE: *((int *)where) = re->name_entry_size; break; diff --git a/harbour/src/3rd/pcre/pcreget.c b/harbour/src/3rd/pcre/pcreget.c index 8e2c82c0dd..07617fe53f 100644 --- a/harbour/src/3rd/pcre/pcreget.c +++ b/harbour/src/3rd/pcre/pcreget.c @@ -65,15 +65,12 @@ Returns: the number of the named parentheses, or a negative number (PCRE_ERROR_NOSUBSTRING) if not found */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_stringnumber(const pcre *code, const char *stringname) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_get_stringnumber(const pcre16 *code, PCRE_SPTR16 stringname) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_get_stringnumber(const pcre32 *code, PCRE_SPTR32 stringname) #endif { int rc; @@ -101,16 +98,6 @@ if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0 if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) return rc; #endif -#ifdef COMPILE_PCRE32 -if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) - return rc; -if (top <= 0) return PCRE_ERROR_NOSUBSTRING; - -if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) - return rc; -if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) - return rc; -#endif bot = 0; while (top > bot) @@ -145,18 +132,14 @@ Returns: the length of each entry, or a negative number (PCRE_ERROR_NOSUBSTRING) if not found */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_stringtable_entries(const pcre *code, const char *stringname, char **firstptr, char **lastptr) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname, PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_get_stringtable_entries(const pcre32 *code, PCRE_SPTR32 stringname, - PCRE_UCHAR32 **firstptr, PCRE_UCHAR32 **lastptr) #endif { int rc; @@ -184,16 +167,6 @@ if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0 if ((rc = pcre16_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) return rc; #endif -#ifdef COMPILE_PCRE32 -if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) - return rc; -if (top <= 0) return PCRE_ERROR_NOSUBSTRING; - -if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) - return rc; -if ((rc = pcre32_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) - return rc; -#endif lastentry = nametable + entrysize * (top - 1); bot = 0; @@ -219,15 +192,12 @@ while (top > bot) (pcre_uchar *)(last + entrysize + IMM2_SIZE)) != 0) break; last += entrysize; } -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 *firstptr = (char *)first; *lastptr = (char *)last; -#elif defined COMPILE_PCRE16 +#else *firstptr = (PCRE_UCHAR16 *)first; *lastptr = (PCRE_UCHAR16 *)last; -#elif defined COMPILE_PCRE32 - *firstptr = (PCRE_UCHAR32 *)first; - *lastptr = (PCRE_UCHAR32 *)last; #endif return entrysize; } @@ -256,40 +226,31 @@ Returns: the number of the first that is set, or a negative number on error */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 static int get_first_set(const pcre *code, const char *stringname, int *ovector) -#elif defined COMPILE_PCRE16 +#else static int get_first_set(const pcre16 *code, PCRE_SPTR16 stringname, int *ovector) -#elif defined COMPILE_PCRE32 -static int -get_first_set(const pcre32 *code, PCRE_SPTR32 stringname, int *ovector) #endif { const REAL_PCRE *re = (const REAL_PCRE *)code; int entrysize; pcre_uchar *entry; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 char *first, *last; -#elif defined COMPILE_PCRE16 +#else PCRE_UCHAR16 *first, *last; -#elif defined COMPILE_PCRE32 -PCRE_UCHAR32 *first, *last; #endif -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0) return pcre_get_stringnumber(code, stringname); entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last); -#elif defined COMPILE_PCRE16 +#else if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0) return pcre16_get_stringnumber(code, stringname); entrysize = pcre16_get_stringtable_entries(code, stringname, &first, &last); -#elif defined COMPILE_PCRE32 -if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0) - return pcre32_get_stringnumber(code, stringname); -entrysize = pcre32_get_stringtable_entries(code, stringname, &first, &last); #endif if (entrysize <= 0) return entrysize; for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize) @@ -330,18 +291,14 @@ Returns: if successful: PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, int stringnumber, PCRE_UCHAR16 *buffer, int size) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_copy_substring(PCRE_SPTR32 subject, int *ovector, int stringcount, - int stringnumber, PCRE_UCHAR32 *buffer, int size) #endif { int yield; @@ -385,31 +342,24 @@ Returns: if successful: PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, char *buffer, int size) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_copy_named_substring(const pcre16 *code, PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 stringname, PCRE_UCHAR16 *buffer, int size) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_copy_named_substring(const pcre32 *code, PCRE_SPTR32 subject, - int *ovector, int stringcount, PCRE_SPTR32 stringname, - PCRE_UCHAR32 *buffer, int size) #endif { int n = get_first_set(code, stringname, ovector); if (n <= 0) return n; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); -#elif defined COMPILE_PCRE16 +#else return pcre16_copy_substring(subject, ovector, stringcount, n, buffer, size); -#elif defined COMPILE_PCRE32 -return pcre32_copy_substring(subject, ovector, stringcount, n, buffer, size); #endif } @@ -436,18 +386,14 @@ Returns: if successful: 0 PCRE_ERROR_NOMEMORY (-6) failed to get store */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_get_substring_list(PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 **listptr) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_get_substring_list(PCRE_SPTR32 subject, int *ovector, int stringcount, - PCRE_SPTR32 **listptr) #endif { int i; @@ -462,12 +408,10 @@ for (i = 0; i < double_count; i += 2) stringlist = (pcre_uchar **)(PUBL(malloc))(size); if (stringlist == NULL) return PCRE_ERROR_NOMEMORY; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 *listptr = (const char **)stringlist; -#elif defined COMPILE_PCRE16 +#else *listptr = (PCRE_SPTR16 *)stringlist; -#elif defined COMPILE_PCRE32 -*listptr = (PCRE_SPTR32 *)stringlist; #endif p = (pcre_uchar *)(stringlist + stringcount + 1); @@ -498,15 +442,12 @@ Argument: the result of a previous pcre_get_substring_list() Returns: nothing */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre_free_substring_list(const char **pointer) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre16_free_substring_list(PCRE_SPTR16 *pointer) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN void PCRE_CALL_CONVENTION -pcre32_free_substring_list(PCRE_SPTR32 *pointer) #endif { (PUBL(free))((void *)pointer); @@ -539,18 +480,14 @@ Returns: if successful: PCRE_ERROR_NOSUBSTRING (-7) substring not present */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_substring(const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_get_substring(PCRE_SPTR16 subject, int *ovector, int stringcount, int stringnumber, PCRE_SPTR16 *stringptr) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_get_substring(PCRE_SPTR32 subject, int *ovector, int stringcount, - int stringnumber, PCRE_SPTR32 *stringptr) #endif { int yield; @@ -563,12 +500,10 @@ substring = (pcre_uchar *)(PUBL(malloc))(IN_UCHARS(yield + 1)); if (substring == NULL) return PCRE_ERROR_NOMEMORY; memcpy(substring, subject + ovector[stringnumber], IN_UCHARS(yield)); substring[yield] = 0; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 *stringptr = (const char *)substring; -#elif defined COMPILE_PCRE16 +#else *stringptr = (PCRE_SPTR16)substring; -#elif defined COMPILE_PCRE32 -*stringptr = (PCRE_SPTR32)substring; #endif return yield; } @@ -602,31 +537,24 @@ Returns: if successful: PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, const char **stringptr) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_get_named_substring(const pcre16 *code, PCRE_SPTR16 subject, int *ovector, int stringcount, PCRE_SPTR16 stringname, PCRE_SPTR16 *stringptr) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_get_named_substring(const pcre32 *code, PCRE_SPTR32 subject, - int *ovector, int stringcount, PCRE_SPTR32 stringname, - PCRE_SPTR32 *stringptr) #endif { int n = get_first_set(code, stringname, ovector); if (n <= 0) return n; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 return pcre_get_substring(subject, ovector, stringcount, n, stringptr); -#elif defined COMPILE_PCRE16 +#else return pcre16_get_substring(subject, ovector, stringcount, n, stringptr); -#elif defined COMPILE_PCRE32 -return pcre32_get_substring(subject, ovector, stringcount, n, stringptr); #endif } @@ -645,15 +573,12 @@ Argument: the result of a previous pcre_get_substring() Returns: nothing */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre_free_substring(const char *pointer) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN void PCRE_CALL_CONVENTION pcre16_free_substring(PCRE_SPTR16 pointer) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN void PCRE_CALL_CONVENTION -pcre32_free_substring(PCRE_SPTR32 pointer) #endif { (PUBL(free))((void *)pointer); diff --git a/harbour/src/3rd/pcre/pcreinal.h b/harbour/src/3rd/pcre/pcreinal.h index f3cb001fea..b8f40ece85 100644 --- a/harbour/src/3rd/pcre/pcreinal.h +++ b/harbour/src/3rd/pcre/pcreinal.h @@ -40,8 +40,8 @@ POSSIBILITY OF SUCH DAMAGE. /* This header contains definitions that are shared between the different modules, but which are not relevant to the exported API. This includes some -functions whose names all begin with "_pcre_", "_pcre16_" or "_pcre32_" -depending on the PRIV macro. */ +functions whose names all begin with "_pcre_" or "_pcre16_" depending on +the PRIV macro. */ #ifndef PCRE_INTERNAL_H #define PCRE_INTERNAL_H @@ -53,8 +53,7 @@ depending on the PRIV macro. */ #endif /* PCRE is compiled as an 8 bit library if it is not requested otherwise. */ - -#if !defined COMPILE_PCRE16 && !defined COMPILE_PCRE32 +#ifndef COMPILE_PCRE16 #define COMPILE_PCRE8 #endif @@ -79,11 +78,11 @@ Until then we define it if SUPPORT_UTF is defined. */ #define SUPPORT_UTF8 1 #endif -/* We do not support both EBCDIC and UTF-8/16/32 at the same time. The "configure" +/* We do not support both EBCDIC and UTF-8/16 at the same time. The "configure" script prevents both being selected, but not everybody uses "configure". */ #if defined EBCDIC && defined SUPPORT_UTF -#error The use of both EBCDIC and SUPPORT_UTF is not supported. +#error The use of both EBCDIC and SUPPORT_UTF8/16 is not supported. #endif /* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef @@ -112,12 +111,6 @@ setjmp and stdarg are used is when NO_RECURSE is set. */ #include #include -/* Valgrind (memcheck) support */ - -#ifdef SUPPORT_VALGRIND -#include -#endif - /* When compiling a DLL for Windows, the exported symbols have to be declared using some MS magic. I found some useful information on this web page: http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the @@ -200,7 +193,7 @@ typedef unsigned char pcre_uint8; typedef unsigned int pcre_uint16; typedef int pcre_int16; #else -# error Cannot determine a type for 16-bit unsigned integers + #error Cannot determine a type for 16-bit unsigned integers #endif #if UINT_MAX == 4294967295 @@ -210,7 +203,7 @@ typedef unsigned char pcre_uint8; typedef unsigned long int pcre_uint32; typedef long int pcre_int32; #else -# error Cannot determine a type for 32-bit unsigned integers + #error Cannot determine a type for 32-bit unsigned integers #endif /* When checking for integer overflow in pcre_compile(), we need to handle @@ -221,9 +214,9 @@ stdint.h is available, include it; it may define INT64_MAX. Systems that do not have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set by "configure". */ -#if defined HAVE_STDINT_H +#if HAVE_STDINT_H #include -#elif defined HAVE_INTTYPES_H +#elif HAVE_INTTYPES_H #include #endif @@ -250,15 +243,16 @@ exactly 256 items. When the character is able to contain more than 256 items, some check is needed before accessing these tables. */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 typedef unsigned char pcre_uchar; #define IN_UCHARS(x) (x) #define MAX_255(c) 1 #define TABLE_GET(c, table, default) ((table)[c]) -#elif defined COMPILE_PCRE16 +#else +#ifdef COMPILE_PCRE16 #if USHRT_MAX != 65535 /* This is a warning message. Change PCRE_UCHAR16 to a 16 bit data type in pcre.h(.in) and disable (comment out) this message. */ @@ -266,22 +260,15 @@ pcre.h(.in) and disable (comment out) this message. */ #endif typedef pcre_uint16 pcre_uchar; -#define UCHAR_SHIFT (1) -#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) -#define MAX_255(c) ((c) <= 255u) -#define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default)) - -#elif defined COMPILE_PCRE32 - -typedef pcre_uint32 pcre_uchar; -#define UCHAR_SHIFT (2) -#define IN_UCHARS(x) ((x) << UCHAR_SHIFT) +#define IN_UCHARS(x) ((x) << 1) #define MAX_255(c) ((c) <= 255u) #define TABLE_GET(c, table, default) (MAX_255(c)? ((table)[c]):(default)) #else #error Unsupported compiling mode -#endif /* COMPILE_PCRE[8|16|32] */ +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ /* This is an unsigned int value that no character can ever have. UTF-8 characters only go up to 0x7fffffff (though Unicode doesn't go beyond @@ -308,8 +295,8 @@ start/end of string field names are. */ &(NLBLOCK->nllen), utf)) \ : \ ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \ - RAWUCHARTEST(p) == NLBLOCK->nl[0] && \ - (NLBLOCK->nllen == 1 || RAWUCHARTEST(p+1) == NLBLOCK->nl[1]) \ + (p)[0] == NLBLOCK->nl[0] && \ + (NLBLOCK->nllen == 1 || (p)[1] == NLBLOCK->nl[1]) \ ) \ ) @@ -322,8 +309,8 @@ start/end of string field names are. */ &(NLBLOCK->nllen), utf)) \ : \ ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \ - RAWUCHARTEST(p - NLBLOCK->nllen) == NLBLOCK->nl[0] && \ - (NLBLOCK->nllen == 1 || RAWUCHARTEST(p - NLBLOCK->nllen + 1) == NLBLOCK->nl[1]) \ + (p)[-NLBLOCK->nllen] == NLBLOCK->nl[0] && \ + (NLBLOCK->nllen == 1 || (p)[-NLBLOCK->nllen+1] == NLBLOCK->nl[1]) \ ) \ ) @@ -348,11 +335,6 @@ values. */ #include "pcre.h" #include "ucp.h" -#ifdef COMPILE_PCRE32 -/* Assert that the public PCRE_UCHAR32 is a 32-bit type */ -typedef int __assert_pcre_uchar32_size[sizeof(PCRE_UCHAR32) == 4 ? 1 : -1]; -#endif - /* When compiling for use with the Virtual Pascal compiler, these functions need to have their names changed. PCRE must be compiled with the -DVPCOMPAT option on the command line. */ @@ -414,7 +396,7 @@ The macros are controlled by the value of LINK_SIZE. This defaults to 2 in the config.h file, but can be overridden by using -D on the command line. This is automated on Unix systems via the "configure" command. */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 #if LINK_SIZE == 2 @@ -459,11 +441,12 @@ is automated on Unix systems via the "configure" command. */ #error LINK_SIZE must be either 2, 3, or 4 #endif -#elif defined COMPILE_PCRE16 +#else /* COMPILE_PCRE8 */ + +#ifdef COMPILE_PCRE16 #if LINK_SIZE == 2 -/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */ #undef LINK_SIZE #define LINK_SIZE 1 @@ -477,7 +460,6 @@ is automated on Unix systems via the "configure" command. */ #elif LINK_SIZE == 3 || LINK_SIZE == 4 -/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */ #undef LINK_SIZE #define LINK_SIZE 2 @@ -495,25 +477,11 @@ is automated on Unix systems via the "configure" command. */ #error LINK_SIZE must be either 2, 3, or 4 #endif -#elif defined COMPILE_PCRE32 - -/* Only supported LINK_SIZE is 4 */ -/* Redefine LINK_SIZE as a multiple of sizeof(pcre_uchar) */ -#undef LINK_SIZE -#define LINK_SIZE 1 - -#define PUT(a,n,d) \ - (a[n] = (d)) - -#define GET(a,n) \ - (a[n]) - -/* Keep it positive */ -#define MAX_PATTERN_SIZE (1 << 30) - #else #error Unsupported compiling mode -#endif /* COMPILE_PCRE[8|16|32] */ +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ /* Convenience macro defined in terms of the others */ @@ -524,7 +492,7 @@ is automated on Unix systems via the "configure" command. */ offsets changes. There are used for repeat counts and for other things such as capturing parenthesis numbers in back references. */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 #define IMM2_SIZE 2 @@ -532,24 +500,12 @@ capturing parenthesis numbers in back references. */ a[n] = (d) >> 8; \ a[(n)+1] = (d) & 255 -/* For reasons that I do not understand, the expression in this GET2 macro is -treated by gcc as a signed expression, even when a is declared as unsigned. It -seems that any kind of arithmetic results in a signed value. */ - #define GET2(a,n) \ - (unsigned int)(((a)[n] << 8) | (a)[(n)+1]) + (((a)[n] << 8) | (a)[(n)+1]) -#elif defined COMPILE_PCRE16 +#else /* COMPILE_PCRE8 */ -#define IMM2_SIZE 1 - -#define PUT2(a,n,d) \ - a[n] = d - -#define GET2(a,n) \ - a[n] - -#elif defined COMPILE_PCRE32 +#ifdef COMPILE_PCRE16 #define IMM2_SIZE 1 @@ -561,25 +517,23 @@ seems that any kind of arithmetic results in a signed value. */ #else #error Unsupported compiling mode -#endif /* COMPILE_PCRE[8|16|32] */ +#endif /* COMPILE_PCRE16 */ + +#endif /* COMPILE_PCRE8 */ #define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE /* The maximum length of a MARK name is currently one data unit; it may be changed in future to be a fixed number of bytes or to depend on LINK_SIZE. */ -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 -#define MAX_MARK ((1u << 16) - 1) -#else -#define MAX_MARK ((1u << 8) - 1) -#endif +#define MAX_MARK ((1 << (sizeof(pcre_uchar)*8)) - 1) /* When UTF encoding is being used, a character is no longer just a single -byte. The macros for character handling generate simple sequences when used in -character-mode, and more complicated ones for UTF characters. GETCHARLENTEST -and other macros are not used when UTF is not supported, so they are not -defined. To make sure they can never even appear when UTF support is omitted, -we don't even define them. */ +character. The macros for character handling generate simple sequences when +used in character-mode, and more complicated ones for UTF characters. +GETCHARLENTEST and other macros are not used when UTF is not supported, +so they are not defined. To make sure they can never even appear when +UTF support is omitted, we don't even define them. */ #ifndef SUPPORT_UTF @@ -592,10 +546,6 @@ we don't even define them. */ #define GETCHARINC(c, eptr) c = *eptr++; #define GETCHARINCTEST(c, eptr) c = *eptr++; #define GETCHARLEN(c, eptr, len) c = *eptr; -#define RAWUCHAR(eptr) (*(eptr)) -#define RAWUCHARINC(eptr) (*(eptr)++) -#define RAWUCHARTEST(eptr) (*(eptr)) -#define RAWUCHARINCTEST(eptr) (*(eptr)++) /* #define GETCHARLENTEST(c, eptr, len) */ /* #define BACKCHAR(eptr) */ /* #define FORWARDCHAR(eptr) */ @@ -603,9 +553,30 @@ we don't even define them. */ #else /* SUPPORT_UTF */ +#ifdef COMPILE_PCRE8 + +/* These macros were originally written in the form of loops that used data +from the tables whose names start with PRIV(utf8_table). They were rewritten by +a user so as not to use loops, because in some environments this gives a +significant performance advantage, and it seems never to do any harm. */ + +/* Tells the biggest code point which can be encoded as a single character. */ + +#define MAX_VALUE_FOR_SINGLE_CHAR 127 + /* Tests whether the code point needs extra characters to decode. */ -#define HASUTF8EXTRALEN(c) ((c) >= 0xc0) +#define HAS_EXTRALEN(c) ((c) >= 0xc0) + +/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. +Otherwise it has an undefined behaviour. */ + +#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f]) + +/* Returns TRUE, if the given character is not the first character +of a UTF sequence. */ + +#define NOT_FIRSTCHAR(c) (((c) & 0xc0) == 0x80) /* Base macro to pick up the remaining bytes of a UTF-8 character, not advancing the pointer. */ @@ -629,6 +600,20 @@ advancing the pointer. */ ((eptr[4] & 0x3f) << 6) | (eptr[5] & 0x3f); \ } +/* Get the next UTF-8 character, not advancing the pointer. This is called when +we know we are in UTF-8 mode. */ + +#define GETCHAR(c, eptr) \ + c = *eptr; \ + if (c >= 0xc0) GETUTF8(c, eptr); + +/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the +pointer. */ + +#define GETCHARTEST(c, eptr) \ + c = *eptr; \ + if (utf && c >= 0xc0) GETUTF8(c, eptr); + /* Base macro to pick up the remaining bytes of a UTF-8 character, advancing the pointer. */ @@ -663,45 +648,6 @@ the pointer. */ } \ } -#if defined COMPILE_PCRE8 - -/* These macros were originally written in the form of loops that used data -from the tables whose names start with PRIV(utf8_table). They were rewritten by -a user so as not to use loops, because in some environments this gives a -significant performance advantage, and it seems never to do any harm. */ - -/* Tells the biggest code point which can be encoded as a single character. */ - -#define MAX_VALUE_FOR_SINGLE_CHAR 127 - -/* Tests whether the code point needs extra characters to decode. */ - -#define HAS_EXTRALEN(c) ((c) >= 0xc0) - -/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE. -Otherwise it has an undefined behaviour. */ - -#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3f]) - -/* Returns TRUE, if the given character is not the first character -of a UTF sequence. */ - -#define NOT_FIRSTCHAR(c) (((c) & 0xc0) == 0x80) - -/* Get the next UTF-8 character, not advancing the pointer. This is called when -we know we are in UTF-8 mode. */ - -#define GETCHAR(c, eptr) \ - c = *eptr; \ - if (c >= 0xc0) GETUTF8(c, eptr); - -/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the -pointer. */ - -#define GETCHARTEST(c, eptr) \ - c = *eptr; \ - if (utf && c >= 0xc0) GETUTF8(c, eptr); - /* Get the next UTF-8 character, advancing the pointer. This is called when we know we are in UTF-8 mode. */ @@ -768,30 +714,6 @@ do not know if we are in UTF-8 mode. */ c = *eptr; \ if (utf && c >= 0xc0) GETUTF8LEN(c, eptr, len); -/* Returns the next uchar, not advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHAR(eptr) \ - (*(eptr)) - -/* Returns the next uchar, advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHARINC(eptr) \ - (*((eptr)++)) - -/* Returns the next uchar, testing for UTF mode, and not advancing the -pointer. */ - -#define RAWUCHARTEST(eptr) \ - (*(eptr)) - -/* Returns the next uchar, testing for UTF mode, advancing the -pointer. */ - -#define RAWUCHARINCTEST(eptr) \ - (*((eptr)++)) - /* If the pointer is not at the start of a character, move it back until it is. This is called only in UTF-8 mode - we don't put a test within the macro because almost all calls are already within a block of UTF-8 only code. */ @@ -805,7 +727,9 @@ because almost all calls are already within a block of UTF-8 only code. */ #define ACROSSCHAR(condition, eptr, action) \ while((condition) && ((eptr) & 0xc0) == 0x80) action -#elif defined COMPILE_PCRE16 +#else /* COMPILE_PCRE8 */ + +#ifdef COMPILE_PCRE16 /* Tells the biggest code point which can be encoded as a single character. */ @@ -887,30 +811,6 @@ we do not know if we are in UTF-16 mode. */ c = *eptr; \ if (utf && (c & 0xfc00) == 0xd800) GETUTF16LEN(c, eptr, len); -/* Returns the next uchar, not advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHAR(eptr) \ - (*(eptr)) - -/* Returns the next uchar, advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHARINC(eptr) \ - (*((eptr)++)) - -/* Returns the next uchar, testing for UTF mode, and not advancing the -pointer. */ - -#define RAWUCHARTEST(eptr) \ - (*(eptr)) - -/* Returns the next uchar, testing for UTF mode, advancing the -pointer. */ - -#define RAWUCHARINCTEST(eptr) \ - (*((eptr)++)) - /* If the pointer is not at the start of a character, move it back until it is. This is called only in UTF-16 mode - we don't put a test within the macro because almost all calls are already within a block of UTF-16 only @@ -925,200 +825,20 @@ code. */ #define ACROSSCHAR(condition, eptr, action) \ if ((condition) && ((eptr) & 0xfc00) == 0xdc00) action -#elif defined COMPILE_PCRE32 +#endif -/* These are trivial for the 32-bit library, since all UTF-32 characters fit -into one pcre_uchar unit. */ -#define MAX_VALUE_FOR_SINGLE_CHAR (0x10ffffu) -#define HAS_EXTRALEN(c) (0) -#define GET_EXTRALEN(c) (0) -#define NOT_FIRSTCHAR(c) (0) - -/* Get the next UTF-32 character, not advancing the pointer. This is called when -we know we are in UTF-32 mode. */ - -#define GETCHAR(c, eptr) \ - c = *(eptr); - -/* Get the next UTF-32 character, testing for UTF-32 mode, and not advancing the -pointer. */ - -#define GETCHARTEST(c, eptr) \ - c = *(eptr); - -/* Get the next UTF-32 character, advancing the pointer. This is called when we -know we are in UTF-32 mode. */ - -#define GETCHARINC(c, eptr) \ - c = *((eptr)++); - -/* Get the next character, testing for UTF-32 mode, and advancing the pointer. -This is called when we don't know if we are in UTF-32 mode. */ - -#define GETCHARINCTEST(c, eptr) \ - c = *((eptr)++); - -/* Get the next UTF-32 character, not advancing the pointer, not incrementing -length (since all UTF-32 is of length 1). This is called when we know we are in -UTF-32 mode. */ - -#define GETCHARLEN(c, eptr, len) \ - GETCHAR(c, eptr) - -/* Get the next UTF-32character, testing for UTF-32 mode, not advancing the -pointer, not incrementing the length (since all UTF-32 is of length 1). -This is called when we do not know if we are in UTF-32 mode. */ - -#define GETCHARLENTEST(c, eptr, len) \ - GETCHARTEST(c, eptr) - -/* Returns the next uchar, not advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHAR(eptr) \ - (*(eptr)) - -/* Returns the next uchar, advancing the pointer. This is called when -we know we are in UTF mode. */ - -#define RAWUCHARINC(eptr) \ - (*((eptr)++)) - -/* Returns the next uchar, testing for UTF mode, and not advancing the -pointer. */ - -#define RAWUCHARTEST(eptr) \ - (*(eptr)) - -/* Returns the next uchar, testing for UTF mode, advancing the -pointer. */ - -#define RAWUCHARINCTEST(eptr) \ - (*((eptr)++)) - -/* If the pointer is not at the start of a character, move it back until -it is. This is called only in UTF-32 mode - we don't put a test within the -macro because almost all calls are already within a block of UTF-32 only -code. -These are all no-ops since all UTF-32 characters fit into one pcre_uchar. */ - -#define BACKCHAR(eptr) do { } while (0) - -/* Same as above, just in the other direction. */ -#define FORWARDCHAR(eptr) do { } while (0) - -/* Same as above, but it allows a fully customizable form. */ -#define ACROSSCHAR(condition, eptr, action) do { } while (0) - -#else -#error Unsupported compiling mode -#endif /* COMPILE_PCRE[8|16|32] */ +#endif /* COMPILE_PCRE8 */ #endif /* SUPPORT_UTF */ -/* Tests for Unicode horizontal and vertical whitespace characters must check a -number of different values. Using a switch statement for this generates the -fastest code (no loop, no memory access), and there are several places in the -interpreter code where this happens. In order to ensure that all the case lists -remain in step, we use macros so that there is only one place where the lists -are defined. -These values are also required as lists in pcre_compile.c when processing \h, -\H, \v and \V in a character class. The lists are defined in pcre_tables.c, but -macros that define the values are here so that all the definitions are -together. The lists must be in ascending character order, terminated by -NOTACHAR (which is 0xffffffff). +/* In case there is no definition of offsetof() provided - though any proper +Standard C system should have one. */ -Any changes should ensure that the various macros are kept in step with each -other. NOTE: The values also appear in pcre_jit_compile.c. */ - -/* ------ ASCII/Unicode environments ------ */ - -#ifndef EBCDIC - -#define HSPACE_LIST \ - CHAR_HT, CHAR_SPACE, 0xa0, \ - 0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \ - 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \ - NOTACHAR - -#define HSPACE_MULTIBYTE_CASES \ - case 0x1680: /* OGHAM SPACE MARK */ \ - case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */ \ - case 0x2000: /* EN QUAD */ \ - case 0x2001: /* EM QUAD */ \ - case 0x2002: /* EN SPACE */ \ - case 0x2003: /* EM SPACE */ \ - case 0x2004: /* THREE-PER-EM SPACE */ \ - case 0x2005: /* FOUR-PER-EM SPACE */ \ - case 0x2006: /* SIX-PER-EM SPACE */ \ - case 0x2007: /* FIGURE SPACE */ \ - case 0x2008: /* PUNCTUATION SPACE */ \ - case 0x2009: /* THIN SPACE */ \ - case 0x200A: /* HAIR SPACE */ \ - case 0x202f: /* NARROW NO-BREAK SPACE */ \ - case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ \ - case 0x3000 /* IDEOGRAPHIC SPACE */ - -#define HSPACE_BYTE_CASES \ - case CHAR_HT: \ - case CHAR_SPACE: \ - case 0xa0 /* NBSP */ - -#define HSPACE_CASES \ - HSPACE_BYTE_CASES: \ - HSPACE_MULTIBYTE_CASES - -#define VSPACE_LIST \ - CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, 0x2028, 0x2029, NOTACHAR - -#define VSPACE_MULTIBYTE_CASES \ - case 0x2028: /* LINE SEPARATOR */ \ - case 0x2029 /* PARAGRAPH SEPARATOR */ - -#define VSPACE_BYTE_CASES \ - case CHAR_LF: \ - case CHAR_VT: \ - case CHAR_FF: \ - case CHAR_CR: \ - case CHAR_NEL - -#define VSPACE_CASES \ - VSPACE_BYTE_CASES: \ - VSPACE_MULTIBYTE_CASES - -/* ------ EBCDIC environments ------ */ - -#else -#define HSPACE_LIST CHAR_HT, CHAR_SPACE - -#define HSPACE_BYTE_CASES \ - case CHAR_HT: \ - case CHAR_SPACE - -#define HSPACE_CASES HSPACE_BYTE_CASES - -#ifdef EBCDIC_NL25 -#define VSPACE_LIST \ - CHAR_VT, CHAR_FF, CHAR_CR, CHAR_NEL, CHAR_LF, NOTACHAR -#else -#define VSPACE_LIST \ - CHAR_VT, CHAR_FF, CHAR_CR, CHAR_LF, CHAR_NEL, NOTACHAR +#ifndef offsetof +#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field)) #endif -#define VSPACE_BYTE_CASES \ - case CHAR_LF: \ - case CHAR_VT: \ - case CHAR_FF: \ - case CHAR_CR: \ - case CHAR_NEL - -#define VSPACE_CASES VSPACE_BYTE_CASES -#endif /* EBCDIC */ - -/* ------ End of whitespace macros ------ */ - - /* Private flags containing information about the compiled regex. They used to live at the top end of the options word, but that got almost full, so now they @@ -1126,9 +846,12 @@ are in a 16-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as the restrictions on partial matching have been lifted. It remains for backwards compatibility. */ -#define PCRE_MODE8 0x0001 /* compiled in 8 bit mode */ -#define PCRE_MODE16 0x0002 /* compiled in 16 bit mode */ -#define PCRE_MODE32 0x0004 /* compiled in 32 bit mode */ +#ifdef COMPILE_PCRE8 +#define PCRE_MODE 0x0001 /* compiled in 8 bit mode */ +#endif +#ifdef COMPILE_PCRE16 +#define PCRE_MODE 0x0002 /* compiled in 16 bit mode */ +#endif #define PCRE_FIRSTSET 0x0010 /* first_char is set */ #define PCRE_FCH_CASELESS 0x0020 /* caseless first char */ #define PCRE_REQCHSET 0x0040 /* req_byte is set */ @@ -1139,15 +862,6 @@ compatibility. */ #define PCRE_HASCRORLF 0x0800 /* explicit \r or \n in pattern */ #define PCRE_HASTHEN 0x1000 /* pattern contains (*THEN) */ -#if defined COMPILE_PCRE8 -#define PCRE_MODE PCRE_MODE8 -#elif defined COMPILE_PCRE16 -#define PCRE_MODE PCRE_MODE16 -#elif defined COMPILE_PCRE32 -#define PCRE_MODE PCRE_MODE32 -#endif -#define PCRE_MODE_MASK (PCRE_MODE8 | PCRE_MODE16 | PCRE_MODE32) - /* Flags for the "extra" block produced by pcre_study(). */ #define PCRE_STUDY_MAPPED 0x0001 /* a map of starting chars exists */ @@ -1179,11 +893,7 @@ time, run time, or study time, respectively. */ #define PUBLIC_STUDY_OPTIONS \ (PCRE_STUDY_JIT_COMPILE|PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE| \ - PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE|PCRE_STUDY_EXTRA_NEEDED) - -#define PUBLIC_JIT_EXEC_OPTIONS \ - (PCRE_NO_UTF8_CHECK|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|\ - PCRE_NOTEMPTY_ATSTART|PCRE_PARTIAL_SOFT|PCRE_PARTIAL_HARD) + PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) /* Magic number to provide a small check against being handed junk. */ @@ -1194,6 +904,11 @@ in different endianness. */ #define REVERSED_MAGIC_NUMBER 0x45524350UL /* 'ERCP' */ +/* Negative values for the firstchar and reqchar variables */ + +#define REQ_UNSET (-2) +#define REQ_NONE (-1) + /* The maximum remaining length of subject we are prepared to search for a req_byte match. */ @@ -1230,71 +945,22 @@ macros to give the functions distinct names. */ #ifndef SUPPORT_UTF /* UTF-8 support is not enabled; use the platform-dependent character literals -so that PCRE works in both ASCII and EBCDIC environments, but only in non-UTF -mode. Newline characters are problematic in EBCDIC. Though it has CR and LF -characters, a common practice has been to use its NL (0x15) character as the -line terminator in C-like processing environments. However, sometimes the LF -(0x25) character is used instead, according to this Unicode document: +so that PCRE works on both ASCII and EBCDIC platforms, in non-UTF-mode only. */ -http://unicode.org/standard/reports/tr13/tr13-5.html - -PCRE defaults EBCDIC NL to 0x15, but has a build-time option to select 0x25 -instead. Whichever is *not* chosen is defined as NEL. - -In both ASCII and EBCDIC environments, CHAR_NL and CHAR_LF are synonyms for the -same code point. */ - -#ifdef EBCDIC - -#ifndef EBCDIC_NL25 -#define CHAR_NL '\x15' -#define CHAR_NEL '\x25' -#define STR_NL "\x15" -#define STR_NEL "\x25" -#else -#define CHAR_NL '\x25' -#define CHAR_NEL '\x15' -#define STR_NL "\x25" -#define STR_NEL "\x15" -#endif - -#define CHAR_LF CHAR_NL -#define STR_LF STR_NL - -#define CHAR_ESC '\047' -#define CHAR_DEL '\007' -#define STR_ESC "\047" -#define STR_DEL "\007" - -#else /* Not EBCDIC */ - -/* In ASCII/Unicode, linefeed is '\n' and we equate this to NL for -compatibility. NEL is the Unicode newline character; make sure it is -a positive value. */ - -#define CHAR_LF '\n' -#define CHAR_NL CHAR_LF -#define CHAR_NEL ((unsigned char)'\x85') -#define CHAR_ESC '\033' -#define CHAR_DEL '\177' - -#define STR_LF "\n" -#define STR_NL STR_LF -#define STR_NEL "\x85" -#define STR_ESC "\033" -#define STR_DEL "\177" - -#endif /* EBCDIC */ - -/* The remaining definitions work in both environments. */ - -#define CHAR_NULL '\0' #define CHAR_HT '\t' #define CHAR_VT '\v' #define CHAR_FF '\f' #define CHAR_CR '\r' +#define CHAR_NL '\n' #define CHAR_BS '\b' #define CHAR_BEL '\a' +#ifdef EBCDIC +#define CHAR_ESC '\047' +#define CHAR_DEL '\007' +#else +#define CHAR_ESC '\033' +#define CHAR_DEL '\177' +#endif #define CHAR_SPACE ' ' #define CHAR_EXCLAMATION_MARK '!' @@ -1396,8 +1062,16 @@ a positive value. */ #define STR_VT "\v" #define STR_FF "\f" #define STR_CR "\r" +#define STR_NL "\n" #define STR_BS "\b" #define STR_BEL "\a" +#ifdef EBCDIC +#define STR_ESC "\047" +#define STR_DEL "\007" +#else +#define STR_ESC "\033" +#define STR_DEL "\177" +#endif #define STR_SPACE " " #define STR_EXCLAMATION_MARK "!" @@ -1528,10 +1202,12 @@ a positive value. */ #define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)" #define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)" #define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)" -#define STRING_UTF8_RIGHTPAR "UTF8)" -#define STRING_UTF16_RIGHTPAR "UTF16)" -#define STRING_UTF32_RIGHTPAR "UTF32)" -#define STRING_UTF_RIGHTPAR "UTF)" +#ifdef COMPILE_PCRE8 +#define STRING_UTF_RIGHTPAR "UTF8)" +#endif +#ifdef COMPILE_PCRE16 +#define STRING_UTF_RIGHTPAR "UTF16)" +#endif #define STRING_UCP_RIGHTPAR "UCP)" #define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)" @@ -1545,15 +1221,12 @@ only. */ #define CHAR_VT '\013' #define CHAR_FF '\014' #define CHAR_CR '\015' -#define CHAR_LF '\012' -#define CHAR_NL CHAR_LF -#define CHAR_NEL ((unsigned char)'\x85') +#define CHAR_NL '\012' #define CHAR_BS '\010' #define CHAR_BEL '\007' #define CHAR_ESC '\033' #define CHAR_DEL '\177' -#define CHAR_NULL '\0' #define CHAR_SPACE '\040' #define CHAR_EXCLAMATION_MARK '\041' #define CHAR_QUOTATION_MARK '\042' @@ -1789,10 +1462,12 @@ only. */ #define STRING_ANYCRLF_RIGHTPAR STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS #define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS #define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS -#define STRING_UTF8_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS -#define STRING_UTF16_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS -#define STRING_UTF32_RIGHTPAR STR_U STR_T STR_F STR_3 STR_2 STR_RIGHT_PARENTHESIS -#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_RIGHT_PARENTHESIS +#ifdef COMPILE_PCRE8 +#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS +#endif +#ifdef COMPILE_PCRE16 +#define STRING_UTF_RIGHTPAR STR_U STR_T STR_F STR_1 STR_6 STR_RIGHT_PARENTHESIS +#endif #define STRING_UCP_RIGHTPAR STR_U STR_C STR_P STR_RIGHT_PARENTHESIS #define STRING_NO_START_OPT_RIGHTPAR STR_N STR_O STR_UNDERSCORE STR_S STR_T STR_A STR_R STR_T STR_UNDERSCORE STR_O STR_P STR_T STR_RIGHT_PARENTHESIS @@ -1809,7 +1484,7 @@ only. */ #endif #ifndef ESC_n -#define ESC_n CHAR_LF +#define ESC_n CHAR_NL #endif #ifndef ESC_r @@ -1834,7 +1509,6 @@ only. */ #define PT_SPACE 6 /* Perl space - Z plus 9,10,12,13 */ #define PT_PXSPACE 7 /* POSIX space - Z plus 9,10,11,12,13 */ #define PT_WORD 8 /* Word - L plus N plus underscore */ -#define PT_CLIST 9 /* Pseudo-property: match character list */ /* Flag bits and data types for the extended class (OP_XCLASS) for classes that contain characters with values greater than 255. */ @@ -1850,19 +1524,19 @@ contain characters with values greater than 255. */ /* These are escaped items that aren't just an encoding of a particular data value such as \n. They must have non-zero values, as check_escape() returns -0 for a data character. Also, they must appear in the same order as in the opcode +their negation. Also, they must appear in the same order as in the opcode definitions below, up to ESC_z. There's a dummy for OP_ALLANY because it corresponds to "." in DOTALL mode rather than an escape sequence. It is also used for [^] in JavaScript compatibility mode, and for \C in non-utf mode. In non-DOTALL mode, "." behaves like \N. The special values ESC_DU, ESC_du, etc. are used instead of ESC_D, ESC_d, etc. -when PCRE_UCP is set and replacement of \d etc by \p sequences is required. +when PCRE_UCP is set, when replacement of \d etc by \p sequences is required. They must be contiguous, and remain in order so that the replacements can be looked up from a table. -Negative numbers are used to encode a backreference (\1, \2, \3, etc.) in -check_escape(). There are two tests in the code for an escape +The final escape must be ESC_REF as subsequent values are used for +backreferences (\1, \2, \3, etc). There are two tests in the code for an escape greater than ESC_b and less than ESC_Z to detect the types that may be repeated. These are the types that consume characters. If any new escapes are put in between that don't consume a character, that code will have to change. @@ -1872,7 +1546,8 @@ enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W, ESC_w, ESC_N, ESC_dum, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H, ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_g, ESC_k, - ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu }; + ESC_DU, ESC_du, ESC_SU, ESC_su, ESC_WU, ESC_wu, + ESC_REF }; /* Opcode table: Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in order to the list of escapes immediately above. @@ -1898,7 +1573,7 @@ enum { OP_NOT_WORDCHAR, /* 10 \W */ OP_WORDCHAR, /* 11 \w */ - OP_ANY, /* 12 Match any character except newline (\N) */ + OP_ANY, /* 12 Match any character except newline */ OP_ALLANY, /* 13 Match any character */ OP_ANYBYTE, /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */ OP_NOTPROP, /* 15 \P (not Unicode property) */ @@ -1909,8 +1584,8 @@ enum { OP_NOT_VSPACE, /* 20 \V (not vertical whitespace) */ OP_VSPACE, /* 21 \v (vertical whitespace) */ OP_EXTUNI, /* 22 \X (extended Unicode sequence */ - OP_EODN, /* 23 End of data or \n at end of data (\Z) */ - OP_EOD, /* 24 End of data (\z) */ + OP_EODN, /* 23 End of data or \n at end of data: \Z. */ + OP_EOD, /* 24 End of data: \z */ OP_CIRC, /* 25 Start of line - not multiline */ OP_CIRCM, /* 26 Start of line - multiline */ @@ -2270,7 +1945,7 @@ enum { ERR0, ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, - ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERRCOUNT }; + ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERRCOUNT }; /* JIT compiling modes. The function list is indexed by them. */ enum { JIT_COMPILE, JIT_PARTIAL_SOFT_COMPILE, JIT_PARTIAL_HARD_COMPILE, @@ -2293,20 +1968,13 @@ fields are present. Currently PCRE always sets the dummy fields to zero. NOTE NOTE NOTE */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 #define REAL_PCRE real_pcre -#elif defined COMPILE_PCRE16 +#else #define REAL_PCRE real_pcre16 -#elif defined COMPILE_PCRE32 -#define REAL_PCRE real_pcre32 #endif -/* It is necessary to fork the struct for 32 bit, since it needs to use - * pcre_uchar for first_char and req_char. Can't put an ifdef inside the - * typedef since pcretest needs access to the struct of the 8-, 16- - * and 32-bit variants. */ - -typedef struct real_pcre8_or_16 { +typedef struct REAL_PCRE { pcre_uint32 magic_number; pcre_uint32 size; /* Total that was malloced */ pcre_uint32 options; /* Public options */ @@ -2322,42 +1990,7 @@ typedef struct real_pcre8_or_16 { pcre_uint16 ref_count; /* Reference count */ const pcre_uint8 *tables; /* Pointer to tables or NULL for std */ const pcre_uint8 *nullpad; /* NULL padding */ -} real_pcre8_or_16; - -typedef struct real_pcre8_or_16 real_pcre; -typedef struct real_pcre8_or_16 real_pcre16; - -typedef struct real_pcre32 { - pcre_uint32 magic_number; - pcre_uint32 size; /* Total that was malloced */ - pcre_uint32 options; /* Public options */ - pcre_uint16 flags; /* Private flags */ - pcre_uint16 max_lookbehind; /* Longest lookbehind (characters) */ - pcre_uint16 top_bracket; /* Highest numbered group */ - pcre_uint16 top_backref; /* Highest numbered back reference */ - pcre_uint32 first_char; /* Starting character */ - pcre_uint32 req_char; /* This character must be seen */ - pcre_uint16 name_table_offset; /* Offset to name table that follows */ - pcre_uint16 name_entry_size; /* Size of any name items */ - pcre_uint16 name_count; /* Number of name items */ - pcre_uint16 ref_count; /* Reference count */ - pcre_uint16 dummy1; /* for later expansion */ - pcre_uint16 dummy2; /* for later expansion */ - const pcre_uint8 *tables; /* Pointer to tables or NULL for std */ - void *nullpad; /* for later expansion */ -} real_pcre32; - -/* Assert that the size of REAL_PCRE is divisible by 8 */ -typedef int __assert_real_pcre_size_divisible_8[(sizeof(REAL_PCRE) % 8) == 0 ? 1 : -1]; - -/* Needed in pcretest to access some fields in the real_pcre* structures - * directly. They're unified for 8/16/32 bits since the structs only differ - * after these fields; if that ever changes, need to fork those defines into - * 8/16 and 32 bit versions. */ -#define REAL_PCRE_MAGIC(re) (((REAL_PCRE*)re)->magic_number) -#define REAL_PCRE_SIZE(re) (((REAL_PCRE*)re)->size) -#define REAL_PCRE_OPTIONS(re) (((REAL_PCRE*)re)->options) -#define REAL_PCRE_FLAGS(re) (((REAL_PCRE*)re)->flags) +} REAL_PCRE; /* The format of the block used to store data from pcre_study(). The same remark (see NOTE above) about extending this structure applies. */ @@ -2398,7 +2031,7 @@ typedef struct compile_data { int names_found; /* Number of entries so far */ int name_entry_size; /* Size of each entry */ int workspace_size; /* Size of workspace */ - unsigned int bracount; /* Count of capturing parens as we compile */ + int bracount; /* Count of capturing parens as we compile */ int final_bracount; /* Saved value after first pass */ int max_lookbehind; /* Maximum lookbehind (characters) */ int top_backref; /* Maximum back reference */ @@ -2408,7 +2041,6 @@ typedef struct compile_data { int external_flags; /* External flag bits to be set */ int req_varyopt; /* "After variable item" flag for reqbyte */ BOOL had_accept; /* (*ACCEPT) encountered */ - BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ BOOL check_lookbehind; /* Lookbehinds need later checking */ int nltype; /* Newline type */ int nllen; /* Newline string length */ @@ -2428,7 +2060,7 @@ call within the pattern; used by pcre_exec(). */ typedef struct recursion_info { struct recursion_info *prevrec; /* Previous recursion record (or NULL) */ - unsigned int group_num; /* Number of group that was called */ + int group_num; /* Number of group that was called */ int *offset_save; /* Pointer to start of saved offsets */ int saved_max; /* Number of saved offsets */ PCRE_PUCHAR subject_position; /* Position at start of recursion */ @@ -2562,30 +2194,25 @@ total length. */ /* Internal function and data prefixes. */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 #ifndef PUBL #define PUBL(name) pcre_##name #endif #ifndef PRIV #define PRIV(name) _pcre_##name #endif -#elif defined COMPILE_PCRE16 +#else /* COMPILE_PCRE8 */ +#ifdef COMPILE_PCRE16 #ifndef PUBL #define PUBL(name) pcre16_##name #endif #ifndef PRIV #define PRIV(name) _pcre16_##name #endif -#elif defined COMPILE_PCRE32 -#ifndef PUBL -#define PUBL(name) pcre32_##name -#endif -#ifndef PRIV -#define PRIV(name) _pcre32_##name -#endif #else #error Unsupported compiling mode -#endif /* COMPILE_PCRE[8|16|32] */ +#endif /* COMPILE_PCRE16 */ +#endif /* COMPILE_PCRE8 */ /* Layout of the UCP type table that translates property names into types and codes. Each entry used to point directly to a name, but to reduce the number of @@ -2605,22 +2232,22 @@ but are not part of the PCRE public API. The data for these tables is in the pcre_tables.c module. */ #ifdef COMPILE_PCRE8 + extern const int PRIV(utf8_table1)[]; extern const int PRIV(utf8_table1_size); extern const int PRIV(utf8_table2)[]; extern const int PRIV(utf8_table3)[]; extern const pcre_uint8 PRIV(utf8_table4)[]; + #endif /* COMPILE_PCRE8 */ extern const char PRIV(utt_names)[]; extern const ucp_type_table PRIV(utt)[]; extern const int PRIV(utt_size); -extern const pcre_uint8 PRIV(OP_lengths)[]; extern const pcre_uint8 PRIV(default_tables)[]; -extern const pcre_uint32 PRIV(hspace_list)[]; -extern const pcre_uint32 PRIV(vspace_list)[]; +extern const pcre_uint8 PRIV(OP_lengths)[]; /* Internal shared functions. These are functions that are used by more than @@ -2628,7 +2255,7 @@ one of the exported public functions. They have to be "external" in the C sense, but are not part of the PCRE public API. */ /* String comparison functions. */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 #define STRCMP_UC_UC(str1, str2) \ strcmp((char *)(str1), (char *)(str2)) @@ -2640,7 +2267,7 @@ sense, but are not part of the PCRE public API. */ strncmp((char *)(str1), (str2), (num)) #define STRLEN_UC(str) strlen((const char *)str) -#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#else extern int PRIV(strcmp_uc_uc)(const pcre_uchar *, const pcre_uchar *); @@ -2662,40 +2289,21 @@ extern unsigned int PRIV(strlen_uc)(const pcre_uchar *str); PRIV(strncmp_uc_c8)((str1), (str2), (num)) #define STRLEN_UC(str) PRIV(strlen_uc)(str) -#endif /* COMPILE_PCRE[8|16|32] */ - -#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 - -#define STRCMP_UC_UC_TEST(str1, str2) STRCMP_UC_UC(str1, str2) -#define STRCMP_UC_C8_TEST(str1, str2) STRCMP_UC_C8(str1, str2) - -#elif defined COMPILE_PCRE32 - -extern int PRIV(strcmp_uc_uc_utf)(const pcre_uchar *, - const pcre_uchar *); -extern int PRIV(strcmp_uc_c8_utf)(const pcre_uchar *, - const char *); - -#define STRCMP_UC_UC_TEST(str1, str2) \ - (utf ? PRIV(strcmp_uc_uc_utf)((str1), (str2)) : PRIV(strcmp_uc_uc)((str1), (str2))) -#define STRCMP_UC_C8_TEST(str1, str2) \ - (utf ? PRIV(strcmp_uc_c8_utf)((str1), (str2)) : PRIV(strcmp_uc_c8)((str1), (str2))) - -#endif /* COMPILE_PCRE[8|16|32] */ +#endif /* COMPILE_PCRE8 */ extern const pcre_uchar *PRIV(find_bracket)(const pcre_uchar *, BOOL, int); extern BOOL PRIV(is_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR, int *, BOOL); -extern unsigned int PRIV(ord2utf)(pcre_uint32, pcre_uchar *); +extern int PRIV(ord2utf)(pcre_uint32, pcre_uchar *); extern int PRIV(valid_utf)(PCRE_PUCHAR, int, int *); extern BOOL PRIV(was_newline)(PCRE_PUCHAR, int, PCRE_PUCHAR, int *, BOOL); -extern BOOL PRIV(xclass)(pcre_uint32, const pcre_uchar *, BOOL); +extern BOOL PRIV(xclass)(int, const pcre_uchar *, BOOL); #ifdef SUPPORT_JIT extern void PRIV(jit_compile)(const REAL_PCRE *, PUBL(extra) *, int); -extern int PRIV(jit_exec)(const PUBL(extra) *, +extern int PRIV(jit_exec)(const REAL_PCRE *, const PUBL(extra) *, const pcre_uchar *, int, int, int, int *, int); extern void PRIV(jit_free)(void *); extern int PRIV(jit_get_size)(void *); @@ -2705,19 +2313,15 @@ extern const char* PRIV(jit_get_target)(void); /* Unicode character database (UCD) */ typedef struct { - pcre_uint8 script; /* ucp_Arabic, etc. */ - pcre_uint8 chartype; /* ucp_Cc, etc. (general categories) */ - pcre_uint8 gbprop; /* ucp_gbControl, etc. (grapheme break property) */ - pcre_uint8 caseset; /* offset to multichar other cases or zero */ - pcre_int32 other_case; /* offset to other case, or zero if none */ + pcre_uint8 script; + pcre_uint8 chartype; + pcre_int32 other_case; } ucd_record; -extern const pcre_uint32 PRIV(ucd_caseless_sets)[]; extern const ucd_record PRIV(ucd_records)[]; extern const pcre_uint8 PRIV(ucd_stage1)[]; extern const pcre_uint16 PRIV(ucd_stage2)[]; -extern const pcre_uint32 PRIV(ucp_gentype)[]; -extern const pcre_uint32 PRIV(ucp_gbtable)[]; +extern const int PRIV(ucp_gentype)[]; #ifdef SUPPORT_JIT extern const int PRIV(ucp_typerange)[]; #endif @@ -2727,15 +2331,13 @@ extern const int PRIV(ucp_typerange)[]; #define UCD_BLOCK_SIZE 128 #define GET_UCD(ch) (PRIV(ucd_records) + \ - PRIV(ucd_stage2)[PRIV(ucd_stage1)[(int)(ch) / UCD_BLOCK_SIZE] * \ - UCD_BLOCK_SIZE + (int)(ch) % UCD_BLOCK_SIZE]) + PRIV(ucd_stage2)[PRIV(ucd_stage1)[(ch) / UCD_BLOCK_SIZE] * \ + UCD_BLOCK_SIZE + (ch) % UCD_BLOCK_SIZE]) -#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype -#define UCD_SCRIPT(ch) GET_UCD(ch)->script -#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)] -#define UCD_GRAPHBREAK(ch) GET_UCD(ch)->gbprop -#define UCD_CASESET(ch) GET_UCD(ch)->caseset -#define UCD_OTHERCASE(ch) ((pcre_uint32)((int)ch + (int)(GET_UCD(ch)->other_case))) +#define UCD_CHARTYPE(ch) GET_UCD(ch)->chartype +#define UCD_SCRIPT(ch) GET_UCD(ch)->script +#define UCD_CATEGORY(ch) PRIV(ucp_gentype)[UCD_CHARTYPE(ch)] +#define UCD_OTHERCASE(ch) (ch + GET_UCD(ch)->other_case) #endif /* SUPPORT_UCP */ diff --git a/harbour/src/3rd/pcre/pcrejitc.c b/harbour/src/3rd/pcre/pcrejitc.c index 76307a3831..fe2d9f7b16 100644 --- a/harbour/src/3rd/pcre/pcrejitc.c +++ b/harbour/src/3rd/pcre/pcrejitc.c @@ -46,7 +46,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "pcreinal.h" -#if defined SUPPORT_JIT +#ifdef SUPPORT_JIT /* All-in-one: Since we use the JIT compiler only from here, we just include it. This way we don't need to touch the build @@ -65,12 +65,9 @@ system files. */ #error Unsupported architecture #endif -/* Allocate memory for the regex stack on the real machine stack. -Fast, but limited size. */ -#define MACHINE_STACK_SIZE 32768 +/* Allocate memory on the stack. Fast, but limited size. */ +#define LOCAL_SPACE_SIZE 32768 -/* Growth rate for stack allocated by the OS. Should be the multiply -of page size. */ #define STACK_GROWTH_RATE 8192 /* Enable to check that the allocation could destroy temporaries. */ @@ -92,15 +89,15 @@ vertical (sub-expression) (See struct backtrack_common for more details). The condition checkers are boolean (true/false) checkers. Machine code is generated for the checker itself and for the actions depending on the result of the checker. -The 'true' case is called as the matching path (expected path), and the other is called as +The 'true' case is called as the try path (expected path), and the other is called as the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken -branches on the matching path. +branches on the try path. Greedy star operator (*) : - Matching path: match happens. + Try path: match happens. Backtrack path: match failed. Non-greedy star operator (*?) : - Matching path: no need to perform a match. + Try path: no need to perform a match. Backtrack path: match is required. The following example shows how the code generated for a capturing bracket @@ -111,18 +108,18 @@ we have the following regular expression: The generated code will be the following: - A matching path - '(' matching path (pushing arguments to the stack) - B matching path - ')' matching path (pushing arguments to the stack) - D matching path + A try path + '(' try path (pushing arguments to the stack) + B try path + ')' try path (pushing arguments to the stack) + D try path return with successful match D backtrack path ')' backtrack path (If we arrived from "C" jump to the backtrack of "C") B backtrack path C expected path - jump to D matching path + jump to D try path C backtrack path A backtrack path @@ -130,22 +127,22 @@ The generated code will be the following: code paths. In this way the topmost value on the stack is always belong to the current backtrack code path. The backtrack path must check whether there is a next alternative. If so, it needs to jump back to - the matching path eventually. Otherwise it needs to clear out its own stack + the try path eventually. Otherwise it needs to clear out its own stack frame and continue the execution on the backtrack code paths. */ /* Saved stack frames: -Atomic blocks and asserts require reloading the values of private data -when the backtrack mechanism performed. Because of OP_RECURSE, the data +Atomic blocks and asserts require reloading the values of local variables +when the backtrack mechanism performed. Because of OP_RECURSE, the locals are not necessarly known in compile time, thus we need a dynamic restore mechanism. The stack frames are stored in a chain list, and have the following format: ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ] -Thus we can restore the private data to a particular point in the stack. +Thus we can restore the locals to a particular point in the stack. */ typedef struct jit_arguments { @@ -170,7 +167,6 @@ typedef struct executable_functions { void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES]; PUBL(jit_callback) callback; void *userdata; - pcre_uint32 top_bracket; sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES]; } executable_functions; @@ -185,15 +181,15 @@ typedef struct stub_list { enum stub_types type; int data; struct sljit_jump *start; - struct sljit_label *quit; + struct sljit_label *leave; struct stub_list *next; } stub_list; typedef int (SLJIT_CALL *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 -the aguments for compile_backtrackingpath. Must be the first member +code generator. It is allocated by compile_trypath, and contains +the aguments for compile_backtrackpath. Must be the first member of its descendants. */ typedef struct backtrack_common { /* Concatenation stack. */ @@ -212,19 +208,19 @@ typedef struct assert_backtrack { /* Less than 0 (-1) if a frame is not needed. */ int framesize; /* Points to our private memory word on the stack. */ - int private_data_ptr; + int localptr; /* For iterators. */ - struct sljit_label *matchingpath; + struct sljit_label *trypath; } assert_backtrack; typedef struct bracket_backtrack { backtrack_common common; /* Where to coninue if an alternative is successfully matched. */ - struct sljit_label *alternative_matchingpath; + struct sljit_label *alttrypath; /* For rmin and rmax iterators. */ - struct sljit_label *recursive_matchingpath; + struct sljit_label *recursivetrypath; /* For greedy ? operator. */ - struct sljit_label *zero_matchingpath; + struct sljit_label *zerotrypath; /* Contains the branches of a failed condition. */ union { /* Both for OP_COND, OP_SCOND. */ @@ -234,13 +230,13 @@ typedef struct bracket_backtrack { int framesize; } u; /* Points to our private memory word on the stack. */ - int private_data_ptr; + int localptr; } bracket_backtrack; typedef struct bracketpos_backtrack { backtrack_common common; /* Points to our private memory word on the stack. */ - int private_data_ptr; + int localptr; /* Reverting stack is needed. */ int framesize; /* Allocated stack size. */ @@ -249,13 +245,13 @@ typedef struct bracketpos_backtrack { typedef struct braminzero_backtrack { backtrack_common common; - struct sljit_label *matchingpath; + struct sljit_label *trypath; } braminzero_backtrack; typedef struct iterator_backtrack { backtrack_common common; /* Next iteration. */ - struct sljit_label *matchingpath; + struct sljit_label *trypath; } iterator_backtrack; typedef struct recurse_entry { @@ -272,17 +268,12 @@ typedef struct recurse_backtrack { backtrack_common common; } recurse_backtrack; -#define MAX_RANGE_SIZE 6 - typedef struct compiler_common { struct sljit_compiler *compiler; pcre_uchar *start; - /* Maps private data offset to each opcode. */ - int *private_data_ptrs; - /* Tells whether the capturing bracket is optimized. */ - pcre_uint8 *optimized_cbracket; - /* Starting offset of private data for capturing brackets. */ + /* Opcode local area direct map. */ + int *localptrs; int cbraptr; /* OVector starting point. Must be divisible by 2. */ int ovector_start; @@ -299,35 +290,29 @@ typedef struct compiler_common { /* Points to the marked string. */ int mark_ptr; - /* Flipped and lower case tables. */ + /* Other */ const pcre_uint8 *fcc; - sljit_sw lcc; - /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */ + sljit_w lcc; int mode; - /* Newline control. */ int nltype; int newline; int bsr_nltype; - /* Dollar endonly. */ int endonly; BOOL has_set_som; - /* Tables. */ - sljit_sw ctypes; - int digits[2 + MAX_RANGE_SIZE]; - /* Named capturing brackets. */ + sljit_w ctypes; sljit_uw name_table; - sljit_sw name_count; - sljit_sw name_entry_size; + sljit_w name_count; + sljit_w name_entry_size; /* Labels and jump lists. */ struct sljit_label *partialmatchlabel; - struct sljit_label *quitlabel; + struct sljit_label *leavelabel; struct sljit_label *acceptlabel; stub_list *stubs; recurse_entry *entries; recurse_entry *currententry; jump_list *partialmatch; - jump_list *quit; + jump_list *leave; jump_list *accept; jump_list *calllimit; jump_list *stackalloc; @@ -344,9 +329,7 @@ typedef struct compiler_common { #ifdef SUPPORT_UCP BOOL use_ucp; #endif -#ifndef COMPILE_PCRE32 jump_list *utfreadchar; -#endif #ifdef COMPILE_PCRE8 jump_list *utfreadtype8; #endif @@ -364,27 +347,27 @@ typedef struct compare_context { #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED int ucharptr; union { - sljit_si asint; + sljit_i asint; sljit_uh asushort; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 sljit_ub asbyte; sljit_ub asuchars[4]; -#elif defined COMPILE_PCRE16 +#else +#ifdef COMPILE_PCRE16 sljit_uh asuchars[2]; -#elif defined COMPILE_PCRE32 - sljit_ui asuchars[1]; +#endif #endif } c; union { - sljit_si asint; + sljit_i asint; sljit_uh asushort; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 sljit_ub asbyte; sljit_ub asuchars[4]; -#elif defined COMPILE_PCRE16 +#else +#ifdef COMPILE_PCRE16 sljit_uh asuchars[2]; -#elif defined COMPILE_PCRE32 - sljit_ui asuchars[1]; +#endif #endif } oc; #endif @@ -400,49 +383,48 @@ enum { #undef CMP /* Used for accessing the elements of the stack. */ -#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_sw)) +#define STACK(i) ((-(i) - 1) * (int)sizeof(sljit_w)) -#define TMP1 SLJIT_SCRATCH_REG1 -#define TMP2 SLJIT_SCRATCH_REG3 +#define TMP1 SLJIT_TEMPORARY_REG1 +#define TMP2 SLJIT_TEMPORARY_REG3 #define TMP3 SLJIT_TEMPORARY_EREG2 #define STR_PTR SLJIT_SAVED_REG1 #define STR_END SLJIT_SAVED_REG2 -#define STACK_TOP SLJIT_SCRATCH_REG2 +#define STACK_TOP SLJIT_TEMPORARY_REG2 #define STACK_LIMIT SLJIT_SAVED_REG3 #define ARGUMENTS SLJIT_SAVED_EREG1 #define CALL_COUNT SLJIT_SAVED_EREG2 #define RETURN_ADDR SLJIT_TEMPORARY_EREG1 -/* Local space layout. */ +/* Locals layout. */ /* These two locals can be used by the current opcode. */ -#define LOCALS0 (0 * sizeof(sljit_sw)) -#define LOCALS1 (1 * sizeof(sljit_sw)) +#define LOCALS0 (0 * sizeof(sljit_w)) +#define LOCALS1 (1 * sizeof(sljit_w)) /* Two local variables for possessive quantifiers (char1 cannot use them). */ -#define POSSESSIVE0 (2 * sizeof(sljit_sw)) -#define POSSESSIVE1 (3 * sizeof(sljit_sw)) +#define POSSESSIVE0 (2 * sizeof(sljit_w)) +#define POSSESSIVE1 (3 * sizeof(sljit_w)) /* Max limit of recursions. */ -#define CALL_LIMIT (4 * sizeof(sljit_sw)) +#define CALL_LIMIT (4 * sizeof(sljit_w)) /* The output vector is stored on the stack, and contains pointers to characters. The vector data is divided into two groups: the first group contains the start / end character pointers, and the second is the start pointers when the end of the capturing group has not yet reached. */ #define OVECTOR_START (common->ovector_start) -#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_sw)) -#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_sw)) -#define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start]) +#define OVECTOR(i) (OVECTOR_START + (i) * sizeof(sljit_w)) +#define OVECTOR_PRIV(i) (common->cbraptr + (i) * sizeof(sljit_w)) +#define PRIV_DATA(cc) (common->localptrs[(cc) - common->start]) -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 #define MOV_UCHAR SLJIT_MOV_UB #define MOVU_UCHAR SLJIT_MOVU_UB -#elif defined COMPILE_PCRE16 +#else +#ifdef COMPILE_PCRE16 #define MOV_UCHAR SLJIT_MOV_UH #define MOVU_UCHAR SLJIT_MOVU_UH -#elif defined COMPILE_PCRE32 -#define MOV_UCHAR SLJIT_MOV_UI -#define MOVU_UCHAR SLJIT_MOVU_UI #else #error Unsupported compiling mode #endif +#endif /* Shortcuts. */ #define DEFINE_COMPILER \ @@ -463,8 +445,8 @@ the start pointers when the end of the capturing group has not yet reached. */ sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)) #define CMPTO(type, src1, src1w, src2, src2w, label) \ sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label)) -#define OP_FLAGS(op, dst, dstw, src, srcw, type) \ - sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type)) +#define COND_VALUE(op, dst, dstw, type) \ + sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type)) #define GET_LOCAL_BASE(dst, dstw, offset) \ sljit_get_local_base(compiler, (dst), (dstw), (offset)) @@ -479,14 +461,14 @@ return cc; /* Functions whose might need modification for all new supported opcodes: next_opcode - get_private_data_length - set_private_data_ptrs + get_localspace + set_localptrs get_framesize init_frame - get_private_data_length_for_copy - copy_private_data - compile_matchingpath - compile_backtrackingpath + get_localsize + copy_locals + compile_trypath + compile_backtrackpath */ static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc) @@ -685,98 +667,13 @@ switch(*cc) } } -#define CASE_ITERATOR_PRIVATE_DATA_1 \ - case OP_MINSTAR: \ - case OP_MINPLUS: \ - case OP_QUERY: \ - case OP_MINQUERY: \ - case OP_MINSTARI: \ - case OP_MINPLUSI: \ - case OP_QUERYI: \ - case OP_MINQUERYI: \ - case OP_NOTMINSTAR: \ - case OP_NOTMINPLUS: \ - case OP_NOTQUERY: \ - case OP_NOTMINQUERY: \ - case OP_NOTMINSTARI: \ - case OP_NOTMINPLUSI: \ - case OP_NOTQUERYI: \ - case OP_NOTMINQUERYI: - -#define CASE_ITERATOR_PRIVATE_DATA_2A \ - case OP_STAR: \ - case OP_PLUS: \ - case OP_STARI: \ - case OP_PLUSI: \ - case OP_NOTSTAR: \ - case OP_NOTPLUS: \ - case OP_NOTSTARI: \ - case OP_NOTPLUSI: - -#define CASE_ITERATOR_PRIVATE_DATA_2B \ - case OP_UPTO: \ - case OP_MINUPTO: \ - case OP_UPTOI: \ - case OP_MINUPTOI: \ - case OP_NOTUPTO: \ - case OP_NOTMINUPTO: \ - case OP_NOTUPTOI: \ - case OP_NOTMINUPTOI: - -#define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \ - case OP_TYPEMINSTAR: \ - case OP_TYPEMINPLUS: \ - case OP_TYPEQUERY: \ - case OP_TYPEMINQUERY: - -#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \ - case OP_TYPESTAR: \ - case OP_TYPEPLUS: - -#define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \ - case OP_TYPEUPTO: \ - case OP_TYPEMINUPTO: - -static int get_class_iterator_size(pcre_uchar *cc) +static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) { -switch(*cc) - { - case OP_CRSTAR: - case OP_CRPLUS: - return 2; - - case OP_CRMINSTAR: - case OP_CRMINPLUS: - case OP_CRQUERY: - case OP_CRMINQUERY: - return 1; - - case OP_CRRANGE: - case OP_CRMINRANGE: - if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE)) - return 0; - return 2; - - default: - return 0; - } -} - -static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) -{ -int private_data_length = 0; +int localspace = 0; pcre_uchar *alternative; -pcre_uchar *name; -pcre_uchar *end = NULL; -int space, size, i; -pcre_uint32 bracketlen; - /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */ while (cc < ccend) { - space = 0; - size = 0; - bracketlen = 0; switch(*cc) { case OP_SET_SOM: @@ -784,12 +681,6 @@ while (cc < ccend) cc += 1; break; - case OP_REF: - case OP_REFI: - common->optimized_cbracket[GET2(cc, 1)] = 0; - cc += 1 + IMM2_SIZE; - break; - case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: @@ -799,117 +690,31 @@ while (cc < ccend) case OP_BRAPOS: case OP_SBRA: case OP_SBRAPOS: - private_data_length += sizeof(sljit_sw); - bracketlen = 1 + LINK_SIZE; + case OP_SCOND: + localspace += sizeof(sljit_w); + cc += 1 + LINK_SIZE; break; case OP_CBRAPOS: case OP_SCBRAPOS: - private_data_length += sizeof(sljit_sw); - common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0; - bracketlen = 1 + LINK_SIZE + IMM2_SIZE; + localspace += sizeof(sljit_w); + cc += 1 + LINK_SIZE + IMM2_SIZE; break; case OP_COND: - case OP_SCOND: - bracketlen = cc[1 + LINK_SIZE]; - if (bracketlen == OP_CREF) - { - bracketlen = GET2(cc, 1 + LINK_SIZE + 1); - common->optimized_cbracket[bracketlen] = 0; - } - else if (bracketlen == OP_NCREF) - { - bracketlen = GET2(cc, 1 + LINK_SIZE + 1); - name = (pcre_uchar *)common->name_table; - alternative = name; - for (i = 0; i < common->name_count; i++) - { - if (GET2(name, 0) == bracketlen) break; - name += common->name_entry_size; - } - SLJIT_ASSERT(i != common->name_count); - - for (i = 0; i < common->name_count; i++) - { - if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0) - common->optimized_cbracket[GET2(alternative, 0)] = 0; - alternative += common->name_entry_size; - } - } - - if (*cc == OP_COND) - { - /* Might be a hidden SCOND. */ - alternative = cc + GET(cc, 1); - if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) - private_data_length += sizeof(sljit_sw); - } - else - private_data_length += sizeof(sljit_sw); - bracketlen = 1 + LINK_SIZE; + /* Might be a hidden SCOND. */ + alternative = cc + GET(cc, 1); + if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) + localspace += sizeof(sljit_w); + cc += 1 + LINK_SIZE; break; - case OP_BRA: - bracketlen = 1 + LINK_SIZE; - break; - - case OP_CBRA: - case OP_SCBRA: - bracketlen = 1 + LINK_SIZE + IMM2_SIZE; - break; - - CASE_ITERATOR_PRIVATE_DATA_1 - space = 1; - size = -2; - break; - - CASE_ITERATOR_PRIVATE_DATA_2A - space = 2; - size = -2; - break; - - CASE_ITERATOR_PRIVATE_DATA_2B - space = 2; - size = -(2 + IMM2_SIZE); - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_1 - space = 1; - size = 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2A - if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) - space = 2; - size = 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2B - if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) - space = 2; - size = 1 + IMM2_SIZE; - break; - - case OP_CLASS: - case OP_NCLASS: - size += 1 + 32 / sizeof(pcre_uchar); - space = get_class_iterator_size(cc + size); - break; - -#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 - case OP_XCLASS: - size = GET(cc, 1); - space = get_class_iterator_size(cc + size); - break; -#endif - case OP_RECURSE: /* Set its value only once. */ if (common->recursive_head == 0) { common->recursive_head = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); + common->ovector_start += sizeof(sljit_w); } cc += 1 + LINK_SIZE; break; @@ -918,7 +723,7 @@ while (cc < ccend) if (common->mark_ptr == 0) { common->mark_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); + common->ovector_start += sizeof(sljit_w); } cc += 1 + 2 + cc[1]; break; @@ -929,49 +734,16 @@ while (cc < ccend) return -1; break; } - - if (space > 0 && cc >= end) - private_data_length += sizeof(sljit_sw) * space; - - if (size != 0) - { - if (size < 0) - { - cc += -size; -#ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - } - else - cc += size; - } - - if (bracketlen != 0) - { - if (cc >= end) - { - end = bracketend(cc); - if (end[-1 - LINK_SIZE] == OP_KET) - end = NULL; - } - cc += bracketlen; - } } -return private_data_length; +return localspace; } -static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend) +static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend) { pcre_uchar *cc = common->start; pcre_uchar *alternative; -pcre_uchar *end = NULL; -int space, size, bracketlen; - while (cc < ccend) { - space = 0; - size = 0; - bracketlen = 0; switch(*cc) { case OP_ASSERT: @@ -984,16 +756,16 @@ while (cc < ccend) case OP_SBRA: case OP_SBRAPOS: case OP_SCOND: - common->private_data_ptrs[cc - common->start] = private_data_ptr; - private_data_ptr += sizeof(sljit_sw); - bracketlen = 1 + LINK_SIZE; + common->localptrs[cc - common->start] = localptr; + localptr += sizeof(sljit_w); + cc += 1 + LINK_SIZE; break; case OP_CBRAPOS: case OP_SCBRAPOS: - common->private_data_ptrs[cc - common->start] = private_data_ptr; - private_data_ptr += sizeof(sljit_sw); - bracketlen = 1 + LINK_SIZE + IMM2_SIZE; + common->localptrs[cc - common->start] = localptr; + localptr += sizeof(sljit_w); + cc += 1 + LINK_SIZE + IMM2_SIZE; break; case OP_COND: @@ -1001,101 +773,17 @@ while (cc < ccend) alternative = cc + GET(cc, 1); if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) { - common->private_data_ptrs[cc - common->start] = private_data_ptr; - private_data_ptr += sizeof(sljit_sw); + common->localptrs[cc - common->start] = localptr; + localptr += sizeof(sljit_w); } - bracketlen = 1 + LINK_SIZE; + cc += 1 + LINK_SIZE; break; - case OP_BRA: - bracketlen = 1 + LINK_SIZE; - break; - - case OP_CBRA: - case OP_SCBRA: - bracketlen = 1 + LINK_SIZE + IMM2_SIZE; - break; - - CASE_ITERATOR_PRIVATE_DATA_1 - space = 1; - size = -2; - break; - - CASE_ITERATOR_PRIVATE_DATA_2A - space = 2; - size = -2; - break; - - CASE_ITERATOR_PRIVATE_DATA_2B - space = 2; - size = -(2 + IMM2_SIZE); - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_1 - space = 1; - size = 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2A - if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI) - space = 2; - size = 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2B - if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI) - space = 2; - size = 1 + IMM2_SIZE; - break; - - case OP_CLASS: - case OP_NCLASS: - size += 1 + 32 / sizeof(pcre_uchar); - space = get_class_iterator_size(cc + size); - break; - -#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 - case OP_XCLASS: - size = GET(cc, 1); - space = get_class_iterator_size(cc + size); - break; -#endif - default: cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); break; } - - if (space > 0 && cc >= end) - { - common->private_data_ptrs[cc - common->start] = private_data_ptr; - private_data_ptr += sizeof(sljit_sw) * space; - } - - if (size != 0) - { - if (size < 0) - { - cc += -size; -#ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - } - else - cc += size; - } - - if (bracketlen > 0) - { - if (cc >= end) - { - end = bracketend(cc); - if (end[-1 - LINK_SIZE] == OP_KET) - end = NULL; - } - cc += bracketlen; - } } } @@ -1201,9 +889,9 @@ while (cc < ccend) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin); - stackpos += (int)sizeof(sljit_sw); + stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); + stackpos += (int)sizeof(sljit_w); setsom_found = TRUE; } cc += 1; @@ -1215,9 +903,9 @@ while (cc < ccend) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); - stackpos += (int)sizeof(sljit_sw); + stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); + stackpos += (int)sizeof(sljit_w); setmark_found = TRUE; } cc += 1 + 2 + cc[1]; @@ -1228,18 +916,18 @@ while (cc < ccend) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin); - stackpos += (int)sizeof(sljit_sw); + stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); + stackpos += (int)sizeof(sljit_w); setsom_found = TRUE; } if (common->mark_ptr != 0 && !setmark_found) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark); - stackpos += (int)sizeof(sljit_sw); + stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); + stackpos += (int)sizeof(sljit_w); setmark_found = TRUE; } cc += 1 + LINK_SIZE; @@ -1251,13 +939,13 @@ while (cc < ccend) case OP_SCBRAPOS: offset = (GET2(cc, 1 + LINK_SIZE)) << 1; OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset)); - stackpos += (int)sizeof(sljit_sw); + stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0); - stackpos += (int)sizeof(sljit_sw); + stackpos += (int)sizeof(sljit_w); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0); - stackpos += (int)sizeof(sljit_sw); + stackpos += (int)sizeof(sljit_w); cc += 1 + LINK_SIZE + IMM2_SIZE; break; @@ -1272,15 +960,13 @@ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end); SLJIT_ASSERT(stackpos == STACK(stacktop)); } -static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) +static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend) { -int private_data_length = 2; -int size; +int localsize = 2; pcre_uchar *alternative; -/* Calculate the sum of the private machine words. */ +/* Calculate the sum of the local variables. */ while (cc < ccend) { - size = 0; switch(*cc) { case OP_ASSERT: @@ -1293,20 +979,19 @@ while (cc < ccend) case OP_SBRA: case OP_SBRAPOS: case OP_SCOND: - private_data_length++; + localsize++; cc += 1 + LINK_SIZE; break; case OP_CBRA: case OP_SCBRA: - if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) - private_data_length++; + localsize++; cc += 1 + LINK_SIZE + IMM2_SIZE; break; case OP_CBRAPOS: case OP_SCBRAPOS: - private_data_length += 2; + localsize += 2; cc += 1 + LINK_SIZE + IMM2_SIZE; break; @@ -1314,68 +999,10 @@ while (cc < ccend) /* Might be a hidden SCOND. */ alternative = cc + GET(cc, 1); if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) - private_data_length++; + localsize++; cc += 1 + LINK_SIZE; break; - CASE_ITERATOR_PRIVATE_DATA_1 - if (PRIVATE_DATA(cc)) - private_data_length++; - cc += 2; -#ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_PRIVATE_DATA_2A - if (PRIVATE_DATA(cc)) - private_data_length += 2; - cc += 2; -#ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_PRIVATE_DATA_2B - if (PRIVATE_DATA(cc)) - private_data_length += 2; - cc += 2 + IMM2_SIZE; -#ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_1 - if (PRIVATE_DATA(cc)) - private_data_length++; - cc += 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2A - if (PRIVATE_DATA(cc)) - private_data_length += 2; - cc += 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2B - if (PRIVATE_DATA(cc)) - private_data_length += 2; - cc += 1 + IMM2_SIZE; - break; - - case OP_CLASS: - case OP_NCLASS: -#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 - case OP_XCLASS: - size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar); -#else - size = 1 + 32 / (int)sizeof(pcre_uchar); -#endif - if (PRIVATE_DATA(cc)) - private_data_length += get_class_iterator_size(cc + size); - cc += size; - break; - default: cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); @@ -1383,15 +1010,15 @@ while (cc < ccend) } } SLJIT_ASSERT(cc == ccend); -return private_data_length; +return localsize; } -static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, +static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL save, int stackptr, int stacktop) { DEFINE_COMPILER; int srcw[2]; -int count, size; +int count; BOOL tmp1next = TRUE; BOOL tmp1empty = TRUE; BOOL tmp2empty = TRUE; @@ -1408,17 +1035,17 @@ stacktop = STACK(stacktop - 1); if (!save) { - stackptr += sizeof(sljit_sw); + stackptr += sizeof(sljit_w); if (stackptr < stacktop) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); - stackptr += sizeof(sljit_sw); + stackptr += sizeof(sljit_w); tmp1empty = FALSE; } if (stackptr < stacktop) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); - stackptr += sizeof(sljit_sw); + stackptr += sizeof(sljit_w); tmp2empty = FALSE; } /* The tmp1next must be TRUE in either way. */ @@ -1456,27 +1083,24 @@ while (status != end) case OP_SBRAPOS: case OP_SCOND: count = 1; - srcw[0] = PRIVATE_DATA(cc); + srcw[0] = PRIV_DATA(cc); SLJIT_ASSERT(srcw[0] != 0); cc += 1 + LINK_SIZE; break; case OP_CBRA: case OP_SCBRA: - if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0) - { - count = 1; - srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); - } + count = 1; + srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); cc += 1 + LINK_SIZE + IMM2_SIZE; break; case OP_CBRAPOS: case OP_SCBRAPOS: count = 2; - srcw[0] = PRIVATE_DATA(cc); srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE)); - SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0); + srcw[0] = PRIV_DATA(cc); + SLJIT_ASSERT(srcw[0] != 0); cc += 1 + LINK_SIZE + IMM2_SIZE; break; @@ -1486,108 +1110,12 @@ while (status != end) if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN) { count = 1; - srcw[0] = PRIVATE_DATA(cc); + srcw[0] = PRIV_DATA(cc); SLJIT_ASSERT(srcw[0] != 0); } cc += 1 + LINK_SIZE; break; - CASE_ITERATOR_PRIVATE_DATA_1 - if (PRIVATE_DATA(cc)) - { - count = 1; - srcw[0] = PRIVATE_DATA(cc); - } - cc += 2; -#ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_PRIVATE_DATA_2A - if (PRIVATE_DATA(cc)) - { - count = 2; - srcw[0] = PRIVATE_DATA(cc); - srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw); - } - cc += 2; -#ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_PRIVATE_DATA_2B - if (PRIVATE_DATA(cc)) - { - count = 2; - srcw[0] = PRIVATE_DATA(cc); - srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw); - } - cc += 2 + IMM2_SIZE; -#ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]); -#endif - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_1 - if (PRIVATE_DATA(cc)) - { - count = 1; - srcw[0] = PRIVATE_DATA(cc); - } - cc += 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2A - if (PRIVATE_DATA(cc)) - { - count = 2; - srcw[0] = PRIVATE_DATA(cc); - srcw[1] = srcw[0] + sizeof(sljit_sw); - } - cc += 1; - break; - - CASE_ITERATOR_TYPE_PRIVATE_DATA_2B - if (PRIVATE_DATA(cc)) - { - count = 2; - srcw[0] = PRIVATE_DATA(cc); - srcw[1] = srcw[0] + sizeof(sljit_sw); - } - cc += 1 + IMM2_SIZE; - break; - - case OP_CLASS: - case OP_NCLASS: -#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 - case OP_XCLASS: - size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar); -#else - size = 1 + 32 / (int)sizeof(pcre_uchar); -#endif - if (PRIVATE_DATA(cc)) - switch(get_class_iterator_size(cc + size)) - { - case 1: - count = 1; - srcw[0] = PRIVATE_DATA(cc); - break; - - case 2: - count = 2; - srcw[0] = PRIVATE_DATA(cc); - srcw[1] = srcw[0] + sizeof(sljit_sw); - break; - - default: - SLJIT_ASSERT_STOP(); - break; - } - cc += size; - break; - default: cc = next_opcode(common, cc); SLJIT_ASSERT(cc != NULL); @@ -1610,7 +1138,7 @@ while (status != end) if (!tmp1empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); - stackptr += sizeof(sljit_sw); + stackptr += sizeof(sljit_w); } OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]); tmp1empty = FALSE; @@ -1621,7 +1149,7 @@ while (status != end) if (!tmp2empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); - stackptr += sizeof(sljit_sw); + stackptr += sizeof(sljit_w); } OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]); tmp2empty = FALSE; @@ -1638,7 +1166,7 @@ while (status != end) if (!tmp1empty) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr); - stackptr += sizeof(sljit_sw); + stackptr += sizeof(sljit_w); } tmp1next = FALSE; } @@ -1650,7 +1178,7 @@ while (status != end) if (!tmp2empty) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr); - stackptr += sizeof(sljit_sw); + stackptr += sizeof(sljit_w); } tmp1next = TRUE; } @@ -1665,12 +1193,12 @@ if (save) if (!tmp1empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); - stackptr += sizeof(sljit_sw); + stackptr += sizeof(sljit_w); } if (!tmp2empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); - stackptr += sizeof(sljit_sw); + stackptr += sizeof(sljit_w); } } else @@ -1678,26 +1206,19 @@ if (save) if (!tmp2empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0); - stackptr += sizeof(sljit_sw); + stackptr += sizeof(sljit_w); } if (!tmp1empty) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0); - stackptr += sizeof(sljit_sw); + stackptr += sizeof(sljit_w); } } } SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty))); } -#undef CASE_ITERATOR_PRIVATE_DATA_1 -#undef CASE_ITERATOR_PRIVATE_DATA_2A -#undef CASE_ITERATOR_PRIVATE_DATA_2B -#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1 -#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A -#undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B - -static SLJIT_INLINE BOOL is_powerof2(unsigned int value) +static SLJIT_INLINE BOOL ispowerof2(unsigned int value) { return (value & (value - 1)) == 0; } @@ -1707,7 +1228,7 @@ static SLJIT_INLINE void set_jumps(jump_list *list, struct sljit_label *label) while (list) { /* sljit_set_label is clever enough to do nothing - if either the jump or the label is NULL. */ + if either the jump or the label is NULL */ sljit_set_label(list->jump, label); list = list->next; } @@ -1734,7 +1255,7 @@ if (list_item) list_item->type = type; list_item->data = data; list_item->start = start; - list_item->quit = LABEL(); + list_item->leave = LABEL(); list_item->next = common->stubs; common->stubs = list_item; } @@ -1754,7 +1275,7 @@ while (list_item) add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL)); break; } - JUMPTO(SLJIT_JUMP, list_item->quit); + JUMPTO(SLJIT_JUMP, list_item->leave); list_item = list_item->next; } common->stubs = NULL; @@ -1773,7 +1294,7 @@ static SLJIT_INLINE void allocate_stack(compiler_common *common, int size) /* May destroy all locals and registers except TMP2. */ DEFINE_COMPILER; -OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); +OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w)); #ifdef DESTROY_REGISTERS OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345); OP1(SLJIT_MOV, TMP3, 0, TMP1, 0); @@ -1787,7 +1308,7 @@ add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, static SLJIT_INLINE void free_stack(compiler_common *common, int size) { DEFINE_COMPILER; -OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw)); +OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w)); } static SLJIT_INLINE void reset_ovector(compiler_common *common, int length) @@ -1797,19 +1318,19 @@ struct sljit_label *loop; int i; /* At this point we can freely use all temporary registers. */ /* TMP1 returns with begin - 1. */ -OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); +OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1)); if (length < 8) { for (i = 0; i < length; i++) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0); } else { - GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length); + GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length); loop = LABEL(); - OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); JUMPTO(SLJIT_C_NOT_ZERO, loop); } } @@ -1824,75 +1345,75 @@ struct sljit_jump *earlyexit; OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0); -OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0); if (common->mark_ptr != 0) - OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); -OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr); +OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount)); if (common->mark_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0); -OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); -OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0); +OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int)); +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin)); GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START); /* Unlikely, but possible */ -earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0); +earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0); loop = LABEL(); -OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0); -OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw)); +OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0); +OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w)); /* Copy the integer value to the output buffer */ -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 -OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT); +#ifdef COMPILE_PCRE16 +OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); #endif -OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0); -OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1); +OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0); +OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); JUMPTO(SLJIT_C_NOT_ZERO, loop); JUMPHERE(earlyexit); /* Calculate the return value, which is the maximum ovector value. */ if (topbracket > 1) { - GET_LOCAL_BASE(SLJIT_SCRATCH_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1); + GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1); /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */ loop = LABEL(); - OP1(SLJIT_MOVU, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), -(2 * (sljit_sw)sizeof(sljit_sw))); - OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1); - CMPTO(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG3, 0, loop); - OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0); + OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w))); + OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1); + CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop); + OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0); } else OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); } -static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit) +static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave) { DEFINE_COMPILER; SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2); SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0)); -OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0); +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL); -OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount)); -CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit); +OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount)); +CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave); /* Store match begin and end. */ -OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); -OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); -OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start); +OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin)); +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets)); +OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start); OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0); -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 -OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT); +#ifdef COMPILE_PCRE16 +OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1); #endif -OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0); +OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0); -OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0); -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 -OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT); +OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0); +#ifdef COMPILE_PCRE16 +OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1); #endif -OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0); +OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0); -JUMPTO(SLJIT_JUMP, quit); +JUMPTO(SLJIT_JUMP, leave); } static SLJIT_INLINE void check_start_used_ptr(compiler_common *common) @@ -2003,10 +1524,10 @@ if (c <= 127 && bit == 0x20) return (0 << 8) | 0x20; /* Since c != oc, they must have at least 1 bit difference. */ -if (!is_powerof2(bit)) +if (!ispowerof2(bit)) return 0; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 #ifdef SUPPORT_UTF if (common->utf && c > 127) @@ -2022,8 +1543,9 @@ if (common->utf && c > 127) #endif /* SUPPORT_UTF */ return (0 << 8) | bit; -#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#else /* COMPILE_PCRE8 */ +#ifdef COMPILE_PCRE16 #ifdef SUPPORT_UTF if (common->utf && c > 65535) { @@ -2034,8 +1556,9 @@ if (common->utf && c > 65535) } #endif /* SUPPORT_UTF */ return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8)); +#endif /* COMPILE_PCRE16 */ -#endif /* COMPILE_PCRE[8|16|32] */ +#endif /* COMPILE_PCRE8 */ } static void check_partial(compiler_common *common, BOOL force) @@ -2133,23 +1656,25 @@ static void read_char(compiler_common *common) /* Reads the character into TMP1, updates STR_PTR. Does not check STR_END. TMP2 Destroyed. */ DEFINE_COMPILER; -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF struct sljit_jump *jump; #endif OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (common->utf) { -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); -#elif defined COMPILE_PCRE16 +#else +#ifdef COMPILE_PCRE16 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); -#endif /* COMPILE_PCRE[8|16] */ +#endif +#endif /* COMPILE_PCRE8 */ add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); JUMPHERE(jump); } -#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ +#endif OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } @@ -2158,31 +1683,33 @@ static void peek_char(compiler_common *common) /* Reads the character into TMP1, keeps STR_PTR. Does not check STR_END. TMP2 Destroyed. */ DEFINE_COMPILER; -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF struct sljit_jump *jump; #endif OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF if (common->utf) { -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); -#elif defined COMPILE_PCRE16 +#else +#ifdef COMPILE_PCRE16 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); -#endif /* COMPILE_PCRE[8|16] */ +#endif +#endif /* COMPILE_PCRE8 */ add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); JUMPHERE(jump); } -#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ +#endif } static void read_char8_type(compiler_common *common) { /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */ DEFINE_COMPILER; -#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 struct sljit_jump *jump; #endif @@ -2191,14 +1718,15 @@ if (common->utf) { OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 /* This can be an extra read in some situations, but hopefully it is needed in most cases. */ OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0); add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL)); JUMPHERE(jump); -#elif defined COMPILE_PCRE16 +#else +#ifdef COMPILE_PCRE16 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); @@ -2206,27 +1734,23 @@ if (common->utf) /* Skip low surrogate if necessary. */ OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -#elif defined COMPILE_PCRE32 - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); - jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); - JUMPHERE(jump); -#endif /* COMPILE_PCRE[8|16|32] */ +#endif +#endif /* COMPILE_PCRE8 */ return; } -#endif /* SUPPORT_UTF */ +#endif OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#ifdef COMPILE_PCRE16 /* The ctypes array contains only 256 values. */ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255); #endif OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#ifdef COMPILE_PCRE16 JUMPHERE(jump); #endif } @@ -2235,8 +1759,7 @@ static void skip_char_back(compiler_common *common) { /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */ DEFINE_COMPILER; -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 -#if defined COMPILE_PCRE8 +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 struct sljit_label *label; if (common->utf) @@ -2248,7 +1771,8 @@ if (common->utf) CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label); return; } -#elif defined COMPILE_PCRE16 +#endif +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 if (common->utf) { OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); @@ -2256,13 +1780,12 @@ if (common->utf) /* Skip low surrogate if necessary. */ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); return; } -#endif /* COMPILE_PCRE[8|16] */ -#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ +#endif OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } @@ -2279,9 +1802,9 @@ if (nltype == NLTYPE_ANY) else if (nltype == NLTYPE_ANYCRLF) { OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO)); } else @@ -2293,7 +1816,7 @@ else #ifdef SUPPORT_UTF -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 static void do_utfreadchar(compiler_common *common) { /* Fast decoding a UTF-8 character. TMP1 contains the first byte @@ -2381,14 +1904,15 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(jump); /* We only have types for characters less than 256. */ -OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); +OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } -#elif defined COMPILE_PCRE16 +#else /* COMPILE_PCRE8 */ +#ifdef COMPILE_PCRE16 static void do_utfreadchar(compiler_common *common) { /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char @@ -2413,8 +1937,9 @@ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } +#endif /* COMPILE_PCRE16 */ -#endif /* COMPILE_PCRE[8|16] */ +#endif /* COMPILE_PCRE8 */ #endif /* SUPPORT_UTF */ @@ -2434,13 +1959,13 @@ SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); -OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); +OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1)); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2)); OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } @@ -2454,7 +1979,7 @@ struct sljit_label *newlinelabel = NULL; struct sljit_jump *start; struct sljit_jump *end = NULL; struct sljit_jump *nl = NULL; -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 +#ifdef SUPPORT_UTF struct sljit_jump *singlechar; #endif jump_list *newline = NULL; @@ -2469,7 +1994,8 @@ if (firstline) { /* Search for the end of the first line. */ SLJIT_ASSERT(common->first_line_end != 0); - OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0); if (common->nltype == NLTYPE_FIXED && common->newline > 255) { @@ -2480,7 +2006,6 @@ if (firstline) OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop); CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop); - JUMPHERE(end); OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } else @@ -2492,12 +2017,12 @@ if (firstline) read_char(common); check_newlinechar(common, common->nltype, &newline, TRUE); CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop); - JUMPHERE(end); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0); set_jumps(newline, LABEL()); } - OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + JUMPHERE(end); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); } start = JUMP(SLJIT_JUMP); @@ -2509,9 +2034,9 @@ if (newlinecheck) end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); +#ifdef COMPILE_PCRE16 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); #endif OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); nl = JUMP(SLJIT_JUMP); @@ -2532,28 +2057,27 @@ if (newlinecheck) CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if defined SUPPORT_UTF && !defined COMPILE_PCRE32 -#if defined COMPILE_PCRE8 +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (common->utf) { singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); JUMPHERE(singlechar); } -#elif defined COMPILE_PCRE16 +#endif +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 if (common->utf) { singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); JUMPHERE(singlechar); } -#endif /* COMPILE_PCRE[8|16] */ -#endif /* SUPPORT_UTF && !COMPILE_PCRE32 */ +#endif JUMPHERE(start); if (newlinecheck) @@ -2565,192 +2089,22 @@ if (newlinecheck) return mainloop; } -#define MAX_N_CHARS 3 - -static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline) -{ -DEFINE_COMPILER; -struct sljit_label *start; -struct sljit_jump *quit; -pcre_uint32 chars[MAX_N_CHARS * 2]; -pcre_uchar *cc = common->start + 1 + IMM2_SIZE; -int location = 0; -pcre_int32 len, c, bit, caseless; -int must_stop; - -/* We do not support alternatives now. */ -if (*(common->start + GET(common->start, 1)) == OP_ALT) - return FALSE; - -while (TRUE) - { - caseless = 0; - must_stop = 1; - switch(*cc) - { - case OP_CHAR: - must_stop = 0; - cc++; - break; - - case OP_CHARI: - caseless = 1; - must_stop = 0; - cc++; - break; - - case OP_SOD: - case OP_SOM: - case OP_SET_SOM: - case OP_NOT_WORD_BOUNDARY: - case OP_WORD_BOUNDARY: - case OP_EODN: - case OP_EOD: - case OP_CIRC: - case OP_CIRCM: - case OP_DOLL: - case OP_DOLLM: - /* Zero width assertions. */ - cc++; - continue; - - case OP_PLUS: - case OP_MINPLUS: - case OP_POSPLUS: - cc++; - break; - - case OP_EXACT: - cc += 1 + IMM2_SIZE; - break; - - case OP_PLUSI: - case OP_MINPLUSI: - case OP_POSPLUSI: - caseless = 1; - cc++; - break; - - case OP_EXACTI: - caseless = 1; - cc += 1 + IMM2_SIZE; - break; - - default: - must_stop = 2; - break; - } - - if (must_stop == 2) - break; - - len = 1; -#ifdef SUPPORT_UTF - if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]); -#endif - - if (caseless && char_has_othercase(common, cc)) - { - caseless = char_get_othercase_bit(common, cc); - if (caseless == 0) - return FALSE; -#ifdef COMPILE_PCRE8 - caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8)); -#else - if ((caseless & 0x100) != 0) - caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9)); - else - caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9)); -#endif - } - else - caseless = 0; - - while (len > 0 && location < MAX_N_CHARS * 2) - { - c = *cc; - bit = 0; - if (len == (caseless & 0xff)) - { - bit = caseless >> 8; - c |= bit; - } - - chars[location] = c; - chars[location + 1] = bit; - - len--; - location += 2; - cc++; - } - - if (location >= MAX_N_CHARS * 2 || must_stop != 0) - break; - } - -/* At least two characters are required. */ -if (location < 2 * 2) - return FALSE; - -if (firstline) - { - SLJIT_ASSERT(common->first_line_end != 0); - OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); - OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1); - } -else - OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1); - -start = LABEL(); -quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); - -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -if (chars[1] != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]); -CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start); -if (location > 2 * 2) - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); -if (chars[3] != 0) - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]); -CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start); -if (location > 2 * 2) - { - if (chars[5] != 0) - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]); - CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start); - } -OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - -JUMPHERE(quit); - -if (firstline) - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); -else - OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1); -return TRUE; -} - -#undef MAX_N_CHARS - static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline) { DEFINE_COMPILER; struct sljit_label *start; -struct sljit_jump *quit; +struct sljit_jump *leave; struct sljit_jump *found; pcre_uchar oc, bit; if (firstline) { - SLJIT_ASSERT(common->first_line_end != 0); - OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); } start = LABEL(); -quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); oc = first_char; @@ -2767,7 +2121,7 @@ if (first_char == oc) else { bit = first_char ^ oc; - if (is_powerof2(bit)) + if (ispowerof2(bit)) { OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit); found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit); @@ -2775,20 +2129,39 @@ else else { OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); found = JUMP(SLJIT_C_NOT_ZERO); } } OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 +if (common->utf) + { + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } +#endif +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 +if (common->utf) + { + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); + OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } +#endif JUMPTO(SLJIT_JUMP, start); JUMPHERE(found); -JUMPHERE(quit); +JUMPHERE(leave); if (firstline) - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); } static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline) @@ -2797,15 +2170,14 @@ DEFINE_COMPILER; struct sljit_label *loop; struct sljit_jump *lastchar; struct sljit_jump *firstchar; -struct sljit_jump *quit; +struct sljit_jump *leave; struct sljit_jump *foundcr = NULL; struct sljit_jump *notfoundnl; jump_list *newline = NULL; if (firstline) { - SLJIT_ASSERT(common->first_line_end != 0); - OP1(SLJIT_MOV, TMP3, 0, STR_END, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); } @@ -2819,21 +2191,21 @@ if (common->nltype == NLTYPE_FIXED && common->newline > 255) OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2)); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL); -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL); +#ifdef COMPILE_PCRE16 + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); #endif OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); loop = LABEL(); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop); CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop); - JUMPHERE(quit); + JUMPHERE(leave); JUMPHERE(firstchar); JUMPHERE(lastchar); @@ -2857,31 +2229,31 @@ set_jumps(newline, loop); if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF) { - quit = JUMP(SLJIT_JUMP); + leave = JUMP(SLJIT_JUMP); JUMPHERE(foundcr); notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); +#ifdef COMPILE_PCRE16 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); #endif OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); JUMPHERE(notfoundnl); - JUMPHERE(quit); + JUMPHERE(leave); } JUMPHERE(lastchar); JUMPHERE(firstchar); if (firstline) - OP1(SLJIT_MOV, STR_END, 0, TMP3, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); } static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline) { DEFINE_COMPILER; struct sljit_label *start; -struct sljit_jump *quit; +struct sljit_jump *leave; struct sljit_jump *found; #ifndef COMPILE_PCRE8 struct sljit_jump *jump; @@ -2889,13 +2261,12 @@ struct sljit_jump *jump; if (firstline) { - SLJIT_ASSERT(common->first_line_end != 0); - OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0); OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); } start = LABEL(); -quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); #ifdef SUPPORT_UTF if (common->utf) @@ -2918,32 +2289,31 @@ if (common->utf) OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); #endif OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#ifdef SUPPORT_UTF -#if defined COMPILE_PCRE8 +#if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (common->utf) { CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); } -#elif defined COMPILE_PCRE16 +#endif +#if defined SUPPORT_UTF && defined COMPILE_PCRE16 if (common->utf) { CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); } -#endif /* COMPILE_PCRE[8|16] */ -#endif /* SUPPORT_UTF */ +#endif JUMPTO(SLJIT_JUMP, start); JUMPHERE(found); -JUMPHERE(quit); +JUMPHERE(leave); if (firstline) - OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0); + OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); } static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar) @@ -2955,7 +2325,7 @@ struct sljit_jump *alreadyfound; struct sljit_jump *found; struct sljit_jump *foundoc = NULL; struct sljit_jump *notfound; -pcre_uint32 oc, bit; +pcre_uchar oc, bit; SLJIT_ASSERT(common->req_char_ptr != 0); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr); @@ -2986,7 +2356,7 @@ if (req_char == oc) else { bit = req_char ^ oc; - if (is_powerof2(bit)) + if (ispowerof2(bit)) { OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit); found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit); @@ -3024,9 +2394,9 @@ mainloop = LABEL(); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0); jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0); -OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); -OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw)); -OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw)); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); +OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w)); JUMPTO(SLJIT_JUMP, mainloop); JUMPHERE(jump); @@ -3037,8 +2407,8 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(jump); jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin); /* Set string begin. */ -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); -OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0); JUMPTO(SLJIT_JUMP, mainloop); @@ -3046,8 +2416,8 @@ JUMPHERE(jump); if (common->mark_ptr != 0) { jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw)); - OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w)); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); JUMPTO(SLJIT_JUMP, mainloop); @@ -3055,7 +2425,7 @@ if (common->mark_ptr != 0) } /* Unknown command. */ -OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w)); JUMPTO(SLJIT_JUMP, mainloop); } @@ -3088,10 +2458,10 @@ if (common->use_ucp) add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); JUMPHERE(jump); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0); } @@ -3132,10 +2502,10 @@ if (common->use_ucp) add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); JUMPHERE(jump); } else @@ -3167,145 +2537,6 @@ OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_R sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); } -/* - range format: - - ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range). - ranges[1] = first bit (0 or 1) - ranges[2-length] = position of the bit change (when the current bit is not equal to the previous) -*/ - -static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch) -{ -DEFINE_COMPILER; -struct sljit_jump *jump; - -if (ranges[0] < 0) - return FALSE; - -switch(ranges[0]) - { - case 1: - if (readch) - read_char(common); - add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); - return TRUE; - - case 2: - if (readch) - read_char(common); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]); - add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2])); - return TRUE; - - case 4: - if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5]) - { - if (readch) - read_char(common); - if (ranges[1] != 0) - { - add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2])); - add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4])); - } - else - { - jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]); - add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4])); - JUMPHERE(jump); - } - return TRUE; - } - if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2])) - { - if (readch) - read_char(common); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]); - OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]); - add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4])); - return TRUE; - } - return FALSE; - - default: - return FALSE; - } -} - -static void get_ctype_ranges(compiler_common *common, int flag, int *ranges) -{ -int i, bit, length; -const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes; - -bit = ctypes[0] & flag; -ranges[0] = -1; -ranges[1] = bit != 0 ? 1 : 0; -length = 0; - -for (i = 1; i < 256; i++) - if ((ctypes[i] & flag) != bit) - { - if (length >= MAX_RANGE_SIZE) - return; - ranges[2 + length] = i; - length++; - bit ^= flag; - } - -if (bit != 0) - { - if (length >= MAX_RANGE_SIZE) - return; - ranges[2 + length] = 256; - length++; - } -ranges[0] = length; -} - -static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks) -{ -int ranges[2 + MAX_RANGE_SIZE]; -pcre_uint8 bit, cbit, all; -int i, byte, length = 0; - -bit = bits[0] & 0x1; -ranges[1] = bit; -/* Can be 0 or 255. */ -all = -bit; - -for (i = 0; i < 256; ) - { - byte = i >> 3; - if ((i & 0x7) == 0 && bits[byte] == all) - i += 8; - else - { - cbit = (bits[byte] >> (i & 0x7)) & 0x1; - if (cbit != bit) - { - if (length >= MAX_RANGE_SIZE) - return FALSE; - ranges[2 + length] = i; - length++; - bit = cbit; - all = -cbit; - } - i++; - } - } - -if (((bit == 0) && nclass) || ((bit == 1) && !nclass)) - { - if (length >= MAX_RANGE_SIZE) - return FALSE; - ranges[2 + length] = 256; - length++; - } -ranges[0] = length; - -return check_ranges(common, ranges, backtracks, FALSE); -} - static void check_anynewline(compiler_common *common) { /* Check whether TMP1 contains a newline character. TMP2 destroyed. */ @@ -3315,21 +2546,21 @@ sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); -OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); +COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); -#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 #ifdef COMPILE_PCRE8 if (common->utf) { #endif - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); #ifdef COMPILE_PCRE8 } #endif -#endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ -OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); +#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ +COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } @@ -3341,33 +2572,33 @@ DEFINE_COMPILER; sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09); -OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); +COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20); -OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); +COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0); -#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 #ifdef COMPILE_PCRE8 if (common->utf) { #endif - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000); #ifdef COMPILE_PCRE8 } #endif -#endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ -OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); +#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ +COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } @@ -3381,21 +2612,21 @@ sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a); -OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); +COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a); -#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 #ifdef COMPILE_PCRE8 if (common->utf) { #endif - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a); #ifdef COMPILE_PCRE8 } #endif -#endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */ -OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); +#endif /* SUPPORT_UTF || COMPILE_PCRE16 */ +COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } @@ -3484,11 +2715,9 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1) { /* This function would be ineffective to do in JIT level. */ -pcre_uint32 c1, c2; +int c1, c2; const pcre_uchar *src2 = args->uchar_ptr; const pcre_uchar *end2 = args->end; -const ucd_record *ur; -const pcre_uint32 *pp; while (src1 < end1) { @@ -3496,16 +2725,7 @@ while (src1 < end1) return (pcre_uchar*)1; GETCHARINC(c1, src1); GETCHARINC(c2, src2); - ur = GET_UCD(c2); - if (c1 != c2 && c1 != c2 + ur->other_case) - { - pp = PRIV(ucd_caseless_sets) + ur->caseset; - for (;;) - { - if (c1 < *pp) return NULL; - if (c1 == *pp++) break; - } - } + if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL; } return src2; } @@ -3527,25 +2747,23 @@ if (caseless && char_has_othercase(common, cc)) othercasebit = char_get_othercase_bit(common, cc); SLJIT_ASSERT(othercasebit); /* Extracting bit difference info. */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 othercasechar = cc + (othercasebit >> 8); othercasebit &= 0xff; -#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - /* Note that this code only handles characters in the BMP. If there - ever are characters outside the BMP whose othercase differs in only one - bit from itself (there currently are none), this code will need to be - revised for COMPILE_PCRE32. */ +#else +#ifdef COMPILE_PCRE16 othercasechar = cc + (othercasebit >> 9); if ((othercasebit & 0x100) != 0) othercasebit = (othercasebit & 0xff) << 8; else othercasebit &= 0xff; -#endif /* COMPILE_PCRE[8|16|32] */ +#endif +#endif } if (context->sourcereg == -1) { -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED if (context->length >= 4) OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); @@ -3554,16 +2772,16 @@ if (context->sourcereg == -1) else #endif OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#elif defined COMPILE_PCRE16 +#else +#ifdef COMPILE_PCRE16 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED if (context->length >= 4) OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); else #endif - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#elif defined COMPILE_PCRE32 - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); -#endif /* COMPILE_PCRE[8|16|32] */ + OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif +#endif /* COMPILE_PCRE8 */ context->sourcereg = TMP2; } @@ -3592,29 +2810,23 @@ do } context->ucharptr++; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1)) -#elif defined COMPILE_PCRE16 +#else if (context->ucharptr >= 2 || context->length == 0) -#elif defined COMPILE_PCRE32 - if (1 /* context->ucharptr >= 1 || context->length == 0 */) #endif { -#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 if (context->length >= 4) OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 else if (context->length >= 2) OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); else if (context->length >= 1) OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#elif defined COMPILE_PCRE16 +#else else if (context->length >= 2) OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#endif /* COMPILE_PCRE[8|16] */ -#elif defined COMPILE_PCRE32 - OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); -#endif /* COMPILE_PCRE[8|16|32] */ +#endif context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; switch(context->ucharptr) @@ -3625,7 +2837,6 @@ do add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint)); break; -#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 case 2 / sizeof(pcre_uchar): if (context->oc.asushort != 0) OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort); @@ -3640,8 +2851,6 @@ do break; #endif -#endif /* COMPILE_PCRE[8|16] */ - default: SLJIT_ASSERT_STOP(); break; @@ -3652,9 +2861,13 @@ do #else /* Unaligned read is unsupported. */ +#ifdef COMPILE_PCRE8 if (context->length > 0) - OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); - + OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#else + if (context->length > 0) + OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length); +#endif context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1; if (othercasebit != 0 && othercasechar == cc) @@ -3699,25 +2912,25 @@ return cc; } \ charoffset = (value); -static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) +static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) { DEFINE_COMPILER; jump_list *found = NULL; jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks; -pcre_int32 c, charoffset; -const pcre_uint32 *other_cases; +unsigned int c; +int compares; struct sljit_jump *jump = NULL; pcre_uchar *ccbegin; -int compares, invertcmp, numberofcmps; #ifdef SUPPORT_UCP BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; BOOL charsaved = FALSE; int typereg = TMP1, scriptreg = TMP1; -pcre_int32 typeoffset; +unsigned int typeoffset; #endif +int invertcmp, numberofcmps; +unsigned int charoffset; -/* Although SUPPORT_UTF must be defined, we are - not necessary in utf mode even in 8 bit mode. */ +/* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */ detect_partial_match(common, backtracks); read_char(common); @@ -3731,15 +2944,12 @@ if ((*cc++ & XCL_MAP) != 0) jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255); #endif - if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list)) - { - OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); - OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); - add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO)); - } + OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); + OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); + OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); + add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO)); #ifndef COMPILE_PCRE8 JUMPHERE(jump); @@ -3812,10 +3022,6 @@ while (*cc != XCL_END) needschar = TRUE; break; - case PT_CLIST: - needschar = TRUE; - break; - default: SLJIT_ASSERT_STOP(); break; @@ -3852,13 +3058,13 @@ if (needstype || needsscript) { if (scriptreg == TMP1) { - OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); + OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3); } else { OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script)); OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0); } } @@ -3894,13 +3100,13 @@ while (*cc != XCL_END) if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) { OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); - OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); numberofcmps++; } else if (numberofcmps > 0) { OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); numberofcmps = 0; } @@ -3933,13 +3139,13 @@ while (*cc != XCL_END) if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE)) { OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); - OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL); + COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); numberofcmps++; } else if (numberofcmps > 0) { OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); numberofcmps = 0; } @@ -3970,11 +3176,11 @@ while (*cc != XCL_END) case PT_LAMP: OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset); - OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); break; @@ -4001,81 +3207,28 @@ while (*cc != XCL_END) } SET_CHAR_OFFSET(9); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL); if (*cc == PT_SPACE) JUMPHERE(jump); SET_TYPE_OFFSET(ucp_Zl); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); break; case PT_WORD: OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); /* ... fall through */ case PT_ALNUM: SET_TYPE_OFFSET(ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); - OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL); + COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL); SET_TYPE_OFFSET(ucp_Nd); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL); - jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); - break; - - case PT_CLIST: - other_cases = PRIV(ucd_caseless_sets) + cc[1]; - - /* At least three characters are required. - Otherwise this case would be handled by the normal code path. */ - SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR); - SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]); - - /* Optimizing character pairs, if their difference is power of 2. */ - if (is_powerof2(other_cases[1] ^ other_cases[0])) - { - if (charoffset == 0) - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); - else - { - OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); - } - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); - other_cases += 2; - } - else if (is_powerof2(other_cases[2] ^ other_cases[1])) - { - if (charoffset == 0) - OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]); - else - { - OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset); - OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]); - } - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); - - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset); - OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); - - other_cases += 3; - } - else - { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); - } - - while (*other_cases != NOTACHAR) - { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset); - OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); - } + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL); jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp); break; } @@ -4096,7 +3249,7 @@ if (found != NULL) #endif -static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks) +static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks) { DEFINE_COMPILER; int length; @@ -4132,21 +3285,10 @@ switch(type) case OP_NOT_DIGIT: case OP_DIGIT: - /* Digits are usually 0-9, so it is worth to optimize them. */ - if (common->digits[0] == -2) - get_ctype_ranges(common, ctype_digit, common->digits); detect_partial_match(common, backtracks); - /* Flip the starting bit in the negative case. */ - if (type == OP_NOT_DIGIT) - common->digits[1] ^= 1; - if (!check_ranges(common, common->digits, backtracks, TRUE)) - { - read_char8_type(common); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); - add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); - } - if (type == OP_NOT_DIGIT) - common->digits[1] ^= 1; + read_char8_type(common); + OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); + add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO)); return cc; case OP_NOT_WHITESPACE: @@ -4193,21 +3335,21 @@ switch(type) { OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if defined COMPILE_PCRE8 || defined COMPILE_PCRE16 -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -#elif defined COMPILE_PCRE16 +#else /* COMPILE_PCRE8 */ +#ifdef COMPILE_PCRE16 jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800); OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -#endif +#endif /* COMPILE_PCRE16 */ +#endif /* COMPILE_PCRE8 */ JUMPHERE(jump[0]); -#endif /* COMPILE_PCRE[8|16] */ return cc; } #endif @@ -4228,7 +3370,7 @@ switch(type) propdata[2] = cc[0]; propdata[3] = cc[1]; propdata[4] = XCL_END; - compile_xclass_matchingpath(common, propdata, backtracks); + compile_xclass_trypath(common, propdata, backtracks); return cc + 2; #endif #endif @@ -4274,30 +3416,19 @@ switch(type) detect_partial_match(common, backtracks); read_char(common); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); - /* Optimize register allocation: use a real register. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); - OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); + add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc)); label = LABEL(); jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); read_char(common); add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop)); - OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3); - - OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2); - OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable)); - OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0); - OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); - OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); - JUMPTO(SLJIT_C_NOT_ZERO, label); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc); + CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label); OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); JUMPHERE(jump[0]); - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); - if (common->mode == JIT_PARTIAL_HARD_COMPILE) { jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0); @@ -4321,9 +3452,9 @@ switch(type) { jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL); add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL)); check_partial(common, TRUE); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); @@ -4423,7 +3554,7 @@ switch(type) add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); if (!common->endonly) - compile_char1_matchingpath(common, OP_EODN, cc, backtracks); + compile_char1_trypath(common, OP_EODN, cc, backtracks); else { add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0)); @@ -4503,16 +3634,16 @@ switch(type) } oc = char_othercase(common, c); bit = c ^ oc; - if (is_powerof2(bit)) + if (ispowerof2(bit)) { OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); return cc + length; } OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); + OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c)); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); return cc + length; @@ -4539,7 +3670,7 @@ switch(type) /* Skip the variable-length character. */ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0); - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); JUMPHERE(jump[0]); return cc + 1; @@ -4564,7 +3695,7 @@ switch(type) { oc = char_othercase(common, c); bit = c ^ oc; - if (is_powerof2(bit)) + if (ispowerof2(bit)) { OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); @@ -4581,9 +3712,6 @@ switch(type) case OP_NCLASS: detect_partial_match(common, backtracks); read_char(common); - if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks)) - return cc + 32 / sizeof(pcre_uchar); - #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 jump[0] = NULL; #ifdef COMPILE_PCRE8 @@ -4602,7 +3730,7 @@ switch(type) #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3); - OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc); + OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc); OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0); add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO)); @@ -4612,9 +3740,9 @@ switch(type) #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */ return cc + 32 / sizeof(pcre_uchar); -#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 case OP_XCLASS: - compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks); + compile_xclass_trypath(common, cc + LINK_SIZE, backtracks); return cc + GET(cc, 0) - 1; #endif @@ -4648,7 +3776,7 @@ SLJIT_ASSERT_STOP(); return cc; } -static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks) +static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks) { /* This function consumes at least one input character. */ /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */ @@ -4711,7 +3839,7 @@ if (context.length > 0) } /* A non-fixed length character will be checked if length == 0. */ -return compile_char1_matchingpath(common, *cc, cc + 1, backtracks); +return compile_char1_trypath(common, *cc, cc + 1, backtracks); } static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks) @@ -4726,9 +3854,9 @@ if (!common->jscript_compat) { /* OVECTOR(1) contains the "string begin - 1" constant. */ OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL); return JUMP(SLJIT_C_NOT_ZERO); } add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); @@ -4737,8 +3865,8 @@ return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset } /* Forward definitions. */ -static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *); -static void compile_backtrackingpath(compiler_common *, struct backtrack_common *); +static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *); +static void compile_backtrackpath(compiler_common *, struct backtrack_common *); #define PUSH_BACKTRACK(size, ccstart, error) \ do \ @@ -4768,7 +3896,7 @@ static void compile_backtrackingpath(compiler_common *, struct backtrack_common #define BACKTRACK_AS(type) ((type *)backtrack) -static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail) +static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail) { DEFINE_COMPILER; int offset = GET2(cc, 1) << 1; @@ -4784,15 +3912,15 @@ if (withchecks && !common->jscript_compat) #if defined SUPPORT_UTF && defined SUPPORT_UCP if (common->utf && *cc == OP_REFI) { - SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3); + SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3); OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); if (withchecks) jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0); /* Needed to save important temporary registers. */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0); - OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 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, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); if (common->mode == JIT_COMPILE) @@ -4850,7 +3978,7 @@ if (jump != NULL) return cc + 1 + IMM2_SIZE; } -static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; @@ -4905,10 +4033,10 @@ if (!minimize) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0); /* Temporary release of STR_PTR. */ - OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); zerolength = compile_ref_checks(common, ccbegin, NULL); /* Restore if not zero length. */ - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); } else { @@ -4921,7 +4049,7 @@ if (!minimize) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); label = LABEL(); - compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); + compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE); if (min > 1 || max > 1) { @@ -4949,7 +4077,7 @@ if (!minimize) } JUMPHERE(zerolength); - BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); decrease_call_count(common); return cc; @@ -4969,11 +4097,11 @@ if (min == 0) else zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks); -BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); +BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); if (max > 0) add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max)); -compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); +compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); if (min > 1) @@ -4981,7 +4109,7 @@ if (min > 1) OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); - CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath); } else if (max > 0) OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); @@ -4994,7 +4122,7 @@ decrease_call_count(common); return cc; } -static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; @@ -5051,11 +4179,11 @@ add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_ return cc + 1 + LINK_SIZE; } -static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) +static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional) { DEFINE_COMPILER; int framesize; -int private_data_ptr; +int localptr; backtrack_common altbacktrack; pcre_uchar *ccbegin; pcre_uchar opcode; @@ -5064,9 +4192,9 @@ jump_list *tmp = NULL; jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks; jump_list **found; /* Saving previous accept variables. */ -struct sljit_label *save_quitlabel = common->quitlabel; +struct sljit_label *save_leavelabel = common->leavelabel; struct sljit_label *save_acceptlabel = common->acceptlabel; -jump_list *save_quit = common->quit; +jump_list *save_leave = common->leave; jump_list *save_accept = common->accept; struct sljit_jump *jump; struct sljit_jump *brajump = NULL; @@ -5077,11 +4205,11 @@ if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) bra = *cc; cc++; } -private_data_ptr = PRIVATE_DATA(cc); -SLJIT_ASSERT(private_data_ptr != 0); +localptr = PRIV_DATA(cc); +SLJIT_ASSERT(localptr != 0); framesize = get_framesize(common, cc, FALSE); backtrack->framesize = framesize; -backtrack->private_data_ptr = private_data_ptr; +backtrack->localptr = localptr; opcode = *cc; SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT); found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target; @@ -5098,24 +4226,24 @@ if (bra == OP_BRAMINZERO) if (framesize < 0) { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); } else { allocate_stack(common, framesize + 2); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); init_frame(common, ccbegin, framesize + 1, 2, FALSE); } memset(&altbacktrack, 0, sizeof(backtrack_common)); -common->quitlabel = NULL; -common->quit = NULL; +common->leavelabel = NULL; +common->leave = NULL; while (1) { common->acceptlabel = NULL; @@ -5127,12 +4255,12 @@ while (1) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); altbacktrack.cc = ccbegin; - compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); + compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { - common->quitlabel = save_quitlabel; + common->leavelabel = save_leavelabel; common->acceptlabel = save_acceptlabel; - common->quit = save_quit; + common->leave = save_leave; common->accept = save_accept; return NULL; } @@ -5142,16 +4270,16 @@ while (1) /* Reset stack. */ if (framesize < 0) - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); else { if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional) { - /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); + /* We don't need to keep the STR_PTR, only the previous localptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w)); } else { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); } } @@ -5167,27 +4295,27 @@ while (1) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); else { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); } - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } else if (framesize >= 0) { /* For OP_BRA and OP_BRAMINZERO. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); } } add_jump(compiler, found, JUMP(SLJIT_JUMP)); - compile_backtrackingpath(common, altbacktrack.top); + compile_backtrackpath(common, altbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { - common->quitlabel = save_quitlabel; + common->leavelabel = save_leavelabel; common->acceptlabel = save_acceptlabel; - common->quit = save_quit; + common->leave = save_leave; common->accept = save_accept; return NULL; } @@ -5200,8 +4328,8 @@ while (1) cc += GET(cc, 1); } /* None of them matched. */ -if (common->quit != NULL) - set_jumps(common->quit, LABEL()); +if (common->leave != NULL) + set_jumps(common->leave, LABEL()); if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) { @@ -5228,7 +4356,7 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) } else free_stack(common, framesize + 2); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); } jump = JUMP(SLJIT_JUMP); if (bra != OP_BRAZERO) @@ -5242,10 +4370,10 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); /* Keep the STR_PTR on the top of the stack. */ if (bra == OP_BRAZERO) - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); else if (bra == OP_BRAMINZERO) { - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } } @@ -5253,14 +4381,14 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) { if (bra == OP_BRA) { - /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw)); + /* We don't need to keep the STR_PTR, only the previous localptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w)); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0); } else { - /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */ - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw)); + /* We don't need to keep the STR_PTR, only the previous localptr. */ + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w)); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0); } @@ -5268,18 +4396,18 @@ if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) if (bra == OP_BRAZERO) { - backtrack->matchingpath = LABEL(); - sljit_set_label(jump, backtrack->matchingpath); + backtrack->trypath = LABEL(); + sljit_set_label(jump, backtrack->trypath); } else if (bra == OP_BRAMINZERO) { - JUMPTO(SLJIT_JUMP, backtrack->matchingpath); + JUMPTO(SLJIT_JUMP, backtrack->trypath); JUMPHERE(brajump); if (framesize >= 0) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w)); } set_jumps(backtrack->common.topbacktracks, LABEL()); } @@ -5307,14 +4435,14 @@ else } else free_stack(common, framesize + 2); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); } if (bra == OP_BRAZERO) - backtrack->matchingpath = LABEL(); + backtrack->trypath = LABEL(); else if (bra == OP_BRAMINZERO) { - JUMPTO(SLJIT_JUMP, backtrack->matchingpath); + JUMPTO(SLJIT_JUMP, backtrack->trypath); JUMPHERE(brajump); } @@ -5326,21 +4454,21 @@ else } } -common->quitlabel = save_quitlabel; +common->leavelabel = save_leavelabel; common->acceptlabel = save_acceptlabel; -common->quit = save_quit; +common->leave = save_leave; common->accept = save_accept; return cc + 1 + LINK_SIZE; } -static sljit_sw SLJIT_CALL do_searchovector(sljit_uw refno, sljit_sw* locals, pcre_uchar *name_table) +static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table) { int condition = FALSE; pcre_uchar *slotA = name_table; pcre_uchar *slotB; -sljit_sw name_count = locals[LOCALS0 / sizeof(sljit_sw)]; -sljit_sw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)]; -sljit_sw no_capture; +sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)]; +sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)]; +sljit_w no_capture; int i; locals += refno & 0xff; @@ -5390,15 +4518,15 @@ if (i < name_count) return condition; } -static sljit_sw SLJIT_CALL do_searchgroups(sljit_uw recno, sljit_uw* locals, pcre_uchar *name_table) +static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table) { int condition = FALSE; pcre_uchar *slotA = name_table; pcre_uchar *slotB; -sljit_uw name_count = locals[LOCALS0 / sizeof(sljit_sw)]; -sljit_uw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)]; -sljit_uw group_num = locals[POSSESSIVE0 / sizeof(sljit_sw)]; -sljit_uw i; +sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)]; +sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)]; +sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)]; +int i; for (i = 0; i < name_count; i++) { @@ -5497,16 +4625,16 @@ return condition; Or nothing, if trace is unnecessary */ -static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; pcre_uchar opcode; -int private_data_ptr = 0; +int localptr = 0; int offset = 0; int stacksize; pcre_uchar *ccbegin; -pcre_uchar *matchingpath; +pcre_uchar *trypath; pcre_uchar bra = OP_BRA; pcre_uchar ket; assert_backtrack *assert; @@ -5527,7 +4655,7 @@ if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) opcode = *cc; ccbegin = cc; -matchingpath = ccbegin + 1 + LINK_SIZE; +trypath = ccbegin + 1 + LINK_SIZE; if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF) { @@ -5544,16 +4672,16 @@ cc += GET(cc, 1); has_alternatives = *cc == OP_ALT; if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) { - has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE; - if (*matchingpath == OP_NRREF) + has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE; + if (*trypath == OP_NRREF) { - stacksize = GET2(matchingpath, 1); + stacksize = GET2(trypath, 1); if (common->currententry == NULL || stacksize == RREF_ANY) has_alternatives = FALSE; else if (common->currententry->start == 0) has_alternatives = stacksize != 0; else - has_alternatives = stacksize != (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); + has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE); } } @@ -5566,25 +4694,17 @@ if (opcode == OP_CBRA || opcode == OP_SCBRA) { /* Capturing brackets has a pre-allocated space. */ offset = GET2(ccbegin, 1 + LINK_SIZE); - if (common->optimized_cbracket[offset] == 0) - { - private_data_ptr = OVECTOR_PRIV(offset); - offset <<= 1; - } - else - { - offset <<= 1; - private_data_ptr = OVECTOR(offset); - } - BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; - matchingpath += IMM2_SIZE; + localptr = OVECTOR_PRIV(offset); + offset <<= 1; + BACKTRACK_AS(bracket_backtrack)->localptr = localptr; + trypath += IMM2_SIZE; } else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND) { /* Other brackets simply allocate the next entry. */ - private_data_ptr = PRIVATE_DATA(ccbegin); - SLJIT_ASSERT(private_data_ptr != 0); - BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr; + localptr = PRIV_DATA(ccbegin); + SLJIT_ASSERT(localptr != 0); + BACKTRACK_AS(bracket_backtrack)->localptr = localptr; if (opcode == OP_ONCE) BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE); } @@ -5630,14 +4750,14 @@ if (bra == OP_BRAMINZERO) /* Checking zero-length iteration. */ if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) { - /* When we come from outside, private_data_ptr contains the previous STR_PTR. */ - braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + /* When we come from outside, localptr contains the previous STR_PTR. */ + braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); } else { /* Except when the whole stack frame must be saved. */ - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w)); } JUMPHERE(skip); } @@ -5651,13 +4771,13 @@ if (bra == OP_BRAMINZERO) } if (ket == OP_KETRMIN) - BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); + BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL(); if (ket == OP_KETRMAX) { rmaxlabel = LABEL(); if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA) - BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel; + BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel; } /* Handling capturing brackets and alternatives. */ @@ -5668,39 +4788,39 @@ if (opcode == OP_ONCE) /* Neither capturing brackets nor recursions are not found in the block. */ if (ket == OP_KETRMIN) { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); allocate_stack(common, 2); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); - OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); } else if (ket == OP_KETRMAX || has_alternatives) { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); } else - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); } else { if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) { allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE); } else { allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE); } @@ -5709,34 +4829,21 @@ if (opcode == OP_ONCE) else if (opcode == OP_CBRA || opcode == OP_SCBRA) { /* Saving the previous values. */ - if (common->optimized_cbracket[offset >> 1] == 0) - { - allocate_stack(common, 3); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); - } - else - { - SLJIT_ASSERT(private_data_ptr == OVECTOR(offset)); - allocate_stack(common, 2); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); - } + allocate_stack(common, 3); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0); } else if (opcode == OP_SBRA || opcode == OP_SCOND) { /* Saving the previous value. */ - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); allocate_stack(common, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); } else if (has_alternatives) @@ -5749,38 +4856,38 @@ else if (has_alternatives) /* Generating code for the first alternative. */ if (opcode == OP_COND || opcode == OP_SCOND) { - if (*matchingpath == OP_CREF) + if (*trypath == OP_CREF) { SLJIT_ASSERT(has_alternatives); add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), - CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); - matchingpath += 1 + IMM2_SIZE; + CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1))); + trypath += 1 + IMM2_SIZE; } - else if (*matchingpath == OP_NCREF) + else if (*trypath == OP_NCREF) { SLJIT_ASSERT(has_alternatives); - stacksize = GET2(matchingpath, 1); + stacksize = GET2(trypath, 1); jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); - OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw))); - GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0); - OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w))); + GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0)); + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); JUMPHERE(jump); - matchingpath += 1 + IMM2_SIZE; + trypath += 1 + IMM2_SIZE; } - else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF) + else if (*trypath == OP_RREF || *trypath == OP_NRREF) { /* Never has other case. */ BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL; - stacksize = GET2(matchingpath, 1); + stacksize = GET2(trypath, 1); if (common->currententry == NULL) stacksize = 0; else if (stacksize == RREF_ANY) @@ -5788,57 +4895,57 @@ if (opcode == OP_COND || opcode == OP_SCOND) else if (common->currententry->start == 0) stacksize = stacksize == 0; else - stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); + stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE); - if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL) + if (*trypath == OP_RREF || stacksize || common->currententry == NULL) { SLJIT_ASSERT(!has_alternatives); if (stacksize != 0) - matchingpath += 1 + IMM2_SIZE; + trypath += 1 + IMM2_SIZE; else { if (*cc == OP_ALT) { - matchingpath = cc + 1 + LINK_SIZE; + trypath = cc + 1 + LINK_SIZE; cc += GET(cc, 1); } else - matchingpath = cc; + trypath = cc; } } else { SLJIT_ASSERT(has_alternatives); - stacksize = GET2(matchingpath, 1); + stacksize = GET2(trypath, 1); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE)); - OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, stacksize); - GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0); - OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize); + GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0); + OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table); sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups)); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); - add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0)); - matchingpath += 1 + IMM2_SIZE; + add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0)); + trypath += 1 + IMM2_SIZE; } } else { - SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT); + SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT); /* Similar code as PUSH_BACKTRACK macro. */ assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack)); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; memset(assert, 0, sizeof(assert_backtrack)); - assert->common.cc = matchingpath; + assert->common.cc = trypath; BACKTRACK_AS(bracket_backtrack)->u.assert = assert; - matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE); + trypath = compile_assert_trypath(common, trypath, assert, TRUE); } } -compile_matchingpath(common, matchingpath, cc, backtrack); +compile_trypath(common, trypath, cc, backtrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; @@ -5846,20 +4953,20 @@ if (opcode == OP_ONCE) { if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); /* TMP2 which is set here used by OP_KETRMAX below. */ if (ket == OP_KETRMAX) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); else if (ket == OP_KETRMIN) { - /* Move the STR_PTR to the private_data_ptr. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0); + /* Move the STR_PTR to the localptr. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0); } } else { stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1; - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w)); if (ket == OP_KETRMAX) { /* TMP2 which is set here used by OP_KETRMAX below. */ @@ -5894,13 +5001,13 @@ if (has_alternatives) if (opcode != OP_ONCE) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0); if (ket != OP_KETRMAX) - BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); + BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL(); } -/* Must be after the matchingpath label. */ +/* Must be after the trypath label. */ if (offset != 0) { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); } @@ -5910,11 +5017,11 @@ if (ket == OP_KETRMAX) if (opcode == OP_ONCE || opcode >= OP_SBRA) { if (has_alternatives) - BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); + BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL(); /* Checking zero-length iteration. */ if (opcode != OP_ONCE) { - CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel); + CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel); /* Drop STR_PTR for greedy plus quantifier. */ if (bra != OP_BRAZERO) free_stack(common, 1); @@ -5925,16 +5032,16 @@ if (ket == OP_KETRMAX) } else JUMPTO(SLJIT_JUMP, rmaxlabel); - BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL(); + BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL(); } if (bra == OP_BRAZERO) - BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL(); + BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL(); if (bra == OP_BRAMINZERO) { /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */ - JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath); + JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath); if (braminzerojump != NULL) { JUMPHERE(braminzerojump); @@ -5943,7 +5050,7 @@ if (bra == OP_BRAMINZERO) framesize is < 0, OP_ONCE will do the release itself. */ if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); } else if (ket == OP_KETRMIN && opcode != OP_ONCE) @@ -5962,12 +5069,12 @@ cc += 1 + LINK_SIZE; return cc; } -static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; pcre_uchar opcode; -int private_data_ptr; +int localptr; int cbraprivptr = 0; int framesize; int stacksize; @@ -5986,9 +5093,9 @@ if (*cc == OP_BRAPOSZERO) } opcode = *cc; -private_data_ptr = PRIVATE_DATA(cc); -SLJIT_ASSERT(private_data_ptr != 0); -BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr; +localptr = PRIV_DATA(cc); +SLJIT_ASSERT(localptr != 0); +BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr; switch(opcode) { case OP_BRAPOS: @@ -5999,9 +5106,6 @@ switch(opcode) case OP_CBRAPOS: case OP_SCBRAPOS: offset = GET2(cc, 1 + LINK_SIZE); - /* This case cannot be optimized in the same was as - normal capturing brackets. */ - SLJIT_ASSERT(common->optimized_cbracket[offset] == 0); cbraprivptr = OVECTOR_PRIV(offset); offset <<= 1; ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE; @@ -6021,7 +5125,7 @@ if (framesize < 0) stacksize++; BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; allocate_stack(common, stacksize); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0); if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) { @@ -6046,9 +5150,9 @@ else BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize; allocate_stack(common, stacksize); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0); stack = 0; if (!zero) { @@ -6074,13 +5178,13 @@ while (*cc != OP_KETRPOS) backtrack->topbacktracks = NULL; cc += GET(cc, 1); - compile_matchingpath(common, ccbegin, cc, backtrack); + compile_trypath(common, ccbegin, cc, backtrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; if (framesize < 0) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) { @@ -6106,7 +5210,7 @@ while (*cc != OP_KETRPOS) { if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) { - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w)); OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0); @@ -6114,11 +5218,11 @@ while (*cc != OP_KETRPOS) } else { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w)); if (opcode == OP_SBRAPOS) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw)); - OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw), STR_PTR, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w)); + OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0); } if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS) @@ -6135,7 +5239,7 @@ while (*cc != OP_KETRPOS) JUMPTO(SLJIT_JUMP, loop); flush_stubs(common); - compile_backtrackingpath(common, backtrack->top); + compile_backtrackpath(common, backtrack->top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return NULL; set_jumps(backtrack->topbacktracks, LABEL()); @@ -6153,13 +5257,13 @@ while (*cc != OP_KETRPOS) { /* Last alternative. */ if (*cc == OP_KETRPOS) - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr); } else { - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_sw)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w)); } } @@ -6173,8 +5277,8 @@ if (!zero) { if (framesize < 0) add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0)); - else /* TMP2 is set to [private_data_ptr] above. */ - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_sw), SLJIT_IMM, 0)); + else /* TMP2 is set to [localptr] above. */ + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0)); } /* None of them matched. */ @@ -6275,7 +5379,7 @@ if (end != NULL) return cc; } -static pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; @@ -6286,55 +5390,11 @@ pcre_uchar* end; jump_list *nomatch = NULL; struct sljit_jump *jump = NULL; struct sljit_label *label; -int private_data_ptr = PRIVATE_DATA(cc); -int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG); -int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; -int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); -int tmp_base, tmp_offset; PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL); cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end); -switch (type) - { - case OP_NOT_DIGIT: - case OP_DIGIT: - case OP_NOT_WHITESPACE: - case OP_WHITESPACE: - case OP_NOT_WORDCHAR: - case OP_WORDCHAR: - case OP_ANY: - case OP_ALLANY: - case OP_ANYBYTE: - case OP_ANYNL: - case OP_NOT_HSPACE: - case OP_HSPACE: - case OP_NOT_VSPACE: - case OP_VSPACE: - case OP_CHAR: - case OP_CHARI: - case OP_NOT: - case OP_NOTI: - case OP_CLASS: - case OP_NCLASS: - tmp_base = TMP3; - tmp_offset = 0; - break; - - default: - SLJIT_ASSERT_STOP(); - /* Fall through. */ - - case OP_EXTUNI: - case OP_XCLASS: - case OP_NOTPROP: - case OP_PROP: - tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG); - tmp_offset = POSSESSIVE0; - break; - } - switch(opcode) { case OP_STAR: @@ -6343,7 +5403,6 @@ switch(opcode) case OP_CRRANGE: if (type == OP_ANYNL || type == OP_EXTUNI) { - SLJIT_ASSERT(private_data_ptr == 0); if (opcode == OP_STAR || opcode == OP_UPTO) { allocate_stack(common, 2); @@ -6355,12 +5414,11 @@ switch(opcode) allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); } - if (opcode == OP_UPTO || opcode == OP_CRRANGE) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); + compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); if (opcode == OP_UPTO || opcode == OP_CRRANGE) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); @@ -6372,7 +5430,6 @@ switch(opcode) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); } - /* We cannot use TMP3 because of this allocate_stack. */ allocate_stack(common, 1); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); JUMPTO(SLJIT_JUMP, label); @@ -6382,106 +5439,105 @@ switch(opcode) else { if (opcode == OP_PLUS) - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); - if (private_data_ptr == 0) - allocate_stack(common, 2); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (opcode <= OP_PLUS) - OP1(SLJIT_MOV, base, offset1, STR_PTR, 0); - else - OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1); + compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &nomatch); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - if (opcode <= OP_PLUS) - JUMPTO(SLJIT_JUMP, label); - else if (opcode == OP_CRRANGE && arg1 == 0) + compile_char1_trypath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0)) { - OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1); + OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); JUMPTO(SLJIT_JUMP, label); } else { - OP1(SLJIT_MOV, TMP1, 0, base, offset1); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV, base, offset1, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); } set_jumps(nomatch, LABEL()); if (opcode == OP_CRRANGE) - add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1)); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); } - BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); break; case OP_MINSTAR: case OP_MINPLUS: if (opcode == OP_MINPLUS) - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); - if (private_data_ptr == 0) - allocate_stack(common, 1); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); break; case OP_MINUPTO: case OP_CRMINRANGE: - if (private_data_ptr == 0) - allocate_stack(common, 2); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1); + allocate_stack(common, 2); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1); if (opcode == OP_CRMINRANGE) add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); - BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); break; case OP_QUERY: case OP_MINQUERY: - if (private_data_ptr == 0) - allocate_stack(common, 1); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + allocate_stack(common, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); if (opcode == OP_QUERY) - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); - BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL(); + compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); + BACKTRACK_AS(iterator_backtrack)->trypath = LABEL(); break; case OP_EXACT: - OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); - OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1); - JUMPTO(SLJIT_C_NOT_ZERO, label); + compile_char1_trypath(common, type, cc, &backtrack->topbacktracks); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); break; case OP_POSSTAR: case OP_POSPLUS: case OP_POSUPTO: - if (opcode == OP_POSPLUS) - compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks); - if (opcode == OP_POSUPTO) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1); - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + if (opcode != OP_POSSTAR) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); label = LABEL(); - compile_char1_matchingpath(common, type, cc, &nomatch); - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + compile_char1_trypath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); if (opcode != OP_POSUPTO) + { + if (opcode == OP_POSPLUS) + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2); JUMPTO(SLJIT_JUMP, label); + } else { - OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1); - JUMPTO(SLJIT_C_NOT_ZERO, label); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label); } set_jumps(nomatch, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); + if (opcode == OP_POSPLUS) + add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2)); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); break; case OP_POSQUERY: - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); - compile_char1_matchingpath(common, type, cc, &nomatch); - OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); + compile_char1_trypath(common, type, cc, &nomatch); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0); set_jumps(nomatch, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1); break; default: @@ -6493,7 +5549,7 @@ decrease_call_count(common); return end; } -static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) +static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; @@ -6537,26 +5593,23 @@ add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP)); return cc + 1; } -static SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc) +static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc) { DEFINE_COMPILER; int offset = GET2(cc, 1); -BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0; /* Data will be discarded anyway... */ if (common->currententry != NULL) return cc + 1 + IMM2_SIZE; -if (!optimized_cbracket) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset)); +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset)); offset <<= 1; OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); -if (!optimized_cbracket) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); return cc + 1 + IMM2_SIZE; } -static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) +static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent) { DEFINE_COMPILER; backtrack_common *backtrack; @@ -6595,7 +5648,7 @@ while (cc < ccend) case OP_NOT: case OP_NOTI: case OP_REVERSE: - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); break; case OP_SET_SOM: @@ -6610,9 +5663,9 @@ while (cc < ccend) case OP_CHAR: case OP_CHARI: if (common->mode == JIT_COMPILE) - cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); break; case OP_STAR: @@ -6680,36 +5733,36 @@ while (cc < ccend) case OP_TYPEPOSPLUS: case OP_TYPEPOSQUERY: case OP_TYPEPOSUPTO: - cc = compile_iterator_matchingpath(common, cc, parent); + cc = compile_iterator_trypath(common, cc, parent); break; case OP_CLASS: case OP_NCLASS: if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE) - cc = compile_iterator_matchingpath(common, cc, parent); + cc = compile_iterator_trypath(common, cc, parent); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); break; -#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#if defined SUPPORT_UTF || defined COMPILE_PCRE16 case OP_XCLASS: if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE) - cc = compile_iterator_matchingpath(common, cc, parent); + cc = compile_iterator_trypath(common, cc, parent); else - cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); + cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks); break; #endif case OP_REF: case OP_REFI: if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE) - cc = compile_ref_iterator_matchingpath(common, cc, parent); + cc = compile_ref_iterator_trypath(common, cc, parent); else - cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); + cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE); break; case OP_RECURSE: - cc = compile_recurse_matchingpath(common, cc, parent); + cc = compile_recurse_trypath(common, cc, parent); break; case OP_ASSERT: @@ -6717,7 +5770,7 @@ while (cc < ccend) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); - cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); + cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); break; case OP_BRAMINZERO: @@ -6734,7 +5787,7 @@ while (cc < ccend) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0); } - BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL(); + BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL(); if (cc[1] > OP_ASSERTBACK_NOT) decrease_call_count(common); break; @@ -6747,16 +5800,16 @@ while (cc < ccend) case OP_SBRA: case OP_SCBRA: case OP_SCOND: - cc = compile_bracket_matchingpath(common, cc, parent); + cc = compile_bracket_trypath(common, cc, parent); break; case OP_BRAZERO: if (cc[1] > OP_ASSERTBACK_NOT) - cc = compile_bracket_matchingpath(common, cc, parent); + cc = compile_bracket_trypath(common, cc, parent); else { PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc); - cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); + cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE); } break; @@ -6765,7 +5818,7 @@ while (cc < ccend) case OP_SBRAPOS: case OP_SCBRAPOS: case OP_BRAPOSZERO: - cc = compile_bracketpos_matchingpath(common, cc, parent); + cc = compile_bracketpos_trypath(common, cc, parent); break; case OP_MARK: @@ -6775,7 +5828,7 @@ while (cc < ccend) allocate_stack(common, 1); OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2)); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0); OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0); cc += 1 + 2 + cc[1]; @@ -6789,11 +5842,11 @@ while (cc < ccend) case OP_FAIL: case OP_ACCEPT: case OP_ASSERT_ACCEPT: - cc = compile_fail_accept_matchingpath(common, cc, parent); + cc = compile_fail_accept_trypath(common, cc, parent); break; case OP_CLOSE: - cc = compile_close_matchingpath(common, cc); + cc = compile_close_trypath(common, cc); break; case OP_SKIPZERO: @@ -6814,10 +5867,10 @@ SLJIT_ASSERT(cc == ccend); #undef PUSH_BACKTRACK_NOVALUE #undef BACKTRACK_AS -#define COMPILE_BACKTRACKINGPATH(current) \ +#define COMPILE_BACKTRACKPATH(current) \ do \ { \ - compile_backtrackingpath(common, (current)); \ + compile_backtrackpath(common, (current)); \ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \ return; \ } \ @@ -6825,7 +5878,7 @@ SLJIT_ASSERT(cc == ccend); #define CURRENT_AS(type) ((type *)current) -static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; pcre_uchar *cc = current->cc; @@ -6835,10 +5888,6 @@ int arg1 = -1, arg2 = -1; struct sljit_label *label = NULL; struct sljit_jump *jump = NULL; jump_list *jumplist = NULL; -int private_data_ptr = PRIVATE_DATA(cc); -int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG); -int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr; -int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw); cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL); @@ -6850,36 +5899,26 @@ switch(opcode) case OP_CRRANGE: if (type == OP_ANYNL || type == OP_EXTUNI) { - SLJIT_ASSERT(private_data_ptr == 0); set_jumps(current->topbacktracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); - CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); } else { - if (opcode == OP_UPTO) + if (opcode <= OP_PLUS || opcode == OP_UPTO) arg2 = 0; - if (opcode <= OP_PLUS) - { - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - jump = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, base, offset1); - } - else - { - OP1(SLJIT_MOV, TMP1, 0, base, offset1); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1); - OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1); - } + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1); + OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, SLJIT_IMM, 1); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); skip_char_back(common); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); if (opcode == OP_CRRANGE) set_jumps(current->topbacktracks, LABEL()); JUMPHERE(jump); - if (private_data_ptr == 0) - free_stack(common, 2); + free_stack(common, 2); if (opcode == OP_PLUS) set_jumps(current->topbacktracks, LABEL()); } @@ -6887,13 +5926,12 @@ switch(opcode) case OP_MINSTAR: case OP_MINPLUS: - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - compile_char1_matchingpath(common, type, cc, &jumplist); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + compile_char1_trypath(common, type, cc, &jumplist); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); set_jumps(jumplist, LABEL()); - if (private_data_ptr == 0) - free_stack(common, 1); + free_stack(common, 1); if (opcode == OP_MINPLUS) set_jumps(current->topbacktracks, LABEL()); break; @@ -6905,51 +5943,48 @@ switch(opcode) label = LABEL(); set_jumps(current->topbacktracks, label); } - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - compile_char1_matchingpath(common, type, cc, &jumplist); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + compile_char1_trypath(common, type, cc, &jumplist); - OP1(SLJIT_MOV, TMP1, 0, base, offset1); - OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV, base, offset1, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0); if (opcode == OP_CRMINRANGE) CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label); if (opcode == OP_CRMINRANGE && arg1 == 0) - JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); else - CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->matchingpath); + CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath); set_jumps(jumplist, LABEL()); - if (private_data_ptr == 0) - free_stack(common, 2); + free_stack(common, 2); break; case OP_QUERY: - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); jump = JUMP(SLJIT_JUMP); set_jumps(current->topbacktracks, LABEL()); - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); JUMPHERE(jump); - if (private_data_ptr == 0) - free_stack(common, 1); + free_stack(common, 1); break; case OP_MINQUERY: - OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); - OP1(SLJIT_MOV, base, offset0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - compile_char1_matchingpath(common, type, cc, &jumplist); - JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath); + compile_char1_trypath(common, type, cc, &jumplist); + JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath); set_jumps(jumplist, LABEL()); JUMPHERE(jump); - if (private_data_ptr == 0) - free_stack(common, 1); + free_stack(common, 1); break; case OP_EXACT: @@ -6968,7 +6003,7 @@ switch(opcode) } } -static void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; pcre_uchar *cc = current->cc; @@ -6980,17 +6015,17 @@ if ((type & 0x1) == 0) set_jumps(current->topbacktracks, LABEL()); OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); - CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); return; } OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); -CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath); +CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath); set_jumps(current->topbacktracks, LABEL()); free_stack(common, 2); } -static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; @@ -7012,7 +6047,7 @@ else if (common->has_set_som || common->mark_ptr != 0) } } -static void compile_assert_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; pcre_uchar *cc = current->cc; @@ -7039,7 +6074,7 @@ if (CURRENT_AS(assert_backtrack)->framesize < 0) if (bra == OP_BRAZERO) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath); free_stack(common, 1); } return; @@ -7050,7 +6085,7 @@ if (bra == OP_BRAZERO) if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT) { OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->matchingpath); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath); free_stack(common, 1); return; } @@ -7060,9 +6095,9 @@ if (bra == OP_BRAZERO) if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->private_data_ptr); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w)); set_jumps(current->topbacktracks, LABEL()); } @@ -7072,19 +6107,19 @@ else if (bra == OP_BRAZERO) { /* We know there is enough place on the stack. */ - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0); - JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->matchingpath); + JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath); JUMPHERE(brajump); } } -static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; int opcode; int offset = 0; -int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr; +int localptr = CURRENT_AS(bracket_backtrack)->localptr; int stacksize; int count; pcre_uchar *cc = current->cc; @@ -7139,17 +6174,17 @@ else if (ket == OP_KETRMIN) { /* Checking zero-length iteration. */ if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0) - CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath); else { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); - CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath); } if (opcode != OP_ONCE) free_stack(common, 1); } else - JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath); } rminlabel = LABEL(); } @@ -7164,7 +6199,7 @@ if (SLJIT_UNLIKELY(opcode == OP_ONCE)) { if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); } once = JUMP(SLJIT_JUMP); @@ -7217,7 +6252,7 @@ else if (*cc == OP_ALT) cc = ccbegin + GET(ccbegin, 1); } -COMPILE_BACKTRACKINGPATH(current->top); +COMPILE_BACKTRACKPATH(current->top); if (current->topbacktracks) set_jumps(current->topbacktracks, LABEL()); @@ -7230,9 +6265,9 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)) assert = CURRENT_AS(bracket_backtrack)->u.assert; if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK)) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); } cond = JUMP(SLJIT_JUMP); set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL()); @@ -7261,35 +6296,35 @@ if (has_alternatives) cc += GET(cc, 1); if (opcode != OP_COND && opcode != OP_SCOND) { - if (private_data_ptr != 0 && opcode != OP_ONCE) - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + if (localptr != 0 && opcode != OP_ONCE) + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); else OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); } - compile_matchingpath(common, ccprev, cc, current); + compile_trypath(common, ccprev, cc, current); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return; } /* Instructions after the current alternative is succesfully matched. */ - /* There is a similar code in compile_bracket_matchingpath. */ + /* There is a similar code in compile_bracket_trypath. */ if (opcode == OP_ONCE) { if (CURRENT_AS(bracket_backtrack)->u.framesize < 0) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); /* TMP2 which is set here used by OP_KETRMAX below. */ if (ket == OP_KETRMAX) OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0); else if (ket == OP_KETRMIN) { - /* Move the STR_PTR to the private_data_ptr. */ - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0); + /* Move the STR_PTR to the localptr. */ + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0); } } else { - OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w)); if (ket == OP_KETRMAX) { /* TMP2 which is set here used by OP_KETRMAX below. */ @@ -7311,7 +6346,7 @@ if (has_alternatives) { /* We know we have place at least for one item on the top of the stack. */ SLJIT_ASSERT(stacksize == 1); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w)); } } @@ -7330,12 +6365,12 @@ if (has_alternatives) if (offset != 0) { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0); } - JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath); + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath); if (opcode != OP_ONCE) { @@ -7344,7 +6379,7 @@ if (has_alternatives) jumplist = jumplist->next; } - COMPILE_BACKTRACKINGPATH(current->top); + COMPILE_BACKTRACKPATH(current->top); if (current->topbacktracks) set_jumps(current->topbacktracks, LABEL()); SLJIT_ASSERT(!current->nextbacktracks); @@ -7359,43 +6394,31 @@ if (has_alternatives) if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0) { - OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr); + OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w)); } JUMPHERE(cond); } /* Free the STR_PTR. */ - if (private_data_ptr == 0) + if (localptr == 0) free_stack(common, 1); } if (offset != 0) { /* Using both tmp register is better for instruction scheduling. */ - if (common->optimized_cbracket[offset >> 1] == 0) - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2)); - free_stack(common, 3); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); - } - else - { - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - free_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); - } + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2)); + free_stack(common, 3); } else if (opcode == OP_SBRA || opcode == OP_SCOND) { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), STACK(0)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(0)); free_stack(common, 1); } else if (opcode == OP_ONCE) @@ -7414,15 +6437,15 @@ else if (opcode == OP_ONCE) } JUMPHERE(once); - /* Restore previous private_data_ptr */ + /* Restore previous localptr */ if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_sw)); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w)); else if (ket == OP_KETRMIN) { OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); /* See the comment below. */ free_stack(common, 2); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0); } } @@ -7431,11 +6454,11 @@ if (ket == OP_KETRMAX) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); if (bra != OP_BRAZERO) free_stack(common, 1); - CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath); + CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath); if (bra == OP_BRAZERO) { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath); + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath); JUMPHERE(brazero); free_stack(common, 1); } @@ -7458,12 +6481,12 @@ else if (ket == OP_KETRMIN) else if (bra == OP_BRAZERO) { OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zero_matchingpath); + JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath); JUMPHERE(brazero); } } -static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; int offset; @@ -7484,7 +6507,7 @@ if (CURRENT_AS(bracketpos_backtrack)->framesize < 0) return; } -OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr); +OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); if (current->topbacktracks) @@ -7495,10 +6518,10 @@ if (current->topbacktracks) free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize); JUMPHERE(jump); } -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw)); +OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w)); } -static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current) { assert_backtrack backtrack; @@ -7507,22 +6530,22 @@ current->topbacktracks = NULL; current->nextbacktracks = NULL; if (current->cc[1] > OP_ASSERTBACK_NOT) { - /* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */ - compile_bracket_matchingpath(common, current->cc, current); - compile_bracket_backtrackingpath(common, current->top); + /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */ + compile_bracket_trypath(common, current->cc, current); + compile_bracket_backtrackpath(common, current->top); } else { memset(&backtrack, 0, sizeof(backtrack)); backtrack.common.cc = current->cc; - backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath; - /* Manual call of compile_assert_matchingpath. */ - compile_assert_matchingpath(common, current->cc, &backtrack, FALSE); + backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath; + /* Manual call of compile_assert_trypath. */ + compile_assert_trypath(common, current->cc, &backtrack, FALSE); } SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks); } -static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current) +static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current) { DEFINE_COMPILER; @@ -7608,23 +6631,23 @@ while (current) #if defined SUPPORT_UTF || !defined COMPILE_PCRE8 case OP_XCLASS: #endif - compile_iterator_backtrackingpath(common, current); + compile_iterator_backtrackpath(common, current); break; case OP_REF: case OP_REFI: - compile_ref_iterator_backtrackingpath(common, current); + compile_ref_iterator_backtrackpath(common, current); break; case OP_RECURSE: - compile_recurse_backtrackingpath(common, current); + compile_recurse_backtrackpath(common, current); break; case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: - compile_assert_backtrackingpath(common, current); + compile_assert_backtrackpath(common, current); break; case OP_ONCE: @@ -7635,14 +6658,14 @@ while (current) case OP_SBRA: case OP_SCBRA: case OP_SCOND: - compile_bracket_backtrackingpath(common, current); + compile_bracket_backtrackpath(common, current); break; case OP_BRAZERO: if (current->cc[1] > OP_ASSERTBACK_NOT) - compile_bracket_backtrackingpath(common, current); + compile_bracket_backtrackpath(common, current); else - compile_assert_backtrackingpath(common, current); + compile_assert_backtrackpath(common, current); break; case OP_BRAPOS: @@ -7650,11 +6673,11 @@ while (current) case OP_SBRAPOS: case OP_SCBRAPOS: case OP_BRAPOSZERO: - compile_bracketpos_backtrackingpath(common, current); + compile_bracketpos_backtrackpath(common, current); break; case OP_BRAMINZERO: - compile_braminzero_backtrackingpath(common, current); + compile_braminzero_backtrackpath(common, current); break; case OP_MARK: @@ -7665,10 +6688,10 @@ while (current) case OP_COMMIT: OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); - if (common->quitlabel == NULL) - add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP)); + if (common->leavelabel == NULL) + add_jump(compiler, &common->leave, JUMP(SLJIT_JUMP)); else - JUMPTO(SLJIT_JUMP, common->quitlabel); + JUMPTO(SLJIT_JUMP, common->leavelabel); break; case OP_FAIL: @@ -7691,13 +6714,13 @@ DEFINE_COMPILER; pcre_uchar *cc = common->start + common->currententry->start; pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE); pcre_uchar *ccend = bracketend(cc); -int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend); +int localsize = get_localsize(common, ccbegin, ccend); int framesize = get_framesize(common, cc, TRUE); int alternativesize; BOOL needsframe; backtrack_common altbacktrack; -struct sljit_label *save_quitlabel = common->quitlabel; -jump_list *save_quit = common->quit; +struct sljit_label *save_leavelabel = common->leavelabel; +jump_list *save_leave = common->leave; struct sljit_jump *jump; SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS); @@ -7711,9 +6734,9 @@ common->currententry->entry = LABEL(); set_jumps(common->currententry->calls, common->currententry->entry); sljit_emit_fast_enter(compiler, TMP2, 0); -allocate_stack(common, private_data_size + framesize + alternativesize); -OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0); -copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize); +allocate_stack(common, localsize + framesize + alternativesize); +OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0); +copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0); if (needsframe) init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE); @@ -7722,9 +6745,9 @@ if (alternativesize > 0) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0); memset(&altbacktrack, 0, sizeof(backtrack_common)); -common->quitlabel = NULL; +common->leavelabel = NULL; common->acceptlabel = NULL; -common->quit = NULL; +common->leave = NULL; common->accept = NULL; altbacktrack.cc = ccbegin; cc += GET(cc, 1); @@ -7736,21 +6759,21 @@ while (1) if (altbacktrack.cc != ccbegin) OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0)); - compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack); + compile_trypath(common, altbacktrack.cc, cc, &altbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { - common->quitlabel = save_quitlabel; - common->quit = save_quit; + common->leavelabel = save_leavelabel; + common->leave = save_leave; return; } add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP)); - compile_backtrackingpath(common, altbacktrack.top); + compile_backtrackpath(common, altbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { - common->quitlabel = save_quitlabel; - common->quit = save_quit; + common->leavelabel = save_leavelabel; + common->leave = save_leave; return; } set_jumps(altbacktrack.topbacktracks, LABEL()); @@ -7762,8 +6785,8 @@ while (1) cc += GET(cc, 1); } /* None of them matched. */ -if (common->quit != NULL) - set_jumps(common->quit, LABEL()); +if (common->leave != NULL) + set_jumps(common->leave, LABEL()); OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); jump = JUMP(SLJIT_JUMP); @@ -7772,25 +6795,25 @@ set_jumps(common->accept, LABEL()); OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head); if (needsframe) { - OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); + OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw)); + OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w)); } OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); JUMPHERE(jump); -copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize); -free_stack(common, private_data_size + framesize + alternativesize); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw)); +copy_locals(common, ccbegin, ccend, FALSE, localsize + framesize + alternativesize, framesize + alternativesize); +free_stack(common, localsize + framesize + alternativesize); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w)); OP1(SLJIT_MOV, TMP1, 0, TMP3, 0); OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0); sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0); -common->quitlabel = save_quitlabel; -common->quit = save_quit; +common->leavelabel = save_leavelabel; +common->leave = save_leave; } -#undef COMPILE_BACKTRACKINGPATH +#undef COMPILE_BACKTRACKPATH #undef CURRENT_AS void @@ -7802,7 +6825,7 @@ compiler_common common_data; compiler_common *common = &common_data; const pcre_uint8 *tables = re->tables; pcre_study_data *study; -int private_data_size; +int localsize; pcre_uchar *ccend; executable_functions *functions; void *executable_func; @@ -7826,14 +6849,14 @@ rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * r common->start = rootbacktrack.cc; common->fcc = tables + fcc_offset; -common->lcc = (sljit_sw)(tables + lcc_offset); +common->lcc = (sljit_w)(tables + lcc_offset); common->mode = mode; common->nltype = NLTYPE_FIXED; switch(re->options & PCRE_NEWLINE_BITS) { case 0: /* Compile-time default */ - switch(NEWLINE) + switch (NEWLINE) { case -1: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; case -2: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; @@ -7861,14 +6884,13 @@ else #endif } common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; -common->ctypes = (sljit_sw)(tables + ctypes_offset); -common->digits[0] = -2; -common->name_table = (sljit_sw)((pcre_uchar *)re + re->name_table_offset); +common->ctypes = (sljit_w)(tables + ctypes_offset); +common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset); common->name_count = re->name_count; common->name_entry_size = re->name_entry_size; common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0; #ifdef SUPPORT_UTF -/* PCRE_UTF[16|32] have the same value as PCRE_UTF8. */ +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ common->utf = (re->options & PCRE_UTF8) != 0; #ifdef SUPPORT_UCP common->use_ucp = (re->options & PCRE_UCP) != 0; @@ -7877,79 +6899,65 @@ common->use_ucp = (re->options & PCRE_UCP) != 0; ccend = bracketend(rootbacktrack.cc); /* Calculate the local space size on the stack. */ -common->ovector_start = CALL_LIMIT + sizeof(sljit_sw); -common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1); -if (!common->optimized_cbracket) - return; -memset(common->optimized_cbracket, 1, re->top_bracket + 1); +common->ovector_start = CALL_LIMIT + sizeof(sljit_w); SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET); -private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend); -if (private_data_size < 0) - { - SLJIT_FREE(common->optimized_cbracket); +localsize = get_localspace(common, rootbacktrack.cc, ccend); +if (localsize < 0) return; - } /* Checking flags and updating ovector_start. */ if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0) { common->req_char_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); + common->ovector_start += sizeof(sljit_w); } if (mode != JIT_COMPILE) { common->start_used_ptr = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); + common->ovector_start += sizeof(sljit_w); if (mode == JIT_PARTIAL_SOFT_COMPILE) { common->hit_start = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); + common->ovector_start += sizeof(sljit_w); } } if ((re->options & PCRE_FIRSTLINE) != 0) { common->first_line_end = common->ovector_start; - common->ovector_start += sizeof(sljit_sw); + common->ovector_start += sizeof(sljit_w); } /* Aligning ovector to even number of sljit words. */ -if ((common->ovector_start & sizeof(sljit_sw)) != 0) - common->ovector_start += sizeof(sljit_sw); +if ((common->ovector_start & sizeof(sljit_w)) != 0) + common->ovector_start += sizeof(sljit_w); SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0)); -common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw); -private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw); -if (private_data_size > SLJIT_MAX_LOCAL_SIZE) - { - SLJIT_FREE(common->optimized_cbracket); +common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w); +localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w); +if (localsize > SLJIT_MAX_LOCAL_SIZE) return; - } -common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int)); -if (!common->private_data_ptrs) - { - SLJIT_FREE(common->optimized_cbracket); +common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int)); +if (!common->localptrs) return; - } -memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); -set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend); +memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int)); +set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend); compiler = sljit_create_compiler(); if (!compiler) { - SLJIT_FREE(common->optimized_cbracket); - SLJIT_FREE(common->private_data_ptrs); + SLJIT_FREE(common->localptrs); return; } common->compiler = compiler; /* Main pcre_jit_exec entry. */ -sljit_emit_enter(compiler, 1, 5, 5, private_data_size); +sljit_emit_enter(compiler, 1, 5, 5, localsize); /* Register init. */ reset_ovector(common, (re->top_bracket + 1) * 2); if (common->req_char_ptr != 0) - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_SCRATCH_REG1, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0); OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0); OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0); @@ -7971,9 +6979,7 @@ if ((re->options & PCRE_ANCHORED) == 0) /* Forward search if possible. */ if ((re->options & PCRE_NO_START_OPTIMIZE) == 0) { - if (mode == JIT_COMPILE && fast_forward_first_n_chars(common, (re->options & PCRE_FIRSTLINE) != 0)) - { /* Do nothing */ } - else if ((re->flags & PCRE_FIRSTSET) != 0) + if ((re->flags & PCRE_FIRSTSET) != 0) fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0); else if ((re->flags & PCRE_STARTLINE) != 0) fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0); @@ -8000,12 +7006,11 @@ if (mode == JIT_PARTIAL_SOFT_COMPILE) else if (mode == JIT_PARTIAL_HARD_COMPILE) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0); -compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack); +compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); - SLJIT_FREE(common->optimized_cbracket); - SLJIT_FREE(common->private_data_ptrs); + SLJIT_FREE(common->localptrs); return; } @@ -8018,25 +7023,24 @@ if (common->accept != NULL) /* This means we have a match. Update the ovector. */ copy_ovector(common, re->top_bracket + 1); -common->quitlabel = LABEL(); -if (common->quit != NULL) - set_jumps(common->quit, common->quitlabel); +common->leavelabel = LABEL(); +if (common->leave != NULL) + set_jumps(common->leave, common->leavelabel); sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0); if (mode != JIT_COMPILE) { common->partialmatchlabel = LABEL(); set_jumps(common->partialmatch, common->partialmatchlabel); - return_with_partial_match(common, common->quitlabel); + return_with_partial_match(common, common->leavelabel); } empty_match_backtrack = LABEL(); -compile_backtrackingpath(common, rootbacktrack.top); +compile_backtrackpath(common, rootbacktrack.top); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); - SLJIT_FREE(common->optimized_cbracket); - SLJIT_FREE(common->private_data_ptrs); + SLJIT_FREE(common->localptrs); return; } @@ -8074,9 +7078,9 @@ if ((re->options & PCRE_ANCHORED) == 0) { OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1)); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0); - OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER); + COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER); OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end); - OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL); + COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL); JUMPTO(SLJIT_C_ZERO, mainloop); } else @@ -8092,7 +7096,7 @@ if (mode == JIT_PARTIAL_SOFT_COMPILE) CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH); -JUMPTO(SLJIT_JUMP, common->quitlabel); +JUMPTO(SLJIT_JUMP, common->leavelabel); flush_stubs(common); @@ -8114,8 +7118,7 @@ while (common->currententry != NULL) if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) { sljit_free_compiler(compiler); - SLJIT_FREE(common->optimized_cbracket); - SLJIT_FREE(common->private_data_ptrs); + SLJIT_FREE(common->localptrs); return; } flush_stubs(common); @@ -8146,12 +7149,12 @@ sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0); JUMPHERE(jump); /* We break the return address cache here, but this is a really rare case. */ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT); -JUMPTO(SLJIT_JUMP, common->quitlabel); +JUMPTO(SLJIT_JUMP, common->leavelabel); /* Call limit reached. */ set_jumps(common->calllimit, LABEL()); OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT); -JUMPTO(SLJIT_JUMP, common->quitlabel); +JUMPTO(SLJIT_JUMP, common->leavelabel); if (common->revertframes != NULL) { @@ -8189,21 +7192,19 @@ if (common->caselesscmp != NULL) do_caselesscmp(common); } #ifdef SUPPORT_UTF -#ifndef COMPILE_PCRE32 if (common->utfreadchar != NULL) { set_jumps(common->utfreadchar, LABEL()); do_utfreadchar(common); } -#endif /* !COMPILE_PCRE32 */ #ifdef COMPILE_PCRE8 if (common->utfreadtype8 != NULL) { set_jumps(common->utfreadtype8, LABEL()); do_utfreadtype8(common); } +#endif #endif /* COMPILE_PCRE8 */ -#endif /* SUPPORT_UTF */ #ifdef SUPPORT_UCP if (common->getucd != NULL) { @@ -8212,8 +7213,7 @@ if (common->getucd != NULL) } #endif -SLJIT_FREE(common->optimized_cbracket); -SLJIT_FREE(common->private_data_ptrs); +SLJIT_FREE(common->localptrs); executable_func = sljit_generate_code(compiler); executable_size = sljit_get_generated_code_size(compiler); sljit_free_compiler(compiler); @@ -8225,15 +7225,6 @@ if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != functions = (executable_functions *)extra->executable_jit; else { - /* Note: If your memory-checker has flagged the allocation below as a - * memory leak, it is probably because you either forgot to call - * pcre_free_study() (or pcre16_free_study()) on the pcre_extra (or - * pcre16_extra) object, or you called said function after having - * cleared the PCRE_EXTRA_EXECUTABLE_JIT bit from the "flags" field - * of the object. (The function will only free the JIT data if the - * bit remains set, as the bit indicates that the pointer to the data - * is valid.) - */ functions = SLJIT_MALLOC(sizeof(executable_functions)); if (functions == NULL) { @@ -8243,7 +7234,6 @@ else return; } memset(functions, 0, sizeof(executable_functions)); - functions->top_bracket = (re->top_bracket + 1) * 2; extra->executable_jit = functions; extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT; } @@ -8258,12 +7248,12 @@ union { void* executable_func; jit_function call_executable_func; } convert_executable_func; -pcre_uint8 local_space[MACHINE_STACK_SIZE]; +pcre_uint8 local_area[LOCAL_SPACE_SIZE]; struct sljit_stack local_stack; -local_stack.top = (sljit_sw)&local_space; +local_stack.top = (sljit_w)&local_area; local_stack.base = local_stack.top; -local_stack.limit = local_stack.base + MACHINE_STACK_SIZE; +local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE; local_stack.max_limit = local_stack.limit; arguments->stack = &local_stack; convert_executable_func.executable_func = executable_func; @@ -8271,7 +7261,7 @@ return convert_executable_func.call_executable_func(arguments); } int -PRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject, +PRIV(jit_exec)(const REAL_PCRE *re, const PUBL(extra) *extra_data, const pcre_uchar *subject, int length, int start_offset, int options, int *offsets, int offsetcount) { executable_functions *functions = (executable_functions *)extra_data->executable_jit; @@ -8290,9 +7280,10 @@ else if ((options & PCRE_PARTIAL_SOFT) != 0) mode = JIT_PARTIAL_SOFT_COMPILE; if (functions->executable_funcs[mode] == NULL) - return PCRE_ERROR_JIT_BADOPTION; + return PCRE_ERROR_NULL; /* Sanity checks should be handled by pcre_exec. */ +arguments.stack = NULL; arguments.str = subject + start_offset; arguments.begin = subject; arguments.end = subject + length; @@ -8313,7 +7304,7 @@ gets the same result with and without JIT. */ if (offsetcount != 2) offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3; -maxoffsetcount = functions->top_bracket; +maxoffsetcount = (re->top_bracket + 1) * 2; if (offsetcount > maxoffsetcount) offsetcount = maxoffsetcount; arguments.offsetcount = offsetcount; @@ -8339,85 +7330,6 @@ if ((extra_data->flags & PCRE_EXTRA_MARK) != 0) return retval; } -#if defined COMPILE_PCRE8 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data, - PCRE_SPTR subject, int length, int start_offset, int options, - int *offsets, int offsetcount, pcre_jit_stack *stack) -#elif defined COMPILE_PCRE16 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data, - PCRE_SPTR16 subject, int length, int start_offset, int options, - int *offsets, int offsetcount, pcre16_jit_stack *stack) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data, - PCRE_SPTR32 subject, int length, int start_offset, int options, - int *offsets, int offsetcount, pcre32_jit_stack *stack) -#endif -{ -pcre_uchar *subject_ptr = (pcre_uchar *)subject; -executable_functions *functions = (executable_functions *)extra_data->executable_jit; -union { - void* executable_func; - jit_function call_executable_func; -} convert_executable_func; -jit_arguments arguments; -int maxoffsetcount; -int retval; -int mode = JIT_COMPILE; - -SLJIT_UNUSED_ARG(argument_re); - -/* Plausibility checks */ -if ((options & ~PUBLIC_JIT_EXEC_OPTIONS) != 0) return PCRE_ERROR_JIT_BADOPTION; - -if ((options & PCRE_PARTIAL_HARD) != 0) - mode = JIT_PARTIAL_HARD_COMPILE; -else if ((options & PCRE_PARTIAL_SOFT) != 0) - mode = JIT_PARTIAL_SOFT_COMPILE; - -if (functions->executable_funcs[mode] == NULL) - return PCRE_ERROR_JIT_BADOPTION; - -/* Sanity checks should be handled by pcre_exec. */ -arguments.stack = (struct sljit_stack *)stack; -arguments.str = subject_ptr + start_offset; -arguments.begin = subject_ptr; -arguments.end = subject_ptr + length; -arguments.mark_ptr = NULL; -/* JIT decreases this value less frequently than the interpreter. */ -arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit; -arguments.notbol = (options & PCRE_NOTBOL) != 0; -arguments.noteol = (options & PCRE_NOTEOL) != 0; -arguments.notempty = (options & PCRE_NOTEMPTY) != 0; -arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0; -arguments.offsets = offsets; - -/* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of -the output vector for storing captured strings, with the remainder used as -workspace. We don't need the workspace here. For compatibility, we limit the -number of captured strings in the same way as pcre_exec(), so that the user -gets the same result with and without JIT. */ - -if (offsetcount != 2) - offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3; -maxoffsetcount = functions->top_bracket; -if (offsetcount > maxoffsetcount) - offsetcount = maxoffsetcount; -arguments.offsetcount = offsetcount; - -convert_executable_func.executable_func = functions->executable_funcs[mode]; -retval = convert_executable_func.call_executable_func(&arguments); - -if (retval * 2 > offsetcount) - retval = 0; -if ((extra_data->flags & PCRE_EXTRA_MARK) != 0) - *(extra_data->mark) = arguments.mark_ptr; - -return retval; -} - void PRIV(jit_free)(void *executable_funcs) { @@ -8448,15 +7360,12 @@ PRIV(jit_get_target)(void) return sljit_get_platform_name(); } -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DECL pcre_jit_stack * pcre_jit_stack_alloc(int startsize, int maxsize) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DECL pcre16_jit_stack * pcre16_jit_stack_alloc(int startsize, int maxsize) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DECL pcre32_jit_stack * -pcre32_jit_stack_alloc(int startsize, int maxsize) #endif { if (startsize < 1 || maxsize < 1) @@ -8468,29 +7377,23 @@ maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1); return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize); } -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *stack) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *stack) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DECL void -pcre32_jit_stack_free(pcre32_jit_stack *stack) #endif { sljit_free_stack((struct sljit_stack *)stack); } -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DECL void -pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata) #endif { executable_functions *functions; @@ -8509,15 +7412,12 @@ if (extra != NULL && /* These are dummy functions to avoid linking errors when JIT support is not being compiled. */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DECL pcre_jit_stack * pcre_jit_stack_alloc(int startsize, int maxsize) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DECL pcre16_jit_stack * pcre16_jit_stack_alloc(int startsize, int maxsize) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DECL pcre32_jit_stack * -pcre32_jit_stack_alloc(int startsize, int maxsize) #endif { (void)startsize; @@ -8525,29 +7425,23 @@ pcre32_jit_stack_alloc(int startsize, int maxsize) return NULL; } -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DECL void pcre_jit_stack_free(pcre_jit_stack *stack) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DECL void pcre16_jit_stack_free(pcre16_jit_stack *stack) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DECL void -pcre32_jit_stack_free(pcre32_jit_stack *stack) #endif { (void)stack; } -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DECL void pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DECL void pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DECL void -pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_jit_callback callback, void *userdata) #endif { (void)extra; diff --git a/harbour/src/3rd/pcre/pcremktb.c b/harbour/src/3rd/pcre/pcremktb.c index a65f6a7034..8bb753907e 100644 --- a/harbour/src/3rd/pcre/pcremktb.c +++ b/harbour/src/3rd/pcre/pcremktb.c @@ -66,15 +66,12 @@ Arguments: none Returns: pointer to the contiguous block of data */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 const unsigned char * pcre_maketables(void) -#elif defined COMPILE_PCRE16 +#else const unsigned char * pcre16_maketables(void) -#elif defined COMPILE_PCRE32 -const unsigned char * -pcre32_maketables(void) #endif { unsigned char *yield, *p; @@ -130,7 +127,7 @@ within regexes. */ for (i = 0; i < 256; i++) { int x = 0; - if (i != CHAR_VT && isspace(i)) x += ctype_space; + if (i != 0x0b && isspace(i)) x += ctype_space; if (isalpha(i)) x += ctype_letter; if (isdigit(i)) x += ctype_digit; if (isxdigit(i)) x += ctype_xdigit; diff --git a/harbour/src/3rd/pcre/pcrenewl.c b/harbour/src/3rd/pcre/pcrenewl.c index fea6d9b46d..2c8b1ac8ef 100644 --- a/harbour/src/3rd/pcre/pcrenewl.c +++ b/harbour/src/3rd/pcre/pcrenewl.c @@ -76,7 +76,7 @@ BOOL PRIV(is_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR endptr, int *lenptr, BOOL utf) { -pcre_uint32 c; +int c; (void)utf; #ifdef SUPPORT_UTF if (utf) @@ -87,13 +87,11 @@ else #endif /* SUPPORT_UTF */ c = *ptr; -/* Note that this function is called only for ANY or ANYCRLF. */ - if (type == NLTYPE_ANYCRLF) switch(c) { - case CHAR_LF: *lenptr = 1; return TRUE; - case CHAR_CR: *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1; - return TRUE; + case 0x000a: *lenptr = 1; return TRUE; /* LF */ + case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1; + return TRUE; /* CR */ default: return FALSE; } @@ -101,29 +99,20 @@ if (type == NLTYPE_ANYCRLF) switch(c) else switch(c) { -#ifdef EBCDIC - case CHAR_NEL: -#endif - case CHAR_LF: - case CHAR_VT: - case CHAR_FF: *lenptr = 1; return TRUE; - - case CHAR_CR: - *lenptr = (ptr < endptr - 1 && ptr[1] == CHAR_LF)? 2 : 1; - return TRUE; - -#ifndef EBCDIC + case 0x000a: /* LF */ + case 0x000b: /* VT */ + case 0x000c: *lenptr = 1; return TRUE; /* FF */ + case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1; + return TRUE; /* CR */ #ifdef COMPILE_PCRE8 - case CHAR_NEL: *lenptr = utf? 2 : 1; return TRUE; + case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 3; return TRUE; /* PS */ -#else /* COMPILE_PCRE16 || COMPILE_PCRE32 */ - case CHAR_NEL: +#else + case 0x0085: /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 1; return TRUE; /* PS */ -#endif /* COMPILE_PCRE8 */ -#endif /* Not EBCDIC */ - +#endif /* COMPILE_PCRE8 */ default: return FALSE; } } @@ -151,7 +140,7 @@ BOOL PRIV(was_newline)(PCRE_PUCHAR ptr, int type, PCRE_PUCHAR startptr, int *lenptr, BOOL utf) { -pcre_uint32 c; +int c; (void)utf; ptr--; #ifdef SUPPORT_UTF @@ -164,45 +153,30 @@ else #endif /* SUPPORT_UTF */ c = *ptr; -/* Note that this function is called only for ANY or ANYCRLF. */ - if (type == NLTYPE_ANYCRLF) switch(c) { - case CHAR_LF: - *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1; - return TRUE; - - case CHAR_CR: *lenptr = 1; return TRUE; + case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1; + return TRUE; /* LF */ + case 0x000d: *lenptr = 1; return TRUE; /* CR */ default: return FALSE; } -/* NLTYPE_ANY */ - else switch(c) { - case CHAR_LF: - *lenptr = (ptr > startptr && ptr[-1] == CHAR_CR)? 2 : 1; - return TRUE; - -#ifdef EBCDIC - case CHAR_NEL: -#endif - case CHAR_VT: - case CHAR_FF: - case CHAR_CR: *lenptr = 1; return TRUE; - -#ifndef EBCDIC + case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1; + return TRUE; /* LF */ + case 0x000b: /* VT */ + case 0x000c: /* FF */ + case 0x000d: *lenptr = 1; return TRUE; /* CR */ #ifdef COMPILE_PCRE8 - case CHAR_NEL: *lenptr = utf? 2 : 1; return TRUE; - case 0x2028: /* LS */ - case 0x2029: *lenptr = 3; return TRUE; /* PS */ -#else /* COMPILE_PCRE16 || COMPILE_PCRE32 */ - case CHAR_NEL: + case 0x0085: *lenptr = utf? 2 : 1; return TRUE; /* NEL */ + case 0x2028: /* LS */ + case 0x2029: *lenptr = 3; return TRUE; /* PS */ +#else + case 0x0085: /* NEL */ case 0x2028: /* LS */ case 0x2029: *lenptr = 1; return TRUE; /* PS */ -#endif /* COMPILE_PCRE8 */ -#endif /* NotEBCDIC */ - +#endif /* COMPILE_PCRE8 */ default: return FALSE; } } diff --git a/harbour/src/3rd/pcre/pcreoutf.c b/harbour/src/3rd/pcre/pcreoutf.c index 0b7ec3f90b..a552557b93 100644 --- a/harbour/src/3rd/pcre/pcreoutf.c +++ b/harbour/src/3rd/pcre/pcreoutf.c @@ -45,16 +45,15 @@ character value into a UTF8 string. */ #include "config.h" #endif -#define COMPILE_PCRE8 - #include "pcreinal.h" + /************************************************* * Convert character value to UTF-8 * *************************************************/ /* This function takes an integer value in the range 0 - 0x10ffff -and encodes it as a UTF-8 character in 1 to 4 pcre_uchars. +and encodes it as a UTF-8 character in 1 to 6 pcre_uchars. Arguments: cvalue the character value @@ -63,7 +62,6 @@ Arguments: Returns: number of characters placed in the buffer */ -unsigned int PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer) { @@ -71,6 +69,11 @@ PRIV(ord2utf)(pcre_uint32 cvalue, pcre_uchar *buffer) register int i, j; +/* Checking invalid cvalue character, encoded as invalid UTF-16 character. +Should never happen in practice. */ +if ((cvalue & 0xf800) == 0xd800 || cvalue >= 0x110000) + cvalue = 0xfffe; + for (i = 0; i < PRIV(utf8_table1_size); i++) if ((int)cvalue <= PRIV(utf8_table1)[i]) break; buffer += i; diff --git a/harbour/src/3rd/pcre/pcreprni.c b/harbour/src/3rd/pcre/pcreprni.c index 9f21e37dad..3cb4a63b18 100644 --- a/harbour/src/3rd/pcre/pcreprni.c +++ b/harbour/src/3rd/pcre/pcreprni.c @@ -78,13 +78,10 @@ having a separate .h file just for this. */ #ifdef PCRE_INCLUDED static /* Keep the following function as private. */ #endif - -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths); -#elif defined COMPILE_PCRE16 +#else void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths); -#elif defined COMPILE_PCRE32 -void pcre32_printint(pcre *external_re, FILE *f, BOOL print_lengths); #endif /* Macro that decides whether a character should be output as a literal or in @@ -114,28 +111,26 @@ static const pcre_uint8 priv_OP_lengths[] = { OP_LENGTHS }; * Print single- or multi-byte character * *************************************************/ -static unsigned int +static int print_char(FILE *f, pcre_uchar *ptr, BOOL utf) { -pcre_uint32 c = *ptr; +int c = *ptr; #ifndef SUPPORT_UTF (void)utf; /* Avoid compiler warning */ -if (PRINTABLE(c)) fprintf(f, "%c", (char)c); -else if (c <= 0x80) fprintf(f, "\\x%02x", c); +if (PRINTABLE(c)) fprintf(f, "%c", c); +else if (c <= 0xff) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c); return 0; #else -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 if (!utf || (c & 0xc0) != 0xc0) { - if (PRINTABLE(c)) fprintf(f, "%c", (char)c); - else if (c < 0x80) fprintf(f, "\\x%02x", c); - else fprintf(f, "\\x{%02x}", c); + if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); return 0; } else @@ -165,13 +160,15 @@ else return a; } -#elif defined COMPILE_PCRE16 +#else + +#ifdef COMPILE_PCRE16 if (!utf || (c & 0xfc00) != 0xd800) { - if (PRINTABLE(c)) fprintf(f, "%c", (char)c); - else if (c <= 0x80) fprintf(f, "\\x%02x", c); - else fprintf(f, "\\x{%02x}", c); + if (PRINTABLE(c)) fprintf(f, "%c", c); + else if (c <= 0xff) fprintf(f, "\\x%02x", c); + else fprintf(f, "\\x{%x}", c); return 0; } else @@ -191,25 +188,9 @@ else return 1; } -#elif defined COMPILE_PCRE32 +#endif /* COMPILE_PCRE16 */ -if (!utf || (c & 0xfffff800u) != 0xd800u) - { - if (PRINTABLE(c)) fprintf(f, "%c", (char)c); - else if (c <= 0x80) fprintf(f, "\\x%02x", c); - else fprintf(f, "\\x{%x}", c); - return 0; - } -else - { - /* This is a check for malformed UTF-32; it should only occur if the sanity - check has been turned off. Rather than swallow a surrogate, just stop if - we hit one. Print it with \X instead of \x as an indication. */ - fprintf(f, "\\X{%x}", c); - return 0; - } - -#endif /* COMPILE_PCRE[8|16|32] */ +#endif /* COMPILE_PCRE8 */ #endif /* SUPPORT_UTF */ } @@ -223,7 +204,7 @@ print_puchar(FILE *f, PCRE_PUCHAR ptr) { while (*ptr != '\0') { - register pcre_uint32 c = *ptr++; + register int c = *ptr++; if (PRINTABLE(c)) fprintf(f, "%c", c); else fprintf(f, "\\x{%x}", c); } } @@ -233,7 +214,7 @@ while (*ptr != '\0') *************************************************/ static const char * -get_ucpname(unsigned int ptype, unsigned int pvalue) +get_ucpname(int ptype, int pvalue) { #ifdef SUPPORT_UCP int i; @@ -250,40 +231,6 @@ return (ptype == pvalue)? "??" : "??"; } -/************************************************* -* Print Unicode property value * -*************************************************/ - -/* "Normal" properties can be printed from tables. The PT_CLIST property is a -pseudo-property that contains a pointer to a list of case-equivalent -characters. This is used only when UCP support is available and UTF mode is -selected. It should never occur otherwise, but just in case it does, have -something ready to print. */ - -static void -print_prop(FILE *f, pcre_uchar *code, const char *before, const char *after) -{ -if (code[1] != PT_CLIST) - { - fprintf(f, "%s%s %s%s", before, priv_OP_names[*code], get_ucpname(code[1], - code[2]), after); - } -else - { - const char *not = (*code == OP_PROP)? "" : "not "; -#ifndef SUPPORT_UCP - fprintf(f, "%s%sclist %d%s", before, not, code[2], after); -#else - const pcre_uint32 *p = PRIV(ucd_caseless_sets) + code[2]; - fprintf (f, "%s%sclist", before, not); - while (*p < NOTACHAR) fprintf(f, " %04x", *p++); - fprintf(f, "%s", after); -#endif - } -} - - - /************************************************* * Print compiled regex * @@ -298,15 +245,12 @@ written that do not depend on the value of LINK_SIZE. */ #ifdef PCRE_INCLUDED static /* Keep the following function as private. */ #endif -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 void pcre_printint(pcre *external_re, FILE *f, BOOL print_lengths) -#elif defined COMPILE_PCRE16 +#else void pcre16_printint(pcre *external_re, FILE *f, BOOL print_lengths) -#elif defined COMPILE_PCRE32 -void -pcre32_printint(pcre *external_re, FILE *f, BOOL print_lengths) #endif { REAL_PCRE *re = (REAL_PCRE *)external_re; @@ -330,15 +274,15 @@ if (re->magic_number != MAGIC_NUMBER) } code = codestart = (pcre_uchar *)re + offset + count * size; -/* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */ +/* PCRE_UTF16 has the same value as PCRE_UTF8. */ utf = (options & PCRE_UTF8) != 0; for(;;) { pcre_uchar *ccode; const char *flag = " "; - pcre_uint32 c; - unsigned int extra = 0; + int c; + int extra = 0; if (print_lengths) fprintf(f, "%3d ", (int)(code - codestart)); @@ -481,12 +425,12 @@ for(;;) fprintf(f, " %s ", flag); if (*code >= OP_TYPESTAR) { + fprintf(f, "%s", priv_OP_names[code[1]]); if (code[1] == OP_PROP || code[1] == OP_NOTPROP) { - print_prop(f, code + 1, "", " "); + fprintf(f, " %s ", get_ucpname(code[2], code[3])); extra = 2; } - else fprintf(f, "%s", priv_OP_names[code[1]]); } else extra = print_char(f, code+1, utf); fprintf(f, "%s", priv_OP_names[*code]); @@ -515,12 +459,13 @@ for(;;) case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: + fprintf(f, " %s", priv_OP_names[code[1 + IMM2_SIZE]]); if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) { - print_prop(f, code + IMM2_SIZE + 1, " ", " "); + fprintf(f, " %s ", get_ucpname(code[1 + IMM2_SIZE + 1], + code[1 + IMM2_SIZE + 2])); extra = 2; } - else fprintf(f, " %s", priv_OP_names[code[1 + IMM2_SIZE]]); fprintf(f, "{"); if (*code != OP_TYPEEXACT) fprintf(f, "0,"); fprintf(f, "%d}", GET2(code,1)); @@ -605,7 +550,7 @@ for(;;) case OP_PROP: case OP_NOTPROP: - print_prop(f, code, " ", ""); + fprintf(f, " %s %s", priv_OP_names[*code], get_ucpname(code[1], code[2])); break; /* OP_XCLASS can only occur in UTF or PCRE16 modes. However, there's no @@ -616,8 +561,7 @@ for(;;) case OP_NCLASS: case OP_XCLASS: { - int i; - unsigned int min, max; + int i, min, max; BOOL printmap; pcre_uint8 *map; @@ -668,19 +612,19 @@ for(;;) if (*code == OP_XCLASS) { - pcre_uchar ch; + int ch; while ((ch = *ccode++) != XCL_END) { if (ch == XCL_PROP) { - unsigned int ptype = *ccode++; - unsigned int pvalue = *ccode++; + int ptype = *ccode++; + int pvalue = *ccode++; fprintf(f, "\\p{%s}", get_ucpname(ptype, pvalue)); } else if (ch == XCL_NOTPROP) { - unsigned int ptype = *ccode++; - unsigned int pvalue = *ccode++; + int ptype = *ccode++; + int pvalue = *ccode++; fprintf(f, "\\P{%s}", get_ucpname(ptype, pvalue)); } else @@ -718,8 +662,8 @@ for(;;) case OP_CRMINRANGE: min = GET2(ccode,1); max = GET2(ccode,1 + IMM2_SIZE); - if (max == 0) fprintf(f, "{%u,}", min); - else fprintf(f, "{%u,%u}", min, max); + if (max == 0) fprintf(f, "{%d,}", min); + else fprintf(f, "{%d,%d}", min, max); if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); extra += priv_OP_lengths[*ccode]; break; diff --git a/harbour/src/3rd/pcre/pcrerefc.c b/harbour/src/3rd/pcre/pcrerefc.c index 868a35bcaa..8a0f0c8e19 100644 --- a/harbour/src/3rd/pcre/pcrerefc.c +++ b/harbour/src/3rd/pcre/pcrerefc.c @@ -68,15 +68,12 @@ Returns: the (possibly updated) count value (a non-negative number), or a negative error number */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre_refcount(pcre *argument_re, int adjust) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN int PCRE_CALL_CONVENTION pcre16_refcount(pcre16 *argument_re, int adjust) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN int PCRE_CALL_CONVENTION -pcre32_refcount(pcre32 *argument_re, int adjust) #endif { REAL_PCRE *re = (REAL_PCRE *)argument_re; diff --git a/harbour/src/3rd/pcre/pcrestud.c b/harbour/src/3rd/pcre/pcrestud.c index 30bdd4c1da..3e196b90e3 100644 --- a/harbour/src/3rd/pcre/pcrestud.c +++ b/harbour/src/3rd/pcre/pcrestud.c @@ -98,7 +98,7 @@ for (;;) { int d, min; pcre_uchar *cs, *ce; - register pcre_uchar op = *cc; + register int op = *cc; switch (op) { @@ -323,19 +323,15 @@ for (;;) /* Check a class for variable quantification */ +#if defined SUPPORT_UTF || !defined COMPILE_PCRE8 + case OP_XCLASS: + cc += GET(cc, 1) - PRIV(OP_lengths)[OP_CLASS]; + /* Fall through */ +#endif + case OP_CLASS: case OP_NCLASS: -#if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - case OP_XCLASS: - /* The original code caused an unsigned overflow in 64 bit systems, - so now we use a conditional statement. */ - if (op == OP_XCLASS) - cc += GET(cc, 1); - else - cc += PRIV(OP_lengths)[OP_CLASS]; -#else cc += PRIV(OP_lengths)[OP_CLASS]; -#endif switch (*cc) { @@ -542,7 +538,7 @@ Arguments: p points to the character caseless the caseless flag cd the block with char table pointers - utf TRUE for UTF-8 / UTF-16 / UTF-32 mode + utf TRUE for UTF-8 / UTF-16 mode Returns: pointer after the character */ @@ -551,7 +547,7 @@ static const pcre_uchar * set_table_bit(pcre_uint8 *start_bits, const pcre_uchar *p, BOOL caseless, compile_data *cd, BOOL utf) { -pcre_uint32 c = *p; +unsigned int c = *p; #ifdef COMPILE_PCRE8 SET_BIT(c); @@ -568,20 +564,18 @@ if (utf && c > 127) (void)PRIV(ord2utf)(c, buff); SET_BIT(buff[0]); } -#endif /* Not SUPPORT_UCP */ +#endif return p; } -#else /* Not SUPPORT_UTF */ -(void)(utf); /* Stops warning for unused parameter */ -#endif /* SUPPORT_UTF */ +#endif /* Not UTF-8 mode, or character is less than 127. */ if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]); return p + 1; -#endif /* COMPILE_PCRE8 */ +#endif -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#ifdef COMPILE_PCRE16 if (c > 0xff) { c = 0xff; @@ -601,12 +595,10 @@ if (utf && c > 127) c = 0xff; SET_BIT(c); } -#endif /* SUPPORT_UCP */ +#endif return p; } -#else /* Not SUPPORT_UTF */ -(void)(utf); /* Stops warning for unused parameter */ -#endif /* SUPPORT_UTF */ +#endif if (caseless && (cd->ctypes[c] & ctype_letter) != 0) SET_BIT(cd->fcc[c]); return p + 1; @@ -636,10 +628,10 @@ Returns: nothing */ static void -set_type_bits(pcre_uint8 *start_bits, int cbit_type, unsigned int table_limit, +set_type_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit, compile_data *cd) { -register pcre_uint32 c; +register int c; for (c = 0; c < table_limit; c++) start_bits[c] |= cd->cbits[c+cbit_type]; #if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (table_limit == 32) return; @@ -678,10 +670,10 @@ Returns: nothing */ static void -set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, unsigned int table_limit, +set_nottype_bits(pcre_uint8 *start_bits, int cbit_type, int table_limit, compile_data *cd) { -register pcre_uint32 c; +register int c; for (c = 0; c < table_limit; c++) start_bits[c] |= ~cd->cbits[c+cbit_type]; #if defined SUPPORT_UTF && defined COMPILE_PCRE8 if (table_limit != 32) for (c = 24; c < 32; c++) start_bits[c] = 0xff; @@ -705,7 +697,7 @@ function fails unless the result is SSB_DONE. Arguments: code points to an expression start_bits points to a 32-byte table, initialized to 0 - utf TRUE if in UTF-8 / UTF-16 / UTF-32 mode + utf TRUE if in UTF-8 / UTF-16 mode cd the block with char table pointers Returns: SSB_FAIL => Failed to find any starting bytes @@ -718,7 +710,7 @@ static int set_start_bits(const pcre_uchar *code, pcre_uint8 *start_bits, BOOL utf, compile_data *cd) { -register pcre_uint32 c; +register int c; int yield = SSB_DONE; #if defined SUPPORT_UTF && defined COMPILE_PCRE8 int table_limit = utf? 16:32; @@ -994,8 +986,8 @@ do identical. */ case OP_HSPACE: - SET_BIT(CHAR_HT); - SET_BIT(CHAR_SPACE); + SET_BIT(0x09); + SET_BIT(0x20); #ifdef SUPPORT_UTF if (utf) { @@ -1004,46 +996,46 @@ do SET_BIT(0xE1); /* For U+1680, U+180E */ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ SET_BIT(0xE3); /* For U+3000 */ -#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#endif +#ifdef COMPILE_PCRE16 SET_BIT(0xA0); SET_BIT(0xFF); /* For characters > 255 */ -#endif /* COMPILE_PCRE[8|16|32] */ +#endif } else #endif /* SUPPORT_UTF */ { -#ifndef EBCDIC SET_BIT(0xA0); -#endif /* Not EBCDIC */ -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#ifdef COMPILE_PCRE16 SET_BIT(0xFF); /* For characters > 255 */ -#endif /* COMPILE_PCRE[16|32] */ +#endif } try_next = FALSE; break; case OP_ANYNL: case OP_VSPACE: - SET_BIT(CHAR_LF); - SET_BIT(CHAR_VT); - SET_BIT(CHAR_FF); - SET_BIT(CHAR_CR); + SET_BIT(0x0A); + SET_BIT(0x0B); + SET_BIT(0x0C); + SET_BIT(0x0D); #ifdef SUPPORT_UTF if (utf) { #ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+0085 */ SET_BIT(0xE2); /* For U+2028, U+2029 */ -#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - SET_BIT(CHAR_NEL); +#endif +#ifdef COMPILE_PCRE16 + SET_BIT(0x85); SET_BIT(0xFF); /* For characters > 255 */ -#endif /* COMPILE_PCRE[8|16|32] */ +#endif } else #endif /* SUPPORT_UTF */ { - SET_BIT(CHAR_NEL); -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 + SET_BIT(0x85); +#ifdef COMPILE_PCRE16 SET_BIT(0xFF); /* For characters > 255 */ #endif } @@ -1066,8 +1058,7 @@ do break; /* The cbit_space table has vertical tab as whitespace; we have to - ensure it is set as not whitespace. Luckily, the code value is the same - (0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate bit. */ + ensure it is set as not whitespace. */ case OP_NOT_WHITESPACE: set_nottype_bits(start_bits, cbit_space, table_limit, cd); @@ -1075,9 +1066,8 @@ do try_next = FALSE; break; - /* The cbit_space table has vertical tab as whitespace; we have to not - set it from the table. Luckily, the code value is the same (0x0b) in - ASCII and EBCDIC, so we can just adjust the appropriate bit. */ + /* The cbit_space table has vertical tab as whitespace; we have to + not set it from the table. */ case OP_WHITESPACE: c = start_bits[1]; /* Save in case it was already set */ @@ -1131,8 +1121,8 @@ do return SSB_FAIL; case OP_HSPACE: - SET_BIT(CHAR_HT); - SET_BIT(CHAR_SPACE); + SET_BIT(0x09); + SET_BIT(0x20); #ifdef SUPPORT_UTF if (utf) { @@ -1141,38 +1131,38 @@ do SET_BIT(0xE1); /* For U+1680, U+180E */ SET_BIT(0xE2); /* For U+2000 - U+200A, U+202F, U+205F */ SET_BIT(0xE3); /* For U+3000 */ -#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#endif +#ifdef COMPILE_PCRE16 SET_BIT(0xA0); SET_BIT(0xFF); /* For characters > 255 */ -#endif /* COMPILE_PCRE[8|16|32] */ +#endif } else #endif /* SUPPORT_UTF */ -#ifndef EBCDIC SET_BIT(0xA0); -#endif /* Not EBCDIC */ break; case OP_ANYNL: case OP_VSPACE: - SET_BIT(CHAR_LF); - SET_BIT(CHAR_VT); - SET_BIT(CHAR_FF); - SET_BIT(CHAR_CR); + SET_BIT(0x0A); + SET_BIT(0x0B); + SET_BIT(0x0C); + SET_BIT(0x0D); #ifdef SUPPORT_UTF if (utf) { #ifdef COMPILE_PCRE8 SET_BIT(0xC2); /* For U+0085 */ SET_BIT(0xE2); /* For U+2028, U+2029 */ -#elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32 - SET_BIT(CHAR_NEL); +#endif +#ifdef COMPILE_PCRE16 + SET_BIT(0x85); SET_BIT(0xFF); /* For characters > 255 */ -#endif /* COMPILE_PCRE16 */ +#endif } else #endif /* SUPPORT_UTF */ - SET_BIT(CHAR_NEL); + SET_BIT(0x85); break; case OP_NOT_DIGIT: @@ -1184,9 +1174,7 @@ do break; /* The cbit_space table has vertical tab as whitespace; we have to - ensure it gets set as not whitespace. Luckily, the code value is the - same (0x0b) in ASCII and EBCDIC, so we can just adjust the appropriate - bit. */ + ensure it gets set as not whitespace. */ case OP_NOT_WHITESPACE: set_nottype_bits(start_bits, cbit_space, table_limit, cd); @@ -1194,8 +1182,7 @@ do break; /* The cbit_space table has vertical tab as whitespace; we have to - avoid setting it. Luckily, the code value is the same (0x0b) in ASCII - and EBCDIC, so we can just adjust the appropriate bit. */ + avoid setting it. */ case OP_WHITESPACE: c = start_bits[1]; /* Save in case it was already set */ @@ -1229,7 +1216,7 @@ do memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ } #endif -#if defined COMPILE_PCRE16 || defined COMPILE_PCRE32 +#ifdef COMPILE_PCRE16 SET_BIT(0xFF); /* For characters > 255 */ #endif /* Fall through */ @@ -1325,15 +1312,12 @@ Returns: pointer to a pcre[16]_extra block, with study_data filled in and NULL on error or if no optimization possible */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION pcre_study(const pcre *external_re, int options, const char **errorptr) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN pcre16_extra * PCRE_CALL_CONVENTION pcre16_study(const pcre16 *external_re, int options, const char **errorptr) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN pcre32_extra * PCRE_CALL_CONVENTION -pcre32_study(const pcre32 *external_re, int options, const char **errorptr) #endif { int min; @@ -1356,12 +1340,10 @@ if (re == NULL || re->magic_number != MAGIC_NUMBER) if ((re->flags & PCRE_MODE) == 0) { -#if defined COMPILE_PCRE8 - *errorptr = "argument not compiled in 8 bit mode"; -#elif defined COMPILE_PCRE16 - *errorptr = "argument not compiled in 16 bit mode"; -#elif defined COMPILE_PCRE32 - *errorptr = "argument not compiled in 32 bit mode"; +#ifdef COMPILE_PCRE8 + *errorptr = "argument is compiled in 16 bit mode"; +#else + *errorptr = "argument is compiled in 8 bit mode"; #endif return NULL; } @@ -1388,18 +1370,14 @@ if ((re->options & PCRE_ANCHORED) == 0 && tables = re->tables; -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 if (tables == NULL) (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, (void *)(&tables)); -#elif defined COMPILE_PCRE16 +#else if (tables == NULL) (void)pcre16_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, (void *)(&tables)); -#elif defined COMPILE_PCRE32 - if (tables == NULL) - (void)pcre32_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, - (void *)(&tables)); #endif compile_block.lcc = tables + lcc_offset; @@ -1430,20 +1408,20 @@ switch(min = find_minlength(code, code, re->options, 0)) } /* If a set of starting bytes has been identified, or if the minimum length is -greater than zero, or if JIT optimization has been requested, or if -PCRE_STUDY_EXTRA_NEEDED is set, get a pcre[16]_extra block and a -pcre_study_data block. The study data is put in the latter, which is pointed to -by the former, which may also get additional data set later by the calling -program. At the moment, the size of pcre_study_data is fixed. We nevertheless -save it in a field for returning via the pcre_fullinfo() function so that if it -becomes variable in the future, we don't have to change that code. */ +greater than zero, or if JIT optimization has been requested, get a +pcre[16]_extra block and a pcre_study_data block. The study data is put in the +latter, which is pointed to by the former, which may also get additional data +set later by the calling program. At the moment, the size of pcre_study_data +is fixed. We nevertheless save it in a field for returning via the +pcre_fullinfo() function so that if it becomes variable in the future, +we don't have to change that code. */ -if (bits_set || min > 0 || (options & ( +if (bits_set || min > 0 #ifdef SUPPORT_JIT - PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE | - PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE | + || (options & (PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_JIT_PARTIAL_SOFT_COMPILE + | PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE)) != 0 #endif - PCRE_STUDY_EXTRA_NEEDED)) != 0) + ) { extra = (PUBL(extra) *)(PUBL(malloc)) (sizeof(PUBL(extra)) + sizeof(pcre_study_data)); @@ -1497,8 +1475,7 @@ if (bits_set || min > 0 || (options & ( /* If JIT support was compiled and requested, attempt the JIT compilation. If no starting bytes were found, and the minimum length is zero, and JIT - compilation fails, abandon the extra block and return NULL, unless - PCRE_STUDY_EXTRA_NEEDED is set. */ + compilation fails, abandon the extra block and return NULL. */ #ifdef SUPPORT_JIT extra->executable_jit = NULL; @@ -1509,15 +1486,13 @@ if (bits_set || min > 0 || (options & ( if ((options & PCRE_STUDY_JIT_PARTIAL_HARD_COMPILE) != 0) PRIV(jit_compile)(re, extra, JIT_PARTIAL_HARD_COMPILE); - if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0 && - (options & PCRE_STUDY_EXTRA_NEEDED) == 0) + if (study->flags == 0 && (extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) == 0) { -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 pcre_free_study(extra); -#elif defined COMPILE_PCRE16 +#endif +#ifdef COMPILE_PCRE16 pcre16_free_study(extra); -#elif defined COMPILE_PCRE32 - pcre32_free_study(extra); #endif extra = NULL; } @@ -1538,15 +1513,12 @@ Argument: a pointer to the pcre[16]_extra block Returns: nothing */ -#if defined COMPILE_PCRE8 +#ifdef COMPILE_PCRE8 PCRE_EXP_DEFN void pcre_free_study(pcre_extra *extra) -#elif defined COMPILE_PCRE16 +#else PCRE_EXP_DEFN void pcre16_free_study(pcre16_extra *extra) -#elif defined COMPILE_PCRE32 -PCRE_EXP_DEFN void -pcre32_free_study(pcre32_extra *extra) #endif { if (extra == NULL) diff --git a/harbour/src/3rd/pcre/pcretabs.c b/harbour/src/3rd/pcre/pcretabs.c index 5cea24bed5..212c65cf13 100644 --- a/harbour/src/3rd/pcre/pcretabs.c +++ b/harbour/src/3rd/pcre/pcretabs.c @@ -58,12 +58,6 @@ the definition is next to the definition of the opcodes in pcre_internal.h. */ const pcre_uint8 PRIV(OP_lengths)[] = { OP_LENGTHS }; -/* Tables of horizontal and vertical whitespace characters, suitable for -adding to classes. */ - -const pcre_uint32 PRIV(hspace_list)[] = { HSPACE_LIST }; -const pcre_uint32 PRIV(vspace_list)[] = { VSPACE_LIST }; - /************************************************* @@ -74,9 +68,9 @@ const pcre_uint32 PRIV(vspace_list)[] = { VSPACE_LIST }; character. */ #if (defined SUPPORT_UTF && defined COMPILE_PCRE8) \ - || (defined PCRE_INCLUDED && (defined SUPPORT_PCRE16 || defined SUPPORT_PCRE32)) + || (defined PCRE_INCLUDED && defined SUPPORT_PCRE16) -/* These tables are also required by pcretest in 16- or 32-bit mode. */ +/* These tables are also required by pcretest in 16 bit mode. */ const int PRIV(utf8_table1)[] = { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff}; @@ -98,13 +92,13 @@ const pcre_uint8 PRIV(utf8_table4)[] = { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; -#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE[16|32])*/ +#endif /* (SUPPORT_UTF && COMPILE_PCRE8) || (PCRE_INCLUDED && SUPPORT_PCRE16)*/ #ifdef SUPPORT_UTF /* Table to translate from particular type value to the general value. */ -const pcre_uint32 PRIV(ucp_gentype)[] = { +const int PRIV(ucp_gentype)[] = { ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */ ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */ ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */ @@ -115,66 +109,6 @@ const pcre_uint32 PRIV(ucp_gentype)[] = { ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */ }; -/* This table encodes the rules for finding the end of an extended grapheme -cluster. Every code point has a grapheme break property which is one of the -ucp_gbXX values defined in ucp.h. The 2-dimensional table is indexed by the -properties of two adjacent code points. The left property selects a word from -the table, and the right property selects a bit from that word like this: - - ucp_gbtable[left-property] & (1 << right-property) - -The value is non-zero if a grapheme break is NOT permitted between the relevant -two code points. The breaking rules are as follows: - -1. Break at the start and end of text (pretty obviously). - -2. Do not break between a CR and LF; otherwise, break before and after - controls. - -3. Do not break Hangul syllable sequences, the rules for which are: - - L may be followed by L, V, LV or LVT - LV or V may be followed by V or T - LVT or T may be followed by T - -4. Do not break before extending characters. - -The next two rules are only for extended grapheme clusters (but that's what we -are implementing). - -5. Do not break before SpacingMarks. - -6. Do not break after Prepend characters. - -7. Otherwise, break everywhere. -*/ - -const pcre_uint32 PRIV(ucp_gbtable[]) = { - (1< 0; p++) { - register pcre_uchar ab, c, d; - pcre_uint32 v = 0; + register int ab, c, d; c = *p; if (c < 128) continue; /* ASCII character */ @@ -187,7 +185,6 @@ for (p = string; length-- > 0; p++) *erroroffset = (int)(p - string) - 2; return PCRE_UTF8_ERR14; } - v = ((c & 0x0f) << 12) | ((d & 0x3f) << 6) | (*p & 0x3f); break; /* 4-byte character. Check 3rd and 4th bytes for 0x80. Then check first 2 @@ -215,7 +212,6 @@ for (p = string; length-- > 0; p++) *erroroffset = (int)(p - string) - 3; return PCRE_UTF8_ERR13; } - v = ((c & 0x07) << 18) | ((d & 0x3f) << 12) | ((p[-1] & 0x3f) << 6) | (*p & 0x3f); break; /* 5-byte and 6-byte characters are not allowed by RFC 3629, and will be @@ -290,20 +286,11 @@ for (p = string; length-- > 0; p++) *erroroffset = (int)(p - string) - ab; return (ab == 4)? PCRE_UTF8_ERR11 : PCRE_UTF8_ERR12; } - - /* Reject non-characters. The pointer p is currently at the last byte of the - character. */ - if ((v & 0xfffeu) == 0xfffeu || (v >= 0xfdd0 && v <= 0xfdef)) - { - *erroroffset = (int)(p - string) - ab; - return PCRE_UTF8_ERR22; - } } -#else /* Not SUPPORT_UTF */ +#else /* SUPPORT_UTF */ (void)(string); /* Keep picky compilers happy */ (void)(length); -(void)(erroroffset); #endif return PCRE_UTF8_ERR0; /* This indicates success */ diff --git a/harbour/src/3rd/pcre/pcrexcls.c b/harbour/src/3rd/pcre/pcrexcls.c index e101239249..dcd06ae3c6 100644 --- a/harbour/src/3rd/pcre/pcrexcls.c +++ b/harbour/src/3rd/pcre/pcrexcls.c @@ -64,9 +64,9 @@ Returns: TRUE if character matches, else FALSE */ BOOL -PRIV(xclass)(pcre_uint32 c, const pcre_uchar *data, BOOL utf) +PRIV(xclass)(int c, const pcre_uchar *data, BOOL utf) { -pcre_uchar t; +int t; BOOL negated = (*data & XCL_NOT) != 0; (void)utf; @@ -94,7 +94,7 @@ if ((*data++ & XCL_MAP) != 0) data += 32 / sizeof(pcre_uchar); while ((t = *data++) != XCL_END) { - pcre_uint32 x, y; + int x, y; if (t == XCL_SINGLE) { #ifdef SUPPORT_UTF diff --git a/harbour/src/3rd/pcre/sjarmth2.c b/harbour/src/3rd/pcre/sjarmth2.c index 0a60dc2a67..465c30d6ea 100644 --- a/harbour/src/3rd/pcre/sjarmth2.c +++ b/harbour/src/3rd/pcre/sjarmth2.c @@ -24,26 +24,23 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { return "ARM-Thumb2" SLJIT_CPUINFO; } -/* Length of an instruction word. */ -typedef sljit_ui sljit_ins; - /* Last register + 1. */ #define TMP_REG1 (SLJIT_NO_REGISTERS + 1) #define TMP_REG2 (SLJIT_NO_REGISTERS + 2) #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) #define TMP_PC (SLJIT_NO_REGISTERS + 4) -#define TMP_FREG1 (0) -#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1) +#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) +#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { - 0, 0, 1, 2, 12, 5, 6, 7, 8, 10, 11, 13, 3, 4, 14, 15 + 0, 0, 1, 2, 12, 5, 6, 7, 8, 10, 11, 13, 3, 4, 14, 15 }; #define COPY_BITS(src, from, to, bits) \ @@ -78,6 +75,8 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { #define IMM12(imm) \ (COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | (imm & 0xff)) +typedef sljit_ui sljit_ins; + /* --------------------------------------------------------------------- */ /* Instrucion forms */ /* --------------------------------------------------------------------- */ @@ -166,18 +165,18 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { #define UXTB_W 0xfa5ff080 #define UXTH 0xb280 #define UXTH_W 0xfa1ff080 -#define VABS_F32 0xeeb00ac0 -#define VADD_F32 0xee300a00 -#define VCMP_F32 0xeeb40a40 -#define VDIV_F32 0xee800a00 -#define VMOV_F32 0xeeb00a40 +#define VABS_F64 0xeeb00bc0 +#define VADD_F64 0xee300b00 +#define VCMP_F64 0xeeb40b40 +#define VDIV_F64 0xee800b00 +#define VMOV_F64 0xeeb00b40 #define VMRS 0xeef1fa10 -#define VMUL_F32 0xee200a00 -#define VNEG_F32 0xeeb10a40 -#define VSTR_F32 0xed000a00 -#define VSUB_F32 0xee300a40 +#define VMUL_F64 0xee200b00 +#define VNEG_F64 0xeeb10b40 +#define VSTR 0xed000b00 +#define VSUB_F64 0xee300b40 -static sljit_si push_inst16(struct sljit_compiler *compiler, sljit_ins inst) +static int push_inst16(struct sljit_compiler *compiler, sljit_ins inst) { sljit_uh *ptr; SLJIT_ASSERT(!(inst & 0xffff0000)); @@ -189,7 +188,7 @@ static sljit_si push_inst16(struct sljit_compiler *compiler, sljit_ins inst) return SLJIT_SUCCESS; } -static sljit_si push_inst32(struct sljit_compiler *compiler, sljit_ins inst) +static int push_inst32(struct sljit_compiler *compiler, sljit_ins inst) { sljit_uh *ptr = (sljit_uh*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -199,7 +198,7 @@ static sljit_si push_inst32(struct sljit_compiler *compiler, sljit_ins inst) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_imm32_const(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +static SLJIT_INLINE int emit_imm32_const(struct sljit_compiler *compiler, int 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))); @@ -209,7 +208,7 @@ static SLJIT_INLINE sljit_si emit_imm32_const(struct sljit_compiler *compiler, s static SLJIT_INLINE void modify_imm32_const(sljit_uh* inst, sljit_uw new_imm) { - sljit_si dst = inst[1] & 0x0f00; + int dst = inst[1] & 0x0f00; SLJIT_ASSERT(((inst[0] & 0xfbf0) == (MOVW >> 16)) && ((inst[2] & 0xfbf0) == (MOVT >> 16)) && dst == (inst[3] & 0x0f00)); inst[0] = (MOVW >> 16) | COPY_BITS(new_imm, 12, 0, 4) | COPY_BITS(new_imm, 11, 10, 1); inst[1] = dst | COPY_BITS(new_imm, 8, 12, 3) | (new_imm & 0xff); @@ -217,9 +216,9 @@ static SLJIT_INLINE void modify_imm32_const(sljit_uh* inst, sljit_uw new_imm) inst[3] = dst | COPY_BITS(new_imm, 8 + 16, 12, 3) | ((new_imm & 0xff0000) >> 16); } -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code) +static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uh *code_ptr, sljit_uh *code) { - sljit_sw diff; + sljit_w diff; if (jump->flags & SLJIT_REWRITABLE_JUMP) return 0; @@ -228,14 +227,14 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh /* Branch to ARM code is not optimized yet. */ if (!(jump->u.target & 0x1)) return 0; - diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2)) >> 1; + diff = ((sljit_w)jump->u.target - (sljit_w)(code_ptr + 2)) >> 1; } else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); - diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)) >> 1; + diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2)) >> 1; } - if (jump->flags & IS_COND) { + if (jump->flags & IS_CONDITIONAL) { SLJIT_ASSERT(!(jump->flags & IS_BL)); if (diff <= 127 && diff >= -128) { jump->flags |= B_TYPE1; @@ -272,7 +271,7 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uh return 0; } -static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_si flush) +static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, int flush) { sljit_uh* inst = (sljit_uh*)addr; modify_imm32_const(inst, new_addr); @@ -283,10 +282,10 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) { - sljit_si type = (jump->flags >> 4) & 0xf; - sljit_sw diff; + int type = (jump->flags >> 4) & 0xf; + sljit_w diff; sljit_uh *jump_inst; - sljit_si s, j1, j2; + int s, j1, j2; if (SLJIT_UNLIKELY(type == 0)) { inline_set_jump_addr(jump->addr, (jump->flags & JUMP_LABEL) ? jump->u.label->addr : jump->u.target, 0); @@ -295,33 +294,33 @@ static SLJIT_INLINE void set_jump_instruction(struct sljit_jump *jump) if (jump->flags & JUMP_ADDR) { SLJIT_ASSERT(jump->u.target & 0x1); - diff = ((sljit_sw)jump->u.target - (sljit_sw)(jump->addr + 4)) >> 1; + diff = ((sljit_w)jump->u.target - (sljit_w)(jump->addr + 4)) >> 1; } else - diff = ((sljit_sw)(jump->u.label->addr) - (sljit_sw)(jump->addr + 4)) >> 1; + diff = ((sljit_w)(jump->u.label->addr) - (sljit_w)(jump->addr + 4)) >> 1; jump_inst = (sljit_uh*)jump->addr; switch (type) { case 1: /* Encoding T1 of 'B' instruction */ - SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_COND)); + SLJIT_ASSERT(diff <= 127 && diff >= -128 && (jump->flags & IS_CONDITIONAL)); jump_inst[0] = 0xd000 | (jump->flags & 0xf00) | (diff & 0xff); return; case 2: /* Encoding T3 of 'B' instruction */ - SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_COND)); + SLJIT_ASSERT(diff <= 524287 && diff >= -524288 && (jump->flags & IS_CONDITIONAL)); jump_inst[0] = 0xf000 | COPY_BITS(jump->flags, 8, 6, 4) | COPY_BITS(diff, 11, 0, 6) | COPY_BITS(diff, 19, 10, 1); jump_inst[1] = 0x8000 | COPY_BITS(diff, 17, 13, 1) | COPY_BITS(diff, 18, 11, 1) | (diff & 0x7ff); return; case 3: - SLJIT_ASSERT(jump->flags & IS_COND); + SLJIT_ASSERT(jump->flags & IS_CONDITIONAL); *jump_inst++ = IT | ((jump->flags >> 4) & 0xf0) | 0x8; diff--; type = 5; break; case 4: /* Encoding T2 of 'B' instruction */ - SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_COND)); + SLJIT_ASSERT(diff <= 1023 && diff >= -1024 && !(jump->flags & IS_CONDITIONAL)); jump_inst[0] = 0xe000 | (diff & 0x7ff); return; } @@ -386,7 +385,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = label->next; } if (jump && jump->addr == half_count) { - jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8); + jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_CONDITIONAL) ? 10 : 8); code_ptr -= detect_jump_type(jump, code_ptr, code); jump = jump->next; } @@ -410,7 +409,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); - SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); + SLJIT_ASSERT(code_ptr - code <= (int)compiler->size); jump = compiler->jumps; while (jump) { @@ -429,7 +428,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil static sljit_uw get_imm(sljit_uw imm) { /* Thumb immediate form. */ - sljit_si counter; + int counter; if (imm <= 0xff) return imm; @@ -475,7 +474,7 @@ static sljit_uw get_imm(sljit_uw imm) return ((imm >> 24) & 0x7f) | COPY_BITS(counter, 4, 26, 1) | COPY_BITS(counter, 1, 12, 3) | COPY_BITS(counter, 0, 7, 1); } -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sljit_uw imm) +static int load_immediate(struct sljit_compiler *compiler, int dst, sljit_uw imm) { sljit_uw tmp; @@ -510,12 +509,12 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst, sl #define SLOW_SRC1 0x0800000 #define SLOW_SRC2 0x1000000 -static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, sljit_si dst, sljit_uw arg1, sljit_uw arg2) +static int emit_op_imm(struct sljit_compiler *compiler, int flags, int dst, sljit_uw arg1, sljit_uw arg2) { /* dst must be register, TMP_REG1 arg1 must be register, TMP_REG1, imm arg2 must be register, TMP_REG2, imm */ - sljit_si reg; + int reg; sljit_uw imm, negated_imm; if (SLJIT_UNLIKELY((flags & (ARG1_IMM | ARG2_IMM)) == (ARG1_IMM | ARG2_IMM))) { @@ -543,7 +542,7 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj /* No form with immediate operand. */ break; case SLJIT_ADD: - negated_imm = (sljit_uw)-(sljit_sw)imm; + negated_imm = (sljit_uw)-(sljit_w)imm; if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) { if (imm <= 0x7) return push_inst16(compiler, ADDSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); @@ -573,7 +572,7 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj break; case SLJIT_SUB: if (flags & ARG2_IMM) { - negated_imm = (sljit_uw)-(sljit_sw)imm; + negated_imm = (sljit_uw)-(sljit_w)imm; if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(reg, dst)) { if (imm <= 0x7) return push_inst16(compiler, SUBSI3 | IMM3(imm) | RD3(dst) | RN3(reg)); @@ -702,11 +701,9 @@ static sljit_si emit_op_imm(struct sljit_compiler *compiler, sljit_si flags, slj case SLJIT_MOV: case SLJIT_MOV_UI: case SLJIT_MOV_SI: - case SLJIT_MOV_P: case SLJIT_MOVU: case SLJIT_MOVU_UI: case SLJIT_MOVU_SI: - case SLJIT_MOVU_P: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); return push_inst16(compiler, MOV | SET_REGS44(dst, arg2)); case SLJIT_MOV_UB: @@ -888,7 +885,7 @@ static SLJIT_CONST sljit_uw sljit_mem32[12] = { }; /* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ -static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) +static int emit_set_delta(struct sljit_compiler *compiler, int dst, int reg, sljit_w value) { if (value >= 0) { if (value <= 0xfff) @@ -909,9 +906,9 @@ static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sl } /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw) { - sljit_si tmp; + int tmp; SLJIT_ASSERT(arg & SLJIT_MEM); @@ -994,7 +991,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, /* see getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) { /* Simple operation except for updates. */ if ((arg & 0xf0) || !(next_arg & SLJIT_MEM)) @@ -1016,10 +1013,10 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static int getput_arg(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw) { - sljit_si tmp_r; - sljit_sw tmp; + int tmp_r; + sljit_w tmp; SLJIT_ASSERT(arg & SLJIT_MEM); if (!(next_arg & SLJIT_MEM)) { @@ -1115,7 +1112,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji return push_inst32(compiler, sljit_mem32[flags] | MEM_IMM12 | RT4(reg) | RN4(TMP_REG3) | 0); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw) { if (getput_arg_fast(compiler, flags, reg, arg, argw)) return compiler->error; @@ -1124,26 +1121,15 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -/* --------------------------------------------------------------------- */ -/* Entry, exit */ -/* --------------------------------------------------------------------- */ - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) -{ - sljit_si size; + int size; sljit_ins push; CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -1160,7 +1146,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil push |= 1 << 7; if (saveds >= 1) push |= 1 << 6; - if (scratches >= 5) + if (temporaries >= 5) push |= 1 << 5; FAIL_IF(saveds >= 3 ? push_inst32(compiler, PUSH_W | (1 << 14) | push) @@ -1180,23 +1166,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil } if (args >= 1) - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG1, SLJIT_SCRATCH_REG1))); + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG1, SLJIT_TEMPORARY_REG1))); if (args >= 2) - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG2, SLJIT_TEMPORARY_REG2))); if (args >= 3) - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_SCRATCH_REG3))); + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(SLJIT_SAVED_REG3, SLJIT_TEMPORARY_REG3))); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { - sljit_si size; + int size; CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, scratches, saveds, local_size); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -1209,12 +1195,13 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, compiler->local_size = local_size; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { sljit_ins pop; CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); @@ -1236,7 +1223,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi pop |= 1 << 7; if (compiler->saveds >= 1) pop |= 1 << 6; - if (compiler->scratches >= 5) + if (compiler->temporaries >= 5) pop |= 1 << 5; return compiler->saveds >= 3 ? push_inst32(compiler, POP_W | (1 << 15) | pop) @@ -1252,8 +1239,8 @@ extern "C" { #endif #if defined(__GNUC__) -extern unsigned int __aeabi_uidivmod(unsigned int numerator, int unsigned denominator); -extern int __aeabi_idivmod(int numerator, int denominator); +extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator); +extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator); #else #error "Software divmod functions are needed" #endif @@ -1262,7 +1249,7 @@ extern int __aeabi_idivmod(int numerator, int denominator); } #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { CHECK_ERROR(); check_sljit_emit_op0(compiler, op); @@ -1278,16 +1265,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler case SLJIT_UMUL: case SLJIT_SMUL: return push_inst32(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) - | (reg_map[SLJIT_SCRATCH_REG2] << 8) - | (reg_map[SLJIT_SCRATCH_REG1] << 12) - | (reg_map[SLJIT_SCRATCH_REG1] << 16) - | reg_map[SLJIT_SCRATCH_REG2]); + | (reg_map[SLJIT_TEMPORARY_REG2] << 8) + | (reg_map[SLJIT_TEMPORARY_REG1] << 12) + | (reg_map[SLJIT_TEMPORARY_REG1] << 16) + | reg_map[SLJIT_TEMPORARY_REG2]); case SLJIT_UDIV: case SLJIT_SDIV: - if (compiler->scratches >= 4) { + if (compiler->temporaries >= 4) { FAIL_IF(push_inst32(compiler, 0xf84d2d04 /* str r2, [sp, #-4]! */)); FAIL_IF(push_inst32(compiler, 0xf84dcd04 /* str ip, [sp, #-4]! */)); - } else if (compiler->scratches >= 3) + } else if (compiler->temporaries >= 3) FAIL_IF(push_inst32(compiler, 0xf84d2d08 /* str r2, [sp, #-8]! */)); #if defined(__GNUC__) FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, @@ -1295,10 +1282,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #else #error "Software divmod functions are needed" #endif - if (compiler->scratches >= 4) { + if (compiler->temporaries >= 4) { FAIL_IF(push_inst32(compiler, 0xf85dcb04 /* ldr ip, [sp], #4 */)); return push_inst32(compiler, 0xf85d2b04 /* ldr r2, [sp], #4 */); - } else if (compiler->scratches >= 3) + } else if (compiler->temporaries >= 3) return push_inst32(compiler, 0xf85d2b08 /* ldr r2, [sp], #8 */); return SLJIT_SUCCESS; } @@ -1306,12 +1293,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_si dst_r, flags; - sljit_si op_flags = GET_ALL_FLAGS(op); + int op_type, dst_r, flags; CHECK_ERROR(); check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); @@ -1321,62 +1307,60 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler compiler->cache_arg = 0; compiler->cache_argw = 0; - dst_r = (dst >= SLJIT_SCRATCH_REG1 && dst <= TMP_REG3) ? dst : TMP_REG1; + op_type = GET_OPCODE(op); + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; - op = GET_OPCODE(op); - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { - switch (op) { + if (op_type >= SLJIT_MOV && op_type <= SLJIT_MOVU_SI) { + switch (op_type) { case SLJIT_MOV: case SLJIT_MOV_UI: case SLJIT_MOV_SI: - case SLJIT_MOV_P: flags = WORD_SIZE; break; case SLJIT_MOV_UB: flags = BYTE_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; + srcw = (unsigned char)srcw; break; case SLJIT_MOV_SB: flags = BYTE_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; + srcw = (signed char)srcw; break; case SLJIT_MOV_UH: flags = HALF_SIZE; if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; + srcw = (unsigned short)srcw; break; case SLJIT_MOV_SH: flags = HALF_SIZE | SIGNED; if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; + srcw = (signed short)srcw; break; case SLJIT_MOVU: case SLJIT_MOVU_UI: case SLJIT_MOVU_SI: - case SLJIT_MOVU_P: flags = WORD_SIZE | UPDATE; break; case SLJIT_MOVU_UB: flags = BYTE_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_ub)srcw; + srcw = (unsigned char)srcw; break; case SLJIT_MOVU_SB: flags = BYTE_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_sb)srcw; + srcw = (signed char)srcw; break; case SLJIT_MOVU_UH: flags = HALF_SIZE | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_uh)srcw; + srcw = (unsigned short)srcw; break; case SLJIT_MOVU_SH: flags = HALF_SIZE | SIGNED | UPDATE; if (src & SLJIT_IMM) - srcw = (sljit_sh)srcw; + srcw = (signed short)srcw; break; default: SLJIT_ASSERT_STOP(); @@ -1393,7 +1377,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw)); } else { if (dst_r != TMP_REG1) - return emit_op_imm(compiler, op, dst_r, TMP_REG1, src); + return emit_op_imm(compiler, op_type, dst_r, TMP_REG1, src); dst_r = src; } @@ -1406,14 +1390,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; } - if (op == SLJIT_NEG) { + if (op_type == SLJIT_NEG) { #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif - return sljit_emit_op2(compiler, SLJIT_SUB | op_flags, dst, dstw, SLJIT_IMM, 0, src, srcw); + return sljit_emit_op2(compiler, GET_FLAGS(op) | SLJIT_SUB, dst, dstw, SLJIT_IMM, 0, src, srcw); } - flags = (GET_FLAGS(op_flags) ? SET_FLAGS : 0) | ((op_flags & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); + flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); if (src & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG2, src, srcw)) FAIL_IF(compiler->error); @@ -1427,7 +1411,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler else srcw = src; - emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw); + emit_op_imm(compiler, flags | op_type, dst_r, TMP_REG1, srcw); if (dst & SLJIT_MEM) { if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw)) @@ -1438,12 +1422,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_si dst_r, flags; + int dst_r, flags; CHECK_ERROR(); check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); @@ -1454,7 +1438,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler compiler->cache_arg = 0; compiler->cache_argw = 0; - dst_r = (dst >= SLJIT_SCRATCH_REG1 && dst <= TMP_REG3) ? dst : TMP_REG1; + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; flags = (GET_FLAGS(op) ? SET_FLAGS : 0) | ((op & SLJIT_KEEP_FLAGS) ? KEEP_FLAGS : 0); if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, WORD_SIZE | STORE | ARG_TEST, TMP_REG1, dst, dstw)) @@ -1520,14 +1504,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { check_sljit_get_register_index(reg); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) { CHECK_ERROR(); check_sljit_emit_op_custom(compiler, instruction, size); @@ -1542,18 +1526,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { return 1; } -#define FPU_LOAD (1 << 20) - -static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static int emit_fop_mem(struct sljit_compiler *compiler, int flags, int reg, int arg, sljit_w argw) { - sljit_sw tmp; - sljit_uw imm; - sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); + sljit_w tmp; + sljit_w inst = VSTR | ((flags & STORE) ? 0 : 0x00100000); SLJIT_ASSERT(arg & SLJIT_MEM); @@ -1564,7 +1545,7 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl argw = 0; } - if ((arg & 0xf) && (argw & 0x3) == 0) { + if (arg & 0xf) { if (!(argw & ~0x3fc)) return push_inst32(compiler, inst | 0x800000 | RN4(arg & 0xf) | DD4(reg) | (argw >> 2)); if (!(-argw & ~0x3fc)) @@ -1585,29 +1566,13 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl } } - if (arg & 0xf) { - if (emit_set_delta(compiler, TMP_REG1, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg)); - } - imm = get_imm(argw & ~0x3fc); - if (imm != INVALID_IMM) { - FAIL_IF(push_inst32(compiler, ADD_WI | RD4(TMP_REG1) | RN4(arg & 0xf) | imm)); - return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2)); - } - imm = get_imm(-argw & ~0x3fc); - if (imm != INVALID_IMM) { - argw = -argw; - FAIL_IF(push_inst32(compiler, SUB_WI | RD4(TMP_REG1) | RN4(arg & 0xf) | imm)); - return push_inst32(compiler, inst | RN4(TMP_REG1) | DD4(reg) | ((argw & 0x3fc) >> 2)); - } - } - compiler->cache_arg = arg; compiler->cache_argw = argw; if (SLJIT_UNLIKELY(!(arg & 0xf))) FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + else if (emit_set_delta(compiler, TMP_REG3, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED) + FAIL_IF(compiler->error); else { FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); if (arg & 0xf) @@ -1616,137 +1581,129 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl return push_inst32(compiler, inst | 0x800000 | RN4(TMP_REG3) | DD4(reg)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_si dst_r; + int dst_r; CHECK_ERROR(); check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); compiler->cache_arg = 0; compiler->cache_argw = 0; - op ^= SLJIT_SINGLE_OP; - if (GET_OPCODE(op) == SLJIT_CMPD) { + if (GET_OPCODE(op) == SLJIT_FCMP) { if (dst & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, dst, dstw); + emit_fop_mem(compiler, 0, TMP_FREG1, dst, dstw); dst = TMP_FREG1; } if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src, srcw); + emit_fop_mem(compiler, 0, TMP_FREG2, src, srcw); src = TMP_FREG2; } - FAIL_IF(push_inst32(compiler, VCMP_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst) | DM4(src))); + FAIL_IF(push_inst32(compiler, VCMP_F64 | DD4(dst) | DM4(src))); return push_inst32(compiler, VMRS); } - dst_r = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst; + dst_r = (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? dst : TMP_FREG1; if (src & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_r, src, srcw); + emit_fop_mem(compiler, 0, dst_r, src, srcw); src = dst_r; } switch (GET_OPCODE(op)) { - case SLJIT_MOVD: + case SLJIT_FMOV: if (src != dst_r) - FAIL_IF(push_inst32(compiler, VMOV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + FAIL_IF(push_inst32(compiler, VMOV_F64 | DD4(dst_r) | DM4(src))); break; - case SLJIT_NEGD: - FAIL_IF(push_inst32(compiler, VNEG_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + case SLJIT_FNEG: + FAIL_IF(push_inst32(compiler, VNEG_F64 | DD4(dst_r) | DM4(src))); break; - case SLJIT_ABSD: - FAIL_IF(push_inst32(compiler, VABS_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DM4(src))); + case SLJIT_FABS: + FAIL_IF(push_inst32(compiler, VABS_F64 | DD4(dst_r) | DM4(src))); break; } if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, STORE, TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_si dst_r; + int dst_r; CHECK_ERROR(); check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); compiler->cache_arg = 0; compiler->cache_argw = 0; - op ^= SLJIT_SINGLE_OP; - dst_r = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst; + dst_r = (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? dst : TMP_FREG1; if (src1 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w); + emit_fop_mem(compiler, 0, TMP_FREG1, src1, src1w); src1 = TMP_FREG1; } if (src2 & SLJIT_MEM) { - emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w); + emit_fop_mem(compiler, 0, TMP_FREG2, src2, src2w); src2 = TMP_FREG2; } switch (GET_OPCODE(op)) { - case SLJIT_ADDD: - FAIL_IF(push_inst32(compiler, VADD_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_FADD: + FAIL_IF(push_inst32(compiler, VADD_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); break; - case SLJIT_SUBD: - FAIL_IF(push_inst32(compiler, VSUB_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_FSUB: + FAIL_IF(push_inst32(compiler, VSUB_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); break; - case SLJIT_MULD: - FAIL_IF(push_inst32(compiler, VMUL_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_FMUL: + FAIL_IF(push_inst32(compiler, VMUL_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); break; - case SLJIT_DIVD: - FAIL_IF(push_inst32(compiler, VDIV_F32 | (op & SLJIT_SINGLE_OP) | DD4(dst_r) | DN4(src1) | DM4(src2))); + case SLJIT_FDIV: + FAIL_IF(push_inst32(compiler, VDIV_F64 | DD4(dst_r) | DN4(src1) | DM4(src2))); break; } if (dst & SLJIT_MEM) - return emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw); + return emit_fop_mem(compiler, STORE, TMP_FREG1, dst, dstw); return SLJIT_SUCCESS; } -#undef FPU_LOAD - /* --------------------------------------------------------------------- */ /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (dst <= TMP_REG3) + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG3)); + else if (dst & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw)) + return compiler->error; + FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3))); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0); + } - /* Memory. */ - if (getput_arg_fast(compiler, WORD_SIZE | STORE, TMP_REG3, dst, dstw)) - return compiler->error; - /* TMP_REG3 is used for caching. */ - FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, TMP_REG3))); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0); + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= TMP_REG3) + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG3, src))); else if (src & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_SIZE, TMP_REG3, src, srcw)) @@ -1767,7 +1724,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Conditional instructions */ /* --------------------------------------------------------------------- */ -static sljit_uw get_cc(sljit_si type) +static sljit_uw get_cc(int type) { switch (type) { case SLJIT_C_EQUAL: @@ -1809,11 +1766,11 @@ static sljit_uw get_cc(sljit_si type) return 0xd; case SLJIT_C_OVERFLOW: - case SLJIT_C_FLOAT_UNORDERED: + case SLJIT_C_FLOAT_NAN: return 0x6; case SLJIT_C_NOT_OVERFLOW: - case SLJIT_C_FLOAT_ORDERED: + case SLJIT_C_FLOAT_NOT_NAN: return 0x7; default: /* SLJIT_JUMP */ @@ -1837,10 +1794,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { struct sljit_jump *jump; - sljit_si cc; + int cc; CHECK_ERROR_PTR(); check_sljit_emit_jump(compiler, type); @@ -1853,7 +1810,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile /* 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; + jump->flags |= IS_CONDITIONAL; cc = get_cc(type); jump->flags |= cc << 8; PTR_FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); @@ -1870,7 +1827,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { struct sljit_jump *jump; @@ -1890,7 +1847,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil FAIL_IF(push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1))); } else { - if (src <= TMP_REG3) + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) 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)); @@ -1900,84 +1857,58 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { - sljit_si dst_r, flags = GET_ALL_FLAGS(op); - sljit_ins ins; + int dst_r; sljit_uw cc; CHECK_ERROR(); - check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + check_sljit_emit_cond_value(compiler, op, dst, dstw, type); ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; - op = GET_OPCODE(op); cc = get_cc(type); - dst_r = (dst <= TMP_REG3) ? dst : TMP_REG2; - - if (op < SLJIT_ADD) { - FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); - if (reg_map[dst_r] > 7) { - FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 1)); - FAIL_IF(push_inst32(compiler, MOV_WI | RD4(dst_r) | 0)); - } else { - FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 1)); - FAIL_IF(push_inst16(compiler, MOVSI | RDN3(dst_r) | 0)); - } - return dst_r == TMP_REG2 ? emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; - } - - ins = (op == SLJIT_AND ? ANDI : (op == SLJIT_OR ? ORRI : EORI)); - if ((op == SLJIT_OR || op == SLJIT_XOR) && dst <= TMP_REG3 && dst == src) { - /* Does not change the other bits. */ + if (GET_OPCODE(op) == SLJIT_OR && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8)); - FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst) | 1)); - if (flags & SLJIT_SET_E) { - /* The condition must always be set, even if the ORRI/EORI is not executed above. */ + FAIL_IF(push_inst32(compiler, ORRI | RN4(dst) | RD4(dst) | 0x1)); + if (op & SLJIT_SET_E) { if (reg_map[dst] <= 7) - return push_inst16(compiler, MOVS | RD3(TMP_REG1) | RN3(dst)); - return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(TMP_REG1) | RM4(dst)); + return push_inst16(compiler, ORRS | RD3(dst) | RN3(dst)); + return push_inst32(compiler, ORR_W | SET_FLAGS | RD4(TMP_REG1) | RN4(dst) | RM4(dst)); } return SLJIT_SUCCESS; } - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, WORD_SIZE, TMP_REG1, src, srcw, dst, dstw)); - src = TMP_REG1; - srcw = 0; - } else if (src & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - srcw = 0; - } + dst_r = TMP_REG2; + if (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && reg_map[dst] <= 7) + dst_r = dst; FAIL_IF(push_inst16(compiler, IT | (cc << 4) | (((cc & 0x1) ^ 0x1) << 3) | 0x4)); - FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 1)); - FAIL_IF(push_inst32(compiler, ins | RN4(src) | RD4(dst_r) | 0)); - if (dst_r == TMP_REG2) - FAIL_IF(emit_op_mem2(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw, 0, 0)); + FAIL_IF(push_inst16(compiler, MOVSI | 0x1 | RDN3(dst_r))); + FAIL_IF(push_inst16(compiler, MOVSI | 0x0 | RDN3(dst_r))); - if (flags & SLJIT_SET_E) { - /* 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)); + if (dst_r == TMP_REG2) { + if (GET_OPCODE(op) == SLJIT_OR) { +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REG2, 0); + } + if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_SIZE | STORE, TMP_REG2, dst, dstw); + else + return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2)); } + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { struct sljit_const *const_; - sljit_si dst_r; + int dst_r; CHECK_ERROR_PTR(); check_sljit_emit_const(compiler, dst, dstw, init_value); @@ -1987,7 +1918,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - dst_r = (dst <= TMP_REG3) ? dst : TMP_REG1; + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG1; PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, init_value)); if (dst & SLJIT_MEM) @@ -2000,7 +1931,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ad inline_set_jump_addr(addr, new_addr, 1); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { sljit_uh* inst = (sljit_uh*)addr; modify_imm32_const(inst, new_constant); diff --git a/harbour/src/3rd/pcre/sjarmv5.c b/harbour/src/3rd/pcre/sjarmv5.c index 23a45a4c6a..5dc555ce75 100644 --- a/harbour/src/3rd/pcre/sjarmv5.c +++ b/harbour/src/3rd/pcre/sjarmv5.c @@ -24,7 +24,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) return "ARMv7" SLJIT_CPUINFO; @@ -41,8 +41,8 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) #define TMP_PC (SLJIT_NO_REGISTERS + 4) -#define TMP_FREG1 (0) -#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1) +#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) +#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) /* In ARM instruction words. Cache lines are usually 32 byte aligned. */ @@ -52,11 +52,11 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) #define ALIGN_INSTRUCTION(ptr) \ (sljit_uw*)(((sljit_uw)(ptr) + (CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1) & ~((CONST_POOL_ALIGNMENT * sizeof(sljit_uw)) - 1)) #define MAX_DIFFERENCE(max_diff) \ - (((max_diff) / (sljit_si)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) + (((max_diff) / (int)sizeof(sljit_uw)) - (CONST_POOL_ALIGNMENT - 1)) /* See sljit_emit_enter and sljit_emit_op0 if you want to change them. */ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { - 0, 0, 1, 2, 10, 11, 4, 5, 6, 7, 8, 13, 3, 12, 14, 15 + 0, 0, 1, 2, 10, 11, 4, 5, 6, 7, 8, 13, 3, 12, 14, 15 }; #define RM(rm) (reg_map[rm]) @@ -99,16 +99,16 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { #define SMULL 0xe0c00090 #define SUB_DP 0x2 #define UMULL 0xe0800090 -#define VABS_F32 0xeeb00ac0 -#define VADD_F32 0xee300a00 -#define VCMP_F32 0xeeb40a40 -#define VDIV_F32 0xee800a00 -#define VMOV_F32 0xeeb00a40 +#define VABS_F64 0xeeb00bc0 +#define VADD_F64 0xee300b00 +#define VCMP_F64 0xeeb40b40 +#define VDIV_F64 0xee800b00 +#define VMOV_F64 0xeeb00b40 #define VMRS 0xeef1fa10 -#define VMUL_F32 0xee200a00 -#define VNEG_F32 0xeeb10a40 -#define VSTR_F32 0xed000a00 -#define VSUB_F32 0xee300a40 +#define VMUL_F64 0xee200b00 +#define VNEG_F64 0xeeb10b40 +#define VSTR 0xed000b00 +#define VSUB_F64 0xee300b40 #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Arm v7 specific instructions. */ @@ -122,13 +122,13 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -static sljit_si push_cpool(struct sljit_compiler *compiler) +static int push_cpool(struct sljit_compiler *compiler) { /* Pushing the constant pool into the instruction stream. */ sljit_uw* inst; sljit_uw* cpool_ptr; sljit_uw* cpool_end; - sljit_si i; + int i; /* The label could point the address after the constant pool. */ if (compiler->last_label && compiler->last_label->size == compiler->size) @@ -160,7 +160,7 @@ static sljit_si push_cpool(struct sljit_compiler *compiler) return SLJIT_SUCCESS; } -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) +static int push_inst(struct sljit_compiler *compiler, sljit_uw inst) { sljit_uw* ptr; @@ -174,7 +174,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) return SLJIT_SUCCESS; } -static sljit_si push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +static int push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) { sljit_uw* ptr; sljit_uw cpool_index = CPOOL_SIZE; @@ -224,7 +224,7 @@ static sljit_si push_inst_with_literal(struct sljit_compiler *compiler, sljit_uw return SLJIT_SUCCESS; } -static sljit_si push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) +static int push_inst_with_unique_literal(struct sljit_compiler *compiler, sljit_uw inst, sljit_uw literal) { sljit_uw* ptr; if (SLJIT_UNLIKELY((compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4092)) || compiler->cpool_fill >= CPOOL_SIZE)) @@ -244,7 +244,7 @@ static sljit_si push_inst_with_unique_literal(struct sljit_compiler *compiler, s return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si prepare_blx(struct sljit_compiler *compiler) +static SLJIT_INLINE int prepare_blx(struct sljit_compiler *compiler) { /* Place for at least two instruction (doesn't matter whether the first has a literal). */ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY && compiler->size - compiler->cpool_diff >= MAX_DIFFERENCE(4088))) @@ -252,7 +252,7 @@ static SLJIT_INLINE sljit_si prepare_blx(struct sljit_compiler *compiler) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_blx(struct sljit_compiler *compiler) +static SLJIT_INLINE int emit_blx(struct sljit_compiler *compiler) { /* Must follow tightly the previous instruction (to be able to convert it to bl instruction). */ SLJIT_ASSERT(compiler->cpool_diff == CONST_POOL_EMPTY || compiler->size - compiler->cpool_diff < MAX_DIFFERENCE(4092)); @@ -282,7 +282,7 @@ static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ /* Must be a load instruction with immediate offset. */ SLJIT_ASSERT(ind < cpool_size && !(*last_pc_patch & (1 << 25)) && (*last_pc_patch & (1 << 20))); - if ((sljit_si)const_pool[ind] < 0) { + if ((int)const_pool[ind] < 0) { const_pool[ind] = counter; ind = counter; counter++; @@ -307,24 +307,24 @@ static sljit_uw patch_pc_relative_loads(sljit_uw *last_pc_patch, sljit_uw *code_ /* In some rare ocasions we may need future patches. The probability is close to 0 in practice. */ struct future_patch { struct future_patch* next; - sljit_si index; - sljit_si value; + int index; + int value; }; -static SLJIT_INLINE sljit_si resolve_const_pool_index(struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) +static SLJIT_INLINE int resolve_const_pool_index(struct future_patch **first_patch, sljit_uw cpool_current_index, sljit_uw *cpool_start_address, sljit_uw *buf_ptr) { - sljit_si value; + int value; struct future_patch *curr_patch, *prev_patch; /* Using the values generated by patch_pc_relative_loads. */ if (!*first_patch) - value = (sljit_si)cpool_start_address[cpool_current_index]; + value = (int)cpool_start_address[cpool_current_index]; else { curr_patch = *first_patch; prev_patch = 0; while (1) { if (!curr_patch) { - value = (sljit_si)cpool_start_address[cpool_current_index]; + value = (int)cpool_start_address[cpool_current_index]; break; } if ((sljit_uw)curr_patch->index == cpool_current_index) { @@ -364,7 +364,7 @@ static SLJIT_INLINE sljit_si resolve_const_pool_index(struct future_patch **firs #else -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) +static int push_inst(struct sljit_compiler *compiler, sljit_uw inst) { sljit_uw* ptr; @@ -375,7 +375,7 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_uw inst) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_imm(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static SLJIT_INLINE int emit_imm(struct sljit_compiler *compiler, int reg, sljit_w imm) { FAIL_IF(push_inst(compiler, MOVW | RD(reg) | ((imm << 4) & 0xf0000) | (imm & 0xfff))); return push_inst(compiler, MOVT | RD(reg) | ((imm >> 12) & 0xf0000) | ((imm >> 16) & 0xfff)); @@ -383,9 +383,9 @@ static SLJIT_INLINE sljit_si emit_imm(struct sljit_compiler *compiler, sljit_si #endif -static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) +static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uw *code_ptr, sljit_uw *code) { - sljit_sw diff; + sljit_w diff; if (jump->flags & SLJIT_REWRITABLE_JUMP) return 0; @@ -395,10 +395,10 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw code_ptr--; if (jump->flags & JUMP_ADDR) - diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 2)); + diff = ((sljit_w)jump->u.target - (sljit_w)(code_ptr + 2)); else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); - diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 2)); + diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2)); } /* Branch to Thumb code has not been optimized yet. */ @@ -421,10 +421,10 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw } #else if (jump->flags & JUMP_ADDR) - diff = ((sljit_sw)jump->u.target - (sljit_sw)code_ptr); + diff = ((sljit_w)jump->u.target - (sljit_w)code_ptr); else { SLJIT_ASSERT(jump->flags & JUMP_LABEL); - diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)code_ptr); + diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)code_ptr); } /* Branch to Thumb code has not been optimized yet. */ @@ -442,14 +442,14 @@ static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_uw return 0; } -static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, sljit_si flush) +static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, int flush) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw *ptr = (sljit_uw*)addr; sljit_uw *inst = (sljit_uw*)ptr[0]; sljit_uw mov_pc = ptr[1]; - sljit_si bl = (mov_pc & 0x0000f000) != RD(TMP_PC); - sljit_sw diff = (sljit_sw)(((sljit_sw)new_addr - (sljit_sw)(inst + 2)) >> 2); + int bl = (mov_pc & 0x0000f000) != RD(TMP_PC); + sljit_w diff = (sljit_w)(((sljit_w)new_addr - (sljit_w)(inst + 2)) >> 2); if (diff <= 0x7fffff && diff >= -0x800000) { /* Turn to branch. */ @@ -498,9 +498,9 @@ static SLJIT_INLINE void inline_set_jump_addr(sljit_uw addr, sljit_uw new_addr, #endif } -static sljit_uw get_imm(sljit_uw imm); +static sljit_uw get_immediate(sljit_uw imm); -static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_si flush) +static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_w new_constant, int flush) { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) sljit_uw *ptr = (sljit_uw*)addr; @@ -508,7 +508,7 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, sljit_uw ldr_literal = ptr[1]; sljit_uw src2; - src2 = get_imm(new_constant); + src2 = get_immediate(new_constant); if (src2) { *inst = 0xe3a00000 | (ldr_literal & 0xf000) | src2; if (flush) { @@ -517,7 +517,7 @@ static SLJIT_INLINE void inline_set_const(sljit_uw addr, sljit_sw new_constant, return; } - src2 = get_imm(~new_constant); + src2 = get_immediate(~new_constant); if (src2) { *inst = 0xe3e00000 | (ldr_literal & 0xf000) | src2; if (flush) { @@ -730,12 +730,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (jump->flags & PATCH_B) { if (!(jump->flags & JUMP_ADDR)) { SLJIT_ASSERT(jump->flags & JUMP_LABEL); - SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); - *buf_ptr |= (((sljit_sw)jump->u.label->addr - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff; + SLJIT_ASSERT(((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >= -0x02000000); + *buf_ptr |= (((sljit_w)jump->u.label->addr - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff; } else { - SLJIT_ASSERT(((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >= -0x02000000); - *buf_ptr |= (((sljit_sw)jump->u.target - (sljit_sw)(buf_ptr + 2)) >> 2) & 0x00ffffff; + SLJIT_ASSERT(((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) <= 0x01ffffff && ((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >= -0x02000000); + *buf_ptr |= (((sljit_w)jump->u.target - (sljit_w)(buf_ptr + 2)) >> 2) & 0x00ffffff; } } else if (jump->flags & SLJIT_REWRITABLE_JUMP) { @@ -785,7 +785,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil } #endif - SLJIT_ASSERT(code_ptr - code <= (sljit_si)size); + SLJIT_ASSERT(code_ptr - code <= (int)size); SLJIT_CACHE_FLUSH(code, code_ptr); compiler->error = SLJIT_ERR_COMPILED; @@ -793,10 +793,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil return code; } -/* --------------------------------------------------------------------- */ -/* Entry, exit */ -/* --------------------------------------------------------------------- */ - /* emit_op inp_flags. WRITE_BACK must be the first, since it is a flag. */ #define WRITE_BACK 0x01 @@ -819,20 +815,20 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #define EMIT_DATA_PROCESS_INS(opcode, set_flags, dst, src1, src2) \ (0xe0000000 | ((opcode) << 21) | (set_flags) | RD(dst) | RN(src1) | (src2)) -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); +static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { - sljit_si size; + int size; sljit_uw push; CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; @@ -841,9 +837,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil /* Push saved registers, temporary registers stmdb sp!, {..., lr} */ push = PUSH | (1 << 14); - if (scratches >= 5) + if (temporaries >= 5) push |= 1 << 11; - if (scratches >= 4) + if (temporaries >= 4) push |= 1 << 10; if (saveds >= 5) push |= 1 << 8; @@ -859,8 +855,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil /* Stack must be aligned to 8 bytes: */ size = (1 + saveds) * sizeof(sljit_uw); - if (scratches >= 4) - size += (scratches - 3) * sizeof(sljit_uw); + if (temporaries >= 4) + size += (temporaries - 3) * sizeof(sljit_uw); local_size += size; local_size = (local_size + 7) & ~7; local_size -= size; @@ -869,43 +865,44 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil FAIL_IF(emit_op(compiler, SLJIT_SUB, ALLOW_IMM, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size)); if (args >= 1) - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG1, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG1))); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG1))); if (args >= 2) - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG2))); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG2, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2))); if (args >= 3) - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG3))); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, SLJIT_SAVED_REG3, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG3))); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { - sljit_si size; + int size; CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, scratches, saveds, local_size); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif size = (1 + saveds) * sizeof(sljit_uw); - if (scratches >= 4) - size += (scratches - 3) * sizeof(sljit_uw); + if (temporaries >= 4) + size += (temporaries - 3) * sizeof(sljit_uw); local_size += size; local_size = (local_size + 7) & ~7; local_size -= size; compiler->local_size = local_size; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { sljit_uw pop; CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); @@ -915,9 +912,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi pop = POP | (1 << 15); /* Push saved registers, temporary registers ldmia sp!, {..., pc} */ - if (compiler->scratches >= 5) + if (compiler->temporaries >= 5) pop |= 1 << 11; - if (compiler->scratches >= 4) + if (compiler->temporaries >= 4) pop |= 1 << 10; if (compiler->saveds >= 5) pop |= 1 << 8; @@ -942,7 +939,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi w/b/h/N - word/byte/half/NOT allowed (2 bit) It contans 16 items, but not all are different. */ -static sljit_sw data_transfer_insts[16] = { +static sljit_w data_transfer_insts[16] = { /* s u w */ 0xe5000000 /* str */, /* s u b */ 0xe5400000 /* strb */, /* s u h */ 0xe10000b0 /* strh */, @@ -1008,80 +1005,12 @@ static sljit_sw data_transfer_insts[16] = { } \ return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (reg_map[(flags & ARGS_SWAPPED) ? src1 : src2] << 8) | (opcode << 5) | 0x10 | ((flags & ARGS_SWAPPED) ? reg_map[src2] : reg_map[src1]))); -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) +static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, + int dst, int src1, int src2) { - sljit_sw mul_inst; + sljit_w mul_inst; switch (GET_OPCODE(op)) { - case SLJIT_MOV: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); - if (dst != src2) { - if (src2 & SRC2_IMM) { - if (flags & INV_IMM) - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); - } - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, reg_map[src2]); - } - return SLJIT_SUCCESS; - - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); - if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - if (op == SLJIT_MOV_UB) - return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff)); - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2])); - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_UB ? 0x20 : 0x40) | reg_map[dst])); -#else - return push_inst(compiler, (op == SLJIT_MOV_UB ? UXTB : SXTB) | RD(dst) | RM(src2)); -#endif - } - else if (dst != src2) { - SLJIT_ASSERT(src2 & SRC2_IMM); - if (flags & INV_IMM) - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); - } - return SLJIT_SUCCESS; - - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); - if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { -#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2])); - return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_UH ? 0x20 : 0x40) | reg_map[dst])); -#else - return push_inst(compiler, (op == SLJIT_MOV_UH ? UXTH : SXTH) | RD(dst) | RM(src2)); -#endif - } - else if (dst != src2) { - SLJIT_ASSERT(src2 & SRC2_IMM); - if (flags & INV_IMM) - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); - } - return SLJIT_SUCCESS; - - case SLJIT_NOT: - if (src2 & SRC2_IMM) { - if (flags & INV_IMM) - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); - } - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, RM(src2)); - - case SLJIT_CLZ: - SLJIT_ASSERT(!(flags & INV_IMM)); - SLJIT_ASSERT(!(src2 & SRC2_IMM)); - FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2))); - if (flags & SET_FLAGS) - EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(CMP_DP, SLJIT_UNUSED, dst, SRC2_IMM); - return SLJIT_SUCCESS; - case SLJIT_ADD: SLJIT_ASSERT(!(flags & INV_IMM)); EMIT_DATA_PROCESS_INS_AND_RETURN(ADD_DP); @@ -1151,6 +1080,74 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj case SLJIT_ASHR: EMIT_SHIFT_INS_AND_RETURN(2); + + case SLJIT_MOV: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); + if (dst != src2) { + if (src2 & SRC2_IMM) { + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + } + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, reg_map[src2]); + } + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); + if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + if (op == SLJIT_MOV_UB) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(AND_DP, 0, dst, src2, SRC2_IMM | 0xff)); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | reg_map[src2])); + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (24 << 7) | (op == SLJIT_MOV_UB ? 0x20 : 0x40) | reg_map[dst])); +#else + return push_inst(compiler, (op == SLJIT_MOV_UB ? UXTB : SXTB) | RD(dst) | RM(src2)); +#endif + } + else if (dst != src2) { + SLJIT_ASSERT(src2 & SRC2_IMM); + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + } + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & ARGS_SWAPPED)); + if ((flags & (REG_DEST | REG_SOURCE)) == (REG_DEST | REG_SOURCE)) { +#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | reg_map[src2])); + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, (16 << 7) | (op == SLJIT_MOV_UH ? 0x20 : 0x40) | reg_map[dst])); +#else + return push_inst(compiler, (op == SLJIT_MOV_UH ? UXTH : SXTH) | RD(dst) | RM(src2)); +#endif + } + else if (dst != src2) { + SLJIT_ASSERT(src2 & SRC2_IMM); + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + } + return SLJIT_SUCCESS; + + case SLJIT_NOT: + if (src2 & SRC2_IMM) { + if (flags & INV_IMM) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MOV_DP, dst, SLJIT_UNUSED, src2); + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, src2); + } + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(MVN_DP, dst, SLJIT_UNUSED, RM(src2)); + + case SLJIT_CLZ: + SLJIT_ASSERT(!(flags & INV_IMM)); + SLJIT_ASSERT(!(src2 & SRC2_IMM)); + FAIL_IF(push_inst(compiler, CLZ | RD(dst) | RM(src2))); + if (flags & SET_FLAGS) + EMIT_FULL_DATA_PROCESS_INS_AND_RETURN(CMP_DP, SLJIT_UNUSED, dst, SRC2_IMM); + return SLJIT_SUCCESS; } SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; @@ -1162,9 +1159,9 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj /* Tests whether the immediate can be stored in the 12 bit imm field. Returns with 0 if not possible. */ -static sljit_uw get_imm(sljit_uw imm) +static sljit_uw get_immediate(sljit_uw imm) { - sljit_si rol; + int rol; if (imm <= 0xff) return SRC2_IMM | imm; @@ -1200,12 +1197,12 @@ static sljit_uw get_imm(sljit_uw imm) } #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -static sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm, sljit_si positive) +static int generate_int(struct sljit_compiler *compiler, int reg, sljit_uw imm, int positive) { sljit_uw mask; sljit_uw imm1; sljit_uw imm2; - sljit_si rol; + int rol; /* Step1: Search a zero byte (8 continous zero bit). */ mask = 0xff000000; @@ -1311,7 +1308,7 @@ static sljit_si generate_int(struct sljit_compiler *compiler, sljit_si reg, slji } #endif -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_uw imm) +static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_uw imm) { sljit_uw tmp; @@ -1321,13 +1318,13 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl #endif /* Create imm by 1 inst. */ - tmp = get_imm(imm); + tmp = get_immediate(imm); if (tmp) { EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, tmp)); return SLJIT_SUCCESS; } - tmp = get_imm(~imm); + tmp = get_immediate(~imm); if (tmp) { EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MVN_DP, 0, reg, SLJIT_UNUSED, tmp)); return SLJIT_SUCCESS; @@ -1345,36 +1342,20 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl #endif } -/* Helper function. Dst should be reg + value, using at most 1 instruction, flags does not set. */ -static sljit_si emit_set_delta(struct sljit_compiler *compiler, sljit_si dst, sljit_si reg, sljit_sw value) -{ - if (value >= 0) { - value = get_imm(value); - if (value) - return push_inst(compiler, EMIT_DATA_PROCESS_INS(ADD_DP, 0, dst, reg, value)); - } - else { - value = get_imm(-value); - if (value) - return push_inst(compiler, EMIT_DATA_PROCESS_INS(SUB_DP, 0, dst, reg, value)); - } - return SLJIT_ERR_UNSUPPORTED; -} - /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static int getput_arg_fast(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw) { sljit_uw imm; if (arg & SLJIT_IMM) { - imm = get_imm(argw); + imm = get_immediate(argw); if (imm) { if (inp_flags & ARG_TEST) return 1; EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, imm)); return -1; } - imm = get_imm(~argw); + imm = get_immediate(~argw); if (imm) { if (inp_flags & ARG_TEST) return 1; @@ -1434,7 +1415,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) { /* Immediate caching is not supported as it would be an operation on constant arguments. */ if (arg & SLJIT_IMM) @@ -1482,12 +1463,11 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static int getput_arg(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw) { - sljit_si tmp_r; - sljit_sw max_delta; - sljit_sw sign; - sljit_uw imm; + int tmp_r; + sljit_w max_delta; + sljit_w sign; if (arg & SLJIT_IMM) { SLJIT_ASSERT(inp_flags & LOAD_DATA); @@ -1501,9 +1481,8 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, if ((arg & 0xf) == SLJIT_UNUSED) { /* Write back is not used. */ - imm = (sljit_uw)(argw - compiler->cache_argw); - if ((compiler->cache_arg & SLJIT_IMM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) { - if (imm <= (sljit_uw)max_delta) { + if ((compiler->cache_arg & SLJIT_IMM) && (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta || ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta)) { + if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) { sign = 1; argw = argw - compiler->cache_argw; } @@ -1512,14 +1491,18 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, argw = compiler->cache_argw - argw; } - GETPUT_ARG_DATA_TRANSFER(sign, 0, reg, TMP_REG3, argw); + if (max_delta & 0xf00) { + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, argw)); + } + else { + EMIT_INSTRUCTION(EMIT_DATA_TRANSFER(inp_flags, sign, 0, reg, TMP_REG3, TYPE2_TRANSFER_IMM(argw))); + } return SLJIT_SUCCESS; } /* With write back, we can create some sophisticated loads, but it is hard to decide whether we should convert downward (0s) or upward (1s). */ - imm = (sljit_uw)(argw - next_argw); - if ((next_arg & SLJIT_MEM) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) { + if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) { SLJIT_ASSERT(inp_flags & LOAD_DATA); compiler->cache_arg = SLJIT_IMM; @@ -1532,6 +1515,29 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, return SLJIT_SUCCESS; } + /* Extended imm addressing for [reg+imm] format. */ + sign = (max_delta << 8) | 0xff; + if (!(arg & 0xf0) && argw <= sign && argw >= -sign) { + TEST_WRITE_BACK(); + if (argw >= 0) { + sign = 1; + } + else { + sign = 0; + argw = -argw; + } + + /* Optimization: add is 0x4, sub is 0x2. Sign is 1 for add and 0 for sub. */ + if (max_delta & 0xf00) + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 12) | 0xa00)); + else + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP << sign, 0, tmp_r, arg & 0xf, SRC2_IMM | (argw >> 8) | 0xc00)); + + argw &= max_delta; + GETPUT_ARG_DATA_TRANSFER(sign, inp_flags & WRITE_BACK, reg, tmp_r, argw); + return SLJIT_SUCCESS; + } + if (arg & 0xf0) { SLJIT_ASSERT((argw & 0x3) && !(max_delta & 0xf00)); if (inp_flags & WRITE_BACK) @@ -1541,33 +1547,17 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, return SLJIT_SUCCESS; } - imm = (sljit_uw)(argw - compiler->cache_argw); - if (compiler->cache_arg == arg && imm <= (sljit_uw)max_delta) { + if (compiler->cache_arg == arg && ((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= (sljit_uw)max_delta) { SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); - GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, imm); - return SLJIT_SUCCESS; - } - if (compiler->cache_arg == arg && imm >= (sljit_uw)-max_delta) { - SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); - imm = (sljit_uw)-(sljit_sw)imm; - GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, imm); + argw = argw - compiler->cache_argw; + GETPUT_ARG_DATA_TRANSFER(1, 0, reg, TMP_REG3, argw); return SLJIT_SUCCESS; } - imm = get_imm(argw & ~max_delta); - if (imm) { - TEST_WRITE_BACK(); - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, tmp_r, arg & 0xf, imm)); - GETPUT_ARG_DATA_TRANSFER(1, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta); - return SLJIT_SUCCESS; - } - - imm = get_imm(-argw & ~max_delta); - if (imm) { - argw = -argw; - TEST_WRITE_BACK(); - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, tmp_r, arg & 0xf, imm)); - GETPUT_ARG_DATA_TRANSFER(0, inp_flags & WRITE_BACK, reg, tmp_r, argw & max_delta); + if (compiler->cache_arg == arg && ((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= (sljit_uw)max_delta) { + SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); + argw = compiler->cache_argw - argw; + GETPUT_ARG_DATA_TRANSFER(0, 0, reg, TMP_REG3, argw); return SLJIT_SUCCESS; } @@ -1589,8 +1579,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, return SLJIT_SUCCESS; } - imm = (sljit_uw)(argw - next_argw); - if (arg == next_arg && !(inp_flags & WRITE_BACK) && (imm <= (sljit_uw)max_delta || imm >= (sljit_uw)-max_delta)) { + if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= (sljit_uw)max_delta || (sljit_uw)next_argw - (sljit_uw)argw <= (sljit_uw)max_delta)) { SLJIT_ASSERT(inp_flags & LOAD_DATA); FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG3, TMP_REG3, reg_map[arg & 0xf])); @@ -1613,26 +1602,10 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) -{ - if (getput_arg_fast(compiler, flags, reg, arg, argw)) - return compiler->error; - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, flags, reg, arg, argw, 0, 0); -} - -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) -{ - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si inp_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg @@ -1640,27 +1613,27 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ /* We prefers register and simple consts. */ - sljit_si dst_r; - sljit_si src1_r; - sljit_si src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; - sljit_si flags = GET_FLAGS(op) ? SET_FLAGS : 0; + int dst_r; + int src1_r; + int src2_r = 0; + int sugg_src2_r = TMP_REG2; + int flags = GET_FLAGS(op) ? SET_FLAGS : 0; compiler->cache_arg = 0; compiler->cache_argw = 0; /* Destination check. */ - if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) - return SLJIT_SUCCESS; - dst_r = TMP_REG2; - } - else if (dst <= TMP_REG3) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) { dst_r = dst; flags |= REG_DEST; if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) sugg_src2_r = dst_r; } + else if (dst == SLJIT_UNUSED) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + dst_r = TMP_REG2; + } else { SLJIT_ASSERT(dst & SLJIT_MEM); if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) { @@ -1674,9 +1647,9 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i } /* Source 1. */ - if (src1 <= TMP_REG3) + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) src1_r = src1; - else if (src2 <= TMP_REG3) { + else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { flags |= ARGS_SWAPPED; src1_r = src2; src2 = src1; @@ -1686,7 +1659,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i src1_r = 0; if ((inp_flags & ALLOW_ANY_IMM) && (src1 & SLJIT_IMM)) { /* The second check will generate a hit. */ - src2_r = get_imm(src1w); + src2_r = get_immediate(src1w); if (src2_r) { flags |= ARGS_SWAPPED; src1 = src2; @@ -1694,7 +1667,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i break; } if (inp_flags & ALLOW_INV_IMM) { - src2_r = get_imm(~src1w); + src2_r = get_immediate(~src1w); if (src2_r) { flags |= ARGS_SWAPPED | INV_IMM; src1 = src2; @@ -1703,7 +1676,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i } } if (GET_OPCODE(op) == SLJIT_ADD) { - src2_r = get_imm(-src1w); + src2_r = get_immediate(-src1w); if (src2_r) { /* Note: ARGS_SWAPPED is intentionally not applied! */ src1 = src2; @@ -1722,7 +1695,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i /* Source 2. */ if (src2_r == 0) { - if (src2 <= TMP_REG3) { + if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { src2_r = src2; flags |= REG_SOURCE; if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) @@ -1730,18 +1703,18 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i } else do { /* do { } while(0) is used because of breaks. */ if ((inp_flags & ALLOW_ANY_IMM) && (src2 & SLJIT_IMM)) { - src2_r = get_imm(src2w); + src2_r = get_immediate(src2w); if (src2_r) break; if (inp_flags & ALLOW_INV_IMM) { - src2_r = get_imm(~src2w); + src2_r = get_immediate(~src2w); if (src2_r) { flags |= INV_IMM; break; } } if (GET_OPCODE(op) == SLJIT_ADD) { - src2_r = get_imm(-src2w); + src2_r = get_immediate(-src2w); if (src2_r) { op = SLJIT_SUB | GET_ALL_FLAGS(op); flags &= ~ARGS_SWAPPED; @@ -1749,7 +1722,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i } } if (GET_OPCODE(op) == SLJIT_SUB && !(flags & ARGS_SWAPPED)) { - src2_r = get_imm(-src2w); + src2_r = get_immediate(-src2w); if (src2_r) { op = SLJIT_ADD | GET_ALL_FLAGS(op); flags &= ~ARGS_SWAPPED; @@ -1824,8 +1797,8 @@ extern "C" { #endif #if defined(__GNUC__) -extern unsigned int __aeabi_uidivmod(unsigned int numerator, unsigned int denominator); -extern int __aeabi_idivmod(int numerator, int denominator); +extern unsigned int __aeabi_uidivmod(unsigned numerator, unsigned denominator); +extern unsigned int __aeabi_idivmod(unsigned numerator, unsigned denominator); #else #error "Software divmod functions are needed" #endif @@ -1834,7 +1807,7 @@ extern int __aeabi_idivmod(int numerator, int denominator); } #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { CHECK_ERROR(); check_sljit_emit_op0(compiler, op); @@ -1851,21 +1824,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler case SLJIT_SMUL: #if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) - | (reg_map[SLJIT_SCRATCH_REG2] << 16) - | (reg_map[SLJIT_SCRATCH_REG1] << 12) - | (reg_map[SLJIT_SCRATCH_REG1] << 8) - | reg_map[SLJIT_SCRATCH_REG2]); + | (reg_map[SLJIT_TEMPORARY_REG2] << 16) + | (reg_map[SLJIT_TEMPORARY_REG1] << 12) + | (reg_map[SLJIT_TEMPORARY_REG1] << 8) + | reg_map[SLJIT_TEMPORARY_REG2]); #else - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_SCRATCH_REG2))); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, RM(SLJIT_TEMPORARY_REG2))); return push_inst(compiler, (op == SLJIT_UMUL ? UMULL : SMULL) - | (reg_map[SLJIT_SCRATCH_REG2] << 16) - | (reg_map[SLJIT_SCRATCH_REG1] << 12) - | (reg_map[SLJIT_SCRATCH_REG1] << 8) + | (reg_map[SLJIT_TEMPORARY_REG2] << 16) + | (reg_map[SLJIT_TEMPORARY_REG1] << 12) + | (reg_map[SLJIT_TEMPORARY_REG1] << 8) | reg_map[TMP_REG1]); #endif case SLJIT_UDIV: case SLJIT_SDIV: - if (compiler->scratches >= 3) + if (compiler->temporaries >= 3) EMIT_INSTRUCTION(0xe52d2008 /* str r2, [sp, #-8]! */); #if defined(__GNUC__) FAIL_IF(sljit_emit_ijump(compiler, SLJIT_FAST_CALL, SLJIT_IMM, @@ -1873,7 +1846,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #else #error "Software divmod functions are needed" #endif - if (compiler->scratches >= 3) + if (compiler->temporaries >= 3) return push_inst(compiler, 0xe49d2008 /* ldr r2, [sp], #8 */); return SLJIT_SUCCESS; } @@ -1881,9 +1854,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); @@ -1894,38 +1867,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler case SLJIT_MOV: case SLJIT_MOV_UI: case SLJIT_MOV_SI: - case SLJIT_MOV_P: return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); case SLJIT_MOVU: case SLJIT_MOVU_UI: case SLJIT_MOVU_SI: - case SLJIT_MOVU_P: return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UB, ALLOW_ANY_IMM | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SB, ALLOW_ANY_IMM | SIGNED_DATA | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UH, ALLOW_ANY_IMM | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SH, ALLOW_ANY_IMM | SIGNED_DATA | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); case SLJIT_NOT: return emit_op(compiler, op, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, src, srcw); @@ -1943,10 +1914,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { CHECK_ERROR(); check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); @@ -1985,14 +1956,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { check_sljit_get_register_index(reg); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) { CHECK_ERROR(); check_sljit_emit_op_custom(compiler, instruction, size); @@ -2009,9 +1980,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* 0 - no fpu 1 - vfp */ -static sljit_si arm_fpu_type = -1; +static int arm_fpu_type = -1; -static void init_compiler(void) +static void init_compiler() { if (arm_fpu_type != -1) return; @@ -2020,7 +1991,7 @@ static void init_compiler(void) arm_fpu_type = 1; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { if (arm_fpu_type == -1) init_compiler(); @@ -2031,7 +2002,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #define arm_fpu_type 1 -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { /* Always available. */ return 1; @@ -2039,61 +2010,56 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif -#define FPU_LOAD (1 << 20) -#define EMIT_FPU_DATA_TRANSFER(inst, add, base, freg, offs) \ - ((inst) | ((add) << 23) | (reg_map[base] << 16) | (freg << 12) | (offs)) -#define EMIT_FPU_OPERATION(opcode, mode, dst, src1, src2) \ - ((opcode) | (mode) | ((dst) << 12) | (src1) | ((src2) << 16)) +#define EMIT_FPU_DATA_TRANSFER(add, load, base, freg, offs) \ + (VSTR | ((add) << 23) | ((load) << 20) | (reg_map[base] << 16) | (freg << 12) | (offs)) +#define EMIT_FPU_OPERATION(opcode, dst, src1, src2) \ + ((opcode) | ((dst) << 12) | (src1) | ((src2) << 16)) -static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw) { - sljit_sw tmp; - sljit_uw imm; - sljit_sw inst = VSTR_F32 | (flags & (SLJIT_SINGLE_OP | FPU_LOAD)); SLJIT_ASSERT(arg & SLJIT_MEM); - if (SLJIT_UNLIKELY(arg & 0xf0)) { - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7))); - arg = SLJIT_MEM | TMP_REG1; - argw = 0; - } - /* Fast loads and stores. */ - if ((arg & 0xf)) { - if (!(argw & ~0x3fc)) - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, arg & 0xf, reg, argw >> 2)); - if (!(-argw & ~0x3fc)) - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, arg & 0xf, reg, (-argw) >> 2)); - } - - if (compiler->cache_arg == arg) { - tmp = argw - compiler->cache_argw; - if (!(tmp & ~0x3fc)) - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, tmp >> 2)); - if (!(-tmp & ~0x3fc)) - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG3, reg, -tmp >> 2)); - if (emit_set_delta(compiler, TMP_REG3, TMP_REG3, tmp) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - compiler->cache_argw = argw; - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); + if ((arg & 0xf) && !(arg & 0xf0) && (argw & 0x3) == 0) { + if (argw >= 0 && argw <= 0x3ff) { + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, arg & 0xf, fpu_reg, argw >> 2)); + return SLJIT_SUCCESS; } - } - - if (arg & 0xf) { - if (emit_set_delta(compiler, TMP_REG1, arg & 0xf, argw) != SLJIT_ERR_UNSUPPORTED) { - FAIL_IF(compiler->error); - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, 0)); + if (argw < 0 && argw >= -0x3ff) { + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, arg & 0xf, fpu_reg, (-argw) >> 2)); + return SLJIT_SUCCESS; } - imm = get_imm(argw & ~0x3fc); - if (imm) { - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, imm)); - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG1, reg, (argw & 0x3fc) >> 2)); + if (argw >= 0 && argw <= 0x3ffff) { + SLJIT_ASSERT(get_immediate(argw & 0x3fc00)); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00))); + argw &= 0x3ff; + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, argw >> 2)); + return SLJIT_SUCCESS; } - imm = get_imm(-argw & ~0x3fc); - if (imm) { + if (argw < 0 && argw >= -0x3ffff) { argw = -argw; - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & 0xf, imm)); - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 0, TMP_REG1, reg, (argw & 0x3fc) >> 2)); + SLJIT_ASSERT(get_immediate(argw & 0x3fc00)); + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(SUB_DP, 0, TMP_REG1, arg & 0xf, get_immediate(argw & 0x3fc00))); + argw &= 0x3ff; + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG1, fpu_reg, argw >> 2)); + return SLJIT_SUCCESS; + } + } + + if (arg & 0xf0) { + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(ADD_DP, 0, TMP_REG1, arg & 0xf, RM((arg >> 4) & 0xf) | ((argw & 0x3) << 7))); + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG1, fpu_reg, 0)); + return SLJIT_SUCCESS; + } + + if (compiler->cache_arg == arg && ((argw - compiler->cache_argw) & 0x3) == 0) { + if (((sljit_uw)argw - (sljit_uw)compiler->cache_argw) <= 0x3ff) { + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, (argw - compiler->cache_argw) >> 2)); + return SLJIT_SUCCESS; + } + if (((sljit_uw)compiler->cache_argw - (sljit_uw)argw) <= 0x3ff) { + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(0, load, TMP_REG3, fpu_reg, (compiler->cache_argw - argw) >> 2)); + return SLJIT_SUCCESS; } } @@ -2106,154 +2072,142 @@ static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sl else FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); - return push_inst(compiler, EMIT_FPU_DATA_TRANSFER(inst, 1, TMP_REG3, reg, 0)); + EMIT_INSTRUCTION(EMIT_FPU_DATA_TRANSFER(1, load, TMP_REG3, fpu_reg, 0)); + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_si dst_fr; + int dst_freg; CHECK_ERROR(); check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100), float_transfer_bit_error); compiler->cache_arg = 0; compiler->cache_argw = 0; - op ^= SLJIT_SINGLE_OP; - if (GET_OPCODE(op) == SLJIT_CMPD) { - if (dst > SLJIT_FLOAT_REG6) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, dst, dstw)); + if (GET_OPCODE(op) == SLJIT_FCMP) { + if (dst > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw)); dst = TMP_FREG1; } - if (src > SLJIT_FLOAT_REG6) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src, srcw)); + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw)); src = TMP_FREG2; } - EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VCMP_F32, op & SLJIT_SINGLE_OP, dst, src, 0)); + EMIT_INSTRUCTION(VCMP_F64 | (dst << 12) | src); EMIT_INSTRUCTION(VMRS); return SLJIT_SUCCESS; } - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst; + dst_freg = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; - if (src > SLJIT_FLOAT_REG6) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, dst_fr, src, srcw)); - src = dst_fr; + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, dst_freg, 1, src, srcw)); + src = dst_freg; } - switch (GET_OPCODE(op)) { - case SLJIT_MOVD: - if (src != dst_fr && dst_fr != TMP_FREG1) - EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMOV_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0)); + switch (op) { + case SLJIT_FMOV: + if (src != dst_freg && dst_freg != TMP_FREG1) + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMOV_F64, dst_freg, src, 0)); break; - case SLJIT_NEGD: - EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VNEG_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0)); + case SLJIT_FNEG: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VNEG_F64, dst_freg, src, 0)); break; - case SLJIT_ABSD: - EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VABS_F32, op & SLJIT_SINGLE_OP, dst_fr, src, 0)); + case SLJIT_FABS: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VABS_F64, dst_freg, src, 0)); break; } - if (dst_fr == TMP_FREG1) { - if (GET_OPCODE(op) == SLJIT_MOVD) - dst_fr = src; - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), dst_fr, dst, dstw)); - } + if (dst_freg == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw)); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_si dst_fr; + int dst_freg; CHECK_ERROR(); check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); compiler->cache_arg = 0; compiler->cache_argw = 0; - op ^= SLJIT_SINGLE_OP; - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst; + dst_freg = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; - if (src2 > SLJIT_FLOAT_REG6) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG2, src2, src2w)); + if (src2 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); src2 = TMP_FREG2; } - if (src1 > SLJIT_FLOAT_REG6) { - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP) | FPU_LOAD, TMP_FREG1, src1, src1w)); + if (src1 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); src1 = TMP_FREG1; } - switch (GET_OPCODE(op)) { - case SLJIT_ADDD: - EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VADD_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + switch (op) { + case SLJIT_FADD: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VADD_F64, dst_freg, src2, src1)); break; - case SLJIT_SUBD: - EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VSUB_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + case SLJIT_FSUB: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VSUB_F64, dst_freg, src2, src1)); break; - case SLJIT_MULD: - EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMUL_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + case SLJIT_FMUL: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VMUL_F64, dst_freg, src2, src1)); break; - case SLJIT_DIVD: - EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VDIV_F32, op & SLJIT_SINGLE_OP, dst_fr, src2, src1)); + case SLJIT_FDIV: + EMIT_INSTRUCTION(EMIT_FPU_OPERATION(VDIV_F64, dst_freg, src2, src1)); break; } - if (dst_fr == TMP_FREG1) - FAIL_IF(emit_fop_mem(compiler, (op & SLJIT_SINGLE_OP), TMP_FREG1, dst, dstw)); + if (dst_freg == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw)); return SLJIT_SUCCESS; } -#undef FPU_LOAD -#undef EMIT_FPU_DATA_TRANSFER -#undef EMIT_FPU_OPERATION - /* --------------------------------------------------------------------- */ /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (dst <= TMP_REG3) + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst, SLJIT_UNUSED, RM(TMP_REG3))); + else if (dst & SLJIT_MEM) { + if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw)) + return compiler->error; + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3))); + compiler->cache_arg = 0; + compiler->cache_argw = 0; + return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); + } - /* Memory. */ - if (getput_arg_fast(compiler, WORD_DATA, TMP_REG3, dst, dstw)) - return compiler->error; - /* TMP_REG3 is used for caching. */ - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG2, SLJIT_UNUSED, RM(TMP_REG3))); - compiler->cache_arg = 0; - compiler->cache_argw = 0; - return getput_arg(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0); + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= TMP_REG3) + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG3, SLJIT_UNUSED, RM(src))); else if (src & SLJIT_MEM) { if (getput_arg_fast(compiler, WORD_DATA | LOAD_DATA, TMP_REG3, src, srcw)) @@ -2274,7 +2228,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Conditional instructions */ /* --------------------------------------------------------------------- */ -static sljit_uw get_cc(sljit_si type) +static sljit_uw get_cc(int type) { switch (type) { case SLJIT_C_EQUAL: @@ -2316,11 +2270,11 @@ static sljit_uw get_cc(sljit_si type) return 0xd0000000; case SLJIT_C_OVERFLOW: - case SLJIT_C_FLOAT_UNORDERED: + case SLJIT_C_FLOAT_NAN: return 0x60000000; case SLJIT_C_NOT_OVERFLOW: - case SLJIT_C_FLOAT_ORDERED: + case SLJIT_C_FLOAT_NOT_NAN: return 0x70000000; default: /* SLJIT_JUMP */ @@ -2344,7 +2298,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { struct sljit_jump *jump; @@ -2385,7 +2339,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { struct sljit_jump *jump; @@ -2413,74 +2367,60 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil jump->addr = compiler->size; } else { - if (src <= TMP_REG3) + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(src)); SLJIT_ASSERT(src & SLJIT_MEM); - FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src, srcw)); + FAIL_IF(emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); return push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG2)); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { - sljit_si dst_r, flags = GET_ALL_FLAGS(op); - sljit_uw cc, ins; + int reg; + sljit_uw cc; CHECK_ERROR(); - check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + check_sljit_emit_cond_value(compiler, op, dst, dstw, type); ADJUST_LOCAL_OFFSET(dst, dstw); - ADJUST_LOCAL_OFFSET(src, srcw); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; - op = GET_OPCODE(op); cc = get_cc(type); - dst_r = (dst <= TMP_REG3) ? dst : TMP_REG2; + if (GET_OPCODE(op) == SLJIT_OR) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ORR_DP, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc); + if (op & SLJIT_SET_E) + return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))); + return SLJIT_SUCCESS; + } - if (op < SLJIT_ADD) { - EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 0)); - EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, dst_r, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); - return (dst_r == TMP_REG2) ? emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw) : SLJIT_SUCCESS; + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 0)); + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, TMP_REG1, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); +#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) + compiler->skip_checks = 1; +#endif + return emit_op(compiler, op, ALLOW_IMM, dst, dstw, TMP_REG1, 0, dst, dstw); } - ins = (op == SLJIT_AND ? AND_DP : (op == SLJIT_OR ? ORR_DP : EOR_DP)); - if ((op == SLJIT_OR || op == SLJIT_XOR) && dst <= TMP_REG3 && dst == src) { - EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst, dst, SRC2_IMM | 1) & ~COND_MASK) | cc); - /* The condition must always be set, even if the ORR/EOR is not executed above. */ - return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst))) : SLJIT_SUCCESS; - } + reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (src & SLJIT_MEM) { - FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); - src = TMP_REG1; - srcw = 0; - } else if (src & SLJIT_IMM) { - FAIL_IF(load_immediate(compiler, TMP_REG1, srcw)); - src = TMP_REG1; - srcw = 0; - } + EMIT_INSTRUCTION(EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 0)); + EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(MOV_DP, 0, reg, SLJIT_UNUSED, SRC2_IMM | 1) & ~COND_MASK) | cc); - EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 1) & ~COND_MASK) | cc); - EMIT_INSTRUCTION((EMIT_DATA_PROCESS_INS(ins, 0, dst_r, src, SRC2_IMM | 0) & ~COND_MASK) | (cc ^ 0x10000000)); - if (dst_r == TMP_REG2) - FAIL_IF(emit_op_mem2(compiler, WORD_DATA, TMP_REG2, dst, dstw, 0, 0)); - - return (flags & SLJIT_SET_E) ? push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, SET_FLAGS, TMP_REG1, SLJIT_UNUSED, RM(dst_r))) : SLJIT_SUCCESS; + if (reg == TMP_REG2) + return emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { struct sljit_const *const_; - sljit_si reg; + int reg; CHECK_ERROR_PTR(); check_sljit_emit_const(compiler, dst, dstw, init_value); @@ -2489,7 +2429,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const)); PTR_FAIL_IF(!const_); - reg = (dst <= TMP_REG3) ? dst : TMP_REG2; + reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, reg, TMP_PC, 0), init_value)); @@ -2500,7 +2440,8 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi set_const(const_, compiler); if (reg == TMP_REG2 && dst != SLJIT_UNUSED) - PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw)); + if (emit_op(compiler, SLJIT_MOV, ALLOW_ANY_IMM, dst, dstw, TMP_REG1, 0, TMP_REG2, 0)) + return NULL; return const_; } @@ -2509,7 +2450,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ad inline_set_jump_addr(addr, new_addr, 1); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { inline_set_const(addr, new_constant, 1); } diff --git a/harbour/src/3rd/pcre/sjconf.h b/harbour/src/3rd/pcre/sjconf.h index 68bc59d089..32c3b10437 100644 --- a/harbour/src/3rd/pcre/sjconf.h +++ b/harbour/src/3rd/pcre/sjconf.h @@ -47,7 +47,6 @@ /* #define SLJIT_CONFIG_PPC_32 1 */ /* #define SLJIT_CONFIG_PPC_64 1 */ /* #define SLJIT_CONFIG_MIPS_32 1 */ -/* #define SLJIT_CONFIG_SPARC_32 1 */ /* #define SLJIT_CONFIG_AUTO 1 */ /* #define SLJIT_CONFIG_UNSUPPORTED 1 */ diff --git a/harbour/src/3rd/pcre/sjconfi.h b/harbour/src/3rd/pcre/sjconfi.h index 3fdcbf9288..dce5328110 100644 --- a/harbour/src/3rd/pcre/sjconfi.h +++ b/harbour/src/3rd/pcre/sjconfi.h @@ -33,23 +33,18 @@ Feature detection (boolean) macros: SLJIT_32BIT_ARCHITECTURE : 32 bit architecture SLJIT_64BIT_ARCHITECTURE : 64 bit architecture - SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index - SLJIT_DOUBLE_SHIFT : the shift required to apply when accessing a double array by index + SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_w/sljit_uw array by index + SLJIT_FLOAT_SHIFT : the shift required to apply when accessing a double array by index SLJIT_LITTLE_ENDIAN : little endian architecture SLJIT_BIG_ENDIAN : big endian architecture SLJIT_UNALIGNED : allows unaligned memory accesses for non-fpu operations (only!) SLJIT_INDIRECT_CALL : see SLJIT_FUNC_OFFSET() for more information - SLJIT_RETURN_ADDRESS_OFFSET : a return instruction always adds this offset to the return address Types and useful macros: - sljit_sb, sljit_ub : signed and unsigned 8 bit byte - sljit_sh, sljit_uh : signed and unsigned 16 bit half-word (short) type - sljit_si, sljit_ui : signed and unsigned 32 bit integer type - sljit_sw, sljit_uw : signed and unsigned machine word, enough to store a pointer - sljit_p : unsgined pointer value (usually the same as sljit_uw, but - some 64 bit ABIs may use 32 bit pointers) - sljit_s : single precision floating point value - sljit_d : double precision floating point value + sljit_b, sljit_ub : signed and unsigned 8 bit byte + sljit_h, sljit_uh : signed and unsigned 16 bit half-word (short) type + sljit_i, sljit_ui : signed and unsigned 32 bit integer type + sljit_w, sljit_uw : signed and unsigned machine word, enough to store a pointer (same as intptr_t) SLJIT_CALL : C calling convention define for both calling JIT form C and C callbacks for JIT SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (compiler independent helper) */ @@ -62,7 +57,6 @@ || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ - || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ || (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)) #error "An architecture must be selected" @@ -77,7 +71,6 @@ + (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \ - + (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \ + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \ + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2 #error "Multiple architectures are selected" @@ -100,14 +93,12 @@ #else #define SLJIT_CONFIG_ARM_V5 1 #endif -#elif defined(__ppc64__) || defined(__powerpc64__) || defined(_ARCH_PPC64) || (defined(_POWER) && defined(__64BIT__)) +#elif defined(__ppc64__) || defined(__powerpc64__) #define SLJIT_CONFIG_PPC_64 1 -#elif defined(__ppc__) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(_ARCH_PWR) || defined(_ARCH_PWR2) || defined(_POWER) +#elif defined(__ppc__) || defined(__powerpc__) #define SLJIT_CONFIG_PPC_32 1 #elif defined(__mips__) #define SLJIT_CONFIG_MIPS_32 1 -#elif defined(__sparc__) || defined(__sparc) -#define SLJIT_CONFIG_SPARC_32 1 #else /* Unsupported architecture */ #define SLJIT_CONFIG_UNSUPPORTED 1 @@ -223,12 +214,6 @@ #define SLJIT_CACHE_FLUSH(from, to) \ ppc_cache_flush((from), (to)) -#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - -/* The __clear_cache() implementation of GCC is a dummy function on Sparc. */ -#define SLJIT_CACHE_FLUSH(from, to) \ - sparc_cache_flush((from), (to)) - #else /* Calls __ARM_NR_cacheflush on ARM-Linux. */ @@ -241,15 +226,15 @@ /* 8 bit byte type. */ typedef unsigned char sljit_ub; -typedef signed char sljit_sb; +typedef signed char sljit_b; /* 16 bit half-word type. */ typedef unsigned short int sljit_uh; -typedef signed short int sljit_sh; +typedef signed short int sljit_h; /* 32 bit integer type. */ typedef unsigned int sljit_ui; -typedef signed int sljit_si; +typedef signed int sljit_i; /* Machine word type. Can encapsulate a pointer. 32 bit for 32 bit machines. @@ -258,35 +243,26 @@ typedef signed int sljit_si; /* Just to have something. */ #define SLJIT_WORD_SHIFT 0 typedef unsigned long int sljit_uw; -typedef long int sljit_sw; +typedef long int sljit_w; #elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define SLJIT_32BIT_ARCHITECTURE 1 #define SLJIT_WORD_SHIFT 2 typedef unsigned int sljit_uw; -typedef int sljit_sw; +typedef int sljit_w; #else #define SLJIT_64BIT_ARCHITECTURE 1 #define SLJIT_WORD_SHIFT 3 #ifdef _WIN32 typedef unsigned __int64 sljit_uw; -typedef __int64 sljit_sw; +typedef __int64 sljit_w; #else typedef unsigned long int sljit_uw; -typedef long int sljit_sw; +typedef long int sljit_w; #endif #endif -typedef sljit_uw sljit_p; - -/* Floating point types. */ -typedef float sljit_s; -typedef double sljit_d; - -/* Shift for pointer sized data. */ -#define SLJIT_POINTER_SHIFT SLJIT_WORD_SHIFT - -/* Shift for double precision sized data. */ -#define SLJIT_DOUBLE_SHIFT 3 +/* Double precision. */ +#define SLJIT_FLOAT_SHIFT 3 #ifndef SLJIT_W @@ -313,24 +289,20 @@ typedef double sljit_d; #define SLJIT_CALL #endif -#elif defined(_MSC_VER) - -#define SLJIT_CALL __fastcall -#define SLJIT_X86_32_FASTCALL 1 - -#elif defined(__BORLANDC__) +#elif defined(_WIN32) +#ifdef __BORLANDC__ #define SLJIT_CALL __msfastcall +#else /* __BORLANDC__ */ +#define SLJIT_CALL __fastcall +#endif /* __BORLANDC__ */ #define SLJIT_X86_32_FASTCALL 1 -#else /* Unknown compiler. */ - -/* The cdecl attribute is the default. */ -#define SLJIT_CALL - +#else /* defined(_WIN32) */ +#define SLJIT_CALL __stdcall #endif -#else /* Non x86-32 architectures. */ +#else /* Other architectures. */ #define SLJIT_CALL @@ -341,9 +313,7 @@ typedef double sljit_d; #if !defined(SLJIT_BIG_ENDIAN) && !defined(SLJIT_LITTLE_ENDIAN) /* These macros are useful for the application. */ -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \ - || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \ - || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #define SLJIT_BIG_ENDIAN 1 #elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) @@ -369,21 +339,11 @@ typedef double sljit_d; #error "Exactly one endianness must be selected" #endif -#ifndef SLJIT_INDIRECT_CALL -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32 && defined _AIX) -/* It seems certain ppc compilers use an indirect addressing for functions - which makes things complicated. */ +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +/* It seems ppc64 compilers use an indirect addressing for functions. + It makes things really complicated. */ #define SLJIT_INDIRECT_CALL 1 #endif -#endif /* SLJIT_INDIRECT_CALL */ - -#ifndef SLJIT_RETURN_ADDRESS_OFFSET -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -#define SLJIT_RETURN_ADDRESS_OFFSET 8 -#else -#define SLJIT_RETURN_ADDRESS_OFFSET 0 -#endif -#endif /* SLJIT_RETURN_ADDRESS_OFFSET */ #ifndef SLJIT_SSE2 @@ -421,29 +381,18 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); #define SLJIT_FREE_EXEC(ptr) sljit_free_exec(ptr) #endif -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) +#if (defined SLJIT_DEBUG && SLJIT_DEBUG) || (defined SLJIT_VERBOSE && SLJIT_VERBOSE) #include #endif #if (defined SLJIT_DEBUG && SLJIT_DEBUG) -#if !defined(SLJIT_ASSERT) || !defined(SLJIT_ASSERT_STOP) - -/* SLJIT_HALT_PROCESS must halt the process. */ -#ifndef SLJIT_HALT_PROCESS -#include - -#define SLJIT_HALT_PROCESS() \ - abort(); -#endif /* !SLJIT_HALT_PROCESS */ - -#include - -#endif /* !SLJIT_ASSERT || !SLJIT_ASSERT_STOP */ - /* Feel free to redefine these two macros. */ #ifndef SLJIT_ASSERT +#define SLJIT_HALT_PROCESS() \ + *((int*)0) = 0 + #define SLJIT_ASSERT(x) \ do { \ if (SLJIT_UNLIKELY(!(x))) { \ @@ -466,7 +415,6 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr); #else /* (defined SLJIT_DEBUG && SLJIT_DEBUG) */ -/* Forcing empty, but valid statements. */ #undef SLJIT_ASSERT #undef SLJIT_ASSERT_STOP diff --git a/harbour/src/3rd/pcre/sjexeca.c b/harbour/src/3rd/pcre/sjexeca.c index 75a38991d5..f66744df82 100644 --- a/harbour/src/3rd/pcre/sjexeca.c +++ b/harbour/src/3rd/pcre/sjexeca.c @@ -52,7 +52,7 @@ The unused blocks are stored in a chain list pointed by free_blocks. This list is useful if we need to find a suitable memory area when the allocator is called. - + When a block is freed, the new free block is connected to its adjacent free blocks if possible. @@ -83,7 +83,7 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size) { - return VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); + return VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); } static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size) @@ -94,20 +94,11 @@ static SLJIT_INLINE void free_chunk(void* chunk, sljit_uw size) #else +#include + static SLJIT_INLINE void* alloc_chunk(sljit_uw size) { - void* retval; - -#ifdef MAP_ANON - retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); -#else - if (dev_zero < 0) { - if (open_dev_zero()) - return NULL; - } - retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0); -#endif - + void* retval = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0); return (retval != MAP_FAILED) ? retval : NULL; } @@ -211,10 +202,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size) chunk_size = (size + sizeof(struct block_header) + CHUNK_SIZE - 1) & CHUNK_MASK; header = (struct block_header*)alloc_chunk(chunk_size); - if (!header) { - allocator_release_lock(); - return NULL; - } + PTR_FAIL_IF(!header); chunk_size -= sizeof(struct block_header); total_size += chunk_size; @@ -249,14 +237,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void* ptr) struct free_block* free_block; allocator_grab_lock(); - header = AS_BLOCK_HEADER(ptr, -(sljit_sw)sizeof(struct block_header)); + header = AS_BLOCK_HEADER(ptr, -(sljit_w)sizeof(struct block_header)); allocated_size -= header->size; /* Connecting free blocks together if possible. */ /* If header->prev_size == 0, free_block will equal to header. In this case, free_block->header.size will be > 0. */ - free_block = AS_FREE_BLOCK(header, -(sljit_sw)header->prev_size); + free_block = AS_FREE_BLOCK(header, -(sljit_w)header->prev_size); if (SLJIT_UNLIKELY(!free_block->header.size)) { free_block->size += header->size; header = AS_BLOCK_HEADER(free_block, free_block->size); diff --git a/harbour/src/3rd/pcre/sjlir.c b/harbour/src/3rd/pcre/sjlir.c index cb4482620a..300b0ff913 100644 --- a/harbour/src/3rd/pcre/sjlir.c +++ b/harbour/src/3rd/pcre/sjlir.c @@ -89,10 +89,7 @@ ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C)) #define GET_ALL_FLAGS(op) \ - ((op) & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) - -#define TYPE_CAST_NEEDED(op) \ - (((op) >= SLJIT_MOV_UB && (op) <= SLJIT_MOV_SH) || ((op) >= SLJIT_MOVU_UB && (op) <= SLJIT_MOVU_SH)) + ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS)) #define BUF_SIZE 4096 @@ -108,127 +105,93 @@ /* SLJIT_REWRITABLE_JUMP is 0x1000. */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -# 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 #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) -# define IS_BL 0x4 -# define PATCH_B 0x8 + #define IS_BL 0x4 + #define PATCH_B 0x8 #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -# define CPOOL_SIZE 512 + #define CPOOL_SIZE 512 #endif #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) -# define IS_COND 0x04 -# define IS_BL 0x08 + #define IS_CONDITIONAL 0x04 + #define IS_BL 0x08 /* cannot be encoded as branch */ -# define B_TYPE0 0x00 + #define B_TYPE0 0x00 /* conditional + imm8 */ -# define B_TYPE1 0x10 + #define B_TYPE1 0x10 /* conditional + imm20 */ -# define B_TYPE2 0x20 + #define B_TYPE2 0x20 /* IT + imm24 */ -# define B_TYPE3 0x30 + #define B_TYPE3 0x30 /* imm11 */ -# define B_TYPE4 0x40 + #define B_TYPE4 0x40 /* imm24 */ -# define B_TYPE5 0x50 + #define B_TYPE5 0x50 /* BL + imm24 */ -# define BL_TYPE6 0x60 + #define BL_TYPE6 0x60 /* 0xf00 cc code for branches */ #endif #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -# define UNCOND_B 0x04 -# define PATCH_B 0x08 -# define ABSOLUTE_B 0x10 + #define UNCOND_B 0x04 + #define PATCH_B 0x08 + #define ABSOLUTE_B 0x10 #endif #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define IS_MOVABLE 0x04 -# define IS_JAL 0x08 -# define IS_BIT26_COND 0x10 -# define IS_BIT16_COND 0x20 + #define IS_MOVABLE 0x04 + #define IS_JAL 0x08 + #define IS_BIT26_COND 0x10 + #define IS_BIT16_COND 0x20 -# define IS_COND (IS_BIT26_COND | IS_BIT16_COND) + #define IS_COND (IS_BIT26_COND | IS_BIT16_COND) -# define PATCH_B 0x40 -# define PATCH_J 0x80 + #define PATCH_B 0x40 + #define PATCH_J 0x80 /* instruction types */ -# define MOVABLE_INS 0 + #define UNMOVABLE_INS 0 /* 1 - 31 last destination register */ + #define FCSR_FCC 32 /* no destination (i.e: store) */ -# define UNMOVABLE_INS 32 - /* FPU status register */ -# define FCSR_FCC 33 -#endif - -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -# define IS_MOVABLE 0x04 -# define IS_COND 0x08 -# define IS_CALL 0x10 - -# define PATCH_B 0x20 -# define PATCH_CALL 0x40 - - /* instruction types */ -# define MOVABLE_INS 0 - /* 1 - 31 last destination register */ - /* no destination (i.e: store) */ -# define UNMOVABLE_INS 32 - -# define DST_INS_MASK 0xff - - /* ICC_SET is the same as SET_FLAGS. */ -# define ICC_IS_SET (1 << 23) -# define FCC_IS_SET (1 << 24) + #define MOVABLE_INS 33 #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) #define SLJIT_HAS_VARIABLE_LOCALS_OFFSET 1 -#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) -#define FIXED_LOCALS_OFFSET (3 * sizeof(sljit_sw)) -#endif #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 #ifdef _WIN64 -#define FIXED_LOCALS_OFFSET ((4 + 2) * sizeof(sljit_sw)) +#define FIXED_LOCALS_OFFSET (4 * sizeof(sljit_w)) #else -#define FIXED_LOCALS_OFFSET (sizeof(sljit_sw)) +#define FIXED_LOCALS_OFFSET (sizeof(sljit_w)) #endif #endif -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) -#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) -#define FIXED_LOCALS_OFFSET ((6 + 8) * sizeof(sljit_sw)) -#else -#define FIXED_LOCALS_OFFSET (2 * sizeof(sljit_sw)) -#endif -#endif - -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 -#define FIXED_LOCALS_OFFSET ((6 + 8) * sizeof(sljit_sw)) -#endif - #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 -#define FIXED_LOCALS_OFFSET (4 * sizeof(sljit_sw)) +#define FIXED_LOCALS_OFFSET (4 * sizeof(sljit_w)) #endif -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 -#define FIXED_LOCALS_OFFSET (23 * sizeof(sljit_sw)) +#define FIXED_LOCALS_OFFSET (2 * sizeof(sljit_w)) +#endif + +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) +#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1 +#define FIXED_LOCALS_OFFSET ((7 + 8) * sizeof(sljit_w)) #endif #if (defined SLJIT_HAS_VARIABLE_LOCALS_OFFSET && SLJIT_HAS_VARIABLE_LOCALS_OFFSET) @@ -270,7 +233,7 @@ #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || ((defined SLJIT_SSE2 && SLJIT_SSE2) && ((defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64))) #define SLJIT_NEEDS_COMPILER_INIT 1 -static sljit_si compiler_initialized = 0; +static int compiler_initialized = 0; /* A thread safe initialization. */ static void init_compiler(void); #endif @@ -283,18 +246,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) SLJIT_ZEROMEM(compiler, sizeof(struct sljit_compiler)); SLJIT_COMPILE_ASSERT( - sizeof(sljit_sb) == 1 && sizeof(sljit_ub) == 1 - && sizeof(sljit_sh) == 2 && sizeof(sljit_uh) == 2 - && sizeof(sljit_si) == 4 && sizeof(sljit_ui) == 4 - && (sizeof(sljit_p) == 4 || sizeof(sljit_p) == 8) - && sizeof(sljit_p) <= sizeof(sljit_sw) - && (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8) - && (sizeof(sljit_uw) == 4 || sizeof(sljit_uw) == 8), + sizeof(sljit_b) == 1 && sizeof(sljit_ub) == 1 + && sizeof(sljit_h) == 2 && sizeof(sljit_uh) == 2 + && sizeof(sljit_i) == 4 && sizeof(sljit_ui) == 4 + && ((sizeof(sljit_w) == 4 && sizeof(sljit_uw) == 4) || (sizeof(sljit_w) == 8 && sizeof(sljit_uw) == 8)), invalid_integer_types); - SLJIT_COMPILE_ASSERT(SLJIT_INT_OP == SLJIT_SINGLE_OP, - int_op_and_single_op_must_be_the_same); - SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_SINGLE_OP, - rewritable_jump_and_single_op_must_not_be_the_same); /* Only the non-zero members must be set. */ compiler->error = SLJIT_SUCCESS; @@ -316,7 +272,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) compiler->abuf->next = NULL; compiler->abuf->used_size = 0; - compiler->scratches = -1; + compiler->temporaries = -1; compiler->saveds = -1; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -339,10 +295,6 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void) compiler->delay_slot = UNMOVABLE_INS; #endif -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - compiler->delay_slot = UNMOVABLE_INS; -#endif - #if (defined SLJIT_NEEDS_COMPILER_INIT && SLJIT_NEEDS_COMPILER_INIT) if (!compiler_initialized) { init_compiler(); @@ -384,7 +336,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) /* Remove thumb mode flag. */ SLJIT_FREE_EXEC((void*)((sljit_uw)code & ~0x1)); } -#elif (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) +#elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) { /* Resolve indirection. */ @@ -422,13 +374,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw /* Private functions */ /* --------------------------------------------------------------------- */ -static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size) +static void* ensure_buf(struct sljit_compiler *compiler, int size) { sljit_ub *ret; struct sljit_memory_fragment *new_frag; - SLJIT_ASSERT(size <= 256); - if (compiler->buf->used_size + size <= (BUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) { + if (compiler->buf->used_size + size <= (int)(BUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) { ret = compiler->buf->memory + compiler->buf->used_size; compiler->buf->used_size += size; return ret; @@ -441,13 +392,12 @@ static void* ensure_buf(struct sljit_compiler *compiler, sljit_uw size) return new_frag->memory; } -static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size) +static void* ensure_abuf(struct sljit_compiler *compiler, int size) { sljit_ub *ret; struct sljit_memory_fragment *new_frag; - SLJIT_ASSERT(size <= 256); - if (compiler->abuf->used_size + size <= (ABUF_SIZE - (sljit_uw)SLJIT_OFFSETOF(struct sljit_memory_fragment, memory))) { + if (compiler->abuf->used_size + size <= (int)(ABUF_SIZE - sizeof(sljit_uw) - sizeof(void*))) { ret = compiler->abuf->memory + compiler->abuf->used_size; compiler->abuf->used_size += size; return ret; @@ -460,7 +410,7 @@ static void* ensure_abuf(struct sljit_compiler *compiler, sljit_uw size) return new_frag->memory; } -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size) { CHECK_ERROR_PTR(); @@ -503,7 +453,7 @@ static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compi compiler->last_label = label; } -static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_si flags) +static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, int flags) { jump->next = NULL; jump->flags = flags; @@ -548,8 +498,8 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp case SLJIT_MUL: \ SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \ break; \ - case SLJIT_CMPD: \ - SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ + case SLJIT_FCMP: \ + SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_SET_S))); \ break; \ case SLJIT_ADD: \ @@ -561,30 +511,19 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp case SLJIT_SUBC: \ SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))); \ break; \ - case SLJIT_BREAKPOINT: \ - case SLJIT_NOP: \ - case SLJIT_UMUL: \ - case SLJIT_SMUL: \ - case SLJIT_MOV: \ - case SLJIT_MOV_P: \ - case SLJIT_MOVU: \ - case SLJIT_MOVU_P: \ + default: \ /* Nothing allowed */ \ SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ break; \ - default: \ - /* Only SLJIT_INT_OP or SLJIT_SINGLE_OP is allowed. */ \ - SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \ - break; \ } #define FUNCTION_CHECK_IS_REG(r) \ ((r) == SLJIT_UNUSED || \ - ((r) >= SLJIT_SCRATCH_REG1 && (r) <= SLJIT_SCRATCH_REG1 - 1 + compiler->scratches) || \ + ((r) >= SLJIT_TEMPORARY_REG1 && (r) <= SLJIT_TEMPORARY_REG1 - 1 + compiler->temporaries) || \ ((r) >= SLJIT_SAVED_REG1 && (r) <= SLJIT_SAVED_REG1 - 1 + compiler->saveds)) #define FUNCTION_CHECK_SRC(p, i) \ - SLJIT_ASSERT(compiler->scratches != -1 && compiler->saveds != -1); \ + SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \ if (FUNCTION_CHECK_IS_REG(p)) \ SLJIT_ASSERT((i) == 0 && (p) != SLJIT_UNUSED); \ else if ((p) == SLJIT_IMM) \ @@ -603,7 +542,7 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp SLJIT_ASSERT_STOP(); #define FUNCTION_CHECK_DST(p, i) \ - SLJIT_ASSERT(compiler->scratches != -1 && compiler->saveds != -1); \ + SLJIT_ASSERT(compiler->temporaries != -1 && compiler->saveds != -1); \ if (FUNCTION_CHECK_IS_REG(p)) \ SLJIT_ASSERT((i) == 0); \ else if ((p) == (SLJIT_MEM1(SLJIT_LOCALS_REG))) \ @@ -620,7 +559,7 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp SLJIT_ASSERT_STOP(); #define FUNCTION_FCHECK(p, i) \ - if ((p) >= SLJIT_FLOAT_REG1 && (p) <= SLJIT_FLOAT_REG6) \ + if ((p) >= SLJIT_FLOAT_REG1 && (p) <= SLJIT_FLOAT_REG4) \ SLJIT_ASSERT(i == 0); \ else if ((p) & SLJIT_MEM) { \ SLJIT_ASSERT(FUNCTION_CHECK_IS_REG((p) & 0xf)); \ @@ -635,7 +574,10 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp SLJIT_ASSERT_STOP(); #define FUNCTION_CHECK_OP1() \ - if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_P) { \ + if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \ + SLJIT_ASSERT(!GET_ALL_FLAGS(op)); \ + } \ + if (GET_OPCODE(op) >= SLJIT_MOVU && GET_OPCODE(op) <= SLJIT_MOVU_SI) { \ SLJIT_ASSERT(!(src & SLJIT_MEM) || (src & 0xf) != SLJIT_LOCALS_REG); \ SLJIT_ASSERT(!(dst & SLJIT_MEM) || (dst & 0xf) != SLJIT_LOCALS_REG); \ if ((src & SLJIT_MEM) && (src & 0xf)) \ @@ -658,18 +600,17 @@ static char* reg_names[] = { }; static char* freg_names[] = { - (char*)"", (char*)"float_r1", (char*)"float_r2", (char*)"float_r3", - (char*)"float_r4", (char*)"float_r5", (char*)"float_r6" + (char*)"", (char*)"float_r1", (char*)"float_r2", (char*)"float_r3", (char*)"float_r4" }; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) #ifdef _WIN64 -# define SLJIT_PRINT_D "I64" + #define SLJIT_PRINT_D "I64" #else -# define SLJIT_PRINT_D "l" + #define SLJIT_PRINT_D "l" #endif #else -# define SLJIT_PRINT_D "" + #define SLJIT_PRINT_D "" #endif #define sljit_verbose_param(p, i) \ @@ -721,18 +662,18 @@ static SLJIT_CONST char* op_names[] = { (char*)"umul", (char*)"smul", (char*)"udiv", (char*)"sdiv", /* op1 */ (char*)"mov", (char*)"mov.ub", (char*)"mov.sb", (char*)"mov.uh", - (char*)"mov.sh", (char*)"mov.ui", (char*)"mov.si", (char*)"mov.p", - (char*)"movu", (char*)"movu.ub", (char*)"movu.sb", (char*)"movu.uh", - (char*)"movu.sh", (char*)"movu.ui", (char*)"movu.si", (char*)"movu.p", - (char*)"not", (char*)"neg", (char*)"clz", + (char*)"mov.sh", (char*)"mov.ui", (char*)"mov.si", (char*)"movu", + (char*)"movu.ub", (char*)"movu.sb", (char*)"movu.uh", (char*)"movu.sh", + (char*)"movu.ui", (char*)"movu.si", (char*)"not", (char*)"neg", + (char*)"clz", /* op2 */ (char*)"add", (char*)"addc", (char*)"sub", (char*)"subc", (char*)"mul", (char*)"and", (char*)"or", (char*)"xor", (char*)"shl", (char*)"lshr", (char*)"ashr", /* fop1 */ - (char*)"cmp", (char*)"mov", (char*)"neg", (char*)"abs", + (char*)"fcmp", (char*)"fmov", (char*)"fneg", (char*)"fabs", /* fop2 */ - (char*)"add", (char*)"sub", (char*)"mul", (char*)"div" + (char*)"fadd", (char*)"fsub", (char*)"fmul", (char*)"fdiv" }; static char* jump_names[] = { @@ -746,7 +687,7 @@ static char* jump_names[] = { (char*)"c_float_equal", (char*)"c_float_not_equal", (char*)"c_float_less", (char*)"c_float_greater_equal", (char*)"c_float_greater", (char*)"c_float_less_equal", - (char*)"c_float_unordered", (char*)"c_float_ordered", + (char*)"c_float_nan", (char*)"c_float_not_nan", (char*)"jump", (char*)"fast_call", (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3" }; @@ -776,32 +717,32 @@ static SLJIT_INLINE void check_sljit_generate_code(struct sljit_compiler *compil #endif } -static SLJIT_INLINE void check_sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +static SLJIT_INLINE void check_sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(scratches); + SLJIT_UNUSED_ARG(temporaries); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT(args >= 0 && args <= 3); - SLJIT_ASSERT(scratches >= 0 && scratches <= SLJIT_NO_TMP_REGISTERS); + SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS); SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS); SLJIT_ASSERT(args <= saveds); SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " enter args=%d scratches=%d saveds=%d local_size=%d\n", args, scratches, saveds, local_size); + fprintf(compiler->verbose, " enter args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size); #endif } -static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(scratches); + SLJIT_UNUSED_ARG(temporaries); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); @@ -813,17 +754,17 @@ static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler #endif SLJIT_ASSERT(args >= 0 && args <= 3); - SLJIT_ASSERT(scratches >= 0 && scratches <= SLJIT_NO_TMP_REGISTERS); + SLJIT_ASSERT(temporaries >= 0 && temporaries <= SLJIT_NO_TMP_REGISTERS); SLJIT_ASSERT(saveds >= 0 && saveds <= SLJIT_NO_GEN_REGISTERS); SLJIT_ASSERT(args <= saveds); SLJIT_ASSERT(local_size >= 0 && local_size <= SLJIT_MAX_LOCAL_SIZE); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " set_context args=%d scratches=%d saveds=%d local_size=%d\n", args, scratches, saveds, local_size); + fprintf(compiler->verbose, " set_context args=%d temporaries=%d saveds=%d local_size=%d\n", args, temporaries, saveds, local_size); #endif } -static SLJIT_INLINE void check_sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE void check_sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); @@ -833,7 +774,7 @@ static SLJIT_INLINE void check_sljit_emit_return(struct sljit_compiler *compiler #if (defined SLJIT_DEBUG && SLJIT_DEBUG) if (op != SLJIT_UNUSED) { - SLJIT_ASSERT(op >= SLJIT_MOV && op <= SLJIT_MOV_P); + SLJIT_ASSERT(op >= SLJIT_MOV && op <= SLJIT_MOV_SI); FUNCTION_CHECK_SRC(src, srcw); } else @@ -852,7 +793,7 @@ static SLJIT_INLINE void check_sljit_emit_return(struct sljit_compiler *compiler #endif } -static SLJIT_INLINE void check_sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +static SLJIT_INLINE void check_sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); @@ -871,7 +812,7 @@ static SLJIT_INLINE void check_sljit_emit_fast_enter(struct sljit_compiler *comp #endif } -static SLJIT_INLINE void check_sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE void check_sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); @@ -890,7 +831,7 @@ static SLJIT_INLINE void check_sljit_emit_fast_return(struct sljit_compiler *com #endif } -static SLJIT_INLINE void check_sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +static SLJIT_INLINE void check_sljit_emit_op0(struct sljit_compiler *compiler, int op) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); @@ -904,9 +845,9 @@ static SLJIT_INLINE void check_sljit_emit_op0(struct sljit_compiler *compiler, s #endif } -static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); @@ -933,8 +874,7 @@ static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, s #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)], - !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_S) ? "" : ".s", !(op & SLJIT_SET_U) ? "" : ".u", - !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K"); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(src, srcw); @@ -943,10 +883,10 @@ static SLJIT_INLINE void check_sljit_emit_op1(struct sljit_compiler *compiler, s #endif } -static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); @@ -975,8 +915,7 @@ static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, s #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { fprintf(compiler->verbose, " %s%s%s%s%s%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)], - !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_S) ? "" : ".s", !(op & SLJIT_SET_U) ? "" : ".u", - !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S", !(op & SLJIT_SET_U) ? "" : "U", !(op & SLJIT_SET_O) ? "" : "O", !(op & SLJIT_SET_C) ? "" : "C", !(op & SLJIT_KEEP_FLAGS) ? "" : "K"); sljit_verbose_param(dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_param(src1, src1w); @@ -987,14 +926,14 @@ static SLJIT_INLINE void check_sljit_emit_op2(struct sljit_compiler *compiler, s #endif } -static SLJIT_INLINE void check_sljit_get_register_index(sljit_si reg) +static SLJIT_INLINE void check_sljit_get_register_index(int reg) { SLJIT_UNUSED_ARG(reg); SLJIT_ASSERT(reg > 0 && reg <= SLJIT_NO_REGISTERS); } static SLJIT_INLINE void check_sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) + void *instruction, int size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(instruction); @@ -1002,9 +941,9 @@ static SLJIT_INLINE void check_sljit_emit_op_custom(struct sljit_compiler *compi SLJIT_ASSERT(instruction); } -static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); @@ -1022,7 +961,7 @@ static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, #endif SLJIT_ASSERT(sljit_is_fpu_available()); - SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_CMPD && GET_OPCODE(op) <= SLJIT_ABSD); + SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FCMP && GET_OPCODE(op) <= SLJIT_FABS); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_OP(); FUNCTION_FCHECK(src, srcw); @@ -1030,8 +969,8 @@ static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s%s%s ", op_names[GET_OPCODE(op)], (op & SLJIT_SINGLE_OP) ? "s" : "d", - !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_SET_S) ? "" : ".s"); + fprintf(compiler->verbose, " %s%s%s ", op_names[GET_OPCODE(op)], + !(op & SLJIT_SET_E) ? "" : "E", !(op & SLJIT_SET_S) ? "" : "S"); sljit_verbose_fparam(dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(src, srcw); @@ -1040,10 +979,10 @@ static SLJIT_INLINE void check_sljit_emit_fop1(struct sljit_compiler *compiler, #endif } -static SLJIT_INLINE void check_sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE void check_sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); @@ -1056,7 +995,7 @@ static SLJIT_INLINE void check_sljit_emit_fop2(struct sljit_compiler *compiler, SLJIT_UNUSED_ARG(src2w); SLJIT_ASSERT(sljit_is_fpu_available()); - SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_ADDD && GET_OPCODE(op) <= SLJIT_DIVD); + SLJIT_ASSERT(GET_OPCODE(op) >= SLJIT_FADD && GET_OPCODE(op) <= SLJIT_FDIV); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_OP(); FUNCTION_FCHECK(src1, src1w); @@ -1065,7 +1004,7 @@ static SLJIT_INLINE void check_sljit_emit_fop2(struct sljit_compiler *compiler, #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %s%s ", op_names[GET_OPCODE(op)], (op & SLJIT_SINGLE_OP) ? "s" : "d"); + fprintf(compiler->verbose, " %s ", op_names[GET_OPCODE(op)]); sljit_verbose_fparam(dst, dstw); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(src1, src1w); @@ -1087,7 +1026,7 @@ static SLJIT_INLINE void check_sljit_emit_label(struct sljit_compiler *compiler) #endif } -static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, int type) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); @@ -1104,13 +1043,13 @@ static SLJIT_INLINE void check_sljit_emit_jump(struct sljit_compiler *compiler, SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_CALL3); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) - fprintf(compiler->verbose, " jump%s<%s>\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]); + fprintf(compiler->verbose, " jump%s <%s>\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); #endif } -static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1119,7 +1058,7 @@ static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, s SLJIT_UNUSED_ARG(src2); SLJIT_UNUSED_ARG(src2w); - SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_INT_OP))); + SLJIT_ASSERT(!(type & ~(0xff | SLJIT_INT_OP | SLJIT_REWRITABLE_JUMP))); SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_C_SIG_LESS_EQUAL); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_SRC(src1, src1w); @@ -1127,7 +1066,7 @@ static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, s #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %scmp%s<%s> ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]); + fprintf(compiler->verbose, " %scmp%s <%s> ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); sljit_verbose_param(src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_param(src2, src2w); @@ -1136,9 +1075,9 @@ static SLJIT_INLINE void check_sljit_emit_cmp(struct sljit_compiler *compiler, s #endif } -static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1148,16 +1087,15 @@ static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, SLJIT_UNUSED_ARG(src2w); SLJIT_ASSERT(sljit_is_fpu_available()); - SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_SINGLE_OP))); - SLJIT_ASSERT((type & 0xff) >= SLJIT_C_FLOAT_EQUAL && (type & 0xff) <= SLJIT_C_FLOAT_ORDERED); + SLJIT_ASSERT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP))); + SLJIT_ASSERT((type & 0xff) >= SLJIT_C_FLOAT_EQUAL && (type & 0xff) <= SLJIT_C_FLOAT_NOT_NAN); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_FCHECK(src1, src1w); FUNCTION_FCHECK(src2, src2w); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " %scmp%s<%s> ", (type & SLJIT_SINGLE_OP) ? "s" : "d", - !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]); + fprintf(compiler->verbose, " fcmp%s <%s> ", !(type & SLJIT_REWRITABLE_JUMP) ? "" : "R", jump_names[type & 0xff]); sljit_verbose_fparam(src1, src1w); fprintf(compiler->verbose, ", "); sljit_verbose_fparam(src2, src2w); @@ -1166,7 +1104,7 @@ static SLJIT_INLINE void check_sljit_emit_fcmp(struct sljit_compiler *compiler, #endif } -static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); @@ -1174,68 +1112,45 @@ static SLJIT_INLINE void check_sljit_emit_ijump(struct sljit_compiler *compiler, SLJIT_UNUSED_ARG(src); SLJIT_UNUSED_ARG(srcw); -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) - if (SLJIT_UNLIKELY(compiler->skip_checks)) { - compiler->skip_checks = 0; - return; - } -#endif - SLJIT_ASSERT(type >= SLJIT_JUMP && type <= SLJIT_CALL3); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) FUNCTION_CHECK_SRC(src, srcw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " ijump<%s> ", jump_names[type]); + fprintf(compiler->verbose, " ijump <%s> ", jump_names[type]); sljit_verbose_param(src, srcw); fprintf(compiler->verbose, "\n"); } #endif } -static SLJIT_INLINE void check_sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +static SLJIT_INLINE void check_sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); SLJIT_UNUSED_ARG(type); SLJIT_ASSERT(type >= SLJIT_C_EQUAL && type < SLJIT_JUMP); - SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_MOV_UI || GET_OPCODE(op) == SLJIT_MOV_SI - || (GET_OPCODE(op) >= SLJIT_AND && GET_OPCODE(op) <= SLJIT_XOR)); - SLJIT_ASSERT((op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C)) == 0); - SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS)); + SLJIT_ASSERT(op == SLJIT_MOV || GET_OPCODE(op) == SLJIT_OR); + SLJIT_ASSERT(GET_ALL_FLAGS(op) == 0 || GET_ALL_FLAGS(op) == SLJIT_SET_E || GET_ALL_FLAGS(op) == SLJIT_KEEP_FLAGS); #if (defined SLJIT_DEBUG && SLJIT_DEBUG) - if (GET_OPCODE(op) < SLJIT_ADD) { - SLJIT_ASSERT(src == SLJIT_UNUSED && srcw == 0); - } else { - SLJIT_ASSERT(src == dst && srcw == dstw); - } FUNCTION_CHECK_DST(dst, dstw); #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) if (SLJIT_UNLIKELY(!!compiler->verbose)) { - fprintf(compiler->verbose, " op_flags<%s%s%s%s> ", !(op & SLJIT_INT_OP) ? "" : "i", - op_names[GET_OPCODE(op)], !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k"); + fprintf(compiler->verbose, " cond_set%s%s <%s> ", !(op & SLJIT_SET_E) ? "" : "E", + !(op & SLJIT_KEEP_FLAGS) ? "" : "K", op_names[GET_OPCODE(op)]); sljit_verbose_param(dst, dstw); - if (src != SLJIT_UNUSED) { - fprintf(compiler->verbose, ", "); - sljit_verbose_param(src, srcw); - } fprintf(compiler->verbose, ", <%s>\n", jump_names[type]); } #endif } -static SLJIT_INLINE void check_sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +static SLJIT_INLINE void check_sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); @@ -1254,7 +1169,7 @@ static SLJIT_INLINE void check_sljit_get_local_base(struct sljit_compiler *compi #endif } -static SLJIT_INLINE void check_sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +static SLJIT_INLINE void check_sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { /* If debug and verbose are disabled, all arguments are unused. */ SLJIT_UNUSED_ARG(compiler); @@ -1274,18 +1189,17 @@ static SLJIT_INLINE void check_sljit_emit_const(struct sljit_compiler *compiler, #endif } -static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE int emit_mov_before_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { /* Return if don't need to do anything. */ if (op == SLJIT_UNUSED) return SLJIT_SUCCESS; #if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE) - /* At the moment the pointer size is always equal to sljit_sw. May be changed in the future. */ - if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_P)) + if (src == SLJIT_RETURN_REG && op == SLJIT_MOV) return SLJIT_SUCCESS; #else - if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P)) + if (src == SLJIT_RETURN_REG && (op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI)) return SLJIT_SUCCESS; #endif @@ -1322,34 +1236,32 @@ static SLJIT_INLINE sljit_si emit_mov_before_return(struct sljit_compiler *compi #define SLJIT_CPUINFO SLJIT_CPUINFO_PART1 SLJIT_CPUINFO_PART2 SLJIT_CPUINFO_PART3 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) -# include "sjx86c.c" + #include "sjx86c.c" #elif (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -# include "sjx86c.c" + #include "sjx86c.c" #elif (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) -# include "sjarmv5.c" + #include "sjarmv5.c" #elif (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) -# include "sjarmv5.c" + #include "sjarmv5.c" #elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) -# include "sjarmth2.c" + #include "sjarmth2.c" #elif (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) -# include "sjppcc.c" + #include "sjppcc.c" #elif (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) -# include "sjppcc.c" + #include "sjppcc.c" #elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# include "sjmipsc.c" -#elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) -# include "sljitNativeSPARC_common.c" + #include "sjmipsc.c" #endif #if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { /* Default compare for most architectures. */ - sljit_si flags, tmp_src, condition; - sljit_sw tmp_srcw; + int flags, tmp_src, condition; + sljit_w tmp_srcw; CHECK_ERROR_PTR(); check_sljit_emit_cmp(compiler, type, src1, src1w, src2, src2w); @@ -1410,23 +1322,24 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler return sljit_emit_jump(compiler, condition | (type & SLJIT_REWRITABLE_JUMP)); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_si flags, condition; + int flags, condition; check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w); condition = type & 0xff; - flags = (condition <= SLJIT_C_FLOAT_NOT_EQUAL) ? SLJIT_SET_E : SLJIT_SET_S; - if (type & SLJIT_SINGLE_OP) - flags |= SLJIT_SINGLE_OP; + if (condition <= SLJIT_C_FLOAT_NOT_EQUAL) + flags = SLJIT_SET_E; + else + flags = SLJIT_SET_S; #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; #endif - sljit_emit_fop1(compiler, SLJIT_CMPD | flags, src1, src1w, src2, src2w); + sljit_emit_fop1(compiler, SLJIT_FCMP | flags, src1, src1w, src2, src2w); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->skip_checks = 1; @@ -1438,7 +1351,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile #if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) && !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) { CHECK_ERROR(); check_sljit_get_local_base(compiler, dst, dstw, offset); @@ -1458,7 +1371,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co /* Empty function bodies for those machines, which are not (yet) supported. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { return "unsupported"; } @@ -1475,7 +1388,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compile SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(size); @@ -1505,28 +1418,28 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code) SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(scratches); + SLJIT_UNUSED_ARG(temporaries); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(args); - SLJIT_UNUSED_ARG(scratches); + SLJIT_UNUSED_ARG(temporaries); SLJIT_UNUSED_ARG(saveds); SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1536,16 +1449,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw, int args, int temporaries, int saveds, int local_size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); + SLJIT_UNUSED_ARG(args); + SLJIT_UNUSED_ARG(temporaries); + SLJIT_UNUSED_ARG(saveds); + SLJIT_UNUSED_ARG(local_size); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(src); @@ -1554,7 +1471,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1562,9 +1479,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1576,10 +1493,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1593,14 +1510,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { SLJIT_ASSERT_STOP(); return reg; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(instruction); @@ -1609,15 +1526,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { SLJIT_ASSERT_STOP(); return 0; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1629,10 +1546,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); @@ -1653,7 +1570,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return NULL; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1661,9 +1578,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return NULL; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1675,9 +1592,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler return NULL; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1703,7 +1620,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(type); @@ -1713,23 +1630,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(op); SLJIT_UNUSED_ARG(dst); SLJIT_UNUSED_ARG(dstw); - SLJIT_UNUSED_ARG(src); - SLJIT_UNUSED_ARG(srcw); SLJIT_UNUSED_ARG(type); SLJIT_ASSERT_STOP(); return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); @@ -1739,7 +1651,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw initval) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w initval) { SLJIT_UNUSED_ARG(compiler); SLJIT_UNUSED_ARG(dst); @@ -1756,7 +1668,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ad SLJIT_ASSERT_STOP(); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { SLJIT_UNUSED_ARG(addr); SLJIT_UNUSED_ARG(new_constant); diff --git a/harbour/src/3rd/pcre/sjlir.h b/harbour/src/3rd/pcre/sjlir.h index a6b7f4a883..b88d456c40 100644 --- a/harbour/src/3rd/pcre/sjlir.h +++ b/harbour/src/3rd/pcre/sjlir.h @@ -34,19 +34,12 @@ Short description Advantages: - - The execution can be continued from any LIR instruction. In other - words, it is possible to jump to any label from anywhere, even from - a code fragment, which is compiled later, if both compiled code - shares the same context. See sljit_emit_enter for more details - - Supports self modifying code: target of (conditional) jump and call - instructions and some constant values can be dynamically modified - during runtime + - The execution can be continued from any LIR instruction + In other words, jump into and out of the code is safe + - Both target of (conditional) jump and call instructions + and constants can be dynamically modified during runtime - although it is not suggested to do it frequently - - can be used for inline caching: save an important value once - in the instruction stream - - since this feature limits the optimization possibilities, a - special flag must be passed at compile time when these - instructions are emitted + - very effective to cache an important value once - A fixed stack space can be allocated for local variables - The compiler is thread-safe - The compiler is highly configurable through preprocessor macros. @@ -54,19 +47,19 @@ threaded applications), and you can use your own system functions (including memory allocators). See sljitConfig.h Disadvantages: - - No automatic register allocation, and temporary results are - not stored on the stack. (hence the name comes) - Limited number of registers (only 6+4 integer registers, max 3+2 - scratch, max 3+2 saved and 6 floating point registers) + temporary, max 3+2 saved and 4 floating point registers) In practice: - This approach is very effective for interpreters - One of the saved registers typically points to a stack interface - - It can jump to any exception handler anytime (even if it belongs - to another function) - - Hot paths can be modified during runtime reflecting the changes + - It can jump to any exception handler anytime (even for another + function. It is safe for SLJIT.) + - Fast paths can be modified during runtime reflecting the changes of the fastest execution path of the dynamic language - SLJIT supports complex memory addressing modes - - mainly position and context independent code (except some cases) + - mainly position independent code + - Optimizations (perhaps later) + - Only for basic blocks (when no labels inserted between LIR instructions) For valgrind users: - pass --smc-check=all argument to valgrind, since JIT is a "self-modifying code" @@ -106,14 +99,12 @@ of sljitConfigInternal.h */ #define SLJIT_UNUSED 0 -/* Scratch (temporary) registers whose may not preserve their values - across function calls. */ -#define SLJIT_SCRATCH_REG1 1 -#define SLJIT_SCRATCH_REG2 2 -#define SLJIT_SCRATCH_REG3 3 -/* Note: extra registers cannot be used for memory addressing. */ -/* Note: on x86-32, these registers are emulated (using stack - loads & stores). */ +/* Temporary (scratch) registers may not preserve their values across function calls. */ +#define SLJIT_TEMPORARY_REG1 1 +#define SLJIT_TEMPORARY_REG2 2 +#define SLJIT_TEMPORARY_REG3 3 +/* Note: Extra Registers cannot be used for memory addressing. */ +/* Note: on x86-32, these registers are emulated (using stack loads & stores). */ #define SLJIT_TEMPORARY_EREG1 4 #define SLJIT_TEMPORARY_EREG2 5 @@ -121,17 +112,15 @@ of sljitConfigInternal.h */ #define SLJIT_SAVED_REG1 6 #define SLJIT_SAVED_REG2 7 #define SLJIT_SAVED_REG3 8 -/* Note: extra registers cannot be used for memory addressing. */ -/* Note: on x86-32, these registers are emulated (using stack - loads & stores). */ +/* Note: Extra Registers cannot be used for memory addressing. */ +/* Note: on x86-32, these registers are emulated (using stack loads & stores). */ #define SLJIT_SAVED_EREG1 9 #define SLJIT_SAVED_EREG2 10 /* Read-only register (cannot be the destination of an operation). Only SLJIT_MEM1(SLJIT_LOCALS_REG) addressing mode is allowed since several ABIs has certain limitations about the stack layout. However - sljit_get_local_base() can be used to obtain the offset of a value - on the stack. */ + sljit_get_local_base() can be used to obtain the offset of a value. */ #define SLJIT_LOCALS_REG 11 /* Number of registers. */ @@ -141,15 +130,15 @@ of sljitConfigInternal.h */ /* Return with machine word. */ -#define SLJIT_RETURN_REG SLJIT_SCRATCH_REG1 +#define SLJIT_RETURN_REG SLJIT_TEMPORARY_REG1 /* x86 prefers specific registers for special purposes. In case of shift - by register it supports only SLJIT_SCRATCH_REG3 for shift argument + by register it supports only SLJIT_TEMPORARY_REG3 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_SCRATCH_REG3 +#define SLJIT_PREF_SHIFT_REG SLJIT_TEMPORARY_REG3 /* --------------------------------------------------------------------- */ /* Floating point registers */ @@ -158,15 +147,12 @@ of sljitConfigInternal.h */ /* Note: SLJIT_UNUSED as destination is not valid for floating point operations, since they cannot be used for setting flags. */ -/* Floating point operations are performed on double or - single precision values. */ +/* Floating point operations are performed on double precision values. */ #define SLJIT_FLOAT_REG1 1 #define SLJIT_FLOAT_REG2 2 #define SLJIT_FLOAT_REG3 3 #define SLJIT_FLOAT_REG4 4 -#define SLJIT_FLOAT_REG5 5 -#define SLJIT_FLOAT_REG6 6 /* --------------------------------------------------------------------- */ /* Main structures and functions */ @@ -175,7 +161,6 @@ of sljitConfigInternal.h */ struct sljit_memory_fragment { struct sljit_memory_fragment *next; sljit_uw used_size; - /* Must be aligned to sljit_sw. */ sljit_ub memory[1]; }; @@ -189,7 +174,7 @@ struct sljit_label { struct sljit_jump { struct sljit_jump *next; sljit_uw addr; - sljit_sw flags; + sljit_w flags; union { sljit_uw target; struct sljit_label* label; @@ -202,7 +187,7 @@ struct sljit_const { }; struct sljit_compiler { - sljit_si error; + int error; struct sljit_label *labels; struct sljit_jump *jumps; @@ -215,29 +200,29 @@ struct sljit_compiler { struct sljit_memory_fragment *abuf; /* Used local registers. */ - sljit_si scratches; + int temporaries; /* Used saved registers. */ - sljit_si saveds; + int saveds; /* Local stack size. */ - sljit_si local_size; + int local_size; /* Code size. */ sljit_uw size; /* For statistical purposes. */ sljit_uw executable_size; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si args; - sljit_si locals_offset; - sljit_si scratches_start; - sljit_si saveds_start; + int args; + int locals_offset; + int temporaries_start; + int saveds_start; #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si mode32; + int mode32; #endif #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si flags_saved; + int flags_saved; #endif #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) @@ -254,31 +239,25 @@ struct sljit_compiler { #if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7) /* Temporary fields. */ sljit_uw shift_imm; - sljit_si cache_arg; - sljit_sw cache_argw; + int cache_arg; + sljit_w cache_argw; #endif #if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) - sljit_si cache_arg; - sljit_sw cache_argw; + int cache_arg; + sljit_w cache_argw; #endif #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - sljit_sw imm; - sljit_si cache_arg; - sljit_sw cache_argw; + sljit_w imm; + int cache_arg; + sljit_w cache_argw; #endif #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) - sljit_si delay_slot; - sljit_si cache_arg; - sljit_sw cache_argw; -#endif - -#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) - sljit_si delay_slot; - sljit_si cache_arg; - sljit_sw cache_argw; + int delay_slot; + int cache_arg; + sljit_w cache_argw; #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) @@ -287,11 +266,11 @@ struct sljit_compiler { #if (defined SLJIT_DEBUG && SLJIT_DEBUG) /* Local size passed to the functions. */ - sljit_si logical_local_size; + int logical_local_size; #endif #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) - sljit_si skip_checks; + int skip_checks; #endif }; @@ -302,29 +281,22 @@ struct sljit_compiler { /* Creates an sljit compiler. Returns NULL if failed. */ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void); - -/* Free everything except the compiled machine code. */ +/* Free everything except the codes. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_compiler(struct sljit_compiler *compiler); -/* Returns the current error code. If an error is occured, future sljit - calls which uses the same compiler argument returns early with the same - error code. Thus there is no need for checking the error after every - call, it is enough to do it before the code is compiled. Removing - these checks increases the performance of the compiling process. */ -static SLJIT_INLINE sljit_si sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; } +static SLJIT_INLINE int sljit_get_compiler_error(struct sljit_compiler *compiler) { return compiler->error; } /* Allocate a small amount of memory. The size must be <= 64 bytes on 32 bit, - and <= 128 bytes on 64 bit architectures. The memory area is owned by the - compiler, and freed by sljit_free_compiler. The returned pointer is - sizeof(sljit_sw) aligned. Excellent for allocating small blocks during - the compiling, and no need to worry about freeing them. The size is - enough to contain at most 16 pointers. If the size is outside of the range, - the function will return with NULL. However, this return value does not - indicate that there is no more memory (does not set the current error code - of the compiler to out-of-memory status). + and <= 128 bytes on 64 bit architectures. The memory area is owned by the compiler, + and freed by sljit_free_compiler. The returned pointer is sizeof(sljit_w) aligned. + Excellent for allocating small blocks during the compiling, and no need to worry + about freeing them. The size is enough to contain at most 16 pointers. + If the size is outside of the range, the function will return with NULL, + but this return value does not indicate that there is no more memory (does + not set the compiler to out-of-memory status). */ -SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, sljit_si size); +SLJIT_API_FUNC_ATTRIBUTE void* sljit_alloc_memory(struct sljit_compiler *compiler, int size); #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) /* Passing NULL disables verbose. */ @@ -335,17 +307,15 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_API_FUNC_ATTRIBUTE void sljit_free_code(void* code); /* - After the machine code generation is finished we can retrieve the allocated - executable memory size, although this area may not be fully filled with - instructions depending on some optimizations. This function is useful only - for statistical purposes. + After the code generation we can retrieve the allocated executable memory size, + although this area may not be fully filled with instructions depending on some + optimizations. This function is useful only for statistical purposes. Before a successful code generation, this function returns with 0. */ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler *compiler) { return compiler->executable_size; } -/* Instruction generation. Returns with any error code. If there is no - error, they return with SLJIT_SUCCESS. */ +/* Instruction generation. Returns with error code. */ /* The executable code is basically a function call from the viewpoint of @@ -356,8 +326,8 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler for the executable code and moves function arguments to the saved registers. The number of arguments are specified in the "args" parameter and the first argument goes to SLJIT_SAVED_REG1, the second - goes to SLJIT_SAVED_REG2 and so on. The number of scratch and - saved registers are passed in "scratches" and "saveds" arguments + goes to SLJIT_SAVED_REG2 and so on. The number of temporary and + saved registers are passed in "temporaries" and "saveds" arguments respectively. Since the saved registers contains the arguments, "args" must be less or equal than "saveds". The sljit_emit_enter is also capable of allocating a stack space for local variables. The @@ -368,53 +338,54 @@ static SLJIT_INLINE sljit_uw sljit_get_generated_code_size(struct sljit_compiler SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely until the function returns. The stack space is uninitialized. - Note: every call of sljit_emit_enter and sljit_set_context - overwrites the previous context. */ + Note: every call of sljit_emit_enter and sljit_set_context overwrites + the previous context. */ #define SLJIT_MAX_LOCAL_SIZE 65536 -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, - sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size); +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, + int args, int temporaries, int saveds, int local_size); /* The machine code has a context (which contains the local stack space size, number of used registers, etc.) which initialized by sljit_emit_enter. Several functions (like sljit_emit_return) requres this context to be able to generate the appropriate code. However, some code fragments (like inline cache) may have no normal entry point so their context is unknown for the compiler. Using the - function below we can specify their context. + function below we can specify thir context. Note: every call of sljit_emit_enter and sljit_set_context overwrites the previous context. */ +/* Note: multiple calls of this function overwrites the previous call. */ + SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, - sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size); + int args, int temporaries, int saveds, int local_size); /* Return from machine code. The op argument can be SLJIT_UNUSED which means the function does not return with anything or any opcode between SLJIT_MOV and - SLJIT_MOV_P (see sljit_emit_op1). As for src and srcw they must be 0 if op + SLJIT_MOV_SI (see sljit_emit_op1). As for src and srcw they must be 0 if op is SLJIT_UNUSED, otherwise see below the description about source and destination arguments. */ +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, + int src, sljit_w srcw); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, - sljit_si src, sljit_sw srcw); +/* Really fast calling method for utility functions inside sljit (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, and sljit_emit_fast_return can + use this as a return value later. */ -/* 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. */ - -/* 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). */ +/* 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). */ /* Note: flags are not changed (unlike sljit_emit_enter / sljit_emit_return). */ /* 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. */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw); +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw); +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw); /* Source and destination values for arithmetical instructions @@ -423,7 +394,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * [imm] - absolute immediate memory address [reg+imm] - indirect memory address [reg+(reg<addr; } static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; } @@ -889,22 +767,22 @@ static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { /* Only the address is required to rewrite the code. */ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr); -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant); +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant); /* --------------------------------------------------------------------- */ /* Miscellaneous utility functions */ /* --------------------------------------------------------------------- */ #define SLJIT_MAJOR_VERSION 0 -#define SLJIT_MINOR_VERSION 90 +#define SLJIT_MINOR_VERSION 88 -/* Get the human readable name of the platform. Can be useful on platforms - like ARM, where ARM and Thumb2 functions can be mixed, and - it is useful to know the type of the code generator. */ +/* Get the human readable name of the platfrom. + Can be useful for debugging on platforms like ARM, where ARM and + Thumb2 functions can be mixed. */ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void); -/* Portable helper function to get an offset of a member. */ -#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10) +/* Portble helper function to get an offset of a member. */ +#define SLJIT_OFFSETOF(base, member) ((sljit_w)(&((base*)0x10)->member) - 0x10) #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) /* This global lock is useful to compile common functions. */ @@ -953,32 +831,32 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* st 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_uw new_limit); +SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit); #endif /* (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) */ #if !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) /* Get the entry address of a given function. */ -#define SLJIT_FUNC_OFFSET(func_name) ((sljit_sw)func_name) +#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)func_name) #else /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ /* All JIT related code should be placed in the same context (library, binary, etc.). */ -#define SLJIT_FUNC_OFFSET(func_name) (*(sljit_sw*)(void*)func_name) +#define SLJIT_FUNC_OFFSET(func_name) ((sljit_w)*(void**)func_name) /* For powerpc64, the function pointers point to a context descriptor. */ struct sljit_function_context { - sljit_sw addr; - sljit_sw r2; - sljit_sw r11; + sljit_w addr; + sljit_w r2; + sljit_w r11; }; /* Fill the context arguments using the addr and the function. If func_ptr is NULL, it will not be set to the address of context If addr is NULL, the function address also comes from the func pointer. */ -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func); +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func); #endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */ diff --git a/harbour/src/3rd/pcre/sjmips32.c b/harbour/src/3rd/pcre/sjmips32.c index f8c214863d..c0cc8b58bb 100644 --- a/harbour/src/3rd/pcre/sjmips32.c +++ b/harbour/src/3rd/pcre/sjmips32.c @@ -26,7 +26,7 @@ /* mips 32-bit arch dependent functions. */ -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm) +static int load_immediate(struct sljit_compiler *compiler, int dst_ar, sljit_w imm) { if (!(imm & ~0xffff)) return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar); @@ -66,92 +66,12 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \ } -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_sw src2) +static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, + int dst, int src1, sljit_w src2) { - sljit_si overflow_ra = 0; + int overflow_ra = 0; switch (GET_OPCODE(op)) { - case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: - case SLJIT_MOV_P: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (dst != src2) - return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst)); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) { -#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) - return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); -#else - FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst))); - return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst)); -#endif - } - return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); - } - else if (dst != src2) - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) { -#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) - return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); -#else - FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst))); - return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst)); -#endif - } - return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); - } - else if (dst != src2) - SLJIT_ASSERT_STOP(); - return SLJIT_SUCCESS; - - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); - return SLJIT_SUCCESS; - - case SLJIT_CLZ: - SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); -#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) - if (op & SLJIT_SET_E) - FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); - if (CHECK_FLAGS(SLJIT_SET_E)) - FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst))); -#else - if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { - FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); - return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); - } - /* Nearly all instructions are unmovable in the following sequence. */ - FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); - /* Check zero. */ - FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(5), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, ADDIU_W | SA(0) | T(dst) | IMM(-1), DR(dst))); - /* Loop for searching the highest bit. */ - FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), DR(dst))); - FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); - FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS)); - if (op & SLJIT_SET_E) - return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); -#endif - return SLJIT_SUCCESS; - case SLJIT_ADD: if (flags & SRC2_IMM) { if (op & SLJIT_SET_O) { @@ -373,16 +293,97 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj case SLJIT_ASHR: EMIT_SHIFT(SRA, SRAV); return SLJIT_SUCCESS; + + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + SLJIT_ASSERT(src1 == TMP_REG1); + if (dst != src2) + return push_inst(compiler, ADDU | S(src2) | TA(0) | D(dst), DR(dst)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) { +#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) + return push_inst(compiler, SEB | T(src2) | D(dst), DR(dst)); +#else + FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(24), DR(dst))); + return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(24), DR(dst)); +#endif + } + return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xff), DR(dst)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) { +#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) + return push_inst(compiler, SEH | T(src2) | D(dst), DR(dst)); +#else + FAIL_IF(push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(16), DR(dst))); + return push_inst(compiler, SRA | T(dst) | D(dst) | SH_IMM(16), DR(dst)); +#endif + } + return push_inst(compiler, ANDI | S(src2) | T(dst) | IMM(0xffff), DR(dst)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, NOR | S(src2) | T(src2) | D(dst), DR(dst))); + return SLJIT_SUCCESS; + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM)); +#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) + if (op & SLJIT_SET_E) + FAIL_IF(push_inst(compiler, CLZ | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG)); + if (CHECK_FLAGS(SLJIT_SET_E)) + FAIL_IF(push_inst(compiler, CLZ | S(src2) | T(dst) | D(dst), DR(dst))); +#else + if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) { + FAIL_IF(push_inst(compiler, SRL | T(src2) | DA(EQUAL_FLAG) | SH_IMM(31), EQUAL_FLAG)); + return push_inst(compiler, XORI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG); + } + /* Nearly all instructions are unmovable in the following sequence. */ + FAIL_IF(push_inst(compiler, ADDU_W | S(src2) | TA(0) | D(TMP_REG1), DR(TMP_REG1))); + /* Check zero. */ + FAIL_IF(push_inst(compiler, BEQ | S(TMP_REG1) | TA(0) | IMM(6), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(32), UNMOVABLE_INS)); + /* Check sign bit. */ + FAIL_IF(push_inst(compiler, BLTZ | S(TMP_REG1) | IMM(4), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ORI | SA(0) | T(dst) | IMM(0), UNMOVABLE_INS)); + /* Loop for searching the highest bit. */ + FAIL_IF(push_inst(compiler, SLL | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), DR(TMP_REG1))); + FAIL_IF(push_inst(compiler, BGEZ | S(TMP_REG1) | IMM(-2), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, ADDIU_W | S(dst) | T(dst) | IMM(1), UNMOVABLE_INS)); + if (op & SLJIT_SET_E) + return push_inst(compiler, ADDU_W | S(dst) | TA(0) | DA(EQUAL_FLAG), EQUAL_FLAG); +#endif + return SLJIT_SUCCESS; } SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw init_value) +static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value) { - FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 16), DR(dst))); - return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst)); + FAIL_IF(push_inst(compiler, LUI | T(reg) | IMM(init_value >> 16), DR(reg))); + return push_inst(compiler, ORI | S(reg) | T(reg) | IMM(init_value), DR(reg)); } SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) @@ -394,7 +395,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ad SLJIT_CACHE_FLUSH(inst, inst + 2); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { sljit_ins *inst = (sljit_ins*)addr; diff --git a/harbour/src/3rd/pcre/sjmipsc.c b/harbour/src/3rd/pcre/sjmipsc.c index 42c80424d3..ee3a4c7e07 100644 --- a/harbour/src/3rd/pcre/sjmipsc.c +++ b/harbour/src/3rd/pcre/sjmipsc.c @@ -24,18 +24,14 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* Latest MIPS architecture. */ -/* Automatically detect SLJIT_MIPS_32_64 */ - -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { -#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) return "MIPS" SLJIT_CPUINFO; -#else - return "MIPS III" SLJIT_CPUINFO; -#endif } +/* Latest MIPS architecture. */ +/* Detect SLJIT_MIPS_32_64 */ + /* Length of an instruction word Both for mips-32 and mips-64 */ typedef sljit_ui sljit_ins; @@ -45,15 +41,15 @@ typedef sljit_ui sljit_ins; #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) /* For position independent code, t9 must contain the function address. */ -#define PIC_ADDR_REG TMP_REG2 +#define PIC_ADDR_REG TMP_REG2 /* TMP_EREG1 is used mainly for literal encoding on 64 bit. */ -#define TMP_EREG1 15 -#define TMP_EREG2 24 +#define TMP_EREG1 15 +#define TMP_EREG2 24 /* Floating point status register. */ -#define FCSR_REG 31 +#define FCSR_REG 31 /* Return address register. */ -#define RETURN_ADDR_REG 31 +#define RETURN_ADDR_REG 31 /* Flags are keept in volatile registers. */ #define EQUAL_FLAG 7 @@ -64,12 +60,8 @@ typedef sljit_ui sljit_ins; #define GREATER_FLAG 13 #define OVERFLOW_FLAG 14 -#define TMP_FREG1 (0) -#define TMP_FREG2 ((SLJIT_FLOAT_REG6 + 1) << 1) - -static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { - 0, 2, 5, 6, 3, 8, 16, 17, 18, 19, 20, 29, 4, 25, 9 -}; +#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) +#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) /* --------------------------------------------------------------------- */ /* Instrucion forms */ @@ -82,20 +74,19 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { #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 FT(t) ((t) << (16 + 1)) +#define FS(s) ((s) << (11 + 1)) +#define FD(d) ((d) << (6 + 1)) #define IMM(imm) ((imm) & 0xffff) #define SH_IMM(imm) ((imm & 0x1f) << 6) #define DR(dr) (reg_map[dr]) #define HI(opcode) ((opcode) << 26) #define LO(opcode) (opcode) -/* S = (16 << 21) D = (17 << 21) */ -#define FMT_SD (16 << 21) +#define FMT_D (17 << 21) -#define ABS_fmt (HI(17) | FMT_SD | LO(5)) -#define ADD_fmt (HI(17) | FMT_SD | LO(0)) +#define ABS_D (HI(17) | FMT_D | LO(5)) +#define ADD_D (HI(17) | FMT_D | LO(0)) #define ADDU (HI(0) | LO(33)) #define ADDIU (HI(9)) #define AND (HI(0) | LO(36)) @@ -111,35 +102,37 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { #define BLTZ (HI(1) | (0 << 16)) #define BNE (HI(5)) #define BREAK (HI(0) | LO(13)) -#define CFC1 (HI(17) | (2 << 21)) -#define C_UN_fmt (HI(17) | FMT_SD | LO(49)) -#define C_UEQ_fmt (HI(17) | FMT_SD | LO(51)) -#define C_ULE_fmt (HI(17) | FMT_SD | LO(55)) -#define C_ULT_fmt (HI(17) | FMT_SD | LO(53)) +#define C_UN_D (HI(17) | FMT_D | LO(49)) +#define C_UEQ_D (HI(17) | FMT_D | LO(51)) +#define C_ULE_D (HI(17) | FMT_D | LO(55)) +#define C_ULT_D (HI(17) | FMT_D | LO(53)) #define DIV (HI(0) | LO(26)) #define DIVU (HI(0) | LO(27)) -#define DIV_fmt (HI(17) | FMT_SD | LO(3)) +#define DIV_D (HI(17) | FMT_D | LO(3)) #define J (HI(2)) #define JAL (HI(3)) #define JALR (HI(0) | LO(9)) #define JR (HI(0) | LO(8)) #define LD (HI(55)) +#define LDC1 (HI(53)) #define LUI (HI(15)) #define LW (HI(35)) +#define NEG_D (HI(17) | FMT_D | LO(7)) #define MFHI (HI(0) | LO(16)) #define MFLO (HI(0) | LO(18)) -#define MOV_fmt (HI(17) | FMT_SD | LO(6)) +#define MOV_D (HI(17) | FMT_D | LO(6)) +#define CFC1 (HI(17) | (2 << 21)) #define MOVN (HI(0) | LO(11)) #define MOVZ (HI(0) | LO(10)) -#define MUL_fmt (HI(17) | FMT_SD | LO(2)) +#define MUL_D (HI(17) | FMT_D | LO(2)) #define MULT (HI(0) | LO(24)) #define MULTU (HI(0) | LO(25)) -#define NEG_fmt (HI(17) | FMT_SD | LO(7)) #define NOP (HI(0) | LO(0)) #define NOR (HI(0) | LO(39)) #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)) @@ -150,7 +143,7 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { #define SRLV (HI(0) | LO(6)) #define SRA (HI(0) | LO(3)) #define SRAV (HI(0) | LO(7)) -#define SUB_fmt (HI(17) | FMT_SD | LO(1)) +#define SUB_D (HI(17) | FMT_D | LO(1)) #define SUBU (HI(0) | LO(35)) #define SW (HI(43)) #define XOR (HI(0) | LO(38)) @@ -179,12 +172,14 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { #define SIMM_MIN (-0x8000) #define UIMM_MAX (0xffff) +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = { + 0, 2, 5, 6, 3, 8, 16, 17, 18, 19, 20, 29, 4, 25, 9 +}; + /* dest_reg is the absolute name of the register Useful for reordering instructions in the delay slot. */ -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot) +static int push_inst(struct sljit_compiler *compiler, sljit_ins ins, int delay_slot) { - SLJIT_ASSERT(delay_slot == MOVABLE_INS || delay_slot >= UNMOVABLE_INS - || delay_slot == ((ins >> 11) & 0x1f) || delay_slot == ((ins >> 16) & 0x1f)); sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); *ptr = ins; @@ -193,14 +188,14 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_ return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_ins invert_branch(sljit_si flags) +static SLJIT_INLINE sljit_ins invert_branch(int flags) { return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16); } static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) { - sljit_sw diff; + sljit_w diff; sljit_uw target_addr; sljit_ins *inst; sljit_ins saved_inst; @@ -220,7 +215,7 @@ static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins /* B instructions. */ if (jump->flags & IS_MOVABLE) { - diff = ((sljit_sw)target_addr - (sljit_sw)(inst)) >> 2; + diff = ((sljit_w)target_addr - (sljit_w)(inst)) >> 2; if (diff <= SIMM_MAX && diff >= SIMM_MIN) { jump->flags |= PATCH_B; @@ -238,7 +233,7 @@ static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins } } - diff = ((sljit_sw)target_addr - (sljit_sw)(inst + 1)) >> 2; + diff = ((sljit_w)target_addr - (sljit_w)(inst + 1)) >> 2; if (diff <= SIMM_MAX && diff >= SIMM_MIN) { jump->flags |= PATCH_B; @@ -340,7 +335,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) jump->addr = (sljit_uw)(code_ptr - 3); #else -#error "Implementation required" + jump->addr = (sljit_uw)(code_ptr - 6); #endif code_ptr = optimize_jump(jump, code_ptr, code); jump = jump->next; @@ -366,7 +361,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); - SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); + SLJIT_ASSERT(code_ptr - code <= (int)compiler->size); jump = compiler->jumps; while (jump) { @@ -375,8 +370,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil buf_ptr = (sljit_ins*)jump->addr; if (jump->flags & PATCH_B) { - addr = (sljit_sw)(addr - (jump->addr + sizeof(sljit_ins))) >> 2; - SLJIT_ASSERT((sljit_sw)addr <= SIMM_MAX && (sljit_sw)addr >= SIMM_MIN); + addr = (sljit_w)(addr - (jump->addr + sizeof(sljit_ins))) >> 2; + SLJIT_ASSERT((sljit_w)addr <= SIMM_MAX && (sljit_w)addr >= SIMM_MIN); buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | (addr & 0xffff); break; } @@ -391,7 +386,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff); buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff); #else -#error "Implementation required" + buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 48) & 0xffff); + buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 32) & 0xffff); + buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | ((addr >> 16) & 0xffff); + buf_ptr[4] = (buf_ptr[4] & 0xffff0000) | (addr & 0xffff); #endif } while (0); jump = jump->next; @@ -408,43 +406,41 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil return code; } -/* --------------------------------------------------------------------- */ -/* Entry, exit */ -/* --------------------------------------------------------------------- */ - /* Creates an index in data_transfer_insts array. */ -#define LOAD_DATA 0x01 #define WORD_DATA 0x00 -#define BYTE_DATA 0x02 -#define HALF_DATA 0x04 -#define INT_DATA 0x06 -#define SIGNED_DATA 0x08 -/* Separates integer and floating point registers */ -#define GPR_REG 0x0f -#define DOUBLE_DATA 0x10 +#define BYTE_DATA 0x01 +#define HALF_DATA 0x02 +#define INT_DATA 0x03 +#define SIGNED_DATA 0x04 +#define LOAD_DATA 0x08 -#define MEM_MASK 0x1f +#define MEM_MASK 0x0f -#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 WRITE_BACK 0x00010 +#define ARG_TEST 0x00020 +#define CUMULATIVE_OP 0x00040 +#define LOGICAL_OP 0x00080 +#define IMM_OP 0x00100 +#define SRC2_IMM 0x00200 -#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 0x00400 +#define REG_DEST 0x00800 +#define REG1_SOURCE 0x01000 +#define REG2_SOURCE 0x02000 +#define SLOW_SRC1 0x04000 +#define SLOW_SRC2 0x08000 +#define SLOW_DEST 0x10000 /* Only these flags are set. UNUSED_DEST is not set when no flags should be set. */ #define CHECK_FLAGS(list) \ (!(flags & UNUSED_DEST) || (op & GET_FLAGS(~(list)))) +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) +#include "sjmips32.c" +#else +#include "sljitNativeMIPS_64.c" +#endif + #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define STACK_STORE SW #define STACK_LOAD LW @@ -453,26 +449,25 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #define STACK_LOAD LD #endif -#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#include "sjmips32.c" -#else -#include "sljitNativeMIPS_64.c" -#endif +static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { sljit_ins base; CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif - local_size += (saveds + 1 + 4) * sizeof(sljit_sw); + local_size += (saveds + 1 + 4) * sizeof(sljit_w); local_size = (local_size + 15) & ~0xf; compiler->local_size = local_size; @@ -489,17 +484,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil local_size = 0; } - FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (sljit_si)sizeof(sljit_sw)), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (saveds >= 1) - FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (sljit_si)sizeof(sljit_sw)), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (saveds >= 2) - FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (sljit_si)sizeof(sljit_sw)), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (saveds >= 3) - FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (sljit_si)sizeof(sljit_sw)), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (saveds >= 4) - FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (sljit_si)sizeof(sljit_sw)), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (saveds >= 5) - FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (sljit_si)sizeof(sljit_sw)), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, STACK_STORE | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (int)sizeof(sljit_w)), MOVABLE_INS)); if (args >= 1) FAIL_IF(push_inst(compiler, ADDU_W | SA(4) | TA(0) | D(SLJIT_SAVED_REG1), DR(SLJIT_SAVED_REG1))); @@ -511,28 +506,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, scratches, saveds, local_size); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif - local_size += (saveds + 1 + 4) * sizeof(sljit_sw); + local_size += (saveds + 1 + 4) * sizeof(sljit_w); compiler->local_size = (local_size + 15) & ~0xf; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { - sljit_si local_size; + int local_size; sljit_ins base; CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); @@ -546,17 +542,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi local_size = 0; } - FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (sljit_si)sizeof(sljit_sw)), RETURN_ADDR_REG)); + FAIL_IF(push_inst(compiler, STACK_LOAD | base | TA(RETURN_ADDR_REG) | IMM(local_size - 1 * (int)sizeof(sljit_w)), RETURN_ADDR_REG)); if (compiler->saveds >= 5) - FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (sljit_si)sizeof(sljit_sw)), DR(SLJIT_SAVED_EREG2))); + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG2) | IMM(local_size - 6 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG2))); if (compiler->saveds >= 4) - FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (sljit_si)sizeof(sljit_sw)), DR(SLJIT_SAVED_EREG1))); + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_EREG1) | IMM(local_size - 5 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_EREG1))); if (compiler->saveds >= 3) - FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (sljit_si)sizeof(sljit_sw)), DR(SLJIT_SAVED_REG3))); + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG3) | IMM(local_size - 4 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG3))); if (compiler->saveds >= 2) - FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (sljit_si)sizeof(sljit_sw)), DR(SLJIT_SAVED_REG2))); + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG2) | IMM(local_size - 3 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG2))); if (compiler->saveds >= 1) - FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (sljit_si)sizeof(sljit_sw)), DR(SLJIT_SAVED_REG1))); + FAIL_IF(push_inst(compiler, STACK_LOAD | base | T(SLJIT_SAVED_REG1) | IMM(local_size - 2 * (int)sizeof(sljit_w)), DR(SLJIT_SAVED_REG1))); FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS)); if (compiler->local_size <= SIMM_MAX) @@ -573,62 +569,57 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* --------------------------------------------------------------------- */ #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -#define ARCH_32_64(a, b) a +#define ARCH_DEPEND(a, b) a #else -#define ARCH_32_64(a, b) b +#define ARCH_DEPEND(a, b) b #endif -static SLJIT_CONST sljit_ins data_transfer_insts[16 + 4] = { -/* u w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), -/* u w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), -/* u b s */ HI(40) /* sb */, -/* u b l */ HI(36) /* lbu */, -/* u h s */ HI(41) /* sh */, -/* u h l */ HI(37) /* lhu */, -/* u i s */ HI(43) /* sw */, -/* u i l */ ARCH_32_64(HI(35) /* lw */, HI(39) /* lwu */), +static SLJIT_CONST sljit_ins data_transfer_insts[16] = { +/* s u w */ ARCH_DEPEND(HI(43) /* sw */, HI(63) /* sd */), +/* s u b */ HI(40) /* sb */, +/* s u h */ HI(41) /* sh*/, +/* s u i */ HI(43) /* sw */, -/* s w s */ ARCH_32_64(HI(43) /* sw */, HI(63) /* sd */), -/* s w l */ ARCH_32_64(HI(35) /* lw */, HI(55) /* ld */), -/* s b s */ HI(40) /* sb */, -/* s b l */ HI(32) /* lb */, -/* s h s */ HI(41) /* sh */, -/* s h l */ HI(33) /* lh */, -/* s i s */ HI(43) /* sw */, -/* s i l */ HI(35) /* lw */, +/* s s w */ ARCH_DEPEND(HI(43) /* sw */, HI(63) /* sd */), +/* s s b */ HI(40) /* sb */, +/* s s h */ HI(41) /* sh*/, +/* s s i */ HI(43) /* sw */, -/* d s */ HI(61) /* sdc1 */, -/* d l */ HI(53) /* ldc1 */, -/* s s */ HI(57) /* swc1 */, -/* s l */ HI(49) /* lwc1 */, +/* l u w */ ARCH_DEPEND(HI(35) /* lw */, HI(55) /* ld */), +/* l u b */ HI(36) /* lbu */, +/* l u h */ HI(37) /* lhu */, +/* l u i */ ARCH_DEPEND(HI(35) /* lw */, HI(39) /* lwu */), + +/* l s w */ ARCH_DEPEND(HI(35) /* lw */, HI(55) /* ld */), +/* l s b */ HI(32) /* lb */, +/* l s h */ HI(33) /* lh */, +/* l s i */ HI(35) /* lw */, }; -#undef ARCH_32_64 - /* reg_ar is an absoulute register! */ /* Can perform an operation using at most 1 instruction. */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +static int getput_arg_fast(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw) { SLJIT_ASSERT(arg & SLJIT_MEM); - if ((!(flags & WRITE_BACK) || !(arg & 0xf)) && !(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) { + if (!(flags & WRITE_BACK) && !(arg & 0xf0) && argw <= SIMM_MAX && argw >= SIMM_MIN) { /* Works for both absoulte and relative addresses. */ if (SLJIT_UNLIKELY(flags & ARG_TEST)) return 1; - FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & 0xf) - | TA(reg_ar) | IMM(argw), ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) ? reg_ar : MOVABLE_INS)); + FAIL_IF(push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(arg & 0xf) | TA(reg_ar) | IMM(argw), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS)); return -1; } - return 0; + return (flags & ARG_TEST) ? SLJIT_SUCCESS : 0; } /* See getput_arg below. Note: can_cache is called only for binary operators. Those operators always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) { - SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); + if (!(next_arg & SLJIT_MEM)) + return 0; /* Simple operation except for updates. */ if (arg & 0xf0) { @@ -640,7 +631,7 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } if (arg == next_arg) { - if (((next_argw - argw) <= SIMM_MAX && (next_argw - argw) >= SIMM_MIN)) + if (((sljit_uw)(next_argw - argw) <= SIMM_MAX && (sljit_uw)(next_argw - argw) >= SIMM_MIN)) return 1; return 0; } @@ -649,9 +640,10 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ } /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static int getput_arg(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw, int next_arg, sljit_w next_argw) { - sljit_si tmp_ar, base, delay_slot; + int tmp_ar; + int base; SLJIT_ASSERT(arg & SLJIT_MEM); if (!(next_arg & SLJIT_MEM)) { @@ -659,13 +651,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji next_argw = 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; - } + tmp_ar = (flags & LOAD_DATA) ? reg_ar : DR(TMP_REG3); base = arg & 0xf; if (SLJIT_UNLIKELY(arg & 0xf0)) { @@ -680,22 +666,22 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji if (argw == compiler->cache_argw) { if (!(flags & WRITE_BACK)) { if (arg == compiler->cache_arg) - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) { if (arg == next_arg && argw == (next_argw & 0x3)) { compiler->cache_arg = arg; compiler->cache_argw = argw; FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | D(TMP_REG3), DR(TMP_REG3))); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(TMP_REG3) | DA(tmp_ar), tmp_ar)); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } } else { if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg) { 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); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } } } @@ -715,10 +701,10 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji } else FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | DA(tmp_ar), tmp_ar)); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(!argw ? ((arg >> 4) & 0xf) : TMP_REG3) | D(base), DR(base))); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), delay_slot); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } if (SLJIT_UNLIKELY(flags & WRITE_BACK) && base) { @@ -754,7 +740,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji 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); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(base) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { @@ -762,7 +748,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji 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; } - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } if (compiler->cache_arg == SLJIT_MEM && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) { @@ -776,19 +762,19 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si flags, slji compiler->cache_argw = argw; if (!base) - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); if (arg == next_arg && next_argw - argw <= SIMM_MAX && next_argw - argw >= SIMM_MIN) { compiler->cache_arg = arg; FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | D(TMP_REG3), DR(TMP_REG3))); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), delay_slot); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | S(TMP_REG3) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(base) | DA(tmp_ar), tmp_ar)); - return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot); + return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), (flags & LOAD_DATA) ? reg_ar : MOVABLE_INS); } -static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg_ar, sljit_si arg, sljit_sw argw) +static SLJIT_INLINE int emit_op_mem(struct sljit_compiler *compiler, int flags, int reg_ar, int arg, sljit_w argw) { if (getput_arg_fast(compiler, flags, reg_ar, arg, argw)) return compiler->error; @@ -797,44 +783,35 @@ static SLJIT_INLINE sljit_si emit_op_mem(struct sljit_compiler *compiler, sljit_ return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) -{ - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static int emit_op(struct sljit_compiler *compiler, int op, int flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg TMP_REG3 can be used for caching result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r = TMP_REG2; - sljit_si src1_r; - sljit_sw src2_r = 0; - sljit_si sugg_src2_r = TMP_REG2; + int dst_r = TMP_REG2; + int src1_r; + sljit_w src2_r = 0; + int sugg_src2_r = TMP_REG2; - if (!(flags & ALT_KEEP_CACHE)) { - compiler->cache_arg = 0; - compiler->cache_argw = 0; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REG3) { + dst_r = dst; + flags |= REG_DEST; + if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) + sugg_src2_r = dst_r; } - - if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { + else if (dst == SLJIT_UNUSED) { if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) return SLJIT_SUCCESS; if (GET_FLAGS(op)) flags |= UNUSED_DEST; } - else if (dst <= TMP_REG3) { - dst_r = dst; - flags |= REG_DEST; - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) - sugg_src2_r = dst_r; - } else if ((dst & SLJIT_MEM) && !getput_arg_fast(compiler, flags | ARG_TEST, DR(TMP_REG1), dst, dstw)) flags |= SLOW_DEST; @@ -846,7 +823,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f src2_r = src2w; } } - if (!(flags & SRC2_IMM) && (flags & CUMULATIVE_OP) && (src1 & SLJIT_IMM) && src1w) { + if ((src1 & SLJIT_IMM) && src1w && (flags & CUMULATIVE_OP) && !(flags & SRC2_IMM)) { if ((!(flags & LOGICAL_OP) && (src1w <= SIMM_MAX && src1w >= SIMM_MIN)) || ((flags & LOGICAL_OP) && !(src1w & ~UIMM_MAX))) { flags |= SRC2_IMM; @@ -862,7 +839,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } /* Source 1. */ - if (src1 <= TMP_REG3) { + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= TMP_REG3) { src1_r = src1; flags |= REG1_SOURCE; } @@ -883,23 +860,20 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f } /* Source 2. */ - if (src2 <= TMP_REG3) { + if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REG3) { src2_r = src2; flags |= REG2_SOURCE; - if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) + if (!(flags & REG_DEST) && GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { if (!(flags & SRC2_IMM)) { - if (src2w) { + if (src2w || (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI)) { FAIL_IF(load_immediate(compiler, DR(sugg_src2_r), src2w)); src2_r = sugg_src2_r; } - else { + else src2_r = 0; - if ((op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) && (dst & SLJIT_MEM)) - dst_r = 0; - } } } else { @@ -939,7 +913,7 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si f return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { CHECK_ERROR(); check_sljit_emit_op0(compiler, op); @@ -952,29 +926,29 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler return push_inst(compiler, NOP, UNMOVABLE_INS); case SLJIT_UMUL: case SLJIT_SMUL: - FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_SCRATCH_REG1), DR(SLJIT_SCRATCH_REG1))); - return push_inst(compiler, MFHI | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)); + FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1))); + return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); case SLJIT_UDIV: case SLJIT_SDIV: #if !(defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); #endif - FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS)); - FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_SCRATCH_REG1), DR(SLJIT_SCRATCH_REG1))); - return push_inst(compiler, MFHI | D(SLJIT_SCRATCH_REG2), DR(SLJIT_SCRATCH_REG2)); + FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_TEMPORARY_REG1) | T(SLJIT_TEMPORARY_REG2), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MFLO | D(SLJIT_TEMPORARY_REG1), DR(SLJIT_TEMPORARY_REG1))); + return push_inst(compiler, MFHI | D(SLJIT_TEMPORARY_REG2), DR(SLJIT_TEMPORARY_REG2)); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define flags 0 + #define inp_flags 0 #endif CHECK_ERROR(); @@ -982,74 +956,74 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); + SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset); + switch (GET_OPCODE(op)) { case SLJIT_MOV: - case SLJIT_MOV_P: - return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_UI: - return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_SI: - return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_UB: - return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOV_SB: - return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOV_UH: - return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOV_SH: - return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)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); + return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_UI: - return emit_op(compiler, SLJIT_MOV_UI, flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_SI: - return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_UB: - return emit_op(compiler, SLJIT_MOV_UB, flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOVU_SB: - return emit_op(compiler, SLJIT_MOV_SB, flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOVU_UH: - return emit_op(compiler, SLJIT_MOV_UH, flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOVU_SH: - return emit_op(compiler, SLJIT_MOV_SH, flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw); + return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); case SLJIT_NOT: - return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, op, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_NEG: - return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); + return emit_op(compiler, SLJIT_SUB | GET_ALL_FLAGS(op), inp_flags | IMM_OP, dst, dstw, SLJIT_IMM, 0, src, srcw); case SLJIT_CLZ: - return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, op, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); } return SLJIT_SUCCESS; #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# undef flags + #undef inp_flags #endif } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# define flags 0 + #define inp_flags 0 #endif CHECK_ERROR(); @@ -1061,19 +1035,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler switch (GET_OPCODE(op)) { case SLJIT_ADD: case SLJIT_ADDC: - return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, op, inp_flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUB: case SLJIT_SUBC: - return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, op, inp_flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); case SLJIT_MUL: - return emit_op(compiler, op, flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, op, inp_flags | CUMULATIVE_OP, dst, dstw, src1, src1w, src2, src2w); case SLJIT_AND: case SLJIT_OR: case SLJIT_XOR: - return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, op, inp_flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SHL: case SLJIT_LSHR: @@ -1082,25 +1056,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler if (src2 & SLJIT_IMM) src2w &= 0x1f; #else - SLJIT_ASSERT_STOP(); + if (src2 & SLJIT_IMM) + src2w &= 0x3f; #endif - return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, op, inp_flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w); } return SLJIT_SUCCESS; #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -# undef flags + #undef inp_flags #endif } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { check_sljit_get_register_index(reg); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) { CHECK_ERROR(); check_sljit_emit_op_custom(compiler, instruction, size); @@ -1113,13 +1088,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { #if (defined SLJIT_QEMU && SLJIT_QEMU) /* Qemu says fir is 0 by default. */ return 1; #elif defined(__GNUC__) - sljit_sw fir; + sljit_w fir; asm ("cfc1 %0, $0" : "=r"(fir)); return (fir >> 22) & 0x1; #else @@ -1127,95 +1102,119 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) #endif } -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7)) -#define FMT(op) (((op & SLJIT_SINGLE_OP) ^ SLJIT_SINGLE_OP) << (21 - 8)) - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw) { - sljit_si dst_fr; + int hi_reg; + + SLJIT_ASSERT(arg & SLJIT_MEM); + + /* Fast loads and stores. */ + if (!(arg & 0xf0)) { + /* Both for (arg & 0xf) == SLJIT_UNUSED and (arg & 0xf) != SLJIT_UNUSED. */ + if (argw <= SIMM_MAX && argw >= SIMM_MIN) + return push_inst(compiler, (load ? LDC1 : SDC1) | S(arg & 0xf) | FT(fpu_reg) | IMM(argw), MOVABLE_INS); + } + + if (arg & 0xf0) { + argw &= 0x3; + hi_reg = (arg >> 4) & 0xf; + if (argw) { + FAIL_IF(push_inst(compiler, SLL_W | T(hi_reg) | D(TMP_REG1) | SH_IMM(argw), DR(TMP_REG1))); + hi_reg = TMP_REG1; + } + FAIL_IF(push_inst(compiler, ADDU_W | S(hi_reg) | T(arg & 0xf) | D(TMP_REG1), DR(TMP_REG1))); + return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG1) | FT(fpu_reg) | IMM(0), MOVABLE_INS); + } + + /* Use cache. */ + if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) + return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG3) | FT(fpu_reg) | IMM(argw - compiler->cache_argw), MOVABLE_INS); + + /* Put value to cache. */ + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + FAIL_IF(load_immediate(compiler, DR(TMP_REG3), argw)); + if (arg & 0xf) + FAIL_IF(push_inst(compiler, ADDU_W | S(TMP_REG3) | T(arg & 0xf) | D(TMP_REG3), DR(TMP_REG3))); + return push_inst(compiler, (load ? LDC1 : SDC1) | S(TMP_REG3) | FT(fpu_reg) | IMM(0), MOVABLE_INS); +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + int dst_fr; CHECK_ERROR(); check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x2), float_transfer_bit_error); compiler->cache_arg = 0; compiler->cache_argw = 0; - if (GET_OPCODE(op) == SLJIT_CMPD) { - if (dst > SLJIT_FLOAT_REG6) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw)); + if (GET_OPCODE(op) == SLJIT_FCMP) { + if (dst > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw)); dst = TMP_FREG1; } - else - dst <<= 1; - - if (src > SLJIT_FLOAT_REG6) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0)); + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw)); src = TMP_FREG2; } - else - src <<= 1; /* src and dst are swapped. */ if (op & SLJIT_SET_E) { - FAIL_IF(push_inst(compiler, C_UEQ_fmt | FMT(op) | FT(src) | FS(dst), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, C_UEQ_D | FT(src) | FS(dst), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, CFC1 | TA(EQUAL_FLAG) | DA(FCSR_REG), EQUAL_FLAG)); FAIL_IF(push_inst(compiler, SRL | TA(EQUAL_FLAG) | DA(EQUAL_FLAG) | SH_IMM(23), EQUAL_FLAG)); FAIL_IF(push_inst(compiler, ANDI | SA(EQUAL_FLAG) | TA(EQUAL_FLAG) | IMM(1), EQUAL_FLAG)); } if (op & SLJIT_SET_S) { /* Mixing the instructions for the two checks. */ - FAIL_IF(push_inst(compiler, C_ULT_fmt | FMT(op) | FT(src) | FS(dst), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, C_ULT_D | FT(src) | FS(dst), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, CFC1 | TA(ULESS_FLAG) | DA(FCSR_REG), ULESS_FLAG)); - FAIL_IF(push_inst(compiler, C_ULT_fmt | FMT(op) | FT(dst) | FS(src), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, C_ULT_D | FT(dst) | FS(src), UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, SRL | TA(ULESS_FLAG) | DA(ULESS_FLAG) | SH_IMM(23), ULESS_FLAG)); FAIL_IF(push_inst(compiler, ANDI | SA(ULESS_FLAG) | TA(ULESS_FLAG) | IMM(1), ULESS_FLAG)); FAIL_IF(push_inst(compiler, CFC1 | TA(UGREATER_FLAG) | DA(FCSR_REG), UGREATER_FLAG)); FAIL_IF(push_inst(compiler, SRL | TA(UGREATER_FLAG) | DA(UGREATER_FLAG) | SH_IMM(23), UGREATER_FLAG)); FAIL_IF(push_inst(compiler, ANDI | SA(UGREATER_FLAG) | TA(UGREATER_FLAG) | IMM(1), UGREATER_FLAG)); } - return push_inst(compiler, C_UN_fmt | FMT(op) | FT(src) | FS(dst), FCSR_FCC); + return push_inst(compiler, C_UN_D | FT(src) | FS(dst), FCSR_FCC); } - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : (dst << 1); + dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; - if (src > SLJIT_FLOAT_REG6) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw)); + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 1, src, srcw)); src = dst_fr; } - else - src <<= 1; - switch (GET_OPCODE(op)) { - case SLJIT_MOVD: + switch (op) { + case SLJIT_FMOV: if (src != dst_fr && dst_fr != TMP_FREG1) - FAIL_IF(push_inst(compiler, MOV_fmt | FMT(op) | FS(src) | FD(dst_fr), MOVABLE_INS)); + FAIL_IF(push_inst(compiler, MOV_D | FS(src) | FD(dst_fr), MOVABLE_INS)); break; - case SLJIT_NEGD: - FAIL_IF(push_inst(compiler, NEG_fmt | FMT(op) | FS(src) | FD(dst_fr), MOVABLE_INS)); + case SLJIT_FNEG: + FAIL_IF(push_inst(compiler, NEG_D | FS(src) | FD(dst_fr), MOVABLE_INS)); break; - case SLJIT_ABSD: - FAIL_IF(push_inst(compiler, ABS_fmt | FMT(op) | FS(src) | FD(dst_fr), MOVABLE_INS)); + case SLJIT_FABS: + FAIL_IF(push_inst(compiler, ABS_D | FS(src) | FD(dst_fr), MOVABLE_INS)); break; } - if (dst_fr == TMP_FREG1) { - if (GET_OPCODE(op) == SLJIT_MOVD) - dst_fr = src; - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_fr, dst, dstw, 0, 0)); - } + if (dst_fr == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw)); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_si dst_fr, flags = 0; + int dst_fr; CHECK_ERROR(); check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); @@ -1223,68 +1222,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile compiler->cache_arg = 0; compiler->cache_argw = 0; - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG2 : (dst << 1); + dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; - if (src1 > SLJIT_FLOAT_REG6) { - if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { - FAIL_IF(compiler->error); - src1 = TMP_FREG1; - } else - flags |= SLOW_SRC1; - } - else - src1 <<= 1; - - if (src2 > SLJIT_FLOAT_REG6) { - if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, 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)); - } - 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)); - } - } - else if (flags & SLOW_SRC1) - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, 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)); - - if (flags & SLOW_SRC1) - src1 = TMP_FREG1; - if (flags & SLOW_SRC2) + if (src2 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); src2 = TMP_FREG2; + } - switch (GET_OPCODE(op)) { - case SLJIT_ADDD: - FAIL_IF(push_inst(compiler, ADD_fmt | FMT(op) | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + if (src1 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); + src1 = TMP_FREG1; + } + + switch (op) { + case SLJIT_FADD: + FAIL_IF(push_inst(compiler, ADD_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); break; - case SLJIT_SUBD: - FAIL_IF(push_inst(compiler, SUB_fmt | FMT(op) | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + case SLJIT_FSUB: + FAIL_IF(push_inst(compiler, SUB_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); break; - case SLJIT_MULD: - FAIL_IF(push_inst(compiler, MUL_fmt | FMT(op) | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + case SLJIT_FMUL: + FAIL_IF(push_inst(compiler, MUL_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); break; - case SLJIT_DIVD: - FAIL_IF(push_inst(compiler, DIV_fmt | FMT(op) | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); + case SLJIT_FDIV: + FAIL_IF(push_inst(compiler, DIV_D | FT(src2) | FS(src1) | FD(dst_fr), MOVABLE_INS)); break; } - if (dst_fr == TMP_FREG2) - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); + if (dst_fr == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw)); return SLJIT_SUCCESS; } @@ -1293,30 +1262,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (dst <= TMP_REG3) + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), DR(dst)); - - /* Memory. */ - return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); + else if (dst & SLJIT_MEM) + return emit_op_mem(compiler, WORD_DATA, RETURN_ADDR_REG, dst, dstw); + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= TMP_REG3) + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG)); else if (src & SLJIT_MEM) FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw)); @@ -1351,7 +1316,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) #define JUMP_LENGTH 4 #else -#error "Implementation required" +#define JUMP_LENGTH 7 #endif #define BR_Z(src) \ @@ -1374,12 +1339,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi flags = IS_BIT16_COND; \ delay_check = FCSR_FCC; -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { struct sljit_jump *jump; sljit_ins inst; - sljit_si flags = 0; - sljit_si delay_check = UNMOVABLE_INS; + int flags = 0; + int delay_check = UNMOVABLE_INS; CHECK_ERROR_PTR(); check_sljit_emit_jump(compiler, type); @@ -1434,10 +1399,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile case SLJIT_C_MUL_NOT_OVERFLOW: BR_NZ(OVERFLOW_FLAG); break; - case SLJIT_C_FLOAT_UNORDERED: + case SLJIT_C_FLOAT_NAN: BR_F(); break; - case SLJIT_C_FLOAT_ORDERED: + case SLJIT_C_FLOAT_NOT_NAN: BR_T(); break; default: @@ -1465,7 +1430,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile 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_SCRATCH_REG1) | TA(0) | DA(4), UNMOVABLE_INS)); + PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS)); } return jump; } @@ -1490,12 +1455,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile src2 = 0; \ } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { struct sljit_jump *jump; - sljit_si flags; + int flags; sljit_ins inst; CHECK_ERROR_PTR(); @@ -1507,11 +1472,17 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler compiler->cache_argw = 0; flags = ((type & SLJIT_INT_OP) ? INT_DATA : WORD_DATA) | LOAD_DATA; if (src1 & SLJIT_MEM) { - PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w)); + if (getput_arg_fast(compiler, flags, DR(TMP_REG1), src1, src1w)) + PTR_FAIL_IF(compiler->error); + else + PTR_FAIL_IF(getput_arg(compiler, flags, DR(TMP_REG1), src1, src1w, src2, src2w)); src1 = TMP_REG1; } if (src2 & SLJIT_MEM) { - PTR_FAIL_IF(emit_op_mem2(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0)); + if (getput_arg_fast(compiler, flags, DR(TMP_REG2), src2, src2w)) + PTR_FAIL_IF(compiler->error); + else + PTR_FAIL_IF(getput_arg(compiler, flags, DR(TMP_REG2), src2, src2w, 0, 0)); src2 = TMP_REG2; } @@ -1611,13 +1582,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler #undef RESOLVE_IMM1 #undef RESOLVE_IMM2 -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_si type, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, int type, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { struct sljit_jump *jump; sljit_ins inst; - sljit_si if_true; + int if_true; CHECK_ERROR_PTR(); check_sljit_emit_fcmp(compiler, type, src1, src1w, src2, src2w); @@ -1625,62 +1596,58 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile compiler->cache_arg = 0; compiler->cache_argw = 0; - if (src1 > SLJIT_FLOAT_REG6) { - PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG1, src1, src1w, src2, src2w)); + if (src1 > SLJIT_FLOAT_REG4) { + PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); src1 = TMP_FREG1; } - else - src1 <<= 1; - - if (src2 > SLJIT_FLOAT_REG6) { - PTR_FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(type) | LOAD_DATA, TMP_FREG2, src2, src2w, 0, 0)); + if (src2 > SLJIT_FLOAT_REG4) { + PTR_FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); src2 = TMP_FREG2; } - else - src2 <<= 1; jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); PTR_FAIL_IF(!jump); set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP); jump->flags |= IS_BIT16_COND; + type &= 0xff; - switch (type & 0xff) { + switch (type) { case SLJIT_C_FLOAT_EQUAL: - inst = C_UEQ_fmt; + inst = C_UEQ_D; if_true = 1; break; case SLJIT_C_FLOAT_NOT_EQUAL: - inst = C_UEQ_fmt; + inst = C_UEQ_D; if_true = 0; break; case SLJIT_C_FLOAT_LESS: - inst = C_ULT_fmt; + inst = C_ULT_D; if_true = 1; break; case SLJIT_C_FLOAT_GREATER_EQUAL: - inst = C_ULT_fmt; + inst = C_ULT_D; if_true = 0; break; case SLJIT_C_FLOAT_GREATER: - inst = C_ULE_fmt; + inst = C_ULE_D; if_true = 0; break; case SLJIT_C_FLOAT_LESS_EQUAL: - inst = C_ULE_fmt; + inst = C_ULE_D; if_true = 1; break; - case SLJIT_C_FLOAT_UNORDERED: - inst = C_UN_fmt; + case SLJIT_C_FLOAT_NAN: + inst = C_UN_D; if_true = 1; break; - case SLJIT_C_FLOAT_ORDERED: + case SLJIT_C_FLOAT_NOT_NAN: default: /* Make compilers happy. */ - inst = C_UN_fmt; + inst = C_UN_D; if_true = 0; break; } - PTR_FAIL_IF(push_inst(compiler, inst | FMT(type) | FT(src2) | FS(src1), UNMOVABLE_INS)); + PTR_FAIL_IF(push_inst(compiler, inst | FT(src2) | FS(src1), UNMOVABLE_INS)); /* Intentionally the other opcode. */ PTR_FAIL_IF(push_inst(compiler, (if_true ? BC1F : BC1T) | JUMP_LENGTH, UNMOVABLE_INS)); PTR_FAIL_IF(emit_const(compiler, TMP_REG2, 0)); @@ -1696,19 +1663,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile #undef BR_T #undef BR_F -#undef FLOAT_DATA -#undef FMT - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { - sljit_si src_r = TMP_REG2; + int src_r = TMP_REG2; struct sljit_jump *jump = NULL; CHECK_ERROR(); check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= TMP_REG3) { + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { if (DR(src) != 4) src_r = src; else @@ -1726,12 +1690,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil } 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_SCRATCH_REG1) | TA(0) | DA(4), UNMOVABLE_INS); + return push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS); } /* Register input. */ if (type >= SLJIT_CALL1) - FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SCRATCH_REG1) | TA(0) | DA(4), 4)); + FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | 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); } @@ -1757,32 +1721,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { - sljit_si sugg_dst_ar, dst_ar; - sljit_si flags = GET_ALL_FLAGS(op); + int sugg_dst_ar, dst_ar; CHECK_ERROR(); - check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + check_sljit_emit_cond_value(compiler, op, dst, dstw, type); ADJUST_LOCAL_OFFSET(dst, dstw); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; - op = GET_OPCODE(op); - sugg_dst_ar = DR((op < SLJIT_ADD && dst <= TMP_REG3) ? dst : TMP_REG2); - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { - ADJUST_LOCAL_OFFSET(src, srcw); - FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw)); - src = TMP_REG1; - srcw = 0; - } + sugg_dst_ar = DR((op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2); switch (type) { case SLJIT_C_EQUAL: @@ -1825,8 +1775,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com dst_ar = EQUAL_FLAG; break; - case SLJIT_C_FLOAT_UNORDERED: - case SLJIT_C_FLOAT_ORDERED: + case SLJIT_C_FLOAT_NAN: + case SLJIT_C_FLOAT_NOT_NAN: FAIL_IF(push_inst(compiler, CFC1 | TA(sugg_dst_ar) | DA(FCSR_REG), sugg_dst_ar)); FAIL_IF(push_inst(compiler, SRL | TA(sugg_dst_ar) | DA(sugg_dst_ar) | SH_IMM(23), sugg_dst_ar)); FAIL_IF(push_inst(compiler, ANDI | SA(sugg_dst_ar) | TA(sugg_dst_ar) | IMM(1), sugg_dst_ar)); @@ -1844,10 +1794,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com dst_ar = sugg_dst_ar; } - if (op >= SLJIT_ADD) { + if (GET_OPCODE(op) == SLJIT_OR) { if (DR(TMP_REG2) != dst_ar) FAIL_IF(push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); - return emit_op(compiler, op | flags, CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0); + return emit_op(compiler, op, CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, dst, dstw, TMP_REG2, 0); } if (dst & SLJIT_MEM) @@ -1858,10 +1808,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { struct sljit_const *const_; - sljit_si reg; + int reg; CHECK_ERROR_PTR(); check_sljit_emit_const(compiler, dst, dstw, init_value); @@ -1871,7 +1821,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - reg = (dst <= TMP_REG3) ? dst : TMP_REG2; + reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; PTR_FAIL_IF(emit_const(compiler, reg, init_value)); diff --git a/harbour/src/3rd/pcre/sjppc32.c b/harbour/src/3rd/pcre/sjppc32.c index 0bd35a6e0e..82d0508ac1 100644 --- a/harbour/src/3rd/pcre/sjppc32.c +++ b/harbour/src/3rd/pcre/sjppc32.c @@ -26,7 +26,7 @@ /* ppc 32-bit arch dependent functions. */ -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm) { if (imm <= SIMM_MAX && imm >= SIMM_MIN) return push_inst(compiler, ADDI | D(reg) | A(0) | IMM(imm)); @@ -41,59 +41,10 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl #define INS_CLEAR_LEFT(dst, src, from) \ (RLWINM | S(src) | A(dst) | ((from) << 6) | (31 << 1)) -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) +static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, + int dst, int src1, int src2) { switch (op) { - case SLJIT_MOV: - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: - case SLJIT_MOV_P: - SLJIT_ASSERT(src1 == TMP_REG1); - if (dst != src2) - return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: - SLJIT_ASSERT(src1 == TMP_REG1); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) - return push_inst(compiler, EXTSB | S(src2) | A(dst)); - return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); - } - else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) - return push_inst(compiler, EXTSB | S(src2) | A(dst)); - else { - SLJIT_ASSERT(dst == src2); - } - return SLJIT_SUCCESS; - - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: - SLJIT_ASSERT(src1 == TMP_REG1); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) - return push_inst(compiler, EXTSH | S(src2) | A(dst)); - return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); - } - else { - SLJIT_ASSERT(dst == src2); - } - return SLJIT_SUCCESS; - - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1); - return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); - - case SLJIT_NEG: - SLJIT_ASSERT(src1 == TMP_REG1); - return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); - - case SLJIT_CLZ: - SLJIT_ASSERT(src1 == TMP_REG1); - return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); - case SLJIT_ADD: if (flags & ALT_FORM1) { /* Flags does not set: BIN_IMM_EXTS unnecessary. */ @@ -120,7 +71,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj case SLJIT_ADDC: if (flags & ALT_FORM1) { - FAIL_IF(push_inst(compiler, MFXER | D(0))); + FAIL_IF(push_inst(compiler, MFXER | S(0))); FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2))); return push_inst(compiler, MTXER | S(0)); } @@ -155,7 +106,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj case SLJIT_SUBC: if (flags & ALT_FORM1) { - FAIL_IF(push_inst(compiler, MFXER | D(0))); + FAIL_IF(push_inst(compiler, MFXER | S(0))); FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1))); return push_inst(compiler, MTXER | S(0)); } @@ -228,23 +179,65 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_ASHR: - if (flags & ALT_FORM3) - FAIL_IF(push_inst(compiler, MFXER | D(0))); if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); compiler->imm &= 0x1f; - FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11))); + return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)); } - else - FAIL_IF(push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2))); - return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS; + return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_MOV: + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + SLJIT_ASSERT(src1 == TMP_REG1); + if (dst != src2) + return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); + } + else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) + return push_inst(compiler, EXTSH | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1); + return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); + + case SLJIT_NEG: + SLJIT_ASSERT(src1 == TMP_REG1); + return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1); + return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); } SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value) +static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value) { FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 16))); return push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value)); @@ -259,7 +252,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ad SLJIT_CACHE_FLUSH(inst, inst + 2); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { sljit_ins *inst = (sljit_ins*)addr; diff --git a/harbour/src/3rd/pcre/sjppc64.c b/harbour/src/3rd/pcre/sjppc64.c index 8eaeb41f4e..cc2ae37eb9 100644 --- a/harbour/src/3rd/pcre/sjppc64.c +++ b/harbour/src/3rd/pcre/sjppc64.c @@ -26,11 +26,9 @@ /* ppc 64-bit arch dependent functions. */ -#if defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM) +#ifdef __GNUC__ #define ASM_SLJIT_CLZ(src, dst) \ - __asm__ volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) ) -#elif defined(__xlc__) -#error "Please enable GCC syntax for inline assembly statements" + asm volatile ( "cntlzd %0, %1" : "=r"(dst) : "r"(src) ) #else #error "Must implement count leading zeroes" #endif @@ -41,7 +39,7 @@ #define PUSH_RLDICR(reg, shift) \ push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1)) -static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static int load_immediate(struct sljit_compiler *compiler, int reg, sljit_w imm) { sljit_uw tmp; sljit_uw shift; @@ -145,74 +143,10 @@ static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si reg, sl src1 = TMP_REG1; \ } -static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, sljit_si op, sljit_si flags, - sljit_si dst, sljit_si src1, sljit_si src2) +static SLJIT_INLINE int emit_single_op(struct sljit_compiler *compiler, int op, int flags, + int dst, int src1, int src2) { switch (op) { - case SLJIT_MOV: - case SLJIT_MOV_P: - SLJIT_ASSERT(src1 == TMP_REG1); - if (dst != src2) - return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); - return SLJIT_SUCCESS; - - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: - SLJIT_ASSERT(src1 == TMP_REG1); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SI) - return push_inst(compiler, EXTSW | S(src2) | A(dst)); - return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0)); - } - else { - SLJIT_ASSERT(dst == src2); - } - return SLJIT_SUCCESS; - - case SLJIT_MOV_UB: - case SLJIT_MOV_SB: - SLJIT_ASSERT(src1 == TMP_REG1); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SB) - return push_inst(compiler, EXTSB | S(src2) | A(dst)); - return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); - } - else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) - return push_inst(compiler, EXTSB | S(src2) | A(dst)); - else { - SLJIT_ASSERT(dst == src2); - } - return SLJIT_SUCCESS; - - case SLJIT_MOV_UH: - case SLJIT_MOV_SH: - SLJIT_ASSERT(src1 == TMP_REG1); - if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { - if (op == SLJIT_MOV_SH) - return push_inst(compiler, EXTSH | S(src2) | A(dst)); - return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); - } - else { - SLJIT_ASSERT(dst == src2); - } - return SLJIT_SUCCESS; - - case SLJIT_NOT: - SLJIT_ASSERT(src1 == TMP_REG1); - UN_EXTS(); - return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); - - case SLJIT_NEG: - SLJIT_ASSERT(src1 == TMP_REG1); - UN_EXTS(); - return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); - - case SLJIT_CLZ: - SLJIT_ASSERT(src1 == TMP_REG1); - if (flags & ALT_FORM1) - return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); - return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst)); - case SLJIT_ADD: if (flags & ALT_FORM1) { /* Flags does not set: BIN_IMM_EXTS unnecessary. */ @@ -241,7 +175,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj case SLJIT_ADDC: if (flags & ALT_FORM1) { - FAIL_IF(push_inst(compiler, MFXER | D(0))); + FAIL_IF(push_inst(compiler, MFXER | S(0))); FAIL_IF(push_inst(compiler, ADDE | D(dst) | A(src1) | B(src2))); return push_inst(compiler, MTXER | S(0)); } @@ -278,7 +212,7 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj case SLJIT_SUBC: if (flags & ALT_FORM1) { - FAIL_IF(push_inst(compiler, MFXER | D(0))); + FAIL_IF(push_inst(compiler, MFXER | S(0))); FAIL_IF(push_inst(compiler, SUBFE | D(dst) | A(src2) | B(src1))); return push_inst(compiler, MTXER | S(0)); } @@ -350,7 +284,9 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return push_inst(compiler, RLDI(dst, src1, compiler->imm, 63 - compiler->imm, 1) | RC(flags)); } } - return push_inst(compiler, ((flags & ALT_FORM2) ? SLW : SLD) | RC(flags) | S(src1) | A(dst) | B(src2)); + if (flags & ALT_FORM2) + return push_inst(compiler, SLW | RC(flags) | S(src1) | A(dst) | B(src2)); + return push_inst(compiler, SLD | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_LSHR: if (flags & ALT_FORM1) { @@ -364,32 +300,92 @@ static SLJIT_INLINE sljit_si emit_single_op(struct sljit_compiler *compiler, slj return push_inst(compiler, RLDI(dst, src1, 64 - compiler->imm, compiler->imm, 0) | RC(flags)); } } - return push_inst(compiler, ((flags & ALT_FORM2) ? SRW : SRD) | RC(flags) | S(src1) | A(dst) | B(src2)); + if (flags & ALT_FORM2) + return push_inst(compiler, SRW | RC(flags) | S(src1) | A(dst) | B(src2)); + return push_inst(compiler, SRD | RC(flags) | S(src1) | A(dst) | B(src2)); case SLJIT_ASHR: - if (flags & ALT_FORM3) - FAIL_IF(push_inst(compiler, MFXER | D(0))); if (flags & ALT_FORM1) { SLJIT_ASSERT(src2 == TMP_REG2); if (flags & ALT_FORM2) { compiler->imm &= 0x1f; - FAIL_IF(push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11))); + return push_inst(compiler, SRAWI | RC(flags) | S(src1) | A(dst) | (compiler->imm << 11)); } else { compiler->imm &= 0x3f; - FAIL_IF(push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4))); + return push_inst(compiler, SRADI | RC(flags) | S(src1) | A(dst) | ((compiler->imm & 0x1f) << 11) | ((compiler->imm & 0x20) >> 4)); } } - else - FAIL_IF(push_inst(compiler, ((flags & ALT_FORM2) ? SRAW : SRAD) | RC(flags) | S(src1) | A(dst) | B(src2))); - return (flags & ALT_FORM3) ? push_inst(compiler, MTXER | S(0)) : SLJIT_SUCCESS; + if (flags & ALT_FORM2) + return push_inst(compiler, SRAW | RC(flags) | S(src1) | A(dst) | B(src2)); + return push_inst(compiler, SRAD | RC(flags) | S(src1) | A(dst) | B(src2)); + + case SLJIT_MOV: + SLJIT_ASSERT(src1 == TMP_REG1); + if (dst != src2) + return push_inst(compiler, OR | S(src2) | A(dst) | B(src2)); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UI: + case SLJIT_MOV_SI: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SI) + return push_inst(compiler, EXTSW | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 0)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UB: + case SLJIT_MOV_SB: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 24)); + } + else if ((flags & REG_DEST) && op == SLJIT_MOV_SB) + return push_inst(compiler, EXTSB | S(src2) | A(dst)); + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_MOV_UH: + case SLJIT_MOV_SH: + SLJIT_ASSERT(src1 == TMP_REG1); + if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) { + if (op == SLJIT_MOV_SH) + return push_inst(compiler, EXTSH | S(src2) | A(dst)); + return push_inst(compiler, INS_CLEAR_LEFT(dst, src2, 16)); + } + else if (dst != src2) + SLJIT_ASSERT_STOP(); + return SLJIT_SUCCESS; + + case SLJIT_NOT: + SLJIT_ASSERT(src1 == TMP_REG1); + UN_EXTS(); + return push_inst(compiler, NOR | RC(flags) | S(src2) | A(dst) | B(src2)); + + case SLJIT_NEG: + SLJIT_ASSERT(src1 == TMP_REG1); + UN_EXTS(); + return push_inst(compiler, NEG | OERC(flags) | D(dst) | A(src2)); + + case SLJIT_CLZ: + SLJIT_ASSERT(src1 == TMP_REG1); + if (flags & ALT_FORM1) + return push_inst(compiler, CNTLZW | RC(flags) | S(src2) | A(dst)); + return push_inst(compiler, CNTLZD | RC(flags) | S(src2) | A(dst)); } SLJIT_ASSERT_STOP(); return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_const(struct sljit_compiler *compiler, sljit_si reg, sljit_sw init_value) +static SLJIT_INLINE int emit_const(struct sljit_compiler *compiler, int reg, sljit_w init_value) { FAIL_IF(push_inst(compiler, ADDIS | D(reg) | A(0) | IMM(init_value >> 48))); FAIL_IF(push_inst(compiler, ORI | S(reg) | A(reg) | IMM(init_value >> 32))); @@ -409,7 +405,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ad SLJIT_CACHE_FLUSH(inst, inst + 5); } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { sljit_ins *inst = (sljit_ins*)addr; @@ -419,3 +415,14 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta inst[4] = (inst[4] & 0xffff0000) | (new_constant & 0xffff); SLJIT_CACHE_FLUSH(inst, inst + 5); } + +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_w addr, void* func) +{ + sljit_w* ptrs; + if (func_ptr) + *func_ptr = (void*)context; + ptrs = (sljit_w*)func; + context->addr = addr ? addr : ptrs[0]; + context->r2 = ptrs[1]; + context->r11 = ptrs[2]; +} diff --git a/harbour/src/3rd/pcre/sjppcc.c b/harbour/src/3rd/pcre/sjppcc.c index c884a1f98e..8abcb9b4f2 100644 --- a/harbour/src/3rd/pcre/sjppcc.c +++ b/harbour/src/3rd/pcre/sjppcc.c @@ -24,7 +24,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { return "PowerPC" SLJIT_CPUINFO; } @@ -33,49 +33,16 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) Both for ppc-32 and ppc-64. */ typedef sljit_ui sljit_ins; -#ifdef _AIX -#include -#endif - static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) { -#ifdef _AIX - _sync_cache_range((caddr_t)from, (int)((size_t)to - (size_t)from)); -#elif defined(__GNUC__) || (defined(__IBM_GCC_ASM) && __IBM_GCC_ASM) -# if defined(_ARCH_PWR) || defined(_ARCH_PWR2) - /* Cache flush for POWER architecture. */ while (from < to) { - __asm__ volatile ( - "clf 0, %0\n" - "dcs\n" - : : "r"(from) - ); - from++; - } - __asm__ volatile ( "ics" ); -# elif defined(_ARCH_COM) && !defined(_ARCH_PPC) -# error "Cache flush is not implemented for PowerPC/POWER common mode." -# else - /* Cache flush for PowerPC architecture. */ - while (from < to) { - __asm__ volatile ( - "dcbf 0, %0\n" - "sync\n" - "icbi 0, %0\n" - : : "r"(from) - ); - from++; - } - __asm__ volatile ( "isync" ); -# endif -# ifdef __xlc__ -# warning "This file may fail to compile if -qfuncsect is used" -# endif -#elif defined(__xlc__) -#error "Please enable GCC syntax for inline assembly statements with -qasm=gcc" +#ifdef __GNUC__ + asm volatile ( "icbi 0, %0" : : "r"(from) ); #else -#error "This platform requires a cache flush implementation." -#endif /* _AIX */ +#error "Must implement icbi" +#endif + from++; + } } #define TMP_REG1 (SLJIT_NO_REGISTERS + 1) @@ -83,12 +50,8 @@ static void ppc_cache_flush(sljit_ins *from, sljit_ins *to) #define TMP_REG3 (SLJIT_NO_REGISTERS + 3) #define ZERO_REG (SLJIT_NO_REGISTERS + 4) -#define TMP_FREG1 (0) -#define TMP_FREG2 (SLJIT_FLOAT_REG6 + 1) - -static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { - 0, 3, 4, 5, 6, 7, 30, 29, 28, 27, 26, 1, 8, 9, 10, 31 -}; +#define TMP_FREG1 (SLJIT_FLOAT_REG4 + 1) +#define TMP_FREG2 (SLJIT_FLOAT_REG4 + 2) /* --------------------------------------------------------------------- */ /* Instrucion forms */ @@ -143,17 +106,16 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { #define EXTSW (HI(31) | LO(986)) #define FABS (HI(63) | LO(264)) #define FADD (HI(63) | LO(21)) -#define FADDS (HI(59) | LO(21)) #define FCMPU (HI(63) | LO(0)) #define FDIV (HI(63) | LO(18)) -#define FDIVS (HI(59) | LO(18)) #define FMR (HI(63) | LO(72)) #define FMUL (HI(63) | LO(25)) -#define FMULS (HI(59) | LO(25)) #define FNEG (HI(63) | LO(40)) #define FSUB (HI(63) | LO(20)) -#define FSUBS (HI(59) | LO(20)) #define LD (HI(58) | 0) +#define LFD (HI(50)) +#define LFDUX (HI(31) | LO(631)) +#define LFDX (HI(31) | LO(599)) #define LWZ (HI(32)) #define MFCR (HI(31) | LO(19)) #define MFLR (HI(31) | LO(339) | 0x80000) @@ -187,6 +149,9 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { #define STD (HI(62) | 0) #define STDU (HI(62) | 1) #define STDUX (HI(31) | LO(181)) +#define STFD (HI(54)) +#define STFDUX (HI(31) | LO(759)) +#define STFDX (HI(31) | LO(727)) #define STW (HI(36)) #define STWU (HI(37)) #define STWUX (HI(31) | LO(183)) @@ -202,20 +167,11 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 5] = { #define SIMM_MIN (-0x8000) #define UIMM_MAX (0xffff) -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func) -{ - sljit_sw* ptrs; - if (func_ptr) - *func_ptr = (void*)context; - ptrs = (sljit_sw*)func; - context->addr = addr ? addr : ptrs[0]; - context->r2 = ptrs[1]; - context->r11 = ptrs[2]; -} -#endif +static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 6] = { + 0, 3, 4, 5, 6, 7, 30, 29, 28, 27, 26, 1, 8, 9, 10, 31 +}; -static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) +static int push_inst(struct sljit_compiler *compiler, sljit_ins ins) { sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins)); FAIL_IF(!ptr); @@ -224,9 +180,9 @@ static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins) return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) +static SLJIT_INLINE int optimize_jump(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code) { - sljit_sw diff; + sljit_w diff; sljit_uw target_addr; if (jump->flags & SLJIT_REWRITABLE_JUMP) @@ -238,7 +194,7 @@ static SLJIT_INLINE sljit_si optimize_jump(struct sljit_jump *jump, sljit_ins *c SLJIT_ASSERT(jump->flags & JUMP_LABEL); target_addr = (sljit_uw)(code + jump->u.label->size); } - diff = ((sljit_sw)target_addr - (sljit_sw)(code_ptr)) & ~0x3l; + diff = ((sljit_w)target_addr - (sljit_w)(code_ptr)) & ~0x3l; if (jump->flags & UNCOND_B) { if (diff <= 0x01ffffff && diff >= -0x02000000) { @@ -281,12 +237,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil check_sljit_generate_code(compiler); reverse_buf(compiler); -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); -#else - compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins)); -#endif #endif code = (sljit_ins*)SLJIT_MALLOC_EXEC(compiler->size * sizeof(sljit_ins)); PTR_FAIL_WITH_EXEC_IF(code); @@ -350,10 +302,10 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil SLJIT_ASSERT(!label); SLJIT_ASSERT(!jump); SLJIT_ASSERT(!const_); -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) - SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins))); +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + SLJIT_ASSERT(code_ptr - code <= (int)compiler->size - ((compiler->size & 0x1) ? 3 : 2)); #else - SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size); + SLJIT_ASSERT(code_ptr - code <= (int)compiler->size); #endif jump = compiler->jumps; @@ -365,7 +317,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil if (jump->flags & UNCOND_B) { if (!(jump->flags & ABSOLUTE_B)) { addr = addr - jump->addr; - SLJIT_ASSERT((sljit_sw)addr <= 0x01ffffff && (sljit_sw)addr >= -0x02000000); + SLJIT_ASSERT((sljit_w)addr <= 0x01ffffff && (sljit_w)addr >= -0x02000000); *buf_ptr = Bx | (addr & 0x03fffffc) | ((*buf_ptr) & 0x1); } else { @@ -376,7 +328,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil else { if (!(jump->flags & ABSOLUTE_B)) { addr = addr - jump->addr; - SLJIT_ASSERT((sljit_sw)addr <= 0x7fff && (sljit_sw)addr >= -0x8000); + SLJIT_ASSERT((sljit_w)addr <= 0x7fff && (sljit_w)addr >= -0x8000); *buf_ptr = BCx | (addr & 0xfffc) | ((*buf_ptr) & 0x03ff0001); } else { @@ -406,41 +358,29 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil compiler->error = SLJIT_ERR_COMPILED; compiler->executable_size = compiler->size * sizeof(sljit_ins); -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (((sljit_sw)code_ptr) & 0x4) + if (((sljit_w)code_ptr) & 0x4) code_ptr++; - sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); + sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_w)code, sljit_generate_code); return code_ptr; -#else - sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_sw)code, (void*)sljit_generate_code); - return code_ptr; -#endif #else return code; #endif } -/* --------------------------------------------------------------------- */ -/* Entry, exit */ -/* --------------------------------------------------------------------- */ - /* inp_flags: */ /* Creates an index in data_transfer_insts array. */ -#define LOAD_DATA 0x01 -#define INDEXED 0x02 -#define WRITE_BACK 0x04 #define WORD_DATA 0x00 -#define BYTE_DATA 0x08 -#define HALF_DATA 0x10 -#define INT_DATA 0x18 -#define SIGNED_DATA 0x20 -/* Separates integer and floating point registers */ -#define GPR_REG 0x3f -#define DOUBLE_DATA 0x40 +#define BYTE_DATA 0x01 +#define HALF_DATA 0x02 +#define INT_DATA 0x03 +#define SIGNED_DATA 0x04 +#define LOAD_DATA 0x08 +#define WRITE_BACK 0x10 +#define INDEXED 0x20 -#define MEM_MASK 0x7f +#define MEM_MASK 0x3f /* Other inp_flags. */ @@ -449,7 +389,6 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil #define ALT_SIGN_EXT 0x000200 /* This flag affects the RC() and OERC() macros. */ #define ALT_SET_FLAGS 0x000400 -#define ALT_KEEP_CACHE 0x000800 #define ALT_FORM1 0x010000 #define ALT_FORM2 0x020000 #define ALT_FORM3 0x040000 @@ -486,43 +425,48 @@ ALT_FORM6 0x200000 */ #define STACK_LOAD LD #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w); + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif FAIL_IF(push_inst(compiler, MFLR | D(0))); - FAIL_IF(push_inst(compiler, STACK_STORE | S(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_STORE | S(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(int)(sizeof(sljit_w))) )); if (saveds >= 1) - FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (int)(sizeof(sljit_w))) )); if (saveds >= 2) - FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (int)(sizeof(sljit_w))) )); if (saveds >= 3) - FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (int)(sizeof(sljit_w))) )); if (saveds >= 4) - FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (int)(sizeof(sljit_w))) )); if (saveds >= 5) - FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (sljit_si)(sizeof(sljit_sw))) )); - FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_sw)) )); + FAIL_IF(push_inst(compiler, STACK_STORE | S(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (int)(sizeof(sljit_w))) )); + FAIL_IF(push_inst(compiler, STACK_STORE | S(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_w)) )); FAIL_IF(push_inst(compiler, ADDI | D(ZERO_REG) | A(0) | 0)); if (args >= 1) - FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_SCRATCH_REG1))); + FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(SLJIT_SAVED_REG1) | B(SLJIT_TEMPORARY_REG1))); if (args >= 2) - FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG2) | A(SLJIT_SAVED_REG2) | B(SLJIT_SCRATCH_REG2))); + FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG2) | A(SLJIT_SAVED_REG2) | B(SLJIT_TEMPORARY_REG2))); if (args >= 3) - FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_SCRATCH_REG3))); + FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG3) | A(SLJIT_SAVED_REG3) | B(SLJIT_TEMPORARY_REG3))); -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) - compiler->local_size = (1 + saveds + 6 + 8) * sizeof(sljit_sw) + local_size; +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + compiler->local_size = (1 + saveds + 2) * sizeof(sljit_w) + local_size; #else - compiler->local_size = (1 + saveds + 2) * sizeof(sljit_sw) + local_size; + compiler->local_size = (1 + saveds + 7 + 8) * sizeof(sljit_w) + local_size; #endif compiler->local_size = (compiler->local_size + 15) & ~0xf; @@ -545,29 +489,30 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, scratches, saveds, local_size); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif -#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) - compiler->local_size = (1 + saveds + 6 + 8) * sizeof(sljit_sw) + local_size; +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + compiler->local_size = (1 + saveds + 2) * sizeof(sljit_w) + local_size; #else - compiler->local_size = (1 + saveds + 2) * sizeof(sljit_sw) + local_size; + compiler->local_size = (1 + saveds + 7 + 8) * sizeof(sljit_w) + local_size; #endif compiler->local_size = (compiler->local_size + 15) & ~0xf; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); @@ -578,18 +523,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi FAIL_IF(push_inst(compiler, ADD | D(SLJIT_LOCALS_REG) | A(SLJIT_LOCALS_REG) | B(0))); } - FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_sw)))); + FAIL_IF(push_inst(compiler, STACK_LOAD | D(0) | A(SLJIT_LOCALS_REG) | IMM(sizeof(sljit_w)))); if (compiler->saveds >= 5) - FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG2) | A(SLJIT_LOCALS_REG) | IMM(-6 * (int)(sizeof(sljit_w))) )); if (compiler->saveds >= 4) - FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_EREG1) | A(SLJIT_LOCALS_REG) | IMM(-5 * (int)(sizeof(sljit_w))) )); if (compiler->saveds >= 3) - FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG3) | A(SLJIT_LOCALS_REG) | IMM(-4 * (int)(sizeof(sljit_w))) )); if (compiler->saveds >= 2) - FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG2) | A(SLJIT_LOCALS_REG) | IMM(-3 * (int)(sizeof(sljit_w))) )); if (compiler->saveds >= 1) - FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (sljit_si)(sizeof(sljit_sw))) )); - FAIL_IF(push_inst(compiler, STACK_LOAD | D(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(sljit_si)(sizeof(sljit_sw))) )); + FAIL_IF(push_inst(compiler, STACK_LOAD | D(SLJIT_SAVED_REG1) | A(SLJIT_LOCALS_REG) | IMM(-2 * (int)(sizeof(sljit_w))) )); + FAIL_IF(push_inst(compiler, STACK_LOAD | D(ZERO_REG) | A(SLJIT_LOCALS_REG) | IMM(-(int)(sizeof(sljit_w))) )); FAIL_IF(push_inst(compiler, MTLR | S(0))); FAIL_IF(push_inst(compiler, BLR)); @@ -617,139 +562,117 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #define UPDATE_REQ 0x20000 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) -#define ARCH_32_64(a, b) a -#define INST_CODE_AND_DST(inst, flags, reg) \ - ((inst) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) +#define ARCH_DEPEND(a, b) a +#define GET_INST_CODE(inst) (inst) #else -#define ARCH_32_64(a, b) b -#define INST_CODE_AND_DST(inst, flags, reg) \ - (((inst) & ~(ADDR_MODE2 | UPDATE_REQ)) | (((flags) & MEM_MASK) <= GPR_REG ? D(reg) : FD(reg))) +#define ARCH_DEPEND(a, b) b +#define GET_INST_CODE(index) ((inst) & ~(ADDR_MODE2 | UPDATE_REQ)) #endif -static SLJIT_CONST sljit_ins data_transfer_insts[64 + 8] = { +static SLJIT_CONST sljit_ins data_transfer_insts[64] = { -/* -------- Unsigned -------- */ +/* No write-back. */ -/* Word. */ +/* i n s u w */ ARCH_DEPEND(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), +/* i n s u b */ HI(38) /* stb */, +/* i n s u h */ HI(44) /* sth*/, +/* i n s u i */ HI(36) /* stw */, -/* u w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), -/* u w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), -/* u w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), -/* u w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), +/* i n s s w */ ARCH_DEPEND(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), +/* i n s s b */ HI(38) /* stb */, +/* i n s s h */ HI(44) /* sth*/, +/* i n s s i */ HI(36) /* stw */, -/* u w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), -/* u w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), -/* u w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), -/* u w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), +/* i n l u w */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), +/* i n l u b */ HI(34) /* lbz */, +/* i n l u h */ HI(40) /* lhz */, +/* i n l u i */ HI(32) /* lwz */, -/* Byte. */ +/* i n l s w */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), +/* i n l s b */ HI(34) /* lbz */ /* EXTS_REQ */, +/* i n l s h */ HI(42) /* lha */, +/* i n l s i */ ARCH_DEPEND(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x2 /* lwa */), -/* u b n i s */ HI(38) /* stb */, -/* u b n i l */ HI(34) /* lbz */, -/* u b n x s */ HI(31) | LO(215) /* stbx */, -/* u b n x l */ HI(31) | LO(87) /* lbzx */, +/* Write-back. */ -/* u b w i s */ HI(39) /* stbu */, -/* u b w i l */ HI(35) /* lbzu */, -/* u b w x s */ HI(31) | LO(247) /* stbux */, -/* u b w x l */ HI(31) | LO(119) /* lbzux */, +/* i w s u w */ ARCH_DEPEND(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), +/* i w s u b */ HI(39) /* stbu */, +/* i w s u h */ HI(45) /* sthu */, +/* i w s u i */ HI(37) /* stwu */, -/* Half. */ +/* i w s s w */ ARCH_DEPEND(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), +/* i w s s b */ HI(39) /* stbu */, +/* i w s s h */ HI(45) /* sthu */, +/* i w s s i */ HI(37) /* stwu */, -/* u h n i s */ HI(44) /* sth */, -/* u h n i l */ HI(40) /* lhz */, -/* u h n x s */ HI(31) | LO(407) /* sthx */, -/* u h n x l */ HI(31) | LO(279) /* lhzx */, +/* i w l u w */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), +/* i w l u b */ HI(35) /* lbzu */, +/* i w l u h */ HI(41) /* lhzu */, +/* i w l u i */ HI(33) /* lwzu */, -/* u h w i s */ HI(45) /* sthu */, -/* u h w i l */ HI(41) /* lhzu */, -/* u h w x s */ HI(31) | LO(439) /* sthux */, -/* u h w x l */ HI(31) | LO(311) /* lhzux */, +/* i w l s w */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), +/* i w l s b */ HI(35) /* lbzu */ /* EXTS_REQ */, +/* i w l s h */ HI(43) /* lhau */, +/* i w l s i */ ARCH_DEPEND(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | UPDATE_REQ | 0x2 /* lwa */), -/* Int. */ +/* ---------- */ +/* Indexed */ +/* ---------- */ -/* u i n i s */ HI(36) /* stw */, -/* u i n i l */ HI(32) /* lwz */, -/* u i n x s */ HI(31) | LO(151) /* stwx */, -/* u i n x l */ HI(31) | LO(23) /* lwzx */, +/* No write-back. */ -/* u i w i s */ HI(37) /* stwu */, -/* u i w i l */ HI(33) /* lwzu */, -/* u i w x s */ HI(31) | LO(183) /* stwux */, -/* u i w x l */ HI(31) | LO(55) /* lwzux */, +/* x n s u w */ ARCH_DEPEND(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), +/* x n s u b */ HI(31) | LO(215) /* stbx */, +/* x n s u h */ HI(31) | LO(407) /* sthx */, +/* x n s u i */ HI(31) | LO(151) /* stwx */, -/* -------- Signed -------- */ +/* x n s s w */ ARCH_DEPEND(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), +/* x n s s b */ HI(31) | LO(215) /* stbx */, +/* x n s s h */ HI(31) | LO(407) /* sthx */, +/* x n s s i */ HI(31) | LO(151) /* stwx */, -/* Word. */ +/* x n l u w */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), +/* x n l u b */ HI(31) | LO(87) /* lbzx */, +/* x n l u h */ HI(31) | LO(279) /* lhzx */, +/* x n l u i */ HI(31) | LO(23) /* lwzx */, -/* s w n i s */ ARCH_32_64(HI(36) /* stw */, HI(62) | ADDR_MODE2 | 0x0 /* std */), -/* s w n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x0 /* ld */), -/* s w n x s */ ARCH_32_64(HI(31) | LO(151) /* stwx */, HI(31) | LO(149) /* stdx */), -/* s w n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), +/* x n l s w */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(21) /* ldx */), +/* x n l s b */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */, +/* x n l s h */ HI(31) | LO(343) /* lhax */, +/* x n l s i */ ARCH_DEPEND(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */), -/* s w w i s */ ARCH_32_64(HI(37) /* stwu */, HI(62) | ADDR_MODE2 | 0x1 /* stdu */), -/* s w w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | 0x1 /* ldu */), -/* s w w x s */ ARCH_32_64(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), -/* s w w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), +/* Write-back. */ -/* Byte. */ +/* x w s u w */ ARCH_DEPEND(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), +/* x w s u b */ HI(31) | LO(247) /* stbux */, +/* x w s u h */ HI(31) | LO(439) /* sthux */, +/* x w s u i */ HI(31) | LO(183) /* stwux */, -/* s b n i s */ HI(38) /* stb */, -/* s b n i l */ HI(34) /* lbz */ /* EXTS_REQ */, -/* s b n x s */ HI(31) | LO(215) /* stbx */, -/* s b n x l */ HI(31) | LO(87) /* lbzx */ /* EXTS_REQ */, +/* x w s s w */ ARCH_DEPEND(HI(31) | LO(183) /* stwux */, HI(31) | LO(181) /* stdux */), +/* x w s s b */ HI(31) | LO(247) /* stbux */, +/* x w s s h */ HI(31) | LO(439) /* sthux */, +/* x w s s i */ HI(31) | LO(183) /* stwux */, -/* s b w i s */ HI(39) /* stbu */, -/* s b w i l */ HI(35) /* lbzu */ /* EXTS_REQ */, -/* s b w x s */ HI(31) | LO(247) /* stbux */, -/* s b w x l */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */, +/* x w l u w */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), +/* x w l u b */ HI(31) | LO(119) /* lbzux */, +/* x w l u h */ HI(31) | LO(311) /* lhzux */, +/* x w l u i */ HI(31) | LO(55) /* lwzux */, -/* Half. */ - -/* s h n i s */ HI(44) /* sth */, -/* s h n i l */ HI(42) /* lha */, -/* s h n x s */ HI(31) | LO(407) /* sthx */, -/* s h n x l */ HI(31) | LO(343) /* lhax */, - -/* s h w i s */ HI(45) /* sthu */, -/* s h w i l */ HI(43) /* lhau */, -/* s h w x s */ HI(31) | LO(439) /* sthux */, -/* s h w x l */ HI(31) | LO(375) /* lhaux */, - -/* Int. */ - -/* s i n i s */ HI(36) /* stw */, -/* s i n i l */ ARCH_32_64(HI(32) /* lwz */, HI(58) | ADDR_MODE2 | 0x2 /* lwa */), -/* s i n x s */ HI(31) | LO(151) /* stwx */, -/* s i n x l */ ARCH_32_64(HI(31) | LO(23) /* lwzx */, HI(31) | LO(341) /* lwax */), - -/* s i w i s */ HI(37) /* stwu */, -/* s i w i l */ ARCH_32_64(HI(33) /* lwzu */, HI(58) | ADDR_MODE2 | UPDATE_REQ | 0x2 /* lwa */), -/* s i w x s */ HI(31) | LO(183) /* stwux */, -/* s i w x l */ ARCH_32_64(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */), - -/* -------- Double -------- */ - -/* d n i s */ HI(54) /* stfd */, -/* d n i l */ HI(50) /* lfd */, -/* d n x s */ HI(31) | LO(727) /* stfdx */, -/* d n x l */ HI(31) | LO(599) /* lfdx */, - -/* s n i s */ HI(52) /* stfs */, -/* s n i l */ HI(48) /* lfs */, -/* s n x s */ HI(31) | LO(663) /* stfsx */, -/* s n x l */ HI(31) | LO(535) /* lfsx */, +/* x w l s w */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(53) /* ldux */), +/* x w l s b */ HI(31) | LO(119) /* lbzux */ /* EXTS_REQ */, +/* x w l s h */ HI(31) | LO(375) /* lhaux */, +/* x w l s i */ ARCH_DEPEND(HI(31) | LO(55) /* lwzux */, HI(31) | LO(373) /* lwaux */) }; -#undef ARCH_32_64 +#undef ARCH_DEPEND /* Simple cases, (no caching is required). */ -static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw) +static int getput_arg_fast(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw) { sljit_ins inst; #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - sljit_si tmp_reg; + int tmp_reg; #endif SLJIT_ASSERT(arg & SLJIT_MEM); @@ -761,7 +684,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); - push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | IMM(argw)); + push_inst(compiler, GET_INST_CODE(inst) | D(reg) | IMM(argw)); return -1; } #else @@ -771,11 +694,11 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl if (inp_flags & ARG_TEST) return 1; - push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | IMM(argw)); + push_inst(compiler, GET_INST_CODE(inst) | D(reg) | IMM(argw)); return -1; } #endif - return 0; + return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0; } if (!(arg & 0xf0)) { @@ -786,7 +709,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl inst = data_transfer_insts[inp_flags & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); - push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | IMM(argw)); + push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | IMM(argw)); return -1; } #else @@ -802,7 +725,7 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl arg = tmp_reg | SLJIT_MEM; argw = 0; } - push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | IMM(argw)); + push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | IMM(argw)); return -1; } #endif @@ -812,24 +735,28 @@ static sljit_si getput_arg_fast(struct sljit_compiler *compiler, sljit_si inp_fl return 1; inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); - push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B((arg >> 4) & 0xf)); + push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B((arg >> 4) & 0xf)); return -1; } - return 0; + return (inp_flags & ARG_TEST) ? SLJIT_SUCCESS : 0; } /* See getput_arg below. Note: can_cache is called only for binary operators. Those operator always uses word arguments without write back. */ -static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static int can_cache(int arg, sljit_w argw, int next_arg, sljit_w next_argw) { - SLJIT_ASSERT((arg & SLJIT_MEM) && (next_arg & SLJIT_MEM)); + SLJIT_ASSERT(arg & SLJIT_MEM); + SLJIT_ASSERT(next_arg & SLJIT_MEM); - if (!(arg & 0xf)) - return (next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX); + if (!(arg & 0xf)) { + if ((next_arg & SLJIT_MEM) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) + return 1; + return 0; + } if (arg & 0xf0) - return ((arg & 0xf0) == (next_arg & 0xf0) && (argw & 0x3) == (next_argw & 0x3)); + return 0; if (argw <= SIMM_MAX && argw >= SIMM_MIN) { if (arg == next_arg && (next_argw >= SIMM_MAX && next_argw <= SIMM_MIN)) @@ -855,17 +782,21 @@ static sljit_si can_cache(sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_ #endif /* Emit the necessary instructions. See can_cache above. */ -static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, sljit_si reg, sljit_si arg, sljit_sw argw, sljit_si next_arg, sljit_sw next_argw) +static int getput_arg(struct sljit_compiler *compiler, int inp_flags, int reg, int arg, sljit_w argw, int next_arg, sljit_w next_argw) { - sljit_si tmp_r; + int tmp_r; sljit_ins inst; SLJIT_ASSERT(arg & SLJIT_MEM); - tmp_r = ((inp_flags & LOAD_DATA) && ((inp_flags) & MEM_MASK) <= GPR_REG) ? reg : TMP_REG1; - /* Special case for "mov reg, [reg, ... ]". */ - if ((arg & 0xf) == tmp_r) - tmp_r = TMP_REG1; + tmp_r = (inp_flags & LOAD_DATA) ? reg : TMP_REG3; + if ((arg & 0xf) == tmp_r) { + /* Special case for "mov reg, [reg, ... ]". + Caching would not happen anyway. */ + tmp_r = TMP_REG3; + compiler->cache_arg = 0; + compiler->cache_argw = 0; + } if (!(arg & 0xf)) { inst = data_transfer_insts[(inp_flags & ~WRITE_BACK) & MEM_MASK]; @@ -873,7 +804,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, argw = argw - compiler->cache_argw; ADJUST_CACHED_IMM(argw); SLJIT_ASSERT(!(inst & UPDATE_REQ)); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(argw)); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3) | IMM(argw)); } if ((next_arg & SLJIT_MEM) && (argw - next_argw <= SIMM_MAX || next_argw - argw <= SIMM_MAX)) { @@ -885,31 +816,21 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, } FAIL_IF(load_immediate(compiler, tmp_r, argw)); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(tmp_r)); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(tmp_r)); } if (SLJIT_UNLIKELY(arg & 0xf0)) { argw &= 0x3; /* Otherwise getput_arg_fast would capture it. */ SLJIT_ASSERT(argw); - - if ((SLJIT_MEM | (arg & 0xf0)) == compiler->cache_arg && argw == compiler->cache_argw) - tmp_r = TMP_REG3; - else { - if ((arg & 0xf0) == (next_arg & 0xf0) && argw == (next_argw & 0x3)) { - compiler->cache_arg = SLJIT_MEM | (arg & 0xf0); - compiler->cache_argw = argw; - tmp_r = TMP_REG3; - } #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1))); + FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(tmp_r) | (argw << 11) | ((31 - argw) << 1))); #else - FAIL_IF(push_inst(compiler, RLDI(tmp_r, (arg >> 4) & 0xf, argw, 63 - argw, 1))); + FAIL_IF(push_inst(compiler, RLDI(tmp_r, (arg >> 4) & 0xf, argw, 63 - argw, 1))); #endif - } inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(tmp_r)); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(tmp_r)); } inst = data_transfer_insts[inp_flags & MEM_MASK]; @@ -918,13 +839,13 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, SLJIT_ASSERT(!(inp_flags & WRITE_BACK)); argw = argw - compiler->cache_argw; ADJUST_CACHED_IMM(argw); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3) | IMM(argw)); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3) | IMM(argw)); } if ((compiler->cache_arg & SLJIT_IMM) && compiler->cache_argw == argw) { inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(TMP_REG3)); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(TMP_REG3)); } if (argw == next_argw && (next_arg & SLJIT_MEM)) { @@ -936,7 +857,7 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(TMP_REG3)); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(TMP_REG3)); } if (arg == next_arg && !(inp_flags & WRITE_BACK) && ((sljit_uw)argw - (sljit_uw)next_argw <= SIMM_MAX || (sljit_uw)next_argw - (sljit_uw)argw <= SIMM_MAX)) { @@ -947,58 +868,49 @@ static sljit_si getput_arg(struct sljit_compiler *compiler, sljit_si inp_flags, compiler->cache_arg = arg; compiler->cache_argw = argw; - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(TMP_REG3)); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(TMP_REG3)); } /* Get the indexed version instead of the normal one. */ inst = data_transfer_insts[(inp_flags | INDEXED) & MEM_MASK]; SLJIT_ASSERT(!(inst & (ADDR_MODE2 | UPDATE_REQ))); FAIL_IF(load_immediate(compiler, tmp_r, argw)); - return push_inst(compiler, INST_CODE_AND_DST(inst, inp_flags, reg) | A(arg & 0xf) | B(tmp_r)); + return push_inst(compiler, GET_INST_CODE(inst) | D(reg) | A(arg & 0xf) | B(tmp_r)); } -static SLJIT_INLINE sljit_si emit_op_mem2(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg1, sljit_sw arg1w, sljit_si arg2, sljit_sw arg2w) -{ - if (getput_arg_fast(compiler, flags, reg, arg1, arg1w)) - return compiler->error; - return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w); -} - -static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si input_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static int emit_op(struct sljit_compiler *compiler, int op, int inp_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { /* arg1 goes to TMP_REG1 or src reg arg2 goes to TMP_REG2, imm or src reg TMP_REG3 can be used for caching result goes to TMP_REG2, so put result can use TMP_REG1 and TMP_REG3. */ - sljit_si dst_r; - sljit_si src1_r; - sljit_si src2_r; - sljit_si sugg_src2_r = TMP_REG2; - sljit_si flags = input_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); + int dst_r; + int src1_r; + int src2_r; + int sugg_src2_r = TMP_REG2; + int flags = inp_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS); - if (!(input_flags & ALT_KEEP_CACHE)) { - compiler->cache_arg = 0; - compiler->cache_argw = 0; - } + compiler->cache_arg = 0; + compiler->cache_argw = 0; /* Destination check. */ - if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) - return SLJIT_SUCCESS; - dst_r = TMP_REG2; - } - else if (dst <= ZERO_REG) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= ZERO_REG) { dst_r = dst; flags |= REG_DEST; if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) sugg_src2_r = dst_r; } + else if (dst == SLJIT_UNUSED) { + if (op >= SLJIT_MOV && op <= SLJIT_MOVU_SI && !(src2 & SLJIT_MEM)) + return SLJIT_SUCCESS; + dst_r = TMP_REG2; + } else { SLJIT_ASSERT(dst & SLJIT_MEM); - if (getput_arg_fast(compiler, input_flags | ARG_TEST, TMP_REG2, dst, dstw)) { + if (getput_arg_fast(compiler, inp_flags | ARG_TEST, TMP_REG2, dst, dstw)) { flags |= FAST_DEST; dst_r = TMP_REG2; } @@ -1009,15 +921,23 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i } /* Source 1. */ - if (src1 <= ZERO_REG) { + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= ZERO_REG) { src1_r = src1; flags |= REG1_SOURCE; } else if (src1 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if ((inp_flags & 0x3) == INT_DATA) { + if (inp_flags & SIGNED_DATA) + src1w = (signed int)src1w; + else + src1w = (unsigned int)src1w; + } +#endif FAIL_IF(load_immediate(compiler, TMP_REG1, src1w)); src1_r = TMP_REG1; } - else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { + else if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w)) { FAIL_IF(compiler->error); src1_r = TMP_REG1; } @@ -1025,17 +945,25 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i src1_r = 0; /* Source 2. */ - if (src2 <= ZERO_REG) { + if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= ZERO_REG) { src2_r = src2; flags |= REG2_SOURCE; if (!(flags & REG_DEST) && op >= SLJIT_MOV && op <= SLJIT_MOVU_SI) dst_r = src2_r; } else if (src2 & SLJIT_IMM) { +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if ((inp_flags & 0x3) == INT_DATA) { + if (inp_flags & SIGNED_DATA) + src2w = (signed int)src2w; + else + src2w = (unsigned int)src2w; + } +#endif FAIL_IF(load_immediate(compiler, sugg_src2_r, src2w)); src2_r = sugg_src2_r; } - else if (getput_arg_fast(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) { + else if (getput_arg_fast(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w)) { FAIL_IF(compiler->error); src2_r = sugg_src2_r; } @@ -1046,26 +974,26 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i All arguments are complex addressing modes, and it is a binary operator. */ if (src1_r == 0 && src2_r == 0 && dst_r == 0) { if (!can_cache(src1, src1w, src2, src2w) && can_cache(src1, src1w, dst, dstw)) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w)); - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); } else { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG2, src2, src2w, dst, dstw)); } src1_r = TMP_REG1; src2_r = TMP_REG2; } else if (src1_r == 0 && src2_r == 0) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, src2, src2w)); src1_r = TMP_REG1; } else if (src1_r == 0 && dst_r == 0) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw)); src1_r = TMP_REG1; } else if (src2_r == 0 && dst_r == 0) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, dst, dstw)); src2_r = sugg_src2_r; } @@ -1073,12 +1001,12 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i dst_r = TMP_REG2; if (src1_r == 0) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, TMP_REG1, src1, src1w, 0, 0)); src1_r = TMP_REG1; } if (src2_r == 0) { - FAIL_IF(getput_arg(compiler, input_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0)); + FAIL_IF(getput_arg(compiler, inp_flags | LOAD_DATA, sugg_src2_r, src2, src2w, 0, 0)); src2_r = sugg_src2_r; } @@ -1086,14 +1014,14 @@ static sljit_si emit_op(struct sljit_compiler *compiler, sljit_si op, sljit_si i if (flags & (FAST_DEST | SLOW_DEST)) { if (flags & FAST_DEST) - FAIL_IF(getput_arg_fast(compiler, input_flags, dst_r, dst, dstw)); + FAIL_IF(getput_arg_fast(compiler, inp_flags, dst_r, dst, dstw)); else - FAIL_IF(getput_arg(compiler, input_flags, dst_r, dst, dstw, 0, 0)); + FAIL_IF(getput_arg(compiler, inp_flags, dst_r, dst, dstw, 0, 0)); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { CHECK_ERROR(); check_sljit_emit_op0(compiler, op); @@ -1105,161 +1033,120 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler break; case SLJIT_UMUL: case SLJIT_SMUL: - FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG1))); + FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1))); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); - return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)); + FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)); #else - FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); - return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2)); + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); + return push_inst(compiler, (GET_OPCODE(op) == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_TEMPORARY_REG2) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2)); #endif case SLJIT_UDIV: case SLJIT_SDIV: - FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG1))); + FAIL_IF(push_inst(compiler, OR | S(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG1))); #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op & SLJIT_INT_OP) { - FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); - FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); - return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); } - FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); - FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); - return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVDU : DIVD) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); + FAIL_IF(push_inst(compiler, MULLD | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); #else - FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_REG2))); - FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG1) | B(SLJIT_SCRATCH_REG2))); - return push_inst(compiler, SUBF | D(SLJIT_SCRATCH_REG2) | A(SLJIT_SCRATCH_REG2) | B(TMP_REG1)); + FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_UDIV ? DIVWU : DIVW) | D(SLJIT_TEMPORARY_REG1) | A(TMP_REG1) | B(SLJIT_TEMPORARY_REG2))); + FAIL_IF(push_inst(compiler, MULLW | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG1) | B(SLJIT_TEMPORARY_REG2))); + return push_inst(compiler, SUBF | D(SLJIT_TEMPORARY_REG2) | A(SLJIT_TEMPORARY_REG2) | B(TMP_REG1)); #endif } return SLJIT_SUCCESS; } -#define EMIT_MOV(type, type_flags, type_cast) \ - emit_op(compiler, (src & SLJIT_IMM) ? SLJIT_MOV : type, flags | (type_flags), dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? type_cast srcw : srcw) - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; - sljit_si op_flags = GET_ALL_FLAGS(op); + int inp_flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; CHECK_ERROR(); check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw); ADJUST_LOCAL_OFFSET(dst, dstw); ADJUST_LOCAL_OFFSET(src, srcw); - op = GET_OPCODE(op); if ((src & SLJIT_IMM) && srcw == 0) src = ZERO_REG; - if (op_flags & SLJIT_SET_O) +#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) + if (op & SLJIT_INT_OP) { + inp_flags |= INT_DATA | SIGNED_DATA; + if (src & SLJIT_IMM) + srcw = (int)srcw; + } +#endif + if (op & SLJIT_SET_O) FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG))); - if (op_flags & SLJIT_INT_OP) { - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { - if (src <= ZERO_REG && src == dst) { - if (!TYPE_CAST_NEEDED(op)) - return SLJIT_SUCCESS; - } -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) - op = SLJIT_MOV_UI; - if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) - op = SLJIT_MOVU_UI; - if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) - op = SLJIT_MOV_SI; - if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) - op = SLJIT_MOVU_SI; -#endif - } -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - else { - /* Most operations expect sign extended arguments. */ - flags |= INT_DATA | SIGNED_DATA; - if (src & SLJIT_IMM) - srcw = (sljit_si)srcw; - } -#endif - } - - switch (op) { + switch (GET_OPCODE(op)) { case SLJIT_MOV: - case SLJIT_MOV_P: -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - case SLJIT_MOV_UI: - case SLJIT_MOV_SI: -#endif - return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA, dst, dstw, TMP_REG1, 0, src, srcw); -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) case SLJIT_MOV_UI: - return EMIT_MOV(SLJIT_MOV_UI, INT_DATA, (sljit_ui)); + return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_SI: - return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, (sljit_si)); -#endif + return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOV_UB: - return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA, (sljit_ub)); + return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOV_SB: - return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA, (sljit_sb)); + return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOV_UH: - return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA, (sljit_uh)); + return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOV_SH: - return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA, (sljit_sh)); + return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); case SLJIT_MOVU: - case SLJIT_MOVU_P: -#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) - case SLJIT_MOVU_UI: - case SLJIT_MOVU_SI: -#endif - return emit_op(compiler, SLJIT_MOV, flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_MOV, inp_flags | WORD_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) case SLJIT_MOVU_UI: - return EMIT_MOV(SLJIT_MOV_UI, INT_DATA | WRITE_BACK, (sljit_ui)); + return emit_op(compiler, SLJIT_MOV_UI, inp_flags | INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_SI: - return EMIT_MOV(SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, (sljit_si)); -#endif + return emit_op(compiler, SLJIT_MOV_SI, inp_flags | INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_MOVU_UB: - return EMIT_MOV(SLJIT_MOV_UB, BYTE_DATA | WRITE_BACK, (sljit_ub)); + return emit_op(compiler, SLJIT_MOV_UB, inp_flags | BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw); case SLJIT_MOVU_SB: - return EMIT_MOV(SLJIT_MOV_SB, BYTE_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sb)); + return emit_op(compiler, SLJIT_MOV_SB, inp_flags | BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw); case SLJIT_MOVU_UH: - return EMIT_MOV(SLJIT_MOV_UH, HALF_DATA | WRITE_BACK, (sljit_uh)); + return emit_op(compiler, SLJIT_MOV_UH, inp_flags | HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw); case SLJIT_MOVU_SH: - return EMIT_MOV(SLJIT_MOV_SH, HALF_DATA | SIGNED_DATA | WRITE_BACK, (sljit_sh)); + return emit_op(compiler, SLJIT_MOV_SH, inp_flags | HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw); case SLJIT_NOT: - return emit_op(compiler, SLJIT_NOT, flags, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_NOT, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_NEG: - return emit_op(compiler, SLJIT_NEG, flags, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_NEG, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); case SLJIT_CLZ: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - return emit_op(compiler, SLJIT_CLZ, flags | (!(op_flags & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_CLZ, inp_flags | (!(op & SLJIT_INT_OP) ? 0 : ALT_FORM1), dst, dstw, TMP_REG1, 0, src, srcw); #else - return emit_op(compiler, SLJIT_CLZ, flags, dst, dstw, TMP_REG1, 0, src, srcw); + return emit_op(compiler, SLJIT_CLZ, inp_flags, dst, dstw, TMP_REG1, 0, src, srcw); #endif } return SLJIT_SUCCESS; } -#undef EMIT_MOV - #define TEST_SL_IMM(src, srcw) \ (((src) & SLJIT_IMM) && (srcw) <= SIMM_MAX && (srcw) >= SIMM_MIN) @@ -1293,12 +1180,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler ((src) & SLJIT_IMM) #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_si flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; + int inp_flags = GET_FLAGS(op) ? ALT_SET_FLAGS : 0; CHECK_ERROR(); check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); @@ -1313,83 +1200,80 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op & SLJIT_INT_OP) { - /* Most operations expect sign extended arguments. */ - flags |= INT_DATA | SIGNED_DATA; + inp_flags |= INT_DATA | SIGNED_DATA; if (src1 & SLJIT_IMM) - src1w = (sljit_si)(src1w); + src1w = (src1w << 32) >> 32; if (src2 & SLJIT_IMM) - src2w = (sljit_si)(src2w); + src2w = (src2w << 32) >> 32; if (GET_FLAGS(op)) - flags |= ALT_SIGN_EXT; + inp_flags |= ALT_SIGN_EXT; } #endif if (op & SLJIT_SET_O) FAIL_IF(push_inst(compiler, MTXER | S(ZERO_REG))); - if (src2 == TMP_REG2) - flags |= ALT_KEEP_CACHE; switch (GET_OPCODE(op)) { case SLJIT_ADD: if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { if (TEST_SL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_SL_IMM(src1, src1w)) { compiler->imm = src1w & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); } if (TEST_SH_IMM(src2, src2w)) { compiler->imm = (src2w >> 16) & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_SH_IMM(src1, src1w)) { compiler->imm = (src1w >> 16) & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); } /* Range between -1 and -32768 is covered above. */ if (TEST_ADD_IMM(src2, src2w)) { compiler->imm = src2w & 0xffffffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_ADD_IMM(src1, src1w)) { compiler->imm = src1w & 0xffffffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src2, src2w, TMP_REG2, 0); } } if (!(GET_FLAGS(op) & (SLJIT_SET_E | SLJIT_SET_O))) { if (TEST_SL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_SL_IMM(src1, src1w)) { compiler->imm = src1w & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); } } - return emit_op(compiler, SLJIT_ADD, flags, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, SLJIT_ADD, inp_flags, dst, dstw, src1, src1w, src2, src2w); case SLJIT_ADDC: - return emit_op(compiler, SLJIT_ADDC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, SLJIT_ADDC, inp_flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUB: if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) { if (TEST_SL_IMM(src2, -src2w)) { compiler->imm = (-src2w) & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_SL_IMM(src1, src1w)) { compiler->imm = src1w & 0xffff; - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); } if (TEST_SH_IMM(src2, -src2w)) { compiler->imm = ((-src2w) >> 16) & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); } /* Range between -1 and -32768 is covered above. */ if (TEST_ADD_IMM(src2, -src2w)) { compiler->imm = -src2w & 0xffffffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0); } } if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U)) && !(op & (SLJIT_SET_O | SLJIT_SET_C))) { @@ -1397,55 +1281,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ if (TEST_SL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); } if (GET_FLAGS(op) == SLJIT_SET_E && TEST_SL_IMM(src1, src1w)) { compiler->imm = src1w & 0xffff; - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); } } if (!(op & (SLJIT_SET_E | SLJIT_SET_S))) { /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ if (TEST_UL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w); } if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) { compiler->imm = src2w; - return emit_op(compiler, SLJIT_SUB, flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2 | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } - return emit_op(compiler, SLJIT_SUB, flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, SLJIT_SUB, inp_flags | ((op & SLJIT_SET_U) ? ALT_FORM4 : 0) | ((op & (SLJIT_SET_E | SLJIT_SET_S)) ? ALT_FORM5 : 0), dst, dstw, src1, src1w, src2, src2w); } if (!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))) { if (TEST_SL_IMM(src2, -src2w)) { compiler->imm = (-src2w) & 0xffff; - return emit_op(compiler, SLJIT_ADD, flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } } /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */ - return emit_op(compiler, SLJIT_SUB, flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, SLJIT_SUB, inp_flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM6), dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUBC: - return emit_op(compiler, SLJIT_SUBC, flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, SLJIT_SUBC, inp_flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w); case SLJIT_MUL: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op & SLJIT_INT_OP) - flags |= ALT_FORM2; + inp_flags |= ALT_FORM2; #endif if (!GET_FLAGS(op)) { if (TEST_SL_IMM(src2, src2w)) { compiler->imm = src2w & 0xffff; - return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_MUL, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_SL_IMM(src1, src1w)) { compiler->imm = src1w & 0xffff; - return emit_op(compiler, SLJIT_MUL, flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + return emit_op(compiler, SLJIT_MUL, inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); } } - return emit_op(compiler, SLJIT_MUL, flags, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, SLJIT_MUL, inp_flags, dst, dstw, src1, src1w, src2, src2w); case SLJIT_AND: case SLJIT_OR: @@ -1454,61 +1338,58 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler if (!GET_FLAGS(op) || GET_OPCODE(op) == SLJIT_AND) { if (TEST_UL_IMM(src2, src2w)) { compiler->imm = src2w; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_UL_IMM(src1, src1w)) { compiler->imm = src1w; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src2, src2w, TMP_REG2, 0); } if (TEST_UH_IMM(src2, src2w)) { compiler->imm = (src2w >> 16) & 0xffff; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM2, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_UH_IMM(src1, src1w)) { compiler->imm = (src1w >> 16) & 0xffff; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM2, dst, dstw, src2, src2w, TMP_REG2, 0); } } if (!GET_FLAGS(op) && GET_OPCODE(op) != SLJIT_AND) { if (TEST_UI_IMM(src2, src2w)) { compiler->imm = src2w; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0); } if (TEST_UI_IMM(src1, src1w)) { compiler->imm = src1w; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM3, dst, dstw, src2, src2w, TMP_REG2, 0); } } - return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, GET_OPCODE(op), inp_flags, dst, dstw, src1, src1w, src2, src2w); - case SLJIT_ASHR: - if (op & SLJIT_KEEP_FLAGS) - flags |= ALT_FORM3; - /* Fall through. */ case SLJIT_SHL: case SLJIT_LSHR: + case SLJIT_ASHR: #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) if (op & SLJIT_INT_OP) - flags |= ALT_FORM2; + inp_flags |= ALT_FORM2; #endif if (src2 & SLJIT_IMM) { compiler->imm = src2w; - return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); + return emit_op(compiler, GET_OPCODE(op), inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0); } - return emit_op(compiler, GET_OPCODE(op), flags, dst, dstw, src1, src1w, src2, src2w); + return emit_op(compiler, GET_OPCODE(op), inp_flags, dst, dstw, src1, src1w, src2, src2w); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { check_sljit_get_register_index(reg); return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) { CHECK_ERROR(); check_sljit_emit_op_custom(compiler, instruction, size); @@ -1521,77 +1402,106 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co /* Floating point operators */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { /* Always available. */ return 1; } -#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6)) -#define SELECT_FOP(op, single, double) ((op & SLJIT_SINGLE_OP) ? single : double) - -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static int emit_fpu_data_transfer(struct sljit_compiler *compiler, int fpu_reg, int load, int arg, sljit_w argw) { - sljit_si dst_fr; + SLJIT_ASSERT(arg & SLJIT_MEM); + + /* Fast loads and stores. */ + if (!(arg & 0xf0)) { + /* Both for (arg & 0xf) == SLJIT_UNUSED and (arg & 0xf) != SLJIT_UNUSED. */ + if (argw <= SIMM_MAX && argw >= SIMM_MIN) + return push_inst(compiler, (load ? LFD : STFD) | FD(fpu_reg) | A(arg & 0xf) | IMM(argw)); + } + + if (arg & 0xf0) { + argw &= 0x3; + if (argw) { +#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) + FAIL_IF(push_inst(compiler, RLWINM | S((arg >> 4) & 0xf) | A(TMP_REG2) | (argw << 11) | ((31 - argw) << 1))); +#else + FAIL_IF(push_inst(compiler, RLDI(TMP_REG2, (arg >> 4) & 0xf, argw, 63 - argw, 1))); +#endif + return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(arg & 0xf) | B(TMP_REG2)); + } + return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(arg & 0xf) | B((arg >> 4) & 0xf)); + } + + /* Use cache. */ + if (compiler->cache_arg == arg && argw - compiler->cache_argw <= SIMM_MAX && argw - compiler->cache_argw >= SIMM_MIN) + return push_inst(compiler, (load ? LFD : STFD) | FD(fpu_reg) | A(TMP_REG3) | IMM(argw - compiler->cache_argw)); + + /* Put value to cache. */ + compiler->cache_arg = arg; + compiler->cache_argw = argw; + + FAIL_IF(load_immediate(compiler, TMP_REG3, argw)); + if (!(arg & 0xf)) + return push_inst(compiler, (load ? LFDX : STFDX) | FD(fpu_reg) | A(0) | B(TMP_REG3)); + return push_inst(compiler, (load ? LFDUX : STFDUX) | FD(fpu_reg) | A(TMP_REG3) | B(arg & 0xf)); +} + +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) +{ + int dst_fr; CHECK_ERROR(); check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); - SLJIT_COMPILE_ASSERT((SLJIT_SINGLE_OP == 0x100) && !(DOUBLE_DATA & 0x4), float_transfer_bit_error); compiler->cache_arg = 0; compiler->cache_argw = 0; - if (GET_OPCODE(op) == SLJIT_CMPD) { - if (dst > SLJIT_FLOAT_REG6) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, dst, dstw, src, srcw)); + if (GET_OPCODE(op) == SLJIT_FCMP) { + if (dst > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, dst, dstw)); dst = TMP_FREG1; } - - if (src > SLJIT_FLOAT_REG6) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src, srcw, 0, 0)); + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src, srcw)); src = TMP_FREG2; } - return push_inst(compiler, FCMPU | CRD(4) | FA(dst) | FB(src)); } - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG1 : dst; + dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; - if (src > SLJIT_FLOAT_REG6) { - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op) | LOAD_DATA, dst_fr, src, srcw, dst, dstw)); + if (src > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, dst_fr, 1, src, srcw)); src = dst_fr; } - switch (GET_OPCODE(op)) { - case SLJIT_MOVD: + switch (op) { + case SLJIT_FMOV: if (src != dst_fr && dst_fr != TMP_FREG1) FAIL_IF(push_inst(compiler, FMR | FD(dst_fr) | FB(src))); break; - case SLJIT_NEGD: + case SLJIT_FNEG: FAIL_IF(push_inst(compiler, FNEG | FD(dst_fr) | FB(src))); break; - case SLJIT_ABSD: + case SLJIT_FABS: FAIL_IF(push_inst(compiler, FABS | FD(dst_fr) | FB(src))); break; } - if (dst_fr == TMP_FREG1) { - if (GET_OPCODE(op) == SLJIT_MOVD) - dst_fr = src; - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), dst_fr, dst, dstw, 0, 0)); - } + if (dst_fr == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, src, 0, dst, dstw)); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_si dst_fr, flags = 0; + int dst_fr; CHECK_ERROR(); check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); @@ -1599,100 +1509,69 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile compiler->cache_arg = 0; compiler->cache_argw = 0; - dst_fr = (dst > SLJIT_FLOAT_REG6) ? TMP_FREG2 : dst; + dst_fr = (dst > SLJIT_FLOAT_REG4) ? TMP_FREG1 : dst; - if (src1 > SLJIT_FLOAT_REG6) { - if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w)) { - FAIL_IF(compiler->error); - src1 = TMP_FREG1; - } else - flags |= ALT_FORM1; - } - - if (src2 > SLJIT_FLOAT_REG6) { - if (getput_arg_fast(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w)) { - FAIL_IF(compiler->error); - src2 = TMP_FREG2; - } else - flags |= ALT_FORM2; - } - - if ((flags & (ALT_FORM1 | ALT_FORM2)) == (ALT_FORM1 | ALT_FORM2)) { - 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)); - } - 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)); - } - } - else if (flags & ALT_FORM1) - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG1, src1, src1w, dst, dstw)); - else if (flags & ALT_FORM2) - FAIL_IF(getput_arg(compiler, FLOAT_DATA(op) | LOAD_DATA, TMP_FREG2, src2, src2w, dst, dstw)); - - if (flags & ALT_FORM1) - src1 = TMP_FREG1; - if (flags & ALT_FORM2) + if (src2 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG2, 1, src2, src2w)); src2 = TMP_FREG2; + } - switch (GET_OPCODE(op)) { - case SLJIT_ADDD: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FADDS, FADD) | FD(dst_fr) | FA(src1) | FB(src2))); + if (src1 > SLJIT_FLOAT_REG4) { + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 1, src1, src1w)); + src1 = TMP_FREG1; + } + + switch (op) { + case SLJIT_FADD: + FAIL_IF(push_inst(compiler, FADD | FD(dst_fr) | FA(src1) | FB(src2))); break; - case SLJIT_SUBD: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FSUBS, FSUB) | FD(dst_fr) | FA(src1) | FB(src2))); + case SLJIT_FSUB: + FAIL_IF(push_inst(compiler, FSUB | FD(dst_fr) | FA(src1) | FB(src2))); break; - case SLJIT_MULD: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FMULS, FMUL) | FD(dst_fr) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); + case SLJIT_FMUL: + FAIL_IF(push_inst(compiler, FMUL | FD(dst_fr) | FA(src1) | FC(src2) /* FMUL use FC as src2 */)); break; - case SLJIT_DIVD: - FAIL_IF(push_inst(compiler, SELECT_FOP(op, FDIVS, FDIV) | FD(dst_fr) | FA(src1) | FB(src2))); + case SLJIT_FDIV: + FAIL_IF(push_inst(compiler, FDIV | FD(dst_fr) | FA(src1) | FB(src2))); break; } - if (dst_fr == TMP_FREG2) - FAIL_IF(emit_op_mem2(compiler, FLOAT_DATA(op), TMP_FREG2, dst, dstw, 0, 0)); + if (dst_fr == TMP_FREG1) + FAIL_IF(emit_fpu_data_transfer(compiler, TMP_FREG1, 0, dst, dstw)); return SLJIT_SUCCESS; } -#undef FLOAT_DATA -#undef SELECT_FOP - /* --------------------------------------------------------------------- */ /* Other instructions */ /* --------------------------------------------------------------------- */ -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); ADJUST_LOCAL_OFFSET(dst, dstw); - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - return SLJIT_SUCCESS; - - if (dst <= ZERO_REG) + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) return push_inst(compiler, MFLR | D(dst)); + else if (dst & SLJIT_MEM) { + FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2))); + return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); + } - /* Memory. */ - FAIL_IF(push_inst(compiler, MFLR | D(TMP_REG2))); - return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= ZERO_REG) + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) FAIL_IF(push_inst(compiler, MTLR | S(src))); else { if (src & SLJIT_MEM) @@ -1724,7 +1603,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi return label; } -static sljit_ins get_bo_bi_flags(sljit_si type) +static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, int type) { switch (type) { case SLJIT_C_EQUAL: @@ -1775,10 +1654,10 @@ static sljit_ins get_bo_bi_flags(sljit_si type) case SLJIT_C_FLOAT_NOT_EQUAL: return (4 << 21) | ((4 + 2) << 16); - case SLJIT_C_FLOAT_UNORDERED: + case SLJIT_C_FLOAT_NAN: return (12 << 21) | ((4 + 3) << 16); - case SLJIT_C_FLOAT_ORDERED: + case SLJIT_C_FLOAT_NOT_NAN: return (4 << 21) | ((4 + 3) << 16); default: @@ -1787,7 +1666,7 @@ static sljit_ins get_bo_bi_flags(sljit_si type) } } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { struct sljit_jump *jump; sljit_ins bo_bi_flags; @@ -1795,7 +1674,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile CHECK_ERROR_PTR(); check_sljit_emit_jump(compiler, type); - bo_bi_flags = get_bo_bi_flags(type & 0xff); + bo_bi_flags = get_bo_bi_flags(compiler, type & 0xff); if (!bo_bi_flags) return NULL; @@ -1815,16 +1694,20 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { + sljit_ins bo_bi_flags; struct sljit_jump *jump = NULL; - sljit_si src_r; + int src_r; CHECK_ERROR(); check_sljit_emit_ijump(compiler, type, src, srcw); ADJUST_LOCAL_OFFSET(src, srcw); - if (src <= ZERO_REG) + bo_bi_flags = get_bo_bi_flags(compiler, type); + FAIL_IF(!bo_bi_flags); + + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) src_r = src; else if (src & SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); @@ -1843,7 +1726,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil FAIL_IF(push_inst(compiler, MTCTR | S(src_r))); if (jump) jump->addr = compiler->size; - return push_inst(compiler, BCCTR | (20 << 21) | (type >= SLJIT_FAST_CALL ? 1 : 0)); + return push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)); } /* Get a bit from CR, all other bits are zeroed. */ @@ -1854,37 +1737,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil #define INVERT_BIT(dst) \ FAIL_IF(push_inst(compiler, XORI | S(dst) | A(dst) | 0x1)); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { - sljit_si reg, input_flags; - sljit_si flags = GET_ALL_FLAGS(op); + int reg; CHECK_ERROR(); - check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + check_sljit_emit_cond_value(compiler, op, dst, dstw, type); ADJUST_LOCAL_OFFSET(dst, dstw); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; - op = GET_OPCODE(op); - reg = (op < SLJIT_ADD && dst <= ZERO_REG) ? dst : TMP_REG2; - - compiler->cache_arg = 0; - compiler->cache_argw = 0; - if (op >= SLJIT_ADD && (src & SLJIT_MEM)) { - ADJUST_LOCAL_OFFSET(src, srcw); -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - input_flags = (flags & SLJIT_INT_OP) ? INT_DATA : WORD_DATA; -#else - input_flags = WORD_DATA; -#endif - FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw)); - src = TMP_REG1; - srcw = 0; - } + reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; switch (type) { case SLJIT_C_EQUAL: @@ -1956,11 +1820,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com INVERT_BIT(reg); break; - case SLJIT_C_FLOAT_UNORDERED: + case SLJIT_C_FLOAT_NAN: GET_CR_BIT(4 + 3, reg); break; - case SLJIT_C_FLOAT_ORDERED: + case SLJIT_C_FLOAT_NOT_NAN: GET_CR_BIT(4 + 3, reg); INVERT_BIT(reg); break; @@ -1970,31 +1834,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com break; } - if (op < SLJIT_ADD) { -#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) - if (op == SLJIT_MOV) - input_flags = WORD_DATA; - else { - op = SLJIT_MOV_UI; - input_flags = INT_DATA; - } -#else - op = SLJIT_MOV; - input_flags = WORD_DATA; -#endif - return (reg == TMP_REG2) ? emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0) : SLJIT_SUCCESS; - } + if (GET_OPCODE(op) == SLJIT_OR) + return emit_op(compiler, GET_OPCODE(op), GET_FLAGS(op) ? ALT_SET_FLAGS : 0, dst, dstw, dst, dstw, TMP_REG2, 0); -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) - compiler->skip_checks = 1; -#endif - return sljit_emit_op2(compiler, op | flags, dst, dstw, src, srcw, TMP_REG2, 0); + if (reg == TMP_REG2) + return emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0); + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { struct sljit_const *const_; - sljit_si reg; + int reg; CHECK_ERROR_PTR(); check_sljit_emit_const(compiler, dst, dstw, init_value); @@ -2004,7 +1855,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi PTR_FAIL_IF(!const_); set_const(const_, compiler); - reg = (dst <= ZERO_REG) ? dst : TMP_REG2; + reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REG2; PTR_FAIL_IF(emit_const(compiler, reg, init_value)); diff --git a/harbour/src/3rd/pcre/sjutils.c b/harbour/src/3rd/pcre/sjutils.c index 1f023fa644..21f5e94485 100644 --- a/harbour/src/3rd/pcre/sjutils.c +++ b/harbour/src/3rd/pcre/sjutils.c @@ -106,9 +106,9 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) #else /* _WIN32 */ -#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) +#include "pthread.h" -#include +#if (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) static pthread_mutex_t allocator_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -126,8 +126,6 @@ static SLJIT_INLINE void allocator_release_lock(void) #if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK) -#include - static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER; SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_grab_lock(void) @@ -148,57 +146,17 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_release_lock(void) /* Stack */ /* ------------------------------------------------------------------------ */ -#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) || (defined SLJIT_EXECUTABLE_ALLOCATOR && SLJIT_EXECUTABLE_ALLOCATOR) +#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) #ifdef _WIN32 #include "windows.h" #else -/* Provides mmap function. */ #include -/* For detecting the page size. */ #include - -#ifndef MAP_ANON - -#include - -/* Some old systems does not have MAP_ANON. */ -static sljit_si dev_zero = -1; - -#if (defined SLJIT_SINGLE_THREADED && SLJIT_SINGLE_THREADED) - -static SLJIT_INLINE sljit_si open_dev_zero(void) -{ - dev_zero = open("/dev/zero", O_RDWR); - return dev_zero < 0; -} - -#else /* SLJIT_SINGLE_THREADED */ - -#include - -static pthread_mutex_t dev_zero_mutex = PTHREAD_MUTEX_INITIALIZER; - -static SLJIT_INLINE sljit_si open_dev_zero(void) -{ - pthread_mutex_lock(&dev_zero_mutex); - dev_zero = open("/dev/zero", O_RDWR); - pthread_mutex_unlock(&dev_zero_mutex); - return dev_zero < 0; -} - -#endif /* SLJIT_SINGLE_THREADED */ - #endif -#endif - -#endif /* SLJIT_UTIL_STACK || SLJIT_EXECUTABLE_ALLOCATOR */ - -#if (defined SLJIT_UTIL_STACK && SLJIT_UTIL_STACK) - /* Planning to make it even more clever in the future. */ -static sljit_sw sljit_page_align = 0; +static sljit_w sljit_page_align = 0; SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(sljit_uw limit, sljit_uw max_limit) { @@ -237,7 +195,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj return NULL; #ifdef _WIN32 - base.ptr = VirtualAlloc(NULL, max_limit, MEM_RESERVE, PAGE_READWRITE); + base.ptr = VirtualAlloc(0, max_limit, MEM_RESERVE, PAGE_READWRITE); if (!base.ptr) { SLJIT_FREE(stack); return NULL; @@ -250,17 +208,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_stack* SLJIT_CALL sljit_allocate_stack(slj return NULL; } #else -#ifdef MAP_ANON - base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); -#else - if (dev_zero < 0) { - if (open_dev_zero()) { - SLJIT_FREE(stack); - return NULL; - } - } - base.ptr = mmap(NULL, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE, dev_zero, 0); -#endif + base.ptr = mmap(0, max_limit, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if (base.ptr == MAP_FAILED) { SLJIT_FREE(stack); return NULL; @@ -285,7 +233,7 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_CALL sljit_free_stack(struct sljit_stack* st SLJIT_FREE(stack); } -SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit) +SLJIT_API_FUNC_ATTRIBUTE sljit_w SLJIT_CALL sljit_stack_resize(struct sljit_stack* stack, sljit_uw new_limit) { sljit_uw aligned_old_limit; sljit_uw aligned_new_limit; @@ -314,14 +262,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_sta } aligned_new_limit = (new_limit + sljit_page_align) & ~sljit_page_align; aligned_old_limit = (stack->limit + sljit_page_align) & ~sljit_page_align; - /* If madvise is available, we release the unnecessary space. */ -#if defined(POSIX_MADV_DONTNEED) if (aligned_new_limit < aligned_old_limit) posix_madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, POSIX_MADV_DONTNEED); -#elif defined(MADV_DONTNEED) - if (aligned_new_limit < aligned_old_limit) - madvise((void*)aligned_new_limit, aligned_old_limit - aligned_new_limit, MADV_DONTNEED); -#endif stack->limit = new_limit; return 0; #endif diff --git a/harbour/src/3rd/pcre/sjx8632.c b/harbour/src/3rd/pcre/sjx8632.c index 03a595bd85..e9558250fc 100644 --- a/harbour/src/3rd/pcre/sjx8632.c +++ b/harbour/src/3rd/pcre/sjx8632.c @@ -26,30 +26,30 @@ /* x86 32-bit arch dependent functions. */ -static sljit_si emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_sw imm) +static int emit_do_imm(struct sljit_compiler *compiler, sljit_ub opcode, sljit_w imm) { - sljit_ub *inst; + sljit_ub *buf; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_sw)); - FAIL_IF(!inst); - INC_SIZE(1 + sizeof(sljit_sw)); - *inst++ = opcode; - *(sljit_sw*)inst = imm; + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_w)); + FAIL_IF(!buf); + INC_SIZE(1 + sizeof(sljit_w)); + *buf++ = opcode; + *(sljit_w*)buf = imm; return SLJIT_SUCCESS; } -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type) { if (type == SLJIT_JUMP) { - *code_ptr++ = JMP_i32; + *code_ptr++ = 0xe9; jump->addr++; } else if (type >= SLJIT_FAST_CALL) { - *code_ptr++ = CALL_i32; + *code_ptr++ = 0xe8; jump->addr++; } else { - *code_ptr++ = GROUP_0F; + *code_ptr++ = 0x0f; *code_ptr++ = get_jump_code(type); jump->addr += 2; } @@ -57,22 +57,22 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ if (jump->flags & JUMP_LABEL) jump->flags |= PATCH_MW; else - *(sljit_sw*)code_ptr = jump->u.target - (jump->addr + 4); + *(sljit_w*)code_ptr = jump->u.target - (jump->addr + 4); code_ptr += 4; return code_ptr; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { - sljit_si size; - sljit_si locals_offset; - sljit_ub *inst; + int size; + int locals_offset; + sljit_ub *buf; CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; compiler->args = args; compiler->flags_saved = 0; @@ -85,15 +85,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #else size = 1 + (saveds <= 3 ? saveds : 3) + (args > 0 ? (2 + args * 3) : 0); #endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); INC_SIZE(size); PUSH_REG(reg_map[TMP_REGISTER]); #if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (args > 0) { - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[TMP_REGISTER] << 3) | 0x4 /* esp */; + *buf++ = 0x8b; + *buf++ = 0xc4 | (reg_map[TMP_REGISTER] << 3); } #endif if (saveds > 2) @@ -105,94 +105,80 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (args > 0) { - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_SCRATCH_REG3]; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[SLJIT_TEMPORARY_REG3]; } if (args > 1) { - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_SCRATCH_REG2]; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[SLJIT_TEMPORARY_REG2]; } if (args > 2) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x4 /* esp */; - *inst++ = 0x24; - *inst++ = sizeof(sljit_sw) * (3 + 2); /* saveds >= 3 as well. */ + *buf++ = 0x8b; + *buf++ = 0x44 | (reg_map[SLJIT_SAVED_REG3] << 3); + *buf++ = 0x24; + *buf++ = sizeof(sljit_w) * (3 + 2); /* saveds >= 3 as well. */ } #else if (args > 0) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER]; - *inst++ = sizeof(sljit_sw) * 2; + *buf++ = 0x8b; + *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG1] << 3) | reg_map[TMP_REGISTER]; + *buf++ = sizeof(sljit_w) * 2; } if (args > 1) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER]; - *inst++ = sizeof(sljit_sw) * 3; + *buf++ = 0x8b; + *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG2] << 3) | reg_map[TMP_REGISTER]; + *buf++ = sizeof(sljit_w) * 3; } if (args > 2) { - *inst++ = MOV_r_rm; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER]; - *inst++ = sizeof(sljit_sw) * 4; + *buf++ = 0x8b; + *buf++ = 0x40 | (reg_map[SLJIT_SAVED_REG3] << 3) | reg_map[TMP_REGISTER]; + *buf++ = sizeof(sljit_w) * 4; } #endif -#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) locals_offset = 2 * sizeof(sljit_uw); -#else - SLJIT_COMPILE_ASSERT(FIXED_LOCALS_OFFSET >= 2 * sizeof(sljit_uw), require_at_least_two_words); - locals_offset = FIXED_LOCALS_OFFSET; -#endif - compiler->scratches_start = locals_offset; - if (scratches > 3) - locals_offset += (scratches - 3) * sizeof(sljit_uw); + compiler->temporaries_start = locals_offset; + if (temporaries > 3) + locals_offset += (temporaries - 3) * sizeof(sljit_uw); compiler->saveds_start = locals_offset; if (saveds > 3) locals_offset += (saveds - 3) * sizeof(sljit_uw); compiler->locals_offset = locals_offset; local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1)); - 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_SCRATCH_REG1], local_size)); -#else - local_size -= FIXED_LOCALS_OFFSET; - FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size)); - FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32, - SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, FIXED_LOCALS_OFFSET)); -#endif + FAIL_IF(emit_do_imm(compiler, 0xb8 + reg_map[SLJIT_TEMPORARY_REG1], local_size)); FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); } #endif + compiler->local_size = local_size; SLJIT_ASSERT(local_size > 0); - return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32, + return emit_non_cum_binary(compiler, 0x2b, 0x29, 0x5 << 3, 0x2d, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size); + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { - sljit_si locals_offset; + int locals_offset; CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, scratches, saveds, local_size); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; compiler->args = args; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif -#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) locals_offset = 2 * sizeof(sljit_uw); -#else - locals_offset = FIXED_LOCALS_OFFSET; -#endif - compiler->scratches_start = locals_offset; - if (scratches > 3) - locals_offset += (scratches - 3) * sizeof(sljit_uw); + compiler->temporaries_start = locals_offset; + if (temporaries > 3) + locals_offset += (temporaries - 3) * sizeof(sljit_uw); compiler->saveds_start = locals_offset; if (saveds > 3) locals_offset += (saveds - 3) * sizeof(sljit_uw); @@ -200,20 +186,21 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, compiler->local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1)); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { - sljit_si size; - sljit_ub *inst; + int size; + sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); SLJIT_ASSERT(compiler->args >= 0); + ADJUST_LOCAL_OFFSET(src, srcw); compiler->flags_saved = 0; FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); SLJIT_ASSERT(compiler->local_size > 0); - FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32, + FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05, SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size)); size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3); @@ -224,8 +211,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi if (compiler->args > 0) size += 2; #endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); INC_SIZE(size); @@ -238,11 +225,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi POP_REG(reg_map[TMP_REGISTER]); #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) if (compiler->args > 2) - RET_I16(sizeof(sljit_sw)); + RETN(sizeof(sljit_w)); else RET(); #else - RET(); + if (compiler->args > 0) + RETN(compiler->args * sizeof(sljit_w)); + else + RET(); #endif return SLJIT_SUCCESS; @@ -253,16 +243,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* --------------------------------------------------------------------- */ /* Size contains the flags as well. */ -static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, +static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size, /* The register or immediate operand. */ - sljit_si a, sljit_sw imma, + int a, sljit_w imma, /* The general operand (not immediate). */ - sljit_si b, sljit_sw immb) + int b, sljit_w immb) { - sljit_ub *inst; + sljit_ub *buf; sljit_ub *buf_ptr; - sljit_si flags = size & ~0xf; - sljit_si inst_size; + int flags = size & ~0xf; + int inst_size; /* Both cannot be switched on. */ SLJIT_ASSERT((flags & (EX86_BIN_INS | EX86_SHIFT_INS)) != (EX86_BIN_INS | EX86_SHIFT_INS)); @@ -273,16 +263,13 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si #if (defined SLJIT_SSE2 && SLJIT_SSE2) /* SSE2 and immediate is not possible. */ SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); - SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) - && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) - && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); #endif size &= 0xf; inst_size = size; #if (defined SLJIT_SSE2 && SLJIT_SSE2) - if (flags & (EX86_PREF_F2 | EX86_PREF_F3)) + if (flags & EX86_PREF_F2) inst_size++; #endif if (flags & EX86_PREF_66) @@ -292,13 +279,13 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si inst_size += 1; /* mod r/m byte. */ if (b & SLJIT_MEM) { if ((b & 0x0f) == SLJIT_UNUSED) - inst_size += sizeof(sljit_sw); + inst_size += sizeof(sljit_w); else if (immb != 0 && !(b & 0xf0)) { /* Immediate operand. */ if (immb <= 127 && immb >= -128) - inst_size += sizeof(sljit_sb); + inst_size += sizeof(sljit_b); else - inst_size += sizeof(sljit_sw); + inst_size += sizeof(sljit_w); } if ((b & 0xf) == SLJIT_LOCALS_REG && !(b & 0xf0)) @@ -328,31 +315,29 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else if (flags & EX86_HALF_ARG) inst_size += sizeof(short); else - inst_size += sizeof(sljit_sw); + inst_size += sizeof(sljit_w); } else SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); - inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); - PTR_FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + PTR_FAIL_IF(!buf); /* Encoding the byte. */ INC_SIZE(inst_size); #if (defined SLJIT_SSE2 && SLJIT_SSE2) if (flags & EX86_PREF_F2) - *inst++ = 0xf2; - if (flags & EX86_PREF_F3) - *inst++ = 0xf3; + *buf++ = 0xf2; #endif if (flags & EX86_PREF_66) - *inst++ = 0x66; + *buf++ = 0x66; - buf_ptr = inst + size; + buf_ptr = buf + size; /* Encode mod/rm byte. */ if (!(flags & EX86_SHIFT_INS)) { if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) - *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; + *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81; if ((a & SLJIT_IMM) || (a == 0)) *buf_ptr = 0; @@ -369,19 +354,19 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else { if (a & SLJIT_IMM) { if (imma == 1) - *inst = GROUP_SHIFT_1; + *buf = 0xd1; else - *inst = GROUP_SHIFT_N; + *buf = 0xc1; } else - *inst = GROUP_SHIFT_CL; + *buf = 0xd3; *buf_ptr = 0; } if (!(b & SLJIT_MEM)) #if (defined SLJIT_SSE2 && SLJIT_SSE2) - *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_map[b] : b); + *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_map[b] : b); #else - *buf_ptr++ |= MOD_REG + reg_map[b]; + *buf_ptr++ |= 0xc0 + reg_map[b]; #endif else if ((b & 0x0f) != SLJIT_UNUSED) { if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) { @@ -403,8 +388,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si if (immb <= 127 && immb >= -128) *buf_ptr++ = immb; /* 8 bit displacement. */ else { - *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_sw); + *(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_w); } } } @@ -415,8 +400,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si } else { *buf_ptr++ |= 0x05; - *(sljit_sw*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_sw); + *(sljit_w*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_w); } if (a & SLJIT_IMM) { @@ -425,57 +410,45 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else if (flags & EX86_HALF_ARG) *(short*)buf_ptr = imma; else if (!(flags & EX86_SHIFT_INS)) - *(sljit_sw*)buf_ptr = imma; + *(sljit_w*)buf_ptr = imma; } - return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); + return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1); } /* --------------------------------------------------------------------- */ /* Call / return instructions */ /* --------------------------------------------------------------------- */ -static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) +static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type) { - sljit_ub *inst; + sljit_ub *buf; #if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL) - inst = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, type >= SLJIT_CALL3 ? 1 + 2 + 1 : 1 + 2); + FAIL_IF(!buf); INC_SIZE(type >= SLJIT_CALL3 ? 2 + 1 : 2); if (type >= SLJIT_CALL3) - PUSH_REG(reg_map[SLJIT_SCRATCH_REG3]); - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_SCRATCH_REG3] << 3) | reg_map[SLJIT_SCRATCH_REG1]; + PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]); + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_TEMPORARY_REG3] << 3) | reg_map[SLJIT_TEMPORARY_REG1]; #else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0)); - FAIL_IF(!inst); - INC_SIZE(4 * (type - SLJIT_CALL0)); - - *inst++ = MOV_rm_r; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG1] << 3) | 0x4 /* SIB */; - *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG]; - *inst++ = 0; - if (type >= SLJIT_CALL2) { - *inst++ = MOV_rm_r; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG2] << 3) | 0x4 /* SIB */; - *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG]; - *inst++ = sizeof(sljit_sw); - } - if (type >= SLJIT_CALL3) { - *inst++ = MOV_rm_r; - *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG3] << 3) | 0x4 /* SIB */; - *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG]; - *inst++ = 2 * sizeof(sljit_sw); - } + buf = (sljit_ub*)ensure_buf(compiler, type - SLJIT_CALL0 + 1); + FAIL_IF(!buf); + INC_SIZE(type - SLJIT_CALL0); + if (type >= SLJIT_CALL3) + PUSH_REG(reg_map[SLJIT_TEMPORARY_REG3]); + if (type >= SLJIT_CALL2) + PUSH_REG(reg_map[SLJIT_TEMPORARY_REG2]); + PUSH_REG(reg_map[SLJIT_TEMPORARY_REG1]); #endif return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { - sljit_ub *inst; + sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); @@ -483,30 +456,33 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c CHECK_EXTRA_REGS(dst, dstw, (void)0); - /* For UNUSED dst. Uncommon, but possible. */ - if (dst == SLJIT_UNUSED) - dst = TMP_REGISTER; - - if (dst <= TMP_REGISTER) { - /* Unused dest is possible here. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); INC_SIZE(1); POP_REG(reg_map[dst]); return SLJIT_SUCCESS; } + else if (dst & SLJIT_MEM) { + buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!buf); + *buf++ = 0x8f; + return SLJIT_SUCCESS; + } - /* Memory. */ - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); - FAIL_IF(!inst); - *inst++ = POP_rm; + /* For UNUSED dst. Uncommon, but possible. */ + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); + + INC_SIZE(1); + POP_REG(reg_map[TMP_REGISTER]); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { - sljit_ub *inst; + sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); @@ -514,32 +490,32 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * CHECK_EXTRA_REGS(src, srcw, (void)0); - if (src <= TMP_REGISTER) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); - FAIL_IF(!inst); + if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + FAIL_IF(!buf); INC_SIZE(1 + 1); PUSH_REG(reg_map[src]); } else if (src & SLJIT_MEM) { - inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst |= PUSH_rm; + buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!buf); + *buf++ = 0xff; + *buf |= 6 << 3; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); INC_SIZE(1); } else { /* SLJIT_IMM. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + FAIL_IF(!buf); INC_SIZE(5 + 1); - *inst++ = PUSH_i32; - *(sljit_sw*)inst = srcw; - inst += sizeof(sljit_sw); + *buf++ = 0x68; + *(sljit_w*)buf = srcw; + buf += sizeof(sljit_w); } RET(); diff --git a/harbour/src/3rd/pcre/sjx8664.c b/harbour/src/3rd/pcre/sjx8664.c index 28f04fddd8..480cebc785 100644 --- a/harbour/src/3rd/pcre/sjx8664.c +++ b/harbour/src/3rd/pcre/sjx8664.c @@ -26,76 +26,75 @@ /* x86 64-bit arch dependent functions. */ -static sljit_si emit_load_imm64(struct sljit_compiler *compiler, sljit_si reg, sljit_sw imm) +static int emit_load_imm64(struct sljit_compiler *compiler, int reg, sljit_w imm) { - sljit_ub *inst; + sljit_ub *buf; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_sw)); - FAIL_IF(!inst); - INC_SIZE(2 + sizeof(sljit_sw)); - *inst++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); - *inst++ = MOV_r_i32 + (reg_map[reg] & 0x7); - *(sljit_sw*)inst = imm; + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_w)); + FAIL_IF(!buf); + INC_SIZE(2 + sizeof(sljit_w)); + *buf++ = REX_W | ((reg_map[reg] <= 7) ? 0 : REX_B); + *buf++ = 0xb8 + (reg_map[reg] & 0x7); + *(sljit_w*)buf = imm; return SLJIT_SUCCESS; } -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type) +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type) { if (type < SLJIT_JUMP) { - /* Invert type. */ *code_ptr++ = get_jump_code(type ^ 0x1) - 0x10; *code_ptr++ = 10 + 3; } SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_first); *code_ptr++ = REX_W | REX_B; - *code_ptr++ = MOV_r_i32 + 1; + *code_ptr++ = 0xb8 + 1; jump->addr = (sljit_uw)code_ptr; if (jump->flags & JUMP_LABEL) jump->flags |= PATCH_MD; else - *(sljit_sw*)code_ptr = jump->u.target; + *(sljit_w*)code_ptr = jump->u.target; - code_ptr += sizeof(sljit_sw); + code_ptr += sizeof(sljit_w); *code_ptr++ = REX_B; - *code_ptr++ = GROUP_FF; - *code_ptr++ = (type >= SLJIT_FAST_CALL) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1); + *code_ptr++ = 0xff; + *code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */; return code_ptr; } -static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type) +static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type) { - sljit_sw delta = addr - ((sljit_sw)code_ptr + 1 + sizeof(sljit_si)); + sljit_w delta = addr - ((sljit_w)code_ptr + 1 + sizeof(sljit_hw)); if (delta <= SLJIT_W(0x7fffffff) && delta >= SLJIT_W(-0x80000000)) { - *code_ptr++ = (type == 2) ? CALL_i32 : JMP_i32; - *(sljit_sw*)code_ptr = delta; + *code_ptr++ = (type == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */; + *(sljit_w*)code_ptr = delta; } else { SLJIT_COMPILE_ASSERT(reg_map[TMP_REG3] == 9, tmp3_is_9_second); *code_ptr++ = REX_W | REX_B; - *code_ptr++ = MOV_r_i32 + 1; - *(sljit_sw*)code_ptr = addr; - code_ptr += sizeof(sljit_sw); + *code_ptr++ = 0xb8 + 1; + *(sljit_w*)code_ptr = addr; + code_ptr += sizeof(sljit_w); *code_ptr++ = REX_B; - *code_ptr++ = GROUP_FF; - *code_ptr++ = (type == 2) ? (MOD_REG | CALL_rm | 1) : (MOD_REG | JMP_rm | 1); + *code_ptr++ = 0xff; + *code_ptr++ = (type == 2) ? 0xd1 /* call */ : 0xe1 /* jmp */; } return code_ptr; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { - sljit_si size, pushed_size; - sljit_ub *inst; + int size, pushed_size; + sljit_ub *buf; CHECK_ERROR(); - check_sljit_emit_enter(compiler, args, scratches, saveds, local_size); + check_sljit_emit_enter(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; compiler->flags_saved = 0; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) @@ -104,38 +103,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil size = saveds; /* Including the return address saved by the call instruction. */ - pushed_size = (saveds + 1) * sizeof(sljit_sw); + pushed_size = (saveds + 1) * sizeof(sljit_w); #ifndef _WIN64 if (saveds >= 2) size += saveds - 1; #else if (saveds >= 4) size += saveds - 3; - if (scratches >= 5) { + if (temporaries >= 5) { size += (5 - 4) * 2; - pushed_size += sizeof(sljit_sw); + pushed_size += sizeof(sljit_w); } #endif size += args * 3; if (size > 0) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); INC_SIZE(size); if (saveds >= 5) { SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG2] >= 8, saved_ereg2_is_hireg); - *inst++ = REX_B; + *buf++ = REX_B; PUSH_REG(reg_lmap[SLJIT_SAVED_EREG2]); } if (saveds >= 4) { SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_EREG1] >= 8, saved_ereg1_is_hireg); - *inst++ = REX_B; + *buf++ = REX_B; PUSH_REG(reg_lmap[SLJIT_SAVED_EREG1]); } if (saveds >= 3) { #ifndef _WIN64 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] >= 8, saved_reg3_is_hireg); - *inst++ = REX_B; + *buf++ = REX_B; #else SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG3] < 8, saved_reg3_is_loreg); #endif @@ -144,7 +143,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil if (saveds >= 2) { #ifndef _WIN64 SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] >= 8, saved_reg2_is_hireg); - *inst++ = REX_B; + *buf++ = REX_B; #else SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SAVED_REG2] < 8, saved_reg2_is_loreg); #endif @@ -155,44 +154,44 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil PUSH_REG(reg_lmap[SLJIT_SAVED_REG1]); } #ifdef _WIN64 - if (scratches >= 5) { + if (temporaries >= 5) { SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_EREG2] >= 8, temporary_ereg2_is_hireg); - *inst++ = REX_B; + *buf++ = REX_B; PUSH_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]); } #endif #ifndef _WIN64 if (args > 0) { - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7 /* rdi */; + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x7; } if (args > 1) { - *inst++ = REX_W | REX_R; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6 /* rsi */; + *buf++ = REX_W | REX_R; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG2] << 3) | 0x6; } if (args > 2) { - *inst++ = REX_W | REX_R; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2 /* rdx */; + *buf++ = REX_W | REX_R; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_lmap[SLJIT_SAVED_REG3] << 3) | 0x2; } #else if (args > 0) { - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1 /* rcx */; + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG1] << 3) | 0x1; } if (args > 1) { - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2 /* rdx */; + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG2] << 3) | 0x2; } if (args > 2) { - *inst++ = REX_W | REX_B; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0 /* r8 */; + *buf++ = REX_W | REX_B; + *buf++ = 0x8b; + *buf++ = 0xc0 | (reg_map[SLJIT_SAVED_REG3] << 3) | 0x0; } #endif } @@ -202,124 +201,101 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil #ifdef _WIN64 if (local_size > 1024) { /* Allocate stack for the callback, which grows the stack. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + (3 + sizeof(sljit_si))); - FAIL_IF(!inst); - INC_SIZE(4 + (3 + sizeof(sljit_si))); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_83; - *inst++ = MOD_REG | SUB | 4; + buf = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!buf); + INC_SIZE(4); + *buf++ = REX_W; + *buf++ = 0x83; + *buf++ = 0xc0 | (5 << 3) | 4; /* Pushed size must be divisible by 8. */ SLJIT_ASSERT(!(pushed_size & 0x7)); if (pushed_size & 0x8) { - *inst++ = 5 * sizeof(sljit_sw); - local_size -= 5 * sizeof(sljit_sw); + *buf++ = 5 * sizeof(sljit_w); + local_size -= 5 * sizeof(sljit_w); } else { - *inst++ = 4 * sizeof(sljit_sw); - local_size -= 4 * sizeof(sljit_sw); + *buf++ = 4 * sizeof(sljit_w); + local_size -= 4 * sizeof(sljit_w); } - /* Second instruction */ - SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG1] < 8, temporary_reg1_is_loreg); - *inst++ = REX_W; - *inst++ = MOV_rm_i32; - *inst++ = MOD_REG | reg_lmap[SLJIT_SCRATCH_REG1]; - *(sljit_si*)inst = local_size; -#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) - compiler->skip_checks = 1; -#endif + FAIL_IF(emit_load_imm64(compiler, SLJIT_TEMPORARY_REG1, local_size)); FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack))); } #endif SLJIT_ASSERT(local_size > 0); if (local_size <= 127) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!buf); INC_SIZE(4); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_83; - *inst++ = MOD_REG | SUB | 4; - *inst++ = local_size; + *buf++ = REX_W; + *buf++ = 0x83; + *buf++ = 0xc0 | (5 << 3) | 4; + *buf++ = local_size; } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 7); + FAIL_IF(!buf); INC_SIZE(7); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_81; - *inst++ = MOD_REG | SUB | 4; - *(sljit_si*)inst = local_size; - inst += sizeof(sljit_si); + *buf++ = REX_W; + *buf++ = 0x81; + *buf++ = 0xc0 | (5 << 3) | 4; + *(sljit_hw*)buf = local_size; + buf += sizeof(sljit_hw); } -#ifdef _WIN64 - /* Save xmm6 with MOVAPS instruction. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); - FAIL_IF(!inst); - INC_SIZE(5); - *inst++ = GROUP_0F; - *(sljit_si*)inst = 0x20247429; -#endif return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int saveds, int local_size) { - sljit_si pushed_size; + int pushed_size; CHECK_ERROR_VOID(); - check_sljit_set_context(compiler, args, scratches, saveds, local_size); + check_sljit_set_context(compiler, args, temporaries, saveds, local_size); - compiler->scratches = scratches; + compiler->temporaries = temporaries; compiler->saveds = saveds; #if (defined SLJIT_DEBUG && SLJIT_DEBUG) compiler->logical_local_size = local_size; #endif /* Including the return address saved by the call instruction. */ - pushed_size = (saveds + 1) * sizeof(sljit_sw); + pushed_size = (saveds + 1) * sizeof(sljit_w); #ifdef _WIN64 - if (scratches >= 5) - pushed_size += sizeof(sljit_sw); + if (temporaries >= 5) + pushed_size += sizeof(sljit_w); #endif compiler->local_size = ((local_size + FIXED_LOCALS_OFFSET + pushed_size + 16 - 1) & ~(16 - 1)) - pushed_size; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int op, int src, sljit_w srcw) { - sljit_si size; - sljit_ub *inst; + int size; + sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_return(compiler, op, src, srcw); + ADJUST_LOCAL_OFFSET(src, srcw); compiler->flags_saved = 0; FAIL_IF(emit_mov_before_return(compiler, op, src, srcw)); -#ifdef _WIN64 - /* Restore xmm6 with MOVAPS instruction. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); - FAIL_IF(!inst); - INC_SIZE(5); - *inst++ = GROUP_0F; - *(sljit_si*)inst = 0x20247428; -#endif SLJIT_ASSERT(compiler->local_size > 0); if (compiler->local_size <= 127) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!buf); INC_SIZE(4); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_83; - *inst++ = MOD_REG | ADD | 4; - *inst = compiler->local_size; + *buf++ = REX_W; + *buf++ = 0x83; + *buf++ = 0xc0 | (0 << 3) | 4; + *buf = compiler->local_size; } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 7); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 7); + FAIL_IF(!buf); INC_SIZE(7); - *inst++ = REX_W; - *inst++ = GROUP_BINARY_81; - *inst++ = MOD_REG | ADD | 4; - *(sljit_si*)inst = compiler->local_size; + *buf++ = REX_W; + *buf++ = 0x81; + *buf++ = 0xc0 | (0 << 3) | 4; + *(sljit_hw*)buf = compiler->local_size; } size = 1 + compiler->saveds; @@ -329,17 +305,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi #else if (compiler->saveds >= 4) size += compiler->saveds - 3; - if (compiler->scratches >= 5) + if (compiler->temporaries >= 5) size += (5 - 4) * 2; #endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); INC_SIZE(size); #ifdef _WIN64 - if (compiler->scratches >= 5) { - *inst++ = REX_B; + if (compiler->temporaries >= 5) { + *buf++ = REX_B; POP_REG(reg_lmap[SLJIT_TEMPORARY_EREG2]); } #endif @@ -347,22 +323,22 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi POP_REG(reg_map[SLJIT_SAVED_REG1]); if (compiler->saveds >= 2) { #ifndef _WIN64 - *inst++ = REX_B; + *buf++ = REX_B; #endif POP_REG(reg_lmap[SLJIT_SAVED_REG2]); } if (compiler->saveds >= 3) { #ifndef _WIN64 - *inst++ = REX_B; + *buf++ = REX_B; #endif POP_REG(reg_lmap[SLJIT_SAVED_REG3]); } if (compiler->saveds >= 4) { - *inst++ = REX_B; + *buf++ = REX_B; POP_REG(reg_lmap[SLJIT_SAVED_EREG1]); } if (compiler->saveds >= 5) { - *inst++ = REX_B; + *buf++ = REX_B; POP_REG(reg_lmap[SLJIT_SAVED_EREG2]); } @@ -374,32 +350,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi /* Operators */ /* --------------------------------------------------------------------- */ -static sljit_si emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_sw imm) +static int emit_do_imm32(struct sljit_compiler *compiler, sljit_ub rex, sljit_ub opcode, sljit_w imm) { - sljit_ub *inst; - sljit_si length = 1 + (rex ? 1 : 0) + sizeof(sljit_si); + sljit_ub *buf; - inst = (sljit_ub*)ensure_buf(compiler, 1 + length); - FAIL_IF(!inst); - INC_SIZE(length); - if (rex) - *inst++ = rex; - *inst++ = opcode; - *(sljit_si*)inst = imm; + if (rex != 0) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + sizeof(sljit_hw)); + FAIL_IF(!buf); + INC_SIZE(2 + sizeof(sljit_hw)); + *buf++ = rex; + *buf++ = opcode; + *(sljit_hw*)buf = imm; + } + else { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + sizeof(sljit_hw)); + FAIL_IF(!buf); + INC_SIZE(1 + sizeof(sljit_hw)); + *buf++ = opcode; + *(sljit_hw*)buf = imm; + } return SLJIT_SUCCESS; } -static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si size, +static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, int size, /* The register or immediate operand. */ - sljit_si a, sljit_sw imma, + int a, sljit_w imma, /* The general operand (not immediate). */ - sljit_si b, sljit_sw immb) + int b, sljit_w immb) { - sljit_ub *inst; + sljit_ub *buf; sljit_ub *buf_ptr; sljit_ub rex = 0; - sljit_si flags = size & ~0xf; - sljit_si inst_size; + int flags = size & ~0xf; + int inst_size; /* The immediate operand must be 32 bit. */ SLJIT_ASSERT(!(a & SLJIT_IMM) || compiler->mode32 || IS_HALFWORD(imma)); @@ -412,9 +395,6 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si #if (defined SLJIT_SSE2 && SLJIT_SSE2) /* SSE2 and immediate is not possible. */ SLJIT_ASSERT(!(a & SLJIT_IMM) || !(flags & EX86_SSE2)); - SLJIT_ASSERT((flags & (EX86_PREF_F2 | EX86_PREF_F3)) != (EX86_PREF_F2 | EX86_PREF_F3) - && (flags & (EX86_PREF_F2 | EX86_PREF_66)) != (EX86_PREF_F2 | EX86_PREF_66) - && (flags & (EX86_PREF_F3 | EX86_PREF_66)) != (EX86_PREF_F3 | EX86_PREF_66)); #endif size &= 0xf; @@ -436,7 +416,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si rex |= REX; #if (defined SLJIT_SSE2 && SLJIT_SSE2) - if (flags & (EX86_PREF_F2 | EX86_PREF_F3)) + if (flags & EX86_PREF_F2) inst_size++; #endif if (flags & EX86_PREF_66) @@ -446,16 +426,16 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si inst_size += 1; /* mod r/m byte. */ if (b & SLJIT_MEM) { if ((b & 0x0f) == SLJIT_UNUSED) - inst_size += 1 + sizeof(sljit_si); /* SIB byte required to avoid RIP based addressing. */ + inst_size += 1 + sizeof(sljit_hw); /* SIB byte required to avoid RIP based addressing. */ else { if (reg_map[b & 0x0f] >= 8) rex |= REX_B; if (immb != 0 && !(b & 0xf0)) { /* Immediate operand. */ if (immb <= 127 && immb >= -128) - inst_size += sizeof(sljit_sb); + inst_size += sizeof(sljit_b); else - inst_size += sizeof(sljit_si); + inst_size += sizeof(sljit_hw); } } @@ -495,7 +475,7 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else if (flags & EX86_HALF_ARG) inst_size += sizeof(short); else - inst_size += sizeof(sljit_si); + inst_size += sizeof(sljit_hw); } else { SLJIT_ASSERT(!(flags & EX86_SHIFT_INS) || a == SLJIT_PREF_SHIFT_REG); @@ -512,27 +492,25 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si if (rex) inst_size++; - inst = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); - PTR_FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + inst_size); + PTR_FAIL_IF(!buf); /* Encoding the byte. */ INC_SIZE(inst_size); #if (defined SLJIT_SSE2 && SLJIT_SSE2) if (flags & EX86_PREF_F2) - *inst++ = 0xf2; - if (flags & EX86_PREF_F3) - *inst++ = 0xf3; + *buf++ = 0xf2; #endif if (flags & EX86_PREF_66) - *inst++ = 0x66; + *buf++ = 0x66; if (rex) - *inst++ = rex; - buf_ptr = inst + size; + *buf++ = rex; + buf_ptr = buf + size; /* Encode mod/rm byte. */ if (!(flags & EX86_SHIFT_INS)) { if ((flags & EX86_BIN_INS) && (a & SLJIT_IMM)) - *inst = (flags & EX86_BYTE_ARG) ? GROUP_BINARY_83 : GROUP_BINARY_81; + *buf = (flags & EX86_BYTE_ARG) ? 0x83 : 0x81; if ((a & SLJIT_IMM) || (a == 0)) *buf_ptr = 0; @@ -549,19 +527,19 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else { if (a & SLJIT_IMM) { if (imma == 1) - *inst = GROUP_SHIFT_1; + *buf = 0xd1; else - *inst = GROUP_SHIFT_N; + *buf = 0xc1; } else - *inst = GROUP_SHIFT_CL; + *buf = 0xd3; *buf_ptr = 0; } if (!(b & SLJIT_MEM)) #if (defined SLJIT_SSE2 && SLJIT_SSE2) - *buf_ptr++ |= MOD_REG + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b); + *buf_ptr++ |= 0xc0 + ((!(flags & EX86_SSE2)) ? reg_lmap[b] : b); #else - *buf_ptr++ |= MOD_REG + reg_lmap[b]; + *buf_ptr++ |= 0xc0 + reg_lmap[b]; #endif else if ((b & 0x0f) != SLJIT_UNUSED) { if ((b & 0xf0) == SLJIT_UNUSED || (b & 0xf0) == (SLJIT_LOCALS_REG << 4)) { @@ -583,8 +561,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si if (immb <= 127 && immb >= -128) *buf_ptr++ = immb; /* 8 bit displacement. */ else { - *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_si); + *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_hw); } } } @@ -596,8 +574,8 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else { *buf_ptr++ |= 0x04; *buf_ptr++ = 0x25; - *(sljit_si*)buf_ptr = immb; /* 32 bit displacement. */ - buf_ptr += sizeof(sljit_si); + *(sljit_hw*)buf_ptr = immb; /* 32 bit displacement. */ + buf_ptr += sizeof(sljit_hw); } if (a & SLJIT_IMM) { @@ -606,55 +584,55 @@ static sljit_ub* emit_x86_instruction(struct sljit_compiler *compiler, sljit_si else if (flags & EX86_HALF_ARG) *(short*)buf_ptr = imma; else if (!(flags & EX86_SHIFT_INS)) - *(sljit_si*)buf_ptr = imma; + *(sljit_hw*)buf_ptr = imma; } - return !(flags & EX86_SHIFT_INS) ? inst : (inst + 1); + return !(flags & EX86_SHIFT_INS) ? buf : (buf + 1); } /* --------------------------------------------------------------------- */ /* Call / return instructions */ /* --------------------------------------------------------------------- */ -static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, sljit_si type) +static SLJIT_INLINE int call_with_args(struct sljit_compiler *compiler, int type) { - sljit_ub *inst; + sljit_ub *buf; #ifndef _WIN64 - SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 6 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers); + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 6 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers); - inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + FAIL_IF(!buf); INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); if (type >= SLJIT_CALL3) { - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x2 /* rdx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3]; + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (0x2 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3]; } - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x7 /* rdi */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1]; + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (0x7 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1]; #else - SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG2] == 2 && reg_map[SLJIT_SCRATCH_REG1] < 8 && reg_map[SLJIT_SCRATCH_REG3] < 8, args_registers); + SLJIT_COMPILE_ASSERT(reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[SLJIT_TEMPORARY_REG1] < 8 && reg_map[SLJIT_TEMPORARY_REG3] < 8, args_registers); - inst = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + ((type < SLJIT_CALL3) ? 3 : 6)); + FAIL_IF(!buf); INC_SIZE((type < SLJIT_CALL3) ? 3 : 6); if (type >= SLJIT_CALL3) { - *inst++ = REX_W | REX_R; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x0 /* r8 */ << 3) | reg_lmap[SLJIT_SCRATCH_REG3]; + *buf++ = REX_W | REX_R; + *buf++ = 0x8b; + *buf++ = 0xc0 | (0x0 << 3) | reg_lmap[SLJIT_TEMPORARY_REG3]; } - *inst++ = REX_W; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (0x1 /* rcx */ << 3) | reg_lmap[SLJIT_SCRATCH_REG1]; + *buf++ = REX_W; + *buf++ = 0x8b; + *buf++ = 0xc0 | (0x1 << 3) | reg_lmap[SLJIT_TEMPORARY_REG1]; #endif return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_enter(struct sljit_compiler *compiler, int dst, sljit_w dstw) { - sljit_ub *inst; + sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_fast_enter(compiler, dst, dstw); @@ -664,34 +642,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *c if (dst == SLJIT_UNUSED) dst = TMP_REGISTER; - if (dst <= TMP_REGISTER) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { if (reg_map[dst] < 8) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); + INC_SIZE(1); POP_REG(reg_lmap[dst]); - return SLJIT_SUCCESS; } + else { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!buf); - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); - FAIL_IF(!inst); - INC_SIZE(2); - *inst++ = REX_B; - POP_REG(reg_lmap[dst]); - return SLJIT_SUCCESS; + INC_SIZE(2); + *buf++ = REX_B; + POP_REG(reg_lmap[dst]); + } + } + else if (dst & SLJIT_MEM) { + /* REX_W is not necessary (src is not immediate). */ + compiler->mode32 = 1; + buf = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!buf); + *buf++ = 0x8f; } - - /* REX_W is not necessary (src is not immediate). */ - compiler->mode32 = 1; - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); - FAIL_IF(!inst); - *inst++ = POP_rm; return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fast_return(struct sljit_compiler *compiler, int src, sljit_w srcw) { - sljit_ub *inst; + sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_fast_return(compiler, src, srcw); @@ -702,45 +682,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * src = TMP_REGISTER; } - if (src <= TMP_REGISTER) { + if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) { if (reg_map[src] < 8) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1); + FAIL_IF(!buf); INC_SIZE(1 + 1); PUSH_REG(reg_lmap[src]); } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 1); + FAIL_IF(!buf); INC_SIZE(2 + 1); - *inst++ = REX_B; + *buf++ = REX_B; PUSH_REG(reg_lmap[src]); } } else if (src & SLJIT_MEM) { /* REX_W is not necessary (src is not immediate). */ compiler->mode32 = 1; - inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst |= PUSH_rm; + buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!buf); + *buf++ = 0xff; + *buf |= 6 << 3; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); INC_SIZE(1); } else { SLJIT_ASSERT(IS_HALFWORD(srcw)); /* SLJIT_IMM. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1); + FAIL_IF(!buf); INC_SIZE(5 + 1); - *inst++ = PUSH_i32; - *(sljit_si*)inst = srcw; - inst += sizeof(sljit_si); + *buf++ = 0x68; + *(sljit_hw*)buf = srcw; + buf += sizeof(sljit_hw); } RET(); @@ -752,12 +732,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler * /* Extend input */ /* --------------------------------------------------------------------- */ -static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static int emit_mov_int(struct sljit_compiler *compiler, int sign, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_ub* code; + int dst_r; compiler->mode32 = 0; @@ -765,32 +745,32 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { - if (dst <= TMP_REGISTER) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { if (sign || ((sljit_uw)srcw <= 0x7fffffff)) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_i32; + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw); + FAIL_IF(!code); + *code = 0xc7; return SLJIT_SUCCESS; } return emit_load_imm64(compiler, dst, srcw); } compiler->mode32 = 1; - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_si)srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_i32; + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_w)(sljit_i)srcw, dst, dstw); + FAIL_IF(!code); + *code = 0xc7; compiler->mode32 = 0; return SLJIT_SUCCESS; } - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_SAVED_REG3) ? dst : TMP_REGISTER; - if ((dst & SLJIT_MEM) && (src <= TMP_REGISTER)) + if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_SAVED_REG3)) dst_r = src; else { if (sign) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = MOVSXD_r_rm; + code = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw); + FAIL_IF(!code); + *code++ = 0x63; } else { compiler->mode32 = 1; FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw)); @@ -800,9 +780,9 @@ static sljit_si emit_mov_int(struct sljit_compiler *compiler, sljit_si sign, if (dst & SLJIT_MEM) { compiler->mode32 = 1; - inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_r; + code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x89; compiler->mode32 = 0; } diff --git a/harbour/src/3rd/pcre/sjx86c.c b/harbour/src/3rd/pcre/sjx86c.c index 0aa59e42e1..d380175eb1 100644 --- a/harbour/src/3rd/pcre/sjx86c.c +++ b/harbour/src/3rd/pcre/sjx86c.c @@ -24,7 +24,7 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) +SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name() { return "x86" SLJIT_CPUINFO; } @@ -67,17 +67,17 @@ SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void) #define TMP_REGISTER (SLJIT_NO_REGISTERS + 1) static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = { - 0, 0, 2, 1, 0, 0, 3, 6, 7, 0, 0, 4, 5 + 0, 0, 2, 1, 0, 0, 3, 6, 7, 0, 0, 4, 5 }; #define CHECK_EXTRA_REGS(p, w, do) \ if (p >= SLJIT_TEMPORARY_EREG1 && p <= SLJIT_TEMPORARY_EREG2) { \ - w = compiler->scratches_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_sw); \ + w = compiler->temporaries_start + (p - SLJIT_TEMPORARY_EREG1) * sizeof(sljit_w); \ p = SLJIT_MEM1(SLJIT_LOCALS_REG); \ do; \ } \ else if (p >= SLJIT_SAVED_EREG1 && p <= SLJIT_SAVED_EREG2) { \ - w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_sw); \ + w = compiler->saveds_start + (p - SLJIT_SAVED_EREG1) * sizeof(sljit_w); \ p = SLJIT_MEM1(SLJIT_LOCALS_REG); \ do; \ } @@ -95,20 +95,20 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 2] = { #ifndef _WIN64 /* 1st passed in rdi, 2nd argument passed in rsi, 3rd in rdx. */ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { - 0, 0, 6, 1, 8, 11, 3, 15, 14, 13, 12, 4, 2, 7, 9 + 0, 0, 6, 1, 8, 11, 3, 15, 14, 13, 12, 4, 2, 7, 9 }; /* low-map. reg_map & 0x7. */ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = { - 0, 0, 6, 1, 0, 3, 3, 7, 6, 5, 4, 4, 2, 7, 1 + 0, 0, 6, 1, 0, 3, 3, 7, 6, 5, 4, 4, 2, 7, 1 }; #else /* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = { - 0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 15, 4, 10, 8, 9 + 0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 15, 4, 10, 8, 9 }; /* low-map. reg_map & 0x7. */ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = { - 0, 0, 2, 1, 3, 5, 3, 6, 7, 6, 7, 4, 2, 0, 1 + 0, 0, 2, 1, 3, 5, 3, 6, 7, 6, 7, 4, 2, 0, 1 }; #endif @@ -118,6 +118,9 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = { #define REX_B 0x41 #define REX 0x40 +typedef unsigned int sljit_uhw; +typedef int sljit_hw; + #define IS_HALFWORD(x) ((x) <= 0x7fffffffll && (x) >= -0x80000000ll) #define NOT_HALFWORD(x) ((x) > 0x7fffffffll || (x) < -0x80000000ll) @@ -126,7 +129,7 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = { #endif /* SLJIT_CONFIG_X86_32 */ #if (defined SLJIT_SSE2 && SLJIT_SSE2) -#define TMP_FREG (0) +#define TMP_FREG (SLJIT_FLOAT_REG4 + 1) #endif /* Size flags for emit_x86_instruction: */ @@ -139,298 +142,108 @@ static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = { #define EX86_PREF_66 0x0400 #if (defined SLJIT_SSE2 && SLJIT_SSE2) -#define EX86_SSE2 0x0800 -#define EX86_PREF_F2 0x1000 -#define EX86_PREF_F3 0x2000 +#define EX86_PREF_F2 0x0800 +#define EX86_SSE2 0x1000 #endif -/* --------------------------------------------------------------------- */ -/* Instrucion forms */ -/* --------------------------------------------------------------------- */ +#define INC_SIZE(s) (*buf++ = (s), compiler->size += (s)) +#define INC_CSIZE(s) (*code++ = (s), compiler->size += (s)) -#define ADD (/* BINARY */ 0 << 3) -#define ADD_EAX_i32 0x05 -#define ADD_r_rm 0x03 -#define ADD_rm_r 0x01 -#define ADDSD_x_xm 0x58 -#define ADC (/* BINARY */ 2 << 3) -#define ADC_EAX_i32 0x15 -#define ADC_r_rm 0x13 -#define ADC_rm_r 0x11 -#define AND (/* BINARY */ 4 << 3) -#define AND_EAX_i32 0x25 -#define AND_r_rm 0x23 -#define AND_rm_r 0x21 -#define ANDPD_x_xm 0x54 -#define BSR_r_rm (/* GROUP_0F */ 0xbd) -#define CALL_i32 0xe8 -#define CALL_rm (/* GROUP_FF */ 2 << 3) -#define CDQ 0x99 -#define CMOVNE_r_rm (/* GROUP_0F */ 0x45) -#define CMP (/* BINARY */ 7 << 3) -#define CMP_EAX_i32 0x3d -#define CMP_r_rm 0x3b -#define CMP_rm_r 0x39 -#define DIV (/* GROUP_F7 */ 6 << 3) -#define DIVSD_x_xm 0x5e -#define INT3 0xcc -#define IDIV (/* GROUP_F7 */ 7 << 3) -#define IMUL (/* GROUP_F7 */ 5 << 3) -#define IMUL_r_rm (/* GROUP_0F */ 0xaf) -#define IMUL_r_rm_i8 0x6b -#define IMUL_r_rm_i32 0x69 -#define JE_i8 0x74 -#define JMP_i8 0xeb -#define JMP_i32 0xe9 -#define JMP_rm (/* GROUP_FF */ 4 << 3) -#define LEA_r_m 0x8d -#define MOV_r_rm 0x8b -#define MOV_r_i32 0xb8 -#define MOV_rm_r 0x89 -#define MOV_rm_i32 0xc7 -#define MOV_rm8_i8 0xc6 -#define MOV_rm8_r8 0x88 -#define MOVSD_x_xm 0x10 -#define MOVSD_xm_x 0x11 -#define MOVSXD_r_rm 0x63 -#define MOVSX_r_rm8 (/* GROUP_0F */ 0xbe) -#define MOVSX_r_rm16 (/* GROUP_0F */ 0xbf) -#define MOVZX_r_rm8 (/* GROUP_0F */ 0xb6) -#define MOVZX_r_rm16 (/* GROUP_0F */ 0xb7) -#define MUL (/* GROUP_F7 */ 4 << 3) -#define MULSD_x_xm 0x59 -#define NEG_rm (/* GROUP_F7 */ 3 << 3) -#define NOP 0x90 -#define NOT_rm (/* GROUP_F7 */ 2 << 3) -#define OR (/* BINARY */ 1 << 3) -#define OR_r_rm 0x0b -#define OR_EAX_i32 0x0d -#define OR_rm_r 0x09 -#define POP_r 0x58 -#define POP_rm 0x8f -#define POPF 0x9d -#define PUSH_i32 0x68 -#define PUSH_r 0x50 -#define PUSH_rm (/* GROUP_FF */ 6 << 3) -#define PUSHF 0x9c -#define RET_near 0xc3 -#define RET_i16 0xc2 -#define SBB (/* BINARY */ 3 << 3) -#define SBB_EAX_i32 0x1d -#define SBB_r_rm 0x1b -#define SBB_rm_r 0x19 -#define SAR (/* SHIFT */ 7 << 3) -#define SHL (/* SHIFT */ 4 << 3) -#define SHR (/* SHIFT */ 5 << 3) -#define SUB (/* BINARY */ 5 << 3) -#define SUB_EAX_i32 0x2d -#define SUB_r_rm 0x2b -#define SUB_rm_r 0x29 -#define SUBSD_x_xm 0x5c -#define TEST_EAX_i32 0xa9 -#define TEST_rm_r 0x85 -#define UCOMISD_x_xm 0x2e -#define XCHG_EAX_r 0x90 -#define XCHG_r_rm 0x87 -#define XOR (/* BINARY */ 6 << 3) -#define XOR_EAX_i32 0x35 -#define XOR_r_rm 0x33 -#define XOR_rm_r 0x31 -#define XORPD_x_xm 0x57 - -#define GROUP_0F 0x0f -#define GROUP_F7 0xf7 -#define GROUP_FF 0xff -#define GROUP_BINARY_81 0x81 -#define GROUP_BINARY_83 0x83 -#define GROUP_SHIFT_1 0xd1 -#define GROUP_SHIFT_N 0xc1 -#define GROUP_SHIFT_CL 0xd3 - -#define MOD_REG 0xc0 -#define MOD_DISP8 0x40 - -#define INC_SIZE(s) (*inst++ = (s), compiler->size += (s)) - -#define PUSH_REG(r) (*inst++ = (PUSH_r + (r))) -#define POP_REG(r) (*inst++ = (POP_r + (r))) -#define RET() (*inst++ = (RET_near)) -#define RET_I16(n) (*inst++ = (RET_i16), *inst++ = n, *inst++ = 0) +#define PUSH_REG(r) (*buf++ = (0x50 + (r))) +#define POP_REG(r) (*buf++ = (0x58 + (r))) +#define RET() (*buf++ = (0xc3)) +#define RETN(n) (*buf++ = (0xc2), *buf++ = n, *buf++ = 0) /* r32, r/m32 */ -#define MOV_RM(mod, reg, rm) (*inst++ = (MOV_r_rm), *inst++ = (mod) << 6 | (reg) << 3 | (rm)) +#define MOV_RM(mod, reg, rm) (*buf++ = (0x8b), *buf++ = (mod) << 6 | (reg) << 3 | (rm)) -/* Multithreading does not affect these static variables, since they store - built-in CPU features. Therefore they can be overwritten by different threads - if they detect the CPU features in the same time. */ -#if (defined SLJIT_SSE2 && SLJIT_SSE2) && (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) -static sljit_si cpu_has_sse2 = -1; -#endif -static sljit_si cpu_has_cmov = -1; - -#if defined(_MSC_VER) && (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -#if _MSC_VER >= 1400 -#include -#else -#error "MSVC does not support inline assembly in 64 bit mode" -#endif -#endif /* _MSC_VER && SLJIT_CONFIG_X86_64 */ - -static void get_cpu_features(void) -{ - sljit_ui features; - -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) - /* AT&T syntax. */ - __asm__ ( - "pushl %%ebx\n" - "movl $0x1, %%eax\n" - "cpuid\n" - "popl %%ebx\n" - "movl %%edx, %0\n" - : "=g" (features) - : - : "%eax", "%ecx", "%edx" - ); -#elif defined(_MSC_VER) || defined(__BORLANDC__) - /* Intel syntax. */ - __asm { - mov eax, 1 - push ebx - cpuid - pop ebx - mov features, edx - } -#else -# error "SLJIT_DETECT_SSE2 is not implemented for this C compiler" -#endif - -#else /* SLJIT_CONFIG_X86_32 */ - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C) - /* AT&T syntax. */ - __asm__ ( - "pushq %%rbx\n" - "movl $0x1, %%eax\n" - "cpuid\n" - "popq %%rbx\n" - "movl %%edx, %0\n" - : "=g" (features) - : - : "%rax", "%rcx", "%rdx" - ); -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - int CPUInfo[4]; - - __cpuid(CPUInfo, 1); - features = (sljit_ui)CPUInfo[3]; -#else - __asm { - mov eax, 1 - push rbx - cpuid - pop rbx - mov features, edx - } -#endif - -#endif /* SLJIT_CONFIG_X86_32 */ - -#if (defined SLJIT_SSE2 && SLJIT_SSE2) && (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) - cpu_has_sse2 = (features >> 26) & 0x1; -#endif - cpu_has_cmov = (features >> 15) & 0x1; -} - -static sljit_ub get_jump_code(sljit_si type) +static sljit_ub get_jump_code(int type) { switch (type) { case SLJIT_C_EQUAL: case SLJIT_C_FLOAT_EQUAL: - return 0x84 /* je */; + return 0x84; case SLJIT_C_NOT_EQUAL: case SLJIT_C_FLOAT_NOT_EQUAL: - return 0x85 /* jne */; + return 0x85; case SLJIT_C_LESS: case SLJIT_C_FLOAT_LESS: - return 0x82 /* jc */; + return 0x82; case SLJIT_C_GREATER_EQUAL: case SLJIT_C_FLOAT_GREATER_EQUAL: - return 0x83 /* jae */; + return 0x83; case SLJIT_C_GREATER: case SLJIT_C_FLOAT_GREATER: - return 0x87 /* jnbe */; + return 0x87; case SLJIT_C_LESS_EQUAL: case SLJIT_C_FLOAT_LESS_EQUAL: - return 0x86 /* jbe */; + return 0x86; case SLJIT_C_SIG_LESS: - return 0x8c /* jl */; + return 0x8c; case SLJIT_C_SIG_GREATER_EQUAL: - return 0x8d /* jnl */; + return 0x8d; case SLJIT_C_SIG_GREATER: - return 0x8f /* jnle */; + return 0x8f; case SLJIT_C_SIG_LESS_EQUAL: - return 0x8e /* jle */; + return 0x8e; case SLJIT_C_OVERFLOW: case SLJIT_C_MUL_OVERFLOW: - return 0x80 /* jo */; + return 0x80; case SLJIT_C_NOT_OVERFLOW: case SLJIT_C_MUL_NOT_OVERFLOW: - return 0x81 /* jno */; + return 0x81; - case SLJIT_C_FLOAT_UNORDERED: - return 0x8a /* jp */; + case SLJIT_C_FLOAT_NAN: + return 0x8a; - case SLJIT_C_FLOAT_ORDERED: - return 0x8b /* jpo */; + case SLJIT_C_FLOAT_NOT_NAN: + return 0x8b; } return 0; } -static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_si type); +static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, int type); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_sw addr, sljit_si type); +static sljit_ub* generate_fixed_jump(sljit_ub *code_ptr, sljit_w addr, int type); #endif -static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, sljit_si type) +static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code_ptr, sljit_ub *code, int type) { - sljit_si short_jump; + int short_jump; sljit_uw label_addr; if (jump->flags & JUMP_LABEL) label_addr = (sljit_uw)(code + jump->u.label->size); else label_addr = jump->u.target; - short_jump = (sljit_sw)(label_addr - (jump->addr + 2)) >= -128 && (sljit_sw)(label_addr - (jump->addr + 2)) <= 127; + short_jump = (sljit_w)(label_addr - (jump->addr + 2)) >= -128 && (sljit_w)(label_addr - (jump->addr + 2)) <= 127; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((sljit_sw)(label_addr - (jump->addr + 1)) > 0x7fffffffll || (sljit_sw)(label_addr - (jump->addr + 1)) < -0x80000000ll) + if ((sljit_w)(label_addr - (jump->addr + 1)) > 0x7fffffffll || (sljit_w)(label_addr - (jump->addr + 1)) < -0x80000000ll) return generate_far_jump_code(jump, code_ptr, type); #endif if (type == SLJIT_JUMP) { if (short_jump) - *code_ptr++ = JMP_i8; + *code_ptr++ = 0xeb; else - *code_ptr++ = JMP_i32; + *code_ptr++ = 0xe9; jump->addr++; } else if (type >= SLJIT_FAST_CALL) { short_jump = 0; - *code_ptr++ = CALL_i32; + *code_ptr++ = 0xe8; jump->addr++; } else if (short_jump) { @@ -438,20 +251,20 @@ static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code jump->addr++; } else { - *code_ptr++ = GROUP_0F; + *code_ptr++ = 0x0f; *code_ptr++ = get_jump_code(type); jump->addr += 2; } if (short_jump) { jump->flags |= PATCH_MB; - code_ptr += sizeof(sljit_sb); + code_ptr += sizeof(sljit_b); } else { jump->flags |= PATCH_MW; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - code_ptr += sizeof(sljit_sw); + code_ptr += sizeof(sljit_w); #else - code_ptr += sizeof(sljit_si); + code_ptr += sizeof(sljit_hw); #endif } @@ -510,19 +323,19 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil label = label->next; } else if (*buf_ptr == 1) { - const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw); + const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_w); const_ = const_->next; } else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *code_ptr++ = (*buf_ptr == 2) ? CALL_i32 : JMP_i32; + *code_ptr++ = (*buf_ptr == 2) ? 0xe8 /* call */ : 0xe9 /* jmp */; buf_ptr++; - *(sljit_sw*)code_ptr = *(sljit_sw*)buf_ptr - ((sljit_sw)code_ptr + sizeof(sljit_sw)); - code_ptr += sizeof(sljit_sw); - buf_ptr += sizeof(sljit_sw) - 1; + *(sljit_w*)code_ptr = *(sljit_w*)buf_ptr - ((sljit_w)code_ptr + sizeof(sljit_w)); + code_ptr += sizeof(sljit_w); + buf_ptr += sizeof(sljit_w) - 1; #else - code_ptr = generate_fixed_jump(code_ptr, *(sljit_sw*)(buf_ptr + 1), *buf_ptr); - buf_ptr += sizeof(sljit_sw); + code_ptr = generate_fixed_jump(code_ptr, *(sljit_w*)(buf_ptr + 1), *buf_ptr); + buf_ptr += sizeof(sljit_w); #endif } buf_ptr++; @@ -539,29 +352,29 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil jump = compiler->jumps; while (jump) { if (jump->flags & PATCH_MB) { - SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) >= -128 && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))) <= 127); - *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_sb))); + SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) >= -128 && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))) <= 127); + *(sljit_ub*)jump->addr = (sljit_ub)(jump->u.label->addr - (jump->addr + sizeof(sljit_b))); } else if (jump->flags & PATCH_MW) { if (jump->flags & JUMP_LABEL) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_sw))); + *(sljit_w*)jump->addr = (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_w))); #else - SLJIT_ASSERT((sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) >= -0x80000000ll && (sljit_sw)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))) <= 0x7fffffffll); - *(sljit_si*)jump->addr = (sljit_si)(jump->u.label->addr - (jump->addr + sizeof(sljit_si))); + SLJIT_ASSERT((sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll); + *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.label->addr - (jump->addr + sizeof(sljit_hw))); #endif } else { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *(sljit_sw*)jump->addr = (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_sw))); + *(sljit_w*)jump->addr = (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_w))); #else - SLJIT_ASSERT((sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) >= -0x80000000ll && (sljit_sw)(jump->u.target - (jump->addr + sizeof(sljit_si))) <= 0x7fffffffll); - *(sljit_si*)jump->addr = (sljit_si)(jump->u.target - (jump->addr + sizeof(sljit_si))); + SLJIT_ASSERT((sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) >= -0x80000000ll && (sljit_w)(jump->u.target - (jump->addr + sizeof(sljit_hw))) <= 0x7fffffffll); + *(sljit_hw*)jump->addr = (sljit_hw)(jump->u.target - (jump->addr + sizeof(sljit_hw))); #endif } } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) else if (jump->flags & PATCH_MD) - *(sljit_sw*)jump->addr = jump->u.label->addr; + *(sljit_w*)jump->addr = jump->u.label->addr; #endif jump = jump->next; @@ -578,65 +391,65 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil /* Operators */ /* --------------------------------------------------------------------- */ -static sljit_si emit_cum_binary(struct sljit_compiler *compiler, +static int emit_cum_binary(struct sljit_compiler *compiler, sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w); -static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, +static int emit_non_cum_binary(struct sljit_compiler *compiler, sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w); + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w); -static sljit_si emit_mov(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw); +static int emit_mov(struct sljit_compiler *compiler, + int dst, sljit_w dstw, + int src, sljit_w srcw); -static SLJIT_INLINE sljit_si emit_save_flags(struct sljit_compiler *compiler) +static SLJIT_INLINE int emit_save_flags(struct sljit_compiler *compiler) { - sljit_ub *inst; + sljit_ub *buf; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!buf); INC_SIZE(5); #else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 6); + FAIL_IF(!buf); INC_SIZE(6); - *inst++ = REX_W; + *buf++ = REX_W; #endif - *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp + sizeof(sljit_sw)] */ - *inst++ = 0x64; - *inst++ = 0x24; - *inst++ = (sljit_ub)sizeof(sljit_sw); - *inst++ = PUSHF; + *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */ + *buf++ = 0x64; + *buf++ = 0x24; + *buf++ = (sljit_ub)sizeof(sljit_w); + *buf++ = 0x9c; /* pushfd / pushfq */ compiler->flags_saved = 1; return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_restore_flags(struct sljit_compiler *compiler, sljit_si keep_flags) +static SLJIT_INLINE int emit_restore_flags(struct sljit_compiler *compiler, int keep_flags) { - sljit_ub *inst; + sljit_ub *buf; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 5); + FAIL_IF(!buf); INC_SIZE(5); - *inst++ = POPF; + *buf++ = 0x9d; /* popfd */ #else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 6); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 6); + FAIL_IF(!buf); INC_SIZE(6); - *inst++ = POPF; - *inst++ = REX_W; + *buf++ = 0x9d; /* popfq */ + *buf++ = REX_W; #endif - *inst++ = LEA_r_m; /* lea esp/rsp, [esp/rsp - sizeof(sljit_sw)] */ - *inst++ = 0x64; - *inst++ = 0x24; - *inst++ = (sljit_ub)-(sljit_sb)sizeof(sljit_sw); + *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */ + *buf++ = 0x64; + *buf++ = 0x24; + *buf++ = (sljit_ub)-(int)sizeof(sljit_w); compiler->flags_saved = keep_flags; return SLJIT_SUCCESS; } @@ -644,7 +457,7 @@ static SLJIT_INLINE sljit_si emit_restore_flags(struct sljit_compiler *compiler, #ifdef _WIN32 #include -static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size) +static void SLJIT_CALL sljit_grow_stack(sljit_w local_size) { /* Workaround for calling the internal _chkstk() function on Windows. This function touches all 4k pages belongs to the requested stack space, @@ -663,79 +476,79 @@ static void SLJIT_CALL sljit_grow_stack(sljit_sw local_size) #include "sjx8664.c" #endif -static sljit_si emit_mov(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static int emit_mov(struct sljit_compiler *compiler, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_ub* inst; + sljit_ub* code; if (dst == SLJIT_UNUSED) { /* No destination, doesn't need to setup flags. */ if (src & SLJIT_MEM) { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); - FAIL_IF(!inst); - *inst = MOV_r_rm; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); + FAIL_IF(!code); + *code = 0x8b; } return SLJIT_SUCCESS; } - if (src <= TMP_REGISTER) { - inst = emit_x86_instruction(compiler, 1, src, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_r; + if (src >= SLJIT_TEMPORARY_REG1 && src <= TMP_REGISTER) { + code = emit_x86_instruction(compiler, 1, src, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x89; return SLJIT_SUCCESS; } if (src & SLJIT_IMM) { - if (dst <= TMP_REGISTER) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); + return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw); #else if (!compiler->mode32) { if (NOT_HALFWORD(srcw)) return emit_load_imm64(compiler, dst, srcw); } else - return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, MOV_r_i32 + reg_lmap[dst], srcw); + return emit_do_imm32(compiler, (reg_map[dst] >= 8) ? REX_B : 0, 0xb8 + reg_lmap[dst], srcw); #endif } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (!compiler->mode32 && NOT_HALFWORD(srcw)) { FAIL_IF(emit_load_imm64(compiler, TMP_REG2, srcw)); - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_r; + code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x89; return SLJIT_SUCCESS; } #endif - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_i32; + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!code); + *code = 0xc7; return SLJIT_SUCCESS; } - if (dst <= TMP_REGISTER) { - inst = emit_x86_instruction(compiler, 1, dst, 0, src, srcw); - FAIL_IF(!inst); - *inst = MOV_r_rm; + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { + code = emit_x86_instruction(compiler, 1, dst, 0, src, srcw); + FAIL_IF(!code); + *code = 0x8b; return SLJIT_SUCCESS; } /* Memory to memory move. Requires two instruction. */ - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); - FAIL_IF(!inst); - *inst = MOV_r_rm; - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_r; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src, srcw); + FAIL_IF(!code); + *code = 0x8b; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x89; return SLJIT_SUCCESS; } #define EMIT_MOV(compiler, dst, dstw, src, srcw) \ FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op0(struct sljit_compiler *compiler, int op) { - sljit_ub *inst; + sljit_ub *buf; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si size; + int size; #endif CHECK_ERROR(); @@ -743,16 +556,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler switch (GET_OPCODE(op)) { case SLJIT_BREAKPOINT: - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); INC_SIZE(1); - *inst = INT3; + *buf = 0xcc; break; case SLJIT_NOP: - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); INC_SIZE(1); - *inst = NOP; + *buf = 0x90; break; case SLJIT_UMUL: case SLJIT_SMUL: @@ -762,14 +575,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) #ifdef _WIN64 SLJIT_COMPILE_ASSERT( - reg_map[SLJIT_SCRATCH_REG1] == 0 - && reg_map[SLJIT_SCRATCH_REG2] == 2 + reg_map[SLJIT_TEMPORARY_REG1] == 0 + && reg_map[SLJIT_TEMPORARY_REG2] == 2 && reg_map[TMP_REGISTER] > 7, invalid_register_assignment_for_div_mul); #else SLJIT_COMPILE_ASSERT( - reg_map[SLJIT_SCRATCH_REG1] == 0 - && reg_map[SLJIT_SCRATCH_REG2] < 7 + reg_map[SLJIT_TEMPORARY_REG1] == 0 + && reg_map[SLJIT_TEMPORARY_REG2] < 7 && reg_map[TMP_REGISTER] == 2, invalid_register_assignment_for_div_mul); #endif @@ -779,86 +592,87 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler op = GET_OPCODE(op); if (op == SLJIT_UDIV) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) - EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_SCRATCH_REG2, 0); - inst = emit_x86_instruction(compiler, 1, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0); + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0); + buf = emit_x86_instruction(compiler, 1, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0); #else - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); + buf = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); #endif - FAIL_IF(!inst); - *inst = XOR_r_rm; + FAIL_IF(!buf); + *buf = 0x33; } if (op == SLJIT_SDIV) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) || defined(_WIN64) - EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_SCRATCH_REG2, 0); + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG2, 0); #endif + /* CDQ instruction */ #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); INC_SIZE(1); - *inst = CDQ; + *buf = 0x99; #else if (compiler->mode32) { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!buf); INC_SIZE(1); - *inst = CDQ; + *buf = 0x99; } else { - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!buf); INC_SIZE(2); - *inst++ = REX_W; - *inst = CDQ; + *buf++ = REX_W; + *buf = 0x99; } #endif } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 2); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 2); + FAIL_IF(!buf); INC_SIZE(2); - *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_SCRATCH_REG2]); + *buf++ = 0xf7; + *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_map[TMP_REGISTER] : reg_map[SLJIT_TEMPORARY_REG2]); #else #ifdef _WIN64 size = (!compiler->mode32 || op >= SLJIT_UDIV) ? 3 : 2; #else size = (!compiler->mode32) ? 3 : 2; #endif - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); INC_SIZE(size); #ifdef _WIN64 if (!compiler->mode32) - *inst++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0); + *buf++ = REX_W | ((op >= SLJIT_UDIV) ? REX_B : 0); else if (op >= SLJIT_UDIV) - *inst++ = REX_B; - *inst++ = GROUP_F7; - *inst = MOD_REG | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_SCRATCH_REG2]); + *buf++ = REX_B; + *buf++ = 0xf7; + *buf = 0xc0 | ((op >= SLJIT_UDIV) ? reg_lmap[TMP_REGISTER] : reg_lmap[SLJIT_TEMPORARY_REG2]); #else if (!compiler->mode32) - *inst++ = REX_W; - *inst++ = GROUP_F7; - *inst = MOD_REG | reg_map[SLJIT_SCRATCH_REG2]; + *buf++ = REX_W; + *buf++ = 0xf7; + *buf = 0xc0 | reg_map[SLJIT_TEMPORARY_REG2]; #endif #endif switch (op) { case SLJIT_UMUL: - *inst |= MUL; + *buf |= 4 << 3; break; case SLJIT_SMUL: - *inst |= IMUL; + *buf |= 5 << 3; break; case SLJIT_UDIV: - *inst |= DIV; + *buf |= 6 << 3; break; case SLJIT_SDIV: - *inst |= IDIV; + *buf |= 7 << 3; break; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && !defined(_WIN64) - EMIT_MOV(compiler, SLJIT_SCRATCH_REG2, 0, TMP_REGISTER, 0); + EMIT_MOV(compiler, SLJIT_TEMPORARY_REG2, 0, TMP_REGISTER, 0); #endif break; } @@ -868,20 +682,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler #define ENCODE_PREFIX(prefix) \ do { \ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); \ - FAIL_IF(!inst); \ - INC_SIZE(1); \ - *inst = (prefix); \ + code = (sljit_ub*)ensure_buf(compiler, 1 + 1); \ + FAIL_IF(!code); \ + INC_CSIZE(1); \ + *code = (prefix); \ } while (0) -static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static int emit_mov_byte(struct sljit_compiler *compiler, int sign, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_ub* code; + int dst_r; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si work_r; + int work_r; #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) @@ -892,25 +706,22 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { - if (dst <= TMP_REGISTER) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); + return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw); #else - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0); - FAIL_IF(!inst); - *inst = MOV_rm_i32; - return SLJIT_SUCCESS; + return emit_load_imm64(compiler, dst, srcw); #endif } - inst = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_i8; + code = emit_x86_instruction(compiler, 1 | EX86_BYTE_ARG | EX86_NO_REXW, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!code); + *code = 0xc6; return SLJIT_SUCCESS; } - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; - if ((dst & SLJIT_MEM) && src <= TMP_REGISTER) { + if ((dst & SLJIT_MEM) && src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (reg_map[src] >= 4) { SLJIT_ASSERT(dst_r == TMP_REGISTER); @@ -922,34 +733,35 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, #endif } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - else if (src <= TMP_REGISTER && reg_map[src] >= 4) { + else if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS && reg_map[src] >= 4) { /* src, dst are registers. */ - SLJIT_ASSERT(dst >= SLJIT_SCRATCH_REG1 && dst <= TMP_REGISTER); + SLJIT_ASSERT(dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER); if (reg_map[dst] < 4) { if (dst != src) EMIT_MOV(compiler, dst, 0, src, 0); - inst = emit_x86_instruction(compiler, 2, dst, 0, dst, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; + code = emit_x86_instruction(compiler, 2, dst, 0, dst, 0); + FAIL_IF(!code); + *code++ = 0x0f; + *code = sign ? 0xbe : 0xb6; } else { if (dst != src) EMIT_MOV(compiler, dst, 0, src, 0); if (sign) { /* shl reg, 24 */ - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); - FAIL_IF(!inst); - *inst |= SHL; - /* sar reg, 24 */ - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); - FAIL_IF(!inst); - *inst |= SAR; + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); + FAIL_IF(!code); + *code |= 0x4 << 3; + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 24, dst, 0); + FAIL_IF(!code); + /* shr/sar reg, 24 */ + *code |= 0x7 << 3; } else { - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0xff, dst, 0); - FAIL_IF(!inst); - *(inst + 1) |= AND; + /* and dst, 0xff */ + code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 255, dst, 0); + FAIL_IF(!code); + *(code + 1) |= 0x4 << 3; } } return SLJIT_SUCCESS; @@ -957,74 +769,74 @@ static sljit_si emit_mov_byte(struct sljit_compiler *compiler, sljit_si sign, #endif else { /* src can be memory addr or reg_map[src] < 4 on x86_32 architectures. */ - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm8 : MOVZX_r_rm8; + code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); + FAIL_IF(!code); + *code++ = 0x0f; + *code = sign ? 0xbe : 0xb6; } if (dst & SLJIT_MEM) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (dst_r == TMP_REGISTER) { /* Find a non-used register, whose reg_map[src] < 4. */ - if ((dst & 0xf) == SLJIT_SCRATCH_REG1) { - if ((dst & 0xf0) == (SLJIT_SCRATCH_REG2 << 4)) - work_r = SLJIT_SCRATCH_REG3; + if ((dst & 0xf) == SLJIT_TEMPORARY_REG1) { + if ((dst & 0xf0) == (SLJIT_TEMPORARY_REG2 << 4)) + work_r = SLJIT_TEMPORARY_REG3; else - work_r = SLJIT_SCRATCH_REG2; + work_r = SLJIT_TEMPORARY_REG2; } else { - if ((dst & 0xf0) != (SLJIT_SCRATCH_REG1 << 4)) - work_r = SLJIT_SCRATCH_REG1; - else if ((dst & 0xf) == SLJIT_SCRATCH_REG2) - work_r = SLJIT_SCRATCH_REG3; + if ((dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4)) + work_r = SLJIT_TEMPORARY_REG1; + else if ((dst & 0xf) == SLJIT_TEMPORARY_REG2) + work_r = SLJIT_TEMPORARY_REG3; else - work_r = SLJIT_SCRATCH_REG2; + work_r = SLJIT_TEMPORARY_REG2; } - if (work_r == SLJIT_SCRATCH_REG1) { - ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REGISTER]); + if (work_r == SLJIT_TEMPORARY_REG1) { + ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]); } else { - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); - FAIL_IF(!inst); - *inst = XCHG_r_rm; + code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); + FAIL_IF(!code); + *code = 0x87; } - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_r8; + code = emit_x86_instruction(compiler, 1, work_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x88; - if (work_r == SLJIT_SCRATCH_REG1) { - ENCODE_PREFIX(XCHG_EAX_r + reg_map[TMP_REGISTER]); + if (work_r == SLJIT_TEMPORARY_REG1) { + ENCODE_PREFIX(0x90 + reg_map[TMP_REGISTER]); } else { - inst = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); - FAIL_IF(!inst); - *inst = XCHG_r_rm; + code = emit_x86_instruction(compiler, 1, work_r, 0, dst_r, 0); + FAIL_IF(!code); + *code = 0x87; } } else { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_r8; + code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x88; } #else - inst = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm8_r8; + code = emit_x86_instruction(compiler, 1 | EX86_REX | EX86_NO_REXW, dst_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x88; #endif } return SLJIT_SUCCESS; } -static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static int emit_mov_half(struct sljit_compiler *compiler, int sign, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_ub* code; + int dst_r; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; @@ -1034,222 +846,193 @@ static sljit_si emit_mov_half(struct sljit_compiler *compiler, sljit_si sign, return SLJIT_SUCCESS; /* Empty instruction. */ if (src & SLJIT_IMM) { - if (dst <= TMP_REGISTER) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - return emit_do_imm(compiler, MOV_r_i32 + reg_map[dst], srcw); + return emit_do_imm(compiler, 0xb8 + reg_map[dst], srcw); #else - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, srcw, dst, 0); - FAIL_IF(!inst); - *inst = MOV_rm_i32; - return SLJIT_SUCCESS; + return emit_load_imm64(compiler, dst, srcw); #endif } - inst = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_i32; + code = emit_x86_instruction(compiler, 1 | EX86_HALF_ARG | EX86_NO_REXW | EX86_PREF_66, SLJIT_IMM, srcw, dst, dstw); + FAIL_IF(!code); + *code = 0xc7; return SLJIT_SUCCESS; } - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; - if ((dst & SLJIT_MEM) && src <= TMP_REGISTER) + if ((dst & SLJIT_MEM) && (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)) dst_r = src; else { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = sign ? MOVSX_r_rm16 : MOVZX_r_rm16; + code = emit_x86_instruction(compiler, 2, dst_r, 0, src, srcw); + FAIL_IF(!code); + *code++ = 0x0f; + *code = sign ? 0xbf : 0xb7; } if (dst & SLJIT_MEM) { - inst = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = MOV_rm_r; + code = emit_x86_instruction(compiler, 1 | EX86_NO_REXW | EX86_PREF_66, dst_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x89; } return SLJIT_SUCCESS; } -static sljit_si emit_unary(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static int emit_unary(struct sljit_compiler *compiler, int un_index, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_ub* inst; + sljit_ub* code; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; + code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= (un_index) << 3; return SLJIT_SUCCESS; } if (dst == src && dstw == srcw) { /* Same input and output */ - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; + code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= (un_index) << 3; return SLJIT_SUCCESS; } - if (dst <= TMP_REGISTER) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { EMIT_MOV(compiler, dst, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; + code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= (un_index) << 3; return SLJIT_SUCCESS; } EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= opcode; + code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= (un_index) << 3; EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); return SLJIT_SUCCESS; } -static sljit_si emit_not_with_flags(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static int emit_not_with_flags(struct sljit_compiler *compiler, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_ub* inst; + sljit_ub* code; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst = OR_r_rm; + code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= 0x2 << 3; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code = 0x0b; return SLJIT_SUCCESS; } - if (dst <= TMP_REGISTER) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { EMIT_MOV(compiler, dst, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, dst, 0, dst, 0); - FAIL_IF(!inst); - *inst = OR_r_rm; + code = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= 0x2 << 3; + code = emit_x86_instruction(compiler, 1, dst, 0, dst, 0); + FAIL_IF(!code); + *code = 0x0b; return SLJIT_SUCCESS; } EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst = OR_r_rm; + code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= 0x2 << 3; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code = 0x0b; EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); return SLJIT_SUCCESS; } -static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +static int emit_clz(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_ub* inst; - sljit_si dst_r; + sljit_ub* code; + int dst_r; - SLJIT_UNUSED_ARG(op_flags); + SLJIT_UNUSED_ARG(op); if (SLJIT_UNLIKELY(dst == SLJIT_UNUSED)) { /* Just set the zero flag. */ EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); - inst = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst++ = GROUP_F7; - *inst |= NOT_rm; + code = emit_x86_instruction(compiler, 1, 0, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0xf7; + *code |= 0x2 << 3; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REGISTER, 0); + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, 31, TMP_REGISTER, 0); #else - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0); + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, TMP_REGISTER, 0); #endif - FAIL_IF(!inst); - *inst |= SHR; + FAIL_IF(!code); + *code |= 0x5 << 3; return SLJIT_SUCCESS; } if (SLJIT_UNLIKELY(src & SLJIT_IMM)) { - EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_IMM, srcw); + EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); src = TMP_REGISTER; srcw = 0; } - inst = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = BSR_r_rm; + code = emit_x86_instruction(compiler, 2, TMP_REGISTER, 0, src, srcw); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xbd; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (dst <= TMP_REGISTER) + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) dst_r = dst; else { /* Find an unused temporary register. */ - if ((dst & 0xf) != SLJIT_SCRATCH_REG1 && (dst & 0xf0) != (SLJIT_SCRATCH_REG1 << 4)) - dst_r = SLJIT_SCRATCH_REG1; - else if ((dst & 0xf) != SLJIT_SCRATCH_REG2 && (dst & 0xf0) != (SLJIT_SCRATCH_REG2 << 4)) - dst_r = SLJIT_SCRATCH_REG2; + if ((dst & 0xf) != SLJIT_TEMPORARY_REG1 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG1 << 4)) + dst_r = SLJIT_TEMPORARY_REG1; + else if ((dst & 0xf) != SLJIT_TEMPORARY_REG2 && (dst & 0xf0) != (SLJIT_TEMPORARY_REG2 << 4)) + dst_r = SLJIT_TEMPORARY_REG2; else - dst_r = SLJIT_SCRATCH_REG3; + dst_r = SLJIT_TEMPORARY_REG3; EMIT_MOV(compiler, dst, dstw, dst_r, 0); } EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, 32 + 31); #else - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REG2; + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= TMP_REGISTER) ? dst : TMP_REG2; compiler->mode32 = 0; - EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 64 + 63 : 32 + 31); - compiler->mode32 = op_flags & SLJIT_INT_OP; + EMIT_MOV(compiler, dst_r, 0, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 64 + 63 : 32 + 31); + compiler->mode32 = op & SLJIT_INT_OP; #endif - if (cpu_has_cmov == -1) - get_cpu_features(); - - if (cpu_has_cmov) { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = CMOVNE_r_rm; - } else { -#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - - *inst++ = JE_i8; - *inst++ = 2; - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_map[dst_r] << 3) | reg_map[TMP_REGISTER]; -#else - inst = (sljit_ub*)ensure_buf(compiler, 1 + 5); - FAIL_IF(!inst); - INC_SIZE(5); - - *inst++ = JE_i8; - *inst++ = 3; - *inst++ = REX_W | (reg_map[dst_r] >= 8 ? REX_R : 0) | (reg_map[TMP_REGISTER] >= 8 ? REX_B : 0); - *inst++ = MOV_r_rm; - *inst++ = MOD_REG | (reg_lmap[dst_r] << 3) | reg_lmap[TMP_REGISTER]; -#endif - } + code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0x45; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0); + code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 31, dst_r, 0); #else - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op_flags & SLJIT_INT_OP) ? 63 : 31, dst_r, 0); + code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, !(op & SLJIT_INT_OP) ? 63 : 31, dst_r, 0); #endif - FAIL_IF(!inst); - *(inst + 1) |= XOR; + FAIL_IF(!code); + *(code + 1) |= 0x6 << 3; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) if (dst & SLJIT_MEM) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); - FAIL_IF(!inst); - *inst = XCHG_r_rm; + code = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x87; } #else if (dst & SLJIT_MEM) @@ -1258,18 +1041,17 @@ static sljit_si emit_clz(struct sljit_compiler *compiler, sljit_si op_flags, return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_ub* inst; - sljit_si update = 0; - sljit_si op_flags = GET_ALL_FLAGS(op); + sljit_ub* code; + int update = 0; #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - sljit_si dst_is_ereg = 0; - sljit_si src_is_ereg = 0; + int dst_is_ereg = 0; + int src_is_ereg = 0; #else -# define src_is_ereg 0 + #define src_is_ereg 0 #endif CHECK_ERROR(); @@ -1280,58 +1062,41 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1); CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - compiler->mode32 = op_flags & SLJIT_INT_OP; + compiler->mode32 = op & SLJIT_INT_OP; #endif - op = GET_OPCODE(op); - if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) { + if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) { + op = GET_OPCODE(op); #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; #endif - if (op_flags & SLJIT_INT_OP) { - if (src <= TMP_REGISTER && src == dst) { - if (!TYPE_CAST_NEEDED(op)) - return SLJIT_SUCCESS; - } -#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (op == SLJIT_MOV_SI && (src & SLJIT_MEM)) - op = SLJIT_MOV_UI; - if (op == SLJIT_MOVU_SI && (src & SLJIT_MEM)) - op = SLJIT_MOVU_UI; - if (op == SLJIT_MOV_UI && (src & SLJIT_IMM)) - op = SLJIT_MOV_SI; - if (op == SLJIT_MOVU_UI && (src & SLJIT_IMM)) - op = SLJIT_MOVU_SI; -#endif - } - - SLJIT_COMPILE_ASSERT(SLJIT_MOV + 8 == SLJIT_MOVU, movu_offset); + SLJIT_COMPILE_ASSERT(SLJIT_MOV + 7 == SLJIT_MOVU, movu_offset); if (op >= SLJIT_MOVU) { update = 1; - op -= 8; + op -= 7; } if (src & SLJIT_IMM) { switch (op) { case SLJIT_MOV_UB: - srcw = (sljit_ub)srcw; + srcw = (unsigned char)srcw; break; case SLJIT_MOV_SB: - srcw = (sljit_sb)srcw; + srcw = (signed char)srcw; break; case SLJIT_MOV_UH: - srcw = (sljit_uh)srcw; + srcw = (unsigned short)srcw; break; case SLJIT_MOV_SH: - srcw = (sljit_sh)srcw; + srcw = (signed short)srcw; break; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) case SLJIT_MOV_UI: - srcw = (sljit_ui)srcw; + srcw = (unsigned int)srcw; break; case SLJIT_MOV_SI: - srcw = (sljit_si)srcw; + srcw = (signed int)srcw; break; #endif } @@ -1342,15 +1107,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler } if (SLJIT_UNLIKELY(update) && (src & SLJIT_MEM) && !src_is_ereg && (src & 0xf) && (srcw != 0 || (src & 0xf0) != 0)) { - inst = emit_x86_instruction(compiler, 1, src & 0xf, 0, src, srcw); - FAIL_IF(!inst); - *inst = LEA_r_m; + code = emit_x86_instruction(compiler, 1, src & 0xf, 0, src, srcw); + FAIL_IF(!code); + *code = 0x8d; src &= SLJIT_MEM | 0xf; srcw = 0; } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI || op == SLJIT_MOV_P) || (src & SLJIT_MEM))) { + if (SLJIT_UNLIKELY(dst_is_ereg) && (!(op == SLJIT_MOV || op == SLJIT_MOV_UI || op == SLJIT_MOV_SI) || (src & SLJIT_MEM))) { SLJIT_ASSERT(dst == SLJIT_MEM1(SLJIT_LOCALS_REG)); dst = TMP_REGISTER; } @@ -1358,7 +1123,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler switch (op) { case SLJIT_MOV: - case SLJIT_MOV_P: #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) case SLJIT_MOV_UI: case SLJIT_MOV_SI: @@ -1366,23 +1130,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler FAIL_IF(emit_mov(compiler, dst, dstw, src, srcw)); break; case SLJIT_MOV_UB: - FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, srcw)); + FAIL_IF(emit_mov_byte(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned char)srcw : srcw)); break; case SLJIT_MOV_SB: - FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, srcw)); + FAIL_IF(emit_mov_byte(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed char)srcw : srcw)); break; case SLJIT_MOV_UH: - FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, srcw)); + FAIL_IF(emit_mov_half(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned short)srcw : srcw)); break; case SLJIT_MOV_SH: - FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, srcw)); + FAIL_IF(emit_mov_half(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed short)srcw : srcw)); break; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) case SLJIT_MOV_UI: - FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, srcw)); + FAIL_IF(emit_mov_int(compiler, 0, dst, dstw, src, (src & SLJIT_IMM) ? (unsigned int)srcw : srcw)); break; case SLJIT_MOV_SI: - FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, srcw)); + FAIL_IF(emit_mov_int(compiler, 1, dst, dstw, src, (src & SLJIT_IMM) ? (signed int)srcw : srcw)); break; #endif } @@ -1393,77 +1157,77 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op1(struct sljit_compiler *compiler #endif if (SLJIT_UNLIKELY(update) && (dst & SLJIT_MEM) && (dst & 0xf) && (dstw != 0 || (dst & 0xf0) != 0)) { - inst = emit_x86_instruction(compiler, 1, dst & 0xf, 0, dst, dstw); - FAIL_IF(!inst); - *inst = LEA_r_m; + code = emit_x86_instruction(compiler, 1, dst & 0xf, 0, dst, dstw); + FAIL_IF(!code); + *code = 0x8d; } return SLJIT_SUCCESS; } - if (SLJIT_UNLIKELY(GET_FLAGS(op_flags))) + if (SLJIT_UNLIKELY(GET_FLAGS(op))) compiler->flags_saved = 0; - switch (op) { + switch (GET_OPCODE(op)) { case SLJIT_NOT: - if (SLJIT_UNLIKELY(op_flags & SLJIT_SET_E)) + if (SLJIT_UNLIKELY(op & SLJIT_SET_E)) return emit_not_with_flags(compiler, dst, dstw, src, srcw); - return emit_unary(compiler, NOT_rm, dst, dstw, src, srcw); + return emit_unary(compiler, 0x2, dst, dstw, src, srcw); case SLJIT_NEG: - if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) FAIL_IF(emit_save_flags(compiler)); - return emit_unary(compiler, NEG_rm, dst, dstw, src, srcw); + return emit_unary(compiler, 0x3, dst, dstw, src, srcw); case SLJIT_CLZ: - if (SLJIT_UNLIKELY(op_flags & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) + if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) FAIL_IF(emit_save_flags(compiler)); - return emit_clz(compiler, op_flags, dst, dstw, src, srcw); + return emit_clz(compiler, op, dst, dstw, src, srcw); } return SLJIT_SUCCESS; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -# undef src_is_ereg + #undef src_is_ereg #endif } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) -#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \ +#define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \ if (IS_HALFWORD(immw) || compiler->mode32) { \ - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ - FAIL_IF(!inst); \ - *(inst + 1) |= (op_imm); \ + code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ + FAIL_IF(!code); \ + *(code + 1) |= (_op_imm_); \ } \ else { \ FAIL_IF(emit_load_imm64(compiler, TMP_REG2, immw)); \ - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \ - FAIL_IF(!inst); \ - *inst = (op_mr); \ + code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, arg, argw); \ + FAIL_IF(!code); \ + *code = (_op_mr_); \ } -#define BINARY_EAX_IMM(op_eax_imm, immw) \ - FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (op_eax_imm), immw)) +#define BINARY_EAX_IMM(_op_eax_imm_, immw) \ + FAIL_IF(emit_do_imm32(compiler, (!compiler->mode32) ? REX_W : 0, (_op_eax_imm_), immw)) #else -#define BINARY_IMM(op_imm, op_mr, immw, arg, argw) \ - inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ - FAIL_IF(!inst); \ - *(inst + 1) |= (op_imm); +#define BINARY_IMM(_op_imm_, _op_mr_, immw, arg, argw) \ + code = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, immw, arg, argw); \ + FAIL_IF(!code); \ + *(code + 1) |= (_op_imm_); -#define BINARY_EAX_IMM(op_eax_imm, immw) \ - FAIL_IF(emit_do_imm(compiler, (op_eax_imm), immw)) +#define BINARY_EAX_IMM(_op_eax_imm_, immw) \ + FAIL_IF(emit_do_imm(compiler, (_op_eax_imm_), immw)) #endif -static sljit_si emit_cum_binary(struct sljit_compiler *compiler, +static int emit_cum_binary(struct sljit_compiler *compiler, sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_ub* inst; + sljit_ub* code; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); @@ -1471,9 +1235,9 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); } else { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; } return SLJIT_SUCCESS; } @@ -1481,9 +1245,9 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, if (dst == src1 && dstw == src1w) { if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128)) { + if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(op_eax_imm, src2w); } @@ -1491,22 +1255,22 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); } } - else if (dst <= TMP_REGISTER) { - inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; + else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); + FAIL_IF(!code); + *code = op_rm; } - else if (src2 <= TMP_REGISTER) { - /* Special exception for sljit_emit_op_flags. */ - inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; + else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= TMP_REGISTER) { + /* Special exception for sljit_emit_cond_value. */ + code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); + FAIL_IF(!code); + *code = op_mr; } else { EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!code); + *code = op_mr; } return SLJIT_SUCCESS; } @@ -1515,9 +1279,9 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, if (dst == src2 && dstw == src2w) { if (src1 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((dst == SLJIT_SCRATCH_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { + if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { #else - if ((dst == SLJIT_SCRATCH_REG1) && (src1w > 127 || src1w < -128)) { + if ((dst == SLJIT_TEMPORARY_REG1) && (src1w > 127 || src1w < -128)) { #endif BINARY_EAX_IMM(op_eax_imm, src1w); } @@ -1525,35 +1289,35 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src1w, dst, dstw); } } - else if (dst <= TMP_REGISTER) { - inst = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w); - FAIL_IF(!inst); - *inst = op_rm; + else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + code = emit_x86_instruction(compiler, 1, dst, dstw, src1, src1w); + FAIL_IF(!code); + *code = op_rm; } - else if (src1 <= TMP_REGISTER) { - inst = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; + else if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { + code = emit_x86_instruction(compiler, 1, src1, src1w, dst, dstw); + FAIL_IF(!code); + *code = op_mr; } else { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!code); + *code = op_mr; } return SLJIT_SUCCESS; } /* General version. */ - if (dst <= TMP_REGISTER) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { EMIT_MOV(compiler, dst, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); } else { - inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; + code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; } } else { @@ -1563,9 +1327,9 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); } else { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; } EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); } @@ -1573,13 +1337,13 @@ static sljit_si emit_cum_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, +static int emit_non_cum_binary(struct sljit_compiler *compiler, sljit_ub op_rm, sljit_ub op_mr, sljit_ub op_imm, sljit_ub op_eax_imm, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_ub* inst; + sljit_ub* code; if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); @@ -1587,9 +1351,9 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); } else { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; } return SLJIT_SUCCESS; } @@ -1597,9 +1361,9 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, if (dst == src1 && dstw == src1w) { if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if ((dst == SLJIT_SCRATCH_REG1) && (src2w > 127 || src2w < -128)) { + if ((dst == SLJIT_TEMPORARY_REG1) && (src2w > 127 || src2w < -128)) { #endif BINARY_EAX_IMM(op_eax_imm, src2w); } @@ -1607,35 +1371,35 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src2w, dst, dstw); } } - else if (dst <= TMP_REGISTER) { - inst = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; + else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { + code = emit_x86_instruction(compiler, 1, dst, dstw, src2, src2w); + FAIL_IF(!code); + *code = op_rm; } - else if (src2 <= TMP_REGISTER) { - inst = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; + else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { + code = emit_x86_instruction(compiler, 1, src2, src2w, dst, dstw); + FAIL_IF(!code); + *code = op_mr; } else { EMIT_MOV(compiler, TMP_REGISTER, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); - FAIL_IF(!inst); - *inst = op_mr; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, dst, dstw); + FAIL_IF(!code); + *code = op_mr; } return SLJIT_SUCCESS; } /* General version. */ - if (dst <= TMP_REGISTER && dst != src2) { + if ((dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) && dst != src2) { EMIT_MOV(compiler, dst, 0, src1, src1w); if (src2 & SLJIT_IMM) { BINARY_IMM(op_imm, op_mr, src2w, dst, 0); } else { - inst = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; + code = emit_x86_instruction(compiler, 1, dst, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; } } else { @@ -1645,9 +1409,9 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, BINARY_IMM(op_imm, op_mr, src2w, TMP_REGISTER, 0); } else { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); - FAIL_IF(!inst); - *inst = op_rm; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = op_rm; } EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); } @@ -1655,28 +1419,28 @@ static sljit_si emit_non_cum_binary(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_mul(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static int emit_mul(struct sljit_compiler *compiler, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_ub* inst; - sljit_si dst_r; + sljit_ub* code; + int dst_r; - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; /* Register destination. */ if (dst_r == src1 && !(src2 & SLJIT_IMM)) { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; + code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xaf; } else if (dst_r == src2 && !(src1 & SLJIT_IMM)) { - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; + code = emit_x86_instruction(compiler, 2, dst_r, 0, src1, src1w); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xaf; } else if (src1 & SLJIT_IMM) { if (src2 & SLJIT_IMM) { @@ -1686,42 +1450,42 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, } if (src1w <= 127 && src1w >= -128) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i8; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = (sljit_sb)src1w; + code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x6b; + code = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!code); + INC_CSIZE(1); + *code = (sljit_b)src1w; } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - *(sljit_sw*)inst = src1w; + code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x69; + code = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!code); + INC_CSIZE(4); + *(sljit_w*)code = src1w; } #else else if (IS_HALFWORD(src1w)) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - *(sljit_si*)inst = (sljit_si)src1w; + code = emit_x86_instruction(compiler, 1, dst_r, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x69; + code = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!code); + INC_CSIZE(4); + *(sljit_hw*)code = (sljit_hw)src1w; } else { EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); if (dst_r != src2) EMIT_MOV(compiler, dst_r, 0, src2, src2w); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; + code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xaf; } #endif } @@ -1729,42 +1493,42 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, /* Note: src1 is NOT immediate. */ if (src2w <= 127 && src2w >= -128) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i8; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1); - FAIL_IF(!inst); - INC_SIZE(1); - *inst = (sljit_sb)src2w; + code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!code); + *code = 0x6b; + code = (sljit_ub*)ensure_buf(compiler, 1 + 1); + FAIL_IF(!code); + INC_CSIZE(1); + *code = (sljit_b)src2w; } #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) else { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - *(sljit_sw*)inst = src2w; + code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!code); + *code = 0x69; + code = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!code); + INC_CSIZE(4); + *(sljit_w*)code = src2w; } #else else if (IS_HALFWORD(src2w)) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); - FAIL_IF(!inst); - *inst = IMUL_r_rm_i32; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4); - FAIL_IF(!inst); - INC_SIZE(4); - *(sljit_si*)inst = (sljit_si)src2w; + code = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w); + FAIL_IF(!code); + *code = 0x69; + code = (sljit_ub*)ensure_buf(compiler, 1 + 4); + FAIL_IF(!code); + INC_CSIZE(4); + *(sljit_hw*)code = (sljit_hw)src2w; } else { EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_IMM, src1w); if (dst_r != src1) EMIT_MOV(compiler, dst_r, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; + code = emit_x86_instruction(compiler, 2, dst_r, 0, TMP_REG2, 0); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xaf; } #endif } @@ -1773,10 +1537,10 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, if (ADDRESSING_DEPENDS_ON(src2, dst_r)) dst_r = TMP_REGISTER; EMIT_MOV(compiler, dst_r, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = IMUL_r_rm; + code = emit_x86_instruction(compiler, 2, dst_r, 0, src2, src2w); + FAIL_IF(!code); + *code++ = 0x0f; + *code = 0xaf; } if (dst_r == TMP_REGISTER) @@ -1785,13 +1549,13 @@ static sljit_si emit_mul(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_lea_binary(struct sljit_compiler *compiler, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static int emit_lea_binary(struct sljit_compiler *compiler, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_ub* inst; - sljit_si dst_r, done = 0; + sljit_ub* code; + int dst_r, done = 0; /* These cases better be left to handled by normal way. */ if (dst == src1 && dstw == src1w) @@ -1799,37 +1563,37 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, if (dst == src2 && dstw == src2w) return SLJIT_ERR_UNSUPPORTED; - dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; - if (src1 <= TMP_REGISTER) { - if (src2 <= TMP_REGISTER || src2 == TMP_REGISTER) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0); - FAIL_IF(!inst); - *inst = LEA_r_m; + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { + if ((src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) || src2 == TMP_REGISTER) { + code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0); + FAIL_IF(!code); + *code = 0x8d; done = 1; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (sljit_si)src2w); + code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), (int)src2w); #else if (src2 & SLJIT_IMM) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w); + code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src1), src2w); #endif - FAIL_IF(!inst); - *inst = LEA_r_m; + FAIL_IF(!code); + *code = 0x8d; done = 1; } } - else if (src2 <= TMP_REGISTER) { + else if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if ((src1 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src1w))) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (sljit_si)src1w); + code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), (int)src1w); #else if (src1 & SLJIT_IMM) { - inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w); + code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM1(src2), src1w); #endif - FAIL_IF(!inst); - *inst = LEA_r_m; + FAIL_IF(!code); + *code = 0x8d; done = 1; } } @@ -1842,37 +1606,37 @@ static sljit_si emit_lea_binary(struct sljit_compiler *compiler, return SLJIT_ERR_UNSUPPORTED; } -static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static int emit_cmp_binary(struct sljit_compiler *compiler, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_ub* inst; + sljit_ub* code; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { + if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { #endif - BINARY_EAX_IMM(CMP_EAX_i32, src2w); + BINARY_EAX_IMM(0x3d, src2w); return SLJIT_SUCCESS; } - if (src1 <= TMP_REGISTER) { + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { if (src2 & SLJIT_IMM) { - BINARY_IMM(CMP, CMP_rm_r, src2w, src1, 0); + BINARY_IMM(0x7 << 3, 0x39, src2w, src1, 0); } else { - inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); - FAIL_IF(!inst); - *inst = CMP_r_rm; + code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x3b; } return SLJIT_SUCCESS; } - if (src2 <= TMP_REGISTER && !(src1 & SLJIT_IMM)) { - inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); - FAIL_IF(!inst); - *inst = CMP_rm_r; + if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS && !(src1 & SLJIT_IMM)) { + code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); + FAIL_IF(!code); + *code = 0x39; return SLJIT_SUCCESS; } @@ -1882,93 +1646,93 @@ static sljit_si emit_cmp_binary(struct sljit_compiler *compiler, src1 = TMP_REGISTER; src1w = 0; } - BINARY_IMM(CMP, CMP_rm_r, src2w, src1, src1w); + BINARY_IMM(0x7 << 3, 0x39, src2w, src1, src1w); } else { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); - FAIL_IF(!inst); - *inst = CMP_r_rm; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x3b; } return SLJIT_SUCCESS; } -static sljit_si emit_test_binary(struct sljit_compiler *compiler, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static int emit_test_binary(struct sljit_compiler *compiler, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_ub* inst; + sljit_ub* code; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { + if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128) && (compiler->mode32 || IS_HALFWORD(src2w))) { #else - if (src1 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { + if (src1 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src2w > 127 || src2w < -128)) { #endif - BINARY_EAX_IMM(TEST_EAX_i32, src2w); + BINARY_EAX_IMM(0xa9, src2w); return SLJIT_SUCCESS; } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - if (src2 == SLJIT_SCRATCH_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { + if (src2 == SLJIT_TEMPORARY_REG1 && (src2 & SLJIT_IMM) && (src1w > 127 || src1w < -128) && (compiler->mode32 || IS_HALFWORD(src1w))) { #else - if (src2 == SLJIT_SCRATCH_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) { + if (src2 == SLJIT_TEMPORARY_REG1 && (src1 & SLJIT_IMM) && (src1w > 127 || src1w < -128)) { #endif - BINARY_EAX_IMM(TEST_EAX_i32, src1w); + BINARY_EAX_IMM(0xa9, src1w); return SLJIT_SUCCESS; } - if (src1 <= TMP_REGISTER) { + if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) { if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src2w) || compiler->mode32) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); - FAIL_IF(!inst); - *inst = GROUP_F7; + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); + FAIL_IF(!code); + *code = 0xf7; } else { FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0); - FAIL_IF(!inst); - *inst = TEST_rm_r; + code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src1, 0); + FAIL_IF(!code); + *code = 0x85; } #else - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); - FAIL_IF(!inst); - *inst = GROUP_F7; + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, src1, 0); + FAIL_IF(!code); + *code = 0xf7; #endif } else { - inst = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); - FAIL_IF(!inst); - *inst = TEST_rm_r; + code = emit_x86_instruction(compiler, 1, src1, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x85; } return SLJIT_SUCCESS; } - if (src2 <= TMP_REGISTER) { + if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) { if (src1 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src1w) || compiler->mode32) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0); - FAIL_IF(!inst); - *inst = GROUP_F7; + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src1w, src2, 0); + FAIL_IF(!code); + *code = 0xf7; } else { FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src1w)); - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0); - FAIL_IF(!inst); - *inst = TEST_rm_r; + code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, src2, 0); + FAIL_IF(!code); + *code = 0x85; } #else - inst = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0); - FAIL_IF(!inst); - *inst = GROUP_F7; + code = emit_x86_instruction(compiler, 1, src1, src1w, src2, 0); + FAIL_IF(!code); + *code = 0xf7; #endif } else { - inst = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); - FAIL_IF(!inst); - *inst = TEST_rm_r; + code = emit_x86_instruction(compiler, 1, src2, 0, src1, src1w); + FAIL_IF(!code); + *code = 0x85; } return SLJIT_SUCCESS; } @@ -1977,72 +1741,72 @@ static sljit_si emit_test_binary(struct sljit_compiler *compiler, if (src2 & SLJIT_IMM) { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (IS_HALFWORD(src2w) || compiler->mode32) { - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst = GROUP_F7; + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); + FAIL_IF(!code); + *code = 0xf7; } else { FAIL_IF(emit_load_imm64(compiler, TMP_REG2, src2w)); - inst = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst = TEST_rm_r; + code = emit_x86_instruction(compiler, 1, TMP_REG2, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code = 0x85; } #else - inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst = GROUP_F7; + code = emit_x86_instruction(compiler, 1, SLJIT_IMM, src2w, TMP_REGISTER, 0); + FAIL_IF(!code); + *code = 0xf7; #endif } else { - inst = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); - FAIL_IF(!inst); - *inst = TEST_rm_r; + code = emit_x86_instruction(compiler, 1, TMP_REGISTER, 0, src2, src2w); + FAIL_IF(!code); + *code = 0x85; } return SLJIT_SUCCESS; } -static sljit_si emit_shift(struct sljit_compiler *compiler, +static int emit_shift(struct sljit_compiler *compiler, sljit_ub mode, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_ub* inst; + sljit_ub* code; if ((src2 & SLJIT_IMM) || (src2 == SLJIT_PREF_SHIFT_REG)) { if (dst == src1 && dstw == src1w) { - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw); - FAIL_IF(!inst); - *inst |= mode; + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, dstw); + FAIL_IF(!code); + *code |= mode; return SLJIT_SUCCESS; } if (dst == SLJIT_UNUSED) { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst |= mode; + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); + FAIL_IF(!code); + *code |= mode; return SLJIT_SUCCESS; } if (dst == SLJIT_PREF_SHIFT_REG && src2 == SLJIT_PREF_SHIFT_REG) { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst |= mode; + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code |= mode; EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); return SLJIT_SUCCESS; } - if (dst <= TMP_REGISTER) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) { EMIT_MOV(compiler, dst, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0); - FAIL_IF(!inst); - *inst |= mode; + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, dst, 0); + FAIL_IF(!code); + *code |= mode; return SLJIT_SUCCESS; } EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); - inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); - FAIL_IF(!inst); - *inst |= mode; + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, src2, src2w, TMP_REGISTER, 0); + FAIL_IF(!code); + *code |= mode; EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); return SLJIT_SUCCESS; } @@ -2050,19 +1814,19 @@ static sljit_si emit_shift(struct sljit_compiler *compiler, if (dst == SLJIT_PREF_SHIFT_REG) { EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w); 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_REGISTER, 0); - FAIL_IF(!inst); - *inst |= mode; + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code |= mode; EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); } - else if (dst <= TMP_REGISTER && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) { + else if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS && dst != src2 && !ADDRESSING_DEPENDS_ON(src2, dst)) { if (src1 != dst) EMIT_MOV(compiler, dst, 0, src1, src1w); EMIT_MOV(compiler, TMP_REGISTER, 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, dst, 0); - FAIL_IF(!inst); - *inst |= mode; + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, dst, 0); + FAIL_IF(!code); + *code |= mode; EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); } else { @@ -2073,16 +1837,16 @@ static sljit_si emit_shift(struct sljit_compiler *compiler, EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0); #else /* [esp+0] contains the flags. */ - EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_sw), SLJIT_PREF_SHIFT_REG, 0); + EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_w), SLJIT_PREF_SHIFT_REG, 0); #endif 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_REGISTER, 0); - FAIL_IF(!inst); - *inst |= mode; + code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0); + FAIL_IF(!code); + *code |= mode; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0); #else - EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_sw)); + EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_w)); #endif EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); } @@ -2090,11 +1854,11 @@ static sljit_si emit_shift(struct sljit_compiler *compiler, return SLJIT_SUCCESS; } -static sljit_si emit_shift_with_flags(struct sljit_compiler *compiler, - sljit_ub mode, sljit_si set_flags, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +static int emit_shift_with_flags(struct sljit_compiler *compiler, + sljit_ub mode, int set_flags, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { /* The CPU does not set flags if the shift count is 0. */ if (src2 & SLJIT_IMM) { @@ -2108,27 +1872,27 @@ static sljit_si 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, 0x0b, 0x09, 0x1 << 3, 0x0d, dst, dstw, src1, src1w, SLJIT_IMM, 0); } if (!set_flags) return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w); - if (!(dst <= TMP_REGISTER)) + if (!(dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)) FAIL_IF(emit_cmp_binary(compiler, src1, src1w, SLJIT_IMM, 0)); FAIL_IF(emit_shift(compiler,mode, dst, dstw, src1, src1w, src2, src2w)); - if (dst <= TMP_REGISTER) + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { CHECK_ERROR(); check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w); @@ -2160,7 +1924,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler compiler->flags_saved = 0; if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved) FAIL_IF(emit_save_flags(compiler)); - return emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32, + return emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05, dst, dstw, src1, src1w, src2, src2w); case SLJIT_ADDC: if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */ @@ -2169,7 +1933,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler FAIL_IF(emit_save_flags(compiler)); if (SLJIT_UNLIKELY(GET_FLAGS(op))) compiler->flags_saved = 0; - return emit_cum_binary(compiler, ADC_r_rm, ADC_rm_r, ADC, ADC_EAX_i32, + return emit_cum_binary(compiler, 0x13, 0x11, 0x2 << 3, 0x15, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUB: if (!GET_FLAGS(op)) { @@ -2182,7 +1946,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler FAIL_IF(emit_save_flags(compiler)); 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, 0x2b, 0x29, 0x5 << 3, 0x2d, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SUBC: if (SLJIT_UNLIKELY(compiler->flags_saved)) /* C flag must be restored. */ @@ -2191,36 +1955,36 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op2(struct sljit_compiler *compiler FAIL_IF(emit_save_flags(compiler)); if (SLJIT_UNLIKELY(GET_FLAGS(op))) compiler->flags_saved = 0; - return emit_non_cum_binary(compiler, SBB_r_rm, SBB_rm_r, SBB, SBB_EAX_i32, + return emit_non_cum_binary(compiler, 0x1b, 0x19, 0x3 << 3, 0x1d, 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, 0x23, 0x21, 0x4 << 3, 0x25, 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, 0x0b, 0x09, 0x1 << 3, 0x0d, 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, 0x33, 0x31, 0x6 << 3, 0x35, dst, dstw, src1, src1w, src2, src2w); case SLJIT_SHL: - return emit_shift_with_flags(compiler, SHL, GET_FLAGS(op), + return emit_shift_with_flags(compiler, 0x4 << 3, GET_FLAGS(op), dst, dstw, src1, src1w, src2, src2w); case SLJIT_LSHR: - return emit_shift_with_flags(compiler, SHR, GET_FLAGS(op), + return emit_shift_with_flags(compiler, 0x5 << 3, GET_FLAGS(op), dst, dstw, src1, src1w, src2, src2w); case SLJIT_ASHR: - return emit_shift_with_flags(compiler, SAR, GET_FLAGS(op), + return emit_shift_with_flags(compiler, 0x7 << 3, GET_FLAGS(op), dst, dstw, src1, src1w, src2, src2w); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_register_index(int reg) { check_sljit_get_register_index(reg); #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) @@ -2231,19 +1995,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg) return reg_map[reg]; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler, - void *instruction, sljit_si size) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(struct sljit_compiler *compiler, + void *instruction, int size) { - sljit_ub *inst; + sljit_ub *buf; CHECK_ERROR(); check_sljit_emit_op_custom(compiler, instruction, size); SLJIT_ASSERT(size > 0 && size < 16); - inst = (sljit_ub*)ensure_buf(compiler, 1 + size); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + size); + FAIL_IF(!buf); INC_SIZE(size); - SLJIT_MEMMOVE(inst, instruction, size); + SLJIT_MEMMOVE(buf, instruction, size); return SLJIT_SUCCESS; } @@ -2254,82 +2018,107 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *co #if (defined SLJIT_SSE2 && SLJIT_SSE2) /* Alignment + 2 * 16 bytes. */ -static sljit_si sse2_data[3 + (4 + 4) * 2]; -static sljit_si *sse2_buffer; +static sljit_i sse2_data[3 + 4 + 4]; +static sljit_i *sse2_buffer; -static void init_compiler(void) +static void init_compiler() { - sse2_buffer = (sljit_si*)(((sljit_uw)sse2_data + 15) & ~0xf); - /* Single precision constants. */ - sse2_buffer[0] = 0x80000000; - sse2_buffer[4] = 0x7fffffff; - /* Double precision constants. */ - sse2_buffer[8] = 0; - sse2_buffer[9] = 0x80000000; - sse2_buffer[12] = 0xffffffff; - sse2_buffer[13] = 0x7fffffff; + sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf); + sse2_buffer[0] = 0; + sse2_buffer[1] = 0x80000000; + sse2_buffer[4] = 0xffffffff; + sse2_buffer[5] = 0x7fffffff; } #endif -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void) +SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void) { #if (defined SLJIT_SSE2 && SLJIT_SSE2) #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2) - if (cpu_has_sse2 == -1) - get_cpu_features(); - return cpu_has_sse2; -#else /* SLJIT_DETECT_SSE2 */ + static int sse2_available = -1; + int features; + + if (sse2_available != -1) + return sse2_available; + +#ifdef __GNUC__ + /* AT&T syntax. */ + asm ( + "pushl %%ebx\n" + "movl $0x1, %%eax\n" + "cpuid\n" + "popl %%ebx\n" + "movl %%edx, %0\n" + : "=g" (features) + : + : "%eax", "%ecx", "%edx" + ); +#elif defined(_MSC_VER) || defined(__BORLANDC__) + /* Intel syntax. */ + __asm { + mov eax, 1 + push ebx + cpuid + pop ebx + mov features, edx + } +#else + #error "SLJIT_DETECT_SSE2 is not implemented for this C compiler" +#endif + sse2_available = (features >> 26) & 0x1; + return sse2_available; +#else return 1; -#endif /* SLJIT_DETECT_SSE2 */ -#else /* SLJIT_SSE2 */ +#endif +#else return 0; #endif } #if (defined SLJIT_SSE2 && SLJIT_SSE2) -static sljit_si emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si single, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) +static int emit_sse2(struct sljit_compiler *compiler, sljit_ub opcode, + int xmm1, int xmm2, sljit_w xmm2w) { - sljit_ub *inst; + sljit_ub *buf; - inst = emit_x86_instruction(compiler, 2 | (single ? EX86_PREF_F3 : EX86_PREF_F2) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = opcode; + buf = emit_x86_instruction(compiler, 2 | EX86_PREF_F2 | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + FAIL_IF(!buf); + *buf++ = 0x0f; + *buf = opcode; return SLJIT_SUCCESS; } -static sljit_si emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode, - sljit_si pref66, sljit_si xmm1, sljit_si xmm2, sljit_sw xmm2w) +static int emit_sse2_logic(struct sljit_compiler *compiler, sljit_ub opcode, + int xmm1, int xmm2, sljit_w xmm2w) { - sljit_ub *inst; + sljit_ub *buf; - inst = emit_x86_instruction(compiler, 2 | (pref66 ? EX86_PREF_66 : 0) | EX86_SSE2, xmm1, 0, xmm2, xmm2w); - FAIL_IF(!inst); - *inst++ = GROUP_0F; - *inst = opcode; + buf = emit_x86_instruction(compiler, 2 | EX86_PREF_66 | EX86_SSE2, xmm1, 0, xmm2, xmm2w); + FAIL_IF(!buf); + *buf++ = 0x0f; + *buf = opcode; return SLJIT_SUCCESS; } -static SLJIT_INLINE sljit_si emit_sse2_load(struct sljit_compiler *compiler, - sljit_si single, sljit_si dst, sljit_si src, sljit_sw srcw) +static SLJIT_INLINE int emit_sse2_load(struct sljit_compiler *compiler, + int dst, int src, sljit_w srcw) { - return emit_sse2(compiler, MOVSD_x_xm, single, dst, src, srcw); + return emit_sse2(compiler, 0x10, dst, src, srcw); } -static SLJIT_INLINE sljit_si emit_sse2_store(struct sljit_compiler *compiler, - sljit_si single, sljit_si dst, sljit_sw dstw, sljit_si src) +static SLJIT_INLINE int emit_sse2_store(struct sljit_compiler *compiler, + int dst, sljit_w dstw, int src) { - return emit_sse2(compiler, MOVSD_xm_x, single, src, dst, dstw); + return emit_sse2(compiler, 0x11, src, dst, dstw); } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { - sljit_si dst_r; + int dst_r; CHECK_ERROR(); check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw); @@ -2338,57 +2127,57 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile compiler->mode32 = 1; #endif - if (GET_OPCODE(op) == SLJIT_CMPD) { + if (GET_OPCODE(op) == SLJIT_FCMP) { compiler->flags_saved = 0; - if (dst <= SLJIT_FLOAT_REG6) + if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) dst_r = dst; else { dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, dst, dstw)); + FAIL_IF(emit_sse2_load(compiler, dst_r, dst, dstw)); } - return emit_sse2_logic(compiler, UCOMISD_x_xm, !(op & SLJIT_SINGLE_OP), dst_r, src, srcw); + return emit_sse2_logic(compiler, 0x2e, dst_r, src, srcw); } - if (op == SLJIT_MOVD) { - if (dst <= SLJIT_FLOAT_REG6) - return emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst, src, srcw); - if (src <= SLJIT_FLOAT_REG6) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, src); - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src, srcw)); - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + if (op == SLJIT_FMOV) { + if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) + return emit_sse2_load(compiler, dst, src, srcw); + if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) + return emit_sse2_store(compiler, dst, dstw, src); + FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src, srcw)); + return emit_sse2_store(compiler, dst, dstw, TMP_FREG); } - if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG6) { + if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) { dst_r = dst; if (dst != src) - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); + FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw)); } else { dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src, srcw)); + FAIL_IF(emit_sse2_load(compiler, dst_r, src, srcw)); } - switch (GET_OPCODE(op)) { - case SLJIT_NEGD: - FAIL_IF(emit_sse2_logic(compiler, XORPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer : sse2_buffer + 8))); + switch (op) { + case SLJIT_FNEG: + FAIL_IF(emit_sse2_logic(compiler, 0x57, dst_r, SLJIT_MEM0(), (sljit_w)sse2_buffer)); break; - case SLJIT_ABSD: - FAIL_IF(emit_sse2_logic(compiler, ANDPD_x_xm, 1, dst_r, SLJIT_MEM0(), (sljit_sw)(op & SLJIT_SINGLE_OP ? sse2_buffer + 4 : sse2_buffer + 12))); + case SLJIT_FABS: + FAIL_IF(emit_sse2_logic(compiler, 0x54, dst_r, SLJIT_MEM0(), (sljit_w)(sse2_buffer + 4))); break; } if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { - sljit_si dst_r; + int dst_r; CHECK_ERROR(); check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w); @@ -2397,55 +2186,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile compiler->mode32 = 1; #endif - if (dst <= SLJIT_FLOAT_REG6) { + if (dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) { dst_r = dst; if (dst == src1) ; /* Do nothing here. */ - else if (dst == src2 && (op == SLJIT_ADDD || op == SLJIT_MULD)) { + else if (dst == src2 && (op == SLJIT_FADD || op == SLJIT_FMUL)) { /* Swap arguments. */ src2 = src1; src2w = src1w; } else if (dst != src2) - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, dst_r, src1, src1w)); + FAIL_IF(emit_sse2_load(compiler, dst_r, src1, src1w)); else { dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w)); } } else { dst_r = TMP_FREG; - FAIL_IF(emit_sse2_load(compiler, op & SLJIT_SINGLE_OP, TMP_FREG, src1, src1w)); + FAIL_IF(emit_sse2_load(compiler, TMP_FREG, src1, src1w)); } - switch (GET_OPCODE(op)) { - case SLJIT_ADDD: - FAIL_IF(emit_sse2(compiler, ADDSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + switch (op) { + case SLJIT_FADD: + FAIL_IF(emit_sse2(compiler, 0x58, dst_r, src2, src2w)); break; - case SLJIT_SUBD: - FAIL_IF(emit_sse2(compiler, SUBSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + case SLJIT_FSUB: + FAIL_IF(emit_sse2(compiler, 0x5c, dst_r, src2, src2w)); break; - case SLJIT_MULD: - FAIL_IF(emit_sse2(compiler, MULSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + case SLJIT_FMUL: + FAIL_IF(emit_sse2(compiler, 0x59, dst_r, src2, src2w)); break; - case SLJIT_DIVD: - FAIL_IF(emit_sse2(compiler, DIVSD_x_xm, op & SLJIT_SINGLE_OP, dst_r, src2, src2w)); + case SLJIT_FDIV: + FAIL_IF(emit_sse2(compiler, 0x5e, dst_r, src2, src2w)); break; } if (dst_r == TMP_FREG) - return emit_sse2_store(compiler, op & SLJIT_SINGLE_OP, dst, dstw, TMP_FREG); + return emit_sse2_store(compiler, dst, dstw, TMP_FREG); return SLJIT_SUCCESS; } #else -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src, sljit_w srcw) { CHECK_ERROR(); /* Should cause an assertion fail. */ @@ -2454,10 +2243,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop1(struct sljit_compiler *compile return SLJIT_ERR_UNSUPPORTED; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src1, sljit_sw src1w, - sljit_si src2, sljit_sw src2w) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op, + int dst, sljit_w dstw, + int src1, sljit_w src1w, + int src2, sljit_w src2w) { CHECK_ERROR(); /* Should cause an assertion fail. */ @@ -2474,7 +2263,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fop2(struct sljit_compiler *compile SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler) { - sljit_ub *inst; + sljit_ub *buf; struct sljit_label *label; CHECK_ERROR_PTR(); @@ -2492,18 +2281,18 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi PTR_FAIL_IF(!label); set_label(label, compiler); - inst = (sljit_ub*)ensure_buf(compiler, 2); - PTR_FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF(!buf); - *inst++ = 0; - *inst++ = 0; + *buf++ = 0; + *buf++ = 0; return label; } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type) { - sljit_ub *inst; + sljit_ub *buf; struct sljit_jump *jump; CHECK_ERROR_PTR(); @@ -2530,17 +2319,17 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile compiler->size += (type >= SLJIT_JUMP) ? (10 + 3) : (2 + 10 + 3); #endif - inst = (sljit_ub*)ensure_buf(compiler, 2); - PTR_FAIL_IF_NULL(inst); + buf = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF_NULL(buf); - *inst++ = 0; - *inst++ = type + 4; + *buf++ = 0; + *buf++ = type + 4; return jump; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compiler, sljit_si type, sljit_si src, sljit_sw srcw) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w srcw) { - sljit_ub *inst; + sljit_ub *code; struct sljit_jump *jump; CHECK_ERROR(); @@ -2558,16 +2347,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil 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_SCRATCH_REG3) { + if (src == SLJIT_TEMPORARY_REG3) { EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); src = TMP_REGISTER; } if (src == SLJIT_MEM1(SLJIT_LOCALS_REG) && type >= SLJIT_CALL3) - srcw += sizeof(sljit_sw); + srcw += sizeof(sljit_w); +#else + if (src == SLJIT_MEM1(SLJIT_LOCALS_REG)) + srcw += sizeof(sljit_w) * (type - SLJIT_CALL0); #endif #endif #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64) - if (src == SLJIT_SCRATCH_REG3) { + if (src == SLJIT_TEMPORARY_REG3) { EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0); src = TMP_REGISTER; } @@ -2588,42 +2380,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil compiler->size += 10 + 3; #endif - inst = (sljit_ub*)ensure_buf(compiler, 2); - FAIL_IF_NULL(inst); + code = (sljit_ub*)ensure_buf(compiler, 2); + FAIL_IF_NULL(code); - *inst++ = 0; - *inst++ = type + 4; + *code++ = 0; + *code++ = type + 4; } else { #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) /* REX_W is not necessary (src is not immediate). */ compiler->mode32 = 1; #endif - inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); - FAIL_IF(!inst); - *inst++ = GROUP_FF; - *inst |= (type >= SLJIT_FAST_CALL) ? CALL_rm : JMP_rm; + code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw); + FAIL_IF(!code); + *code++ = 0xff; + *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3); } return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_si op, - sljit_si dst, sljit_sw dstw, - sljit_si src, sljit_sw srcw, - sljit_si type) +SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(struct sljit_compiler *compiler, int op, int dst, sljit_w dstw, int type) { - sljit_ub *inst; + sljit_ub *buf; sljit_ub cond_set = 0; + int dst_save = dst; + sljit_w dstw_save = dstw; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si reg; -#else - /* CHECK_EXTRA_REGS migh overwrite these values. */ - sljit_si dst_save = dst; - sljit_sw dstw_save = dstw; + int reg; #endif CHECK_ERROR(); - check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type); + check_sljit_emit_cond_value(compiler, op, dst, dstw, type); if (dst == SLJIT_UNUSED) return SLJIT_SUCCESS; @@ -2633,117 +2420,177 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_flags(struct sljit_compiler *com if (SLJIT_UNLIKELY(compiler->flags_saved)) FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS)); - /* setcc = jcc + 0x10. */ - cond_set = get_jump_code(type) + 0x10; + switch (type) { + case SLJIT_C_EQUAL: + case SLJIT_C_FLOAT_EQUAL: + cond_set = 0x94; + break; + + case SLJIT_C_NOT_EQUAL: + case SLJIT_C_FLOAT_NOT_EQUAL: + cond_set = 0x95; + break; + + case SLJIT_C_LESS: + case SLJIT_C_FLOAT_LESS: + cond_set = 0x92; + break; + + case SLJIT_C_GREATER_EQUAL: + case SLJIT_C_FLOAT_GREATER_EQUAL: + cond_set = 0x93; + break; + + case SLJIT_C_GREATER: + case SLJIT_C_FLOAT_GREATER: + cond_set = 0x97; + break; + + case SLJIT_C_LESS_EQUAL: + case SLJIT_C_FLOAT_LESS_EQUAL: + cond_set = 0x96; + break; + + case SLJIT_C_SIG_LESS: + cond_set = 0x9c; + break; + + case SLJIT_C_SIG_GREATER_EQUAL: + cond_set = 0x9d; + break; + + case SLJIT_C_SIG_GREATER: + cond_set = 0x9f; + break; + + case SLJIT_C_SIG_LESS_EQUAL: + cond_set = 0x9e; + break; + + case SLJIT_C_OVERFLOW: + case SLJIT_C_MUL_OVERFLOW: + cond_set = 0x90; + break; + + case SLJIT_C_NOT_OVERFLOW: + case SLJIT_C_MUL_NOT_OVERFLOW: + cond_set = 0x91; + break; + + case SLJIT_C_FLOAT_NAN: + cond_set = 0x9a; + break; + + case SLJIT_C_FLOAT_NOT_NAN: + cond_set = 0x9b; + break; + } #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - reg = (op == SLJIT_MOV && dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + reg = (op == SLJIT_MOV && dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; - inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4); - FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4); + FAIL_IF(!buf); INC_SIZE(4 + 4); /* Set low register to conditional flag. */ - *inst++ = (reg_map[reg] <= 7) ? REX : REX_B; - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | reg_lmap[reg]; - *inst++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst = MOD_REG | (reg_lmap[reg] << 3) | reg_lmap[reg]; + *buf++ = (reg_map[reg] <= 7) ? 0x40 : REX_B; + *buf++ = 0x0f; + *buf++ = cond_set; + *buf++ = 0xC0 | reg_lmap[reg]; + *buf++ = REX_W | (reg_map[reg] <= 7 ? 0 : (REX_B | REX_R)); + *buf++ = 0x0f; + *buf++ = 0xb6; + *buf = 0xC0 | (reg_lmap[reg] << 3) | reg_lmap[reg]; - if (reg != TMP_REGISTER) - return SLJIT_SUCCESS; - - if (GET_OPCODE(op) < SLJIT_ADD) { - compiler->mode32 = GET_OPCODE(op) != SLJIT_MOV; - return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0); - } + if (reg == TMP_REGISTER) { + if (op == SLJIT_MOV) { + compiler->mode32 = 0; + EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0); + } + else { #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) - compiler->skip_checks = 1; + compiler->skip_checks = 1; #endif - return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0); -#else /* SLJIT_CONFIG_X86_64 */ - if (GET_OPCODE(op) < SLJIT_ADD && dst <= TMP_REGISTER) { - if (reg_map[dst] <= 4) { - /* Low byte is accessible. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); - FAIL_IF(!inst); + return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REGISTER, 0); + } + } +#else + if (op == SLJIT_MOV) { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) { + buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); + FAIL_IF(!buf); INC_SIZE(3 + 3); /* Set low byte to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | reg_map[dst]; + *buf++ = 0x0f; + *buf++ = cond_set; + *buf++ = 0xC0 | reg_map[dst]; - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst = MOD_REG | (reg_map[dst] << 3) | reg_map[dst]; - return SLJIT_SUCCESS; + *buf++ = 0x0f; + *buf++ = 0xb6; + *buf = 0xC0 | (reg_map[dst] << 3) | reg_map[dst]; } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0); - /* Low byte is not accessible. */ - if (cpu_has_cmov == -1) - get_cpu_features(); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3); + FAIL_IF(!buf); + INC_SIZE(3 + 3); + /* Set al to conditional flag. */ + *buf++ = 0x0f; + *buf++ = cond_set; + *buf++ = 0xC0; - if (cpu_has_cmov) { - EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_IMM, 1); - /* a xor reg, reg operation would overwrite the flags. */ - EMIT_MOV(compiler, dst, 0, SLJIT_IMM, 0); + *buf++ = 0x0f; + *buf++ = 0xb6; + if (dst >= SLJIT_SAVED_REG1 && dst <= SLJIT_NO_REGISTERS) + *buf = 0xC0 | (reg_map[dst] << 3); + else { + *buf = 0xC0; + EMIT_MOV(compiler, dst, dstw, SLJIT_TEMPORARY_REG1, 0); + } - inst = (sljit_ub*)ensure_buf(compiler, 1 + 3); - FAIL_IF(!inst); + EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0); + } + } + else { + if (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_TEMPORARY_REG3) { + EMIT_MOV(compiler, TMP_REGISTER, 0, dst, 0); + buf = (sljit_ub*)ensure_buf(compiler, 1 + 3); + FAIL_IF(!buf); INC_SIZE(3); - *inst++ = GROUP_0F; - /* cmovcc = setcc - 0x50. */ - *inst++ = cond_set - 0x50; - *inst++ = MOD_REG | (reg_map[dst] << 3) | reg_map[TMP_REGISTER]; - return SLJIT_SUCCESS; + *buf++ = 0x0f; + *buf++ = cond_set; + *buf++ = 0xC0 | reg_map[dst]; } + else { + EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0); - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); - FAIL_IF(!inst); - INC_SIZE(1 + 3 + 3 + 1); - *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; - /* Set al to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 0 /* eax */; + buf = (sljit_ub*)ensure_buf(compiler, 1 + 3 + 3 + 1); + FAIL_IF(!buf); + INC_SIZE(3 + 3 + 1); + /* Set al to conditional flag. */ + *buf++ = 0x0f; + *buf++ = cond_set; + *buf++ = 0xC0; - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst++ = MOD_REG | (reg_map[dst] << 3) | 0 /* eax */; - *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; - return SLJIT_SUCCESS; - } - - /* Set TMP_REGISTER to the bit. */ - inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1); - FAIL_IF(!inst); - INC_SIZE(1 + 3 + 3 + 1); - *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; - /* Set al to conditional flag. */ - *inst++ = GROUP_0F; - *inst++ = cond_set; - *inst++ = MOD_REG | 0 /* eax */; - - *inst++ = GROUP_0F; - *inst++ = MOVZX_r_rm8; - *inst++ = MOD_REG | (0 << 3) /* eax */ | 0 /* eax */; - - *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER]; - - if (GET_OPCODE(op) < SLJIT_ADD) - return emit_mov(compiler, dst, dstw, TMP_REGISTER, 0); + *buf++ = 0x0f; + *buf++ = 0xb6; + *buf++ = 0xC0; + *buf++ = 0x90 + reg_map[TMP_REGISTER]; + } #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG) - compiler->skip_checks = 1; + compiler->skip_checks = 1; #endif - return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REGISTER, 0); -#endif /* SLJIT_CONFIG_X86_64 */ + return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REGISTER, 0); + } +#endif + + return SLJIT_SUCCESS; } -SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw offset) +SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset) { CHECK_ERROR(); check_sljit_get_local_base(compiler, dst, dstw, offset); @@ -2774,12 +2621,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co return emit_mov(compiler, dst, dstw, SLJIT_LOCALS_REG, 0); } -SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value) +SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value) { - sljit_ub *inst; + sljit_ub *buf; struct sljit_const *const_; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) - sljit_si reg; + int reg; #endif CHECK_ERROR_PTR(); @@ -2794,7 +2641,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) compiler->mode32 = 0; - reg = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER; + reg = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER; if (emit_load_imm64(compiler, reg, init_value)) return NULL; @@ -2806,11 +2653,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi return NULL; #endif - inst = (sljit_ub*)ensure_buf(compiler, 2); - PTR_FAIL_IF(!inst); + buf = (sljit_ub*)ensure_buf(compiler, 2); + PTR_FAIL_IF(!buf); - *inst++ = 0; - *inst++ = 1; + *buf++ = 0; + *buf++ = 1; #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) if (reg == TMP_REGISTER && dst != SLJIT_UNUSED) @@ -2824,13 +2671,13 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr) { #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32) - *(sljit_sw*)addr = new_addr - (addr + 4); + *(sljit_w*)addr = new_addr - (addr + 4); #else *(sljit_uw*)addr = new_addr; #endif } -SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant) +SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_w new_constant) { - *(sljit_sw*)addr = new_constant; + *(sljit_w*)addr = new_constant; } diff --git a/harbour/src/3rd/pcre/ucp.h b/harbour/src/3rd/pcre/ucp.h index 21039106e5..59c3bec3d3 100644 --- a/harbour/src/3rd/pcre/ucp.h +++ b/harbour/src/3rd/pcre/ucp.h @@ -7,11 +7,7 @@ /* This file contains definitions of the property values that are returned by the UCD access macros. New values that are added for new releases of Unicode -should always be at the end of each enum, for backwards compatibility. - -IMPORTANT: Note also that the specific numeric values of the enums have to be -the same as the values that are generated by the maint/MultiStage2.py script, -where the equivalent property descriptive names are listed in vectors. */ +should always be at the end of each enum, for backwards compatibility. */ /* These are the general character categories. */ @@ -25,7 +21,7 @@ enum { ucp_Z /* Separator */ }; -/* These are the particular character categories. */ +/* These are the particular character types. */ enum { ucp_Cc, /* Control */ @@ -60,26 +56,6 @@ enum { ucp_Zs /* Space separator */ }; -/* These are grapheme break properties. Note that the code for processing them -assumes that the values are less than 16. If more values are added that take -the number to 16 or more, the code will have to be rewritten. */ - -enum { - ucp_gbCR, /* 0 */ - ucp_gbLF, /* 1 */ - ucp_gbControl, /* 2 */ - ucp_gbExtend, /* 3 */ - ucp_gbPrepend, /* 4 */ - ucp_gbSpacingMark, /* 5 */ - ucp_gbL, /* 6 Hangul syllable type L */ - ucp_gbV, /* 7 Hangul syllable type V */ - ucp_gbT, /* 8 Hangul syllable type T */ - ucp_gbLV, /* 9 Hangul syllable type LV */ - ucp_gbLVT, /* 10 Hangul syllable type LVT */ - ucp_gbRegionalIndicator, /* 11 */ - ucp_gbOther /* 12 */ -}; - /* These are the script identifications. */ enum { diff --git a/harbour/utils/hbmk2/hbmk2.es_PE.po b/harbour/utils/hbmk2/hbmk2.es_PE.po index 34479c8b9d..9b360cb095 100644 --- a/harbour/utils/hbmk2/hbmk2.es_PE.po +++ b/harbour/utils/hbmk2/hbmk2.es_PE.po @@ -943,8 +943,8 @@ msgstr "no agregue lista adicional de librerías del sistema a lista de librerí #: hbmk2.prg:7960 hbmk2.prg:11650 hbmk2.prg:13120 #, c-format -msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][|||]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" -msgstr "filtros para plataformas son aceptados en cada linea de archivo .hbc y con varias opciones.\\nFormato de filtro: {[!][|||]}. Filtros pueden ser combinados usando los operadores '&', '|' y agrupados en parénteses. Ej.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" +msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][|||]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" +msgstr "filtros para plataformas son aceptados en cada linea de archivo .hbc y con varias opciones.\\nFormato de filtro: {[!][|||]}. Filtros pueden ser combinados usando los operadores '&', '|' y agrupados en parénteses. Ej.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" #: hbmk2.prg:7555 hbmk2.prg:7672 hbmk2.prg:7755 hbmk2.prg:11163 hbmk2.prg:11284 hbmk2.prg:11408 hbmk2.prg:12183 hbmk2.prg:12311 hbmk2.prg:12459 #, c-format diff --git a/harbour/utils/hbmk2/hbmk2.hu_HU.po b/harbour/utils/hbmk2/hbmk2.hu_HU.po index b5babf5b81..d9519263dc 100644 --- a/harbour/utils/hbmk2/hbmk2.hu_HU.po +++ b/harbour/utils/hbmk2/hbmk2.hu_HU.po @@ -99,8 +99,8 @@ msgstr "Figyelem: Hibás -gt érték figyelmen kívül hagyva: %1$s" #: hbmk2.prg:7959 hbmk2.prg:11650 hbmk2.prg:13120 #, c-format -msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][|||]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" -msgstr "A szűrők az egyes .hbc sorokban használhatók és számos opció esetén támogatottak.\\nSzűrő formátum: {[!][|||]}. Szűrők kombinálhatók '&', '|' operátorokkal és zárójelekkel csoportosíthatók. Pl.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" +msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][|||]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" +msgstr "A szűrők az egyes .hbc sorokban használhatók és számos opció esetén támogatottak.\\nSzűrő formátum: {[!][|||]}. Szűrők kombinálhatók '&', '|' operátorokkal és zárójelekkel csoportosíthatók. Pl.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" #: hbmk2.prg:4128 hbmk2.prg:5633 hbmk2.prg:6212 #, c-format diff --git a/harbour/utils/hbmk2/hbmk2.prg b/harbour/utils/hbmk2/hbmk2.prg index 7a3b4f5857..695cb00ab4 100644 --- a/harbour/utils/hbmk2/hbmk2.prg +++ b/harbour/utils/hbmk2/hbmk2.prg @@ -1772,7 +1772,7 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel ) { {|| FindInPath( "dmc.exe" ) }, "dmc" }} #endif aCOMPSUP := { ; - "mingw", "msvc", "bcc", "watcom", "icc", "pocc", "xcc", ; + "mingw", "msvc", "clang", "bcc", "watcom", "icc", "pocc", "xcc", ; "mingw64", "msvc64", "msvcia64", "bcc64", "iccia64", "pocc64" } l_aLIBHBGT := { "gtwin", "gtwvt", "gtgui" } hbmk[ _HBMK_cGTDEFAULT ] := "gtwin" @@ -3282,6 +3282,7 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel ) CASE hb_FNameExt( cParamL ) == ".res" IF HBMK_ISCOMP( "mingw|mingw64|mingwarm" ) .OR. ; + ( hbmk[ _HBMK_cPLAT ] == "win" .AND. HBMK_ISCOMP( "clang" ) ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "os2" .AND. HBMK_ISCOMP( "gcc|gccomf" ) ) /* For MinGW/EMX GCC family add .res files as source input, as they will need to be converted to coff format with windres (just @@ -3999,6 +4000,7 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel ) CASE ( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "gcc" ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "mingw" ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "mingw64" ) .OR. ; + ( hbmk[ _HBMK_cPLAT ] == "win" .AND. hbmk[ _HBMK_cCOMP ] == "clang" ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "wce" .AND. hbmk[ _HBMK_cCOMP ] == "mingw" ) .OR. ; ( hbmk[ _HBMK_cPLAT ] == "wce" .AND. hbmk[ _HBMK_cCOMP ] == "mingwarm" ) @@ -4011,8 +4013,13 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel ) cLibPrefix := "-l" cLibExt := "" cObjExt := ".o" - cBin_CompCPP := hbmk[ _HBMK_cCCPREFIX ] + "g++" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ] - cBin_CompC := iif( hbmk[ _HBMK_lCPP ] != NIL .AND. hbmk[ _HBMK_lCPP ], cBin_CompCPP, hbmk[ _HBMK_cCCPREFIX ] + "gcc" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ] ) + IF hbmk[ _HBMK_cCOMP ] == "clang" + cBin_CompCPP := hbmk[ _HBMK_cCCPREFIX ] + "clang++" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ] + cBin_CompC := iif( hbmk[ _HBMK_lCPP ] != NIL .AND. hbmk[ _HBMK_lCPP ], cBin_CompCPP, hbmk[ _HBMK_cCCPREFIX ] + "clang" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ] ) + ELSE + cBin_CompCPP := hbmk[ _HBMK_cCCPREFIX ] + "g++" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ] + cBin_CompC := iif( hbmk[ _HBMK_lCPP ] != NIL .AND. hbmk[ _HBMK_lCPP ], cBin_CompCPP, hbmk[ _HBMK_cCCPREFIX ] + "gcc" + hbmk[ _HBMK_cCCPOSTFIX ] + hbmk[ _HBMK_cCCEXT ] ) + ENDIF cOpt_CompC := "-c" IF hbmk[ _HBMK_lOPTIM ] cOpt_CompC += " -O3" @@ -4148,7 +4155,7 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel ) ENDIF ENDIF - IF HBMK_ISCOMP( "mingw|mingw64|mingwarm" ) + IF HBMK_ISCOMP( "mingw|mingw64|mingwarm|clang" ) cBin_Res := hbmk[ _HBMK_cCCPREFIX ] + "windres" + hbmk[ _HBMK_cCCEXT ] cResExt := ".reso" cOpt_Res := "{FR} {IR} -O coff -o {OS}" @@ -5742,7 +5749,7 @@ FUNCTION hbmk( aArgs, nArgTarget, /* @ */ lPause, nLevel ) "LNK4217: locally defined symbol ... imported in function ..." if using 'dllimport'. [vszakats] */ tmp := "" - CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm" ) + CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang" ) tmp := "__attribute__ (( dllimport ))" CASE HBMK_ISCOMP( "bcc|bcc64|watcom" ) tmp := "__declspec( dllimport )" @@ -7761,7 +7768,7 @@ STATIC FUNCTION FindNewerHeaders( hbmk, cFileName, tTimeParent, lCMode, cBin_Com cExt := Lower( hb_FNameExt( cFileName ) ) /* Filter out non-source format inputs for MinGW / windres */ - IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm" ) .AND. HBMK_ISPLAT( "win|wce" ) .AND. cExt == ".res" + IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang" ) .AND. HBMK_ISPLAT( "win|wce" ) .AND. cExt == ".res" RETURN .F. ENDIF @@ -8814,7 +8821,7 @@ STATIC FUNCTION LibExists( hbmk, cDir, cLib, cLibPrefix, cLibExt ) cDir := hb_DirSepAdd( PathSepToSelf( cDir ) ) DO CASE - CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm" ) .AND. HBMK_ISPLAT( "win|wce|cygwin" ) + CASE HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|clang" ) .AND. HBMK_ISPLAT( "win|wce|cygwin" ) /* NOTE: ld/gcc option -dll-search-prefix isn't taken into account here, So, 'xxx.dll' format libs won't be found here in any case. */ DO CASE @@ -9619,7 +9626,7 @@ STATIC FUNCTION PathSepToTarget( hbmk, cFileName, nStart ) hb_default( @nStart, 1 ) - IF HBMK_ISPLAT( "win|wce|dos|os2" ) .AND. ! HBMK_ISCOMP( "mingw|mingw64|mingwarm" ) + IF HBMK_ISPLAT( "win|wce|dos|os2" ) .AND. ! HBMK_ISCOMP( "mingw|mingw64|mingwarm|clang" ) RETURN Left( cFileName, nStart - 1 ) + StrTran( SubStr( cFileName, nStart ), "/", "\" ) ENDIF @@ -9950,8 +9957,10 @@ STATIC FUNCTION HBC_ProcessOne( hbmk, cFileName, nNestingLevel ) AAddNew( hbmk[ _HBMK_aDEF ], tmp ) NEXT CASE hb_FNameExt( cItemL ) == ".res" - IF HBMK_ISCOMP( "mingw|mingw64|mingwarm" ) - /* For MinGW family add .res files as source input, as they + IF HBMK_ISCOMP( "mingw|mingw64|mingwarm" ) .OR. ; + ( hbmk[ _HBMK_cPLAT ] == "win" .AND. HBMK_ISCOMP( "clang" ) ) .OR. ; + ( hbmk[ _HBMK_cPLAT ] == "os2" .AND. HBMK_ISCOMP( "gcc|gccomf" ) ) + /* For MinGW/EMX GCC family add .res files as source input, as they will need to be converted to coff format with windres (just like plain .rc files) before feeding them to gcc. */ FOR EACH tmp IN FN_Expand( cItem, .F. ) @@ -11002,7 +11011,7 @@ STATIC FUNCTION getFirstFunc( hbmk, cFile ) LOCAL cFuncList, cExecNM, cFuncName, cExt, cLine, n, c cFuncName := "" - IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|gccomf" ) + IF HBMK_ISCOMP( "gcc|mingw|mingw64|mingwarm|gccomf|clang" ) hb_FNameSplit( cFile,,, @cExt ) IF cExt == ".c" FOR EACH cLine IN hb_ATokens( StrTran( hb_MemoRead( cFile ), Chr( 13 ), Chr( 10 ) ), Chr( 10 ) ) @@ -14551,9 +14560,9 @@ STATIC PROCEDURE ShowHelp( hbmk, lLong ) LOCAL aText_Supp := {; "", ; I_( "Supported values for each supported value:" ), ; - " - linux : gcc, clang, icc, watcom, sunpro, open64, pcc", ; - " - darwin : gcc, clang, icc, pcc", ; - " - win : mingw, msvc, bcc, bcc64, watcom, icc, pocc, xcc,", ; + " - linux : gcc, clang, icc, watcom, sunpro, open64", ; + " - darwin : gcc, clang, icc", ; + " - win : mingw, msvc, clang, bcc, bcc64, watcom, icc, pocc, xcc,", ; " mingw64, msvc64, msvcia64, iccia64, pocc64", ; " - wce : mingwarm, mingw, msvcarm, poccarm", ; " - os2 : gcc, gccomf, watcom", ; @@ -14568,7 +14577,7 @@ STATIC PROCEDURE ShowHelp( hbmk, lLong ) " - cygwin : gcc", ; " - minix : gcc, clang, ack", ; " - aix : gcc", ; - " - sunos : gcc, sunpro, pcc" } + " - sunos : gcc, sunpro" } LOCAL aOpt_Basic := {; { "-o" , I_( "output file name" ) }, ; @@ -14732,7 +14741,7 @@ STATIC PROCEDURE ShowHelp( hbmk, lLong ) hb_StrFormat( I_( "%1$s option file in %2$s directory is always processed if it exists. On *nix platforms ~/.harbour, /etc/harbour, /etc/harbour, /etc are checked (in that order) before the %2$s directory." ), _HBMK_AUTOHBC_NAME, _SELF_NAME_ ), ; hb_StrFormat( I_( "%1$s make script in current directory is always processed if it exists." ), _HBMK_AUTOHBM_NAME ), ; I_( ".hbc options (they should come in separate lines): libs=[], hbcs=[<.hbc file[s]>], gt=[gtname], syslibs=[], frameworks=[], prgflags=[Harbour flags], cflags=[C compiler flags], resflags=[resource compiler flags], ldflags=[linker flags], pflags=[flags for plugins], libpaths=[paths], sources=[source files], headers=[Harbour header files], psources=[source files for plugins], incpaths=[paths], requests=[func], instfiles=[files], instpaths=[paths], autohbcs=[<.ch>:<.hbc>], plugins=[plugins], gui|mt|pic|shared|nulrdd|nodefgt|debug|opt|map|strip|hbcppmm|winuni|implib|run|inc=[yes|no], cpp=[yes|no|def], warn=[max|yes|low|no|def], compr=[yes|no|def|min|max], head=[off|full|native|dep], skip=, stop=, echo=\nLines starting with '#' char are ignored" ), ; - I_( "Platform filters are accepted in each .hbc line and with several options.\nFilter format: {[!][|||]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" ), ; + I_( "Platform filters are accepted in each .hbc line and with several options.\nFilter format: {[!][|||]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" ), ; I_( "Certain .hbc lines (libs=, hbcs=, prgflags=, cflags=, ldflags=, libpaths=, instfiles=, instpaths=, echo=) and corresponding command line parameters will accept macros: ${hb_root}, ${hb_dir}, ${hb_dirname}, ${hb_name}, ${hb_self}, ${hb_curdir}, ${hb_tempdir}, ${hb_targetname}, ${hb_targettype}, ${hb_plat}, ${hb_comp}, ${hb_comp_ver}, ${hb_build}, ${hb_cpu}, ${hb_work}, ${hb_workdynsub}, ${hb_dynprefix}, ${hb_dynsuffix}, ${hb_dynext}, ${hb_ver}, ${hb_verstr}, ${hb_major}, ${hb_minor}, ${hb_release}, ${hb_status}, ${hb_revision}, ${hb_host_plat}, ${hb_host_plat_unix}, ${hb_bin}, ${hb_lib}, ${hb_lib3rd}, ${hb_dyn}, ${hb_inc}, ${hb_first}, ${hb_outputdir}, ${hb_outputname}, ${hb_level}, ${}. libpaths= also accepts %{hb_name} which translates to the name of the .hbc file under search." ), ; I_( 'Options accepting macros also support command substitution. Enclose command inside ``, and, if the command contains space, also enclose in double quotes. F.e. "-cflag=`wx-config --cflags`", or ldflags={unix&gcc}"`wx-config --libs`".' ), ; I_( "Libraries and object files built with/for CA-Cl*pper won't work with any supported platform/compiler." ) , ; diff --git a/harbour/utils/hbmk2/hbmk2.pt_BR.po b/harbour/utils/hbmk2/hbmk2.pt_BR.po index 917c740219..c88046412e 100644 --- a/harbour/utils/hbmk2/hbmk2.pt_BR.po +++ b/harbour/utils/hbmk2/hbmk2.pt_BR.po @@ -943,8 +943,8 @@ msgstr "não adicione bibliotecas extras do sistema à lista padrão de bibliote #: hbmk2.prg:7960 hbmk2.prg:11650 hbmk2.prg:13120 #, c-format -msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][|||]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" -msgstr "Os filtros para plataformas são aceitos para cada uma das linhas de um arquivo .hbc e possuem diversas opções.\\nFormato de um filtro: {[!][|||]}. Os filtros podem ser combinados usando os operadores '&', '|' e agrupados por parênteses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" +msgid "Platform filters are accepted in each .hbc line and with several options.\\nFilter format: {[!][|||]}. Filters can be combined using '&', '|' operators and grouped by parentheses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" +msgstr "Os filtros para plataformas são aceitos para cada uma das linhas de um arquivo .hbc e possuem diversas opções.\\nFormato de um filtro: {[!][|||]}. Os filtros podem ser combinados usando os operadores '&', '|' e agrupados por parênteses. Ex.: {win}, {gcc}, {linux|darwin}, {win&!pocc}, {(win|linux)&!watcom}, {unix&mt&gui}, -cflag={win}-DMYDEF, -stop{dos}, -stop{!allwin}, {allwin|allmsvc|allgcc|allmingw|allicc|allbcc|allpocc|unix}, {x86|x86_64|ia64|arm|mips|sh}, {debug|nodebug|gui|std|mt|st|shared|static|winuni|winansi|xhb}" #: hbmk2.prg:7555 hbmk2.prg:7672 hbmk2.prg:7755 hbmk2.prg:11163 hbmk2.prg:11284 hbmk2.prg:11408 hbmk2.prg:12183 hbmk2.prg:12311 hbmk2.prg:12459 #, c-format