Пример #1
0
static sljit_s32 emit_mov_int(struct sljit_compiler *compiler, sljit_s32 sign,
	sljit_s32 dst, sljit_sw dstw,
	sljit_s32 src, sljit_sw srcw)
{
	sljit_u8* inst;
	sljit_s32 dst_r;

	compiler->mode32 = 0;

	if (dst == SLJIT_UNUSED && !(src & SLJIT_MEM))
		return SLJIT_SUCCESS; /* Empty instruction. */

	if (src & SLJIT_IMM) {
		if (FAST_IS_REG(dst)) {
			if (sign || ((sljit_uw)srcw <= 0x7fffffff)) {
				inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);
				FAIL_IF(!inst);
				*inst = MOV_rm_i32;
				return SLJIT_SUCCESS;
			}
			return emit_load_imm64(compiler, dst, srcw);
		}
		compiler->mode32 = 1;
		inst = emit_x86_instruction(compiler, 1, SLJIT_IMM, (sljit_sw)(sljit_s32)srcw, dst, dstw);
		FAIL_IF(!inst);
		*inst = MOV_rm_i32;
		compiler->mode32 = 0;
		return SLJIT_SUCCESS;
	}

	dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;

	if ((dst & SLJIT_MEM) && FAST_IS_REG(src))
		dst_r = src;
	else {
		if (sign) {
			inst = emit_x86_instruction(compiler, 1, dst_r, 0, src, srcw);
			FAIL_IF(!inst);
			*inst++ = MOVSXD_r_rm;
		} else {
			compiler->mode32 = 1;
			FAIL_IF(emit_mov(compiler, dst_r, 0, src, srcw));
			compiler->mode32 = 0;
		}
	}

	if (dst & SLJIT_MEM) {
		compiler->mode32 = 1;
		inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
		FAIL_IF(!inst);
		*inst = MOV_rm_r;
		compiler->mode32 = 0;
	}

	return SLJIT_SUCCESS;
}
Пример #2
0
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_si dst, sljit_sw dstw)
{
    sljit_ub *inst;

    CHECK_ERROR();
    CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
    ADJUST_LOCAL_OFFSET(dst, dstw);

    CHECK_EXTRA_REGS(dst, dstw, (void)0);

    /* For UNUSED dst. Uncommon, but possible. */
    if (dst == SLJIT_UNUSED)
        dst = TMP_REG1;

    if (FAST_IS_REG(dst)) {
        /* Unused dest is possible here. */
        inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
        FAIL_IF(!inst);

        INC_SIZE(1);
        POP_REG(reg_map[dst]);
        return SLJIT_SUCCESS;
    }

    /* Memory. */
    inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
    FAIL_IF(!inst);
    *inst++ = POP_rm;
    return SLJIT_SUCCESS;
}
Пример #3
0
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_s32 src, sljit_sw srcw)
{
	sljit_u8 *inst;

	CHECK_ERROR();
	CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
	ADJUST_LOCAL_OFFSET(src, srcw);

	if ((src & SLJIT_IMM) && NOT_HALFWORD(srcw)) {
		FAIL_IF(emit_load_imm64(compiler, TMP_REG1, srcw));
		src = TMP_REG1;
	}

	if (FAST_IS_REG(src)) {
		if (reg_map[src] < 8) {
			inst = (sljit_u8*)ensure_buf(compiler, 1 + 1 + 1);
			FAIL_IF(!inst);

			INC_SIZE(1 + 1);
			PUSH_REG(reg_lmap[src]);
		}
		else {
			inst = (sljit_u8*)ensure_buf(compiler, 1 + 2 + 1);
			FAIL_IF(!inst);

			INC_SIZE(2 + 1);
			*inst++ = REX_B;
			PUSH_REG(reg_lmap[src]);
		}
	}
	else if (src & SLJIT_MEM) {
		/* REX_W is not necessary (src is not immediate). */
		compiler->mode32 = 1;
		inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
		FAIL_IF(!inst);
		*inst++ = GROUP_FF;
		*inst |= PUSH_rm;

		inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
		FAIL_IF(!inst);
		INC_SIZE(1);
	}
	else {
		SLJIT_ASSERT(IS_HALFWORD(srcw));
		/* SLJIT_IMM. */
		inst = (sljit_u8*)ensure_buf(compiler, 1 + 5 + 1);
		FAIL_IF(!inst);

		INC_SIZE(5 + 1);
		*inst++ = PUSH_i32;
		sljit_unaligned_store_s32(inst, srcw);
		inst += sizeof(sljit_s32);
	}

	RET();
	return SLJIT_SUCCESS;
}
Пример #4
0
SLJIT_API_FUNC_ATTRIBUTE sljit_si sljit_emit_fast_return(struct sljit_compiler *compiler, sljit_si src, sljit_sw srcw)
{
    sljit_ub *inst;

    CHECK_ERROR();
    CHECK(check_sljit_emit_fast_return(compiler, src, srcw));
    ADJUST_LOCAL_OFFSET(src, srcw);

    CHECK_EXTRA_REGS(src, srcw, (void)0);

    if (FAST_IS_REG(src)) {
        inst = (sljit_ub*)ensure_buf(compiler, 1 + 1 + 1);
        FAIL_IF(!inst);

        INC_SIZE(1 + 1);
        PUSH_REG(reg_map[src]);
    }
    else if (src & SLJIT_MEM) {
        inst = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);
        FAIL_IF(!inst);
        *inst++ = GROUP_FF;
        *inst |= PUSH_rm;

        inst = (sljit_ub*)ensure_buf(compiler, 1 + 1);
        FAIL_IF(!inst);
        INC_SIZE(1);
    }
    else {
        /* SLJIT_IMM. */
        inst = (sljit_ub*)ensure_buf(compiler, 1 + 5 + 1);
        FAIL_IF(!inst);

        INC_SIZE(5 + 1);
        *inst++ = PUSH_i32;
        *(sljit_sw*)inst = srcw;
        inst += sizeof(sljit_sw);
    }

    RET();
    return SLJIT_SUCCESS;
}
Пример #5
0
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fast_enter(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
{
	sljit_u8 *inst;

	CHECK_ERROR();
	CHECK(check_sljit_emit_fast_enter(compiler, dst, dstw));
	ADJUST_LOCAL_OFFSET(dst, dstw);

	/* For UNUSED dst. Uncommon, but possible. */
	if (dst == SLJIT_UNUSED)
		dst = TMP_REG1;

	if (FAST_IS_REG(dst)) {
		if (reg_map[dst] < 8) {
			inst = (sljit_u8*)ensure_buf(compiler, 1 + 1);
			FAIL_IF(!inst);
			INC_SIZE(1);
			POP_REG(reg_lmap[dst]);
			return SLJIT_SUCCESS;
		}

		inst = (sljit_u8*)ensure_buf(compiler, 1 + 2);
		FAIL_IF(!inst);
		INC_SIZE(2);
		*inst++ = REX_B;
		POP_REG(reg_lmap[dst]);
		return SLJIT_SUCCESS;
	}

	/* REX_W is not necessary (src is not immediate). */
	compiler->mode32 = 1;
	inst = emit_x86_instruction(compiler, 1, 0, 0, dst, dstw);
	FAIL_IF(!inst);
	*inst++ = POP_rm;
	return SLJIT_SUCCESS;
}