[Pcre-svn] [1460] code/trunk: JIT compiler update (with MIPS…

トップ ページ
このメッセージを削除
著者: Subversion repository
日付:  
To: pcre-svn
題目: [Pcre-svn] [1460] code/trunk: JIT compiler update (with MIPS64 support).
Revision: 1460
          http://vcs.pcre.org/viewvc?view=rev&revision=1460
Author:   zherczeg
Date:     2014-03-05 14:44:22 +0000 (Wed, 05 Mar 2014)


Log Message:
-----------
JIT compiler update (with MIPS64 support).

Modified Paths:
--------------
    code/trunk/Makefile.am
    code/trunk/sljit/sljitConfig.h
    code/trunk/sljit/sljitConfigInternal.h
    code/trunk/sljit/sljitLir.c
    code/trunk/sljit/sljitLir.h
    code/trunk/sljit/sljitNativeARM_32.c
    code/trunk/sljit/sljitNativeARM_64.c
    code/trunk/sljit/sljitNativeARM_T2_32.c
    code/trunk/sljit/sljitNativeMIPS_32.c
    code/trunk/sljit/sljitNativeMIPS_common.c
    code/trunk/sljit/sljitNativePPC_common.c
    code/trunk/sljit/sljitNativeSPARC_common.c
    code/trunk/sljit/sljitNativeTILEGX_64.c
    code/trunk/sljit/sljitNativeX86_common.c


Added Paths:
-----------
    code/trunk/sljit/sljitNativeMIPS_64.c


Modified: code/trunk/Makefile.am
===================================================================
--- code/trunk/Makefile.am    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/Makefile.am    2014-03-05 14:44:22 UTC (rev 1460)
@@ -354,6 +354,7 @@
   sljit/sljitNativeARM_64.c \
   sljit/sljitNativeARM_T2_32.c \
   sljit/sljitNativeMIPS_32.c \
+  sljit/sljitNativeMIPS_64.c \
   sljit/sljitNativeMIPS_common.c \
   sljit/sljitNativePPC_32.c \
   sljit/sljitNativePPC_64.c \


Modified: code/trunk/sljit/sljitConfig.h
===================================================================
--- code/trunk/sljit/sljitConfig.h    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitConfig.h    2014-03-05 14:44:22 UTC (rev 1460)
@@ -48,6 +48,7 @@
 /* #define SLJIT_CONFIG_PPC_32 1 */
 /* #define SLJIT_CONFIG_PPC_64 1 */
 /* #define SLJIT_CONFIG_MIPS_32 1 */
+/* #define SLJIT_CONFIG_MIPS_64 1 */
 /* #define SLJIT_CONFIG_SPARC_32 1 */
 /* #define SLJIT_CONFIG_TILEGX 1 */


@@ -107,6 +108,13 @@
#define SLJIT_VERBOSE 1
#endif

-/* See the beginning of sljitConfigInternal.h */
+/*
+  SLJIT_IS_FPU_AVAILABLE
+    The availability of the FPU can be controlled by SLJIT_IS_FPU_AVAILABLE.
+      zero value - FPU is NOT present.
+      nonzero value - FPU is present.
+*/


+/* For further configurations, see the beginning of sljitConfigInternal.h */
+
#endif

Modified: code/trunk/sljit/sljitConfigInternal.h
===================================================================
--- code/trunk/sljit/sljitConfigInternal.h    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitConfigInternal.h    2014-03-05 14:44:22 UTC (rev 1460)
@@ -63,6 +63,7 @@
     || (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) \
     || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
     || (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+    || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
     || (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
     || (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \
     || (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
@@ -81,6 +82,7 @@
     + (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
     + (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX) \
     + (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+    + (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
     + (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32) \
     + (defined SLJIT_CONFIG_AUTO && SLJIT_CONFIG_AUTO) \
     + (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) >= 2
@@ -112,6 +114,8 @@
 #define SLJIT_CONFIG_PPC_32 1
 #elif defined(__mips__) && !defined(_LP64)
 #define SLJIT_CONFIG_MIPS_32 1
+#elif defined(__mips64)
+#define SLJIT_CONFIG_MIPS_64 1
 #elif defined(__sparc__) || defined(__sparc)
 #define SLJIT_CONFIG_SPARC_32 1
 #elif defined(__tilegx__)
@@ -281,6 +285,7 @@
 #elif !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
     && !(defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
     && !(defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) \
+    && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) \
     && !(defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
 #define SLJIT_32BIT_ARCHITECTURE 1
 #define SLJIT_WORD_SHIFT 2
@@ -368,7 +373,8 @@
 #define SLJIT_BIG_ENDIAN 1
 #endif


-#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) \
+    || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)


#ifdef __MIPSEL__
#define SLJIT_LITTLE_ENDIAN 1

Modified: code/trunk/sljit/sljitLir.c
===================================================================
--- code/trunk/sljit/sljitLir.c    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitLir.c    2014-03-05 14:44:22 UTC (rev 1460)
@@ -83,13 +83,13 @@
 #if !(defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED)


 #define GET_OPCODE(op) \
-    ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))
+    ((op) & ~(SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))


 #define GET_FLAGS(op) \
-    ((op) & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))
+    ((op) & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | 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))
+    ((op) & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | 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))
@@ -153,11 +153,13 @@
 #endif


 #if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
-#    define IS_COND        0x04
-#    define IS_CBZ        0x08
-#    define IS_BL        0x10
-#    define PATCH_B        0x20
-#    define PATCH_COND    0x40
+#    define IS_COND        0x004
+#    define IS_CBZ        0x008
+#    define IS_BL        0x010
+#    define PATCH_B        0x020
+#    define PATCH_COND    0x040
+#    define PATCH_ABS48    0x080
+#    define PATCH_ABS64    0x100
 #endif


 #if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
@@ -165,19 +167,27 @@
 #    define PATCH_B        0x08
 #    define ABSOLUTE_B    0x10
 #    define REMOVE_COND    0x20
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#    define PATCH_ABS32    0x40
+#    define PATCH_ABS48    0x80
 #endif
+#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
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+#    define IS_MOVABLE    0x004
+#    define IS_JAL        0x008
+#    define IS_BIT26_COND    0x010
+#    define IS_BIT16_COND    0x020


 #    define IS_COND        (IS_BIT26_COND | IS_BIT16_COND)


-#    define PATCH_B        0x40
-#    define PATCH_J        0x80
+#    define PATCH_B        0x040
+#    define PATCH_J        0x080


+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+#    define PATCH_ABS32    0x100
+#endif
+
     /* instruction types */
 #    define MOVABLE_INS    0
     /* 1 - 31 last destination register */
@@ -255,6 +265,11 @@
 #define FIXED_LOCALS_OFFSET (4 * sizeof(sljit_sw))
 #endif


+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+#define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
+#define FIXED_LOCALS_OFFSET 0
+#endif
+
 #if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
 #define SLJIT_HAS_FIXED_LOCALS_OFFSET 1
 #define FIXED_LOCALS_OFFSET (23 * sizeof(sljit_sw))
@@ -364,7 +379,7 @@
     compiler->cpool_diff = 0xffffffff;
 #endif


-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
     compiler->delay_slot = UNMOVABLE_INS;
 #endif


@@ -439,8 +454,6 @@
 SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target)
 {
     if (SLJIT_LIKELY(!!jump)) {
-        SLJIT_ASSERT(jump->flags & SLJIT_REWRITABLE_JUMP);
-
         jump->flags &= ~JUMP_LABEL;
         jump->flags |= JUMP_ADDR;
         jump->u.target = target;
@@ -569,41 +582,43 @@
     case SLJIT_SHL: \
     case SLJIT_LSHR: \
     case SLJIT_ASHR: \
-        SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O | SLJIT_SET_C))); \
+        SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C))); \
         break; \
     case SLJIT_NEG: \
-        SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \
+        SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \
         break; \
     case SLJIT_MUL: \
-        SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))); \
+        SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))); \
         break; \
     case SLJIT_CMPD: \
         SLJIT_ASSERT(!(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: \
-        SLJIT_ASSERT(!(op & (SLJIT_SET_S | SLJIT_SET_U))); \
+        SLJIT_ASSERT(!(op & (SLJIT_SET_U | SLJIT_SET_S))); \
         break; \
     case SLJIT_SUB: \
         break; \
     case SLJIT_ADDC: \
     case SLJIT_SUBC: \
-        SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))); \
+        SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O))); \
         break; \
     case SLJIT_BREAKPOINT: \
     case SLJIT_NOP: \
     case SLJIT_UMUL: \
     case SLJIT_SMUL: \
     case SLJIT_MOV: \
