[Pcre-svn] [1237] code/trunk/sljit: JIT compiler update.

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [1237] code/trunk/sljit: JIT compiler update.
Revision: 1237
          http://vcs.pcre.org/viewvc?view=rev&revision=1237
Author:   zherczeg
Date:     2013-01-01 21:41:23 +0000 (Tue, 01 Jan 2013)


Log Message:
-----------
JIT compiler update.

Modified Paths:
--------------
    code/trunk/sljit/sljitLir.c
    code/trunk/sljit/sljitNativeX86_common.c


Modified: code/trunk/sljit/sljitLir.c
===================================================================
--- code/trunk/sljit/sljitLir.c    2012-12-30 17:09:59 UTC (rev 1236)
+++ code/trunk/sljit/sljitLir.c    2013-01-01 21:41:23 UTC (rev 1237)
@@ -652,14 +652,14 @@
 }


 static char* reg_names[] = {
-    (char*)"<noreg>", (char*)"t1", (char*)"t2", (char*)"t3",
-    (char*)"te1", (char*)"te2", (char*)"s1", (char*)"s2",
-    (char*)"s3", (char*)"se1", (char*)"se2", (char*)"lcr"
+    (char*)"unused", (char*)"s1", (char*)"s2", (char*)"s3",
+    (char*)"se1", (char*)"se2", (char*)"p1", (char*)"p2",
+    (char*)"p3", (char*)"pe1", (char*)"pe2", (char*)"lc"
 };


 static char* freg_names[] = {
-    (char*)"<noreg>", (char*)"float_r1", (char*)"float_r2", (char*)"float_r3",
-    (char*)"float_r4", (char*)"float_r5", (char*)"float_r6"
+    (char*)"unused", (char*)"f1", (char*)"f2", (char*)"f3",
+    (char*)"f4", (char*)"f5", (char*)"f6"
 };


