summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15>2012-11-19 08:04:03 +0000
committerzherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15>2012-11-19 08:04:03 +0000
commit9a9fa49e61579779c641791795a2a6448161cc04 (patch)
tree71b63adf9aaf7e61d0befe19c616da606e997e89
parentfd5db157a2356f859e77744c4ea82fbe8aa17183 (diff)
downloadpcre-9a9fa49e61579779c641791795a2a6448161cc04.tar.gz
JIT compiler update.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1222 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--sljit/sljitConfigInternal.h20
-rw-r--r--sljit/sljitLir.c3
-rw-r--r--sljit/sljitLir.h8
-rw-r--r--sljit/sljitNativeMIPS_common.c10
-rw-r--r--sljit/sljitNativeSPARC_common.c3
-rw-r--r--sljit/sljitNativeX86_32.c51
-rw-r--r--sljit/sljitNativeX86_common.c25
7 files changed, 81 insertions, 39 deletions
diff --git a/sljit/sljitConfigInternal.h b/sljit/sljitConfigInternal.h
index 0b13203..2b6616e 100644
--- a/sljit/sljitConfigInternal.h
+++ b/sljit/sljitConfigInternal.h
@@ -309,20 +309,24 @@ typedef double sljit_d;
#define SLJIT_CALL __attribute__ ((fastcall))
#define SLJIT_X86_32_FASTCALL 1
-#elif defined(_WIN32)
+#elif defined(_MSC_VER)
-#ifdef __BORLANDC__
-#define SLJIT_CALL __msfastcall
-#else /* __BORLANDC__ */
#define SLJIT_CALL __fastcall
-#endif /* __BORLANDC__ */
#define SLJIT_X86_32_FASTCALL 1
-#else /* defined(_WIN32) */
-#define SLJIT_CALL __stdcall
+#elif defined(__BORLANDC__)
+
+#define SLJIT_CALL __msfastcall
+#define SLJIT_X86_32_FASTCALL 1
+
+#else /* Unknown compiler. */
+
+/* The cdecl attribute is the default. */
+#define SLJIT_CALL
+
#endif
-#else /* Other architectures. */
+#else /* Non x86-32 architectures. */
#define SLJIT_CALL
diff --git a/sljit/sljitLir.c b/sljit/sljitLir.c
index 32af2fd..6979841 100644
--- a/sljit/sljitLir.c
+++ b/sljit/sljitLir.c
@@ -193,6 +193,9 @@
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
#define SLJIT_HAS_VARIABLE_LOCALS_OFFSET 1
+#if !(defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
+#define FIXED_LOCALS_OFFSET (3 * sizeof(sljit_sw))
+#endif
#endif
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
diff --git a/sljit/sljitLir.h b/sljit/sljitLir.h
index 9ec991a..3171d15 100644
--- a/sljit/sljitLir.h
+++ b/sljit/sljitLir.h
@@ -881,7 +881,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_get_local_base(struct sljit_compiler *co
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw, sljit_sw init_value);
/* After the code generation the address for label, jump and const instructions
- are computed. Since these structures are freed sljit_free_compiler, the
+ are computed. Since these structures are freed by sljit_free_compiler, the
addresses must be preserved by the user program elsewere. */
static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->addr; }
static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
@@ -898,12 +898,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
#define SLJIT_MAJOR_VERSION 0
#define SLJIT_MINOR_VERSION 90
-/* Get the human readable name of the platfrom. Can be useful on platforms
+/* Get the human readable name of the platform. Can be useful on platforms
like ARM, where ARM and Thumb2 functions can be mixed, and
it is useful to know the type of the code generator. */
SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void);
-/* Portble helper function to get an offset of a member. */
+/* Portable helper function to get an offset of a member. */
#define SLJIT_OFFSETOF(base, member) ((sljit_sw)(&((base*)0x10)->member) - 0x10)
#if (defined SLJIT_UTIL_GLOBAL_LOCK && SLJIT_UTIL_GLOBAL_LOCK)
@@ -966,7 +966,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw SLJIT_CALL sljit_stack_resize(struct sljit_sta
/* All JIT related code should be placed in the same context (library, binary, etc.). */
-#define SLJIT_FUNC_OFFSET(func_name) ((sljit_sw)*(void**)func_name)
+#define SLJIT_FUNC_OFFSET(func_name) (*(sljit_sw*)(void*)func_name)
/* For powerpc64, the function pointers point to a context descriptor. */
struct sljit_function_context {
diff --git a/sljit/sljitNativeMIPS_common.c b/sljit/sljitNativeMIPS_common.c
index 72b228e..9559ec3 100644
--- a/sljit/sljitNativeMIPS_common.c
+++ b/sljit/sljitNativeMIPS_common.c
@@ -24,14 +24,18 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/* Latest MIPS architecture. */
+/* Automatically detect SLJIT_MIPS_32_64 */
+
SLJIT_API_FUNC_ATTRIBUTE SLJIT_CONST char* sljit_get_platform_name(void)
{
+#if (defined SLJIT_MIPS_32_64 && SLJIT_MIPS_32_64)
return "MIPS" SLJIT_CPUINFO;
+#else
+ return "MIPS III" SLJIT_CPUINFO;
+#endif
}
-/* Latest MIPS architecture. */
-/* Detect SLJIT_MIPS_32_64 */
-
/* Length of an instruction word
Both for mips-32 and mips-64 */
typedef sljit_ui sljit_ins;
diff --git a/sljit/sljitNativeSPARC_common.c b/sljit/sljitNativeSPARC_common.c
index aa8a744..c6522be 100644
--- a/sljit/sljitNativeSPARC_common.c
+++ b/sljit/sljitNativeSPARC_common.c
@@ -153,10 +153,11 @@ static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 7] = {
Useful for reordering instructions in the delay slot. */
static sljit_si push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit_si delay_slot)
{
+ sljit_ins *ptr;
SLJIT_ASSERT((delay_slot & DST_INS_MASK) == UNMOVABLE_INS
|| (delay_slot & DST_INS_MASK) == MOVABLE_INS
|| (delay_slot & DST_INS_MASK) == ((ins >> 25) & 0x1f));
- sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
FAIL_IF(!ptr);
*ptr = ins;
compiler->size++;
diff --git a/sljit/sljitNativeX86_32.c b/sljit/sljitNativeX86_32.c
index 96791a7..03a595b 100644
--- a/sljit/sljitNativeX86_32.c
+++ b/sljit/sljitNativeX86_32.c
@@ -136,7 +136,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
}
#endif
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
locals_offset = 2 * sizeof(sljit_uw);
+#else
+ SLJIT_COMPILE_ASSERT(FIXED_LOCALS_OFFSET >= 2 * sizeof(sljit_uw), require_at_least_two_words);
+ locals_offset = FIXED_LOCALS_OFFSET;
+#endif
compiler->scratches_start = locals_offset;
if (scratches > 3)
locals_offset += (scratches - 3) * sizeof(sljit_uw);
@@ -146,19 +151,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_enter(struct sljit_compiler *compil
compiler->locals_offset = locals_offset;
local_size = locals_offset + ((local_size + sizeof(sljit_uw) - 1) & ~(sizeof(sljit_uw) - 1));
+ compiler->local_size = local_size;
#ifdef _WIN32
if (local_size > 1024) {
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size));
+#else
+ local_size -= FIXED_LOCALS_OFFSET;
+ FAIL_IF(emit_do_imm(compiler, MOV_r_i32 + reg_map[SLJIT_SCRATCH_REG1], local_size));
+ FAIL_IF(emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
+ SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, FIXED_LOCALS_OFFSET));
+#endif
FAIL_IF(sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_grow_stack)));
}
#endif
- compiler->local_size = local_size;
SLJIT_ASSERT(local_size > 0);
return emit_non_cum_binary(compiler, SUB_r_rm, SUB_rm_r, SUB, SUB_EAX_i32,
SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, local_size);
-
- return SLJIT_SUCCESS;
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler, sljit_si args, sljit_si scratches, sljit_si saveds, sljit_si local_size)
@@ -175,7 +185,11 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_context(struct sljit_compiler *compiler,
compiler->logical_local_size = local_size;
#endif
+#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
locals_offset = 2 * sizeof(sljit_uw);
+#else
+ locals_offset = FIXED_LOCALS_OFFSET;
+#endif
compiler->scratches_start = locals_offset;
if (scratches > 3)
locals_offset += (scratches - 3) * sizeof(sljit_uw);
@@ -228,10 +242,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compi
else
RET();
#else
- if (compiler->args > 0)
- RET_I16(compiler->args * sizeof(sljit_sw));
- else
- RET();
+ RET();
#endif
return SLJIT_SUCCESS;
@@ -438,14 +449,26 @@ static SLJIT_INLINE sljit_si call_with_args(struct sljit_compiler *compiler, slj
*inst++ = MOV_r_rm;
*inst++ = MOD_REG | (reg_map[SLJIT_SCRATCH_REG3] << 3) | reg_map[SLJIT_SCRATCH_REG1];
#else
- inst = (sljit_ub*)ensure_buf(compiler, type - SLJIT_CALL0 + 1);
+ inst = (sljit_ub*)ensure_buf(compiler, 1 + 4 * (type - SLJIT_CALL0));
FAIL_IF(!inst);
- INC_SIZE(type - SLJIT_CALL0);
- if (type >= SLJIT_CALL3)
- PUSH_REG(reg_map[SLJIT_SCRATCH_REG3]);
- if (type >= SLJIT_CALL2)
- PUSH_REG(reg_map[SLJIT_SCRATCH_REG2]);
- PUSH_REG(reg_map[SLJIT_SCRATCH_REG1]);
+ INC_SIZE(4 * (type - SLJIT_CALL0));
+
+ *inst++ = MOV_rm_r;
+ *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG1] << 3) | 0x4 /* SIB */;
+ *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
+ *inst++ = 0;
+ if (type >= SLJIT_CALL2) {
+ *inst++ = MOV_rm_r;
+ *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG2] << 3) | 0x4 /* SIB */;
+ *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
+ *inst++ = sizeof(sljit_sw);
+ }
+ if (type >= SLJIT_CALL3) {
+ *inst++ = MOV_rm_r;
+ *inst++ = MOD_DISP8 | (reg_map[SLJIT_SCRATCH_REG3] << 3) | 0x4 /* SIB */;
+ *inst++ = (0x4 /* none*/ << 3) | reg_map[SLJIT_LOCALS_REG];
+ *inst++ = 2 * sizeof(sljit_sw);
+ }
#endif
return SLJIT_SUCCESS;
}
diff --git a/sljit/sljitNativeX86_common.c b/sljit/sljitNativeX86_common.c
index 1cd6acd..ab98a03 100644
--- a/sljit/sljitNativeX86_common.c
+++ b/sljit/sljitNativeX86_common.c
@@ -268,8 +268,12 @@ static sljit_si cpu_has_sse2 = -1;
static sljit_si cpu_has_cmov = -1;
#if defined(_MSC_VER) && (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+#if _MSC_VER >= 1400
#include <intrin.h>
+#else
+#error "MSVC does not support inline assembly in 64 bit mode"
#endif
+#endif /* _MSC_VER && SLJIT_CONFIG_X86_64 */
static void get_cpu_features(void)
{
@@ -277,9 +281,9 @@ static void get_cpu_features(void)
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-#if defined(__GNUC__) || defined(__SUNPRO_C)
+#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C)
/* AT&T syntax. */
- asm (
+ __asm__ (
"pushl %%ebx\n"
"movl $0x1, %%eax\n"
"cpuid\n"
@@ -304,9 +308,9 @@ static void get_cpu_features(void)
#else /* SLJIT_CONFIG_X86_32 */
-#if defined(__GNUC__) || defined(__SUNPRO_C)
+#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_C)
/* AT&T syntax. */
- asm (
+ __asm__ (
"pushq %%rbx\n"
"movl $0x1, %%eax\n"
"cpuid\n"
@@ -316,13 +320,19 @@ static void get_cpu_features(void)
:
: "%rax", "%rcx", "%rdx"
);
-#elif defined(_MSC_VER)
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
int CPUInfo[4];
__cpuid(CPUInfo, 1);
features = (sljit_ui)CPUInfo[3];
#else
-# error "SLJIT_DETECT_SSE2 is not implemented for this C compiler"
+ __asm {
+ mov eax, 1
+ push rbx
+ cpuid
+ pop rbx
+ mov features, edx
+ }
#endif
#endif /* SLJIT_CONFIG_X86_32 */
@@ -2554,9 +2564,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_ijump(struct sljit_compiler *compil
}
if (src == SLJIT_MEM1(SLJIT_LOCALS_REG) && type >= SLJIT_CALL3)
srcw += sizeof(sljit_sw);
-#else
- if (src == SLJIT_MEM1(SLJIT_LOCALS_REG))
- srcw += sizeof(sljit_sw) * (type - SLJIT_CALL0);
#endif
#endif
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)