+    case SLJIT_MOV_UI: \
     case SLJIT_MOV_P: \
     case SLJIT_MOVU: \
+    case SLJIT_MOVU_UI: \
     case SLJIT_MOVU_P: \
         /* 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))); \
+        SLJIT_ASSERT(!(op & (SLJIT_INT_OP | SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | 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))); \
+        SLJIT_ASSERT(!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C | SLJIT_KEEP_FLAGS))); \
         break; \
     }


@@ -691,9 +706,7 @@
     (char*)"f4", (char*)"f5", (char*)"f6"
 };


-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) \
-    || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
-    || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
 #ifdef _WIN64
 #    define SLJIT_PRINT_D    "I64"
 #else
@@ -964,7 +977,7 @@
 #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_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s",
             !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
         sljit_verbose_param(dst, dstw);
         fprintf(compiler->verbose, ", ");
@@ -1006,7 +1019,7 @@
 #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_E) ? "" : ".e", !(op & SLJIT_SET_U) ? "" : ".u", !(op & SLJIT_SET_S) ? "" : ".s",
             !(op & SLJIT_SET_O) ? "" : ".o", !(op & SLJIT_SET_C) ? "" : ".c", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
         sljit_verbose_param(dst, dstw);
         fprintf(compiler->verbose, ", ");
@@ -1248,7 +1261,7 @@
     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_U | SLJIT_SET_S | SLJIT_SET_O | SLJIT_SET_C)) == 0);
     SLJIT_ASSERT((op & (SLJIT_SET_E | SLJIT_KEEP_FLAGS)) != (SLJIT_SET_E | SLJIT_KEEP_FLAGS));
 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
     if (GET_OPCODE(op) < SLJIT_ADD) {
@@ -1376,13 +1389,15 @@
 #    include "sljitNativePPC_common.c"
 #elif (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
 #    include "sljitNativeMIPS_common.c"
+#elif (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+#    include "sljitNativeMIPS_common.c"
 #elif (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
 #    include "sljitNativeSPARC_common.c"
 #elif (defined SLJIT_CONFIG_TILEGX && SLJIT_CONFIG_TILEGX)
 #    include "sljitNativeTILEGX_64.c"
 #endif


-#if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#if !(defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) && !(defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)

 SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_si type,
     sljit_si src1, sljit_sw src1w,


Modified: code/trunk/sljit/sljitLir.h
===================================================================
--- code/trunk/sljit/sljitLir.h    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitLir.h    2014-03-05 14:44:22 UTC (rev 1460)
@@ -277,7 +277,7 @@
     sljit_sw cache_argw;
 #endif


-#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) || (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
     sljit_si delay_slot;
     sljit_si cache_arg;
     sljit_sw cache_argw;
@@ -500,12 +500,12 @@
    is specified, all register arguments must be the result of other operations with
    the same SLJIT_INT_OP flag. In other words, although a register can hold either
    a 64 or 32 bit value, these values cannot be mixed. The only exceptions are
-   SLJIT_IMOV and SLJIT_IMOVU (SLJIT_MOV_SI/SLJIT_MOV_UI/SLJIT_MOVU_SI/SLJIT_MOV_UI
-   with SLJIT_INT_OP flag) which can convert any source argument to SLJIT_INT_OP
-   compatible result. This conversion might be unnecessary on some CPUs like x86-64,
-   since the upper 32 bit is always ignored. In this case SLJIT is clever enough
-   to not generate any instructions if the source and destination operands are the
-   same registers. Affects sljit_emit_op0, sljit_emit_op1 and sljit_emit_op2. */
+   SLJIT_IMOV and SLJIT_IMOVU (SLJIT_MOV_SI/SLJIT_MOVU_SI with SLJIT_INT_OP flag)
+   which can convert any source argument to SLJIT_INT_OP compatible result. This
+   conversion might be unnecessary on some CPUs like x86-64, since the upper 32
+   bit is always ignored. In this case SLJIT is clever enough to not generate any
+   instructions if the source and destination operands are the same registers.
+   Affects sljit_emit_op0, sljit_emit_op1 and sljit_emit_op2. */
 #define SLJIT_INT_OP        0x100


/* Single precision mode (SP). This flag is similar to SLJIT_INT_OP, just
@@ -531,10 +531,10 @@

 /* Set Equal (Zero) status flag (E). */
 #define SLJIT_SET_E            0x0200
+/* Set unsigned status flag (U). */
+#define SLJIT_SET_U            0x0400
 /* Set signed status flag (S). */
-#define SLJIT_SET_S            0x0400
-/* Set unsgined status flag (U). */
-#define SLJIT_SET_U            0x0800
+#define SLJIT_SET_S            0x0800
 /* Set signed overflow flag (O). */
 #define SLJIT_SET_O            0x1000
 /* Set carry flag (C).
@@ -608,7 +608,7 @@
 /* Flags: I - (never set any flags)
    Note: see SLJIT_INT_OP for further details. */
 #define SLJIT_MOV_UI            11
-/* No SLJIT_INT_OP form, since it the same as SLJIT_IMOV. */
+/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOV. */
 /* Flags: I - (never set any flags)
    Note: see SLJIT_INT_OP for further details. */
 #define SLJIT_MOV_SI            12
@@ -632,7 +632,7 @@
 /* Flags: I - (never set any flags)
    Note: see SLJIT_INT_OP for further details. */
 #define SLJIT_MOVU_UI            19
-/* No SLJIT_INT_OP form, since it the same as SLJIT_IMOVU. */
+/* No SLJIT_INT_OP form, since it is the same as SLJIT_IMOVU. */
 /* Flags: I - (never set any flags)
    Note: see SLJIT_INT_OP for further details. */
 #define SLJIT_MOVU_SI            20
@@ -662,7 +662,7 @@
 /* Flags: I | C | K */
 #define SLJIT_ADDC            26
 #define SLJIT_IADDC            (SLJIT_ADDC | SLJIT_INT_OP)
-/* Flags: I | E | S | U | O | C | K */
+/* Flags: I | E | U | S | O | C | K */
 #define SLJIT_SUB            27
 #define SLJIT_ISUB            (SLJIT_SUB | SLJIT_INT_OP)
 /* Flags: I | C | K */
@@ -857,8 +857,7 @@


/* Set the destination of the jump to this label. */
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);
-/* Only for jumps defined with SLJIT_REWRITABLE_JUMP flag.
- Note: use sljit_emit_ijump for fixed jumps. */
+/* Set the destination address of the jump to this label. */
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw target);

