static carry_result lower_sub_borrow(ir_node *left, ir_node *right, ir_mode *mode) { assert(!mode_is_signed(mode)); bitinfo *bi_left = get_bitinfo(left); if (!bi_left) { return can_carry; } bitinfo *bi_right = get_bitinfo(right); // If we have bitinfo for one node, we should also have it for // the other assert(bi_right); ir_tarval *lmin = tarval_convert_to(bitinfo_min(bi_left), mode); ir_tarval *rmin = tarval_convert_to(bitinfo_min(bi_right), mode); ir_tarval *lmax = tarval_convert_to(bitinfo_max(bi_left), mode); ir_tarval *rmax = tarval_convert_to(bitinfo_max(bi_right), mode); carry_result result = no_carry; int old_wrap_on_overflow = tarval_get_wrap_on_overflow(); tarval_set_wrap_on_overflow(false); if (tarval_sub(lmin, rmax) == tarval_bad) { result = can_carry; if (tarval_sub(lmax, rmin) == tarval_bad) { result = must_carry; } } tarval_set_wrap_on_overflow(old_wrap_on_overflow); return result; }
void init_constfold(void) { tarval_set_wrap_on_overflow(true); const backend_params *be_params = be_get_backend_param(); /* initialize modes for arithmetic types */ memset(atomic_modes, 0, sizeof(atomic_modes)); const ir_type *const type_ld = be_params->type_long_double; if (type_ld != NULL) atomic_modes[ATOMIC_TYPE_LONG_DOUBLE] = get_type_mode(type_ld); mode_float_arithmetic = be_params->mode_float_arithmetic; for (int i = 0; i <= ATOMIC_TYPE_LAST; ++i) { if (atomic_modes[i] != NULL) continue; atomic_modes[i] = init_atomic_ir_mode((atomic_type_kind_t) i); } }