[Pcre-svn] [860] code/trunk: rename PCRE_SCHAR16 to PCRE_UCH…

Startseite
Nachricht löschen
Autor: Subversion repository
Datum:  
To: pcre-svn
Betreff: [Pcre-svn] [860] code/trunk: rename PCRE_SCHAR16 to PCRE_UCHAR16 and JIT compiler update
Revision: 860
          http://vcs.pcre.org/viewvc?view=rev&revision=860
Author:   zherczeg
Date:     2012-01-09 20:12:58 +0000 (Mon, 09 Jan 2012)


Log Message:
-----------
rename PCRE_SCHAR16 to PCRE_UCHAR16 and JIT compiler update

Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/pcre.h.in
    code/trunk/pcre16_utf16_utils.c
    code/trunk/pcre_get.c
    code/trunk/pcre_internal.h
    code/trunk/pcre_jit_compile.c
    code/trunk/pcre_jit_test.c
    code/trunk/pcretest.c
    code/trunk/sljit/sljitLir.c
    code/trunk/sljit/sljitLir.h
    code/trunk/sljit/sljitNativeARM_Thumb2.c
    code/trunk/sljit/sljitNativeARM_v5.c
    code/trunk/sljit/sljitNativeMIPS_common.c
    code/trunk/sljit/sljitNativePPC_32.c
    code/trunk/sljit/sljitNativePPC_64.c
    code/trunk/sljit/sljitNativePPC_common.c
    code/trunk/sljit/sljitNativeX86_32.c
    code/trunk/sljit/sljitNativeX86_64.c
    code/trunk/sljit/sljitNativeX86_common.c


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/ChangeLog    2012-01-09 20:12:58 UTC (rev 860)
@@ -30,7 +30,10 @@
     command "pattern=`printf 'xxx\r\njkl'`" was run. The pattern is now taken
     from a file.


+8.  Ovector size of 2 is also supported by JIT based pcre_exec (the ovector size
+    rounding is not applied in this particular case).


+
Version 8.21 12-Dec-2011
------------------------


Modified: code/trunk/pcre.h.in
===================================================================
--- code/trunk/pcre.h.in    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/pcre.h.in    2012-01-09 20:12:58 UTC (rev 860)
@@ -280,15 +280,15 @@
 struct real_pcre16_jit_stack;     /* declaration; the definition is private  */
 typedef struct real_pcre16_jit_stack pcre16_jit_stack;


-/* If PCRE is compiled with 16 bit character support, PCRE_SCHAR16 must contain
+/* 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. */
-#ifndef PCRE_SCHAR16
-#define PCRE_SCHAR16 unsigned short
+#ifndef PCRE_UCHAR16
+#define PCRE_UCHAR16 unsigned short
#endif

#ifndef PCRE_SPTR16
-#define PCRE_SPTR16 const PCRE_SCHAR16 *
+#define PCRE_SPTR16 const PCRE_UCHAR16 *
#endif

 /* When PCRE is compiled as a C++ library, the subject pointer type can be
@@ -323,7 +323,7 @@
   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_SCHAR16 **mark;            /* For passing back a mark pointer */
+  PCRE_UCHAR16 **mark;            /* For passing back a mark pointer */
   void *executable_jit;           /* Contains a pointer to a compiled jit code */
 } pcre16_extra;


@@ -370,7 +370,7 @@
   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_SCHAR16 *mark;       /* Pointer to current mark or NULL    */
+  const PCRE_UCHAR16 *mark;       /* Pointer to current mark or NULL    */
   /* ------------------------------------------------------------------ */
 } pcre16_callout_block;


@@ -426,11 +426,11 @@
 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_SCHAR16 *, int);
+                  int *, int, PCRE_SPTR16, PCRE_UCHAR16 *, 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_SCHAR16 *, int);
+                  PCRE_UCHAR16 *, 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 *,
@@ -456,7 +456,7 @@
 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_SCHAR16 **, PCRE_SCHAR16 **);
+                  PCRE_UCHAR16 **, PCRE_UCHAR16 **);
 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,
@@ -481,7 +481,7 @@
                   const unsigned char *);
 PCRE_EXP_DECL int  pcre16_pattern_to_host_byte_order(pcre16 *, pcre16_extra *,
                   const unsigned char *);
-PCRE_EXP_DECL int  pcre16_utf16_to_host_byte_order(PCRE_SCHAR16 *,
+PCRE_EXP_DECL int  pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *,
                   PCRE_SPTR16, int, int *, int);


/* JIT compiler related functions. */

Modified: code/trunk/pcre16_utf16_utils.c
===================================================================
--- code/trunk/pcre16_utf16_utils.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/pcre16_utf16_utils.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -82,7 +82,7 @@
 */


