Skip to content

Commit

Permalink
Implement return_to on mips, ppc, riscv
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoltan Herczeg committed Nov 8, 2022
1 parent e21f485 commit 8996588
Show file tree
Hide file tree
Showing 12 changed files with 176 additions and 76 deletions.
4 changes: 2 additions & 2 deletions sljit_src/sljitNativeARM_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1402,7 +1402,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c
FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src, srcw, TMP_REG1));
src = TMP_REG1;
srcw = 0;
} else if (src >= SLJIT_FIRST_SAVED_REG && src <= SLJIT_S0) {
} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src)));
src = TMP_REG1;
srcw = 0;
Expand Down Expand Up @@ -2924,7 +2924,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
src = TMP_REG1;
}

if ((type & SLJIT_CALL_RETURN) && (src >= SLJIT_FIRST_SAVED_REG && src <= SLJIT_S0)) {
if ((type & SLJIT_CALL_RETURN) && (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {
FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG1) | RM(src)));
src = TMP_REG1;
}
Expand Down
4 changes: 2 additions & 2 deletions sljit_src/sljitNativeARM_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -1244,7 +1244,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
src = TMP_REG1;
srcw = 0;
} else if (src >= SLJIT_FIRST_SAVED_REG && src <= SLJIT_S0) {
} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(src)));
src = TMP_REG1;
srcw = 0;
Expand Down Expand Up @@ -1969,7 +1969,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
}

if (type & SLJIT_CALL_RETURN) {
if (src >= SLJIT_FIRST_SAVED_REG && src <= SLJIT_S0) {
if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
FAIL_IF(push_inst(compiler, ORR | RD(TMP_REG1) | RN(TMP_ZERO) | RM(src)));
src = TMP_REG1;
}
Expand Down
4 changes: 2 additions & 2 deletions sljit_src/sljitNativeARM_T2_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1520,7 +1520,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *c
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src, srcw, TMP_REG1));
src = TMP_REG1;
srcw = 0;
} else if (src >= SLJIT_FIRST_SAVED_REG && src <= SLJIT_S0) {
} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, src)));
src = TMP_REG1;
srcw = 0;
Expand Down Expand Up @@ -2492,7 +2492,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
src = TMP_REG1;
}

if ((type & SLJIT_CALL_RETURN) && (src >= SLJIT_FIRST_SAVED_REG && src <= SLJIT_S0)) {
if ((type & SLJIT_CALL_RETURN) && (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options)))) {
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG1, src)));
src = TMP_REG1;
}
Expand Down
2 changes: 1 addition & 1 deletion sljit_src/sljitNativeMIPS_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi

if ((type & 0xff) == SLJIT_CALL_REG_ARG) {
if (type & SLJIT_CALL_RETURN) {
if (src >= SLJIT_FIRST_SAVED_REG && src <= SLJIT_S0) {
if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
FAIL_IF(push_inst(compiler, ADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
src = PIC_ADDR_REG;
srcw = 0;
Expand Down
2 changes: 1 addition & 1 deletion sljit_src/sljitNativeMIPS_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi

if ((type & 0xff) == SLJIT_CALL_REG_ARG) {
if (type & SLJIT_CALL_RETURN) {
if (src >= SLJIT_FIRST_SAVED_REG && src <= SLJIT_S0) {
if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
FAIL_IF(push_inst(compiler, DADDU | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
src = PIC_ADDR_REG;
srcw = 0;
Expand Down
45 changes: 41 additions & 4 deletions sljit_src/sljitNativeMIPS_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1007,12 +1007,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp
static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 frame_size, sljit_ins *ins_ptr)
{
sljit_s32 local_size, i, tmp, offset;
sljit_s32 load_return_addr = (frame_size == 0);
sljit_s32 scratches = compiler->scratches;
sljit_s32 saveds = compiler->saveds;
sljit_s32 fsaveds = compiler->fsaveds;
sljit_s32 fscratches = compiler->fscratches;
sljit_s32 kept_saveds_count = SLJIT_KEPT_SAVEDS_COUNT(compiler->options);

SLJIT_ASSERT(frame_size == 1 || (frame_size & 0xf) == 0);
frame_size &= ~0xf;

local_size = compiler->local_size;

tmp = GET_SAVED_REGISTERS_SIZE(scratches, saveds - kept_saveds_count, 1);
Expand Down Expand Up @@ -1043,7 +1047,7 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit
SLJIT_ASSERT(local_size >= frame_size);

offset = local_size - SSIZE_OF(sw);
if (frame_size == 0)
if (load_return_addr)
FAIL_IF(push_inst(compiler, LOAD_W | S(SLJIT_SP) | TA(RETURN_ADDR_REG) | IMM(offset), RETURN_ADDR_REG));

tmp = SLJIT_S0 - saveds;
Expand Down Expand Up @@ -1095,6 +1099,39 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler
return push_inst(compiler, ins, UNMOVABLE_INS);
}

SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
sljit_s32 src, sljit_sw srcw)
{
sljit_ins ins;

CHECK_ERROR();
CHECK(check_sljit_emit_return_to(compiler, src, srcw));

if (src & SLJIT_MEM) {
ADJUST_LOCAL_OFFSET(src, srcw);
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(PIC_ADDR_REG), src, srcw));
src = PIC_ADDR_REG;
srcw = 0;
} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | D(PIC_ADDR_REG), DR(PIC_ADDR_REG)));
src = PIC_ADDR_REG;
srcw = 0;
}

FAIL_IF(emit_stack_frame_release(compiler, 1, &ins));

if (!(src & SLJIT_IMM)) {
FAIL_IF(push_inst(compiler, JR | S(src), UNMOVABLE_INS));
return push_inst(compiler, ins, UNMOVABLE_INS);
}

if (ins != NOP)
FAIL_IF(push_inst(compiler, ins, MOVABLE_INS));

SLJIT_SKIP_CHECKS(compiler);
return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
}

/* --------------------------------------------------------------------- */
/* Operators */
/* --------------------------------------------------------------------- */
Expand Down Expand Up @@ -2848,7 +2885,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi

CHECK_ERROR();
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
ADJUST_LOCAL_OFFSET(src, srcw);

if (src & SLJIT_IMM) {
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
Expand All @@ -2860,8 +2896,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
jump->flags |= IS_MOVABLE;

src = TMP_REG2;
}
else if (src & SLJIT_MEM) {
} else if (src & SLJIT_MEM) {
ADJUST_LOCAL_OFFSET(src, srcw);
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), src, srcw));
src = TMP_REG2;
}
Expand All @@ -2881,6 +2917,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
compiler->size += 6;
#endif
}

FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
return SLJIT_SUCCESS;
}
Expand Down
55 changes: 41 additions & 14 deletions sljit_src/sljitNativePPC_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,9 @@ ALT_FORM5 0x010000 */

#define STACK_MAX_DISTANCE (0x8000 - SSIZE_OF(sw) - LR_SAVE_OFFSET)

static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 inp_flags, sljit_s32 reg,
sljit_s32 arg, sljit_sw argw, sljit_s32 tmp_reg);

SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
Expand Down Expand Up @@ -855,7 +858,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_set_context(struct sljit_compiler *comp
return SLJIT_SUCCESS;
}

static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler)
static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit_s32 is_return_to)
{
sljit_s32 i, tmp, base, offset;
sljit_s32 local_size = compiler->local_size;
Expand All @@ -873,7 +876,8 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler)
}

offset = local_size;
FAIL_IF(push_inst(compiler, STACK_LOAD | S(0) | A(base) | IMM(offset + LR_SAVE_OFFSET)));
if (!is_return_to)
FAIL_IF(push_inst(compiler, STACK_LOAD | S(0) | A(base) | IMM(offset + LR_SAVE_OFFSET)));

