Commit 5f0018d1 authored by Matthias Braun's avatar Matthias Braun
Browse files

irmode: cleanup, add new_non_arithmetic_mode() function

We combine all non-arithmetic modes into irms_auxiliary (two auxiliary
nodes are considered equal iff they have the same name).
parent 86de8b94
......@@ -35,8 +35,7 @@
*/
typedef enum ir_mode_arithmetic {
irma_none = 1, /**< For modes for which no representation is
specified. These are modes of sort auxiliary,
internal_boolean and character. */
specified. */
irma_twos_complement = 2, /**< Values of the mode are represented as two's
complement. Only legal for modes of sort
int_number and reference. */
......@@ -93,6 +92,12 @@ FIRM_API ir_mode *new_float_mode(const char *name,
unsigned exponent_size,
unsigned mantissa_size);
/**
* Creates a new mode for data values which are not used to perform arithmetic.
* Arithmetic will be set to irma_none.
*/
FIRM_API ir_mode *new_non_arithmetic_mode(const char *name);
/**
* Checks whether a pointer points to a mode.
*
......
......@@ -30,8 +30,11 @@ static ir_mode **mode_list;
static bool modes_are_equal(const ir_mode *m, const ir_mode *n)
{
return m->sort == n->sort &&
m->arithmetic == n->arithmetic &&
if (m->sort != n->sort)
return false;
if (m->sort == irms_auxiliary || m->sort == irms_data)
return strcmp(m->name, n->name) == 0;
return m->arithmetic == n->arithmetic &&
m->size == n->size &&
m->sign == n->sign &&
m->modulo_shift == n->modulo_shift;
......@@ -82,12 +85,8 @@ static void set_mode_values(ir_mode* mode)
mode->all_one = tarval_b_true;
break;
case irms_control_flow:
case irms_block:
case irms_tuple:
case irms_any:
case irms_bad:
case irms_memory:
case irms_auxiliary:
case irms_data:
mode->min = tarval_bad;
mode->max = tarval_bad;
mode->null = tarval_bad;
......@@ -249,6 +248,18 @@ ir_mode *new_float_mode(const char *name, ir_mode_arithmetic arithmetic,
return register_mode(result);
}
ir_mode *new_non_arithmetic_mode(const char *name)
{
ir_mode *result = alloc_mode(name, irms_data, irma_none, 0, 0, 0);
return register_mode(result);
}
static ir_mode *new_non_data_mode(const char *name)
{
ir_mode *result = alloc_mode(name, irms_auxiliary, irma_none, 0, 0, 0);
return register_mode(result);
}
ident *(get_mode_ident)(const ir_mode *mode)
{
return get_mode_ident_(mode);
......@@ -431,36 +442,30 @@ int smaller_mode(const ir_mode *sm, const ir_mode *lm)
return sm_bits <= lm_bits;
}
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
case irms_reference:
case irms_float_number:
/* int to float works if the float is large enough */
return false;
default:
break;
}
break;
panic("invalid mode_sort");
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 true;
}
break;
return get_mode_arithmetic(sm) == get_mode_arithmetic(lm)
&& get_mode_sort(lm) == irms_float_number
&& get_mode_size_bits(lm) >= get_mode_size_bits(sm);
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
case irms_reference:
/* do exist machines out there with different pointer lengths ?*/
return false;
case irms_internal_boolean:
return mode_is_int(lm);
default:
break;
}
/* else */
return false;
panic("invalid mode_sort");
}
int values_in_mode(const ir_mode *sm, const ir_mode *lm)
......@@ -523,25 +528,20 @@ void set_reference_mode_unsigned_eq(ir_mode *ref_mode, ir_mode *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);
}
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_BB = new_non_data_mode("BB");
mode_X = new_non_data_mode("X");
mode_M = new_non_data_mode("M");
mode_T = new_non_data_mode("T");
mode_ANY = new_non_data_mode("ANY");
mode_BAD = new_non_data_mode("BAD");
mode_b = alloc_mode("b", irms_internal_boolean, irma_none, 0, 0, 0);
mode_b = register_mode(mode_b);
mode_F = new_float_mode("F", irma_ieee754, 8, 23);
mode_D = new_float_mode("D", irma_ieee754, 11, 52);
......
......@@ -93,30 +93,21 @@ enum ir_mode_sort_helper {
/**
* These values represent the different mode classes of value representations.
* Beware: do not change the order of these values without checking
* the mode_is
*/
typedef enum ir_mode_sort {
irms_control_flow = 0, /**< Marks all control flow modes. */
irms_block = 1,
irms_tuple = 2,
irms_any = 3,
irms_bad = 4,
irms_memory = 5,
/** Internal boolean representation.
Storing to memory impossible, convert first. (irm_b) */
irms_internal_boolean = 6,
irms_auxiliary = 0,
irms_internal_boolean = 1 | irmsh_is_data,
irms_data = 2 | irmsh_is_data,
/** A mode to represent entities.
Restricted int computations can be performed */
irms_reference = 7 | irmsh_is_data,
irms_reference = 3 | irmsh_is_data,
/** A mode to represent int numbers.
Integer computations can be performed. */
irms_int_number = 8 | irmsh_is_data | irmsh_is_num,
irms_int_number = 4 | irmsh_is_data | irmsh_is_num,
/** A mode to represent float numbers.
Floating point computations can be performed. */
irms_float_number = 9 | irmsh_is_data | irmsh_is_num,
irms_float_number = 5 | irmsh_is_data | irmsh_is_num,
} ir_mode_sort;
/**
......
......@@ -464,9 +464,6 @@ ir_tarval *(get_tarval_unreachable)(void)
ir_tarval *get_tarval_max(ir_mode *mode)
{
switch (get_mode_sort(mode)) {
case irms_internal_boolean:
return tarval_b_true;
case irms_float_number: {
const float_descriptor_t *desc = get_descriptor(mode);
fc_get_max(desc, NULL);
......@@ -477,17 +474,20 @@ ir_tarval *get_tarval_max(ir_mode *mode)
case irms_int_number:
sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
default:
case irms_internal_boolean:
return tarval_b_true;
case irms_auxiliary:
case irms_data:
panic("mode %F does not support maximum value", mode);
}
panic("invalid mode sort");
}
ir_tarval *get_tarval_min(ir_mode *mode)
{
switch (get_mode_sort(mode)) {
case irms_internal_boolean:
return tarval_b_false;
case irms_float_number: {
const float_descriptor_t *desc = get_descriptor(mode);
fc_get_min(desc, NULL);
......@@ -498,9 +498,15 @@ ir_tarval *get_tarval_min(ir_mode *mode)
case irms_int_number:
sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode), NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode);
default:
case irms_internal_boolean:
return tarval_b_false;
case irms_auxiliary:
case irms_data:
panic("mode %F does not support minimum value", mode);
}
panic("invalid mode sort");
}
/** The bit pattern for the pointer NULL */
......@@ -512,48 +518,60 @@ ir_tarval *get_tarval_null(ir_mode *mode)
case irms_float_number:
return new_tarval_from_double(0.0, mode);
case irms_internal_boolean:
case irms_int_number:
return new_tarval_from_long(0l, mode);
case irms_reference:
return new_tarval_from_long(_null_value, mode);
default:
case irms_internal_boolean:
return tarval_b_false;
case irms_auxiliary:
case irms_data:
panic("mode %F does not support null value", mode);
}
panic("invalid mode sort");
}
ir_tarval *get_tarval_one(ir_mode *mode)
{
switch (get_mode_sort(mode)) {
case irms_internal_boolean:
return tarval_b_true;
case irms_float_number:
return new_tarval_from_double(1.0, mode);
case irms_reference:
case irms_int_number:
return new_tarval_from_long(1l, mode);
default:
case irms_internal_boolean:
return tarval_b_true;
case irms_auxiliary:
case irms_data:
panic("mode %F does not support one value", mode);
}
panic("invalid mode sort");
}
ir_tarval *get_tarval_all_one(ir_mode *mode)
{
switch (get_mode_sort(mode)) {
case irms_int_number:
case irms_internal_boolean:
case irms_reference:
return tarval_not(get_mode_null(mode));
case irms_internal_boolean:
return tarval_b_true;
case irms_float_number:
return tarval_bad;
default:
case irms_auxiliary:
case irms_data:
panic("mode %F does not support all-one value", mode);
}
panic("invalid mode sort");
}
int tarval_is_constant(ir_tarval *tv)
......@@ -566,6 +584,7 @@ ir_tarval *get_tarval_minus_one(ir_mode *mode)
{
switch (get_mode_sort(mode)) {
case irms_reference:
case irms_internal_boolean:
return tarval_bad;
case irms_float_number:
......@@ -574,40 +593,38 @@ ir_tarval *get_tarval_minus_one(ir_mode *mode)
case irms_int_number:
return new_tarval_from_long(-1l, mode);
default:
case irms_auxiliary:
case irms_data:
panic("mode %F does not support minus one value", mode);
}
panic("invalid mode sort");
}
ir_tarval *get_tarval_nan(ir_mode *mode)
{
if (get_mode_sort(mode) == irms_float_number) {
const float_descriptor_t *desc = get_descriptor(mode);
fc_get_qnan(desc, NULL);
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
} else {
if (get_mode_sort(mode) != irms_float_number)
panic("mode %F does not support NaN value", mode);
}
const float_descriptor_t *desc = get_descriptor(mode);
fc_get_qnan(desc, NULL);
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
}
ir_tarval *get_tarval_plus_inf(ir_mode *mode)
{
if (get_mode_sort(mode) == irms_float_number) {
const float_descriptor_t *desc = get_descriptor(mode);
fc_get_plusinf(desc, NULL);
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
} else
if (get_mode_sort(mode) != irms_float_number)
panic("mode %F does not support +inf value", mode);
const float_descriptor_t *desc = get_descriptor(mode);
fc_get_plusinf(desc, NULL);
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
}
ir_tarval *get_tarval_minus_inf(ir_mode *mode)
{
if (get_mode_sort(mode) == irms_float_number) {
const float_descriptor_t *desc = get_descriptor(mode);
fc_get_minusinf(desc, NULL);
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
} else
if (get_mode_sort(mode) != irms_float_number)
panic("mode %F does not support -inf value", mode);
const float_descriptor_t *desc = get_descriptor(mode);
fc_get_minusinf(desc, NULL);
return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode);
}
/*
......@@ -618,6 +635,7 @@ int tarval_is_negative(ir_tarval *a)
{
switch (get_mode_sort(a->mode)) {
case irms_int_number:
case irms_reference:
if (!mode_is_signed(a->mode)) {
return 0;
} else {
......@@ -627,9 +645,12 @@ int tarval_is_negative(ir_tarval *a)
case irms_float_number:
return fc_is_negative((const fp_value*) a->value);
default:
case irms_auxiliary:
case irms_internal_boolean:
case irms_data:
panic("mode %F does not support negation value", a->mode);
}
panic("invalid mode sort");
}
int tarval_is_null(ir_tarval *a)
......@@ -737,11 +758,6 @@ ir_tarval *tarval_convert_to(ir_tarval *src, ir_mode *dst_mode)
return get_tarval_overflow(buffer, src->length, dst_mode);
}
case irms_internal_boolean:
/* XXX C semantics */
if (src == get_mode_null(src->mode)) return tarval_b_false;
else return tarval_b_true;
case irms_float_number: {
/* XXX floating point unit does not understand internal integer
* representation, convert to string first, then create float from
......@@ -756,17 +772,13 @@ ir_tarval *tarval_convert_to(ir_tarval *src, ir_mode *dst_mode)
fp_value *val = fc_val_from_str(buffer, len, NULL);
return get_tarval_from_fp_value(val, dst_mode);
}
default:
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
break;
}
break;
case irms_internal_boolean:
/* beware: this is C semantic for the INTERNAL boolean mode */
if (get_mode_sort(dst_mode) == irms_int_number)
return src == tarval_b_true ? get_mode_one(dst_mode) : get_mode_null(dst_mode);
break;
case irms_reference:
if (get_mode_sort(dst_mode) == irms_int_number) {
char *buffer = ALLOCAN(char, sc_get_buffer_length());
......@@ -775,7 +787,10 @@ ir_tarval *tarval_convert_to(ir_tarval *src, ir_mode *dst_mode)
return get_tarval_overflow(buffer, src->length, dst_mode);
}
break;
default:
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
return tarval_bad;
}
......@@ -799,9 +814,12 @@ ir_tarval *tarval_not(ir_tarval *a)
return tarval_b_true;
return tarval_bad;
default:
case irms_auxiliary:
case irms_data:
case irms_float_number:
panic("bitwise negation is only allowed for integer and boolean");
}
panic("invalid mode sort");
}
ir_tarval *tarval_neg(ir_tarval *a)
......@@ -811,7 +829,8 @@ ir_tarval *tarval_neg(ir_tarval *a)
/* note: negation is allowed even for unsigned modes. */
switch (get_mode_sort(a->mode)) {
case irms_int_number: {
case irms_int_number:
case irms_reference: {
char *buffer = ALLOCAN(char, sc_get_buffer_length());
sc_neg(a->value, buffer);
return get_tarval_overflow(buffer, a->length, a->mode);
......@@ -821,9 +840,12 @@ ir_tarval *tarval_neg(ir_tarval *a)
fc_neg((const fp_value*) a->value, NULL);
return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
default:
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
return tarval_bad;
}
panic("invalid mode sort");
}
ir_tarval *tarval_add(ir_tarval *a, ir_tarval *b)
......@@ -849,9 +871,12 @@ ir_tarval *tarval_add(ir_tarval *a, ir_tarval *b)
fc_add((const fp_value*) a->value, (const fp_value*) b->value, NULL);
return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
default:
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
return tarval_bad;
}
panic("invalid mode sort");
}
ir_tarval *tarval_sub(ir_tarval *a, ir_tarval *b, ir_mode *dst_mode)
......@@ -877,9 +902,12 @@ ir_tarval *tarval_sub(ir_tarval *a, ir_tarval *b, ir_mode *dst_mode)
fc_sub((const fp_value*) a->value, (const fp_value*) b->value, NULL);
return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
default:
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
return tarval_bad;
}
panic("invalid mode sort");
}
ir_tarval *tarval_mul(ir_tarval *a, ir_tarval *b)
......@@ -887,7 +915,8 @@ ir_tarval *tarval_mul(ir_tarval *a, ir_tarval *b)
assert(a->mode == b->mode);
switch (get_mode_sort(a->mode)) {
case irms_int_number: {
case irms_int_number:
case irms_reference: {
/* modes of a,b are equal */
char *buffer = ALLOCAN(char, sc_get_buffer_length());
sc_mul(a->value, b->value, buffer);
......@@ -898,9 +927,12 @@ ir_tarval *tarval_mul(ir_tarval *a, ir_tarval *b)
fc_mul((const fp_value*) a->value, (const fp_value*) b->value, NULL);
return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode);
default:
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
return tarval_bad;
}
panic("invalid mode sort");
}
ir_tarval *tarval_div(ir_tarval *a, ir_tarval *b)
......@@ -922,9 +954,12 @@ ir_tarval *tarval_div(ir_tarval *a, ir_tarval *b)
fc_div((const fp_value*) a->value, (const fp_value*) b->value, NULL);
return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), mode);
default:
return tarval_bad;
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
panic("operation not defined on mode");
}
panic("invalid mode sort");
}
ir_tarval *tarval_mod(ir_tarval *a, ir_tarval *b)
......@@ -941,9 +976,13 @@ ir_tarval *tarval_mod(ir_tarval *a, ir_tarval *b)
sc_mod(a->value, b->value, NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
default:
return tarval_bad;
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
case irms_float_number:
panic("operation not defined on mode");
}
panic("invalid mode sort");
}
ir_tarval *tarval_divmod(ir_tarval *a, ir_tarval *b, ir_tarval **mod)
......@@ -964,10 +1003,15 @@ ir_tarval *tarval_divmod(ir_tarval *a, ir_tarval *b, ir_tarval **mod)
sc_divmod(a->value, b->value, div_res, mod_res);
*mod = get_tarval(mod_res, len, a->mode);
return get_tarval(div_res, len, a->mode);
}
default:
return tarval_bad;
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
case irms_float_number:
panic("operation not defined on mode");
}
panic("invalid mode sort");
}
ir_tarval *tarval_abs(ir_tarval *a)
......@@ -976,6 +1020,7 @@ ir_tarval *tarval_abs(ir_tarval *a)
switch (get_mode_sort(a->mode)) {
case irms_int_number:
case irms_reference:
if (sc_comp(a->value, get_mode_null(a->mode)->value) == ir_relation_less) {
char *buffer = ALLOCAN(char, sc_get_buffer_length());
sc_neg(a->value, buffer);
......@@ -990,10 +1035,12 @@ ir_tarval *tarval_abs(ir_tarval *a)
}
return a;
default:
break;
case irms_auxiliary:
case irms_data:
case irms_internal_boolean:
panic("operation not defined on mode");
}
return tarval_bad;
panic("invalid mode sort");
}
ir_tarval *tarval_and(ir_tarval *a, ir_tarval *b)
......@@ -1009,9 +1056,12 @@ ir_tarval *tarval_and(ir_tarval *a, ir_tarval *b)
sc_and(a->value, b->value, NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
default:
case irms_auxiliary:
case irms_data:
case irms_float_number:
panic("operation not defined on mode");
}
panic("invalid mode sort");
}
ir_tarval *tarval_andnot(ir_tarval *a, ir_tarval *b)
......@@ -1027,9 +1077,12 @@ ir_tarval *tarval_andnot(ir_tarval *a, ir_tarval *b)
sc_andnot(a->value, b->value, NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
default:
case irms_auxiliary:
case irms_data:
case irms_float_number:
panic("operation not defined on mode");
}
panic("invalid mode sort");
}
ir_tarval *tarval_or(ir_tarval *a, ir_tarval *b)
......@@ -1045,9 +1098,12 @@ ir_tarval *tarval_or(ir_tarval *a, ir_tarval *b)
sc_or(a->value, b->value, NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
default:
case irms_auxiliary:
case irms_data:
case irms_float_number:
panic("operation not defined on mode");
}
panic("invalid mode sort");
}
ir_tarval *tarval_eor(ir_tarval *a, ir_tarval *b)
......@@ -1063,9 +1119,12 @@ ir_tarval *tarval_eor(ir_tarval *a, ir_tarval *b)
sc_xor(a->value, b->value, NULL);
return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode);
default:
case irms_auxiliary:
case irms_data:
case irms_float_number:
panic("operation not defined on mode");
}