int
-pcre16_utf16_to_host_byte_order(PCRE_SCHAR16 *output, PCRE_SPTR16 input,
+pcre16_utf16_to_host_byte_order(PCRE_UCHAR16 *output, PCRE_SPTR16 input,
int length, int *host_byte_order, int keep_boms)
{
#ifdef SUPPORT_UTF

Modified: code/trunk/pcre_get.c
===================================================================
--- code/trunk/pcre_get.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/pcre_get.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -139,7 +139,7 @@
 #else
 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
 pcre16_get_stringtable_entries(const pcre16 *code, PCRE_SPTR16 stringname,
-  PCRE_SCHAR16 **firstptr, PCRE_SCHAR16 **lastptr)
+  PCRE_UCHAR16 **firstptr, PCRE_UCHAR16 **lastptr)
 #endif
 {
 int rc;
@@ -196,8 +196,8 @@
     *firstptr = (char *)first;
     *lastptr = (char *)last;
 #else
-    *firstptr = (PCRE_SCHAR16 *)first;
-    *lastptr = (PCRE_SCHAR16 *)last;
+    *firstptr = (PCRE_UCHAR16 *)first;
+    *lastptr = (PCRE_UCHAR16 *)last;
 #endif
     return entrysize;
     }
@@ -247,7 +247,7 @@
 if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
   return pcre16_get_stringnumber(code, stringname);
 entrysize = pcre16_get_stringtable_entries(code, stringname,
-  (PCRE_SCHAR16 **)&first, (PCRE_SCHAR16 **)&last);
+  (PCRE_UCHAR16 **)&first, (PCRE_UCHAR16 **)&last);
 #endif
 if (entrysize <= 0) return entrysize;
 for (entry = (pcre_uchar *)first; entry <= (pcre_uchar *)last; entry += entrysize)
@@ -295,7 +295,7 @@
 #else
 PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
 pcre16_copy_substring(PCRE_SPTR16 subject, int *ovector, int stringcount,
-  int stringnumber, PCRE_SCHAR16 *buffer, int size)
+  int stringnumber, PCRE_UCHAR16 *buffer, int size)
 #endif
 {
 int yield;
@@ -348,7 +348,7 @@
 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_SCHAR16 *buffer, int size)
+  PCRE_UCHAR16 *buffer, int size)
 #endif
 {
 int n = get_first_set(code, stringname, ovector);


Modified: code/trunk/pcre_internal.h
===================================================================
--- code/trunk/pcre_internal.h    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/pcre_internal.h    2012-01-09 20:12:58 UTC (rev 860)
@@ -254,9 +254,9 @@


#ifdef COMPILE_PCRE16
#if USHRT_MAX != 65535
-/* This is a warning message. Change PCRE_SCHAR16 to a 16 bit data type in
+/* This is a warning message. Change PCRE_UCHAR16 to a 16 bit data type in
pcre.h(.in) and disable (comment out) this message. */
-#error Warning: PCRE_SCHAR16 is not a 16 bit data type.
+#error Warning: PCRE_UCHAR16 is not a 16 bit data type.
#endif

typedef pcre_uint16 pcre_uchar;

Modified: code/trunk/pcre_jit_compile.c
===================================================================
--- code/trunk/pcre_jit_compile.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/pcre_jit_compile.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -6772,7 +6772,8 @@
 number of captured strings in the same way as pcre_exec(), so that the user
 gets the same result with and without JIT. */


-offsetcount = ((offsetcount - (offsetcount % 3)) * 2)/3;
+if (offsetcount != 2)
+ offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
maxoffsetcount = (re->top_bracket + 1) * 2;
if (offsetcount > maxoffsetcount)
offsetcount = maxoffsetcount;

Modified: code/trunk/pcre_jit_test.c
===================================================================
--- code/trunk/pcre_jit_test.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/pcre_jit_test.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -680,7 +680,7 @@
     char null_str[1] = { 0 };
 #else
     pcre16 *regex;
-    PCRE_SCHAR16 null_str[1] = { 0 };
+    PCRE_UCHAR16 null_str[1] = { 0 };
 #endif


     if (mode) {
@@ -771,7 +771,7 @@


#ifdef SUPPORT_PCRE16

-static int convert_utf8_to_utf16(const char *input, PCRE_SCHAR16 *output, int *offsetmap, int max_length)
+static int convert_utf8_to_utf16(const char *input, PCRE_UCHAR16 *output, int *offsetmap, int max_length)
 {
     unsigned char *iptr = (unsigned char*)input;
     unsigned short *optr = (unsigned short *)output;
@@ -819,7 +819,7 @@
     return (int)(optr - (unsigned short *)output);
 }


-static int copy_char8_to_char16(const char *input, PCRE_SCHAR16 *output, int max_length)
+static int copy_char8_to_char16(const char *input, PCRE_UCHAR16 *output, int max_length)
 {
     unsigned char *iptr = (unsigned char*)input;
     unsigned short *optr = (unsigned short *)output;
@@ -836,7 +836,7 @@
 }


#define REGTEST_MAX_LENGTH 4096
-static PCRE_SCHAR16 regtest_buf[REGTEST_MAX_LENGTH];
+static PCRE_UCHAR16 regtest_buf[REGTEST_MAX_LENGTH];
static int regtest_offsetmap[REGTEST_MAX_LENGTH];

#endif /* SUPPORT_PCRE16 */

Modified: code/trunk/pcretest.c
===================================================================
--- code/trunk/pcretest.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/pcretest.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -307,11 +307,11 @@
 #define PCRE_COPY_NAMED_SUBSTRING16(rc, re, bptr, offsets, count, \
     namesptr, cbuffer, size) \
   rc = pcre16_copy_named_substring((pcre16 *)re, (PCRE_SPTR16)bptr, offsets, \
-    count, (PCRE_SPTR16)namesptr, (PCRE_SCHAR16 *)cbuffer, size/2)
+    count, (PCRE_SPTR16)namesptr, (PCRE_UCHAR16 *)cbuffer, size/2)


 #define PCRE_COPY_SUBSTRING16(rc, bptr, offsets, count, i, cbuffer, size) \
   rc = pcre16_copy_substring((PCRE_SPTR16)bptr, offsets, count, i, \
-    (PCRE_SCHAR16 *)cbuffer, size/2)
+    (PCRE_UCHAR16 *)cbuffer, size/2)


 #define PCRE_DFA_EXEC16(count, re, extra, bptr, len, start_offset, options, \
     offsets, size_offsets, workspace, size_workspace) \