/* Call function or jump anywhere. Both direct and indirect form

Modified: code/trunk/sljit/sljitNativeARM_32.c
===================================================================
--- code/trunk/sljit/sljitNativeARM_32.c    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitNativeARM_32.c    2014-03-05 14:44:22 UTC (rev 1460)
@@ -2029,9 +2029,13 @@


 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
 {
+#ifdef SLJIT_IS_FPU_AVAILABLE
+    return SLJIT_IS_FPU_AVAILABLE;
+#else
     if (arm_fpu_type == -1)
         init_compiler();
     return arm_fpu_type;
+#endif
 }


#else

Modified: code/trunk/sljit/sljitNativeARM_64.c
===================================================================
--- code/trunk/sljit/sljitNativeARM_64.c    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitNativeARM_64.c    2014-03-05 14:44:22 UTC (rev 1460)
@@ -152,16 +152,20 @@
 static SLJIT_INLINE sljit_si detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code)
 {
     sljit_sw diff;
+    sljit_uw target_addr;


-    if (jump->flags & SLJIT_REWRITABLE_JUMP)
+    if (jump->flags & SLJIT_REWRITABLE_JUMP) {
+        jump->flags |= PATCH_ABS64;
         return 0;
+    }


     if (jump->flags & JUMP_ADDR)
-        diff = ((sljit_sw)jump->u.target - (sljit_sw)(code_ptr + 4));
+        target_addr = jump->u.target;
     else {
         SLJIT_ASSERT(jump->flags & JUMP_LABEL);
-        diff = ((sljit_sw)(code + jump->u.label->size) - (sljit_sw)(code_ptr + 4));
+        target_addr = (sljit_uw)(code + jump->u.label->size);
     }
+    diff = (sljit_sw)target_addr - (sljit_sw)(code_ptr + 4);


     if (jump->flags & IS_COND) {
         diff += sizeof(sljit_ins);
@@ -174,11 +178,27 @@
         diff -= sizeof(sljit_ins);
     }


-    if (diff > 0x7ffffff || diff < -0x8000000)
-        return 0;
+    if (diff <= 0x7ffffff && diff >= -0x8000000) {
+        jump->flags |= PATCH_B;
+        return 4;
+    }


-    jump->flags |= PATCH_B;
-    return 4;
+    if (target_addr <= 0xffffffffl) {
+        if (jump->flags & IS_COND)
+            code_ptr[-5] -= (2 << 5);
+        code_ptr[-2] = code_ptr[0];
+        return 2;
+    }
+    if (target_addr <= 0xffffffffffffl) {
+        if (jump->flags & IS_COND)
+            code_ptr[-5] -= (1 << 5);
+        jump->flags |= PATCH_ABS48;
+        code_ptr[-1] = code_ptr[0];
+        return 1;
+    }
+
+    jump->flags |= PATCH_ABS64;
+    return 0;
 }


 SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
@@ -190,6 +210,7 @@
     sljit_ins *buf_end;
     sljit_uw word_count;
     sljit_uw addr;
+    sljit_si dst;


     struct sljit_label *label;
     struct sljit_jump *jump;
@@ -269,7 +290,17 @@
                 buf_ptr[0] = (buf_ptr[0] & ~0xffffe0) | ((addr & 0x7ffff) << 5);
                 break;
             }
-            modify_imm64_const(buf_ptr, addr);
+
+            SLJIT_ASSERT((jump->flags & (PATCH_ABS48 | PATCH_ABS64)) || addr <= 0xffffffffl);
+            SLJIT_ASSERT((jump->flags & PATCH_ABS64) || addr <= 0xffffffffffffl);
+
+            dst = buf_ptr[0] & 0x1f;
+            buf_ptr[0] = MOVZ | dst | ((addr & 0xffff) << 5);
+            buf_ptr[1] = MOVK | dst | (((addr >> 16) & 0xffff) << 5) | (1 << 21);
+            if (jump->flags & (PATCH_ABS48 | PATCH_ABS64))
+                buf_ptr[2] = MOVK | dst | (((addr >> 32) & 0xffff) << 5) | (2 << 21);
+            if (jump->flags & PATCH_ABS64)
+                buf_ptr[3] = MOVK | dst | (((addr >> 48) & 0xffff) << 5) | (3 << 21);
         } while (0);
         jump = jump->next;
     }
@@ -1432,7 +1463,12 @@


 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
 {
+#ifdef SLJIT_IS_FPU_AVAILABLE
+    return SLJIT_IS_FPU_AVAILABLE;
+#else
+    /* Available by default. */
     return 1;
+#endif
 }


static sljit_si emit_fop_mem(struct sljit_compiler *compiler, sljit_si flags, sljit_si reg, sljit_si arg, sljit_sw argw)

Modified: code/trunk/sljit/sljitNativeARM_T2_32.c
===================================================================
--- code/trunk/sljit/sljitNativeARM_T2_32.c    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitNativeARM_T2_32.c    2014-03-05 14:44:22 UTC (rev 1460)
@@ -1533,7 +1533,12 @@


 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
 {
+#ifdef SLJIT_IS_FPU_AVAILABLE
+    return SLJIT_IS_FPU_AVAILABLE;
+#else
+    /* Available by default. */
     return 1;
+#endif
 }


#define FPU_LOAD (1 << 20)

Modified: code/trunk/sljit/sljitNativeMIPS_32.c
===================================================================
--- code/trunk/sljit/sljitNativeMIPS_32.c    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitNativeMIPS_32.c    2014-03-05 14:44:22 UTC (rev 1460)
@@ -52,7 +52,7 @@
             FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \
     }


-#define EMIT_SHIFT(op_imm, op_norm) \
+#define EMIT_SHIFT(op_imm, op_v) \
     if (flags & SRC2_IMM) { \
         if (op & SLJIT_SET_E) \
             FAIL_IF(push_inst(compiler, op_imm | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
@@ -61,16 +61,14 @@
     } \
     else { \
         if (op & SLJIT_SET_E) \
-            FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
+            FAIL_IF(push_inst(compiler, op_v | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
         if (CHECK_FLAGS(SLJIT_SET_E)) \
-            FAIL_IF(push_inst(compiler, op_norm | S(src2) | T(src1) | D(dst), DR(dst))); \
+            FAIL_IF(push_inst(compiler, op_v | 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)
 {
-    sljit_si overflow_ra = 0;
-
     switch (GET_OPCODE(op)) {
     case SLJIT_MOV:
     case SLJIT_MOV_UI:
@@ -138,30 +136,31 @@
             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)));
+        FAIL_IF(push_inst(compiler, ADDU | 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)));
+        FAIL_IF(push_inst(compiler, ADDIU | 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, ADDIU | 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);
+            return push_inst(compiler, ADDU | 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) {
-                FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
-                if (src2 < 0)
-                    FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1));
+                if (src2 >= 0)
+                    FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
+                else
+                    FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
             }
             if (op & SLJIT_SET_E)
                 FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
-            if (op & SLJIT_SET_C) {
+            if (op & (SLJIT_SET_C | SLJIT_SET_O)) {
                 if (src2 >= 0)
                     FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
                 else {
@@ -172,45 +171,28 @@
             /* dst may be the same as src1 or src2. */
             if (CHECK_FLAGS(SLJIT_SET_E))
                 FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(src2), DR(dst)));
-            if (op & SLJIT_SET_O) {
-                FAIL_IF(push_inst(compiler, SRL | T(dst) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
-                if (src2 < 0)
-                    FAIL_IF(push_inst(compiler, XORI | SA(OVERFLOW_FLAG) | TA(OVERFLOW_FLAG) | IMM(1), OVERFLOW_FLAG));
-            }
         }
         else {
-            if (op & SLJIT_SET_O) {
+            if (op & SLJIT_SET_O)
                 FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
-                FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
-                if (src1 != dst)
-                    overflow_ra = DR(src1);
-                else if (src2 != dst)
-                    overflow_ra = DR(src2);
-                else {
-                    /* Rare ocasion. */
-                    FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
-                    overflow_ra = TMP_EREG2;
-                }
-            }
             if (op & SLJIT_SET_E)
                 FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-            if (op & SLJIT_SET_C)
+            if (op & (SLJIT_SET_C | SLJIT_SET_O))
                 FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
             /* dst may be the same as src1 or src2. */
             if (CHECK_FLAGS(SLJIT_SET_E))
                 FAIL_IF(push_inst(compiler, ADDU | S(src1) | T(src2) | D(dst), DR(dst)));
-            if (op & SLJIT_SET_O) {
-                FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-                FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
-            }
         }


         /* a + b >= a | b (otherwise, the carry should be set to 1). */
-        if (op & SLJIT_SET_C)
+        if (op & (SLJIT_SET_C | SLJIT_SET_O))
             FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
-        if (op & SLJIT_SET_O)
-            return push_inst(compiler, MOVN | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
-        return SLJIT_SUCCESS;
+        if (!(op & SLJIT_SET_O))
+            return SLJIT_SUCCESS;
+        FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
+        FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+        FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+        return push_inst(compiler, SLL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);


     case SLJIT_ADDC:
         if (flags & SRC2_IMM) {
@@ -236,14 +218,13 @@
         if (!(op & SLJIT_SET_C))
             return SLJIT_SUCCESS;


-        /* Set TMP_EREG2 (dst == 0) && (ULESS_FLAG == 1). */
-        FAIL_IF(push_inst(compiler, SLTIU | S(dst) | TA(TMP_EREG2) | IMM(1), TMP_EREG2));
-        FAIL_IF(push_inst(compiler, AND | SA(TMP_EREG2) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2));
+        /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */
+        FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
         /* Set carry flag. */
-        return push_inst(compiler, OR | SA(TMP_EREG2) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG);
+        return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG);


     case SLJIT_SUB:
-        if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_S | SLJIT_SET_U)) || src2 == SIMM_MIN)) {
+        if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) {
             FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
             src2 = TMP_REG2;
             flags &= ~SRC2_IMM;
@@ -251,40 +232,25 @@


         if (flags & SRC2_IMM) {
             if (op & SLJIT_SET_O) {
-                FAIL_IF(push_inst(compiler, SRL | T(src1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
-                if (src2 < 0)
-                    FAIL_IF(push_inst(compiler, XORI | SA(TMP_EREG1) | TA(TMP_EREG1) | IMM(1), TMP_EREG1));
-                if (src1 != dst)
-                    overflow_ra = DR(src1);
-                else {
-                    /* Rare ocasion. */
-                    FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
-                    overflow_ra = TMP_EREG2;
-                }
+                if (src2 >= 0)
+                    FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
+                else
+                    FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
             }
             if (op & SLJIT_SET_E)
                 FAIL_IF(push_inst(compiler, ADDIU | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
-            if (op & SLJIT_SET_C)
+            if (op & (SLJIT_SET_C | SLJIT_SET_O))
                 FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
             /* dst may be the same as src1 or src2. */
             if (CHECK_FLAGS(SLJIT_SET_E))
                 FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
         }
         else {
-            if (op & SLJIT_SET_O) {
+            if (op & SLJIT_SET_O)
                 FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
-                FAIL_IF(push_inst(compiler, SRL | TA(TMP_EREG1) | DA(TMP_EREG1) | SH_IMM(31), TMP_EREG1));
-                if (src1 != dst)
-                    overflow_ra = DR(src1);
-                else {
-                    /* Rare ocasion. */
-                    FAIL_IF(push_inst(compiler, ADDU | S(src1) | TA(0) | DA(TMP_EREG2), TMP_EREG2));
-                    overflow_ra = TMP_EREG2;
-                }
-            }
             if (op & SLJIT_SET_E)
                 FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
-            if (op & (SLJIT_SET_U | SLJIT_SET_C))
+            if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O))
                 FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
             if (op & SLJIT_SET_U)
                 FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG));
@@ -293,16 +259,16 @@
                 FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG));
             }
             /* dst may be the same as src1 or src2. */
-            if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))
+            if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
                 FAIL_IF(push_inst(compiler, SUBU | S(src1) | T(src2) | D(dst), DR(dst)));
         }


