SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags()

in pcre/sljit/sljitNativePPC_common.c [2218:2357]


SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *compiler, sljit_s32 op,
	sljit_s32 dst, sljit_sw dstw,
	sljit_s32 src, sljit_sw srcw,
	sljit_s32 type)
{
	sljit_s32 reg, input_flags;
	sljit_s32 flags = GET_ALL_FLAGS(op);
	sljit_sw original_dstw = dstw;

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

	if (dst == SLJIT_UNUSED)
		return SLJIT_SUCCESS;

	op = GET_OPCODE(op);
	reg = (op < SLJIT_ADD && FAST_IS_REG(dst)) ? dst : TMP_REG2;

	compiler->cache_arg = 0;
	compiler->cache_argw = 0;
	if (op >= SLJIT_ADD && (src & SLJIT_MEM)) {
		ADJUST_LOCAL_OFFSET(src, srcw);
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
		input_flags = (flags & SLJIT_I32_OP) ? INT_DATA : WORD_DATA;
#else
		input_flags = WORD_DATA;
#endif
		FAIL_IF(emit_op_mem2(compiler, input_flags | LOAD_DATA, TMP_REG1, src, srcw, dst, dstw));
		src = TMP_REG1;
		srcw = 0;
	}

	switch (type & 0xff) {
	case SLJIT_EQUAL:
		GET_CR_BIT(2, reg);
		break;

	case SLJIT_NOT_EQUAL:
		GET_CR_BIT(2, reg);
		INVERT_BIT(reg);
		break;

	case SLJIT_LESS:
	case SLJIT_LESS_F64:
		GET_CR_BIT(4 + 0, reg);
		break;

	case SLJIT_GREATER_EQUAL:
	case SLJIT_GREATER_EQUAL_F64:
		GET_CR_BIT(4 + 0, reg);
		INVERT_BIT(reg);
		break;

	case SLJIT_GREATER:
	case SLJIT_GREATER_F64:
		GET_CR_BIT(4 + 1, reg);
		break;

	case SLJIT_LESS_EQUAL:
	case SLJIT_LESS_EQUAL_F64:
		GET_CR_BIT(4 + 1, reg);
		INVERT_BIT(reg);
		break;

	case SLJIT_SIG_LESS:
		GET_CR_BIT(0, reg);
		break;

	case SLJIT_SIG_GREATER_EQUAL:
		GET_CR_BIT(0, reg);
		INVERT_BIT(reg);
		break;

	case SLJIT_SIG_GREATER:
		GET_CR_BIT(1, reg);
		break;

	case SLJIT_SIG_LESS_EQUAL:
		GET_CR_BIT(1, reg);
		INVERT_BIT(reg);
		break;

	case SLJIT_OVERFLOW:
	case SLJIT_MUL_OVERFLOW:
		GET_CR_BIT(3, reg);
		break;

	case SLJIT_NOT_OVERFLOW:
	case SLJIT_MUL_NOT_OVERFLOW:
		GET_CR_BIT(3, reg);
		INVERT_BIT(reg);
		break;

	case SLJIT_EQUAL_F64:
		GET_CR_BIT(4 + 2, reg);
		break;

	case SLJIT_NOT_EQUAL_F64:
		GET_CR_BIT(4 + 2, reg);
		INVERT_BIT(reg);
		break;

	case SLJIT_UNORDERED_F64:
		GET_CR_BIT(4 + 3, reg);
		break;

	case SLJIT_ORDERED_F64:
		GET_CR_BIT(4 + 3, reg);
		INVERT_BIT(reg);
		break;

	default:
		SLJIT_ASSERT_STOP();
		break;
	}

	if (op < SLJIT_ADD) {
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
		if (op == SLJIT_MOV)
			input_flags = WORD_DATA;
		else {
			op = SLJIT_MOV_U32;
			input_flags = INT_DATA;
		}
#else
		op = SLJIT_MOV;
		input_flags = WORD_DATA;
#endif
		if (reg != TMP_REG2)
			return SLJIT_SUCCESS;
		return emit_op(compiler, op, input_flags, dst, dstw, TMP_REG1, 0, TMP_REG2, 0);
	}

#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
		|| (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
	compiler->skip_checks = 1;
#endif
	return sljit_emit_op2(compiler, op | flags, dst, original_dstw, src, srcw, TMP_REG2, 0);
}