Modified: code/trunk/sljit/sljitLir.c
===================================================================
--- code/trunk/sljit/sljitLir.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/sljit/sljitLir.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -694,7 +694,7 @@
 #endif
 }


-static SLJIT_INLINE void check_sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
+static SLJIT_INLINE void check_sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
 {
     /* If debug and verbose are disabled, all arguments are unused. */
     SLJIT_UNUSED_ARG(compiler);
@@ -798,7 +798,7 @@
         || ((op & ~SLJIT_INT_OP) >= SLJIT_UDIV && (op & ~SLJIT_INT_OP) <= SLJIT_SDIV));
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
     if (SLJIT_UNLIKELY(!!compiler->verbose))
-        fprintf(compiler->verbose, "  %s%s\n", op_names[GET_OPCODE(op)], !(op & SLJIT_INT_OP) ? "" : "i");
+        fprintf(compiler->verbose, "  %s%s\n", !(op & SLJIT_INT_OP) ? "" : "i", op_names[GET_OPCODE(op)]);
 #endif
 }


@@ -1233,7 +1233,7 @@
     return SLJIT_ERR_UNSUPPORTED;
 }


-SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
 {
     SLJIT_UNUSED_ARG(compiler);
     SLJIT_UNUSED_ARG(args);


Modified: code/trunk/sljit/sljitLir.h
===================================================================
--- code/trunk/sljit/sljitLir.h    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/sljit/sljitLir.h    2012-01-09 20:12:58 UTC (rev 860)
@@ -312,32 +312,46 @@
 /* Instruction generation. Returns with error code. */


/*
- Entry instruction. The instruction has "args" number of arguments
- and will use the first "general" number of general registers.
- The arguments are passed into the general registers (arg1 to general_reg1, and so on).
- Thus, "args" must be less or equal than "general". A local_size extra
- stack space is allocated for the jit code (must be less or equal than
- SLJIT_MAX_LOCAL_SIZE), which can accessed through SLJIT_LOCALS_REG (see
- the notes there). SLJIT_LOCALS_REG is not necessary the real stack pointer!
- It just points somewhere in the stack if local_size > 0 (!). Thus, the only
- thing which is known that the memory area between SLJIT_LOCALS_REG and
- SLJIT_LOCALS_REG + local_size is a valid stack area if local_size > 0
-*/
+ The executable code is basically a function call from the viewpoint of
+ the C language. The function calls must obey to the ABI (Application
+ Binary Interface) of the platform, which specify the purpose of machine
+ registers and stack handling among other things. The sljit_emit_enter
+ function emits the necessary instructions for setting up a new context
+ for the executable code and moves function arguments to the general
+ registers. The number of arguments are specified in the "args"
+ parameter and the first argument goes to SLJIT_GENERAL_REG1, the second
+ goes to SLJIT_GENERAL_REG2 and so on. The number of temporary and
+ general registers are passed in "temporaries" and "generals" arguments
+ respectively. Since the general registers contains the arguments,
+ "args" must be less or equal than "generals". The sljit_emit_enter
+ is also capable of allocating a stack space for local variables. The
+ "local_size" argument contains the size in bytes of this local area
+ and its staring address is stored in SLJIT_LOCALS_REG. However
+ the SLJIT_LOCALS_REG is not necessary the machine stack pointer.
+ The memory bytes between SLJIT_LOCALS_REG (inclusive) and
+ SLJIT_LOCALS_REG + local_size (exclusive) can be modified freely
+ until the function returns. The stack space is uninitialized.

-/* Note: multiple calls of this function overwrites the previous call. */
+   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 int sljit_emit_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size);

