summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15>2011-10-07 19:18:55 +0000
committerzherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15>2011-10-07 19:18:55 +0000
commit280edf4c74c573c233ec15e7c63a467a13505931 (patch)
tree4bda06709dde3a04967069bd1a43b33e51a2ae8c
parentbecc86067b92d862b2e7cd076d51d017ed0c836a (diff)
downloadpcre-280edf4c74c573c233ec15e7c63a467a13505931.tar.gz
JIT compiler update: Make fast_call a separate call type. Allows call optimizations on MIPS.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@722 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r--sljit/sljitLir.c2
-rw-r--r--sljit/sljitLir.h10
-rw-r--r--sljit/sljitNativeARM_Thumb2.c17
-rw-r--r--sljit/sljitNativeARM_v5.c20
-rw-r--r--sljit/sljitNativeMIPS_common.c19
-rw-r--r--sljit/sljitNativePPC_common.c4
-rw-r--r--sljit/sljitNativeX86_32.c2
-rw-r--r--sljit/sljitNativeX86_64.c2
-rw-r--r--sljit/sljitNativeX86_common.c4
9 files changed, 38 insertions, 42 deletions
diff --git a/sljit/sljitLir.c b/sljit/sljitLir.c
index 844029e..dcc82c4 100644
--- a/sljit/sljitLir.c
+++ b/sljit/sljitLir.c
@@ -662,7 +662,7 @@ static char* jump_names[] = {
(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"
};
diff --git a/sljit/sljitLir.h b/sljit/sljitLir.h
index ddf775f..9502f14 100644
--- a/sljit/sljitLir.h
+++ b/sljit/sljitLir.h
@@ -573,13 +573,13 @@ struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler);
#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
diff --git a/sljit/sljitNativeARM_Thumb2.c b/sljit/sljitNativeARM_Thumb2.c
index de68d7b..9a7d6b9 100644
--- a/sljit/sljitNativeARM_Thumb2.c
+++ b/sljit/sljitNativeARM_Thumb2.c
@@ -1736,26 +1736,19 @@ int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w
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;
diff --git a/sljit/sljitNativeARM_v5.c b/sljit/sljitNativeARM_v5.c
index b1551df..075fefe 100644
--- a/sljit/sljitNativeARM_v5.c
+++ b/sljit/sljitNativeARM_v5.c
@@ -400,7 +400,7 @@ static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uw *code
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 @@ static SLJIT_INLINE int detect_jump_type(struct sljit_jump *jump, sljit_uw *code
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 @@ struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
/* 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 @@ struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
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 @@ struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
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 @@ int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w
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;
}
diff --git a/sljit/sljitNativeMIPS_common.c b/sljit/sljitNativeMIPS_common.c
index 4a34222..7c7df5f 100644
--- a/sljit/sljitNativeMIPS_common.c
+++ b/sljit/sljitNativeMIPS_common.c
@@ -97,6 +97,7 @@ typedef sljit_ui sljit_ins;
#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 @@ typedef sljit_ui sljit_ins;
#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 @@ static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins
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 @@ static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins
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 @@ static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins
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 @@ static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins
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 @@ static SLJIT_INLINE sljit_ins* optimize_jump(struct sljit_jump *jump, sljit_ins
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 @@ struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
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 @@ int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w
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)
diff --git a/sljit/sljitNativePPC_common.c b/sljit/sljitNativePPC_common.c
index 0ad1a35..d356af2 100644
--- a/sljit/sljitNativePPC_common.c
+++ b/sljit/sljitNativePPC_common.c
@@ -1612,7 +1612,7 @@ struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, int type)
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 @@ int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w
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. */
diff --git a/sljit/sljitNativeX86_32.c b/sljit/sljitNativeX86_32.c
index a1123cb..97e6ade 100644
--- a/sljit/sljitNativeX86_32.c
+++ b/sljit/sljitNativeX86_32.c
@@ -44,7 +44,7 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_
*code_ptr++ = 0xe9;
jump->addr++;
}
- else if (type >= SLJIT_CALL0) {
+ else if (type >= SLJIT_FAST_CALL) {
*code_ptr++ = 0xe8;
jump->addr++;
}
diff --git a/sljit/sljitNativeX86_64.c b/sljit/sljitNativeX86_64.c
index c41d15c..0ee34f0 100644
--- a/sljit/sljitNativeX86_64.c
+++ b/sljit/sljitNativeX86_64.c
@@ -59,7 +59,7 @@ static sljit_ub* generate_far_jump_code(struct sljit_jump *jump, sljit_ub *code_
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;
}
diff --git a/sljit/sljitNativeX86_common.c b/sljit/sljitNativeX86_common.c
index dd993e0..f86546e 100644
--- a/sljit/sljitNativeX86_common.c
+++ b/sljit/sljitNativeX86_common.c
@@ -245,7 +245,7 @@ static sljit_ub* generate_near_jump_code(struct sljit_jump *jump, sljit_ub *code
*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 @@ int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w
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;
}