X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firmode.c;h=a208d9b077403c0e45967641d0b20e9e15171b0f;hb=8940e28146a93b189ad4e6a6ed409ebf5631eacf;hp=448f873ff20117fe448abb9a0ede609df094b62c;hpb=0fbcef83aa6060534172bb13e71cdadb04428806;p=libfirm diff --git a/ir/ir/irmode.c b/ir/ir/irmode.c index 448f873ff..a208d9b07 100644 --- a/ir/ir/irmode.c +++ b/ir/ir/irmode.c @@ -1,74 +1,44 @@ /* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. - * * This file is part of libFirm. - * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file LICENSE.GPL included in the - * packaging of this file. - * - * Licensees holding valid libFirm Professional Edition licenses may use - * this file in accordance with the libFirm Commercial License. - * Agreement provided with the Software. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. + * Copyright (C) 2012 University of Karlsruhe. */ /** * @file * @brief Data modes of operations. * @author Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Mathias Heil - * @version $Id$ */ #include "config.h" -#ifdef HAVE_STDLIB_H -# include -#endif -#ifdef HAVE_STRING_H -# include -#endif - -# include - -# include "irprog_t.h" -# include "irmode_t.h" -# include "ident.h" -# include "tv_t.h" -# include "obst.h" -# include "irhooks.h" -# include "irtools.h" -# include "array.h" +#include +#include +#include +#include + +#include "irprog_t.h" +#include "irmode_t.h" +#include "ident.h" +#include "tv_t.h" +#include "obst.h" +#include "irhooks.h" +#include "irtools.h" +#include "array.h" +#include "error.h" +#include "pattern_dmp.h" /** Obstack to hold all modes. */ static struct obstack modes; -/** Number of defined modes. */ -static int num_modes = 0; - /** The list of all currently existing modes. */ static ir_mode **mode_list; -/** - * Compare modes that don't need to have their code field - * correctly set - * - * TODO: Add other fields - **/ -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 && - m->size == n->size && - m->sign == n->sign && - m->modulo_shift == n->modulo_shift && - m->vector_elem == n->vector_elem) - return 1; - - return 0; +static bool modes_are_equal(const ir_mode *m, const ir_mode *n) +{ + return m->sort == n->sort && + m->arithmetic == n->arithmetic && + m->size == n->size && + m->sign == n->sign && + m->modulo_shift == n->modulo_shift; } /** @@ -76,9 +46,10 @@ static INLINE int modes_are_equal(const ir_mode *m, const ir_mode *n) { * a pointer on an equal mode already in the array, NULL if * none found */ -static ir_mode *find_mode(const ir_mode *m) { - int i; - for (i = ARR_LEN(mode_list) - 1; i >= 0; --i) { +static ir_mode *find_mode(const ir_mode *m) +{ + size_t i, n_modes; + for (i = 0, n_modes = ARR_LEN(mode_list); i < n_modes; ++i) { ir_mode *n = mode_list[i]; if (modes_are_equal(n, m)) return n; @@ -86,30 +57,11 @@ static ir_mode *find_mode(const ir_mode *m) { 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 */ -static void set_mode_values(ir_mode* mode) { +static void set_mode_values(ir_mode* mode) +{ switch (get_mode_sort(mode)) { case irms_reference: case irms_int_number: @@ -119,7 +71,7 @@ static void set_mode_values(ir_mode* mode) { mode->null = get_tarval_null(mode); mode->one = get_tarval_one(mode); mode->minus_one = get_tarval_minus_one(mode); - if(get_mode_sort(mode) != irms_float_number) { + if (get_mode_sort(mode) != irms_float_number) { mode->all_one = get_tarval_all_one(mode); } else { mode->all_one = tarval_bad; @@ -135,9 +87,12 @@ static void set_mode_values(ir_mode* mode) { mode->all_one = tarval_b_true; break; - case irms_auxiliary: - case irms_memory: case irms_control_flow: + case irms_block: + case irms_tuple: + case irms_any: + case irms_bad: + case irms_memory: mode->min = tarval_bad; mode->max = tarval_bad; mode->null = tarval_bad; @@ -147,13 +102,6 @@ static void set_mode_values(ir_mode* mode) { } } -/* * * - * globals defined in irmode.h - * * */ - -/* --- Predefined modes --- */ - -/* FIRM internal modes: */ ir_mode *mode_T; ir_mode *mode_X; ir_mode *mode_M; @@ -161,38 +109,31 @@ ir_mode *mode_BB; ir_mode *mode_ANY; ir_mode *mode_BAD; -/* predefined numerical modes: */ -ir_mode *mode_F; /* float */ -ir_mode *mode_D; /* double */ -ir_mode *mode_E; /* long double */ +ir_mode *mode_F; +ir_mode *mode_D; +ir_mode *mode_Q; -ir_mode *mode_Bs; /* integral values, signed and unsigned */ -ir_mode *mode_Bu; /* 8 bit */ -ir_mode *mode_Hs; /* 16 bit */ +ir_mode *mode_Bs; +ir_mode *mode_Bu; +ir_mode *mode_Hs; ir_mode *mode_Hu; -ir_mode *mode_Is; /* 32 bit */ +ir_mode *mode_Is; ir_mode *mode_Iu; -ir_mode *mode_Ls; /* 64 bit */ +ir_mode *mode_Ls; ir_mode *mode_Lu; -ir_mode *mode_LLs; /* 128 bit */ +ir_mode *mode_LLs; ir_mode *mode_LLu; ir_mode *mode_b; ir_mode *mode_P; -/* machine specific modes */ -ir_mode *mode_P_code; /**< machine specific pointer mode for code addresses */ -ir_mode *mode_P_data; /**< machine specific pointer mode for data addresses */ - -/* * * - * functions defined in irmode.h - * * */ +ir_mode *mode_P_code; +ir_mode *mode_P_data; -/* JNI access functions */ ir_mode *get_modeT(void) { return mode_T; } ir_mode *get_modeF(void) { return mode_F; } ir_mode *get_modeD(void) { return mode_D; } -ir_mode *get_modeE(void) { return mode_E; } +ir_mode *get_modeQ(void) { return mode_Q; } ir_mode *get_modeBs(void) { return mode_Bs; } ir_mode *get_modeBu(void) { return mode_Bu; } ir_mode *get_modeHs(void) { return mode_Hs; } @@ -212,314 +153,274 @@ ir_mode *get_modeANY(void) { return mode_ANY; } ir_mode *get_modeBAD(void) { return mode_BAD; } -ir_mode *(get_modeP_code)(void) { - return _get_modeP_code(); +ir_mode *(get_modeP_code)(void) +{ + return get_modeP_code_(); } -ir_mode *(get_modeP_data)(void) { - return _get_modeP_data(); +ir_mode *(get_modeP_data)(void) +{ + return get_modeP_data_(); } -void set_modeP_code(ir_mode *p) { +void set_modeP_code(ir_mode *p) +{ assert(mode_is_reference(p)); mode_P_code = p; } -void set_modeP_data(ir_mode *p) { +void set_modeP_data(ir_mode *p) +{ assert(mode_is_reference(p)); mode_P_data = p; + mode_P = p; } -/** - * Registers a new mode. - * - * @param new_mode The new mode template. +/* + * Creates a new mode. */ -static ir_mode *register_mode(const ir_mode *new_mode) { - ir_mode *mode = NULL; - - assert(new_mode); +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); - /* copy mode struct to modes array */ - mode = (ir_mode *)obstack_copy(&modes, new_mode, sizeof(*mode)); - ARR_APP1(ir_mode*, mode_list, 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; +} - mode->kind = k_ir_mode; - if (num_modes >= irm_max) { - mode->code = num_modes; +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; } - num_modes++; - - /* add the new mode to the irp list of modes */ - add_irp_mode(mode); + 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(new_mode, mode); + hook_new_mode(mode); return mode; } -/* - * Creates a new mode. - */ -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; - - 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 = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0; - mode_tmpl.vector_elem = 1; - mode_tmpl.arithmetic = arithmetic; - mode_tmpl.link = NULL; - mode_tmpl.tv_priv = NULL; - - mode = find_mode(&mode_tmpl); - if (mode) { - hook_new_mode(&mode_tmpl, mode); - return mode; - } - - /* sanity checks */ - switch (sort) { - case irms_auxiliary: - case irms_control_flow: - case irms_memory: - case irms_internal_boolean: - assert(0 && "internal modes cannot be user defined"); - break; - - case irms_float_number: - case irms_int_number: - case irms_reference: - mode = register_mode(&mode_tmpl); - } - 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); } -/* - * Creates a new vector mode. - */ -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; - - mode_tmpl.name = new_id_from_str(name); - mode_tmpl.sort = sort; - mode_tmpl.size = bit_size * num_of_elem; - mode_tmpl.sign = sign ? 1 : 0; - mode_tmpl.modulo_shift = (mode_tmpl.sort == irms_int_number) ? modulo_shift : 0; - mode_tmpl.vector_elem = num_of_elem; - mode_tmpl.arithmetic = arithmetic; - mode_tmpl.link = NULL; - mode_tmpl.tv_priv = NULL; - - mode = find_mode(&mode_tmpl); - if (mode) { - hook_new_mode(&mode_tmpl, mode); - return mode; - } - - if (num_of_elem <= 1) { - assert(0 && "vector modes should have at least 2 elements"); - return NULL; - } - - /* sanity checks */ - switch (sort) { - case irms_auxiliary: - case irms_control_flow: - case irms_memory: - case irms_internal_boolean: - assert(0 && "internal modes cannot be user defined"); - break; - - case irms_reference: - assert(0 && "only integer and floating point modes can be vectorized"); - break; - - case irms_float_number: - assert(0 && "not yet implemented"); - break; +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); +} - case irms_int_number: - mode = register_mode(&mode_tmpl); +ir_mode *new_float_mode(const char *name, ir_mode_arithmetic arithmetic, + unsigned exponent_size, unsigned mantissa_size) +{ + bool explicit_one = false; + unsigned bit_size = exponent_size + mantissa_size + 1; + ir_mode *result; + + if (arithmetic == irma_x86_extended_float) { + explicit_one = true; + bit_size++; + } else if (arithmetic != irma_ieee754) { + panic("Arithmetic %s invalid for float"); } - return mode; -} + if (exponent_size >= 256) + panic("Exponents >= 256 bits not supported"); + if (mantissa_size >= 256) + panic("Mantissa >= 256 bits not supported"); -/* Functions for the direct access to all attributes of an ir_mode */ -ir_modecode (get_mode_modecode)(const ir_mode *mode) { - return _get_mode_modecode(mode); + result = alloc_mode(name, irms_float_number, irma_x86_extended_float, bit_size, 1, 0); + result->float_desc.exponent_size = exponent_size; + result->float_desc.mantissa_size = mantissa_size; + result->float_desc.explicit_one = explicit_one; + return register_mode(result); } -ident *(get_mode_ident)(const ir_mode *mode) { - return _get_mode_ident(mode); +ident *(get_mode_ident)(const ir_mode *mode) +{ + return get_mode_ident_(mode); } -const char *get_mode_name(const ir_mode *mode) { +const char *get_mode_name(const ir_mode *mode) +{ return get_id_str(mode->name); } -ir_mode_sort (get_mode_sort)(const ir_mode* mode) { - return _get_mode_sort(mode); -} - -unsigned (get_mode_size_bits)(const ir_mode *mode) { - return _get_mode_size_bits(mode); +unsigned (get_mode_size_bits)(const ir_mode *mode) +{ + return get_mode_size_bits_(mode); } -unsigned (get_mode_size_bytes)(const ir_mode *mode) { - return _get_mode_size_bytes(mode); +unsigned (get_mode_size_bytes)(const ir_mode *mode) +{ + return get_mode_size_bytes_(mode); } -int (get_mode_sign)(const ir_mode *mode) { - return _get_mode_sign(mode); +int (get_mode_sign)(const ir_mode *mode) +{ + return get_mode_sign_(mode); } -ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode) { - return get_mode_arithmetic(mode); +ir_mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode) +{ + return get_mode_arithmetic_(mode); } -/* Attribute modulo shift specifies for modes of kind irms_int_number - * whether shift applies modulo to value of bits to shift. Asserts - * if mode is not irms_int_number. - */ -unsigned int (get_mode_modulo_shift)(const ir_mode *mode) { - return _get_mode_modulo_shift(mode); -} - -unsigned int (get_mode_n_vector_elems)(const ir_mode *mode) { - return _get_mode_vector_elems(mode); +unsigned int (get_mode_modulo_shift)(const ir_mode *mode) +{ + return get_mode_modulo_shift_(mode); } -void *(get_mode_link)(const ir_mode *mode) { - return _get_mode_link(mode); +void *(get_mode_link)(const ir_mode *mode) +{ + return get_mode_link_(mode); } -void (set_mode_link)(ir_mode *mode, void *l) { - _set_mode_link(mode, l); +void (set_mode_link)(ir_mode *mode, void *l) +{ + set_mode_link_(mode, l); } -tarval *get_mode_min(ir_mode *mode) { +ir_tarval *get_mode_min(ir_mode *mode) +{ assert(mode); - assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_data(mode)); return mode->min; } -tarval *get_mode_max(ir_mode *mode) { +ir_tarval *get_mode_max(ir_mode *mode) +{ assert(mode); - assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_data(mode)); return mode->max; } -tarval *get_mode_null(ir_mode *mode) { +ir_tarval *get_mode_null(ir_mode *mode) +{ assert(mode); - assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_datab(mode)); return mode->null; } -tarval *get_mode_one(ir_mode *mode) { +ir_tarval *get_mode_one(ir_mode *mode) +{ assert(mode); - assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_datab(mode)); return mode->one; } -tarval *get_mode_minus_one(ir_mode *mode) { +ir_tarval *get_mode_minus_one(ir_mode *mode) +{ assert(mode); - assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_data(mode)); return mode->minus_one; } -tarval *get_mode_all_one(ir_mode *mode) { +ir_tarval *get_mode_all_one(ir_mode *mode) +{ assert(mode); - 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) { +ir_tarval *get_mode_infinite(ir_mode *mode) +{ assert(mode); - assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_float(mode)); return get_tarval_plus_inf(mode); } -tarval *get_mode_NAN(ir_mode *mode) { +ir_tarval *get_mode_NAN(ir_mode *mode) +{ assert(mode); - assert(get_mode_modecode(mode) < (ir_modecode) num_modes); assert(mode_is_float(mode)); return get_tarval_nan(mode); } -int is_mode(void *thing) { - if (get_kind(thing) == k_ir_mode) - return 1; - else - return 0; +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_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_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_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_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_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_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_datab)(const ir_mode *mode) +{ + return mode_is_datab_(mode); } -int (mode_is_dataM)(const ir_mode *mode) { - return _mode_is_dataM(mode); +int (mode_is_dataM)(const ir_mode *mode) +{ + return mode_is_dataM_(mode); } -int (mode_is_float_vector)(const ir_mode *mode) { - return _mode_is_float_vector(mode); +unsigned (get_mode_mantissa_size)(const ir_mode *mode) +{ + return get_mode_mantissa_size_(mode); } -int (mode_is_int_vector)(const ir_mode *mode) { - return _mode_is_int_vector(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 smaller_mode(const ir_mode *sm, const ir_mode *lm) +{ int sm_bits, lm_bits; assert(sm); @@ -556,7 +457,6 @@ int smaller_mode(const ir_mode *sm, const ir_mode *lm) { } return sm_bits <= lm_bits; } - break; case irms_float_number: /* int to float works if the float is large enough */ @@ -576,7 +476,7 @@ int smaller_mode(const ir_mode *sm, const ir_mode *lm) { break; case irms_reference: - /* do exist machines out there with different pointer lenghts ?*/ + /* do exist machines out there with different pointer lengths ?*/ return 0; case irms_internal_boolean: @@ -590,286 +490,110 @@ 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; +int values_in_mode(const ir_mode *sm, const ir_mode *lm) +{ + if (sm == lm) + return true; 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 mode_is_int(lm) || mode_is_float(lm); + + ir_mode_arithmetic larith = get_mode_arithmetic(lm); + ir_mode_arithmetic sarith = get_mode_arithmetic(sm); + switch (larith) { + case irma_x86_extended_float: + case irma_ieee754: + if (sarith == irma_ieee754 || sarith == irma_x86_extended_float) { return get_mode_size_bits(sm) <= get_mode_size_bits(lm); - - default: - return 0; + } else if (sarith == irma_twos_complement) { + unsigned int_mantissa = get_mode_size_bits(sm) - (mode_is_signed(sm) ? 1 : 0); + unsigned float_mantissa = get_mode_mantissa_size(lm) + 1; + return int_mantissa <= float_mantissa; + } + break; + case irma_twos_complement: + if (sarith == irma_twos_complement) { + return get_mode_size_bits(sm) <= get_mode_size_bits(lm); + } + break; + case irma_none: + break; } + return false; } -/* Return the signed integer equivalent mode for an reference mode. */ -ir_mode *get_reference_mode_signed_eq(ir_mode *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) { +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) { +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) { +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; } -/* initialization, build the default modes */ -void init_mode(void) { - ir_mode newmode; +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); - num_modes = 0; /* initialize predefined modes */ - - /* Internal Modes */ - newmode.arithmetic = irma_none; - newmode.size = 0; - newmode.sign = 0; - newmode.modulo_shift = 0; - newmode.vector_elem = 0; - newmode.eq_signed = NULL; - newmode.eq_unsigned = NULL; - newmode.link = NULL; - newmode.tv_priv = NULL; - - /* Control Flow Modes*/ - newmode.sort = irms_control_flow; - - /* Basic Block */ - newmode.name = new_id_from_chars("BB", 2); - newmode.code = irm_BB; - - mode_BB = register_mode(&newmode); - - /* eXecution */ - newmode.name = new_id_from_chars("X", 1); - newmode.code = irm_X; - - mode_X = register_mode(&newmode); - - /* Memory Modes */ - newmode.sort = irms_memory; - - /* Memory */ - newmode.name = new_id_from_chars("M", 1); - newmode.code = irm_M; - - mode_M = register_mode(&newmode); - - /* Auxiliary Modes */ - newmode.sort = irms_auxiliary, - - /* Tuple */ - newmode.name = new_id_from_chars("T", 1); - newmode.code = irm_T; - - mode_T = register_mode(&newmode); - - /* ANY */ - newmode.name = new_id_from_chars("ANY", 3); - newmode.code = irm_ANY; - - mode_ANY = register_mode(&newmode); - - /* BAD */ - newmode.name = new_id_from_chars("BAD", 3); - newmode.code = irm_BAD; - - mode_BAD = register_mode(&newmode); - - /* Internal Boolean Modes */ - newmode.sort = irms_internal_boolean; - - /* boolean */ - newmode.name = new_id_from_chars("b", 1); - newmode.code = irm_b; - - mode_b = register_mode(&newmode); - - /* Data Modes */ - newmode.vector_elem = 1; - - /* Float Number Modes */ - newmode.sort = irms_float_number; - newmode.arithmetic = irma_ieee754; - - /* float */ - newmode.name = new_id_from_chars("F", 1); - newmode.code = irm_F; - newmode.sign = 1; - newmode.size = 32; - - mode_F = register_mode(&newmode); - - /* double */ - newmode.name = new_id_from_chars("D", 1); - newmode.code = irm_D; - newmode.sign = 1; - newmode.size = 64; - - mode_D = register_mode(&newmode); - - /* extended */ - newmode.name = new_id_from_chars("E", 1); - newmode.code = irm_E; - newmode.sign = 1; - newmode.size = 80; - - mode_E = register_mode(&newmode); - - /* Integer Number Modes */ - newmode.sort = irms_int_number; - newmode.arithmetic = irma_twos_complement; - - /* signed byte */ - newmode.name = new_id_from_chars("Bs", 2); - newmode.code = irm_Bs; - newmode.sign = 1; - newmode.size = 8; - newmode.modulo_shift = 32; - - mode_Bs = register_mode(&newmode); - - /* unsigned byte */ - newmode.name = new_id_from_chars("Bu", 2); - newmode.code = irm_Bu; - newmode.arithmetic = irma_twos_complement; - newmode.sign = 0; - newmode.size = 8; - newmode.modulo_shift = 32; - - mode_Bu = register_mode(&newmode); - - /* signed short integer */ - newmode.name = new_id_from_chars("Hs", 2); - newmode.code = irm_Hs; - newmode.sign = 1; - newmode.size = 16; - newmode.modulo_shift = 32; - - mode_Hs = register_mode(&newmode); - - /* unsigned short integer */ - newmode.name = new_id_from_chars("Hu", 2); - newmode.code = irm_Hu; - newmode.sign = 0; - newmode.size = 16; - newmode.modulo_shift = 32; - - mode_Hu = register_mode(&newmode); - - /* signed integer */ - newmode.name = new_id_from_chars("Is", 2); - newmode.code = irm_Is; - newmode.sign = 1; - newmode.size = 32; - newmode.modulo_shift = 32; - - mode_Is = register_mode(&newmode); - - /* unsigned integer */ - newmode.name = new_id_from_chars("Iu", 2); - newmode.code = irm_Iu; - newmode.sign = 0; - newmode.size = 32; - newmode.modulo_shift = 32; - - mode_Iu = register_mode(&newmode); - - /* signed long integer */ - newmode.name = new_id_from_chars("Ls", 2); - newmode.code = irm_Ls; - newmode.sign = 1; - newmode.size = 64; - newmode.modulo_shift = 64; - - mode_Ls = register_mode(&newmode); - - /* unsigned long integer */ - newmode.name = new_id_from_chars("Lu", 2); - newmode.code = irm_Lu; - newmode.sign = 0; - newmode.size = 64; - newmode.modulo_shift = 64; - - mode_Lu = register_mode(&newmode); - - /* signed long long integer */ - newmode.name = new_id_from_chars("LLs", 3); - newmode.code = irm_LLs; - newmode.sign = 1; - newmode.size = 128; - newmode.modulo_shift = 128; - - mode_LLs = register_mode(&newmode); - - /* unsigned long long integer */ - newmode.name = new_id_from_chars("LLu", 3); - newmode.code = irm_LLu; - newmode.sign = 0; - newmode.size = 128; - newmode.modulo_shift = 128; - - mode_LLu = register_mode(&newmode); - - /* Reference Mode */ - newmode.sort = irms_reference; - newmode.arithmetic = irma_twos_complement; - - /* pointer */ - newmode.name = new_id_from_chars("P", 1); - newmode.code = irm_P; - newmode.sign = 0; - newmode.size = 32; - newmode.modulo_shift = 0; - newmode.eq_signed = mode_Is; - newmode.eq_unsigned = mode_Iu; - - mode_P = register_mode(&newmode); + 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 *find_unsigned_mode(const ir_mode *mode) +{ ir_mode n = *mode; /* allowed for reference mode */ @@ -881,8 +605,8 @@ ir_mode *find_unsigned_mode(const ir_mode *mode) { return find_mode(&n); } -/* find an unsigned mode for a signed integer mode */ -ir_mode *find_signed_mode(const ir_mode *mode) { +ir_mode *find_signed_mode(const ir_mode *mode) +{ ir_mode n = *mode; assert(mode->sort == irms_int_number); @@ -890,8 +614,8 @@ ir_mode *find_signed_mode(const ir_mode *mode) { 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 *find_double_bits_int_mode(const ir_mode *mode) +{ ir_mode n = *mode; assert(mode->sort == irms_int_number && mode->arithmetic == irma_twos_complement); @@ -900,11 +624,8 @@ ir_mode *find_double_bits_int_mode(const ir_mode *mode) { return find_mode(&n); } -/* - * Returns non-zero if the given mode honors signed zero's, i.e., - * a +0 and a -0 exists and handled differently. - */ -int mode_honor_signed_zeros(const ir_mode *mode) { +int mode_honor_signed_zeros(const ir_mode *mode) +{ /* for floating point, we know that IEEE 754 has +0 and -0, * but always handles it identical. */ @@ -913,35 +634,21 @@ int mode_honor_signed_zeros(const ir_mode *mode) { mode->arithmetic != irma_ieee754; } -/* - * Returns non-zero if the given mode might overflow on unary Minus. - * - * This does NOT happen on IEEE 754. - */ -int mode_overflow_on_unary_Minus(const ir_mode *mode) { +int mode_overflow_on_unary_Minus(const ir_mode *mode) +{ if (mode->sort == irms_float_number) return mode->arithmetic == irma_ieee754 ? 0 : 1; return 1; } -/* - * Returns non-zero if the mode has a reversed wrap-around - * logic, especially (a + x) - x == a. - * - * This is normally true for integer modes, not for floating - * point modes. - */ -int mode_wrap_around(const ir_mode *mode) { +int mode_wrap_around(const ir_mode *mode) +{ /* FIXME: better would be an extra mode property */ 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) { +int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst) +{ ir_mode_arithmetic ma; if (src == dst) @@ -952,10 +659,27 @@ int is_reinterpret_cast(const ir_mode *src, const ir_mode *dst) { if (ma != get_mode_arithmetic(dst)) return 0; - return ma == irma_twos_complement || ma == irma_ones_complement; + return ma == irma_twos_complement; } -void finish_mode(void) { +ir_type *(get_type_for_mode) (const ir_mode *mode) +{ + return get_type_for_mode_(mode); +} + +size_t ir_get_n_modes(void) +{ + return ARR_LEN(mode_list); +} + +ir_mode *ir_get_mode(size_t num) +{ + assert(num < ARR_LEN(mode_list)); + return mode_list[num]; +} + +void finish_mode(void) +{ obstack_free(&modes, 0); DEL_ARR_F(mode_list); @@ -968,7 +692,6 @@ void finish_mode(void) { mode_F = NULL; mode_D = NULL; - mode_E = NULL; mode_Bs = NULL; mode_Bu = NULL;