-/* Since sljit_emit_return (and many asserts) uses variables which are initialized
- by sljit_emit_enter, a simple return is not possible if these variables are not
- initialized. sljit_fake_enter does not emit any instruction, just initialize
- those variables. */
+/* 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 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_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size);

 /* Return from jit. See below the possible values for src and srcw. */
 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_return(struct sljit_compiler *compiler, int src, sljit_w srcw);
@@ -530,8 +544,8 @@
 #define SLJIT_SUB            25
 /* Flags: I | C | K */
 #define SLJIT_SUBC            26
-/* Note: integer mul */
-/* Flags: I | O (see SLJIT_C_MUL_*) | K */
+/* Note: integer mul
+   Flags: I | O (see SLJIT_C_MUL_*) | K */
 #define SLJIT_MUL            27
 /* Flags: I | E | K */
 #define SLJIT_AND            28
@@ -539,11 +553,23 @@
 #define SLJIT_OR            29
 /* Flags: I | E | K */
 #define SLJIT_XOR            30
-/* Flags: I | E | K */
+/* Flags: I | E | K
+   Let bit_length be the length of the shift operation: 32 or 64.
+   If src2 is immediate, src2w is masked by (bit_length - 1).
+   Otherwise, if the content of src2 is outside the range from 0
+   to bit_length - 1, the operation is undefined. */
 #define SLJIT_SHL            31
-/* Flags: I | E | K */
+/* Flags: I | E | K
+   Let bit_length be the length of the shift operation: 32 or 64.
+   If src2 is immediate, src2w is masked by (bit_length - 1).
+   Otherwise, if the content of src2 is outside the range from 0
+   to bit_length - 1, the operation is undefined. */
 #define SLJIT_LSHR            32
-/* Flags: I | E | K */
+/* Flags: I | E | K
+   Let bit_length be the length of the shift operation: 32 or 64.
+   If src2 is immediate, src2w is masked by (bit_length - 1).
+   Otherwise, if the content of src2 is outside the range from 0
+   to bit_length - 1, the operation is undefined. */
 #define SLJIT_ASHR            33


SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,

Modified: code/trunk/sljit/sljitNativeARM_Thumb2.c
===================================================================
--- code/trunk/sljit/sljitNativeARM_Thumb2.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/sljit/sljitNativeARM_Thumb2.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -122,9 +122,11 @@
 #define LSR_W        0xfa20f000
 #define LSR_WI        0xea4f0010
 #define MOV        0x4600
+#define MOVS        0x0000
 #define MOVSI        0x2000
 #define MOVT        0xf2c00000
 #define MOVW        0xf2400000
+#define MOV_W        0xea4f0000
 #define MOV_WI        0xf04f0000
 #define MUL        0xfb00f000
 #define MVNS        0x43c0
@@ -617,6 +619,13 @@
         case SLJIT_SHL:
             if (flags & ARG2_IMM) {
                 imm &= 0x1f;
+                if (imm == 0) {
+                    if (!(flags & SET_FLAGS))
+                        return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
+                    if (IS_2_LO_REGS(dst, reg))
+                        return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
+                    return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
+                }
                 if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
                     return push_inst16(compiler, LSLSI | RD3(dst) | RN3(reg) | (imm << 6));
                 return push_inst32(compiler, LSL_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
@@ -625,6 +634,13 @@
         case SLJIT_LSHR:
             if (flags & ARG2_IMM) {
                 imm &= 0x1f;
+                if (imm == 0) {
+                    if (!(flags & SET_FLAGS))
+                        return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
+                    if (IS_2_LO_REGS(dst, reg))
+                        return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
+                    return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
+                }
                 if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
                     return push_inst16(compiler, LSRSI | RD3(dst) | RN3(reg) | (imm << 6));
                 return push_inst32(compiler, LSR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
@@ -633,6 +649,13 @@
         case SLJIT_ASHR:
             if (flags & ARG2_IMM) {
                 imm &= 0x1f;
+                if (imm == 0) {
+                    if (!(flags & SET_FLAGS))
+                        return push_inst16(compiler, MOV | SET_REGS44(dst, reg));
+                    if (IS_2_LO_REGS(dst, reg))
+                        return push_inst16(compiler, MOVS | RD3(dst) | RN3(reg));
+                    return push_inst32(compiler, MOV_W | SET_FLAGS | RD4(dst) | RM4(reg));
+                }
                 if (!(flags & KEEP_FLAGS) && IS_2_LO_REGS(dst, reg))
                     return push_inst16(compiler, ASRSI | RD3(dst) | RN3(reg) | (imm << 6));
                 return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
@@ -1129,12 +1152,12 @@
     return SLJIT_SUCCESS;
 }


-SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
 {
     int size;


     CHECK_ERROR_VOID();
-    check_sljit_fake_enter(compiler, args, temporaries, generals, local_size);
+    check_sljit_set_context(compiler, args, temporaries, generals, local_size);


     compiler->temporaries = temporaries;
     compiler->generals = generals;


Modified: code/trunk/sljit/sljitNativeARM_v5.c
===================================================================
--- code/trunk/sljit/sljitNativeARM_v5.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/sljit/sljitNativeARM_v5.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -871,12 +871,12 @@
     return SLJIT_SUCCESS;
 }


-SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
 {
     int size;


     CHECK_ERROR_VOID();
-    check_sljit_fake_enter(compiler, args, temporaries, generals, local_size);
+    check_sljit_set_context(compiler, args, temporaries, generals, local_size);


     compiler->temporaries = temporaries;
     compiler->generals = generals;
@@ -993,7 +993,9 @@
     if (compiler->shift_imm != 0x20) { \
         SLJIT_ASSERT(src1 == TMP_REG1); \
         SLJIT_ASSERT(!(flags & ARGS_SWAPPED)); \
-        return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \
+        if (compiler->shift_imm != 0) \
+            return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, (compiler->shift_imm << 7) | (opcode << 5) | reg_map[src2])); \
+        return push_inst(compiler, EMIT_DATA_PROCESS_INS(MOV_DP, flags & SET_FLAGS, dst, SLJIT_UNUSED, reg_map[src2])); \
     } \
     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])));



