X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Ftv.c;h=36487127c25ae2adf56806deea25ba7875e790f1;hb=6571b31236f780199ba476adc33ee23518200497;hp=e0b51c18b735148b618076a36f1d4be70cb81014;hpb=e07b61c6ed5d198a484761f8a40a4f26520d964d;p=libfirm diff --git a/ir/tv/tv.c b/ir/tv/tv.c index e0b51c18b..36487127c 100644 --- a/ir/tv/tv.c +++ b/ir/tv/tv.c @@ -24,34 +24,28 @@ * @date 2003 * @author Mathias Heil * @version $Id$ - * @summary + * @brief * * Values are stored in a format depending upon chosen arithmetic * module. Default uses strcalc and fltcalc. * This implementation assumes: * - target has IEEE-754 floating-point arithmetic. */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif +#include "config.h" -#include /* assertions */ -#include /* atoi() */ -#ifdef HAVE_STRING_H -# include /* nice things for strings */ -#endif +#include +#include +#include #ifdef HAVE_STRINGS_H -#include /* strings.h also includes bsd only function strcasecmp */ -#endif -#ifdef HAVE_STDLIB_H -# include +#include #endif +#include #include "tv_t.h" -#include "set.h" /* to store tarvals in */ -#include "entity_t.h" /* needed to store pointers to entities */ +#include "set.h" +#include "entity_t.h" #include "irmode_t.h" -#include "irnode.h" /* defines boolean return values (pnc_number)*/ +#include "irnode.h" #include "strcalc.h" #include "fltcalc.h" #include "irtools.h" @@ -99,6 +93,9 @@ static struct set *tarvals = NULL; /** A set containing all existing values. */ static struct set *values = NULL; +/** The carry flag for SOME operations. -1 means UNDEFINED here */ +static int carry_flag = -1; + /** The integer overflow mode. */ static tarval_int_overflow_mode_t int_overflow_mode = TV_OVERFLOW_WRAP; @@ -132,10 +129,10 @@ static void _fail_verify(tarval *tv, const char* file, int line) panic("%s:%d: Invalid tarval (null)", file, line); } #ifdef __GNUC__ -INLINE static void tarval_verify(tarval *tv) __attribute__ ((unused)); +inline static void tarval_verify(tarval *tv) __attribute__ ((unused)); #endif -INLINE static void tarval_verify(tarval *tv) +inline static void tarval_verify(tarval *tv) { assert(tv); assert(tv->mode); @@ -338,10 +335,10 @@ tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode) case irms_internal_boolean: /* match [tT][rR][uU][eE]|[fF][aA][lL][sS][eE] */ - if (strcasecmp(str, "true")) - return tarval_b_true; - else if (strcasecmp(str, "false")) + if (!strcasecmp(str, "true")) return tarval_b_true; + else if (!strcasecmp(str, "false")) + return tarval_b_false; else /* XXX This is C semantics */ return atoi(str) ? tarval_b_true : tarval_b_false; @@ -352,7 +349,9 @@ tarval *new_tarval_from_str(const char *str, size_t len, ir_mode *mode) return get_tarval(fc_get_buffer(), fc_get_buffer_length(), mode); case irms_reference: - /* same as integer modes */ + if (!strcasecmp(str, "null")) + return get_tarval_null(mode); + /* FALLTHROUGH */ case irms_int_number: sc_val_from_str(str, len, NULL, mode); return get_tarval(sc_get_buffer(), sc_get_buffer_length(), mode); @@ -699,8 +698,6 @@ tarval *get_tarval_minus_inf(ir_mode *mode) { * test if negative number, 1 means 'yes' */ int tarval_is_negative(tarval *a) { - assert(a); - if (get_mode_n_vector_elems(a->mode) > 1) panic("vector arithmetic not implemented yet"); @@ -755,8 +752,7 @@ int tarval_is_minus_one(tarval *a) { * comparison */ pn_Cmp tarval_cmp(tarval *a, tarval *b) { - assert(a); - assert(b); + carry_flag = -1; if (a == tarval_bad || b == tarval_bad) { panic("Comparison with tarval_bad"); @@ -820,6 +816,8 @@ tarval *tarval_convert_to(tarval *src, ir_mode *dst_mode) { fp_value *res; const ieee_descriptor_t *desc; + carry_flag = -1; + assert(src); assert(dst_mode); @@ -928,7 +926,7 @@ tarval *tarval_convert_to(tarval *src, ir_mode *dst_mode) { tarval *tarval_not(tarval *a) { char *buffer; - assert(a); + carry_flag = -1; /* works for vector mode without changes */ @@ -958,9 +956,10 @@ tarval *tarval_not(tarval *a) { tarval *tarval_neg(tarval *a) { char *buffer; - assert(a); assert(mode_is_num(a->mode)); /* negation only for numerical values */ + carry_flag = -1; + /* note: negation is allowed even for unsigned modes. */ if (get_mode_n_vector_elems(a->mode) > 1) { @@ -993,8 +992,7 @@ tarval *tarval_neg(tarval *a) { tarval *tarval_add(tarval *a, tarval *b) { char *buffer; - assert(a); - assert(b); + carry_flag = -1; if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(b->mode) > 1) { /* vector arithmetic not implemented yet */ @@ -1015,6 +1013,7 @@ tarval *tarval_add(tarval *a, tarval *b) { /* modes of a,b are equal, so result has mode of a as this might be the character */ buffer = alloca(sc_get_buffer_length()); sc_add(a->value, b->value, buffer); + carry_flag = sc_get_bit_at(buffer, get_mode_size_bits(a->mode)); return get_tarval_overflow(buffer, a->length, a->mode); case irms_float_number: @@ -1035,8 +1034,7 @@ tarval *tarval_add(tarval *a, tarval *b) { tarval *tarval_sub(tarval *a, tarval *b, ir_mode *dst_mode) { char *buffer; - assert(a); - assert(b); + carry_flag = -1; if (get_mode_n_vector_elems(a->mode) > 1 || get_mode_n_vector_elems(b->mode) > 1) { /* vector arithmetic not implemented yet */ @@ -1057,6 +1055,7 @@ tarval *tarval_sub(tarval *a, tarval *b, ir_mode *dst_mode) { /* modes of a,b are equal, so result has mode of a as this might be the character */ buffer = alloca(sc_get_buffer_length()); sc_sub(a->value, b->value, buffer); + carry_flag = sc_get_bit_at(buffer, get_mode_size_bits(a->mode)); return get_tarval_overflow(buffer, a->length, a->mode); case irms_float_number: @@ -1077,10 +1076,10 @@ tarval *tarval_sub(tarval *a, tarval *b, ir_mode *dst_mode) { tarval *tarval_mul(tarval *a, tarval *b) { char *buffer; - assert(a); - assert(b); assert(a->mode == b->mode); + carry_flag = -1; + if (get_mode_n_vector_elems(a->mode) > 1) { /* vector arithmetic not implemented yet */ return tarval_bad; @@ -1109,10 +1108,10 @@ tarval *tarval_mul(tarval *a, tarval *b) { * floating point division */ tarval *tarval_quo(tarval *a, tarval *b) { - assert(a); - assert(b); assert((a->mode == b->mode) && mode_is_float(a->mode)); + carry_flag = -1; + if (no_float) return tarval_bad; @@ -1130,10 +1129,10 @@ tarval *tarval_quo(tarval *a, tarval *b) { * overflow is impossible, but look out for division by zero */ tarval *tarval_div(tarval *a, tarval *b) { - assert(a); - assert(b); assert((a->mode == b->mode) && mode_is_int(a->mode)); + carry_flag = -1; + if (get_mode_n_vector_elems(a->mode) > 1) { /* vector arithmetic not implemented yet */ return tarval_bad; @@ -1151,10 +1150,10 @@ tarval *tarval_div(tarval *a, tarval *b) { * overflow is impossible, but look out for division by zero */ tarval *tarval_mod(tarval *a, tarval *b) { - assert(a); - assert(b); assert((a->mode == b->mode) && mode_is_int(a->mode)); + carry_flag = -1; + if (get_mode_n_vector_elems(a->mode) > 1) { /* vector arithmetic not implemented yet */ return tarval_bad; @@ -1176,10 +1175,10 @@ tarval *tarval_divmod(tarval *a, tarval *b, tarval **mod) { char *div_res = alloca(len); char *mod_res = alloca(len); - assert(a); - assert(b); assert((a->mode == b->mode) && mode_is_int(a->mode)); + carry_flag = -1; + if (get_mode_n_vector_elems(a->mode) > 1) { /* vector arithmetic not implemented yet */ return tarval_bad; @@ -1200,7 +1199,7 @@ tarval *tarval_divmod(tarval *a, tarval *b, tarval **mod) { tarval *tarval_abs(tarval *a) { char *buffer; - assert(a); + carry_flag = -1; assert(mode_is_num(a->mode)); if (get_mode_n_vector_elems(a->mode) > 1) { @@ -1238,11 +1237,10 @@ tarval *tarval_abs(tarval *a) { * bitwise and */ tarval *tarval_and(tarval *a, tarval *b) { - assert(a); - assert(b); assert(a->mode == b->mode); /* works even for vector modes */ + carry_flag = 0; switch (get_mode_sort(a->mode)) { case irms_internal_boolean: @@ -1262,11 +1260,10 @@ tarval *tarval_and(tarval *a, tarval *b) { * bitwise or */ tarval *tarval_or(tarval *a, tarval *b) { - assert(a); - assert(b); assert(a->mode == b->mode); /* works even for vector modes */ + carry_flag = 0; switch (get_mode_sort(a->mode)) { case irms_internal_boolean: @@ -1286,11 +1283,10 @@ tarval *tarval_or(tarval *a, tarval *b) { * bitwise exclusive or (xor) */ tarval *tarval_eor(tarval *a, tarval *b) { - assert(a); - assert(b); assert((a->mode == b->mode)); /* works even for vector modes */ + carry_flag = 0; switch (get_mode_sort(a->mode)) { case irms_internal_boolean: @@ -1312,10 +1308,10 @@ tarval *tarval_eor(tarval *a, tarval *b) { tarval *tarval_shl(tarval *a, tarval *b) { char *temp_val = NULL; - assert(a); - assert(b); assert(mode_is_int(a->mode) && mode_is_int(b->mode)); + carry_flag = -1; + 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; @@ -1339,10 +1335,10 @@ tarval *tarval_shl(tarval *a, tarval *b) { tarval *tarval_shr(tarval *a, tarval *b) { char *temp_val = NULL; - assert(a); - assert(b); assert(mode_is_int(a->mode) && mode_is_int(b->mode)); + carry_flag = -1; + 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; @@ -1366,10 +1362,10 @@ tarval *tarval_shr(tarval *a, tarval *b) { tarval *tarval_shrs(tarval *a, tarval *b) { char *temp_val = NULL; - assert(a); - assert(b); assert(mode_is_int(a->mode) && mode_is_int(b->mode)); + carry_flag = -1; + 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; @@ -1393,10 +1389,10 @@ tarval *tarval_shrs(tarval *a, tarval *b) { tarval *tarval_rotl(tarval *a, tarval *b) { char *temp_val = NULL; - assert(a); - assert(b); assert(mode_is_int(a->mode) && mode_is_int(b->mode)); + carry_flag = -1; + 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; @@ -1418,8 +1414,9 @@ tarval *tarval_rotl(tarval *a, tarval *b) { * carry flag of the last operation */ int tarval_carry(void) { - panic("tarval_carry() requetsed: not implemented on all operations"); - return sc_had_carry(); + if (carry_flag == -1) + panic("Carry undefined for the last operation"); + return carry_flag; } /* @@ -1442,7 +1439,7 @@ int tarval_snprintf(char *buf, size_t len, tarval *tv) { switch (get_mode_sort(tv->mode)) { case irms_reference: if (tv == tv->mode->null) return snprintf(buf, len, "NULL"); - /* fall through */ + /* FALLTHROUGH */ case irms_int_number: switch (mode_info->mode_output) { @@ -1454,8 +1451,9 @@ int tarval_snprintf(char *buf, size_t len, tarval *tv) { str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_OCT, 0); break; - case TVO_HEX: case TVO_NATIVE: + prefix = "0x"; + case TVO_HEX: default: str = sc_print(tv->value, get_mode_size_bits(tv->mode), SC_HEX, 0); break; @@ -1517,7 +1515,7 @@ int tarval_printf(tarval *tv) { res = tarval_snprintf(buf, sizeof(buf), tv); assert(res < (int) sizeof(buf) && "buffer to small for tarval_snprintf"); - printf(buf); + printf("%s", buf); return res; } @@ -1691,11 +1689,12 @@ tarval_int_overflow_mode_t tarval_get_integer_overflow_mode(void) { } /* Enable/Disable floating point constant folding. */ -int tarval_enable_fp_ops(int enable) { - int old = !no_float; - +void tarval_enable_fp_ops(int enable) { no_float = !enable; - return old; +} + +int tarval_fp_ops_enabled(void) { + return !no_float; } /**