Revision: 722
http://vcs.pcre.org/viewvc?view=rev&revision=722
Author: zherczeg
Date: 2011-10-07 20:18:55 +0100 (Fri, 07 Oct 2011)
Log Message:
-----------
JIT compiler update: Make fast_call a separate call type. Allows call optimizations on MIPS.
Modified Paths:
--------------
code/trunk/sljit/sljitLir.c
code/trunk/sljit/sljitLir.h
code/trunk/sljit/sljitNativeARM_Thumb2.c
code/trunk/sljit/sljitNativeARM_v5.c
code/trunk/sljit/sljitNativeMIPS_common.c
code/trunk/sljit/sljitNativePPC_common.c
code/trunk/sljit/sljitNativeX86_32.c
code/trunk/sljit/sljitNativeX86_64.c
code/trunk/sljit/sljitNativeX86_common.c
Modified: code/trunk/sljit/sljitLir.c
===================================================================
--- code/trunk/sljit/sljitLir.c 2011-10-07 15:51:39 UTC (rev 721)
+++ code/trunk/sljit/sljitLir.c 2011-10-07 19:18:55 UTC (rev 722)
@@ -662,7 +662,7 @@
(char*)"c_float_less", (char*)"c_float_greater_equal",
(char*)"c_float_greater", (char*)"c_float_less_equal",
(char*)"c_float_nan", (char*)"c_float_not_nan",
- (char*)"jump",
+ (char*)"jump", (char*)"fast_call",
(char*)"call0", (char*)"call1", (char*)"call2", (char*)"call3"
};
Modified: code/trunk/sljit/sljitLir.h
===================================================================
--- code/trunk/sljit/sljitLir.h 2011-10-07 15:51:39 UTC (rev 721)
+++ code/trunk/sljit/sljitLir.h 2011-10-07 19:18:55 UTC (rev 722)
@@ -573,13 +573,13 @@
#define SLJIT_C_FLOAT_NOT_NAN 21
#define SLJIT_JUMP 22
-#define SLJIT_CALL0 23
-#define SLJIT_CALL1 24
-#define SLJIT_CALL2 25
-#define SLJIT_CALL3 26
+#define SLJIT_FAST_CALL 23
+#define SLJIT_CALL0 24
+#define SLJIT_CALL1 25
+#define SLJIT_CALL2 26
+#define SLJIT_CALL3 27
/* Fast calling method. See sljit_emit_fast_enter / sljit_emit_fast_return. */
-#define SLJIT_FAST_CALL SLJIT_CALL0
/* The target can be changed during runtime (see: sljit_set_jump_addr). */
#define SLJIT_REWRITABLE_JUMP 0x1000
Modified: code/trunk/sljit/sljitNativeARM_Thumb2.c
===================================================================
--- code/trunk/sljit/sljitNativeARM_Thumb2.c 2011-10-07 15:51:39 UTC (rev 721)
+++ code/trunk/sljit/sljitNativeARM_Thumb2.c 2011-10-07 19:18:55 UTC (rev 722)
@@ -1736,26 +1736,19 @@
if (src & SLJIT_IMM) {
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
FAIL_IF(!jump);
- set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_CALL0) ? IS_BL : 0));
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
jump->u.target = srcw;
FAIL_IF(emit_imm32_const(compiler, TMP_REG1, 0));
jump->addr = compiler->size;
- if (type <= SLJIT_JUMP)
- FAIL_IF(push_inst16(compiler, BX | RN3(TMP_REG1)));
- else
- FAIL_IF(push_inst16(compiler, BLX | RN3(TMP_REG1)));
+ FAIL_IF(push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(TMP_REG1)));
}
else {
- if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) {
- if (type <= SLJIT_JUMP)
- return push_inst16(compiler, BX | RN3(src));
- else
- return push_inst16(compiler, BLX | RN3(src));
- }
+ if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS)
+ return push_inst16(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RN3(src));
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, src, srcw));
- if (type >= SLJIT_CALL0)
+ if (type >= SLJIT_FAST_CALL)
return push_inst16(compiler, BLX | RN3(TMP_REG1));
}
return SLJIT_SUCCESS;
Modified: code/trunk/sljit/sljitNativeARM_v5.c
===================================================================
--- code/trunk/sljit/sljitNativeARM_v5.c 2011-10-07 15:51:39 UTC (rev 721)
+++ code/trunk/sljit/sljitNativeARM_v5.c 2011-10-07 19:18:55 UTC (rev 722)
@@ -400,7 +400,7 @@
diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)(code_ptr + 2));
}
- /* Branch to Thumb code has not optimized yet. */
+ /* Branch to Thumb code has not been optimized yet. */
if (diff & 0x3)
return 0;
@@ -426,7 +426,7 @@
diff = ((sljit_w)(code + jump->u.label->size) - (sljit_w)code_ptr);
}
- /* Branch to Thumb code has not optimized yet. */
+ /* Branch to Thumb code has not been optimized yet. */
if (diff & 0x3)
return 0;
@@ -2220,7 +2220,7 @@
/* In ARM, we don't need to touch the arguments. */
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (type >= SLJIT_CALL0)
+ if (type >= SLJIT_FAST_CALL)
PTR_FAIL_IF(prepare_blx(compiler));
PTR_FAIL_IF(push_inst_with_unique_literal(compiler, ((EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0,
type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0)) & ~COND_MASK) | get_cc(type), 0));
@@ -2230,7 +2230,7 @@
compiler->patches++;
}
- if (type >= SLJIT_CALL0) {
+ if (type >= SLJIT_FAST_CALL) {
jump->flags |= IS_BL;
PTR_FAIL_IF(emit_blx(compiler));
}
@@ -2238,10 +2238,10 @@
if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
jump->addr = compiler->size;
#else
- if (type >= SLJIT_CALL0)
+ if (type >= SLJIT_FAST_CALL)
jump->flags |= IS_BL;
PTR_FAIL_IF(emit_imm(compiler, TMP_REG1, 0));
- PTR_FAIL_IF(push_inst(compiler, (((type < SLJIT_CALL0 ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(type)));
+ PTR_FAIL_IF(push_inst(compiler, (((type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)) & ~COND_MASK) | get_cc(type)));
jump->addr = compiler->size;
#endif
return jump;
@@ -2258,18 +2258,18 @@
if (src & SLJIT_IMM) {
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
FAIL_IF(!jump);
- set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_CALL0) ? IS_BL : 0));
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_BL : 0));
jump->u.target = srcw;
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (type >= SLJIT_CALL0)
+ if (type >= SLJIT_FAST_CALL)
FAIL_IF(prepare_blx(compiler));
FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_DATA | LOAD_DATA, 1, 0, type <= SLJIT_JUMP ? TMP_PC : TMP_REG1, TMP_PC, 0), 0));
- if (type >= SLJIT_CALL0)
+ if (type >= SLJIT_FAST_CALL)
FAIL_IF(emit_blx(compiler));
#else
FAIL_IF(emit_imm(compiler, TMP_REG1, 0));
- FAIL_IF(push_inst(compiler, (type < SLJIT_CALL0 ? BX : BLX) | RM(TMP_REG1)));
+ FAIL_IF(push_inst(compiler, (type <= SLJIT_JUMP ? BX : BLX) | RM(TMP_REG1)));
#endif
jump->addr = compiler->size;
}
Modified: code/trunk/sljit/sljitNativeMIPS_common.c
===================================================================
--- code/trunk/sljit/sljitNativeMIPS_common.c 2011-10-07 15:51:39 UTC (rev 721)
+++ code/trunk/sljit/sljitNativeMIPS_common.c 2011-10-07 19:18:55 UTC (rev 722)
@@ -97,6 +97,7 @@
#define AND (HI(0) | LO(36))
#define ANDI (HI(12))
#define B (HI(4))
+#define BAL (HI(1) | (17 << 16))
#define BC1F (HI(17) | (8 << 21))
#define BC1T (HI(17) | (8 << 21) | (1 << 16))
#define BEQ (HI(4))
@@ -111,6 +112,7 @@
#define C_ULT_D (HI(17) | FMT_D | LO(53))
#define DIV_D (HI(17) | FMT_D | LO(3))
#define J (HI(2))
+#define JAL (HI(3))
#define JALR (HI(0) | LO(9))
#define JR (HI(0) | LO(8))
#define LD (HI(55))
@@ -199,7 +201,7 @@
sljit_ins *inst;
sljit_ins saved_inst;
- if (jump->flags & (SLJIT_REWRITABLE_JUMP | IS_JAL))
+ if (jump->flags & SLJIT_REWRITABLE_JUMP)
return code_ptr;
if (jump->flags & JUMP_ADDR)
@@ -220,7 +222,7 @@
if (!(jump->flags & IS_COND)) {
inst[0] = inst[-1];
- inst[-1] = B;
+ inst[-1] = (jump->flags & IS_JAL) ? BAL : B;
jump->addr -= sizeof(sljit_ins);
return inst;
}
@@ -237,7 +239,7 @@
jump->flags |= PATCH_B;
if (!(jump->flags & IS_COND)) {
- inst[0] = B;
+ inst[0] = (jump->flags & IS_JAL) ? BAL : B;
inst[1] = NOP;
return inst + 1;
}
@@ -265,7 +267,7 @@
if ((target_addr & ~0xfffffff) == (jump->addr & ~0xfffffff)) {
jump->flags |= PATCH_J;
inst[0] = inst[-1];
- inst[-1] = J;
+ inst[-1] = (jump->flags & IS_JAL) ? JAL : J;
jump->addr -= sizeof(sljit_ins);
return inst;
}
@@ -273,7 +275,7 @@
if ((target_addr & ~0xfffffff) == ((jump->addr + sizeof(sljit_ins)) & ~0xfffffff)) {
jump->flags |= PATCH_J;
- inst[0] = J;
+ inst[0] = (jump->flags & IS_JAL) ? JAL : J;
inst[1] = NOP;
return inst + 1;
}
@@ -1396,11 +1398,12 @@
jump->addr = compiler->size;
PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
} else {
- /* Cannot be optimized out. */
SLJIT_ASSERT(DR(PIC_ADDR_REG) == 25 && PIC_ADDR_REG == TMP_REG2);
- jump->flags |= IS_JAL;
+ /* Cannot be optimized out if type is >= CALL0. */
+ jump->flags |= IS_JAL | (type >= SLJIT_CALL0 ? SLJIT_REWRITABLE_JUMP : 0);
PTR_FAIL_IF(push_inst(compiler, JALR | S(TMP_REG2) | DA(RETURN_ADDR_REG), UNMOVABLE_INS));
jump->addr = compiler->size;
+ /* A NOP if type < CALL1. */
PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS));
}
return jump;
@@ -1596,7 +1599,7 @@
if (src & SLJIT_IMM) {
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
FAIL_IF(!jump);
- set_jump(jump, compiler, JUMP_ADDR);
+ set_jump(jump, compiler, JUMP_ADDR | ((type >= SLJIT_FAST_CALL) ? IS_JAL : 0));
jump->u.target = srcw;
if (compiler->delay_slot != UNMOVABLE_INS)
Modified: code/trunk/sljit/sljitNativePPC_common.c
===================================================================
--- code/trunk/sljit/sljitNativePPC_common.c 2011-10-07 15:51:39 UTC (rev 721)
+++ code/trunk/sljit/sljitNativePPC_common.c 2011-10-07 19:18:55 UTC (rev 722)
@@ -1612,7 +1612,7 @@
PTR_FAIL_IF(emit_const(compiler, TMP_REG1, 0));
PTR_FAIL_IF(push_inst(compiler, MTCTR | S(TMP_REG1)));
jump->addr = compiler->size;
- PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_CALL0 ? 1 : 0)));
+ PTR_FAIL_IF(push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0)));
return jump;
}
@@ -1647,7 +1647,7 @@
FAIL_IF(push_inst(compiler, MTCTR | S(src_r)));
if (jump)
jump->addr = compiler->size;
- return push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_CALL0 ? 1 : 0));
+ return push_inst(compiler, BCCTR | bo_bi_flags | (type >= SLJIT_FAST_CALL ? 1 : 0));
}
/* Get a bit from CR, all other bits are zeroed. */
Modified: code/trunk/sljit/sljitNativeX86_32.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_32.c 2011-10-07 15:51:39 UTC (rev 721)
+++ code/trunk/sljit/sljitNativeX86_32.c 2011-10-07 19:18:55 UTC (rev 722)
@@ -44,7 +44,7 @@
*code_ptr++ = 0xe9;
jump->addr++;
}
- else if (type >= SLJIT_CALL0) {
+ else if (type >= SLJIT_FAST_CALL) {
*code_ptr++ = 0xe8;
jump->addr++;
}
Modified: code/trunk/sljit/sljitNativeX86_64.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_64.c 2011-10-07 15:51:39 UTC (rev 721)
+++ code/trunk/sljit/sljitNativeX86_64.c 2011-10-07 19:18:55 UTC (rev 722)
@@ -59,7 +59,7 @@
code_ptr += sizeof(sljit_w);
*code_ptr++ = REX_B;
*code_ptr++ = 0xff;
- *code_ptr++ = (type >= SLJIT_CALL0) ? 0xd1 /* call */ : 0xe1 /* jmp */;
+ *code_ptr++ = (type >= SLJIT_FAST_CALL) ? 0xd1 /* call */ : 0xe1 /* jmp */;
return code_ptr;
}
Modified: code/trunk/sljit/sljitNativeX86_common.c
===================================================================
--- code/trunk/sljit/sljitNativeX86_common.c 2011-10-07 15:51:39 UTC (rev 721)
+++ code/trunk/sljit/sljitNativeX86_common.c 2011-10-07 19:18:55 UTC (rev 722)
@@ -245,7 +245,7 @@
*code_ptr++ = 0xe9;
jump->addr++;
}
- else if (type >= SLJIT_CALL0) {
+ else if (type >= SLJIT_FAST_CALL) {
short_jump = 0;
*code_ptr++ = 0xe8;
jump->addr++;
@@ -2436,7 +2436,7 @@
code = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
FAIL_IF(!code);
*code++ = 0xff;
- *code |= (type >= SLJIT_CALL0) ? (2 << 3) : (4 << 3);
+ *code |= (type >= SLJIT_FAST_CALL) ? (2 << 3) : (4 << 3);
}
return SLJIT_SUCCESS;
}