Modified: code/trunk/sljit/sljitNativeMIPS_common.c
===================================================================
--- code/trunk/sljit/sljitNativeMIPS_common.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/sljit/sljitNativeMIPS_common.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -513,10 +513,10 @@
     return SLJIT_SUCCESS;
 }


-SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
 {
     CHECK_ERROR_VOID();
-    check_sljit_fake_enter(compiler, args, temporaries, generals, local_size);
+    check_sljit_set_context(compiler, args, temporaries, generals, local_size);


     compiler->temporaries = temporaries;
     compiler->generals = generals;


Modified: code/trunk/sljit/sljitNativePPC_32.c
===================================================================
--- code/trunk/sljit/sljitNativePPC_32.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/sljit/sljitNativePPC_32.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -47,10 +47,12 @@
     switch (op) {
     case SLJIT_ADD:
         if (flags & ALT_FORM1) {
+            /* Flags does not set: BIN_IMM_EXTS unnecessary. */
             SLJIT_ASSERT(src2 == TMP_REG2);
             return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm);
         }
         if (flags & ALT_FORM2) {
+            /* Flags does not set: BIN_IMM_EXTS unnecessary. */
             SLJIT_ASSERT(src2 == TMP_REG2);
             return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
         }
@@ -58,6 +60,11 @@
             SLJIT_ASSERT(src2 == TMP_REG2);
             return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
         }
+        if (flags & ALT_FORM4) {
+            /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+            FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff)));
+            return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1)));
+        }
         if (!(flags & ALT_SET_FLAGS))
             return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
         return push_inst(compiler, ADDC | OERC(ALT_SET_FLAGS) | D(dst) | A(src1) | B(src2));
@@ -72,22 +79,28 @@


     case SLJIT_SUB:
         if (flags & ALT_FORM1) {
+            /* Flags does not set: BIN_IMM_EXTS unnecessary. */
             SLJIT_ASSERT(src2 == TMP_REG2);
             return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
         }
-        if (flags & ALT_FORM2) {
+        if (flags & (ALT_FORM2 | ALT_FORM3)) {
             SLJIT_ASSERT(src2 == TMP_REG2);
-            return push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm);
+            if (flags & ALT_FORM2)
+                FAIL_IF(push_inst(compiler, CMPI | CRD(0) | A(src1) | compiler->imm));
+            if (flags & ALT_FORM3)
+                return push_inst(compiler, CMPLI | CRD(4) | A(src1) | compiler->imm);
+            return SLJIT_SUCCESS;
         }
-        if (flags & ALT_FORM3) {
-            SLJIT_ASSERT(src2 == TMP_REG2);
-            return push_inst(compiler, CMPLI | CRD(4) | A(src1) | compiler->imm);
+        if (flags & (ALT_FORM4 | ALT_FORM5)) {
+            if (flags & ALT_FORM4)
+                FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2)));
+            if (flags & ALT_FORM5)
+                FAIL_IF(push_inst(compiler, CMP | CRD(0) | A(src1) | B(src2)));
+            return SLJIT_SUCCESS;
         }
-        if (flags & ALT_FORM4)
-            return push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2));
         if (!(flags & ALT_SET_FLAGS))
             return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
-        if (flags & ALT_FORM5)
+        if (flags & ALT_FORM6)
             FAIL_IF(push_inst(compiler, CMPL | CRD(4) | A(src1) | B(src2)));
         return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));