#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) || (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
@@ -736,17 +736,17 @@
};

 static char* jump_names[] = {
-    (char*)"c_equal", (char*)"c_not_equal",
-    (char*)"c_less", (char*)"c_greater_equal",
-    (char*)"c_greater", (char*)"c_less_equal",
-    (char*)"c_sig_less", (char*)"c_sig_greater_equal",
-    (char*)"c_sig_greater", (char*)"c_sig_less_equal",
-    (char*)"c_overflow", (char*)"c_not_overflow",
-    (char*)"c_mul_overflow", (char*)"c_mul_not_overflow",
-    (char*)"c_float_equal", (char*)"c_float_not_equal",
-    (char*)"c_float_less", (char*)"c_float_greater_equal",
-    (char*)"c_float_greater", (char*)"c_float_less_equal",
-    (char*)"c_float_unordered", (char*)"c_float_ordered",
+    (char*)"equal", (char*)"not_equal",
+    (char*)"less", (char*)"greater_equal",
+    (char*)"greater", (char*)"less_equal",
+    (char*)"sig_less", (char*)"sig_greater_equal",
+    (char*)"sig_greater", (char*)"sig_less_equal",
+    (char*)"overflow", (char*)"not_overflow",
+    (char*)"mul_overflow", (char*)"mul_not_overflow",
+    (char*)"float_equal", (char*)"float_not_equal",
+    (char*)"float_less", (char*)"float_greater_equal",
+    (char*)"float_greater", (char*)"float_less_equal",
+    (char*)"float_unordered", (char*)"float_ordered",
     (char*)"jump", (char*)"fast_call",
     (char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
 };
@@ -1104,7 +1104,7 @@
     SLJIT_ASSERT((type & 0xff) >= SLJIT_C_EQUAL && (type & 0xff) <= SLJIT_CALL3);
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
     if (SLJIT_UNLIKELY(!!compiler->verbose))
-        fprintf(compiler->verbose, "  jump%s<%s>\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
+        fprintf(compiler->verbose, "  jump%s.%s\n", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
 #endif
 }


@@ -1127,7 +1127,7 @@
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
     if (SLJIT_UNLIKELY(!!compiler->verbose)) {
-        fprintf(compiler->verbose, "  %scmp%s<%s> ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
+        fprintf(compiler->verbose, "  %scmp%s.%s ", !(type & SLJIT_INT_OP) ? "" : "i", !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
         sljit_verbose_param(src1, src1w);
         fprintf(compiler->verbose, ", ");
         sljit_verbose_param(src2, src2w);
@@ -1156,7 +1156,7 @@
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
     if (SLJIT_UNLIKELY(!!compiler->verbose)) {
-        fprintf(compiler->verbose, "  %scmp%s<%s> ", (type & SLJIT_SINGLE_OP) ? "s" : "d",
+        fprintf(compiler->verbose, "  %scmp%s.%s ", (type & SLJIT_SINGLE_OP) ? "s" : "d",
             !(type & SLJIT_REWRITABLE_JUMP) ? "" : ".r", jump_names[type & 0xff]);
         sljit_verbose_fparam(src1, src1w);
         fprintf(compiler->verbose, ", ");
@@ -1187,7 +1187,7 @@
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
     if (SLJIT_UNLIKELY(!!compiler->verbose)) {
-        fprintf(compiler->verbose, "  ijump<%s> ", jump_names[type]);
+        fprintf(compiler->verbose, "  ijump.%s ", jump_names[type]);
         sljit_verbose_param(src, srcw);
         fprintf(compiler->verbose, "\n");
     }
@@ -1223,14 +1223,14 @@
 #endif
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
     if (SLJIT_UNLIKELY(!!compiler->verbose)) {
-        fprintf(compiler->verbose, "  op_flags<%s%s%s%s> ", !(op & SLJIT_INT_OP) ? "" : "i",
+        fprintf(compiler->verbose, "  %sflags.%s%s%s ", !(op & SLJIT_INT_OP) ? "" : "i",
             op_names[GET_OPCODE(op)], !(op & SLJIT_SET_E) ? "" : ".e", !(op & SLJIT_KEEP_FLAGS) ? "" : ".k");
         sljit_verbose_param(dst, dstw);
         if (src != SLJIT_UNUSED) {
             fprintf(compiler->verbose, ", ");
             sljit_verbose_param(src, srcw);
         }
-        fprintf(compiler->verbose, ", <%s>\n", jump_names[type]);
+        fprintf(compiler->verbose, ", %s\n", jump_names[type]);
     }
 #endif
 }


Modified: code/trunk/sljit/sljitNativeX86_common.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_common.c    2012-12-30 17:09:59 UTC (rev 1236)
+++ code/trunk/sljit/sljitNativeX86_common.c    2013-01-01 21:41:23 UTC (rev 1237)
@@ -206,6 +206,7 @@
 #define OR_r_rm        0x0b
 #define OR_EAX_i32    0x0d
 #define OR_rm_r        0x09
+#define OR_rm8_r8    0x08
 #define POP_r        0x58
 #define POP_rm        0x8f
 #define POPF        0x9d
@@ -286,12 +287,20 @@
     /* AT&T syntax. */
     __asm__ (
         "movl $0x1, %%eax\n"
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+        /* On x86-32, there is no red zone, so this
+           should work (no need for a local variable). */
+        "push %%ebx\n"
+#endif
         "cpuid\n"
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+        "pop %%ebx\n"
+#endif
         "movl %%edx, %0\n"
         : "=g" (features)
         :
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-        : "%eax", "%ebx", "%ecx", "%edx"
+        : "%eax", "%ecx", "%edx"
 #else
         : "%rax", "%rbx", "%rcx", "%rdx"
 #endif
@@ -1757,7 +1766,7 @@
     return SLJIT_SUCCESS;
 }


-static sljit_si emit_lea_binary(struct sljit_compiler *compiler,
+static sljit_si emit_lea_binary(struct sljit_compiler *compiler, sljit_si keep_flags,
     sljit_si dst, sljit_sw dstw,
     sljit_si src1, sljit_sw src1w,
     sljit_si src2, sljit_sw src2w)
@@ -1766,10 +1775,12 @@
     sljit_si dst_r, done = 0;


     /* These cases better be left to handled by normal way. */
-    if (dst == src1 && dstw == src1w)
-        return SLJIT_ERR_UNSUPPORTED;
-    if (dst == src2 && dstw == src2w)
-        return SLJIT_ERR_UNSUPPORTED;
+    if (!keep_flags) {
+        if (dst == src1 && dstw == src1w)
+            return SLJIT_ERR_UNSUPPORTED;
+        if (dst == src2 && dstw == src2w)
+            return SLJIT_ERR_UNSUPPORTED;
+    }


     dst_r = (dst <= TMP_REGISTER) ? dst : TMP_REGISTER;


@@ -2125,7 +2136,7 @@
     switch (GET_OPCODE(op)) {
     case SLJIT_ADD:
         if (!GET_FLAGS(op)) {
-            if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
+            if (emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
                 return compiler->error;
         }
         else
@@ -2145,7 +2156,7 @@
             dst, dstw, src1, src1w, src2, src2w);
     case SLJIT_SUB:
         if (!GET_FLAGS(op)) {
-            if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
+            if ((src2 & SLJIT_IMM) && emit_lea_binary(compiler, op & SLJIT_KEEP_FLAGS, dst, dstw, src1, src1w, SLJIT_IMM, -src2w) != SLJIT_ERR_UNSUPPORTED)
                 return compiler->error;
         }
         else
@@ -2609,6 +2620,21 @@
     cond_set = get_jump_code(type) + 0x10;


 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+    if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && dst <= TMP_REGISTER && dst == src) {
+        inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 3);
+        FAIL_IF(!inst);
+        INC_SIZE(4 + 3);
+        /* Set low register to conditional flag. */
+        *inst++ = (reg_map[TMP_REGISTER] <= 7) ? REX : REX_B;
+        *inst++ = GROUP_0F;
+        *inst++ = cond_set;
+        *inst++ = MOD_REG | reg_lmap[TMP_REGISTER];
+        *inst++ = REX | (reg_map[TMP_REGISTER] <= 7 ? 0 : REX_R) | (reg_map[dst] <= 7 ? 0 : REX_B);
+        *inst++ = OR_rm8_r8;
+        *inst++ = MOD_REG | (reg_lmap[TMP_REGISTER] << 3) | reg_lmap[dst];
+        return SLJIT_SUCCESS;
+    }
+
     reg = (op == SLJIT_MOV && dst <= TMP_REGISTER) ? dst : TMP_REGISTER;


     inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 + 4);
@@ -2689,6 +2715,39 @@
         return SLJIT_SUCCESS;
     }


+    if (GET_OPCODE(op) == SLJIT_OR && !GET_ALL_FLAGS(op) && dst <= TMP_REGISTER && dst == src && reg_map[dst] <= 4) {
+        SLJIT_COMPILE_ASSERT(reg_map[SLJIT_SCRATCH_REG1] == 0, scratch_reg1_must_be_eax);
+        if (dst != SLJIT_SCRATCH_REG1) {
+            inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 2 + 1);
+            FAIL_IF(!inst);
+            INC_SIZE(1 + 3 + 2 + 1);
+            /* Set low register to conditional flag. */
+            *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER];
+            *inst++ = GROUP_0F;
+            *inst++ = cond_set;
+            *inst++ = MOD_REG | 0 /* eax */;
+            *inst++ = OR_rm8_r8;
+            *inst++ = MOD_REG | (0 /* eax */ << 3) | reg_map[dst];
+            *inst++ = XCHG_EAX_r + reg_map[TMP_REGISTER];
+        }
+        else {
+            inst = (sljit_ub*)ensure_buf(compiler, 1 + 2 + 3 + 2 + 2);
+            FAIL_IF(!inst);
+            INC_SIZE(2 + 3 + 2 + 2);
+            /* Set low register to conditional flag. */
+            *inst++ = XCHG_r_rm;
+            *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REGISTER];
+            *inst++ = GROUP_0F;
+            *inst++ = cond_set;
+            *inst++ = MOD_REG | 1 /* ecx */;
+            *inst++ = OR_rm8_r8;
+            *inst++ = MOD_REG | (1 /* ecx */ << 3) | 0 /* eax */;
+            *inst++ = XCHG_r_rm;
+            *inst++ = MOD_REG | (1 /* ecx */ << 3) | reg_map[TMP_REGISTER];
+        }
+        return SLJIT_SUCCESS;
+    }
+
     /* Set TMP_REGISTER to the bit. */
     inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 3 + 3 + 1);
     FAIL_IF(!inst);
@@ -2733,16 +2792,16 @@
     if (NOT_HALFWORD(offset)) {
         FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, offset));
 #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
-        SLJIT_ASSERT(emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0) != SLJIT_ERR_UNSUPPORTED);
+        SLJIT_ASSERT(emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0) != SLJIT_ERR_UNSUPPORTED);
         return compiler->error;
 #else
-        return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0);
+        return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0);
 #endif
     }
 #endif


     if (offset != 0)
-        return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset);
+        return emit_lea_binary(compiler, SLJIT_KEEP_FLAGS, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset);
     return emit_mov(compiler, dst, dstw, SLJIT_LOCALS_REG, 0);
 }