+ assert(mode);
+ assert(mode_is_datab(mode));
+ return mode->all_one;
+}
+
+ir_tarval *get_mode_infinite(ir_mode *mode)
+{
+ assert(mode);
+ assert(mode_is_float(mode));
+
+ return get_tarval_plus_inf(mode);
+}
+
+ir_tarval *get_mode_NAN(ir_mode *mode)
+{
+ assert(mode);
+ assert(mode_is_float(mode));
+
+ return get_tarval_nan(mode);
+}
+
+int is_mode(const void *thing)
+{
+ return get_kind(thing) == k_ir_mode;
+}
+
+int (mode_is_signed)(const ir_mode *mode)
+{
+ return mode_is_signed_(mode);
+}
+
+int (mode_is_float)(const ir_mode *mode)
+{
+ return mode_is_float_(mode);
+}
+
+int (mode_is_int)(const ir_mode *mode)
+{
+ return mode_is_int_(mode);
+}
+
+int (mode_is_reference)(const ir_mode *mode)
+{
+ return mode_is_reference_(mode);
+}
+
+int (mode_is_num)(const ir_mode *mode)
+{
+ return mode_is_num_(mode);
+}
+
+int (mode_is_data)(const ir_mode *mode)
+{
+ return mode_is_data_(mode);
+}
+
+int (mode_is_datab)(const ir_mode *mode)
+{
+ return mode_is_datab_(mode);
+}
+
+int (mode_is_dataM)(const ir_mode *mode)
+{
+ return mode_is_dataM_(mode);
+}
+
+unsigned (get_mode_mantissa_size)(const ir_mode *mode)
+{
+ return get_mode_mantissa_size_(mode);
+}
+
+unsigned (get_mode_exponent_size)(const ir_mode *mode)
+{
+ return get_mode_exponent_size_(mode);
+}
+
+/* Returns true if sm can be converted to lm without loss. */
+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;
+}
+
+/* Returns true if a value of mode sm can be converted into mode lm
+ and backwards without loss. */
+int values_in_mode(const ir_mode *sm, const ir_mode *lm)
+{
+ ir_mode_arithmetic arith;
+
+ assert(sm);
+ assert(lm);
+
+ if (sm == lm) return 1;
+
+ if (sm == mode_b)
+ return mode_is_int(lm);
+
+ arith = get_mode_arithmetic(sm);
+ if (arith != get_mode_arithmetic(lm))
+ return 0;
+
+ switch (arith) {
+ case irma_twos_complement:
+ case irma_ieee754:
+ return get_mode_size_bits(sm) <= get_mode_size_bits(lm);
+
+ default:
+ return 0;
+ }
+}
+
+/* Return the signed integer equivalent mode for an reference mode. */
+ir_mode *get_reference_mode_signed_eq(ir_mode *mode)
+{
+ assert(mode_is_reference(mode));
+ return mode->eq_signed;
+}
+
+/* Sets the signed integer equivalent mode for an reference mode. */
+void set_reference_mode_signed_eq(ir_mode *ref_mode, ir_mode *int_mode)
+{
+ assert(mode_is_reference(ref_mode));
+ assert(mode_is_int(int_mode));
+ ref_mode->eq_signed = int_mode;
+}
+
+/* Return the unsigned integer equivalent mode for an reference mode. */
+ir_mode *get_reference_mode_unsigned_eq(ir_mode *mode)
+{
+ assert(mode_is_reference(mode));
+ return mode->eq_unsigned;
+}
+
+/* Sets the unsigned integer equivalent mode for an reference mode. */
+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;
+}
+
+static ir_mode *new_internal_mode(const char *name, ir_mode_sort sort)
+{
+ ir_mode *mode = alloc_mode(name, sort, irma_none, 0, 0, 0);
+ return register_mode(mode);
+}
+
+/* initialization, build the default modes */
+void init_mode(void)
+{
+ obstack_init(&modes);
+ mode_list = NEW_ARR_F(ir_mode*, 0);
+
+ /* initialize predefined modes */
+ mode_BB = new_internal_mode("BB", irms_block);
+ mode_X = new_internal_mode("X", irms_control_flow);
+ mode_M = new_internal_mode("M", irms_memory);
+ mode_T = new_internal_mode("T", irms_tuple);
+ mode_ANY = new_internal_mode("ANY", irms_any);
+ mode_BAD = new_internal_mode("BAD", irms_bad);
+ mode_b = new_internal_mode("b", irms_internal_boolean);
+
+ mode_F = new_float_mode("F", irma_ieee754, 8, 23);
+ mode_D = new_float_mode("D", irma_ieee754, 11, 52);
+ mode_Q = new_float_mode("Q", irma_ieee754, 15, 112);
+
+ mode_Bs = new_int_mode("Bs", irma_twos_complement, 8, 1, 32);
+ mode_Bu = new_int_mode("Bu", irma_twos_complement, 8, 0, 32);
+ mode_Hs = new_int_mode("Hs", irma_twos_complement, 16, 1, 32);
+ mode_Hu = new_int_mode("Hu", irma_twos_complement, 16, 0, 32);
+ mode_Is = new_int_mode("Is", irma_twos_complement, 32, 1, 32);
+ mode_Iu = new_int_mode("Iu", irma_twos_complement, 32, 0, 32);
+ mode_Ls = new_int_mode("Ls", irma_twos_complement, 64, 1, 64);
+ mode_Lu = new_int_mode("Lu", irma_twos_complement, 64, 0, 64);
+ mode_LLs = new_int_mode("LLs", irma_twos_complement, 128, 1, 128);
+ mode_LLu = new_int_mode("LLu", irma_twos_complement, 128, 0, 128);
+
+ mode_P = new_reference_mode("P", irma_twos_complement, 32, 32);
+ set_reference_mode_signed_eq(mode_P, mode_Is);
+ set_reference_mode_unsigned_eq(mode_P, mode_Iu);
+
+ /* set the machine specific modes to the predefined ones */
+ mode_P_code = mode_P;
+ mode_P_data = mode_P;
+}
+
+/* find a signed mode for an unsigned integer mode */
+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(n.sort == irms_int_number);
+ n.sign = 0;
+ return find_mode(&n);
+}
+
+/* find an unsigned mode for a signed integer mode */
+ir_mode *find_signed_mode(const ir_mode *mode)
+{
+ ir_mode n = *mode;
+
+ assert(mode->sort == irms_int_number);
+ n.sign = 1;
+ return find_mode(&n);
+}
+
+/* finds a integer mode with 2*n bits for an integer mode with n bits. */
+ir_mode *find_double_bits_int_mode(const ir_mode *mode)
+{
+ ir_mode n = *mode;
+
+ assert(mode->sort == irms_int_number && mode->arithmetic == irma_twos_complement);
+
+ n.size = 2*mode->size;
+ return find_mode(&n);