-        if (op & SLJIT_SET_O) {
-            FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(overflow_ra) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
-            FAIL_IF(push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
-            return push_inst(compiler, MOVZ | SA(0) | TA(TMP_EREG1) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
-        }
-        return SLJIT_SUCCESS;
+        if (!(op & SLJIT_SET_O))
+            return SLJIT_SUCCESS;
+        FAIL_IF(push_inst(compiler, SLL | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
+        FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+        FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+        return push_inst(compiler, SRL | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);


     case SLJIT_SUBC:
         if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
@@ -313,7 +279,7 @@


         if (flags & SRC2_IMM) {
             if (op & SLJIT_SET_C)
-                FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(-src2), TMP_EREG1));
+                FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
             /* dst may be the same as src1 or src2. */
             FAIL_IF(push_inst(compiler, ADDIU | S(src1) | T(dst) | IMM(-src2), DR(dst)));
         }
@@ -325,15 +291,11 @@
         }


         if (op & SLJIT_SET_C)
-            FAIL_IF(push_inst(compiler, MOVZ | SA(ULESS_FLAG) | T(dst) | DA(TMP_EREG1), TMP_EREG1));
+            FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2));


         FAIL_IF(push_inst(compiler, SUBU | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
+        return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS;


-        if (op & SLJIT_SET_C)
-            FAIL_IF(push_inst(compiler, ADDU | SA(TMP_EREG1) | TA(0) | DA(ULESS_FLAG), ULESS_FLAG));
-
-        return SLJIT_SUCCESS;
-
     case SLJIT_MUL:
         SLJIT_ASSERT(!(flags & SRC2_IMM));
         if (!(op & SLJIT_SET_O)) {


Added: code/trunk/sljit/sljitNativeMIPS_64.c
===================================================================
--- code/trunk/sljit/sljitNativeMIPS_64.c                            (rev 0)
+++ code/trunk/sljit/sljitNativeMIPS_64.c    2014-03-05 14:44:22 UTC (rev 1460)
@@ -0,0 +1,469 @@
+/*
+ *    Stack-less Just-In-Time compiler
+ *
+ *    Copyright 2009-2012 Zoltan Herczeg (hzmester@???). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ *   1. Redistributions of source code must retain the above copyright notice, this list of
+ *      conditions and the following disclaimer.
+ *
+ *   2. Redistributions in binary form must reproduce the above copyright notice, this list
+ *      of conditions and the following disclaimer in the documentation and/or other materials
+ *      provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+ * SHALL THE COPYRIGHT HOLDER(S) OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* mips 64-bit arch dependent functions. */
+
+static sljit_si load_immediate(struct sljit_compiler *compiler, sljit_si dst_ar, sljit_sw imm)
+{
+    sljit_si shift = 32;
+    sljit_si shift2;
+    sljit_si inv = 0;
+    sljit_ins ins;
+    sljit_uw uimm;
+
+    if (!(imm & ~0xffff))
+        return push_inst(compiler, ORI | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
+
+    if (imm < 0 && imm >= SIMM_MIN)
+        return push_inst(compiler, ADDIU | SA(0) | TA(dst_ar) | IMM(imm), dst_ar);
+
+    if (imm <= 0x7fffffffl && imm >= -0x80000000l) {
+        FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(imm >> 16), dst_ar));
+        return (imm & 0xffff) ? push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar) : SLJIT_SUCCESS;
+    }
+
+    /* Zero extended number. */
+    uimm = imm;
+    if (imm < 0) {
+        uimm = ~imm;
+        inv = 1;
+    }
+
+    while (!(uimm & 0xff00000000000000l)) {
+        shift -= 8;
+        uimm <<= 8;
+    }
+
+    if (!(uimm & 0xf000000000000000l)) {
+        shift -= 4;
+        uimm <<= 4;
+    }
+
+    if (!(uimm & 0xc000000000000000l)) {
+        shift -= 2;
+        uimm <<= 2;
+    }
+
+    if ((sljit_sw)uimm < 0) {
+        uimm >>= 1;
+        shift += 1;
+    }
+    SLJIT_ASSERT(((uimm & 0xc000000000000000l) == 0x4000000000000000l) && (shift > 0) && (shift <= 32));
+
+    if (inv)
+        uimm = ~uimm;
+
+    FAIL_IF(push_inst(compiler, LUI | TA(dst_ar) | IMM(uimm >> 48), dst_ar));
+    if (uimm & 0x0000ffff00000000l)
+        FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 32), dst_ar));
+
+    imm &= (1l << shift) - 1;
+    if (!(imm & ~0xffff)) {
+        ins = (shift == 32) ? DSLL32 : DSLL;
+        if (shift < 32)
+            ins |= SH_IMM(shift);
+        FAIL_IF(push_inst(compiler, ins | TA(dst_ar) | DA(dst_ar), dst_ar));
+        return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar);
+    }
+
+    /* Double shifts needs to be performed. */
+    uimm <<= 32;
+    shift2 = shift - 16;
+
+    while (!(uimm & 0xf000000000000000l)) {
+        shift2 -= 4;
+        uimm <<= 4;
+    }
+
+    if (!(uimm & 0xc000000000000000l)) {
+        shift2 -= 2;
+        uimm <<= 2;
+    }
+
+    if (!(uimm & 0x8000000000000000l)) {
+        shift2--;
+        uimm <<= 1;
+    }
+
+    SLJIT_ASSERT((uimm & 0x8000000000000000l) && (shift2 > 0) && (shift2 <= 16));
+
+    FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift - shift2), dst_ar));
+    FAIL_IF(push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(uimm >> 48), dst_ar));
+    FAIL_IF(push_inst(compiler, DSLL | TA(dst_ar) | DA(dst_ar) | SH_IMM(shift2), dst_ar));
+
+    imm &= (1l << shift2) - 1;
+    return !(imm & 0xffff) ? SLJIT_SUCCESS : push_inst(compiler, ORI | SA(dst_ar) | TA(dst_ar) | IMM(imm), dst_ar);
+}
+
+#define SELECT_OP(a, b) \
+    (!(op & SLJIT_INT_OP) ? a : b)
+
+#define EMIT_LOGICAL(op_imm, op_norm) \
+    if (flags & SRC2_IMM) { \
+        if (op & SLJIT_SET_E) \
+            FAIL_IF(push_inst(compiler, op_imm | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG)); \
+        if (CHECK_FLAGS(SLJIT_SET_E)) \
+            FAIL_IF(push_inst(compiler, op_imm | S(src1) | T(dst) | IMM(src2), DR(dst))); \
+    } \
+    else { \
+        if (op & SLJIT_SET_E) \
+            FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
+        if (CHECK_FLAGS(SLJIT_SET_E)) \
+            FAIL_IF(push_inst(compiler, op_norm | S(src1) | T(src2) | D(dst), DR(dst))); \
+    }
+
+#define EMIT_SHIFT(op_dimm, op_dimm32, op_imm, op_dv, op_v) \
+    if (flags & SRC2_IMM) { \
+        if (src2 >= 32) { \
+            SLJIT_ASSERT(!(op & SLJIT_INT_OP)); \
+            ins = op_dimm32; \
+            src2 -= 32; \
+        } \
+        else \
+            ins = (op & SLJIT_INT_OP) ? op_imm : op_dimm; \
+        if (op & SLJIT_SET_E) \
+            FAIL_IF(push_inst(compiler, ins | T(src1) | DA(EQUAL_FLAG) | SH_IMM(src2), EQUAL_FLAG)); \
+        if (CHECK_FLAGS(SLJIT_SET_E)) \
+            FAIL_IF(push_inst(compiler, ins | T(src1) | D(dst) | SH_IMM(src2), DR(dst))); \
+    } \
+    else { \
+        ins = (op & SLJIT_INT_OP) ? op_v : op_dv; \
+        if (op & SLJIT_SET_E) \
+            FAIL_IF(push_inst(compiler, ins | S(src2) | T(src1) | DA(EQUAL_FLAG), EQUAL_FLAG)); \
+        if (CHECK_FLAGS(SLJIT_SET_E)) \
+            FAIL_IF(push_inst(compiler, ins | 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)
+{
+    sljit_ins ins;
+
+    switch (GET_OPCODE(op)) {
+    case SLJIT_MOV:
+    case SLJIT_MOV_P:
+        SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+        if (dst != src2)
+            return push_inst(compiler, SELECT_OP(DADDU, 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) {
+                FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(24), DR(dst)));
+                return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(24), DR(dst));
+            }
+            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) {
+                FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(16), DR(dst)));
+                return push_inst(compiler, DSRA32 | T(dst) | D(dst) | SH_IMM(16), DR(dst));
+            }
+            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_MOV_UI:
+        SLJIT_ASSERT(!(op & SLJIT_INT_OP));
+        FAIL_IF(push_inst(compiler, DSLL32 | T(src2) | D(dst) | SH_IMM(0), DR(dst)));
+        return push_inst(compiler, DSRL32 | T(dst) | D(dst) | SH_IMM(0), DR(dst));
+
+    case SLJIT_MOV_SI:
+        SLJIT_ASSERT(src1 == TMP_REG1 && !(flags & SRC2_IMM));
+        return push_inst(compiler, SLL | T(src2) | D(dst) | SH_IMM(0), DR(dst));
+
+    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, SELECT_OP(DCLZ, CLZ) | S(src2) | TA(EQUAL_FLAG) | DA(EQUAL_FLAG), EQUAL_FLAG));
+        if (CHECK_FLAGS(SLJIT_SET_E))
+            FAIL_IF(push_inst(compiler, SELECT_OP(DCLZ, CLZ) | S(src2) | T(dst) | D(dst), DR(dst)));
+#else
+        if (SLJIT_UNLIKELY(flags & UNUSED_DEST)) {
+            FAIL_IF(push_inst(compiler, SELECT_OP(DSRL32, 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, SELECT_OP(DADDU, ADDU) | 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((op & SLJIT_INT_OP) ? 32 : 64), UNMOVABLE_INS));
+        FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | T(dst) | IMM(-1), DR(dst)));
+        /* Loop for searching the highest bit. */
+        FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | 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, SELECT_OP(DSLL, SLL) | T(TMP_REG1) | D(TMP_REG1) | SH_IMM(1), UNMOVABLE_INS));
+        if (op & SLJIT_SET_E)
+            return push_inst(compiler, SELECT_OP(DADDU, ADDU) | 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) {
+                if (src2 >= 0)
+                    FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
+                else
+                    FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
+            }
+            if (op & SLJIT_SET_E)
+                FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(src2), EQUAL_FLAG));
+            if (op & (SLJIT_SET_C | SLJIT_SET_O)) {
+                if (src2 >= 0)
+                    FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+                else {
+                    FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+                    FAIL_IF(push_inst(compiler, OR | S(src1) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+                }
+            }
+            /* dst may be the same as src1 or src2. */
+            if (CHECK_FLAGS(SLJIT_SET_E))
+                FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
+        }
+        else {
+            if (op & SLJIT_SET_O)
+                FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+            if (op & SLJIT_SET_E)
+                FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+            if (op & (SLJIT_SET_C | SLJIT_SET_O))
+                FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+            /* dst may be the same as src1 or src2. */
+            if (CHECK_FLAGS(SLJIT_SET_E))
+                FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
+        }
+
+        /* a + b >= a | b (otherwise, the carry should be set to 1). */
+        if (op & (SLJIT_SET_C | SLJIT_SET_O))
+            FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+        if (!(op & SLJIT_SET_O))
+            return SLJIT_SUCCESS;
+        FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
+        FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+        FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+        return push_inst(compiler, SELECT_OP(DSRL32, SLL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
+
+    case SLJIT_ADDC:
+        if (flags & SRC2_IMM) {
+            if (op & SLJIT_SET_C) {
+                if (src2 >= 0)
+                    FAIL_IF(push_inst(compiler, ORI | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
+                else {
+                    FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | SA(0) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
+                    FAIL_IF(push_inst(compiler, OR | S(src1) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
+                }
+            }
+            FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(src2), DR(dst)));
+        } else {
+            if (op & SLJIT_SET_C)
+                FAIL_IF(push_inst(compiler, OR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+            /* dst may be the same as src1 or src2. */
+            FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(src1) | T(src2) | D(dst), DR(dst)));
+        }
+        if (op & SLJIT_SET_C)
+            FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(TMP_EREG1) | DA(TMP_EREG1), TMP_EREG1));
+
+        FAIL_IF(push_inst(compiler, SELECT_OP(DADDU, ADDU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
+        if (!(op & SLJIT_SET_C))
+            return SLJIT_SUCCESS;
+
+        /* Set ULESS_FLAG (dst == 0) && (ULESS_FLAG == 1). */
+        FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(ULESS_FLAG), ULESS_FLAG));
+        /* Set carry flag. */
+        return push_inst(compiler, OR | SA(ULESS_FLAG) | TA(TMP_EREG1) | DA(ULESS_FLAG), ULESS_FLAG);
+
+    case SLJIT_SUB:
+        if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_MIN)) {
+            FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+            src2 = TMP_REG2;
+            flags &= ~SRC2_IMM;
+        }
+
+        if (flags & SRC2_IMM) {
+            if (op & SLJIT_SET_O) {
+                if (src2 >= 0)
+                    FAIL_IF(push_inst(compiler, OR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
+                else
+                    FAIL_IF(push_inst(compiler, NOR | S(src1) | T(src1) | DA(TMP_EREG1), TMP_EREG1));
+            }
+            if (op & SLJIT_SET_E)
+                FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | TA(EQUAL_FLAG) | IMM(-src2), EQUAL_FLAG));
+            if (op & (SLJIT_SET_C | SLJIT_SET_O))
+                FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(ULESS_FLAG) | IMM(src2), ULESS_FLAG));
+            /* dst may be the same as src1 or src2. */
+            if (CHECK_FLAGS(SLJIT_SET_E))
+                FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
+        }
+        else {
+            if (op & SLJIT_SET_O)
+                FAIL_IF(push_inst(compiler, XOR | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+            if (op & SLJIT_SET_E)
+                FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | DA(EQUAL_FLAG), EQUAL_FLAG));
+            if (op & (SLJIT_SET_U | SLJIT_SET_C | SLJIT_SET_O))
+                FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(ULESS_FLAG), ULESS_FLAG));
+            if (op & SLJIT_SET_U)
+                FAIL_IF(push_inst(compiler, SLTU | S(src2) | T(src1) | DA(UGREATER_FLAG), UGREATER_FLAG));
+            if (op & SLJIT_SET_S) {
+                FAIL_IF(push_inst(compiler, SLT | S(src1) | T(src2) | DA(LESS_FLAG), LESS_FLAG));
+                FAIL_IF(push_inst(compiler, SLT | S(src2) | T(src1) | DA(GREATER_FLAG), GREATER_FLAG));
+            }
+            /* dst may be the same as src1 or src2. */
+            if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
+                FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
+        }
+
+        if (!(op & SLJIT_SET_O))
+            return SLJIT_SUCCESS;
+        FAIL_IF(push_inst(compiler, SELECT_OP(DSLL32, SLL) | TA(ULESS_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG));
+        FAIL_IF(push_inst(compiler, XOR | SA(TMP_EREG1) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+        FAIL_IF(push_inst(compiler, XOR | S(dst) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG));
+        return push_inst(compiler, SELECT_OP(DSRL32, SRL) | TA(OVERFLOW_FLAG) | DA(OVERFLOW_FLAG) | SH_IMM(31), OVERFLOW_FLAG);
+
+    case SLJIT_SUBC:
+        if ((flags & SRC2_IMM) && src2 == SIMM_MIN) {
+            FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(TMP_REG2) | IMM(src2), DR(TMP_REG2)));
+            src2 = TMP_REG2;
+            flags &= ~SRC2_IMM;
+        }
+
+        if (flags & SRC2_IMM) {
+            if (op & SLJIT_SET_C)
+                FAIL_IF(push_inst(compiler, SLTIU | S(src1) | TA(TMP_EREG1) | IMM(src2), TMP_EREG1));
+            /* dst may be the same as src1 or src2. */
+            FAIL_IF(push_inst(compiler, SELECT_OP(DADDIU, ADDIU) | S(src1) | T(dst) | IMM(-src2), DR(dst)));
+        }
+        else {
+            if (op & SLJIT_SET_C)
+                FAIL_IF(push_inst(compiler, SLTU | S(src1) | T(src2) | DA(TMP_EREG1), TMP_EREG1));
+            /* dst may be the same as src1 or src2. */
+            FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(src1) | T(src2) | D(dst), DR(dst)));
+        }
+
+        if (op & SLJIT_SET_C)
+            FAIL_IF(push_inst(compiler, SLTU | S(dst) | TA(ULESS_FLAG) | DA(TMP_EREG2), TMP_EREG2));
+
+        FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | S(dst) | TA(ULESS_FLAG) | D(dst), DR(dst)));
+        return (op & SLJIT_SET_C) ? push_inst(compiler, OR | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(ULESS_FLAG), ULESS_FLAG) : SLJIT_SUCCESS;
+
+    case SLJIT_MUL:
+        SLJIT_ASSERT(!(flags & SRC2_IMM));
+        if (!(op & SLJIT_SET_O)) {
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
+            if (op & SLJIT_INT_OP)
+                return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst));
+            FAIL_IF(push_inst(compiler, DMULT | S(src1) | T(src2), MOVABLE_INS));
+            return push_inst(compiler, MFLO | D(dst), DR(dst));
+#else
+            FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
+            return push_inst(compiler, MFLO | D(dst), DR(dst));
+#endif
+        }
+        FAIL_IF(push_inst(compiler, SELECT_OP(DMULT, MULT) | S(src1) | T(src2), MOVABLE_INS));
+        FAIL_IF(push_inst(compiler, MFHI | DA(TMP_EREG1), TMP_EREG1));
+        FAIL_IF(push_inst(compiler, MFLO | D(dst), DR(dst)));
+        FAIL_IF(push_inst(compiler, SELECT_OP(DSRA32, SRA) | T(dst) | DA(TMP_EREG2) | SH_IMM(31), TMP_EREG2));
+        return push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(TMP_EREG1) | TA(TMP_EREG2) | DA(OVERFLOW_FLAG), OVERFLOW_FLAG);
+
+    case SLJIT_AND:
+        EMIT_LOGICAL(ANDI, AND);
+        return SLJIT_SUCCESS;
+
+    case SLJIT_OR:
+        EMIT_LOGICAL(ORI, OR);
+        return SLJIT_SUCCESS;
+
+    case SLJIT_XOR:
+        EMIT_LOGICAL(XORI, XOR);
+        return SLJIT_SUCCESS;
+
+    case SLJIT_SHL:
+        EMIT_SHIFT(DSLL, DSLL32, SLL, DSLLV, SLLV);
+        return SLJIT_SUCCESS;
+
+    case SLJIT_LSHR:
+        EMIT_SHIFT(DSRL, DSRL32, SRL, DSRLV, SRLV);
+        return SLJIT_SUCCESS;
+
+    case SLJIT_ASHR:
+        EMIT_SHIFT(DSRA, DSRA32, SRA, DSRAV, SRAV);
+        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)
+{
+    FAIL_IF(push_inst(compiler, LUI | T(dst) | IMM(init_value >> 48), DR(dst)));
+    FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 32), DR(dst)));
+    FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
+    FAIL_IF(push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value >> 16), DR(dst)));
+    FAIL_IF(push_inst(compiler, DSLL | T(dst) | D(dst) | SH_IMM(16), DR(dst)));
+    return push_inst(compiler, ORI | S(dst) | T(dst) | IMM(init_value), DR(dst));
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_addr)
+{
+    sljit_ins *inst = (sljit_ins*)addr;
+
+    inst[0] = (inst[0] & 0xffff0000) | ((new_addr >> 48) & 0xffff);
+    inst[1] = (inst[1] & 0xffff0000) | ((new_addr >> 32) & 0xffff);
+    inst[3] = (inst[3] & 0xffff0000) | ((new_addr >> 16) & 0xffff);
+    inst[5] = (inst[5] & 0xffff0000) | (new_addr & 0xffff);
+    SLJIT_CACHE_FLUSH(inst, inst + 6);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant)
+{
+    sljit_ins *inst = (sljit_ins*)addr;
+
+    inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 48) & 0xffff);
+    inst[1] = (inst[1] & 0xffff0000) | ((new_constant >> 32) & 0xffff);
+    inst[3] = (inst[3] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
+    inst[5] = (inst[5] & 0xffff0000) | (new_constant & 0xffff);
+    SLJIT_CACHE_FLUSH(inst, inst + 6);
+}


