diff options
author | zherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2011-09-22 10:44:35 +0000 |
---|---|---|
committer | zherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2011-09-22 10:44:35 +0000 |
commit | 4e19e57fe86d77826eb14db6bb3d9c5b1cf41237 (patch) | |
tree | acba26d7f26973627243a552ff38ad18b0517170 | |
parent | dbc7a6926ec2ed732556f906824a6ddb946c31b3 (diff) | |
download | pcre-4e19e57fe86d77826eb14db6bb3d9c5b1cf41237.tar.gz |
JIT compiler fix for MIPS position independent calls
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@705 2f5784b3-3f2a-0410-8824-cb99058d5e15
-rw-r--r-- | sljit/sljitNativeMIPS_common.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/sljit/sljitNativeMIPS_common.c b/sljit/sljitNativeMIPS_common.c index 799d06a..b4ca330 100644 --- a/sljit/sljitNativeMIPS_common.c +++ b/sljit/sljitNativeMIPS_common.c @@ -1560,14 +1560,27 @@ int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w check_sljit_emit_ijump(compiler, type, src, srcw); if (src >= SLJIT_TEMPORARY_REG1 && src <= SLJIT_NO_REGISTERS) { - if (DR(src) < 4 || DR(src) > 6) + if (DR(src) != 4) src_r = src; else FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(TMP_REG2), DR(TMP_REG2))); } - if (type >= SLJIT_CALL1) - FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), 4)); + if (type >= SLJIT_CALL0) { + if (src & SLJIT_IMM) { + FAIL_IF(load_immediate(compiler, 25, srcw)); + FAIL_IF(push_inst(compiler, JALR | SA(25) | DA(31), UNMOVABLE_INS)); + /* We need an extra instruction in any case. */ + return push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), UNMOVABLE_INS); + } + if (src & SLJIT_MEM) + FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); + + if (type >= SLJIT_CALL1) + FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_TEMPORARY_REG1) | TA(0) | DA(4), 4)); + FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(31), UNMOVABLE_INS)); + return push_inst(compiler, ADDU_W | S(src_r) | TA(0) | DA(25), UNMOVABLE_INS); + } if (src & SLJIT_IMM) { jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump)); @@ -1583,10 +1596,7 @@ int sljit_emit_ijump(struct sljit_compiler *compiler, int type, int src, sljit_w else if (src & SLJIT_MEM) FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_REG2, 0, TMP_REG1, 0, src, srcw)); - if (type <= SLJIT_JUMP) - FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS)); - else - FAIL_IF(push_inst(compiler, JALR | S(src_r) | DA(31), UNMOVABLE_INS)); + FAIL_IF(push_inst(compiler, JR | S(src_r), UNMOVABLE_INS)); if (jump) jump->addr = compiler->size; FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); |