X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Fstrcalc.c;h=6e45a26b4bbdc13f03242d6ae9b30995f1a2bfb3;hb=4ca2b9085b12d5dac2d975a830f7e74148e67e78;hp=b23b0ece15882ed4d4dcec3ac25606cc6adc410c;hpb=b78bdd4d94de46de4156272e6dbfe44e97933a5b;p=libfirm diff --git a/ir/tv/strcalc.c b/ir/tv/strcalc.c index b23b0ece1..6e45a26b4 100644 --- a/ir/tv/strcalc.c +++ b/ir/tv/strcalc.c @@ -45,10 +45,10 @@ #define fail_char(a, b, c, d) _fail_char((a), (b), (c), (d), __FILE__, __LINE__) /* shortcut output for debugging */ -# define sc_print_hex(a) sc_print((a), 0, SC_HEX) -# define sc_print_dec(a) sc_print((a), 0, SC_DEC) -# define sc_print_oct(a) sc_print((a), 0, SC_OCT) -# define sc_print_bin(a) sc_print((a), 0, SC_BIN) +# define sc_print_hex(a) sc_print((a), 0, SC_HEX, 0) +# define sc_print_dec(a) sc_print((a), 0, SC_DEC, 1) +# define sc_print_oct(a) sc_print((a), 0, SC_OCT, 0) +# define sc_print_bin(a) sc_print((a), 0, SC_BIN, 0) #ifdef STRCALC_DEBUG_PRINTCOMP # define DEBUGPRINTF_COMPUTATION(x) printf x @@ -78,6 +78,7 @@ static int carry_flag; /**< some computation set the carry_flag: and often defined in other ways! */ static const char sex_digit[4] = { SC_E, SC_C, SC_8, SC_0 }; +static const char zex_digit[4] = { SC_1, SC_3, SC_7, SC_F }; static const char max_digit[4] = { SC_0, SC_1, SC_3, SC_7 }; static const char min_digit[4] = { SC_F, SC_E, SC_C, SC_8 }; @@ -850,7 +851,6 @@ static void _shr(const char *val1, char *buffer, long offset, int radius, unsign int bitoffset = 0; assert((offset >= 0) || (0 && "negative rightshift")); - assert(((_sign(val1) != -1) || is_signed) || (0 && "unsigned mode and negative value")); assert(((!_bitisset(val1[(radius-1)/4], (radius-1)%4)) || !is_signed || (_sign(val1) == -1)) || (0 && "value is positive, should be negative")); assert(((_bitisset(val1[(radius-1)/4], (radius-1)%4)) || !is_signed || (_sign(val1) == 1)) || (0 && "value is negative, should be positive")); @@ -960,23 +960,32 @@ int sc_get_buffer_length(void) } /** - * Do sign extension if the mode is signed, expects all upper bits - * cleared. + * Do sign extension if the mode is signed, otherwise to zero extension. */ -static void sign_extend(char *calc_buffer, ir_mode *mode) { - if (mode_is_signed(mode)) { - int bits = get_mode_size_bits(mode) - 1; - int ofs = bits >> 2; - int max = max_digit[bits & 3]; - int i; +void sign_extend(char *calc_buffer, ir_mode *mode) { + int bits = get_mode_size_bits(mode) - 1; + int nibble = bits >> 2; + int max = max_digit[bits & 3]; + int i; - if (calc_buffer[ofs] > max) { + if (mode_is_signed(mode)) { + if (calc_buffer[nibble] > max) { /* sign bit is set, we need sign expansion */ - for (i = ofs + 1; i < calc_buffer_size; ++i) + for (i = nibble + 1; i < calc_buffer_size; ++i) calc_buffer[i] = SC_F; - calc_buffer[ofs] = or_table[calc_buffer[ofs]][sex_digit[bits & 3]]; + calc_buffer[nibble] = or_table[(int)calc_buffer[nibble]][(int)sex_digit[bits & 3]]; + } else { + /* set all bits to zero */ + for (i = nibble + 1; i < calc_buffer_size; ++i) + calc_buffer[i] = SC_0; + calc_buffer[nibble] = and_table[(int)calc_buffer[nibble]][(int)zex_digit[bits & 3]]; } + } else { + /* do zero extension */ + for (i = nibble + 1; i < calc_buffer_size; ++i) + calc_buffer[i] = SC_0; + calc_buffer[nibble] = and_table[(int)calc_buffer[nibble]][(int)zex_digit[bits & 3]]; } } @@ -1445,7 +1454,7 @@ unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs) * convert to a string * FIXME: Doesn't check buffer bounds */ -const char *sc_print(const void *value, unsigned bits, enum base_t base) +const char *sc_print(const void *value, unsigned bits, enum base_t base, int signed_mode) { static const char big_digits[] = "0123456789ABCDEF"; static const char small_digits[] = "0123456789abcdef"; @@ -1463,7 +1472,7 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base) base_val = alloca(calc_buffer_size); div1_res = alloca(calc_buffer_size); div2_res = alloca(calc_buffer_size); - rem_res = alloca(calc_buffer_size); + rem_res = alloca(calc_buffer_size); pos = output_buffer + bit_pattern_size; *(--pos) = '\0'; @@ -1540,7 +1549,7 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base) p = val; sign = 0; - if (base == SC_DEC) { + if (signed_mode && base == SC_DEC) { /* check for negative values */ if (_bit(val, bits - 1)) { _negate(val, div2_res); @@ -1571,7 +1580,7 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base) *(--pos) = digits[_val(rem_res[0])]; x = 0; - for (i = 0; i < sizeof(div1_res); ++i) + for (i = 0; i < calc_buffer_size; ++i) x |= _val(m[i]); if (x == 0)