X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Ftv.c;h=f9cea8730813d63c9fac35979f089b44b3ab1b39;hb=003979e6f8a15a2e380407134af0092268ce2bbc;hp=41960b00408adcb284304dc96c212539f3220538;hpb=54ce4eb3599f32b1dfffeaf0dd071f1907d2b898;p=libfirm diff --git a/ir/tv/tv.c b/ir/tv/tv.c index 41960b004..f9cea8730 100644 --- a/ir/tv/tv.c +++ b/ir/tv/tv.c @@ -42,15 +42,14 @@ #include /* atoi() */ #include /* nice things for strings */ -#include +#include #include "tv_t.h" #include "set.h" /* to store tarvals in */ #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 */ -#include "xprintf.h" -#include "xp_help.h" #include "host.h" #include "strcalc.h" #include "fltcalc.h" @@ -99,7 +98,7 @@ static void _fail_verify(tarval *tv, const char* file, int line) assert(0); } -static void tarval_verify(tarval *tv) +inline static void tarval_verify(tarval *tv) { assert(tv); assert(tv->mode); @@ -135,7 +134,7 @@ static int hash_val(const void *value, unsigned int length) return hash; } -/* finds tarval with value/mode or creates new tarval*/ +/* finds tarval with value/mode or creates new tarval */ static tarval *get_tarval(const void *value, int length, ir_mode *mode) { tarval tv; @@ -163,13 +162,16 @@ static int overflows(tarval *tv) { switch (get_mode_sort(tv->mode)) { - case character: - case int_number: + case irms_character: + case irms_int_number: if (sc_comp(tv->value, get_mode_max(tv->mode)->value) == 1) return 1; if (sc_comp(tv->value, get_mode_min(tv->mode)->value) == -1) return 1; break; - case float_number: + case irms_float_number: + /* + * TODO: check NaNs + */ if (fc_comp(tv->value, get_mode_max(tv->mode)->value) == 1) return 1; if (fc_comp(tv->value, get_mode_min(tv->mode)->value) == -1) return 1; break; @@ -181,18 +183,19 @@ static int overflows(tarval *tv) return 0; } -/**************************************************************************** +/* * public variables declared in tv.h - ****************************************************************************/ + */ tarval *tarval_bad; tarval *tarval_undefined; tarval *tarval_b_false; tarval *tarval_b_true; tarval *tarval_P_void; -/**************************************************************************** +/* * public functions declared in tv.h - ****************************************************************************/ + */ + /* * Constructors ============================================================= */ @@ -205,27 +208,27 @@ tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode) switch (get_mode_sort(mode)) { - case auxiliary: + case irms_auxiliary: assert(0); break; - case internal_boolean: + case irms_internal_boolean: /* match tTrRuUeE/fFaAlLsSeE */ if (strcasecmp(str, "true")) return tarval_b_true; else if (strcasecmp(str, "false")) return tarval_b_true; else return atoi(str) ? tarval_b_true : tarval_b_false; - case float_number: + case irms_float_number: fc_val_from_str(str, len); return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode); - case int_number: - case character: + case irms_int_number: + case irms_character: sc_val_from_str(str, len); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode); - case reference: + case irms_reference: return get_tarval(str, len, mode); } @@ -249,26 +252,29 @@ char *tarval_to_str(tarval *tv) } #endif +/* + * helper function, create a tarval from long + */ tarval *new_tarval_from_long(long l, ir_mode *mode) { ANNOUNCE(); - assert(mode && !(get_mode_sort(mode) == auxiliary)); + assert(mode && !(get_mode_sort(mode) == irms_auxiliary)); switch(get_mode_sort(mode)) { - case internal_boolean: + case irms_internal_boolean: /* XXX C-Semantics ! */ return l ? tarval_b_true : tarval_b_false ; - case int_number: - case character: + case irms_int_number: + case irms_character: sc_val_from_long(l); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode); - case float_number: + case irms_float_number: return new_tarval_from_double((long double)l, mode); - case reference: + case irms_reference: return l ? tarval_bad : get_tarval(NULL, 0, mode); /* null pointer or tarval_bad */ default: @@ -277,17 +283,18 @@ tarval *new_tarval_from_long(long l, ir_mode *mode) return NULL; } +/* returns non-zero if can be converted to long */ int tarval_is_long(tarval *tv) { ANNOUNCE(); - return ((get_mode_sort(tv->mode) == int_number) || (get_mode_sort(tv->mode) == character)); + return ((get_mode_sort(tv->mode) == irms_int_number) || (get_mode_sort(tv->mode) == irms_character)); } /* this might overflow the machine's long, so use only with small values */ long tarval_to_long(tarval* tv) { ANNOUNCE(); - assert(tv && get_mode_sort(tv->mode) == int_number); + assert(tv && get_mode_sort(tv->mode) == irms_int_number); return sc_val_to_long(tv->value); /* might overflow */ } @@ -295,18 +302,19 @@ long tarval_to_long(tarval* tv) tarval *new_tarval_from_double(long double d, ir_mode *mode) { ANNOUNCE(); - assert(mode && (get_mode_sort(mode) == float_number)); + assert(mode && (get_mode_sort(mode) == irms_float_number)); fc_val_from_float(d); return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode); } +/* returns non-zero if can be converted to double */ int tarval_is_double(tarval *tv) { ANNOUNCE(); assert(tv); - return (get_mode_sort(tv->mode) == float_number); + return (get_mode_sort(tv->mode) == irms_float_number); } long double tarval_to_double(tarval *tv) @@ -323,7 +331,7 @@ tarval *new_tarval_from_entity (entity *ent, ir_mode *mode) { ANNOUNCE(); assert(ent); - assert(mode && (get_mode_sort(mode) == reference)); + assert(mode && (get_mode_sort(mode) == irms_reference)); return get_tarval((void *)ent, 0, mode); } @@ -332,7 +340,7 @@ int tarval_is_entity(tarval *tv) ANNOUNCE(); assert(tv); /* tv->value == NULL means dereferencing a null pointer */ - return ((get_mode_sort(tv->mode) == reference) && (tv->value != NULL) && (tv->length == 0)); + return ((get_mode_sort(tv->mode) == irms_reference) && (tv->value != NULL) && (tv->length == 0)); } entity *tarval_to_entity(tarval *tv) @@ -348,21 +356,30 @@ entity *tarval_to_entity(tarval *tv) } } +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 ======================================== */ -#ifdef TARVAL_ACCESS_DEFINES -# undef get_tarval_mode -#endif ir_mode *get_tarval_mode (tarval *tv) /* get the mode of the tarval */ { ANNOUNCE(); assert(tv); return tv->mode; } -#ifdef TARVAL_ACCESS_DEFINES -# define get_tarval_mode(tv) (tv)->mode -#endif /* * Special value query functions ============================================ @@ -407,20 +424,20 @@ tarval *get_tarval_max(ir_mode *mode) switch(get_mode_sort(mode)) { - case reference: - case auxiliary: + case irms_reference: + case irms_auxiliary: assert(0); break; - case internal_boolean: + case irms_internal_boolean: return tarval_b_true; - case float_number: + case irms_float_number: fc_get_max(get_mode_size_bits(mode)); return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode); - case int_number: - case character: + case irms_int_number: + case irms_character: sc_max_from_bits(get_mode_size_bits(mode), mode_is_signed(mode)); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode); } @@ -434,20 +451,20 @@ tarval *get_tarval_min(ir_mode *mode) switch(get_mode_sort(mode)) { - case reference: - case auxiliary: + case irms_reference: + case irms_auxiliary: assert(0); break; - case internal_boolean: + case irms_internal_boolean: return tarval_b_false; - case float_number: + case irms_float_number: fc_get_min(get_mode_size_bits(mode)); return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode); - case int_number: - case character: + case irms_int_number: + case irms_character: sc_min_from_bits(get_mode_size_bits(mode), mode_is_signed(mode)); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode); } @@ -461,19 +478,19 @@ tarval *get_tarval_null(ir_mode *mode) switch(get_mode_sort(mode)) { - case auxiliary: - case internal_boolean: + case irms_auxiliary: + case irms_internal_boolean: assert(0); break; - case float_number: + case irms_float_number: return new_tarval_from_double(0.0, mode); - case int_number: - case character: + case irms_int_number: + case irms_character: return new_tarval_from_long(0l, mode); - case reference: + case irms_reference: return tarval_P_void; } return tarval_bad; @@ -486,17 +503,17 @@ tarval *get_tarval_one(ir_mode *mode) switch(get_mode_sort(mode)) { - case auxiliary: - case internal_boolean: - case reference: + case irms_auxiliary: + case irms_internal_boolean: + case irms_reference: assert(0); break; - case float_number: + case irms_float_number: return new_tarval_from_double(1.0, mode); - case int_number: - case character: + case irms_int_number: + case irms_character: return new_tarval_from_long(1l, mode); break; } @@ -508,7 +525,7 @@ tarval *get_tarval_nan(ir_mode *mode) ANNOUNCE(); assert(mode); - if (get_mode_sort(mode) == float_number) { + if (get_mode_sort(mode) == irms_float_number) { fc_get_nan(); return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode); } @@ -523,7 +540,7 @@ tarval *get_tarval_inf(ir_mode *mode) ANNOUNCE(); assert(mode); - if (get_mode_sort(mode) == float_number) { + if (get_mode_sort(mode) == irms_float_number) { fc_get_inf(); return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode); } @@ -537,7 +554,9 @@ tarval *get_tarval_inf(ir_mode *mode) * Arithmethic operations on tarvals ======================================== */ -/* test if negative number, 1 means 'yes' */ +/* + * test if negative number, 1 means 'yes' + */ int tarval_is_negative(tarval *a) { ANNOUNCE(); @@ -545,12 +564,12 @@ int tarval_is_negative(tarval *a) switch (get_mode_sort(a->mode)) { - case int_number: + 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; - case float_number: + case irms_float_number: return fc_comp(a->value, get_mode_null(a->mode)->value) == -1 ? 1 : 0; default: @@ -559,7 +578,19 @@ int tarval_is_negative(tarval *a) } } -/* comparison */ +/* + * test if null, 1 means 'yes' + */ +int tarval_is_null(tarval *a) +{ + ir_mode *m = get_tarval_mode(a); + + return a == get_tarval_null(m); +} + +/* + * comparison + */ pnc_number tarval_cmp(tarval *a, tarval *b) { ANNOUNCE(); @@ -574,25 +605,28 @@ pnc_number tarval_cmp(tarval *a, tarval *b) /* Here the two tarvals are unequal and of the same mode */ switch (get_mode_sort(a->mode)) { - case auxiliary: + case irms_auxiliary: return False; - case float_number: + case irms_float_number: return (fc_comp(a->value, b->value)==1)?(Gt):(Lt); - case int_number: - case character: + case irms_int_number: + case irms_character: return (sc_comp(a->value, b->value)==1)?(Gt):(Lt); - case internal_boolean: + case irms_internal_boolean: return (a == tarval_b_true)?(Gt):(Lt); - case reference: + case irms_reference: return Uo; } return False; } +/* + * convert to other mode + */ tarval *tarval_convert_to(tarval *src, ir_mode *m) { ANNOUNCE(); @@ -605,27 +639,39 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) switch (get_mode_sort(src->mode)) { - case auxiliary: + case irms_auxiliary: break; - case float_number: + case irms_float_number: + switch (get_mode_sort(m)) { + case irms_float_number: + tv.mode = m; + tv.length = src->length; + tv.value = src->value; + if (overflows(&tv)) { + return tarval_bad; + } + + return INSERT_TARVAL(&tv); + + default: + break; + } break; - case int_number: - switch (get_mode_sort(m)) - { - case int_number: - case character: - tv.mode = m; + case irms_int_number: + switch (get_mode_sort(m)) { + case irms_int_number: + case irms_character: + tv.mode = m; tv.length = src->length; - tv.value = src->value; + tv.value = src->value; if (overflows(&tv)) - { return tarval_bad; - } + return INSERT_TARVAL(&tv); - case internal_boolean: + case irms_internal_boolean: /* XXX C semantics */ if (src == get_mode_null(src->mode)) return tarval_b_false; else return tarval_b_true; @@ -635,10 +681,10 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) } break; - case internal_boolean: + case irms_internal_boolean: switch (get_mode_sort(m)) { - case int_number: + case irms_int_number: if (src == tarval_b_true) return get_mode_one(m); else return get_mode_null(m); @@ -647,31 +693,32 @@ tarval *tarval_convert_to(tarval *src, ir_mode *m) } break; - case character: + case irms_character: break; - case reference: + case irms_reference: break; } return tarval_bad; } -tarval *tarval_neg(tarval *a) /* negation */ +/* + * negation + */ +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 */ -printf("NEG\n"); switch (get_mode_sort(a->mode)) { - case int_number: + case irms_int_number: sc_neg(a->value); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); - case float_number: -printf("FP NEG\n"); + case irms_float_number: fc_neg(a->value); return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode); @@ -680,23 +727,26 @@ printf("FP NEG\n"); } } -tarval *tarval_add(tarval *a, tarval *b) /* addition */ +/* + * addition + */ +tarval *tarval_add(tarval *a, tarval *b) { ANNOUNCE(); assert(a); assert(b); - assert((a->mode == b->mode) || (get_mode_sort(a->mode) == character && mode_is_int(b->mode))); + assert((a->mode == b->mode) || (get_mode_sort(a->mode) == irms_character && mode_is_int(b->mode))); switch (get_mode_sort(a->mode)) { - case character: - case int_number: + case irms_character: + case irms_int_number: /* modes of a,b are equal, so result has mode of a as this might be the character */ sc_add(a->value, b->value); /* FIXME: Check for overflow */ return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); - case float_number: + case irms_float_number: /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */ fc_add(a->value, b->value); return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode); @@ -706,23 +756,26 @@ tarval *tarval_add(tarval *a, tarval *b) /* addition */ } } -tarval *tarval_sub(tarval *a, tarval *b) /* subtraction */ +/* + * subtraction + */ +tarval *tarval_sub(tarval *a, tarval *b) { ANNOUNCE(); assert(a); assert(b); - assert((a->mode == b->mode) || (get_mode_sort(a->mode) == character && mode_is_int(b->mode))); + assert((a->mode == b->mode) || (get_mode_sort(a->mode) == irms_character && mode_is_int(b->mode))); switch (get_mode_sort(a->mode)) { - case character: - case int_number: + case irms_character: + case irms_int_number: /* modes of a,b are equal, so result has mode of a as this might be the character */ sc_sub(a->value, b->value); /* FIXME: check for overflow */ return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); - case float_number: + case irms_float_number: /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */ fc_add(a->value, b->value); return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode); @@ -732,7 +785,10 @@ tarval *tarval_sub(tarval *a, tarval *b) /* subtraction */ } } -tarval *tarval_mul(tarval *a, tarval *b) /* multiplication */ +/* + * multiplication + */ +tarval *tarval_mul(tarval *a, tarval *b) { ANNOUNCE(); assert(a); @@ -741,13 +797,13 @@ tarval *tarval_mul(tarval *a, tarval *b) /* multiplication */ switch (get_mode_sort(a->mode)) { - case int_number: + case irms_int_number: /* modes of a,b are equal */ sc_mul(a->value, b->value); /* FIXME: check for overflow */ return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); - case float_number: + case irms_float_number: /* FIXME: Overflow/Underflow/transition to inf when mode < 80bit */ fc_add(a->value, b->value); return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode); @@ -757,7 +813,10 @@ tarval *tarval_mul(tarval *a, tarval *b) /* multiplication */ } } -tarval *tarval_quo(tarval *a, tarval *b) /* floating point division */ +/* + * floating point division + */ +tarval *tarval_quo(tarval *a, tarval *b) { ANNOUNCE(); assert(a); @@ -769,7 +828,10 @@ tarval *tarval_quo(tarval *a, tarval *b) /* floating point division */ return get_tarval(fc_get_buffer(), fc_get_buffer_length(), a->mode); } -tarval *tarval_div(tarval *a, tarval *b) /* integer division */ +/* + * integer division + */ +tarval *tarval_div(tarval *a, tarval *b) { ANNOUNCE(); assert(a); @@ -781,7 +843,10 @@ tarval *tarval_div(tarval *a, tarval *b) /* integer division */ return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } -tarval *tarval_mod(tarval *a, tarval *b) /* remainder */ +/* + * remainder + */ +tarval *tarval_mod(tarval *a, tarval *b) { ANNOUNCE(); assert(a); @@ -793,7 +858,10 @@ tarval *tarval_mod(tarval *a, tarval *b) /* remainder */ return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } -tarval *tarval_abs(tarval *a) /* absolute value */ +/* + * absolute value + */ +tarval *tarval_abs(tarval *a) { ANNOUNCE(); assert(a); @@ -801,7 +869,7 @@ tarval *tarval_abs(tarval *a) /* absolute value */ switch (get_mode_sort(a->mode)) { - case int_number: + case irms_int_number: if (sc_comp(a->value, get_mode_null(a->mode)->value) == -1) { sc_neg(a->value); @@ -809,7 +877,7 @@ tarval *tarval_abs(tarval *a) /* absolute value */ } return a; - case float_number: + case irms_float_number: break; default: @@ -818,27 +886,49 @@ tarval *tarval_abs(tarval *a) /* absolute value */ return tarval_bad; } -tarval *tarval_and(tarval *a, tarval *b) /* bitwise and */ +/* + * bitwise and + */ +tarval *tarval_and(tarval *a, tarval *b) { ANNOUNCE(); assert(a); assert(b); - assert((a->mode == b->mode) && mode_is_int(a->mode)); + assert(a->mode == b->mode); + + /* GL: needed for easy optimization. */ + if (a->mode == mode_b) return (a == tarval_b_false) ? a : b; + + assert(mode_is_int(a->mode)); sc_and(a->value, b->value); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } -tarval *tarval_or (tarval *a, tarval *b) /* bitwise or */ + +/* + * bitwise or + */ +tarval *tarval_or (tarval *a, tarval *b) { ANNOUNCE(); assert(a); assert(b); - assert((a->mode == b->mode) && mode_is_int(a->mode)); + assert(a->mode == b->mode); + + /* GL: needed for easy optimization. */ + if (a->mode == mode_b) return (a == tarval_b_true) ? a : b; + + + assert(mode_is_int(a->mode)); sc_or(a->value, b->value); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } -tarval *tarval_eor(tarval *a, tarval *b) /* bitwise exclusive or (xor) */ + +/* + * bitwise exclusive or (xor) + */ +tarval *tarval_eor(tarval *a, tarval *b) { ANNOUNCE(); assert(a); @@ -849,7 +939,10 @@ tarval *tarval_eor(tarval *a, tarval *b) /* bitwise exclusive or (xor) */ return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } -tarval *tarval_shl(tarval *a, tarval *b) /* bitwise left shift */ +/* + * bitwise left shift + */ +tarval *tarval_shl(tarval *a, tarval *b) { ANNOUNCE(); assert(a); @@ -859,7 +952,11 @@ tarval *tarval_shl(tarval *a, tarval *b) /* bitwise left shift */ sc_shl(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode)); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } -tarval *tarval_shr(tarval *a, tarval *b) /* bitwise unsigned right shift */ + +/* + * bitwise unsigned right shift + */ +tarval *tarval_shr(tarval *a, tarval *b) { ANNOUNCE(); assert(a); @@ -869,7 +966,11 @@ tarval *tarval_shr(tarval *a, tarval *b) /* bitwise unsigned right shift */ sc_shr(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode)); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } -tarval *tarval_shrs(tarval *a, tarval *b) /* bitwise signed right shift */ + +/* + * bitwise signed right shift + */ +tarval *tarval_shrs(tarval *a, tarval *b) { ANNOUNCE(); assert(a); @@ -879,7 +980,11 @@ tarval *tarval_shrs(tarval *a, tarval *b) /* bitwise signed right shift */ sc_shrs(a->value, b->value, get_mode_size_bits(a->mode), mode_is_signed(a->mode)); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } -tarval *tarval_rot(tarval *a, tarval *b) /* bitwise rotation */ + +/* + * bitwise rotation + */ +tarval *tarval_rot(tarval *a, tarval *b) { ANNOUNCE(); assert(a); @@ -890,48 +995,115 @@ tarval *tarval_rot(tarval *a, tarval *b) /* bitwise rotation */ return get_tarval(sc_get_buffer(), sc_get_buffer_length(), a->mode); } -/** *********** Output of tarvals *********** **/ -int tarval_print(XP_PAR1, const xprintf_info *info ATTRIBUTE((unused)), XP_PARN) + +/* + * Output of tarvals + */ +int tarval_snprintf(char *buf, size_t len, tarval *tv) { - ANNOUNCE(); - tarval *tv; + static const tarval_mode_info default_info = { TVO_NATIVE, NULL, NULL }; + const char *str; - char buf[100]; + char tv_buf[100]; + const tarval_mode_info *mode_info; + const char *prefix, *suffix; + + ANNOUNCE(); + + mode_info = tv->mode->tv_priv; + if (! mode_info) + mode_info = &default_info; + prefix = mode_info->mode_prefix ? mode_info->mode_prefix : ""; + suffix = mode_info->mode_suffix ? mode_info->mode_suffix : ""; - tv = XP_GETARG(tarval *, 0); switch (get_mode_sort(tv->mode)) { - case int_number: - case character: - str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC); - return XPF1R("%s", str); + case irms_int_number: + case irms_character: + switch (mode_info->mode_output) { + + case TVO_DECIMAL: + str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_DEC); + break; + + case TVO_OCTAL: + str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_OCT); + break; + + case TVO_HEX: + case TVO_NATIVE: + default: + str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX); + break; + } + return snprintf(buf, len, "%s%s%s", prefix, str, suffix); - case float_number: - return XPF1R("%s", fc_print_dec(tv->value, buf, sizeof(buf))); + case irms_float_number: + return snprintf(buf, len, "%s%s%s", prefix, fc_print_dec(tv->value, tv_buf, sizeof(tv_buf)), suffix); - case reference: + case irms_reference: if (tv->value != NULL) - if (tarval_is_entity(tv)) + if (tarval_is_entity(tv)) { if (get_entity_peculiarity((entity *)tv->value) == existent) - return XPF1R("&(%I)", get_entity_ld_ident((entity *)tv->value)); - else - return XPSR("NULL"); - else - return XPMR((char*)tv->value, tv->length); + 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; + } else - return XPSR("void"); + return snprintf(buf, len, "void"); + + case irms_internal_boolean: + switch (mode_info->mode_output) { + + case TVO_DECIMAL: + case TVO_OCTAL: + case TVO_HEX: + case TVO_BINARY: + return snprintf(buf, len, "%s%c%s", prefix, (tv == tarval_b_true) ? '1' : '0', suffix); - case internal_boolean: - if (tv == tarval_b_true) return XPSR("true"); - else return XPSR("false"); + case TVO_NATIVE: + default: + return snprintf(buf, len, "%s%s%s", prefix, (tv == tarval_b_true) ? "true" : "false", suffix); + } - case auxiliary: - return XPSR(""); + case irms_auxiliary: + return snprintf(buf, len, ""); } return 0; } + +/** + * Output of tarvals to stdio. + */ +int tarval_printf(tarval *tv) { + char buf[1024]; + int res; + + res = tarval_snprintf(buf, sizeof(buf), tv); + assert(res < sizeof(buf) && "buffer to small for tarval_snprintf"); + printf(buf); + return res; +} + + char *tarval_bitpattern(tarval *tv) { return NULL; @@ -943,11 +1115,11 @@ char *tarval_bitpattern(tarval *tv) unsigned char tarval_sub_bits(tarval *tv, unsigned byte_ofs) { switch (get_mode_sort(tv->mode)) { - case int_number: - case character: + case irms_int_number: + case irms_character: return sc_sub_bits(tv->value, tv->length, byte_ofs); - case float_number: + case irms_float_number: return fc_sub_bits(tv->value, get_mode_size_bits(tv->mode), byte_ofs); default: @@ -955,6 +1127,21 @@ unsigned char tarval_sub_bits(tarval *tv, unsigned byte_ofs) } } +/* + * Specify the output options of one mode. + * + * This functions stores the modinfo, so DO NOT DESTROY it. + * + * Returns zero on success. + */ +int tarval_set_mode_output_option(ir_mode *mode, const tarval_mode_info *modeinfo) +{ + assert(mode); + + mode->tv_priv = modeinfo; + return 0; +} + /* Identifying some tarvals ??? */ /* Implemented in old tv.c as such: * return 0 for additive neutral, @@ -970,13 +1157,15 @@ long tarval_classify(tarval *tv) if (tv == get_mode_null(tv->mode)) return 0; else if (tv == get_mode_one(tv->mode)) return 1; - else if ((get_mode_sort(tv->mode) == int_number) + else if ((get_mode_sort(tv->mode) == irms_int_number) && (tv == new_tarval_from_long(-1, tv->mode))) return -1; return 2; } -/* Initialization of the tarval module: called before init_mode() */ +/* + * Initialization of the tarval module: called before init_mode() + */ void init_tarval_1(void) { ANNOUNCE(); @@ -984,18 +1173,42 @@ void init_tarval_1(void) * an initial size, which is the expected number of constants */ tarvals = new_set(memcmp, TUNE_NCONSTANTS); values = new_set(memcmp, TUNE_NCONSTANTS); + /* init with default precision */ + init_strcalc(0); + /* init_fltcalc(0); not yet*/ } -/* Initialization of the tarval module: called after init_mode() */ +/** + * default mode_info for output as HEX + */ +static const tarval_mode_info hex_output = { + TVO_HEX, + "0x", + NULL, +}; + +/** + * default mode_info for output as reference + */ +static const tarval_mode_info reference_output = { + TVO_NATIVE, + "&(", + ")", +}; + + +/* + * Initialization of the tarval module: called after init_mode() + */ void init_tarval_2(void) { ANNOUNCE(); tarval_bad = (tarval*)malloc(sizeof(tarval)); - tarval_bad->mode = NULL; + tarval_bad->mode = mode_BAD; tarval_undefined = (tarval*)malloc(sizeof(tarval)); - tarval_undefined->mode = NULL; + tarval_undefined->mode = mode_ANY; tarval_b_true = (tarval*)malloc(sizeof(tarval)); tarval_b_true->mode = mode_b; @@ -1005,22 +1218,26 @@ void init_tarval_2(void) tarval_P_void = (tarval*)malloc(sizeof(tarval)); tarval_P_void->mode = mode_P; + + /* + * 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_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); } /**************************************************************************** * end of tv.c ****************************************************************************/ - -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 forever (They live on an obstack.). - 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. We cannot remove tarvals from the obstack but we can - remove the entry in the hash table. */ - /* this will be re-implemented later */ - ANNOUNCE(); -}