+smaller_mode(ir_mode *sm, ir_mode *lm)
+{
+ ANNOUNCE();
+ assert(sm);
+ assert(lm);
+
+ if (sm == lm) return 1;
+
+ switch(get_mode_sort(sm))
+ {
+ case int_number:
+ switch(get_mode_sort(lm))
+ {
+ case int_number:
+ /* 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)
+ */
+ if (mode_is_signed(sm))
+ {
+ if ( mode_is_signed(lm) && (get_mode_size(lm) > get_mode_size(sm)) )
+ return 1;
+ }
+ else if (mode_is_signed(lm))
+ {
+ if (get_mode_size(lm) > get_mode_size(sm) + 1)
+ return 1;
+ }
+ else if (get_mode_size(lm) > get_mode_size(sm))
+ {
+ return 1;
+ }
+ break;
+
+ case float_number:
+ /* int to float works if the float is large enough */
+ return 0;
+
+ default:
+ break;
+ }
+ break;
+
+ case float_number:
+ /* XXX currently only the three standard 32,64,80 bit floats
+ * are supported which can safely be converted */
+ if ( (get_mode_sort(lm) == float_number)
+ && (get_mode_size(lm) > get_mode_size(sm)) )
+ return 1;
+ break;
+
+ case reference:
+ /* do exist machines out there with different pointer lenghts ?*/
+ return 0;
+
+ default:
+ break;
+ }
+
+ /* else */
+ return 0;
+}
+
+/** ** initialization ** **/
+void
+init_mode (void)
+{
+ ANNOUNCE();
+ /* init flexible array */
+ modes = NEW_ARR_F(ir_mode, irm_max);
+ modes_min = NEW_ARR_F(tarval*, irm_max);
+ modes_max = NEW_ARR_F(tarval*, irm_max);
+ modes_null = NEW_ARR_F(tarval*, irm_max);
+ modes_one = NEW_ARR_F(tarval*, irm_max);
+
+ /* initialize predefined modes */
+ /* Basic Block */
+ mode_BB = &modes[irm_BB];
+ mode_BB->name = id_from_str("BB", 2);
+ mode_BB->code = irm_BB;
+ mode_BB->sort = auxiliary;
+ mode_BB->sign = 0;
+
+ /* eXecution */
+ mode_X = &modes[irm_X];
+ mode_X->name = id_from_str("X", 1);
+ mode_X->code = irm_X;
+ mode_X->sort = auxiliary;
+ mode_X->sign = 0;
+
+ /* Memory */
+ mode_M = &modes[irm_M];
+ mode_M->name = id_from_str("M", 1);
+ mode_M->code = irm_M;
+ mode_M->sort = auxiliary;
+ mode_M->sign = 0;
+
+ /* Tuple */
+ mode_T = &modes[irm_T];
+ mode_T->name = id_from_str("T", 1);
+ mode_T->code = irm_T;
+ mode_T->sign = 0;
+
+ /* boolean */
+ mode_b = &modes[irm_b];
+ mode_b->name = id_from_str("b", 1);
+ mode_b->code = irm_b;
+ mode_b->sort = internal_boolean;
+ mode_b->sign = 0;
+
+ /* float */
+ mode_F = &modes[irm_F];
+ mode_F->name = id_from_str("F", 1);
+ mode_F->code = irm_F;
+ mode_F->sort = float_number;
+ mode_F->sign = 1;
+ mode_F->align = 32;
+ mode_F->size = 32;
+
+ set_mode_values(mode_F);
+
+ /* double */
+ mode_D = &modes[irm_D];
+ mode_D->name = id_from_str("D", 1);
+ mode_D->code = irm_D;
+ mode_D->sort = float_number;
+ mode_D->sign = 1;
+ mode_D->align = 32;
+ mode_D->size = 64;
+
+ set_mode_values(mode_D);
+
+ /* extended */
+ mode_E = &modes[irm_E];
+ mode_E->name = id_from_str("E", 1);
+ mode_E->code = irm_E;
+ mode_E->sort = float_number;
+ mode_E->sign = 1;
+ mode_E->align = 32;
+ mode_E->size = 80;
+
+ set_mode_values(mode_E);
+
+ /* signed byte */
+ mode_Bs = &modes[irm_Bs];
+ mode_Bs->name = id_from_str("Bs", 2);
+ mode_Bs->code = irm_Bs;
+ mode_Bs->sort = int_number;
+ mode_Bs->sign = 1;
+ mode_Bs->align = 8;
+ mode_Bs->size = 8;
+
+ set_mode_values(mode_Bs);
+
+ /* unsigned byte */
+ mode_Bu = &modes[irm_Bu];
+ mode_Bu->name = id_from_str("Bu", 2);
+ mode_Bu->code = irm_Bu;
+ mode_Bu->sort = int_number;
+ mode_Bu->sign = 0;
+ mode_Bu->align = 8;
+ mode_Bu->size = 8;
+
+ set_mode_values(mode_Bu);
+
+ /* signed short integer */
+ mode_Hs = &modes[irm_Hs];
+ mode_Hs->name = id_from_str("Hs", 2);
+ mode_Hs->code = irm_Hs;
+ mode_Hs->sort = int_number;
+ mode_Hs->sign = 1;
+ mode_Hs->align = 16;
+ mode_Hs->size = 16;
+
+ set_mode_values(mode_Hs);
+
+ /* unsigned short integer */
+ mode_Hu = &modes[irm_Hu];
+ mode_Hu->name = id_from_str("Hu", 2);
+ mode_Hu->code = irm_Hu;
+ mode_Hu->sort = int_number;
+ mode_Hu->sign = 0;
+ mode_Hu->align = 16;
+ mode_Hu->size = 16;
+
+ set_mode_values(mode_Hu);
+
+ /* signed integer */
+ mode_Is = &modes[irm_Is];
+ mode_Is->name = id_from_str("Is", 2);
+ mode_Is->code = irm_Is;
+ mode_Is->sort = int_number;
+ mode_Is->sign = 1;
+ mode_Is->align = 32;
+ mode_Is->size = 32;
+
+ set_mode_values(mode_Is);
+
+ /* unsigned integer */
+ mode_Iu = &modes[irm_Iu];
+ mode_Iu->name = id_from_str("Iu", 2);
+ mode_Iu->code = irm_Iu;
+ mode_Iu->sort = int_number;
+ mode_Iu->sign = 0;
+ mode_Iu->align = 32;
+ mode_Iu->size = 32;
+
+ set_mode_values(mode_Iu);
+
+ /* signed long integer */
+ mode_Ls = &modes[irm_Ls];
+ mode_Ls->name = id_from_str("Ls", 2);
+ mode_Ls->code = irm_Ls;
+ mode_Ls->sort = int_number;
+ mode_Ls->sign = 1;
+ mode_Ls->align = 32;
+ mode_Ls->size = 64;
+
+ set_mode_values(mode_Ls);
+
+ /* unsigned long integer */
+ mode_Lu = &modes[irm_Lu];
+ mode_Lu->name = id_from_str("Lu", 2);
+ mode_Lu->code = irm_Lu;
+ mode_Lu->sort = int_number;
+ mode_Lu->sign = 0;
+ mode_Lu->align = 32;
+ mode_Lu->size = 64;
+
+ set_mode_values(mode_Lu);
+
+ /* Character */
+ mode_C = &modes[irm_C];
+ mode_C->name = id_from_str("C", 1);
+ mode_C->code = irm_C;
+ mode_C->sort = character;
+ mode_C->sign = 0;
+ mode_C->align = 8;
+ mode_C->size = 8;
+
+ set_mode_values(mode_C);
+
+ /* Unicode character */
+ mode_U = &modes[irm_U];
+ mode_U->name = id_from_str("U", 1);
+ mode_U->code = irm_U;
+ mode_U->sort = character;
+ mode_U->sign = 0;
+ mode_U->align = 16;
+ mode_U->size = 16;
+
+ set_mode_values(mode_U);
+
+ /* pointer */
+ mode_P = &modes[irm_P];
+ mode_P->name = id_from_str("P", 1);
+ mode_P->code = irm_P;
+ mode_P->sort = reference;
+ mode_P->sign = 0;
+ mode_P->align = 32;
+ mode_P->size = 32;
+
+ num_modes = irm_max;