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

トップ ページ
このメッセージを削除
著者: Subversion repository
日付:  
To: pcre-svn
題目: [Pcre-svn] [1598] code/trunk/sljit: JIT compiler update.
Revision: 1598
          http://vcs.pcre.org/viewvc?view=rev&revision=1598
Author:   zherczeg
Date:     2015-08-30 06:40:41 +0100 (Sun, 30 Aug 2015)
Log Message:
-----------
JIT compiler update.


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


Modified: code/trunk/sljit/sljitLir.h
===================================================================
--- code/trunk/sljit/sljitLir.h    2015-08-29 15:23:48 UTC (rev 1597)
+++ code/trunk/sljit/sljitLir.h    2015-08-30 05:40:41 UTC (rev 1598)
@@ -869,34 +869,6 @@
     sljit_si src1, sljit_sw src1w,
     sljit_si src2, sljit_sw src2w);


-/* The following function is a helper function for sljit_emit_op_custom.
-   It returns with the real machine register index ( >=0 ) of any SLJIT_R,
-   SLJIT_S and SLJIT_SP registers.
-
-   Note: it returns with -1 for virtual registers (only on x86-32). */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
-
-/* The following function is a helper function for sljit_emit_op_custom.
-   It returns with the real machine register index of any SLJIT_FLOAT register.
-
-   Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg);
-
-/* Any instruction can be inserted into the instruction stream by
-   sljit_emit_op_custom. It has a similar purpose as inline assembly.
-   The size parameter must match to the instruction size of the target
-   architecture:
-
-         x86: 0 < size <= 15. The instruction argument can be byte aligned.
-      Thumb2: if size == 2, the instruction argument must be 2 byte aligned.
-              if size == 4, the instruction argument must be 4 byte aligned.
-   Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
-
-SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
-    void *instruction, sljit_si size);
-
 /* Returns with non-zero if fpu is available. */


SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_is_fpu_available(void);
@@ -1214,4 +1186,64 @@

#endif /* !(defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL) */

+/* --------------------------------------------------------------------- */
+/*  CPU specific functions                                               */
+/* --------------------------------------------------------------------- */
+
+/* The following function is a helper function for sljit_emit_op_custom.
+   It returns with the real machine register index ( >=0 ) of any SLJIT_R,
+   SLJIT_S and SLJIT_SP registers.
+
+   Note: it returns with -1 for virtual registers (only on x86-32). */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_register_index(sljit_si reg);
+
+/* The following function is a helper function for sljit_emit_op_custom.
+   It returns with the real machine register index of any SLJIT_FLOAT register.
+
+   Note: the index is always an even number on ARM (except ARM-64), MIPS, and SPARC. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_float_register_index(sljit_si reg);
+
+/* Any instruction can be inserted into the instruction stream by
+   sljit_emit_op_custom. It has a similar purpose as inline assembly.
+   The size parameter must match to the instruction size of the target
+   architecture:
+
+         x86: 0 < size <= 15. The instruction argument can be byte aligned.
+      Thumb2: if size == 2, the instruction argument must be 2 byte aligned.
+              if size == 4, the instruction argument must be 4 byte aligned.
+   Otherwise: size must be 4 and instruction argument must be 4 byte aligned. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_op_custom(struct sljit_compiler *compiler,
+    void *instruction, sljit_si size);
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+
+/* Returns with non-zero if sse2 is available. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void);
+
+/* Returns with non-zero if cmov instruction is available. */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void);
+
+/* Emit a conditional mov instruction on x86 CPUs. This instruction
+   moves src to destination, if the condition is satisfied. Unlike
+   other arithmetic instructions, destination must be a register.
+   Before such instructions are emitted, cmov support should be
+   checked by sljit_x86_is_cmov_available function.
+    type must be between SLJIT_EQUAL and SLJIT_S_ORDERED
+    dst_reg must be a valid register and it can be combined
+      with SLJIT_INT_OP to perform 32 bit arithmetic
+   Flags: I - (never set any flags)
+ */
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler,
+    sljit_si type,
+    sljit_si dst_reg,
+    sljit_si src, sljit_sw srcw);
+
+#endif
+
 #endif /* _SLJIT_LIR_H_ */


Modified: code/trunk/sljit/sljitNativeX86_common.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_common.c    2015-08-29 15:23:48 UTC (rev 1597)
+++ code/trunk/sljit/sljitNativeX86_common.c    2015-08-30 05:40:41 UTC (rev 1598)
@@ -2936,3 +2936,69 @@
 {
     *(sljit_sw*)addr = new_constant;
 }
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_sse2_available(void)
+{
+#if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
+    if (cpu_has_sse2 == -1)
+        get_cpu_features();
+    return cpu_has_sse2;
+#else
+    return 1;
+#endif
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_is_cmov_available(void)
+{
+    if (cpu_has_cmov == -1)
+        get_cpu_features();
+    return cpu_has_cmov;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_x86_emit_cmov(struct sljit_compiler *compiler,
+    sljit_si type,
+    sljit_si dst_reg,
+    sljit_si src, sljit_sw srcw)
+{
+    sljit_ub* inst;
+
+    CHECK_ERROR();
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+    CHECK_ARGUMENT(sljit_x86_is_cmov_available());
+    CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_INT_OP)));
+    CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_D_ORDERED);
+    CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg & ~SLJIT_INT_OP));
+    FUNCTION_CHECK_SRC(src, srcw);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+    if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+        fprintf(compiler->verbose, "  x86_cmov%s %s%s, ",
+            !(dst_reg & SLJIT_INT_OP) ? "" : ".i",
+            JUMP_PREFIX(type), jump_names[type & 0xff]);
+        sljit_verbose_reg(compiler, dst_reg & ~SLJIT_INT_OP);
+        fprintf(compiler->verbose, ", ");
+        sljit_verbose_param(compiler, src, srcw);
+        fprintf(compiler->verbose, "\n");
+    }
+#endif
+
+    ADJUST_LOCAL_OFFSET(src, srcw);
+    CHECK_EXTRA_REGS(src, srcw, (void)0);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+    compiler->mode32 = dst_reg & SLJIT_INT_OP;
+#endif
+    dst_reg &= ~SLJIT_INT_OP;
+
+    if (SLJIT_UNLIKELY(src & SLJIT_IMM)) {
+        EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, srcw);
+        src = TMP_REG1;
+        srcw = 0;
+    }
+
+    inst = emit_x86_instruction(compiler, 2, dst_reg, 0, src, srcw);
+    FAIL_IF(!inst);
+    *inst++ = GROUP_0F;
+    *inst = get_jump_code(type & 0xff) - 0x40;
+    return SLJIT_SUCCESS;
+}