diff options
author | zherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2011-10-07 19:18:55 +0000 |
---|---|---|
committer | zherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2011-10-07 19:18:55 +0000 |
commit | 280edf4c74c573c233ec15e7c63a467a13505931 (patch) | |
tree | 4bda06709dde3a04967069bd1a43b33e51a2ae8c | |
parent | becc86067b92d862b2e7cd076d51d017ed0c836a (diff) | |
download | pcre-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.c | 2 | ||||
-rw-r--r-- | sljit/sljitLir.h | 10 | ||||
-rw-r--r-- | sljit/sljitNativeARM_Thumb2.c | 17 | ||||
-rw-r--r-- | sljit/sljitNativeARM_v5.c | 20 | ||||
-rw-r--r-- | sljit/sljitNativeMIPS_common.c | 19 | ||||
-rw-r--r-- | sljit/sljitNativePPC_common.c | 4 | ||||
-rw-r--r-- | sljit/sljitNativeX86_32.c | 2 | ||||
-rw-r--r-- | sljit/sljitNativeX86_64.c | 2 | ||||
-rw-r--r-- | sljit/sljitNativeX86_common.c | 4 |
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; } |