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"); }
/** * 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; } }
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; }