X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Ftv%2Fstrcalc.c;h=b012b7479694ae7b1460d1bc604b68212786d884;hb=2d09549421b49587d4680a94dab277646e9fef44;hp=bd69ca8edfe1d8aac36c91d445a79908125eaafb;hpb=25a9079a440dca3115aedcc4c22438e187ed9d7d;p=libfirm diff --git a/ir/tv/strcalc.c b/ir/tv/strcalc.c index bd69ca8ed..b012b7479 100644 --- a/ir/tv/strcalc.c +++ b/ir/tv/strcalc.c @@ -10,9 +10,21 @@ * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE. */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + #include "strcalc.h" #include +#ifdef HAVE_ALLOCA_H +# include +#endif +#ifdef HAVE_MALLOC_H +# include +#endif #include /* assertions */ #include /* memset/memcmp */ #include /* output for error messages */ @@ -508,19 +520,24 @@ static void _add(const char *val1, const char *val2, char *buffer) buffer[counter] = add2[0]; carry = add_table[_val(add1[1])][_val(add2[1])][0]; } + carry_flag = carry != SC_0; } static void _mul(const char *val1, const char *val2, char *buffer) { - char temp_buffer[CALC_BUFFER_SIZE]; /* result buffer */ - char neg_val1[CALC_BUFFER_SIZE]; /* abs of val1 */ - char neg_val2[CALC_BUFFER_SIZE]; /* abs of val2 */ + char* temp_buffer; /* result buffer */ + char* neg_val1; /* abs of val1 */ + char* neg_val2; /* abs of val2 */ const char *mul, *add1, *add2; /* intermediate result containers */ char carry = SC_0; /* container for carries */ char sign = 0; /* marks result sign */ int c_inner, c_outer; /* loop counters */ + temp_buffer = alloca(CALC_BUFFER_SIZE); + neg_val1 = alloca(CALC_BUFFER_SIZE); + neg_val2 = alloca(CALC_BUFFER_SIZE); + /* init result buffer to zeroes */ memset(temp_buffer, SC_0, CALC_BUFFER_SIZE); @@ -585,7 +602,8 @@ static void _mul(const char *val1, const char *val2, char *buffer) static void _sub(const char *val1, const char *val2, char *buffer) { - char temp_buffer[CALC_BUFFER_SIZE]; /* intermediate buffer to hold -val2 */ + char *temp_buffer; /* intermediate buffer to hold -val2 */ + temp_buffer = alloca(CALC_BUFFER_SIZE); _negate(val2, temp_buffer); _add(val1, temp_buffer, buffer); @@ -606,13 +624,16 @@ static void _push(const char digit, char *buffer) static void _divmod(const char *dividend, const char *divisor, char *quot, char *rem) { const char *minus_divisor; - char neg_val1[CALC_BUFFER_SIZE]; - char neg_val2[CALC_BUFFER_SIZE]; + char *neg_val1; + char *neg_val2; char sign = 0; /* remember result sign */ int c_dividend; /* loop counters */ + neg_val1 = alloca(CALC_BUFFER_SIZE); + neg_val2 = alloca(CALC_BUFFER_SIZE); + /* clear result buffer */ memset(quot, SC_0, CALC_BUFFER_SIZE); memset(rem, SC_0, CALC_BUFFER_SIZE); @@ -844,8 +865,9 @@ static void _shr(const char *val1, char *buffer, long offset, int radius, unsign /* positive: low-order -> high order, negative other direction */ static void _rot(const char *val1, char *buffer, long offset, int radius, unsigned is_signed) { - char temp1[CALC_BUFFER_SIZE]; - char temp2[CALC_BUFFER_SIZE]; + char *temp1, *temp2; + temp1 = alloca(CALC_BUFFER_SIZE); + temp2 = alloca(CALC_BUFFER_SIZE); offset = offset % radius; @@ -881,8 +903,10 @@ void sc_val_from_str(const char *str, unsigned int len, void *buffer) unsigned int orig_len = len; char sign = 0; - char base[CALC_BUFFER_SIZE]; - char val[CALC_BUFFER_SIZE]; + char *base, *val; + + base = alloca(CALC_BUFFER_SIZE); + val = alloca(CALC_BUFFER_SIZE); /* verify valid pointers (not null) */ assert(str); @@ -1126,11 +1150,12 @@ void sc_max_from_bits(unsigned int num_bits, unsigned int sign, void *buffer) void sc_calc(const void* value1, const void* value2, unsigned op, void *buffer) { - char unused_res[CALC_BUFFER_SIZE]; /* temp buffer holding unused result of divmod */ + char *unused_res; /* temp buffer holding unused result of divmod */ const char *val1 = (const char *)value1; const char *val2 = (const char *)value2; + unused_res = alloca(CALC_BUFFER_SIZE); CLEAR_BUFFER(calc_buffer); carry_flag = 0; @@ -1141,7 +1166,7 @@ void sc_calc(const void* value1, const void* value2, unsigned op, void *buffer) case SC_NEG: _negate(val1, calc_buffer); DEBUGPRINTF_COMPUTATION(("negated: %s\n", sc_print_hex(calc_buffer))); - return; + break; case SC_OR: DEBUGPRINTF_COMPUTATION(("| ")); _bitor(val1, val2, calc_buffer); @@ -1157,7 +1182,7 @@ void sc_calc(const void* value1, const void* value2, unsigned op, void *buffer) case SC_NOT: _bitnot(val1, calc_buffer); DEBUGPRINTF_COMPUTATION(("bit-negated: %s\n", sc_print_hex(calc_buffer))); - return; + break; case SC_ADD: DEBUGPRINTF_COMPUTATION(("+ ")); _add(val1, val2, calc_buffer); @@ -1340,10 +1365,7 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base) static const char big_digits[] = "0123456789ABCDEF"; static const char small_digits[] = "0123456789abcdef"; - char base_val[CALC_BUFFER_SIZE]; - char div1_res[CALC_BUFFER_SIZE]; - char div2_res[CALC_BUFFER_SIZE]; - char rem_res[CALC_BUFFER_SIZE]; + char *base_val, *div1_res, *div2_res, *rem_res; int counter, nibbles, i, sign; char x; @@ -1353,6 +1375,11 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base) char *pos; const char *digits = small_digits; + base_val = alloca(CALC_BUFFER_SIZE); + div1_res = alloca(CALC_BUFFER_SIZE); + div2_res = alloca(CALC_BUFFER_SIZE); + rem_res = alloca(CALC_BUFFER_SIZE); + pos = output_buffer + BIT_PATTERN_SIZE; *(--pos) = '\0'; @@ -1483,17 +1510,16 @@ void init_strcalc(int precision) if (precision <= 0) precision = SC_DEFAULT_PRECISION; /* round up to multiple of 4 */ - if (precision & 0x3) precision += 4 - (precision&0x3); + precision = (precision + 3) & ~3; BIT_PATTERN_SIZE = (precision); CALC_BUFFER_SIZE = (precision / 2); MAX_VALUE_SIZE = (precision / 4); - calc_buffer = malloc(CALC_BUFFER_SIZE+1 * sizeof(char)); + calc_buffer = malloc(CALC_BUFFER_SIZE+1 * sizeof(char)); output_buffer = malloc(BIT_PATTERN_SIZE+1 * sizeof(char)); - if (calc_buffer == NULL || output_buffer == NULL) - { + if (calc_buffer == NULL || output_buffer == NULL) { assert(0 && "malloc failed"); exit(-1); } @@ -1501,6 +1527,13 @@ void init_strcalc(int precision) DEBUGPRINTF(("init strcalc: \n\tPRECISION: %d\n\tCALC_BUFFER_SIZE = %d\n\tMAX_VALUE_SIZE = %d\n\tbuffer pointer: %p\n", precision, CALC_BUFFER_SIZE, MAX_VALUE_SIZE, calc_buffer)); } } + + +void finish_strcalc() { + free(calc_buffer); calc_buffer = NULL; + free(output_buffer); output_buffer = NULL; +} + int sc_get_precision(void) { return BIT_PATTERN_SIZE;