Modified: code/trunk/sljit/sljitNativeMIPS_common.c
===================================================================
--- code/trunk/sljit/sljitNativeMIPS_common.c    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitNativeMIPS_common.c    2014-03-05 14:44:22 UTC (rev 1460)
@@ -30,7 +30,7 @@
 SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
 {
 #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
-    return "MIPS(32)" SLJIT_CPUINFO;
+    return "MIPS V" SLJIT_CPUINFO;
 #else
     return "MIPS III" SLJIT_CPUINFO;
 #endif
@@ -47,7 +47,7 @@
 /* For position independent code, t9 must contain the function address. */
 #define PIC_ADDR_REG    TMP_REG2


-/* TMP_EREG1 is used mainly for literal encoding on 64 bit. */
+/* TMP_EREGs are used mainly for arithmetic operations. */
 #define TMP_EREG1    15
 #define TMP_EREG2    24
 /* Floating point status register. */
@@ -86,7 +86,7 @@
 #define FS(s)        ((s) << 11)
 #define FD(d)        ((d) << 6)
 #define IMM(imm)    ((imm) & 0xffff)
-#define SH_IMM(imm)    ((imm & 0x1f) << 6)
+#define SH_IMM(imm)    ((imm) << 6)


 #define DR(dr)        (reg_map[dr])
 #define HI(opcode)    ((opcode) << 26)
@@ -96,8 +96,8 @@


 #define ABS_fmt        (HI(17) | FMT_SD | LO(5))
 #define ADD_fmt        (HI(17) | FMT_SD | LO(0))
+#define ADDIU        (HI(9))
 #define ADDU        (HI(0) | LO(33))
-#define ADDIU        (HI(9))
 #define AND        (HI(0) | LO(36))
 #define ANDI        (HI(12))
 #define B        (HI(4))
@@ -116,9 +116,25 @@
 #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 DADDIU        (HI(25))
+#define DADDU        (HI(0) | LO(45))
+#define DDIV        (HI(0) | LO(30))
+#define DDIVU        (HI(0) | LO(31))
 #define DIV        (HI(0) | LO(26))
 #define DIVU        (HI(0) | LO(27))
 #define DIV_fmt        (HI(17) | FMT_SD | LO(3))
+#define DMULT        (HI(0) | LO(28))
+#define DMULTU        (HI(0) | LO(29))
+#define DSLL        (HI(0) | LO(56))
+#define DSLL32        (HI(0) | LO(60))
+#define DSLLV        (HI(0) | LO(20))
+#define DSRA        (HI(0) | LO(59))
+#define DSRA32        (HI(0) | LO(63))
+#define DSRAV        (HI(0) | LO(23))
+#define DSRL        (HI(0) | LO(58))
+#define DSRL32        (HI(0) | LO(62))
+#define DSRLV        (HI(0) | LO(22))
+#define DSUBU        (HI(0) | LO(47))
 #define J        (HI(2))
 #define JAL        (HI(3))
 #define JALR        (HI(0) | LO(9))
@@ -129,8 +145,6 @@
 #define MFHI        (HI(0) | LO(16))
 #define MFLO        (HI(0) | LO(18))
 #define MOV_fmt        (HI(17) | FMT_SD | LO(6))
-#define MOVN        (HI(0) | LO(11))
-#define MOVZ        (HI(0) | LO(10))
 #define MUL_fmt        (HI(17) | FMT_SD | LO(2))
 #define MULT        (HI(0) | LO(24))
 #define MULTU        (HI(0) | LO(25))
@@ -158,6 +172,7 @@


 #if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
 #define CLZ        (HI(28) | LO(32))
+#define DCLZ        (HI(28) | LO(36))
 #define MUL        (HI(28) | LO(2))
 #define SEB        (HI(31) | (16 << 6) | LO(32))
 #define SEH        (HI(31) | (24 << 6) | LO(32))
@@ -292,6 +307,15 @@
         return inst + 1;
     }