Modified: code/trunk/sljit/sljitNativePPC_64.c
===================================================================
--- code/trunk/sljit/sljitNativePPC_64.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/sljit/sljitNativePPC_64.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -149,12 +149,12 @@
     switch (op) {
     case SLJIT_ADD:
         if (flags & ALT_FORM1) {
-            /* Flags not set: BIN_IMM_EXTS unnecessary. */
+            /* Flags does not set: BIN_IMM_EXTS unnecessary. */
             SLJIT_ASSERT(src2 == TMP_REG2);
             return push_inst(compiler, ADDI | D(dst) | A(src1) | compiler->imm);
         }
         if (flags & ALT_FORM2) {
-            /* Flags not set: BIN_IMM_EXTS unnecessary. */
+            /* Flags does not set: BIN_IMM_EXTS unnecessary. */
             SLJIT_ASSERT(src2 == TMP_REG2);
             return push_inst(compiler, ADDIS | D(dst) | A(src1) | compiler->imm);
         }
@@ -163,6 +163,11 @@
             BIN_IMM_EXTS();
             return push_inst(compiler, ADDIC | D(dst) | A(src1) | compiler->imm);
         }
+        if (flags & ALT_FORM4) {
+            /* Flags does not set: BIN_IMM_EXTS unnecessary. */
+            FAIL_IF(push_inst(compiler, ADDI | D(dst) | A(src1) | (compiler->imm & 0xffff)));
+            return push_inst(compiler, ADDIS | D(dst) | A(dst) | (((compiler->imm >> 16) & 0xffff) + ((compiler->imm >> 15) & 0x1)));
+        }
         if (!(flags & ALT_SET_FLAGS))
             return push_inst(compiler, ADD | D(dst) | A(src1) | B(src2));
         BIN_EXTS();
@@ -179,24 +184,29 @@


     case SLJIT_SUB:
         if (flags & ALT_FORM1) {
-            /* Flags not set: BIN_IMM_EXTS unnecessary. */
+            /* Flags does not set: BIN_IMM_EXTS unnecessary. */
             SLJIT_ASSERT(src2 == TMP_REG2);
             return push_inst(compiler, SUBFIC | D(dst) | A(src1) | compiler->imm);
         }
-        if (flags & ALT_FORM2) {
+        if (flags & (ALT_FORM2 | ALT_FORM3)) {
             SLJIT_ASSERT(src2 == TMP_REG2);
-            return push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm);
+            if (flags & ALT_FORM2)
+                FAIL_IF(push_inst(compiler, CMPI | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm));
+            if (flags & ALT_FORM3)
+                return push_inst(compiler, CMPLI | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm);
+            return SLJIT_SUCCESS;
         }
-        if (flags & ALT_FORM3) {
-            SLJIT_ASSERT(src2 == TMP_REG2);
-            return push_inst(compiler, CMPLI | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | compiler->imm);
+        if (flags & (ALT_FORM4 | ALT_FORM5)) {
+            if (flags & ALT_FORM4)
+                FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
+            if (flags & ALT_FORM5)
+                return push_inst(compiler, CMP | CRD(0 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2));
+            return SLJIT_SUCCESS;
         }
-        if (flags & ALT_FORM4)
-            return push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2));
         if (!(flags & ALT_SET_FLAGS))
             return push_inst(compiler, SUBF | D(dst) | A(src2) | B(src1));
         BIN_EXTS();
-        if (flags & ALT_FORM5)
+        if (flags & ALT_FORM6)
             FAIL_IF(push_inst(compiler, CMPL | CRD(4 | ((flags & ALT_SIGN_EXT) ? 0 : 1)) | A(src1) | B(src2)));
         return push_inst(compiler, SUBFC | OERC(ALT_SET_FLAGS) | D(dst) | A(src2) | B(src1));



Modified: code/trunk/sljit/sljitNativePPC_common.c
===================================================================
--- code/trunk/sljit/sljitNativePPC_common.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/sljit/sljitNativePPC_common.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -75,9 +75,9 @@


 /* Instruction bit sections.
    OE and Rc flag (see ALT_SET_FLAGS). */
-#define OERC(flags)    (((flags & ALT_SET_FLAGS) >> 15) | ((flags & ALT_SET_FLAGS) >> 5))
+#define OERC(flags)    (((flags & ALT_SET_FLAGS) >> 10) | (flags & ALT_SET_FLAGS))
 /* Rc flag (see ALT_SET_FLAGS). */
-#define RC(flags)    ((flags & ALT_SET_FLAGS) >> 15)
+#define RC(flags)    ((flags & ALT_SET_FLAGS) >> 10)
 #define HI(opcode)    ((opcode) << 26)
 #define LO(opcode)    ((opcode) << 1)


@@ -97,6 +97,7 @@
 #define BLR        (HI(19) | LO(16) | (0x14 << 21))
 #define CNTLZD        (HI(31) | LO(58))
 #define CNTLZW        (HI(31) | LO(26))
+#define CMP        (HI(31) | LO(0))
 #define CMPI        (HI(11))
 #define CMPL        (HI(31) | LO(32))
 #define CMPLI        (HI(10))
@@ -390,32 +391,32 @@


/* Other inp_flags. */

-#define ARG_TEST    0x0100
-#define ALT_FORM1    0x0200
-#define ALT_FORM2    0x0400
-#define ALT_FORM3    0x0800
-#define ALT_FORM4    0x1000
-#define ALT_FORM5    0x2000
+#define ARG_TEST    0x000100
 /* Integer opertion and set flags -> requires exts on 64 bit systems. */
