+static ir_mode *alloc_mode(const char *name, ir_mode_sort sort,
+ ir_mode_arithmetic arithmetic, unsigned bit_size,
+ int sign, unsigned modulo_shift)
+{
+ ir_mode *mode_tmpl = OALLOCZ(&modes, ir_mode);
+
+ mode_tmpl->name = new_id_from_str(name);
+ mode_tmpl->sort = sort;
+ mode_tmpl->size = bit_size;
+ mode_tmpl->sign = sign ? 1 : 0;
+ mode_tmpl->modulo_shift = modulo_shift;
+ mode_tmpl->arithmetic = arithmetic;
+ mode_tmpl->link = NULL;
+ mode_tmpl->tv_priv = NULL;
+ return mode_tmpl;
+}
+
+static ir_mode *register_mode(ir_mode *mode)
+{
+ /* does any of the existing modes have the same properties? */
+ ir_mode *old = find_mode(mode);
+ if (old != NULL) {
+ /* remove new mode from obstack */
+ obstack_free(&modes, mode);
+ return old;
+ }
+
+ mode->kind = k_ir_mode;
+ mode->type = new_type_primitive(mode);
+ ARR_APP1(ir_mode*, mode_list, mode);
+ set_mode_values(mode);
+ hook_new_mode(mode);
+ return mode;
+}
+
+ir_mode *new_int_mode(const char *name, ir_mode_arithmetic arithmetic,
+ unsigned bit_size, int sign, unsigned modulo_shift)
+{
+ ir_mode *result = alloc_mode(name, irms_int_number, arithmetic, bit_size,
+ sign, modulo_shift);
+ return register_mode(result);
+}
+
+ir_mode *new_reference_mode(const char *name, ir_mode_arithmetic arithmetic,
+ unsigned bit_size, unsigned modulo_shift)
+{
+ ir_mode *result = alloc_mode(name, irms_reference, arithmetic, bit_size,
+ 0, modulo_shift);
+ return register_mode(result);
+}
+
+ir_mode *new_float_mode(const char *name, ir_mode_arithmetic arithmetic,
+ unsigned exponent_size, unsigned mantissa_size)