+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+    if (target_addr <= 0x7fffffff) {
+        jump->flags |= PATCH_ABS32;
+        inst[2] = inst[6];
+        inst[3] = inst[7];
+        return inst + 3;
+    }
+#endif
+
     return code_ptr;
 }


@@ -348,7 +372,7 @@
 #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 - 7);
 #endif
                 code_ptr = detect_jump_type(jump, code_ptr, code);
                 jump = jump->next;
@@ -399,7 +423,17 @@
             buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
             buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
 #else
-#error "Implementation required"
+            if (jump->flags & PATCH_ABS32) {
+                SLJIT_ASSERT(addr <= 0x7fffffff);
+                buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
+                buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
+            }
+            else {
+                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[5] = (buf_ptr[5] & 0xffff0000) | (addr & 0xffff);
+            }
 #endif
         } while (0);
         jump = jump->next;
@@ -481,7 +515,11 @@
 #endif


     local_size += (saveds + 1 + 4) * sizeof(sljit_sw);
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
     local_size = (local_size + 15) & ~0xf;
+#else
+    local_size = (local_size + 31) & ~0x1f;
+#endif
     compiler->local_size = local_size;


     if (local_size <= SIMM_MAX) {
@@ -531,7 +569,11 @@
 #endif


     local_size += (saveds + 1 + 4) * sizeof(sljit_sw);
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
     compiler->local_size = (local_size + 15) & ~0xf;
+#else
+    compiler->local_size = (local_size + 31) & ~0x1f;
+#endif
 }


SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
@@ -949,6 +991,10 @@

 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
 {
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+    sljit_si int_op = op & SLJIT_INT_OP;
+#endif
+
     CHECK_ERROR();
     check_sljit_emit_op0(compiler, op);


@@ -960,7 +1006,11 @@
         return push_inst(compiler, NOP, UNMOVABLE_INS);
     case SLJIT_UMUL:
     case SLJIT_SMUL:
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+        FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? DMULTU : DMULT) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS));
+#else
         FAIL_IF(push_inst(compiler, (op == SLJIT_UMUL ? MULTU : MULT) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS));
+#endif
         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));
     case SLJIT_UDIV:
@@ -969,7 +1019,16 @@
         FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
         FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
 #endif
+
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+        if (int_op)
+            FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS));
+        else
+            FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DDIVU : DDIV) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS));
+#else
         FAIL_IF(push_inst(compiler, (op == SLJIT_UDIV ? DIVU : DIV) | S(SLJIT_SCRATCH_REG1) | T(SLJIT_SCRATCH_REG2), MOVABLE_INS));
+#endif
+
         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));
     }
@@ -983,6 +1042,8 @@
 {
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
 #    define flags 0
+#else
+    sljit_si flags = 0;
 #endif


     CHECK_ERROR();
@@ -990,50 +1051,74 @@
     ADJUST_LOCAL_OFFSET(dst, dstw);
     ADJUST_LOCAL_OFFSET(src, srcw);


+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+    if ((op & SLJIT_INT_OP) && GET_OPCODE(op) >= SLJIT_NOT) {
+        flags |= INT_DATA | SIGNED_DATA;
+        if (src & SLJIT_IMM)
+            srcw = (sljit_si)srcw;
+    }
+#endif
+
     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, 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);
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+        return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+#else
+        return emit_op(compiler, SLJIT_MOV_UI, INT_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw);
+#endif


     case SLJIT_MOV_SI:
-        return emit_op(compiler, SLJIT_MOV_SI, flags | INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+        return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, srcw);
+#else
+        return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw);
+#endif


     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, BYTE_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)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, BYTE_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)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, HALF_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)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, HALF_DATA | SIGNED_DATA, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)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, 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);
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+        return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+#else
+        return emit_op(compiler, SLJIT_MOV_UI, INT_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ui)srcw : srcw);
+#endif


     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);
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+        return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, srcw);
+#else
+        return emit_op(compiler, SLJIT_MOV_SI, INT_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_si)srcw : srcw);
+#endif


     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, BYTE_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_ub)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, BYTE_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sb)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, HALF_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_uh)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, HALF_DATA | SIGNED_DATA | WRITE_BACK, dst, dstw, TMP_REG1, 0, src, (src & SLJIT_IMM) ? (sljit_sh)srcw : srcw);


     case SLJIT_NOT:
         return emit_op(compiler, op, flags, dst, dstw, TMP_REG1, 0, src, srcw);
@@ -1046,6 +1131,7 @@
     }


     return SLJIT_SUCCESS;
+
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
 #    undef flags
 #endif
@@ -1058,6 +1144,8 @@
 {
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
 #    define flags 0
+#else
+    sljit_si flags = 0;
 #endif


     CHECK_ERROR();
@@ -1066,6 +1154,16 @@
     ADJUST_LOCAL_OFFSET(src1, src1w);
     ADJUST_LOCAL_OFFSET(src2, src2w);


+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+    if (op & SLJIT_INT_OP) {
+        flags |= INT_DATA | SIGNED_DATA;
+        if (src1 & SLJIT_IMM)
+            src1w = (sljit_si)src1w;
+        if (src2 & SLJIT_IMM)
+            src2w = (sljit_si)src2w;
+    }
+#endif
+
     switch (GET_OPCODE(op)) {
     case SLJIT_ADD:
     case SLJIT_ADDC:
@@ -1090,12 +1188,18 @@
         if (src2 & SLJIT_IMM)
             src2w &= 0x1f;
 #else
-        SLJIT_ASSERT_STOP();
+        if (src2 & SLJIT_IMM) {
+            if (op & SLJIT_INT_OP)
+                src2w &= 0x1f;
+            else
+                src2w &= 0x3f;
+        }
 #endif
         return emit_op(compiler, op, flags | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
     }


     return SLJIT_SUCCESS;
+
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
 #    undef flags
 #endif
@@ -1129,9 +1233,8 @@


 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
 {
-#if (defined SLJIT_QEMU && SLJIT_QEMU)
-    /* Qemu says fir is 0 by default. */
-    return 1;
+#ifdef SLJIT_IS_FPU_AVAILABLE
+    return SLJIT_IS_FPU_AVAILABLE;
 #elif defined(__GNUC__)
     sljit_sw fir;
     asm ("cfc1 %0, $0" : "=r"(fir));
@@ -1365,7 +1468,7 @@
 #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
 #define JUMP_LENGTH    4
 #else
-#error "Implementation required"
+#define JUMP_LENGTH    8
 #endif


 #define BR_Z(src) \
@@ -1778,6 +1881,11 @@
 {
     sljit_si sugg_dst_ar, dst_ar;
     sljit_si flags = GET_ALL_FLAGS(op);
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#    define mem_type WORD_DATA
+#else
+    sljit_si mem_type = (op & SLJIT_INT_OP) ? (INT_DATA | SIGNED_DATA) : WORD_DATA;
+#endif


     CHECK_ERROR();
     check_sljit_emit_op_flags(compiler, op, dst, dstw, src, srcw, type);
@@ -1787,13 +1895,17 @@
         return SLJIT_SUCCESS;


     op = GET_OPCODE(op);
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+    if (op == SLJIT_MOV_SI || op == SLJIT_MOV_UI)
+        mem_type = INT_DATA | SIGNED_DATA;
+#endif
     sugg_dst_ar = DR((op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2);


     compiler->cache_arg = 0;
     compiler->cache_argw = 0;
     if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
         ADJUST_LOCAL_OFFSET(src, srcw);
-        FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw));
+        FAIL_IF(emit_op_mem2(compiler, mem_type | LOAD_DATA, DR(TMP_REG1), src, srcw, dst, dstw));
         src = TMP_REG1;
         srcw = 0;
     }
@@ -1861,15 +1973,19 @@
     if (op >= SLJIT_ADD) {
         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 | flags, mem_type | CUMULATIVE_OP | LOGICAL_OP | IMM_OP | ALT_KEEP_CACHE, dst, dstw, src, srcw, TMP_REG2, 0);
     }


     if (dst & SLJIT_MEM)
-        return emit_op_mem(compiler, WORD_DATA, dst_ar, dst, dstw);
+        return emit_op_mem(compiler, mem_type, dst_ar, dst, dstw);


     if (sugg_dst_ar != dst_ar)
         return push_inst(compiler, ADDU_W | SA(dst_ar) | TA(0) | DA(sugg_dst_ar), sugg_dst_ar);
     return SLJIT_SUCCESS;
+
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+#    undef mem_type
+#endif
 }


SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value)

Modified: code/trunk/sljit/sljitNativePPC_common.c
===================================================================
--- code/trunk/sljit/sljitNativePPC_common.c    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitNativePPC_common.c    2014-03-05 14:44:22 UTC (rev 1460)
@@ -269,6 +269,18 @@
         jump->flags |= PATCH_B | ABSOLUTE_B | extra_jump_flags;
         return 1;
     }
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+    if (target_addr <= 0x7fffffff) {
+        jump->flags |= PATCH_ABS32;
+        return 1;
+    }
+    if (target_addr <= 0x7fffffffffffl) {
+        jump->flags |= PATCH_ABS48;
+        return 1;
+    }
+#endif
+
     return 0;
 }


@@ -332,8 +344,24 @@
                     code_ptr[-3] = code_ptr[0];
                     code_ptr -= 3;
 #else
-                    code_ptr[-6] = code_ptr[0];
-                    code_ptr -= 6;
+                    if (jump->flags & PATCH_ABS32) {
+                        code_ptr -= 3;
+                        code_ptr[-1] = code_ptr[2];
+                        code_ptr[0] = code_ptr[3];
+                    }
+                    else if (jump->flags & PATCH_ABS48) {
+                        code_ptr--;
+                        code_ptr[-1] = code_ptr[0];
+                        code_ptr[0] = code_ptr[1];
+                        /* rldicr rX,rX,32,31 -> rX,rX,16,47 */
+                        code_ptr[-3] ^= 0x8422;
+                        /* oris -> ori */
+                        code_ptr[-2] ^= 0x4000000;
+                    }
+                    else {
+                        code_ptr[-6] = code_ptr[0];
+                        code_ptr -= 6;
+                    }
 #endif
                     if (jump->flags & REMOVE_COND) {
                         code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);
@@ -406,6 +434,19 @@
             buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
             buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
 #else
+            if (jump->flags & PATCH_ABS32) {
+                SLJIT_ASSERT(addr <= 0x7fffffff);
+                buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 16) & 0xffff);
+                buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | (addr & 0xffff);
+                break;
+            }
+            if (jump->flags & PATCH_ABS48) {
+                SLJIT_ASSERT(addr <= 0x7fffffffffff);
+                buf_ptr[0] = (buf_ptr[0] & 0xffff0000) | ((addr >> 32) & 0xffff);
+                buf_ptr[1] = (buf_ptr[1] & 0xffff0000) | ((addr >> 16) & 0xffff);
+                buf_ptr[3] = (buf_ptr[3] & 0xffff0000) | (addr & 0xffff);
+                break;
+            }
             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);
@@ -1170,10 +1211,15 @@


 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op0(struct sljit_compiler *compiler, sljit_si op)
 {
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+    sljit_si int_op = op & SLJIT_INT_OP;
+#endif
+
     CHECK_ERROR();
     check_sljit_emit_op0(compiler, op);


-    switch (GET_OPCODE(op)) {
+    op = GET_OPCODE(op);
+    switch (op) {
     case SLJIT_BREAKPOINT:
     case SLJIT_NOP:
         return push_inst(compiler, NOP);
@@ -1182,25 +1228,25 @@
         FAIL_IF(push_inst(compiler, OR | S(SLJIT_SCRATCH_REG1) | A(TMP_REG1) | B(SLJIT_SCRATCH_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));
+        return push_inst(compiler, (op == SLJIT_UMUL ? MULHDU : MULHD) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_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));
+        return push_inst(compiler, (op == SLJIT_UMUL ? MULHWU : MULHW) | D(SLJIT_SCRATCH_REG2) | A(TMP_REG1) | B(SLJIT_SCRATCH_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)));
 #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)));
+        if (int_op) {
+            FAIL_IF(push_inst(compiler, (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));
+        } else {
+            FAIL_IF(push_inst(compiler, (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)));
         }
-        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));
 #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, (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));
 #endif
@@ -1232,7 +1278,7 @@
         FAIL_IF(push_inst(compiler, MTXER | S(TMP_ZERO)));


     if (op_flags & SLJIT_INT_OP) {
-        if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
+        if (op < SLJIT_NOT) {
             if (FAST_IS_REG(src) && src == dst) {
                 if (!TYPE_CAST_NEEDED(op))
                     return SLJIT_SUCCESS;
@@ -1466,7 +1512,7 @@
                 return emit_op(compiler, SLJIT_ADD, 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))) {
+        if (dst == SLJIT_UNUSED && (op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S)) && !(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)) {
@@ -1492,7 +1538,7 @@
             }
             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);
         }
-        if (!(op & (SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_O))) {
+        if (!(op & (SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | 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);
@@ -1603,8 +1649,12 @@


 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
 {
-    /* Always available. */
+#ifdef SLJIT_IS_FPU_AVAILABLE
+    return SLJIT_IS_FPU_AVAILABLE;
+#else
+    /* Available by default. */
     return 1;
+#endif
 }


#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 6))

Modified: code/trunk/sljit/sljitNativeSPARC_common.c
===================================================================
--- code/trunk/sljit/sljitNativeSPARC_common.c    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitNativeSPARC_common.c    2014-03-05 14:44:22 UTC (rev 1460)
@@ -943,7 +943,12 @@


 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
 {
+#ifdef SLJIT_IS_FPU_AVAILABLE
+    return SLJIT_IS_FPU_AVAILABLE;
+#else
+    /* Available by default. */
     return 1;
+#endif
 }


#define FLOAT_DATA(op) (DOUBLE_DATA | ((op & SLJIT_SINGLE_OP) >> 7))

Modified: code/trunk/sljit/sljitNativeTILEGX_64.c
===================================================================
--- code/trunk/sljit/sljitNativeTILEGX_64.c    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitNativeTILEGX_64.c    2014-03-05 14:44:22 UTC (rev 1460)
@@ -1799,7 +1799,7 @@
         return OR(ULESS_FLAG, TMP_EREG2, TMP_EREG1);


     case SLJIT_SUB:
-        if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_S | SLJIT_SET_U)) || src2 == SIMM_16BIT_MIN)) {
+        if ((flags & SRC2_IMM) && ((op & (SLJIT_SET_U | SLJIT_SET_S)) || src2 == SIMM_16BIT_MIN)) {
             FAIL_IF(ADDLI(TMP_REG2_mapped, ZERO, src2));
             src2 = TMP_REG2;
             flags &= ~SRC2_IMM;
@@ -1864,7 +1864,7 @@
             }


             /* dst may be the same as src1 or src2. */
-            if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_S | SLJIT_SET_U | SLJIT_SET_C))
+            if (CHECK_FLAGS(SLJIT_SET_E | SLJIT_SET_U | SLJIT_SET_S | SLJIT_SET_C))
                 FAIL_IF(SUB(reg_map[dst], reg_map[src1], reg_map[src2]));
         }



Modified: code/trunk/sljit/sljitNativeX86_common.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_common.c    2014-03-04 10:45:15 UTC (rev 1459)
+++ code/trunk/sljit/sljitNativeX86_common.c    2014-03-05 14:44:22 UTC (rev 1460)
@@ -2263,7 +2263,9 @@


 SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void)
 {
-#if (defined SLJIT_SSE2 && SLJIT_SSE2)
+#ifdef SLJIT_IS_FPU_AVAILABLE
+    return SLJIT_IS_FPU_AVAILABLE;
+#elif (defined SLJIT_SSE2 && SLJIT_SSE2)
 #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
     if (cpu_has_sse2 == -1)
         get_cpu_features();