示例#1
0
int smaller_mode(const ir_mode *sm, const ir_mode *lm)
{
    assert(sm != NULL);
    assert(lm != NULL);
    if (sm == lm) return true;

    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 false;

            /* 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 signed and is at least one bit larger (the sign) */
            unsigned sm_bits = get_mode_size_bits(sm);
            unsigned lm_bits = get_mode_size_bits(lm);
            if (mode_is_signed(sm)) {
                if (!mode_is_signed(lm))
                    return false;
            } else {
                if (mode_is_signed(lm))
                    return sm_bits < lm_bits;
            }
            return sm_bits <= lm_bits;

        case irms_auxiliary:
        case irms_data:
        case irms_internal_boolean:
        case irms_reference:
        case irms_float_number:
            /* int to float works if the float is large enough */
            return false;
        }
        panic("invalid mode_sort");

    case irms_float_number:
        return get_mode_arithmetic(sm) == get_mode_arithmetic(lm)
               && mode_is_float(lm)
               && get_mode_size_bits(lm) >= get_mode_size_bits(sm);

    case irms_auxiliary:
    case irms_data:
    case irms_internal_boolean:
    case irms_reference:
        /* do exist machines out there with different pointer lengths ?*/
        return false;
    }

    panic("invalid mode_sort");
}
示例#2
0
文件: irmode.c 项目: qznc/libfirm
/**
 * sets special values of modes
 */
static void set_mode_values(ir_mode* mode)
{
    switch (get_mode_sort(mode))    {
    case irms_reference:
    case irms_int_number:
    case irms_float_number:
        mode->min  = get_tarval_min(mode);
        mode->max  = get_tarval_max(mode);
        mode->null = get_tarval_null(mode);
        mode->one  = get_tarval_one(mode);
        mode->minus_one = get_tarval_minus_one(mode);
        if (get_mode_sort(mode) != irms_float_number) {
            mode->all_one = get_tarval_all_one(mode);
        } else {
            mode->all_one = tarval_bad;
        }
        break;

    case irms_internal_boolean:
        mode->min  = tarval_b_false;
        mode->max  = tarval_b_true;
        mode->null = tarval_b_false;
        mode->one  = tarval_b_true;
        mode->minus_one = tarval_bad;
        mode->all_one = tarval_b_true;
        break;

    case irms_control_flow:
    case irms_block:
    case irms_tuple:
    case irms_any:
    case irms_bad:
    case irms_memory:
        mode->min  = tarval_bad;
        mode->max  = tarval_bad;
        mode->null = tarval_bad;
        mode->one  = tarval_bad;
        mode->minus_one = tarval_bad;
        break;
    }
}
示例#3
0
文件: irmode.c 项目: qznc/libfirm
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;
}