X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Ftv.c;h=7af7434e5bafb849e7a75004bef963059cf799d6;hb=f73f5c542edb2e4ff58a4bdc4f9d53415a14c4a1;hp=600cd93e56bcb39a80b8f5006270029abd43cd9d;hpb=a5f5e1e5cfebfef059ac10e0ba043e60c3ef6463;p=libfirm diff --git a/ir/tv/tv.c b/ir/tv/tv.c index 600cd93e5..7af7434e5 100644 --- a/ir/tv/tv.c +++ b/ir/tv/tv.c @@ -20,33 +20,43 @@ /* This implementation assumes: * - target has IEEE-754 floating-point arithmetic. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + #include /* assertions */ #include /* atoi() */ -#include /* nice things for strings */ +#ifdef HAVE_STRING_H +# include /* nice things for strings */ +#endif +#ifdef HAVE_STRINGS_H #include /* strings.h also includes bsd only function strcasecmp */ +#endif #include -#include +#ifdef HAVE_ALLOCA_H +# include +#endif +#ifdef HAVE_MALLOC_H +# include +#endif #include "tv_t.h" #include "set.h" /* to store tarvals in */ -//#include "tune.h" /* some constants */ +/* #include "tune.h" */ /* some constants */ #include "entity_t.h" /* needed to store pointers to entities */ -#include "irmode.h" /* defines modes etc */ #include "irmode_t.h" #include "irnode.h" /* defines boolean return values (pnc_number)*/ -#include "host.h" #include "strcalc.h" #include "fltcalc.h" /** Size of hash tables. Should correspond to average number of distinct constant target values */ -#define N_CONSTANTS 2048 +#define N_CONSTANTS 2048 -/* XXX hack until theres's a proper interface */ -#define BAD 1 -#define SATURATE 2 -#define WRAP 3 -#define GET_OVERFLOW_MODE() BAD +/* get the integer overflow mode */ +#define GET_OVERFLOW_MODE() int_overflow_mode /* unused, float to int doesn't work yet */ #define TRUNCATE 1 @@ -83,6 +93,7 @@ static long long count = 0; ****************************************************************************/ static struct set *tarvals; /* container for tarval structs */ static struct set *values; /* container for values */ +static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP; /**************************************************************************** * private functions @@ -158,6 +169,9 @@ static tarval *get_tarval(const void *value, int length, ir_mode *mode) return (tarval *)INSERT_TARVAL(&tv); } +/** + * handle overflow + */ static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode) { switch (get_mode_sort(mode)) @@ -165,9 +179,9 @@ static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode) case irms_int_number: if (sc_comp(value, get_mode_max(mode)->value) == 1) { switch (GET_OVERFLOW_MODE()) { - case SATURATE: + case TV_OVERFLOW_SATURATE: return get_mode_max(mode); - case WRAP: + case TV_OVERFLOW_WRAP: { char *temp = alloca(sc_get_buffer_length()); char *diff = alloca(sc_get_buffer_length()); @@ -179,7 +193,7 @@ static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode) sc_sub(temp, diff, temp); return get_tarval(temp, length, mode); } - case BAD: + case TV_OVERFLOW_BAD: return tarval_bad; default: return get_tarval(value, length, mode); @@ -187,9 +201,9 @@ static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode) } if (sc_comp(value, get_mode_min(mode)->value) == -1) { switch (GET_OVERFLOW_MODE()) { - case SATURATE: + case TV_OVERFLOW_SATURATE: return get_mode_min(mode); - case WRAP: + case TV_OVERFLOW_WRAP: { char *temp = alloca(sc_get_buffer_length()); char *diff = alloca(sc_get_buffer_length()); @@ -201,7 +215,7 @@ static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode) sc_add(temp, diff, temp); return get_tarval(temp, length, mode); } - case BAD: + case TV_OVERFLOW_BAD: return tarval_bad; default: return get_tarval(value, length, mode); @@ -266,7 +280,7 @@ tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode) else if (strcasecmp(str, "false")) return tarval_b_true; else /* XXX This is C semantics */ - return atoi(str) ? tarval_b_true : tarval_b_false; + return atoi(str) ? tarval_b_true : tarval_b_false; case irms_float_number: switch(get_mode_size_bits(mode)) { @@ -346,7 +360,7 @@ int tarval_is_long(tarval *tv) } /* this might overflow the machine's long, so use only with small values */ -long tarval_to_long(tarval* tv) +long get_tarval_long(tarval* tv) { ANNOUNCE(); assert(tarval_is_long(tv) && "tarval too big to fit in long"); @@ -382,7 +396,7 @@ int tarval_is_double(tarval *tv) return (get_mode_sort(tv->mode) == irms_float_number); } -long double tarval_to_double(tarval *tv) +long double get_tarval_double(tarval *tv) { ANNOUNCE(); assert(tarval_is_double(tv)); @@ -390,52 +404,6 @@ long double tarval_to_double(tarval *tv) return fc_val_to_float(tv->value); } -/* The tarval represents the address of the entity. As the address must - be constant the entity must have as owner the global type. */ -tarval *new_tarval_from_entity (entity *ent, ir_mode *mode) -{ - ANNOUNCE(); - assert(ent); - assert(mode && (get_mode_sort(mode) == irms_reference)); - - return get_tarval((void *)ent, 0, mode); -} -int tarval_is_entity(tarval *tv) -{ - ANNOUNCE(); - assert(tv); - /* tv->value == NULL means dereferencing a null pointer */ - return ((get_mode_sort(tv->mode) == irms_reference) && (tv->value != NULL) && (tv->length == 0) - && (tv != tarval_P_void)); -} - -entity *tarval_to_entity(tarval *tv) -{ - ANNOUNCE(); - assert(tv); - - if (tarval_is_entity(tv)) - return (entity *)tv->value; - else { - assert(0 && "tarval did not represent an entity"); - return NULL; - } -} - -void free_tarval_entity(entity *ent) { - /* There can be a tarval referencing this entity. Even if the - tarval is not used by the code any more, it can still reference - the entity as tarvals live indepently of the entity referenced. - Further the tarval is hashed into a set. If a hash function - evaluation happens to collide with this tarval, we will vrfy that - it contains a proper entity and we will crash if the entity is - freed. - - Unluckily, tarvals can neither be changed nor deleted, and to find - one, all existing reference modes have to be tried -> a facility - to retrieve all modes of a kind is needed. */ - ANNOUNCE(); -} /* * Access routines for tarval fields ======================================== @@ -447,6 +415,15 @@ ir_mode *get_tarval_mode (tarval *tv) /* get the mode of the tarval */ return tv->mode; } +/* +void *get_tarval_link (tarval *tv) +{ + ANNOUNCE (); + assert (tv); + return (tv->link); +} +*/ + /* * Special value query functions ============================================ * @@ -488,6 +465,11 @@ tarval *get_tarval_max(ir_mode *mode) ANNOUNCE(); assert(mode); + if (get_mode_n_vector_elems(mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + switch(get_mode_sort(mode)) { case irms_reference: @@ -528,6 +510,11 @@ tarval *get_tarval_min(ir_mode *mode) ANNOUNCE(); assert(mode); + if (get_mode_n_vector_elems(mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + switch(get_mode_sort(mode)) { case irms_reference: @@ -568,6 +555,11 @@ tarval *get_tarval_null(ir_mode *mode) ANNOUNCE(); assert(mode); + if (get_mode_n_vector_elems(mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + switch(get_mode_sort(mode)) { case irms_control_flow: @@ -595,6 +587,11 @@ tarval *get_tarval_one(ir_mode *mode) ANNOUNCE(); assert(mode); + if (get_mode_n_vector_elems(mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + switch(get_mode_sort(mode)) { case irms_control_flow: @@ -621,6 +618,11 @@ tarval *get_tarval_nan(ir_mode *mode) ANNOUNCE(); assert(mode); + if (get_mode_n_vector_elems(mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + if (get_mode_sort(mode) == irms_float_number) { switch(get_mode_size_bits(mode)) { @@ -647,6 +649,11 @@ tarval *get_tarval_inf(ir_mode *mode) ANNOUNCE(); assert(mode); + if (get_mode_n_vector_elems(mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + if (get_mode_sort(mode) == irms_float_number) { switch(get_mode_size_bits(mode)) { @@ -680,12 +687,18 @@ int tarval_is_negative(tarval *a) ANNOUNCE(); assert(a); + if (get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + assert(0 && "tarval_is_negative is not allowed for vector modes"); + return 0; + } + switch (get_mode_sort(a->mode)) { case irms_int_number: if (!mode_is_signed(a->mode)) return 0; else - return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0; + return sc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0; case irms_float_number: return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0; @@ -706,6 +719,16 @@ int tarval_is_null(tarval *a) return a == get_tarval_null(m); } +/* + * test if one, 1 means 'yes' + */ +int tarval_is_one(tarval *a) +{ + ir_mode *m = get_tarval_mode(a); + + return a == get_tarval_one(m); +} + /* * comparison */ @@ -718,7 +741,12 @@ pnc_number tarval_cmp(tarval *a, tarval *b) if (a == tarval_bad || b == tarval_bad) assert(0 && "Comparison with tarval_bad"); if (a == tarval_undefined || b == tarval_undefined) return False; if (a == b) return Eq; - if (get_tarval_mode(a) != get_tarval_mode(b)) return False; + if (a->mode != b->mode) return False; + + if (get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + assert(0 && "cmp not implemented for vector modes"); + } /* Here the two tarvals are unequal and of the same mode */ switch (get_mode_sort(a->mode)) @@ -760,6 +788,11 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) if (src->mode == m) return src; + if (get_mode_n_vector_elems(src->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + switch (get_mode_sort(src->mode)) { case irms_control_flow: @@ -770,7 +803,7 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) /* cast float to something */ case irms_float_number: switch (get_mode_sort(m)) { - case irms_float_number: + case irms_float_number: switch (get_mode_size_bits(m)) { case 32: @@ -786,7 +819,6 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) break; } return get_tarval(fc_get_buffer(), fc_get_buffer_length(), m); - break; case irms_int_number: switch (GET_FLOAT_TO_INT_MODE()) @@ -805,7 +837,6 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) * an intermediate representation is needed here first. */ /* return get_tarval(); */ return tarval_bad; - break; default: /* the rest can't be converted */ @@ -875,7 +906,32 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) } /* - * negation + * bitwise negation + */ +tarval *tarval_not(tarval *a) +{ + char *buffer; + + ANNOUNCE(); + assert(a); + assert(mode_is_int(a->mode)); /* bitwise negation is only allowed for integer */ + + /* works for vector mode without changes */ + + switch (get_mode_sort(a->mode)) + { + case irms_int_number: + buffer = alloca(sc_get_buffer_length()); + sc_not(a->value, buffer); + return get_tarval(buffer, a->length, a->mode); + + default: + return tarval_bad; + } +} + +/* + * arithmetic negation */ tarval *tarval_neg(tarval *a) { @@ -884,7 +940,13 @@ tarval *tarval_neg(tarval *a) ANNOUNCE(); assert(a); assert(mode_is_num(a->mode)); /* negation only for numerical values */ - assert(mode_is_signed(a->mode)); /* negation is difficult without negative numbers, isn't it */ + + /* note: negation is allowed even for unsigned modes. */ + + if (get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } switch (get_mode_sort(a->mode)) { @@ -912,7 +974,12 @@ tarval *tarval_add(tarval *a, tarval *b) ANNOUNCE(); assert(a); assert(b); - assert((a->mode == b->mode) || (get_mode_sort(a->mode) == irms_character && mode_is_int(b->mode))); + assert(a->mode == b->mode); + + if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(b->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } switch (get_mode_sort(a->mode)) { @@ -942,8 +1009,12 @@ tarval *tarval_sub(tarval *a, tarval *b) ANNOUNCE(); assert(a); assert(b); - assert((a->mode == b->mode) || (get_mode_sort(a->mode) == irms_character && mode_is_int(b->mode))); + assert(a->mode == b->mode); + if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(b->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } switch (get_mode_sort(a->mode)) { case irms_character: @@ -972,7 +1043,12 @@ tarval *tarval_mul(tarval *a, tarval *b) ANNOUNCE(); assert(a); assert(b); - assert((a->mode == b->mode) && mode_is_num(a->mode)); + assert(a->mode == b->mode); + + if (get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } switch (get_mode_sort(a->mode)) { @@ -1001,6 +1077,11 @@ tarval *tarval_quo(tarval *a, tarval *b) assert(b); assert((a->mode == b->mode) && mode_is_float(a->mode)); + if (get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + fc_div(a->value, b->value, NULL); return get_tarval_overflow(fc_get_buffer(), fc_get_buffer_length(), a->mode); } @@ -1016,6 +1097,11 @@ tarval *tarval_div(tarval *a, tarval *b) assert(b); assert((a->mode == b->mode) && mode_is_int(a->mode)); + if (get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + /* x/0 error */ if (b == get_mode_null(b->mode)) return tarval_bad; /* modes of a,b are equal */ @@ -1034,6 +1120,11 @@ tarval *tarval_mod(tarval *a, tarval *b) assert(b); assert((a->mode == b->mode) && mode_is_int(a->mode)); + if (get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + /* x/0 error */ if (b == get_mode_null(b->mode)) return tarval_bad; /* modes of a,b are equal */ @@ -1052,6 +1143,11 @@ tarval *tarval_abs(tarval *a) assert(a); assert(mode_is_num(a->mode)); + if (get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + switch (get_mode_sort(a->mode)) { case irms_int_number: @@ -1087,6 +1183,8 @@ tarval *tarval_and(tarval *a, tarval *b) assert(b); assert(a->mode == b->mode); + /* works even for vector modes */ + switch(get_mode_sort(a->mode)) { case irms_internal_boolean: @@ -1112,6 +1210,8 @@ tarval *tarval_or (tarval *a, tarval *b) assert(b); assert(a->mode == b->mode); + /* works even for vector modes */ + switch (get_mode_sort(a->mode)) { case irms_internal_boolean: @@ -1137,13 +1237,15 @@ tarval *tarval_eor(tarval *a, tarval *b) assert(b); assert((a->mode == b->mode)); + /* works even for vector modes */ + switch (get_mode_sort(a->mode)) { case irms_internal_boolean: return (a == b)? tarval_b_false : tarval_b_true; case irms_int_number: - sc_or(a->value, b->value, NULL); + sc_xor(a->value, b->value, NULL); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); default: @@ -1157,12 +1259,28 @@ tarval *tarval_eor(tarval *a, tarval *b) */ tarval *tarval_shl(tarval *a, tarval *b) { + char *temp_val = NULL; ANNOUNCE(); assert(a); assert(b); assert(mode_is_int(a->mode) && mode_is_int(b->mode)); - sc_shl(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL); + if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + + if (get_mode_modulo_shift(a->mode) != 0) + { + temp_val = alloca(sc_get_buffer_length()); + + sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val); + sc_mod(b->value, temp_val, temp_val); + } + else + temp_val = (char*)b->value; + + sc_shl(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } @@ -1171,12 +1289,28 @@ tarval *tarval_shl(tarval *a, tarval *b) */ tarval *tarval_shr(tarval *a, tarval *b) { + char *temp_val = NULL; ANNOUNCE(); assert(a); assert(b); assert(mode_is_int(a->mode) && mode_is_int(b->mode)); - sc_shr(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL); + if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + + if (get_mode_modulo_shift(a->mode) != 0) + { + temp_val = alloca(sc_get_buffer_length()); + + sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val); + sc_mod(b->value, temp_val, temp_val); + } + else + temp_val = (char*)b->value; + + sc_shr(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } @@ -1185,12 +1319,28 @@ tarval *tarval_shr(tarval *a, tarval *b) */ tarval *tarval_shrs(tarval *a, tarval *b) { + char *temp_val = NULL; ANNOUNCE(); assert(a); assert(b); assert(mode_is_int(a->mode) && mode_is_int(b->mode)); - sc_shrs(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL); + if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + + if (get_mode_modulo_shift(a->mode) != 0) + { + temp_val = alloca(sc_get_buffer_length()); + + sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val); + sc_mod(b->value, temp_val, temp_val); + } + else + temp_val = (char*)b->value; + + sc_shrs(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } @@ -1199,15 +1349,38 @@ tarval *tarval_shrs(tarval *a, tarval *b) */ tarval *tarval_rot(tarval *a, tarval *b) { + char *temp_val = NULL; ANNOUNCE(); assert(a); assert(b); assert(mode_is_int(a->mode) && mode_is_int(b->mode)); - sc_rot(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL); + if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(a->mode) > 1) { + /* vector arithmetic not implemented yet */ + return tarval_bad; + } + + if (get_mode_modulo_shift(a->mode) != 0) + { + temp_val = alloca(sc_get_buffer_length()); + + sc_val_from_ulong(get_mode_modulo_shift(a->mode), temp_val); + sc_mod(b->value, temp_val, temp_val); + } + else + temp_val = (char*)b->value; + + sc_rot(a->value, temp_val, get_mode_size_bits(a->mode), mode_is_signed(a->mode), NULL); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } +/* + * carry flag of the last operation + */ +int tarval_carry(void) +{ + return sc_had_carry(); +} /* * Output of tarvals @@ -1237,17 +1410,17 @@ int tarval_snprintf(char *buf, size_t len, tarval *tv) case TVO_DECIMAL: str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC); - break; + break; case TVO_OCTAL: str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_OCT); - break; + break; case TVO_HEX: case TVO_NATIVE: default: str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX); - break; + break; } return snprintf(buf, len, "%s%s%s", prefix, str, suffix); @@ -1267,32 +1440,21 @@ int tarval_snprintf(char *buf, size_t len, tarval *tv) break; case irms_reference: - if (tv==tarval_P_void) return snprintf(buf, len, "NULL"); - if (tv->value != NULL) - if (tarval_is_entity(tv)) { - if (get_entity_peculiarity((entity *)tv->value) == peculiarity_existent) - return snprintf(buf, len, "%s%s%s", prefix, get_entity_ld_name((entity *)tv->value), suffix); - else { - if (mode_info->mode_output == TVO_NATIVE) - return snprintf(buf, len, "NULL"); - else - return snprintf(buf, len, "0"); - } - } - else { - if (size > tv->length) { - memcpy(buf, tv->value, tv->length); - buf[tv->length] = '\0'; - } - else { - /* truncated */ - memcpy(buf, tv->value, size-1); - buf[size-1] = '\0'; - } - return tv->length; - } + if (tv == tarval_P_void) return snprintf(buf, len, "NULL"); + if (tv->value != NULL){ + if (len > tv->length) { + memcpy(buf, tv->value, tv->length); + buf[tv->length] = '\0'; + } + else { + /* truncated */ + memcpy(buf, tv->value, len-1); + buf[len-1] = '\0'; + } + return tv->length; + } else - return snprintf(buf, len, "void"); + return snprintf(buf, len, "void"); case irms_internal_boolean: switch (mode_info->mode_output) { @@ -1311,7 +1473,7 @@ int tarval_snprintf(char *buf, size_t len, tarval *tv) case irms_control_flow: case irms_memory: case irms_auxiliary: - return snprintf(buf, len, ""); + return snprintf(buf, len, ""); } return 0; @@ -1332,15 +1494,30 @@ int tarval_printf(tarval *tv) { } -char *tarval_bitpattern(tarval *tv) +char *get_tarval_bitpattern(tarval *tv) { - return NULL; + int i, j, pos = 0; + int n = get_mode_size_bits(tv->mode); + int bytes = (n + 7) / 8; + char *res = malloc((n + 1) * sizeof(char)); + unsigned char byte; + + for(i = 0; i < bytes; i++) { + byte = get_tarval_sub_bits(tv, i); + for(j = 1; j < 256; j <<= 1) + if(pos < n) + res[pos++] = j & byte ? '1' : '0'; + } + + res[n] = '\0'; + + return res; } /* * access to the bitpattern */ -unsigned char tarval_sub_bits(tarval *tv, unsigned byte_ofs) +unsigned char get_tarval_sub_bits(tarval *tv, unsigned byte_ofs) { switch (get_mode_sort(tv->mode)) { case irms_int_number: @@ -1362,7 +1539,7 @@ unsigned char tarval_sub_bits(tarval *tv, unsigned byte_ofs) * * Returns zero on success. */ -int tarval_set_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinfo) +int set_tarval_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinfo) { assert(mode); @@ -1375,33 +1552,50 @@ int tarval_set_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinf * * This functions returns the modinfo of a given mode. */ -const tarval_mode_info *tarval_get_mode_output_option(ir_mode *mode) +const tarval_mode_info *get_tarval_mode_output_option(ir_mode *mode) { assert(mode); return mode->tv_priv; } - -/* Identifying some tarvals ??? */ -/* Implemented in old tv.c as such: - * return 0 for additive neutral, - * 1 for multiplicative neutral, - * -1 for bitwise-and neutral - * 2 else +/* + * Identifying tarvals values for algebraic simplifications. * - * Implemented for compatibility */ -long tarval_classify(tarval *tv) + * Returns: + * - TV_CLASSIFY_NULL for additive neutral, + * - TV_CLASSIFY_ONE for multiplicative neutral, + * - TV_CLASSIFY_ALL_ONE for bitwise-and neutral + * - TV_CLASSIFY_OTHER else + */ +tarval_classification_t classify_tarval(tarval *tv) { ANNOUNCE(); - if (!tv || tv == tarval_bad) return 2; + if (!tv || tv == tarval_bad) return TV_CLASSIFY_OTHER; - if (tv == get_mode_null(tv->mode)) return 0; - else if (tv == get_mode_one(tv->mode)) return 1; + if (tv == get_mode_null(tv->mode)) + return TV_CLASSIFY_NULL; + else if (tv == get_mode_one(tv->mode)) + return TV_CLASSIFY_ONE; else if ((get_mode_sort(tv->mode) == irms_int_number) - && (tv == new_tarval_from_long(-1, tv->mode))) return -1; + && (tv == new_tarval_from_long(-1, tv->mode))) + return TV_CLASSIFY_ALL_ONE; - return 2; + return TV_CLASSIFY_OTHER; +} + +/** + * Sets the overflow mode for integer operations. + */ +void tarval_set_integer_overflow_mode(tarval_int_overflow_mode_t ov_mode) { + int_overflow_mode = ov_mode; +} + +/** + * Get the overflow mode for integer operations. + */ +tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void) { + return int_overflow_mode; } /** @@ -1456,17 +1650,25 @@ void init_tarval_2(void) * assign output modes that are compatible with the * old implementation: Hex output */ - tarval_set_mode_output_option(mode_U, &hex_output); - tarval_set_mode_output_option(mode_C, &hex_output); - tarval_set_mode_output_option(mode_Bs, &hex_output); - tarval_set_mode_output_option(mode_Bu, &hex_output); - tarval_set_mode_output_option(mode_Hs, &hex_output); - tarval_set_mode_output_option(mode_Hu, &hex_output); - tarval_set_mode_output_option(mode_Is, &hex_output); - tarval_set_mode_output_option(mode_Iu, &hex_output); - tarval_set_mode_output_option(mode_Ls, &hex_output); - tarval_set_mode_output_option(mode_Lu, &hex_output); - tarval_set_mode_output_option(mode_P, &reference_output); + set_tarval_mode_output_option(mode_U, &hex_output); + set_tarval_mode_output_option(mode_C, &hex_output); + set_tarval_mode_output_option(mode_Bs, &hex_output); + set_tarval_mode_output_option(mode_Bu, &hex_output); + set_tarval_mode_output_option(mode_Hs, &hex_output); + set_tarval_mode_output_option(mode_Hu, &hex_output); + set_tarval_mode_output_option(mode_Is, &hex_output); + set_tarval_mode_output_option(mode_Iu, &hex_output); + set_tarval_mode_output_option(mode_Ls, &hex_output); + set_tarval_mode_output_option(mode_Lu, &hex_output); + set_tarval_mode_output_option(mode_P, &reference_output); +} + +/* free all memory occupied by tarval. */ +void finish_tarval(void) { + finish_strcalc (); + finish_fltcalc (); + del_set(tarvals); tarvals = NULL; + del_set(values); values = NULL; } /****************************************************************************