X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firmode.c;h=75b02bcb73f097abb44caae59bf6edd74e67a447;hb=afbbc0b1ccd684c4c24bfd43d0f994123245f39f;hp=b441d5717d87712a8058976c84921163dcbb6009;hpb=2402e5c731667b4cf89feac723aacad1a780bf14;p=libfirm diff --git a/ir/ir/irmode.c b/ir/ir/irmode.c index b441d5717..75b02bcb7 100644 --- a/ir/ir/irmode.c +++ b/ir/ir/irmode.c @@ -45,30 +45,22 @@ # include "irtools.h" # include "array.h" -/* * * - * local values - * * */ - - -/** dynamic array to hold all modes */ +/** Obstack to hold all modes. */ static struct obstack modes; -/** number of defined modes */ +/** Number of defined modes. */ static int num_modes = 0; +/** The list of all currently existing modes. */ static ir_mode **mode_list; -/* * * - * local functions - * * */ - /** * Compare modes that don't need to have their code field * correctly set * * TODO: Add other fields **/ -INLINE static int modes_are_equal(const ir_mode *m, const ir_mode *n) { +static INLINE int modes_are_equal(const ir_mode *m, const ir_mode *n) { if (m == n) return 1; if (m->sort == n->sort && m->arithmetic == n->arithmetic && @@ -87,17 +79,34 @@ INLINE static int modes_are_equal(const ir_mode *m, const ir_mode *n) { * none found */ static ir_mode *find_mode(const ir_mode *m) { - unsigned len = ARR_LEN(mode_list); - unsigned i; - - for(i = 0; i < len; ++i) { + int i; + for (i = ARR_LEN(mode_list) - 1; i >= 0; --i) { ir_mode *n = mode_list[i]; if (modes_are_equal(n, m)) return n; } + return NULL; +} + +#ifdef FIRM_STATISTICS +/* return the mode index, only needed for statistics */ +int stat_find_mode_index(const ir_mode *m) { + int i; + for (i = ARR_LEN(mode_list) - 1; i >= 0; --i) { + ir_mode *n = mode_list[i]; + if (modes_are_equal(n, m)) + return i; + } + return -1; +} +/* return the mode for a given index, only needed for statistics */ +ir_mode *stat_mode_for_index(int idx) { + if (0 <= idx && idx < ARR_LEN(mode_list)) + return mode_list[idx]; return NULL; } +#endif /** * sets special values of modes @@ -255,8 +264,8 @@ static ir_mode *register_mode(const ir_mode *new_mode) { /* * Creates a new mode. */ -ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int sign, - mode_arithmetic arithmetic, unsigned int modulo_shift) +ir_mode *new_ir_mode(const char *name, ir_mode_sort sort, int bit_size, int sign, + ir_mode_arithmetic arithmetic, unsigned int modulo_shift) { ir_mode mode_tmpl; ir_mode *mode = NULL; @@ -297,8 +306,8 @@ ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int sign, /* * Creates a new vector mode. */ -ir_mode *new_ir_vector_mode(const char *name, mode_sort sort, int bit_size, unsigned num_of_elem, int sign, - mode_arithmetic arithmetic, unsigned int modulo_shift) +ir_mode *new_ir_vector_mode(const char *name, ir_mode_sort sort, int bit_size, unsigned num_of_elem, int sign, + ir_mode_arithmetic arithmetic, unsigned int modulo_shift) { ir_mode mode_tmpl; ir_mode *mode = NULL; @@ -348,7 +357,7 @@ ir_mode *new_ir_vector_mode(const char *name, mode_sort sort, int bit_size, unsi } /* Functions for the direct access to all attributes of an ir_mode */ -modecode (get_mode_modecode)(const ir_mode *mode) { +ir_modecode (get_mode_modecode)(const ir_mode *mode) { return _get_mode_modecode(mode); } @@ -360,7 +369,7 @@ const char *get_mode_name(const ir_mode *mode) { return get_id_str(mode->name); } -mode_sort (get_mode_sort)(const ir_mode* mode) { +ir_mode_sort (get_mode_sort)(const ir_mode* mode) { return _get_mode_sort(mode); } @@ -376,7 +385,7 @@ int (get_mode_sign)(const ir_mode *mode) { return _get_mode_sign(mode); } -mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode) { +ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode) { return get_mode_arithmetic(mode); } @@ -403,7 +412,7 @@ void (set_mode_link)(ir_mode *mode, void *l) { tarval *get_mode_min(ir_mode *mode) { assert(mode); - assert(get_mode_modecode(mode) < (modecode) num_modes); + assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_data(mode)); return mode->min; @@ -411,7 +420,7 @@ tarval *get_mode_min(ir_mode *mode) { tarval *get_mode_max(ir_mode *mode) { assert(mode); - assert(get_mode_modecode(mode) < (modecode) num_modes); + assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_data(mode)); return mode->max; @@ -419,7 +428,7 @@ tarval *get_mode_max(ir_mode *mode) { tarval *get_mode_null(ir_mode *mode) { assert(mode); - assert(get_mode_modecode(mode) < (modecode) num_modes); + assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_datab(mode)); return mode->null; @@ -427,7 +436,7 @@ tarval *get_mode_null(ir_mode *mode) { tarval *get_mode_one(ir_mode *mode) { assert(mode); - assert(get_mode_modecode(mode) < (modecode) num_modes); + assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_datab(mode)); return mode->one; @@ -435,7 +444,7 @@ tarval *get_mode_one(ir_mode *mode) { tarval *get_mode_minus_one(ir_mode *mode) { assert(mode); - assert(get_mode_modecode(mode) < (modecode) num_modes); + assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_data(mode)); return mode->minus_one; @@ -443,14 +452,14 @@ tarval *get_mode_minus_one(ir_mode *mode) { tarval *get_mode_all_one(ir_mode *mode) { assert(mode); - assert(get_mode_modecode(mode) < (modecode) num_modes); + assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_datab(mode)); return mode->all_one; } tarval *get_mode_infinite(ir_mode *mode) { assert(mode); - assert(get_mode_modecode(mode) < (modecode) num_modes); + assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_float(mode)); return get_tarval_plus_inf(mode); @@ -458,7 +467,7 @@ tarval *get_mode_infinite(ir_mode *mode) { tarval *get_mode_NAN(ir_mode *mode) { assert(mode); - assert(get_mode_modecode(mode) < (modecode) num_modes); + assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_float(mode)); return get_tarval_nan(mode); @@ -527,11 +536,11 @@ int smaller_mode(const ir_mode *sm, const ir_mode *lm) { case irms_int_number: switch (get_mode_sort(lm)) { case irms_int_number: - if(get_mode_arithmetic(sm) != get_mode_arithmetic(lm)) + if (get_mode_arithmetic(sm) != get_mode_arithmetic(lm)) return 0; /* only two complement implemented */ - assert(get_mode_arithmetic(sm)==irma_twos_complement); + assert(get_mode_arithmetic(sm) == irma_twos_complement); /* integers are convertable if * - both have the same sign and lm is the larger one @@ -539,12 +548,12 @@ int smaller_mode(const ir_mode *sm, const ir_mode *lm) { * (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)) + if (mode_is_signed(sm)) { + if (!mode_is_signed(lm)) return 0; return sm_bits <= lm_bits; } else { - if(mode_is_signed(lm)) { + if (mode_is_signed(lm)) { return sm_bits < lm_bits; } return sm_bits <= lm_bits; @@ -583,6 +592,37 @@ int smaller_mode(const ir_mode *sm, const ir_mode *lm) { 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) { + int sm_bits, lm_bits; + ir_mode_arithmetic arith; + + assert(sm); + assert(lm); + + if (sm == lm) return 1; + + if (sm == mode_b) + return mode_is_int(lm); + + sm_bits = get_mode_size_bits(sm); + lm_bits = get_mode_size_bits(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)); @@ -834,7 +874,11 @@ void init_mode(void) { ir_mode *find_unsigned_mode(const ir_mode *mode) { ir_mode n = *mode; - assert(mode->sort == irms_int_number); + /* 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); } @@ -894,6 +938,25 @@ int mode_wrap_around(const ir_mode *mode) { return mode_is_int(mode); } +/* + * Returns non-zero if the cast from mode src to mode dst is a + * reinterpret cast (ie. only the bit pattern is reinterpreted, + * no conversion is done) + */ +int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst) { + ir_mode_arithmetic ma; + + if (src == dst) + return 1; + if (get_mode_size_bits(src) != get_mode_size_bits(dst)) + return 0; + ma = get_mode_arithmetic(src); + if (ma != get_mode_arithmetic(dst)) + return 0; + + return ma == irma_twos_complement || ma == irma_ones_complement; +} + void finish_mode(void) { obstack_free(&modes, 0); DEL_ARR_F(mode_list);