예제 #1
0
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
{
    sljit_si size;
    sljit_ub *inst;

    CHECK_ERROR();
    CHECK(check_sljit_emit_return(compiler, op, src, srcw));
    SLJIT_ASSERT(compiler->args >= 0);

    compiler->flags_saved = 0;
    FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));

    SLJIT_ASSERT(compiler->local_size > 0);
    FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
        SLJIT_SP, 0, SLJIT_SP, 0, SLJIT_IMM, compiler->local_size));

#if !defined(__APPLE__)
    if (compiler->options & SLJIT_DOUBLE_ALIGNMENT) {
        inst = (sljit_ub*)ensure_buf(compiler, 1 + 3);
        FAIL_IF(!inst);

        INC_SIZE(3);
        inst[0] = MOV_r_rm;
        inst[1] = (reg_map[SLJIT_SP] << 3) | 0x4 /* SIB */;
        inst[2] = (4 << 3) | reg_map[SLJIT_SP];
    }
#endif

    size = 2 + (compiler->scratches > 7 ? (compiler->scratches - 7) : 0) +
        (compiler->saveds <= 3 ? compiler->saveds : 3);
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
    if (compiler->args > 2)
        size += 2;
#else
    if (compiler->args > 0)
        size += 2;
#endif
    inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
    FAIL_IF(!inst);

    INC_SIZE(size);

    if (compiler->saveds > 0 || compiler->scratches > 9)
        POP_REG(reg_map[SLJIT_S0]);
    if (compiler->saveds > 1 || compiler->scratches > 8)
        POP_REG(reg_map[SLJIT_S1]);
    if (compiler->saveds > 2 || compiler->scratches > 7)
        POP_REG(reg_map[SLJIT_S2]);
    POP_REG(reg_map[TMP_REG1]);
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
    if (compiler->args > 2)
        RET_I16(sizeof(sljit_sw));
    else
        RET();
#else
    RET();
#endif

    return SLJIT_SUCCESS;
}
예제 #2
0
int sljit_emit_return(struct sljit_compiler *compiler, int src, sljit_w srcw)
{
	int size;
	sljit_ub *buf;

	CHECK_ERROR();
	check_sljit_emit_return(compiler, src, srcw);
	SLJIT_ASSERT(compiler->args >= 0);

	compiler->flags_saved = 0;
	CHECK_EXTRA_REGS(src, srcw, (void)0);

	if (src != SLJIT_UNUSED && src != SLJIT_RETURN_REG)
		FAIL_IF(emit_mov(compiler, SLJIT_RETURN_REG, 0, src, srcw));

	if (compiler->local_size > 0)
		FAIL_IF(emit_cum_binary(compiler, 0x03, 0x01, 0x0 << 3, 0x05,
				SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));

	size = 2 + (compiler->generals <= 3 ? compiler->generals : 3);
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
	if (compiler->args > 2)
		size += 2;
#else
	if (compiler->args > 0)
		size += 2;
#endif
	buf = (sljit_ub*)ensure_buf(compiler, 1 + size);
	FAIL_IF(!buf);

	INC_SIZE(size);

	if (compiler->generals > 0)
		POP_REG(reg_map[SLJIT_GENERAL_REG1]);
	if (compiler->generals > 1)
		POP_REG(reg_map[SLJIT_GENERAL_REG2]);
	if (compiler->generals > 2)
		POP_REG(reg_map[SLJIT_GENERAL_REG3]);
	POP_REG(reg_map[TMP_REGISTER]);
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
	if (compiler->args > 2)
		RETN(sizeof(sljit_w));
	else
		RET();
#else
	if (compiler->args > 0)
		RETN(compiler->args * sizeof(sljit_w));
	else
		RET();
#endif

	return SLJIT_SUCCESS;
}
예제 #3
0
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_return(struct sljit_compiler *compiler, sljit_si op, sljit_si src, sljit_sw srcw)
{
	sljit_si size;
	sljit_ub *inst;

	CHECK_ERROR();
	check_sljit_emit_return(compiler, op, src, srcw);
	SLJIT_ASSERT(compiler->args >= 0);

	compiler->flags_saved = 0;
	FAIL_IF(emit_mov_before_return(compiler, op, src, srcw));

	SLJIT_ASSERT(compiler->local_size > 0);
	FAIL_IF(emit_cum_binary(compiler, ADD_r_rm, ADD_rm_r, ADD, ADD_EAX_i32,
		SLJIT_LOCALS_REG, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, compiler->local_size));

	size = 2 + (compiler->saveds <= 3 ? compiler->saveds : 3);
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
	if (compiler->args > 2)
		size += 2;
#else
	if (compiler->args > 0)
		size += 2;
#endif
	inst = (sljit_ub*)ensure_buf(compiler, 1 + size);
	FAIL_IF(!inst);

	INC_SIZE(size);

	if (compiler->saveds > 0)
		POP_REG(reg_map[SLJIT_SAVED_REG1]);
	if (compiler->saveds > 1)
		POP_REG(reg_map[SLJIT_SAVED_REG2]);
	if (compiler->saveds > 2)
		POP_REG(reg_map[SLJIT_SAVED_REG3]);
	POP_REG(reg_map[TMP_REGISTER]);
#if (defined SLJIT_X86_32_FASTCALL && SLJIT_X86_32_FASTCALL)
	if (compiler->args > 2)
		RET_I16(sizeof(sljit_sw));
	else
		RET();
#else
	if (compiler->args > 0)
		RET_I16(compiler->args * sizeof(sljit_sw));
	else
		RET();
#endif

	return SLJIT_SUCCESS;
}