summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15>2011-09-22 10:44:35 +0000
committerzherczeg <zherczeg@2f5784b3-3f2a-0410-8824-cb99058d5e15>2011-09-22 10:44:35 +0000
commit4e19e57fe86d77826eb14db6bb3d9c5b1cf41237 (patch)
treeacba26d7f26973627243a552ff38ad18b0517170
parentdbc7a6926ec2ed732556f906824a6ddb946c31b3 (diff)
downloadpcre-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.c24
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));