Skip to content

Commit

Permalink
MIPS-JIT compiler fix: flags were not preserved for fast return.
Browse files Browse the repository at this point in the history
git-svn-id: svn:https://vcs.exim.org/pcre/code/trunk@1730 2f5784b3-3f2a-0410-8824-cb99058d5e15
  • Loading branch information
zherczeg committed Mar 19, 2018
1 parent c748e48 commit d16d457
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 13 deletions.
4 changes: 2 additions & 2 deletions sljit/sljitNativeMIPS_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
sljit_ins ins = NOP;
sljit_u8 offsets[4];

SLJIT_ASSERT(reg_map[TMP_REG3] == 4 && freg_map[TMP_FREG1] == 12);
SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12);

arg_types >>= SLJIT_DEF_SHIFT;

Expand Down Expand Up @@ -516,7 +516,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
else if (arg_count != word_arg_count)
ins = ADDU | S(word_arg_count) | TA(0) | DA(4 + (offsets[arg_count - 1] >> 2));
else if (arg_count == 1)
ins = ADDU | S(SLJIT_R0) | TA(0) | D(TMP_REG3);
ins = ADDU | S(SLJIT_R0) | TA(0) | DA(4);

arg_count--;
word_arg_count--;
Expand Down
4 changes: 2 additions & 2 deletions sljit/sljitNativeMIPS_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
sljit_ins prev_ins = NOP;
sljit_ins ins = NOP;

SLJIT_ASSERT(reg_map[TMP_REG3] == 4 && freg_map[TMP_FREG1] == 12);
SLJIT_ASSERT(reg_map[TMP_REG1] == 4 && freg_map[TMP_FREG1] == 12);

arg_types >>= SLJIT_DEF_SHIFT;

Expand Down Expand Up @@ -591,7 +591,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
if (arg_count != word_arg_count)
ins = DADDU | S(word_arg_count) | TA(0) | D(arg_count);
else if (arg_count == 1)
ins = DADDU | S(SLJIT_R0) | TA(0) | D(TMP_REG3);
ins = DADDU | S(SLJIT_R0) | TA(0) | DA(4);
arg_count--;
word_arg_count--;
break;
Expand Down
48 changes: 39 additions & 9 deletions sljit/sljitNativeMIPS_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ typedef sljit_u32 sljit_ins;
#define RETURN_ADDR_REG 31

/* Flags are kept in volatile registers. */
#define EQUAL_FLAG 31
#define EQUAL_FLAG 3
#define OTHER_FLAG 1

#define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1)
#define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2)

static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = {
0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 3, 25, 4
0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31
};

#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
Expand Down Expand Up @@ -612,16 +612,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
/* Frequent case. */
FAIL_IF(push_inst(compiler, ADDIU_W | S(SLJIT_SP) | T(SLJIT_SP) | IMM(-local_size), DR(SLJIT_SP)));
base = S(SLJIT_SP);
offs = local_size - (sljit_sw)sizeof(sljit_sw);
}
else {
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), local_size));
FAIL_IF(load_immediate(compiler, DR(OTHER_FLAG), local_size));
FAIL_IF(push_inst(compiler, ADDU_W | S(SLJIT_SP) | TA(0) | D(TMP_REG2), DR(TMP_REG2)));
FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(TMP_REG1) | D(SLJIT_SP), DR(SLJIT_SP)));
FAIL_IF(push_inst(compiler, SUBU_W | S(SLJIT_SP) | T(OTHER_FLAG) | D(SLJIT_SP), DR(SLJIT_SP)));
base = S(TMP_REG2);
local_size = 0;
offs = -(sljit_sw)sizeof(sljit_sw);
}

offs = local_size - (sljit_sw)(sizeof(sljit_sw));
FAIL_IF(push_inst(compiler, STACK_STORE | base | TA(RETURN_ADDR_REG) | IMM(offs), MOVABLE_INS));

tmp = saveds < SLJIT_NUMBER_OF_SAVED_REGISTERS ? (SLJIT_S0 + 1 - saveds) : SLJIT_FIRST_SAVED_REG;
Expand Down Expand Up @@ -805,7 +806,8 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
tmp_ar = reg_ar;
delay_slot = reg_ar;
} else {
}
else {
tmp_ar = DR(TMP_REG1);
delay_slot = MOVABLE_INS;
}
Expand Down Expand Up @@ -881,11 +883,39 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl

static SLJIT_INLINE sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg, sljit_sw argw)
{
sljit_s32 tmp_ar, base, delay_slot;

if (getput_arg_fast(compiler, flags, reg_ar, arg, argw))
return compiler->error;
compiler->cache_arg = 0;
compiler->cache_argw = 0;
return getput_arg(compiler, flags, reg_ar, arg, argw, 0, 0);

if ((flags & MEM_MASK) <= GPR_REG && (flags & LOAD_DATA)) {
tmp_ar = reg_ar;
delay_slot = reg_ar;
}
else {
tmp_ar = DR(TMP_REG1);
delay_slot = MOVABLE_INS;
}
base = arg & REG_MASK;

if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
argw &= 0x3;

if (SLJIT_UNLIKELY(argw)) {
FAIL_IF(push_inst(compiler, SLL_W | T(OFFS_REG(arg)) | DA(tmp_ar) | SH_IMM(argw), tmp_ar));
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | TA(tmp_ar) | DA(tmp_ar), tmp_ar));
}
else
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | T(OFFS_REG(arg)) | DA(tmp_ar), tmp_ar));
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
}

FAIL_IF(load_immediate(compiler, tmp_ar, argw));

if (base != 0)
FAIL_IF(push_inst(compiler, ADDU_W | S(base) | TA(tmp_ar) | DA(tmp_ar), tmp_ar));

return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar), delay_slot);
}

static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
Expand Down

0 comments on commit d16d457

Please sign in to comment.