Ejemplo n.º 1
0
ir_mode *find_signed_mode(const ir_mode *mode)
{
    assert(mode_is_int(mode));
    ir_mode n = *mode;
    n.sign = 1;
    return find_mode(&n);
}
Ejemplo n.º 2
0
int values_in_mode(const ir_mode *sm, const ir_mode *lm)
{
    assert(sm != NULL);
    assert(lm != NULL);
    if (sm == lm)
        return true;

    if (sm == mode_b)
        return mode_is_int(lm) || mode_is_float(lm);

    ir_mode_arithmetic larith = get_mode_arithmetic(lm);
    ir_mode_arithmetic sarith = get_mode_arithmetic(sm);
    switch (larith) {
    case irma_x86_extended_float:
    case irma_ieee754:
        if (sarith == irma_ieee754 || sarith == irma_x86_extended_float) {
            return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
        } else if (sarith == irma_twos_complement) {
            unsigned int_mantissa
                = get_mode_size_bits(sm) - (mode_is_signed(sm) ? 1 : 0);
            unsigned float_mantissa = get_mode_mantissa_size(lm) + 1;
            return int_mantissa <= float_mantissa;
        }
        break;
    case irma_twos_complement:
        if (sarith == irma_twos_complement)
            return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
        break;
    case irma_none:
        break;
    }
    return false;
}
Ejemplo n.º 3
0
ir_mode *find_double_bits_int_mode(const ir_mode *mode)
{
    assert(mode_is_int(mode) && mode->arithmetic == irma_twos_complement);
    ir_mode n = *mode;
    n.size = 2*mode->size;
    if (n.modulo_shift != 0 && n.modulo_shift < n.size)
        n.modulo_shift = n.size;
    return find_mode(&n);
}
Ejemplo n.º 4
0
ir_mode *find_unsigned_mode(const ir_mode *mode)
{
    ir_mode n = *mode;

    /* allowed for reference mode */
    if (mode->sort == irms_reference)
        n.sort = irms_int_number;

    assert(mode_is_int(&n));
    n.sign = 0;
    return find_mode(&n);
}
Ejemplo n.º 5
0
static void amd64_emit_mode_suffix(const ir_mode *mode)
{
	assert(mode_is_int(mode) || mode_is_reference(mode));
	char c;
	switch (get_mode_size_bits(mode)) {
	case 8:  c = 'b'; break;
	case 16: c = 'w'; break;
	case 32: c = 'l'; break;
	case 64: c = 'q'; break;
	default:
		panic("Can't output mode_suffix for %+F", mode);
	}
	be_emit_char(c);
}
Ejemplo n.º 6
0
/*
 * Check, if the value of a node can be confirmed >= 0 or <= 0,
 * If the mode of the value did not honor signed zeros, else
 * check for >= 0 or < 0.
 */