-#define ALT_SIGN_EXT    0x4000
+#define ALT_SIGN_EXT    0x000200
 /* This flag affects the RC() and OERC() macros. */
-#define ALT_SET_FLAGS    0x8000
+#define ALT_SET_FLAGS    0x000400
+#define ALT_FORM1    0x010000
+#define ALT_FORM2    0x020000
+#define ALT_FORM3    0x040000
+#define ALT_FORM4    0x080000
+#define ALT_FORM5    0x100000
+#define ALT_FORM6    0x200000


-  /* Source and destination is register. */
-#define REG_DEST    0x0001
-#define REG1_SOURCE    0x0002
-#define REG2_SOURCE    0x0004
-  /* getput_arg_fast returned true. */
-#define FAST_DEST    0x0008
-  /* Multiple instructions are required. */
-#define SLOW_DEST    0x0010
-/* ALT_FORM1        0x0200
-   ALT_FORM2        0x0400
-   ALT_FORM3        0x0800
-   ALT_FORM4        0x1000
-   ALT_FORM5        0x2000
-   ALT_SIGN_EXT        0x4000
-   ALT_SET_FLAGS    0x8000 */
+/* Source and destination is register. */
+#define REG_DEST    0x000001
+#define REG1_SOURCE    0x000002
+#define REG2_SOURCE    0x000004
+/* getput_arg_fast returned true. */
+#define FAST_DEST    0x000008
+/* Multiple instructions are required. */
+#define SLOW_DEST    0x000010
+/*
+ALT_SIGN_EXT        0x000200
+ALT_SET_FLAGS        0x000400
+ALT_FORM1        0x010000
+...
+ALT_FORM6        0x200000 */


 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
 #include "sljitNativePPC_32.c"
@@ -499,10 +500,10 @@
     return SLJIT_SUCCESS;
 }


-SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
 {
     CHECK_ERROR_VOID();
-    check_sljit_fake_enter(compiler, args, temporaries, generals, local_size);
+    check_sljit_set_context(compiler, args, temporaries, generals, local_size);


     compiler->temporaries = temporaries;
     compiler->generals = generals;
@@ -901,7 +902,7 @@
     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_SIGN_EXT | ALT_SET_FLAGS);
+    int flags = inp_flags & (ALT_FORM1 | ALT_FORM2 | ALT_FORM3 | ALT_FORM4 | ALT_FORM5 | ALT_FORM6 | ALT_SIGN_EXT | ALT_SET_FLAGS);


     compiler->cache_arg = 0;
     compiler->cache_argw = 0;
@@ -1173,6 +1174,14 @@
     (((src) & SLJIT_IMM) && !((srcw) & ~0xffff0000))


 #if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#define TEST_ADD_IMM(src, srcw) \
+    (((src) & SLJIT_IMM) && (srcw) <= SLJIT_W(0x7fff7fff) && (srcw) >= SLJIT_W(-0x80000000))
+#else
+#define TEST_ADD_IMM(src, srcw) \
+    ((src) & SLJIT_IMM)
+#endif
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
 #define TEST_UI_IMM(src, srcw) \
     (((src) & SLJIT_IMM) && !((srcw) & ~0xffffffff))
 #else
@@ -1211,7 +1220,7 @@


     switch (GET_OPCODE(op)) {
     case SLJIT_ADD:
-        if (!GET_FLAGS(op)) {
+        if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
             if (TEST_SL_IMM(src2, src2w)) {
                 compiler->imm = src2w & 0xffff;
                 return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
@@ -1228,6 +1237,15 @@
                 compiler->imm = (src1w >> 16) & 0xffff;
                 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, 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, 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)) {
@@ -1245,7 +1263,7 @@
         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)) {
+        if (!GET_FLAGS(op) && ((src1 | src2) & SLJIT_IMM)) {
             if (TEST_SL_IMM(src2, -src2w)) {
                 compiler->imm = (-src2w) & 0xffff;
                 return emit_op(compiler, SLJIT_ADD, inp_flags | ALT_FORM1, dst, dstw, src1, src1w, TMP_REG2, 0);
@@ -1258,25 +1276,37 @@
                 compiler->imm = ((-src2w) >> 16) & 0xffff;
                 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, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, TMP_REG2, 0);
+            }
         }
