SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1()

in pcre/sljit/sljitNativeARM_64.c [1278:1428]


SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compiler, sljit_s32 op,
	sljit_s32 dst, sljit_sw dstw,
	sljit_s32 src, sljit_sw srcw)
{
	sljit_s32 dst_r, flags, mem_flags;
	sljit_s32 op_flags = GET_ALL_FLAGS(op);

	CHECK_ERROR();
	CHECK(check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw));
	ADJUST_LOCAL_OFFSET(dst, dstw);
	ADJUST_LOCAL_OFFSET(src, srcw);

	compiler->cache_arg = 0;
	compiler->cache_argw = 0;

	dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG1;

	op = GET_OPCODE(op);
	if (op >= SLJIT_MOV && op <= SLJIT_MOVU_P) {
		switch (op) {
		case SLJIT_MOV:
		case SLJIT_MOV_P:
			flags = WORD_SIZE;
			break;
		case SLJIT_MOV_U8:
			flags = BYTE_SIZE;
			if (src & SLJIT_IMM)
				srcw = (sljit_u8)srcw;
			break;
		case SLJIT_MOV_S8:
			flags = BYTE_SIZE | SIGNED;
			if (src & SLJIT_IMM)
				srcw = (sljit_s8)srcw;
			break;
		case SLJIT_MOV_U16:
			flags = HALF_SIZE;
			if (src & SLJIT_IMM)
				srcw = (sljit_u16)srcw;
			break;
		case SLJIT_MOV_S16:
			flags = HALF_SIZE | SIGNED;
			if (src & SLJIT_IMM)
				srcw = (sljit_s16)srcw;
			break;
		case SLJIT_MOV_U32:
			flags = INT_SIZE;
			if (src & SLJIT_IMM)
				srcw = (sljit_u32)srcw;
			break;
		case SLJIT_MOV_S32:
			flags = INT_SIZE | SIGNED;
			if (src & SLJIT_IMM)
				srcw = (sljit_s32)srcw;
			break;
		case SLJIT_MOVU:
		case SLJIT_MOVU_P:
			flags = WORD_SIZE | UPDATE;
			break;
		case SLJIT_MOVU_U8:
			flags = BYTE_SIZE | UPDATE;
			if (src & SLJIT_IMM)
				srcw = (sljit_u8)srcw;
			break;
		case SLJIT_MOVU_S8:
			flags = BYTE_SIZE | SIGNED | UPDATE;
			if (src & SLJIT_IMM)
				srcw = (sljit_s8)srcw;
			break;
		case SLJIT_MOVU_U16:
			flags = HALF_SIZE | UPDATE;
			if (src & SLJIT_IMM)
				srcw = (sljit_u16)srcw;
			break;
		case SLJIT_MOVU_S16:
			flags = HALF_SIZE | SIGNED | UPDATE;
			if (src & SLJIT_IMM)
				srcw = (sljit_s16)srcw;
			break;
		case SLJIT_MOVU_U32:
			flags = INT_SIZE | UPDATE;
			if (src & SLJIT_IMM)
				srcw = (sljit_u32)srcw;
			break;
		case SLJIT_MOVU_S32:
			flags = INT_SIZE | SIGNED | UPDATE;
			if (src & SLJIT_IMM)
				srcw = (sljit_s32)srcw;
			break;
		default:
			SLJIT_ASSERT_STOP();
			flags = 0;
			break;
		}

		if (src & SLJIT_IMM)
			FAIL_IF(emit_op_imm(compiler, SLJIT_MOV | ARG2_IMM, dst_r, TMP_REG1, srcw));
		else if (src & SLJIT_MEM) {
			if (getput_arg_fast(compiler, flags, dst_r, src, srcw))
				FAIL_IF(compiler->error);
			else
				FAIL_IF(getput_arg(compiler, flags, dst_r, src, srcw, dst, dstw));
		} else {
			if (dst_r != TMP_REG1)
				return emit_op_imm(compiler, op | ((op_flags & SLJIT_I32_OP) ? INT_OP : 0), dst_r, TMP_REG1, src);
			dst_r = src;
		}

		if (dst & SLJIT_MEM) {
			if (getput_arg_fast(compiler, flags | STORE, dst_r, dst, dstw))
				return compiler->error;
			else
				return getput_arg(compiler, flags | STORE, dst_r, dst, dstw, 0, 0);
		}
		return SLJIT_SUCCESS;
	}

	flags = GET_FLAGS(op_flags) ? SET_FLAGS : 0;
	mem_flags = WORD_SIZE;
	if (op_flags & SLJIT_I32_OP) {
		flags |= INT_OP;
		mem_flags = INT_SIZE;
	}

	if (dst == SLJIT_UNUSED)
		flags |= UNUSED_RETURN;

	if (src & SLJIT_MEM) {
		if (getput_arg_fast(compiler, mem_flags, TMP_REG2, src, srcw))
			FAIL_IF(compiler->error);
		else
			FAIL_IF(getput_arg(compiler, mem_flags, TMP_REG2, src, srcw, dst, dstw));
		src = TMP_REG2;
	}

	if (src & SLJIT_IMM) {
		flags |= ARG2_IMM;
		if (op_flags & SLJIT_I32_OP)
			srcw = (sljit_s32)srcw;
	} else
		srcw = src;

	emit_op_imm(compiler, flags | op, dst_r, TMP_REG1, srcw);

	if (dst & SLJIT_MEM) {
		if (getput_arg_fast(compiler, mem_flags | STORE, dst_r, dst, dstw))
			return compiler->error;
		else
			return getput_arg(compiler, mem_flags | STORE, dst_r, dst, dstw, 0, 0);
	}
	return SLJIT_SUCCESS;
}