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); }
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; }
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); }
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); }
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); }
/* * 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; } }
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; }
int mode_wrap_around(const ir_mode *mode) { /* FIXME: better would be an extra mode property */ return mode_is_int(mode); }
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; }