-        if (dst == SLJIT_UNUSED && !(GET_FLAGS(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_SL_IMM(src2, src2w)) {
-                compiler->imm = src2w & 0xffff;
-                return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM2, 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))) {
+            if (!(op & SLJIT_SET_U)) {
+                /* 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, 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, inp_flags | ALT_FORM2, dst, dstw, src2, src2w, 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, 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, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+                }
+                return emit_op(compiler, SLJIT_SUB, inp_flags | ALT_FORM4, dst, dstw, src1, src1w, src2, src2w);
             }
-        }
-        if (dst == SLJIT_UNUSED && GET_FLAGS(op) == SLJIT_SET_U) {
-            /* 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, inp_flags | ALT_FORM3, dst, dstw, src1, src1w, TMP_REG2, 0);
+            if ((src2 & SLJIT_IMM) && src2w >= 0 && src2w <= 0x7fff) {
+                compiler->imm = src2w;
+                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, inp_flags | ALT_FORM4, 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)) {
@@ -1285,7 +1315,7 @@
             }
         }
         /* We know ALT_SIGN_EXT is set if it is an SLJIT_INT_OP on 64 bit systems. */
-        return emit_op(compiler, SLJIT_SUB, inp_flags | (!(op & SLJIT_SET_U) ? 0 : ALT_FORM5), 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, inp_flags | (!(op & SLJIT_KEEP_FLAGS) ? 0 : ALT_FORM1), dst, dstw, src1, src1w, src2, src2w);


Modified: code/trunk/sljit/sljitNativeX86_32.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_32.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/sljit/sljitNativeX86_32.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -156,10 +156,10 @@
     return SLJIT_SUCCESS;
 }


-SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
 {
     CHECK_ERROR_VOID();
-    check_sljit_fake_enter(compiler, args, temporaries, generals, local_size);
+    check_sljit_set_context(compiler, args, temporaries, generals, local_size);


     compiler->temporaries = temporaries;
     compiler->generals = generals;


Modified: code/trunk/sljit/sljitNativeX86_64.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_64.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/sljit/sljitNativeX86_64.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -273,12 +273,12 @@
     return SLJIT_SUCCESS;
 }


-SLJIT_API_FUNC_ATTRIBUTE void sljit_fake_enter(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, int args, int temporaries, int generals, int local_size)
 {
     int pushed_size;


     CHECK_ERROR_VOID();
-    check_sljit_fake_enter(compiler, args, temporaries, generals, local_size);
+    check_sljit_set_context(compiler, args, temporaries, generals, local_size);


     compiler->temporaries = temporaries;
     compiler->generals = generals;
@@ -508,7 +508,7 @@
                 inst_size += 4;
         }
         else if (flags & EX86_SHIFT_INS) {
-            imma &= 0x3f;
+            imma &= compiler->mode32 ? 0x1f : 0x3f;
             if (imma != 1) {
                 inst_size ++;
                 flags |= EX86_BYTE_ARG;


Modified: code/trunk/sljit/sljitNativeX86_common.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_common.c    2012-01-09 17:43:54 UTC (rev 859)
+++ code/trunk/sljit/sljitNativeX86_common.c    2012-01-09 20:12:58 UTC (rev 860)
@@ -1836,21 +1836,19 @@
         EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
     }
     else {
-        /* This case is really difficult, since ecx can be used for
-           addressing as well, and we must ensure to work even in that case. */
+        /* This case is really difficult, since ecx itself may used for
+           addressing, and we must ensure to work even in that case. */
+        EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
         EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
 #else
         /* [esp - 4] is reserved for eflags. */
         EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), -(int)(2 * sizeof(sljit_w)), SLJIT_PREF_SHIFT_REG, 0);
 #endif
-
-        EMIT_MOV(compiler, TMP_REGISTER, 0, src1, src1w);
         EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
         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
@@ -1863,6 +1861,41 @@
     return SLJIT_SUCCESS;
 }


+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) {
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+        if ((src2w & 0x3f) != 0 || (compiler->mode32 && (src2w & 0x1f) != 0))
+            return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
+#else
+        if ((src2w & 0x1f) != 0)
+            return emit_shift(compiler, mode, dst, dstw, src1, src1w, src2, src2w);
+#endif
+        if (!set_flags)
+            return emit_mov(compiler, dst, dstw, src1, src1w);
+        /* OR dst, src, 0 */
+        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 >= 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 >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS)
+        return emit_cmp_binary(compiler, dst, dstw, SLJIT_IMM, 0);
+    return SLJIT_SUCCESS;
+}
+
 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct sljit_compiler *compiler, int op,
     int dst, sljit_w dstw,
     int src1, sljit_w src1w,
@@ -1942,13 +1975,13 @@
         return emit_cum_binary(compiler, 0x33, 0x31, 0x6 << 3, 0x35,
             dst, dstw, src1, src1w, src2, src2w);
     case SLJIT_SHL:
-        return emit_shift(compiler, 0x4 << 3,
+        return emit_shift_with_flags(compiler, 0x4 << 3, GET_FLAGS(op),
             dst, dstw, src1, src1w, src2, src2w);
     case SLJIT_LSHR:
-        return emit_shift(compiler, 0x5 << 3,
+        return emit_shift_with_flags(compiler, 0x5 << 3, GET_FLAGS(op),
             dst, dstw, src1, src1w, src2, src2w);
     case SLJIT_ASHR:
-        return emit_shift(compiler, 0x7 << 3,
+        return emit_shift_with_flags(compiler, 0x7 << 3, GET_FLAGS(op),
             dst, dstw, src1, src1w, src2, src2w);
     }