tmp = SLJIT_FS0 - compiler->fsaveds;
for (i = SLJIT_FS0; i > tmp; i--) {
Expand Down Expand Up @@ -902,7 +906,8 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler)
FAIL_IF(push_inst(compiler, STACK_LOAD | S(i) | A(base) | IMM(offset)));
}

push_inst(compiler, MTLR | S(0));
if (!is_return_to)
push_inst(compiler, MTLR | S(0));

if (local_size > 0)
return push_inst(compiler, ADDI | D(SLJIT_SP) | A(base) | IMM(local_size));
Expand All @@ -911,17 +916,40 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler)
return push_inst(compiler, OR | S(base) | A(SLJIT_SP) | B(base));
}

#undef STACK_STORE
#undef STACK_LOAD

SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_void(struct sljit_compiler *compiler)
{
CHECK_ERROR();
CHECK(check_sljit_emit_return_void(compiler));

FAIL_IF(emit_stack_frame_release(compiler));
FAIL_IF(emit_stack_frame_release(compiler, 0));
return push_inst(compiler, BLR);
}

#undef STACK_STORE
#undef STACK_LOAD
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return_to(struct sljit_compiler *compiler,
sljit_s32 src, sljit_sw srcw)
{
CHECK_ERROR();
CHECK(check_sljit_emit_return_to(compiler, src, srcw));

if (src & SLJIT_MEM) {
ADJUST_LOCAL_OFFSET(src, srcw);
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_CALL_REG, src, srcw, TMP_CALL_REG));
src = TMP_CALL_REG;
srcw = 0;
} else if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
src = TMP_CALL_REG;
srcw = 0;
}

FAIL_IF(emit_stack_frame_release(compiler, 1));

SLJIT_SKIP_CHECKS(compiler);
return sljit_emit_ijump(compiler, SLJIT_JUMP, src, srcw);
}

/* --------------------------------------------------------------------- */
/* Operators */
Expand Down Expand Up @@ -2194,7 +2222,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compile
#endif

if (type & SLJIT_CALL_RETURN) {
PTR_FAIL_IF(emit_stack_frame_release(compiler));
PTR_FAIL_IF(emit_stack_frame_release(compiler, 0));
type = SLJIT_JUMP | (type & SLJIT_REWRITABLE_JUMP);
}

Expand All @@ -2209,7 +2237,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi

CHECK_ERROR();
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
ADJUST_LOCAL_OFFSET(src, srcw);

if (FAST_IS_REG(src)) {
#if (defined SLJIT_PASS_ENTRY_ADDR_TO_CALL && SLJIT_PASS_ENTRY_ADDR_TO_CALL)
Expand All @@ -2236,9 +2263,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi

FAIL_IF(emit_const(compiler, TMP_CALL_REG, 0));
src_r = TMP_CALL_REG;
}
else {
FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
} else {
ADJUST_LOCAL_OFFSET(src, srcw);
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_CALL_REG, src, srcw, TMP_CALL_REG));
src_r = TMP_CALL_REG;
}

Expand All @@ -2257,17 +2284,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi

if (src & SLJIT_MEM) {
ADJUST_LOCAL_OFFSET(src, srcw);
FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, TMP_CALL_REG, 0, TMP_REG1, 0, src, srcw));
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_CALL_REG, src, srcw, TMP_CALL_REG));
src = TMP_CALL_REG;
}

if (type & SLJIT_CALL_RETURN) {
if (src >= SLJIT_FIRST_SAVED_REG && src <= SLJIT_S0) {
if (src >= SLJIT_FIRST_SAVED_REG && src <= (SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options))) {
FAIL_IF(push_inst(compiler, OR | S(src) | A(TMP_CALL_REG) | B(src)));
src = TMP_CALL_REG;
}

FAIL_IF(emit_stack_frame_release(compiler));
FAIL_IF(emit_stack_frame_release(compiler, 0));
type = SLJIT_JUMP;
}

Expand Down
Loading

0 comments on commit 8996588

Please sign in to comment.