X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firmode.c;h=4d0da3da4dd8a8faf6a856b98fb2ffe5ed67c265;hb=b7bf9774e5e704382bdf3eb7c09bc5755d4f067e;hp=eba8facf25ece726de99853d5492f3185fcefad0;hpb=b2883fe45bd4299e88e841cceb78097293fcdae0;p=libfirm diff --git a/ir/ir/irmode.c b/ir/ir/irmode.c index eba8facf2..4d0da3da4 100644 --- a/ir/ir/irmode.c +++ b/ir/ir/irmode.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -23,41 +23,42 @@ * @author Martin Trapp, Christian Schaefer, Goetz Lindenmaier, Mathias Heil * @version $Id$ */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#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 "config.h" -/* * * - * local values - * * */ +#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" -/** dynamic array to hold all modes */ +/** 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; -/* * * - * local functions - * * */ +const char *get_mode_arithmetic_name(ir_mode_arithmetic ari) +{ +#define X(a) case a: return #a + switch (ari) { + X(irma_uninitialized); + X(irma_none); + X(irma_twos_complement); + X(irma_ieee754); + default: return ""; + } +#undef X +} /** * Compare modes that don't need to have their code field @@ -65,7 +66,8 @@ static int num_modes = 0; * * 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 && @@ -78,59 +80,27 @@ INLINE static int modes_are_equal(const ir_mode *m, const ir_mode *n) { return 0; } -/* - * calculates the next obstack address - */ -static void *next_obstack_adr(struct obstack *o, void *p, size_t s) { - PTR_INT_TYPE adr = PTR_TO_INT((char *)p); - int mask = obstack_alignment_mask(o); - - adr += s + mask; - - return INT_TO_PTR(adr & ~mask); -} - /** * searches the modes obstack for the given mode and returns * a pointer on an equal mode already in the array, NULL if * none found */ -static ir_mode *find_mode(const ir_mode *m) { - ir_mode *n, *nn; - struct _obstack_chunk *p; - - p = modes.chunk; - n = (ir_mode *)p->contents; - nn = next_obstack_adr(&modes, n, sizeof(*n)); - for (; (char *)nn <= modes.next_free;) { - assert(is_mode(n)); +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; - - n = nn; - nn = next_obstack_adr(&modes, n, sizeof(*n)); } - - for (p = p->prev; p; p = p->prev) { - n = (ir_mode *)p->contents; - nn = next_obstack_adr(&modes, n, sizeof(*n)); - for (; (char *)nn < p->limit;) { - assert(is_mode(n)); - if (modes_are_equal(n, m)) - return n; - - n = nn; - nn = next_obstack_adr(&modes, n, sizeof(*n)); - } - } - return NULL; } /** * 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: @@ -140,7 +110,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; @@ -233,22 +203,27 @@ ir_mode *get_modeANY(void) { return mode_ANY; } ir_mode *get_modeBAD(void) { return mode_BAD; } -ir_mode *(get_modeP_code)(void) { +ir_mode *(get_modeP_code)(void) +{ return _get_modeP_code(); } -ir_mode *(get_modeP_data)(void) { +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; } /** @@ -256,19 +231,18 @@ void set_modeP_data(ir_mode *p) { * * @param new_mode The new mode template. */ -static ir_mode *register_mode(const ir_mode *new_mode) { +static ir_mode *register_mode(const ir_mode *new_mode) +{ ir_mode *mode = NULL; assert(new_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->kind = k_ir_mode; - if (num_modes >= irm_max) { - mode->code = num_modes; - } - num_modes++; + mode->type = new_type_primitive(mode); /* add the new mode to the irp list of modes */ add_irp_mode(mode); @@ -282,8 +256,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; @@ -292,7 +266,8 @@ ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int sign, 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.modulo_shift = (mode_tmpl.sort == irms_int_number || + mode_tmpl.sort == irms_reference) ? modulo_shift : 0; mode_tmpl.vector_elem = 1; mode_tmpl.arithmetic = arithmetic; mode_tmpl.link = NULL; @@ -310,22 +285,23 @@ ir_mode *new_ir_mode(const char *name, mode_sort sort, int bit_size, int sign, case irms_control_flow: case irms_memory: case irms_internal_boolean: - assert(0 && "internal modes cannot be user defined"); - break; + panic("internal modes cannot be user defined"); case irms_float_number: case irms_int_number: case irms_reference: mode = register_mode(&mode_tmpl); + break; } + assert(mode != NULL); return mode; } /* * 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; @@ -347,8 +323,7 @@ ir_mode *new_ir_vector_mode(const char *name, mode_sort sort, int bit_size, unsi } if (num_of_elem <= 1) { - assert(0 && "vector modes should have at least 2 elements"); - return NULL; + panic("vector modes should have at least 2 elements"); } /* sanity checks */ @@ -357,53 +332,54 @@ ir_mode *new_ir_vector_mode(const char *name, mode_sort sort, int bit_size, unsi case irms_control_flow: case irms_memory: case irms_internal_boolean: - assert(0 && "internal modes cannot be user defined"); - break; + panic("internal modes cannot be user defined"); case irms_reference: - assert(0 && "only integer and floating point modes can be vectorized"); - break; + panic("only integer and floating point modes can be vectorized"); case irms_float_number: - assert(0 && "not yet implemented"); - break; + panic("not yet implemented"); case irms_int_number: mode = register_mode(&mode_tmpl); } + assert(mode != NULL); return mode; } /* Functions for the direct access to all attributes of an ir_mode */ -modecode (get_mode_modecode)(const ir_mode *mode) { - return _get_mode_modecode(mode); -} - -ident *(get_mode_ident)(const ir_mode *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); } -mode_sort (get_mode_sort)(const ir_mode* mode) { +ir_mode_sort (get_mode_sort)(const ir_mode* mode) +{ return _get_mode_sort(mode); } -unsigned (get_mode_size_bits)(const ir_mode *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) { +unsigned (get_mode_size_bytes)(const ir_mode *mode) +{ return _get_mode_size_bytes(mode); } -int (get_mode_sign)(const ir_mode *mode) { +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); } @@ -412,134 +388,147 @@ mode_arithmetic (get_mode_arithmetic)(const ir_mode *mode) { * 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) { +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) { +unsigned int (get_mode_n_vector_elems)(const ir_mode *mode) +{ return _get_mode_vector_elems(mode); } -void *(get_mode_link)(const ir_mode *mode) { +void *(get_mode_link)(const ir_mode *mode) +{ return _get_mode_link(mode); } -void (set_mode_link)(ir_mode *mode, void *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) < (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) < (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) < (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) < (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) < (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) < (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) < (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) < (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) { +int (mode_is_signed)(const ir_mode *mode) +{ return _mode_is_signed(mode); } -int (mode_is_float)(const ir_mode *mode) { +int (mode_is_float)(const ir_mode *mode) +{ return _mode_is_float(mode); } -int (mode_is_int)(const ir_mode *mode) { +int (mode_is_int)(const ir_mode *mode) +{ return _mode_is_int(mode); } -int (mode_is_reference)(const ir_mode *mode) { +int (mode_is_reference)(const ir_mode *mode) +{ return _mode_is_reference(mode); } -int (mode_is_num)(const ir_mode *mode) { +int (mode_is_num)(const ir_mode *mode) +{ return _mode_is_num(mode); } -int (mode_is_data)(const ir_mode *mode) { +int (mode_is_data)(const ir_mode *mode) +{ return _mode_is_data(mode); } -int (mode_is_datab)(const ir_mode *mode) { +int (mode_is_datab)(const ir_mode *mode) +{ return _mode_is_datab(mode); } -int (mode_is_dataM)(const ir_mode *mode) { +int (mode_is_dataM)(const ir_mode *mode) +{ return _mode_is_dataM(mode); } -int (mode_is_float_vector)(const ir_mode *mode) { +int (mode_is_float_vector)(const ir_mode *mode) +{ return _mode_is_float_vector(mode); } -int (mode_is_int_vector)(const ir_mode *mode) { +int (mode_is_int_vector)(const ir_mode *mode) +{ return _mode_is_int_vector(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); @@ -554,11 +543,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 @@ -566,17 +555,16 @@ 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; } - break; case irms_float_number: /* int to float works if the float is large enough */ @@ -596,7 +584,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: @@ -610,39 +598,72 @@ 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) +{ + ir_mode_arithmetic arith; + + assert(sm); + assert(lm); + + if (sm == lm) return 1; + + if (sm == mode_b) + return mode_is_int(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) { +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) { +void init_mode(void) +{ ir_mode newmode; obstack_init(&modes); + mode_list = NEW_ARR_F(ir_mode*, 0); - num_modes = 0; /* initialize predefined modes */ /* Internal Modes */ @@ -661,54 +682,40 @@ void init_mode(void) { /* Basic Block */ newmode.name = new_id_from_chars("BB", 2); - newmode.code = irm_BB; - - mode_BB = register_mode(&newmode); + mode_BB = register_mode(&newmode); /* eXecution */ newmode.name = new_id_from_chars("X", 1); - newmode.code = irm_X; - - mode_X = register_mode(&newmode); + 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); + 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); + mode_T = register_mode(&newmode); /* ANY */ newmode.name = new_id_from_chars("ANY", 3); - newmode.code = irm_ANY; - - mode_ANY = register_mode(&newmode); + mode_ANY = register_mode(&newmode); /* BAD */ newmode.name = new_id_from_chars("BAD", 3); - newmode.code = irm_BAD; - - mode_BAD = register_mode(&newmode); + 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); + mode_b = register_mode(&newmode); /* Data Modes */ newmode.vector_elem = 1; @@ -719,27 +726,23 @@ void init_mode(void) { /* float */ newmode.name = new_id_from_chars("F", 1); - newmode.code = irm_F; newmode.sign = 1; newmode.size = 32; - - mode_F = register_mode(&newmode); + 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); + 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); + /* note that the tarval module is calculating with 80 bits, but we use + * 96 bits, as that is what will be stored to memory by most hardware */ + newmode.size = 96; + mode_E = register_mode(&newmode); /* Integer Number Modes */ newmode.sort = irms_int_number; @@ -747,94 +750,74 @@ void init_mode(void) { /* 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + mode_LLu = register_mode(&newmode); /* Reference Mode */ newmode.sort = irms_reference; @@ -842,14 +825,12 @@ void init_mode(void) { /* pointer */ newmode.name = new_id_from_chars("P", 1); - newmode.code = irm_P; newmode.sign = 0; newmode.size = 32; - newmode.modulo_shift = 0; + newmode.modulo_shift = 32; newmode.eq_signed = mode_Is; newmode.eq_unsigned = mode_Iu; - - mode_P = register_mode(&newmode); + mode_P = register_mode(&newmode); /* set the machine specific modes to the predefined ones */ mode_P_code = mode_P; @@ -857,16 +838,22 @@ void init_mode(void) { } /* 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; - 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); } /* 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); @@ -875,7 +862,8 @@ ir_mode *find_signed_mode(const ir_mode *mode) { } /* 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); @@ -888,7 +876,8 @@ ir_mode *find_double_bits_int_mode(const ir_mode *mode) { * 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. */ @@ -902,7 +891,8 @@ int mode_honor_signed_zeros(const ir_mode *mode) { * * 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; @@ -915,13 +905,41 @@ int mode_overflow_on_unary_Minus(const ir_mode *mode) { * 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); } -void finish_mode(void) { +/* + * 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; +} + +ir_type *(get_type_for_mode) (const ir_mode *mode) +{ + return get_type_for_mode_(mode); +} + +void finish_mode(void) +{ obstack_free(&modes, 0); + DEL_ARR_F(mode_list); mode_T = NULL; mode_X = NULL;