ir_value_classify_sign classify_value_sign(ir_node *n)
{
	ir_tarval *tv, *c;
	ir_mode *mode;
	ir_relation cmp, ncmp;
	int negate = 1;

	for (;;) {
		unsigned code = get_irn_opcode(n);

		switch (code) {
		case iro_Minus:
			negate *= -1;
			n = get_Minus_op(n);
			continue;
		case iro_Confirm:
			break;
		default:
			return value_classified_unknown;
		}
		break;
	}
	if (!is_Confirm(n))
		return value_classified_unknown;

	tv  = value_of(get_Confirm_bound(n));
	if (tv == tarval_bad)
		return value_classified_unknown;

	mode = get_irn_mode(n);

	/*
	 * We can handle only >=, >, <, <= cases.
	 * We could handle == too, but this will be optimized into
	 * a constant either.
	 *
	 * Note that for integer modes we have a slightly better
	 * optimization possibilities, so we handle this
	 * different.
	 */
	cmp = get_Confirm_relation(n);

	switch (cmp) {
	case ir_relation_less:
		/*
		 * must be x < c <= 1 to be useful if integer mode and -0 = 0
		 *         x < c <= 0 to be useful else
		 */
	case ir_relation_less_equal:
		/*
		 * must be x <= c < 1 to be useful if integer mode and -0 = 0
		 *         x <= c < 0 to be useful else
		 */
		c = mode_is_int(mode) && mode_honor_signed_zeros(mode) ?
			get_mode_one(mode) : get_mode_null(mode);

		ncmp = tarval_cmp(tv, c);
		if (ncmp == ir_relation_equal)
			ncmp = ir_relation_less_equal;

		if (cmp != (ncmp ^ ir_relation_equal))
			return value_classified_unknown;

		/* yep, negative */
		return value_classified_negative * negate;

	case ir_relation_greater_equal:
		/*
		 * must be x >= c > -1 to be useful if integer mode
		 *         x >= c >= 0 to be useful else
		 */
	case ir_relation_greater:
		/*
		 * must be x > c >= -1 to be useful if integer mode
		 *         x > c >= 0 to be useful else
		 */
		if (mode_is_int(mode)) {
			c = get_mode_minus_one(mode);

			ncmp = tarval_cmp(tv, c);
			if (ncmp == ir_relation_equal)
				ncmp = ir_relation_greater_equal;

			if (cmp != (ncmp ^ ir_relation_equal))
				return value_classified_unknown;
		} else {
			c = get_mode_minus_one(mode);

			ncmp = tarval_cmp(tv, c);

			if (ncmp != ir_relation_equal && ncmp != ir_relation_greater)
				return value_classified_unknown;
		}

		/* yep, positive */
		return value_classified_positive * negate;

	default:
		return value_classified_unknown;
	}
}
Ejemplo n.º 7
0
void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *int_mode)
{
    assert(mode_is_reference(ref_mode));
    assert(mode_is_int(int_mode));
    ref_mode->eq_unsigned = int_mode;
}
Ejemplo n.º 8
0
int mode_wrap_around(const ir_mode *mode)
{
    /* FIXME: better would be an extra mode property */
    return mode_is_int(mode);
}
Ejemplo n.º 9
0
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
    int sm_bits, lm_bits;

    assert(sm);
    assert(lm);

    if (sm == lm) return 1;

    sm_bits = get_mode_size_bits(sm);
    lm_bits = get_mode_size_bits(lm);

    switch (get_mode_sort(sm)) {
    case irms_int_number:
        switch (get_mode_sort(lm)) {
        case irms_int_number:
            if (get_mode_arithmetic(sm) != get_mode_arithmetic(lm))
                return 0;

            /* only two complement implemented */
            assert(get_mode_arithmetic(sm) == irma_twos_complement);

            /* integers are convertable if
             *   - both have the same sign and lm is the larger one
             *   - lm is the signed one and is at least two bits larger
             *     (one for the sign, one for the highest bit of sm)
             *   - sm & lm are two_complement and lm has greater or equal number of bits
             */
            if (mode_is_signed(sm)) {
                if (!mode_is_signed(lm))
                    return 0;
                return sm_bits <= lm_bits;
            } else {
                if (mode_is_signed(lm)) {
                    return sm_bits < lm_bits;
                }
                return sm_bits <= lm_bits;
            }

        case irms_float_number:
            /* int to float works if the float is large enough */
            return 0;

        default:
            break;
        }
        break;

    case irms_float_number:
        if (get_mode_arithmetic(sm) == get_mode_arithmetic(lm)) {
            if ( (get_mode_sort(lm) == irms_float_number)
                    && (get_mode_size_bits(lm) >= get_mode_size_bits(sm)) )
                return 1;
        }
        break;

    case irms_reference:
        /* do exist machines out there with different pointer lengths ?*/
        return 0;

    case irms_internal_boolean:
        return mode_is_int(lm);

    default:
        break;
    }

    /* else */
    return 0;
}