From 7816a44e81b81659b2cf355c8a4c9127de016d50 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Tue, 2 Oct 2007 07:46:21 +0000 Subject: [PATCH] fix fehler89 by correctly truncating tarvals (wrote a new sc_truncate function) [r16028] --- ir/tv/strcalc.c | 19 ++++++++++++++++++- ir/tv/strcalc.h | 3 +++ ir/tv/tv.c | 12 ++++++------ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/ir/tv/strcalc.c b/ir/tv/strcalc.c index dc6879645..43d126b29 100644 --- a/ir/tv/strcalc.c +++ b/ir/tv/strcalc.c @@ -1180,6 +1180,23 @@ void sc_max_from_bits(unsigned int num_bits, unsigned int sign, void *buffer) { *pos++ = SC_0; } +void sc_truncate(unsigned int num_bits, void *buffer) { + char *pos = buffer + (num_bits / 4); + char *end = buffer + calc_buffer_size; + + assert(pos < end); + + switch(num_bits % 4) { + case 0: /* nothing to do */ break; + case 1: *pos = and_table[_val(*pos)][SC_1]; pos++; break; + case 2: *pos = and_table[_val(*pos)][SC_3]; pos++; break; + case 3: *pos = and_table[_val(*pos)][SC_7]; pos++; break; + } + + for( ; pos < end; ++pos) + *pos = SC_0; +} + int sc_comp(const void* value1, const void* value2) { int counter = calc_buffer_size - 1; const char *val1 = (const char *)value1; @@ -1288,7 +1305,7 @@ unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs) { res |= _val(val[nibble_ofs + 1]) << 4; /* kick bits outsize */ - if (len < 8*byte_ofs) { + if (len < (int) (8*byte_ofs)) { res &= 0xFF >> (8*byte_ofs - len); } return res; diff --git a/ir/tv/strcalc.h b/ir/tv/strcalc.h index ec666bc9b..49b3a28b6 100644 --- a/ir/tv/strcalc.h +++ b/ir/tv/strcalc.h @@ -200,6 +200,9 @@ long sc_val_to_long(const void *val); void sc_min_from_bits(unsigned int num_bits, unsigned int sign, void *buffer); void sc_max_from_bits(unsigned int num_bits, unsigned int sign, void *buffer); +/** truncates a value to lowest @p num_bits bits */ +void sc_truncate(unsigned num_bits, void *buffer); + /** * Compares val1 and val2 */ diff --git a/ir/tv/tv.c b/ir/tv/tv.c index eaa888674..096381307 100644 --- a/ir/tv/tv.c +++ b/ir/tv/tv.c @@ -193,8 +193,8 @@ static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode) case irms_reference: /* addresses always wrap around */ temp = alloca(sc_get_buffer_length()); - sc_val_from_ulong(-1, temp); - sc_and(temp, value, temp); + memcpy(temp, sc_get_buffer(), sc_get_buffer_length()); + sc_truncate(get_mode_size_bits(mode), temp); /* the sc_ module expects that all bits are set ... */ sign_extend(temp, mode); return get_tarval(temp, length, mode); @@ -206,8 +206,8 @@ static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode) return get_mode_max(mode); case TV_OVERFLOW_WRAP: temp = alloca(sc_get_buffer_length()); - sc_val_from_ulong(-1, temp); - sc_and(temp, value, temp); + memcpy(temp, sc_get_buffer(), sc_get_buffer_length()); + sc_truncate(get_mode_size_bits(mode), temp); /* the sc_ module expects that all bits are set ... */ sign_extend(temp, mode); return get_tarval(temp, length, mode); @@ -223,8 +223,8 @@ static tarval *get_tarval_overflow(const void *value, int length, ir_mode *mode) return get_mode_min(mode); case TV_OVERFLOW_WRAP: { char *temp = alloca(sc_get_buffer_length()); - sc_val_from_ulong(-1, temp); - sc_and(temp, value, temp); + memcpy(temp, sc_get_buffer(), sc_get_buffer_length()); + sc_truncate(get_mode_size_bits(mode), temp); return get_tarval(temp, length, mode); } case TV_OVERFLOW_BAD: -- 2.20.1