becopyheur4: Clean up co_mst_irn_init().
[libfirm] / ir / tv / strcalc.c
index 338ad01..9d9ee6e 100644 (file)
@@ -1,20 +1,6 @@
 /*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
- *
  * This file is part of libFirm.
- *
- * This file may be distributed and/or modified under the terms of the
- * GNU General Public License version 2 as published by the Free Software
- * Foundation and appearing in the file LICENSE.GPL included in the
- * packaging of this file.
- *
- * Licensees holding valid libFirm Professional Edition licenses may use
- * this file in accordance with the libFirm Commercial License.
- * Agreement provided with the Software.
- *
- * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
- * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE.
+ * Copyright (C) 2012 University of Karlsruhe.
  */
 
 /**
@@ -22,7 +8,6 @@
  * @brief    Provides basic mathematical operations on values represented as strings.
  * @date     2003
  * @author   Mathias Heil
- * @version  $Id$
  */
 #include "config.h"
 
 /*
  * local definitions and macros
  */
+#define SC_BITS      4
+#define SC_RESULT(x) ((x) & ((1U << SC_BITS) - 1U))
+#define SC_CARRY(x)  ((unsigned)(x) >> SC_BITS)
+
 #define CLEAR_BUFFER(b) assert(b); memset(b, SC_0, calc_buffer_size)
 #define SHIFT(count) (SC_1 << (count))
 #define _val(a) ((a)-SC_0)
 #define _digit(a) ((a)+SC_0)
 #define _bitisset(digit, pos) (((digit) & SHIFT(pos)) != SC_0)
 
-#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, 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
-#else
-#  define DEBUGPRINTF_COMPUTATION(x) ((void)0)
-#endif
-#ifdef STRCALC_DEBUG
-#  define DEBUGPRINTF(x) printf x
-#else
-#  define DEBUGPRINTF(x) ((void)0)
-#endif
-
-
 /*
  * private variables
  */
@@ -85,170 +54,6 @@ 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 };
 
-static char const add_table[16][16][2] = {
-                       { {SC_0, SC_0}, {SC_1, SC_0}, {SC_2, SC_0}, {SC_3, SC_0},
-                         {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0},
-                         {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
-                         {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0} },
-
-                       { {SC_1, SC_0}, {SC_2, SC_0}, {SC_3, SC_0}, {SC_4, SC_0},
-                         {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0},
-                         {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0},
-                         {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1} },
-
-                       { {SC_2, SC_0}, {SC_3, SC_0}, {SC_4, SC_0}, {SC_5, SC_0},
-                         {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0},
-                         {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0},
-                         {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1} },
-
-                       { {SC_3, SC_0}, {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0},
-                         {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0},
-                         {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0},
-                         {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1} },
-
-                       { {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0},
-                         {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
-                         {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0},
-                         {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1} },
-
-                       { {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0},
-                         {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0},
-                         {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1},
-                         {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1} },
-
-                       { {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0},
-                         {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0},
-                         {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1},
-                         {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1} },
-
-                       { {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0},
-                         {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0},
-                         {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1},
-                         {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1} },
-
-                       { {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
-                         {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0},
-                         {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1},
-                         {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1} },
-
-                       { {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0},
-                         {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1},
-                         {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1},
-                         {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1} },
-
-                       { {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0},
-                         {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1},
-                         {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1},
-                         {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1} },
-
-                       { {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0},
-                         {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1},
-                         {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1},
-                         {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1}, {SC_A, SC_1} },
-
-                       { {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0},
-                         {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1},
-                         {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1},
-                         {SC_8, SC_1}, {SC_9, SC_1}, {SC_A, SC_1}, {SC_B, SC_1} },
-
-                       { {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1},
-                         {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1},
-                         {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1},
-                         {SC_9, SC_1}, {SC_A, SC_1}, {SC_B, SC_1}, {SC_C, SC_1} },
-
-                       { {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1},
-                         {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1},
-                         {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1},
-                         {SC_A, SC_1}, {SC_B, SC_1}, {SC_C, SC_1}, {SC_D, SC_1} },
-
-                       { {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1},
-                         {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1},
-                         {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1}, {SC_A, SC_1},
-                         {SC_B, SC_1}, {SC_C, SC_1}, {SC_D, SC_1}, {SC_E, SC_1} }
-                             };
-
-static char const mul_table[16][16][2] = {
-                       { {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0},
-                         {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0},
-                         {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0},
-                         {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0} },
-
-                       { {SC_0, SC_0}, {SC_1, SC_0}, {SC_2, SC_0}, {SC_3, SC_0},
-                         {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0},
-                         {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
-                         {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0} },
-
-                       { {SC_0, SC_0}, {SC_2, SC_0}, {SC_4, SC_0}, {SC_6, SC_0},
-                         {SC_8, SC_0}, {SC_A, SC_0}, {SC_C, SC_0}, {SC_E, SC_0},
-                         {SC_0, SC_1}, {SC_2, SC_1}, {SC_4, SC_1}, {SC_6, SC_1},
-                         {SC_8, SC_1}, {SC_A, SC_1}, {SC_C, SC_1}, {SC_E, SC_1} },
-
-                       { {SC_0, SC_0}, {SC_3, SC_0}, {SC_6, SC_0}, {SC_9, SC_0},
-                         {SC_C, SC_0}, {SC_F, SC_0}, {SC_2, SC_1}, {SC_5, SC_1},
-                         {SC_8, SC_1}, {SC_B, SC_1}, {SC_E, SC_1}, {SC_1, SC_2},
-                         {SC_4, SC_2}, {SC_7, SC_2}, {SC_A, SC_2}, {SC_D, SC_2} },
-
-                       { {SC_0, SC_0}, {SC_4, SC_0}, {SC_8, SC_0}, {SC_C, SC_0},
-                         {SC_0, SC_1}, {SC_4, SC_1}, {SC_8, SC_1}, {SC_C, SC_1},
-                         {SC_0, SC_2}, {SC_4, SC_2}, {SC_8, SC_2}, {SC_C, SC_2},
-                         {SC_0, SC_3}, {SC_4, SC_3}, {SC_8, SC_3}, {SC_C, SC_3} },
-
-                       { {SC_0, SC_0}, {SC_5, SC_0}, {SC_A, SC_0}, {SC_F, SC_0},
-                         {SC_4, SC_1}, {SC_9, SC_1}, {SC_E, SC_1}, {SC_3, SC_2},
-                         {SC_8, SC_2}, {SC_D, SC_2}, {SC_2, SC_3}, {SC_7, SC_3},
-                         {SC_C, SC_3}, {SC_1, SC_4}, {SC_6, SC_4}, {SC_B, SC_4} },
-
-                       { {SC_0, SC_0}, {SC_6, SC_0}, {SC_C, SC_0}, {SC_2, SC_1},
-                         {SC_8, SC_1}, {SC_E, SC_1}, {SC_4, SC_2}, {SC_A, SC_2},
-                         {SC_0, SC_3}, {SC_6, SC_3}, {SC_C, SC_3}, {SC_2, SC_4},
-                         {SC_8, SC_4}, {SC_E, SC_4}, {SC_4, SC_5}, {SC_A, SC_5} },
-
-                       { {SC_0, SC_0}, {SC_7, SC_0}, {SC_E, SC_0}, {SC_5, SC_1},
-                         {SC_C, SC_1}, {SC_3, SC_2}, {SC_A, SC_2}, {SC_1, SC_3},
-                         {SC_8, SC_3}, {SC_F, SC_3}, {SC_6, SC_4}, {SC_D, SC_4},
-                         {SC_4, SC_5}, {SC_B, SC_5}, {SC_2, SC_6}, {SC_9, SC_6} },
-
-                       { {SC_0, SC_0}, {SC_8, SC_0}, {SC_0, SC_1}, {SC_8, SC_1},
-                         {SC_0, SC_2}, {SC_8, SC_2}, {SC_0, SC_3}, {SC_8, SC_3},
-                         {SC_0, SC_4}, {SC_8, SC_4}, {SC_0, SC_5}, {SC_8, SC_5},
-                         {SC_0, SC_6}, {SC_8, SC_6}, {SC_0, SC_7}, {SC_8, SC_7} },
-
-                       { {SC_0, SC_0}, {SC_9, SC_0}, {SC_2, SC_1}, {SC_B, SC_1},
-                         {SC_4, SC_2}, {SC_D, SC_2}, {SC_6, SC_3}, {SC_F, SC_3},
-                         {SC_8, SC_4}, {SC_1, SC_5}, {SC_A, SC_5}, {SC_3, SC_6},
-                         {SC_C, SC_6}, {SC_5, SC_7}, {SC_E, SC_7}, {SC_7, SC_8} },
-
-                       { {SC_0, SC_0}, {SC_A, SC_0}, {SC_4, SC_1}, {SC_E, SC_1},
-                         {SC_8, SC_2}, {SC_2, SC_3}, {SC_C, SC_3}, {SC_6, SC_4},
-                         {SC_0, SC_5}, {SC_A, SC_5}, {SC_4, SC_6}, {SC_E, SC_6},
-                         {SC_8, SC_7}, {SC_2, SC_8}, {SC_C, SC_8}, {SC_6, SC_9} },
-
-                       { {SC_0, SC_0}, {SC_B, SC_0}, {SC_6, SC_1}, {SC_1, SC_2},
-                         {SC_C, SC_2}, {SC_7, SC_3}, {SC_2, SC_4}, {SC_D, SC_4},
-                         {SC_8, SC_5}, {SC_3, SC_6}, {SC_E, SC_6}, {SC_9, SC_7},
-                         {SC_4, SC_8}, {SC_F, SC_8}, {SC_A, SC_9}, {SC_5, SC_A} },
-
-                       { {SC_0, SC_0}, {SC_C, SC_0}, {SC_8, SC_1}, {SC_4, SC_2},
-                         {SC_0, SC_3}, {SC_C, SC_3}, {SC_8, SC_4}, {SC_4, SC_5},
-                         {SC_0, SC_6}, {SC_C, SC_6}, {SC_8, SC_7}, {SC_4, SC_8},
-                         {SC_0, SC_9}, {SC_C, SC_9}, {SC_8, SC_A}, {SC_4, SC_B} },
-
-                       { {SC_0, SC_0}, {SC_D, SC_0}, {SC_A, SC_1}, {SC_7, SC_2},
-                         {SC_4, SC_3}, {SC_1, SC_4}, {SC_E, SC_4}, {SC_B, SC_5},
-                         {SC_8, SC_6}, {SC_5, SC_7}, {SC_2, SC_8}, {SC_F, SC_8},
-                         {SC_C, SC_9}, {SC_9, SC_A}, {SC_6, SC_B}, {SC_3, SC_C} },
-
-                       { {SC_0, SC_0}, {SC_E, SC_0}, {SC_C, SC_1}, {SC_A, SC_2},
-                         {SC_8, SC_3}, {SC_6, SC_4}, {SC_4, SC_5}, {SC_2, SC_6},
-                         {SC_0, SC_7}, {SC_E, SC_7}, {SC_C, SC_8}, {SC_A, SC_9},
-                         {SC_8, SC_A}, {SC_6, SC_B}, {SC_4, SC_C}, {SC_2, SC_D} },
-
-                       { {SC_0, SC_0}, {SC_F, SC_0}, {SC_E, SC_1}, {SC_D, SC_2},
-                         {SC_C, SC_3}, {SC_B, SC_4}, {SC_A, SC_5}, {SC_9, SC_6},
-                         {SC_8, SC_7}, {SC_7, SC_8}, {SC_6, SC_9}, {SC_5, SC_A},
-                         {SC_4, SC_B}, {SC_3, SC_C}, {SC_2, SC_D}, {SC_1, SC_E} }
-                             };
-
 static char const shrs_table[16][4][2] = {
                        { {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0} },
                        { {SC_1, SC_0}, {SC_0, SC_8}, {SC_0, SC_4}, {SC_0, SC_2} },
@@ -269,7 +74,7 @@ static char const shrs_table[16][4][2] = {
                                    };
 
 /** converting a digit to a binary string */
-static const char *binary_table[16] = {
+static char const *const binary_table[] = {
        "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
        "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
 };
@@ -277,14 +82,6 @@ static const char *binary_table[16] = {
 /*****************************************************************************
  * private functions
  *****************************************************************************/
-static void _fail_char(const char *str, size_t len, const char fchar, int pos,
-                       const char *file, int line) {
-       printf("ERROR:\n");
-       printf("Unexpected character '%c' in %s:%d\n", fchar, file, line);
-       while (len-- && *str) printf("%c", *str++); printf("\n");
-       while (--pos) printf(" "); printf("^\n");
-       exit(-1);
-}
 
 /**
  * implements the bitwise NOT operation
@@ -376,7 +173,7 @@ static void do_inc(const char *val, char *buffer)
                        val++;
                } else {
                        /* No carry here, *val != SC_F */
-                       *buffer = add_table[_val(*val)][SC_1][0];
+                       *buffer = *val + SC_1;
                        return;
                }
        }
@@ -401,16 +198,11 @@ static void do_negate(const char *val, char *buffer)
  */
 static void do_add(const char *val1, const char *val2, char *buffer)
 {
-       int counter;
-       const char *add1, *add2;
-       char carry = SC_0;
-
-       for (counter = 0; counter < calc_buffer_size; counter++)   {
-               add1 = add_table[_val(val1[counter])][_val(val2[counter])];
-               add2 = add_table[_val(add1[0])][_val(carry)];
-               /* carry might be zero */
-               buffer[counter] = add2[0];
-               carry = add_table[_val(add1[1])][_val(add2[1])][0];
+       unsigned carry = SC_0;
+       for (int counter = 0; counter < calc_buffer_size; ++counter) {
+               unsigned const sum = val1[counter] + val2[counter] + carry;
+               buffer[counter] = SC_RESULT(sum);
+               carry           = SC_CARRY(sum);
        }
        carry_flag = carry != SC_0;
 }
@@ -420,7 +212,7 @@ static void do_add(const char *val1, const char *val2, char *buffer)
  */
 static void do_sub(const char *val1, const char *val2, char *buffer)
 {
-       char *temp_buffer = alloca(calc_buffer_size); /* intermediate buffer to hold -val2 */
+       char *temp_buffer = (char*) alloca(calc_buffer_size); /* intermediate buffer to hold -val2 */
 
        do_negate(val2, temp_buffer);
        do_add(val1, temp_buffer, buffer);
@@ -435,14 +227,12 @@ static void do_mul(const char *val1, const char *val2, char *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);
+       temp_buffer = (char*) alloca(calc_buffer_size);
+       neg_val1 = (char*) alloca(calc_buffer_size);
+       neg_val2 = (char*) alloca(calc_buffer_size);
 
        /* init result buffer to zeros */
        memset(temp_buffer, SC_0, calc_buffer_size);
@@ -462,6 +252,7 @@ static void do_mul(const char *val1, const char *val2, char *buffer)
 
        for (c_outer = 0; c_outer < max_value_size; c_outer++) {
                if (val2[c_outer] != SC_0) {
+                       unsigned carry = SC_0; /* container for carries */
                        for (c_inner = 0; c_inner < max_value_size; c_inner++) {
                                /* do the following calculation:                                    *
                                 * Add the current carry, the value at position c_outer+c_inner     *
@@ -469,11 +260,9 @@ static void do_mul(const char *val1, const char *val2, char *buffer)
                                 * val2[c_outer]. This is the usual pen-and-paper multiplication.   */
 
                                /* multiplicate the two digits */
-                               mul = mul_table[_val(val1[c_inner])][_val(val2[c_outer])];
-                               /* add old value to result of multiplication */
-                               add1 = add_table[_val(temp_buffer[c_inner + c_outer])][_val(mul[0])];
-                               /* add carry to the sum */
-                               add2 = add_table[_val(add1[0])][_val(carry)];
+                               unsigned const mul = val1[c_inner] * val2[c_outer];
+                               /* add old value to result of multiplication and the carry */
+                               unsigned const sum = temp_buffer[c_inner + c_outer] + mul + carry;
 
                                /* all carries together result in new carry. This is always smaller *
                                 * than the base b:                                                 *
@@ -484,16 +273,13 @@ static void do_mul(const char *val1, const char *val2, char *buffer)
                                 * (b-1)(b-1)+(b-1)+(b-1) = b*b-1                                   *
                                 * The tables list all operations rem b, so the carry is at most    *
                                 * (b*b-1)rem b = -1rem b = b-1                                     */
-                               carry = add_table[_val(mul[1])][_val(add1[1])][0];
-                               carry = add_table[_val(carry)][_val(add2[1])][0];
-
-                               temp_buffer[c_inner + c_outer] = add2[0];
+                               temp_buffer[c_inner + c_outer] = SC_RESULT(sum);
+                               carry                          = SC_CARRY(sum);
                        }
 
                        /* A carry may hang over */
                        /* c_outer is always smaller than max_value_size! */
                        temp_buffer[max_value_size + c_outer] = carry;
-                       carry = SC_0;
                }
        }
 
@@ -533,18 +319,18 @@ static void do_divmod(const char *rDividend, const char *divisor, char *quot, ch
 
        int c_dividend;      /* loop counters */
 
-       neg_val1 = alloca(calc_buffer_size);
-       neg_val2 = alloca(calc_buffer_size);
+       neg_val1 = (char*) alloca(calc_buffer_size);
+       neg_val2 = (char*) alloca(calc_buffer_size);
 
        /* clear result buffer */
        memset(quot, SC_0, calc_buffer_size);
        memset(rem, SC_0, calc_buffer_size);
 
        /* if the divisor is zero this won't work (quot is zero) */
-       if (sc_comp(divisor, quot) == 0) assert(0 && "division by zero!");
+       assert(sc_comp(divisor, quot) != ir_relation_equal && "division by zero!");
 
        /* if the dividend is zero result is zero (quot is zero) */
-       if (sc_comp(dividend, quot) == 0)
+       if (sc_comp(dividend, quot) == ir_relation_equal)
                return;
 
        if (do_sign(dividend) == -1) {
@@ -565,11 +351,11 @@ static void do_divmod(const char *rDividend, const char *divisor, char *quot, ch
        /* if divisor >= dividend division is easy
         * (remember these are absolute values) */
        switch (sc_comp(dividend, divisor)) {
-       case 0: /* dividend == divisor */
+       case ir_relation_equal: /* dividend == divisor */
                quot[0] = SC_1;
                goto end;
 
-       case -1: /* dividend < divisor */
+       case ir_relation_less: /* dividend < divisor */
                memcpy(rem, dividend, calc_buffer_size);
                goto end;
 
@@ -581,13 +367,13 @@ static void do_divmod(const char *rDividend, const char *divisor, char *quot, ch
                do_push(dividend[c_dividend], rem);
                do_push(SC_0, quot);
 
-               if (sc_comp(rem, divisor) != -1) {  /* remainder >= divisor */
+               if (sc_comp(rem, divisor) != ir_relation_less) {  /* remainder >= divisor */
                        /* subtract until the remainder becomes negative, this should
                         * be faster than comparing remainder with divisor  */
                        do_add(rem, minus_divisor, rem);
 
                        while (do_sign(rem) == 1) {
-                               quot[0] = add_table[_val(quot[0])][SC_1][0];
+                               quot[0] = SC_RESULT(quot[0] + SC_1); /* TODO can this generate carry or is masking redundant? */
                                do_add(rem, minus_divisor, rem);
                        }
 
@@ -614,10 +400,6 @@ end:
  */
 static void do_shl(const char *val1, char *buffer, long shift_cnt, int bitsize, unsigned is_signed)
 {
-       const char *shl;
-       char shift;
-       char carry = SC_0;
-
        int counter;
        int bitoffset = 0;
 
@@ -632,19 +414,20 @@ static void do_shl(const char *val1, char *buffer, long shift_cnt, int bitsize,
                return;
        }
 
-       shift     = SHIFT(shift_cnt % 4); /* this is 2 ** (offset % 4) */
+       unsigned const shift = shift_cnt % SC_BITS;
        shift_cnt = shift_cnt / 4;
 
        /* shift the single digits some bytes (offset) and some bits (table)
         * to the left */
+       unsigned carry = SC_0;
        for (counter = 0; counter < bitsize/4 - shift_cnt; counter++) {
-               shl = mul_table[_val(val1[counter])][_val(shift)];
-               buffer[counter + shift_cnt] = shl[0] | carry;
-               carry = shl[1];
+               unsigned const shl = val1[counter] << shift | carry;
+               buffer[counter + shift_cnt] = SC_RESULT(shl);
+               carry = SC_CARRY(shl);
        }
        if (bitsize%4 > 0) {
-               shl = mul_table[_val(val1[counter])][_val(shift)];
-               buffer[counter + shift_cnt] = shl[0] | carry;
+               unsigned const shl = val1[counter] << shift | carry;
+               buffer[counter + shift_cnt] = SC_RESULT(shl);
                bitoffset = counter;
        } else {
                bitoffset = counter - 1;
@@ -761,8 +544,8 @@ static void do_shr(const char *val1, char *buffer, long shift_cnt, int bitsize,
 static void do_rotl(const char *val1, char *buffer, long offset, int radius, unsigned is_signed)
 {
        char *temp1, *temp2;
-       temp1 = alloca(calc_buffer_size);
-       temp2 = alloca(calc_buffer_size);
+       temp1 = (char*) alloca(calc_buffer_size);
+       temp2 = (char*) alloca(calc_buffer_size);
 
        offset = offset % radius;
 
@@ -796,7 +579,7 @@ int sc_get_buffer_length(void)
  */
 void sign_extend(void *buffer, ir_mode *mode)
 {
-       char *calc_buffer = buffer;
+       char *calc_buffer = (char*) buffer;
        int bits          = get_mode_size_bits(mode) - 1;
        int nibble        = bits >> 2;
        int max           = max_digit[bits & 3];
@@ -823,139 +606,77 @@ void sign_extend(void *buffer, ir_mode *mode)
        }
 }
 
-/* FIXME doesn't check for overflows */
-void sc_val_from_str(const char *str, unsigned int len, void *buffer, ir_mode *mode)
+/* we assume that '0'-'9', 'a'-'z' and 'A'-'Z' are a range.
+ * The C-standard does theoretically allow otherwise. */
+static inline void check_ascii(void)
 {
-       const char *orig_str = str;
-       unsigned int orig_len = len;
+       /* C standard guarantees that '0'-'9' is a range */
+       assert('b'-'a' == 1
+               && 'c'-'a' == 2
+               && 'd'-'a' == 3
+               && 'e'-'a' == 4
+               && 'f'-'a' == 5);
+       assert('B'-'A' == 1
+               && 'C'-'A' == 2
+               && 'D'-'A' == 3
+               && 'E'-'A' == 4
+               && 'F'-'A' == 5);
+}
 
-       char sign = 0;
-       char *base, *val;
+int sc_val_from_str(char sign, unsigned base, const char *str,
+                    size_t len, void *buffer)
+{
+       char *sc_base, *val;
 
-       base = alloca(calc_buffer_size);
-       val = alloca(calc_buffer_size);
+       assert(sign == -1 || sign == 1);
+       assert(str != NULL);
+       assert(len > 0);
+       check_ascii();
 
-       /* verify valid pointers (not null) */
-       assert(str);
-       /* a string no characters long is an error */
-       assert(len);
+       assert(base > 1 && base <= 16);
+       sc_base = (char*) alloca(calc_buffer_size);
+       sc_val_from_ulong(base, sc_base);
 
-       if (buffer == NULL) buffer = calc_buffer;
+       val = (char*) alloca(calc_buffer_size);
+       if (buffer == NULL)
+               buffer = calc_buffer;
 
        CLEAR_BUFFER(buffer);
-       CLEAR_BUFFER(base);
        CLEAR_BUFFER(val);
 
-       /* strip leading spaces */
-       while ((len > 0) && (*str == ' ')) { len--; str++; }
-
-       /* if the first two characters are 0x or 0X -> hex
-        * if the first is a 0 -> oct
-        * else dec, strip leading -/+ and remember sign
-        *
-        * only a + or - sign is no number resulting in an error */
-       if (len >= 2) {
-               switch (str[0]) {
-               case '0':
-                       if (str[1] == 'x' || str[1] == 'X') { /* hex */
-                               str += 2;
-                               len -= 2;
-                               base[1] = SC_1; base[0] = SC_0;
-                       } else { /* oct */
-                               str += 1;
-                               len -= 1;
-                               base[1] = SC_0; base[0] = SC_8;
-                       }
-                       break;
-
-               case '+':
-                       str += 1;
-                       len -= 1;
-                       base[1] = SC_0; base[0] = SC_A;
-                       break;
-
-               case '-':
-                       str += 1;
-                       len -= 1;
-                       sign = 1;
-                       base[1] = SC_0; base[0] = SC_A;
-                       break;
-
-               default: /* dec, else would have begun with 0x or 0 */
-                       base[1] = SC_0; base[0] = SC_A;
-               }
-       } else { /* dec, else would have begun with 0x or 0 */
-               base[1] = SC_0; base[0] = SC_A;
-       }
-
        /* BEGIN string evaluation, from left to right */
        while (len > 0) {
-               switch (*str) {
-               case 'f':
-               case 'e':
-               case 'd':
-               case 'c':
-               case 'b':
-               case 'a':
-                       if (base[0] > SC_A || base[1] > SC_0) { /* (base > 10) */
-                               val[0] = _digit((*str)-'a'+10);
-                       }
-                       else
-                               fail_char(orig_str, orig_len, *str, str-orig_str+1);
-                       break;
-
-               case 'F':
-               case 'E':
-               case 'D':
-               case 'C':
-               case 'B':
-               case 'A':
-                       if (base[0] > SC_A || base[1] > SC_0) { /* (base > 10) */
-                               val[0] = _digit((*str)-'A'+10);
-                       }
-                       else
-                               fail_char(orig_str, orig_len, *str, str-orig_str+1);
-                       break;
-
-               case '9':
-               case '8':
-                       if (base[0] > SC_8 || base[1] > SC_0) { /* (base > 8) */
-                               val[0] = _digit((*str)-'0');
-                       }
-                       else
-                               fail_char(orig_str, orig_len, *str, str-orig_str+1);
-                       break;
-
-               case '7':
-               case '6':
-               case '5':
-               case '4':
-               case '3':
-               case '2':
-               case '1':
-               case '0':
-                       val[0] = _digit((*str)-'0');
-                       break;
+               char c = *str;
+               unsigned v;
+               if (c >= '0' && c <= '9')
+                       v = c - '0';
+               else if (c >= 'A' && c <= 'F')
+                       v = c - 'A' + 10;
+               else if (c >= 'a' && c <= 'f')
+                       v = c - 'a' + 10;
+               else
+                       return 0;
 
-               default:
-                       fail_char(orig_str, orig_len, *str, str-orig_str+1);
-               } /* switch(*str) */
+               if (v >= base)
+                       return 0;
+               val[0] = v;
 
                /* Radix conversion from base b to base B:
                 *  (UnUn-1...U1U0)b == ((((Un*b + Un-1)*b + ...)*b + U1)*b + U0)B */
-               do_mul(base, calc_buffer, calc_buffer); /* multiply current value with base */
-               do_add(val, calc_buffer, calc_buffer);  /* add next digit to current value  */
+               /* multiply current value with base */
+               do_mul(sc_base, (const char*) buffer, (char*) buffer);
+               /* add next digit to current value  */
+               do_add(val, (const char*) buffer, (char*) buffer);
 
                /* get ready for the next letter */
                str++;
                len--;
-       } /* while (len > 0 ) */
+       }
 
-       if (sign)
-               do_negate(calc_buffer, calc_buffer);
+       if (sign < 0)
+               do_negate((const char*) buffer, (char*) buffer);
 
-       /* beware: even if hex numbers have no sign, we need sign extension here */
-       sign_extend(calc_buffer, mode);
+       return 1;
 }
 
 void sc_val_from_long(long value, void *buffer)
@@ -964,7 +685,7 @@ void sc_val_from_long(long value, void *buffer)
        char sign, is_minlong;
 
        if (buffer == NULL) buffer = calc_buffer;
-       pos = buffer;
+       pos = (char*) buffer;
 
        sign = (value < 0);
        is_minlong = value == LONG_MIN;
@@ -986,9 +707,9 @@ void sc_val_from_long(long value, void *buffer)
 
        if (sign) {
                if (is_minlong)
-                       do_inc(buffer, buffer);
+                       do_inc((const char*) buffer, (char*) buffer);
 
-               do_negate(buffer, buffer);
+               do_negate((const char*) buffer, (char*) buffer);
        }
 }
 
@@ -997,7 +718,7 @@ void sc_val_from_ulong(unsigned long value, void *buffer)
        unsigned char *pos;
 
        if (buffer == NULL) buffer = calc_buffer;
-       pos = buffer;
+       pos = (unsigned char*) buffer;
 
        while (pos < (unsigned char *)buffer + calc_buffer_size) {
                *pos++ = (unsigned char)_digit(value & 0xf);
@@ -1026,7 +747,7 @@ void sc_min_from_bits(unsigned int num_bits, unsigned int sign, void *buffer)
 
        if (!sign) return;  /* unsigned means minimum is 0(zero) */
 
-       pos = buffer;
+       pos = (char*) buffer;
 
        bits = num_bits - 1;
        for (i = 0; i < bits/4; i++)
@@ -1045,7 +766,7 @@ void sc_max_from_bits(unsigned int num_bits, unsigned int sign, void *buffer)
 
        if (buffer == NULL) buffer = calc_buffer;
        CLEAR_BUFFER(buffer);
-       pos = buffer;
+       pos = (char*) buffer;
 
        bits = num_bits - sign;
        for (i = 0; i < bits/4; i++)
@@ -1059,24 +780,24 @@ void sc_max_from_bits(unsigned int num_bits, unsigned int sign, void *buffer)
 
 void sc_truncate(unsigned int num_bits, void *buffer)
 {
-       char *cbuffer = buffer;
+       char *cbuffer = (char*) buffer;
        char *pos = cbuffer + (num_bits / 4);
        char *end = cbuffer + calc_buffer_size;
 
        assert(pos < end);
 
-       switch(num_bits % 4) {
+       switch (num_bits % 4) {
        case 0: /* nothing to do */ break;
        case 1: *pos++ &= SC_1; break;
        case 2: *pos++ &= SC_3; break;
        case 3: *pos++ &= SC_7; break;
        }
 
-       for( ; pos < end; ++pos)
+       for ( ; pos < end; ++pos)
                *pos = SC_0;
 }
 
-int sc_comp(const void* value1, const void* value2)
+ir_relation sc_comp(void const* const value1, void const* const value2)
 {
        int counter = calc_buffer_size - 1;
        const char *val1 = (const char *)value1;
@@ -1085,19 +806,19 @@ int sc_comp(const void* value1, const void* value2)
        /* compare signs first:
         * the loop below can only compare values of the same sign! */
        if (do_sign(val1) != do_sign(val2))
-               return (do_sign(val1) == 1)?(1):(-1);
+               return do_sign(val1) == 1 ? ir_relation_greater : ir_relation_less;
 
        /* loop until two digits differ, the values are equal if there
         * are no such two digits */
        while (val1[counter] == val2[counter]) {
                counter--;
-               if (counter < 0) return 0;
+               if (counter < 0) return ir_relation_equal;
        }
 
        /* the leftmost digit is the most significant, so this returns
         * the correct result.
         * This implies the digit enum is ordered */
-       return (val1[counter] > val2[counter]) ? (1) : (-1);
+       return val1[counter] > val2[counter] ? ir_relation_greater : ir_relation_less;
 }
 
 int sc_get_highest_set_bit(const void *value)
@@ -1156,7 +877,7 @@ int sc_get_lowest_set_bit(const void *value)
 
 int sc_get_bit_at(const void *value, unsigned pos)
 {
-       const char *val = value;
+       const char *val = (const char*) value;
        unsigned nibble = pos >> 2;
 
        return (val[nibble] & SHIFT(pos & 3)) != SC_0;
@@ -1164,7 +885,7 @@ int sc_get_bit_at(const void *value, unsigned pos)
 
 void sc_set_bit_at(void *value, unsigned pos)
 {
-       char *val = value;
+       char *val = (char*) value;
        unsigned nibble = pos >> 2;
 
        val[nibble] |= SHIFT(pos & 3);
@@ -1184,7 +905,7 @@ int sc_is_zero(const void *value)
 
 int sc_is_negative(const void *value)
 {
-       return do_sign(value) == -1;
+       return do_sign((const char*) value) == -1;
 }
 
 int sc_had_carry(void)
@@ -1232,10 +953,10 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base, int sig
        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);
+       base_val = (char*) alloca(calc_buffer_size);
+       div1_res = (char*) alloca(calc_buffer_size);
+       div2_res = (char*) alloca(calc_buffer_size);
+       rem_res  = (char*) alloca(calc_buffer_size);
 
        pos = output_buffer + bit_pattern_size;
        *(--pos) = '\0';
@@ -1243,9 +964,6 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base, int sig
        /* special case */
        if (bits == 0) {
                bits = bit_pattern_size;
-#ifdef STRCALC_DEBUG_FULLPRINT
-               bits <<= 1;
-#endif
        }
        nibbles = bits >> 2;
        switch (base) {
@@ -1255,10 +973,6 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base, int sig
        case SC_hex:
                for (counter = 0; counter < nibbles; ++counter) {
                        *(--pos) = digits[_val(val[counter])];
-#ifdef STRCALC_DEBUG_GROUPPRINT
-                       if ((counter+1)%8 == 0)
-                               *(--pos) = ' ';
-#endif
                }
 
                /* last nibble must be masked */
@@ -1270,9 +984,6 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base, int sig
 
                /* now kill zeros */
                for (; counter > 1; --counter, ++pos) {
-#ifdef STRCALC_DEBUG_GROUPPRINT
-                       if (pos[0] == ' ') ++pos;
-#endif
                        if (pos[0] != '0')
                                break;
                }
@@ -1375,8 +1086,6 @@ void init_strcalc(int precision)
 
                calc_buffer   = XMALLOCN(char, calc_buffer_size + 1);
                output_buffer = XMALLOCN(char, bit_pattern_size + 1);
-
-               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));
        }
 }
 
@@ -1398,12 +1107,7 @@ void sc_add(const void *value1, const void *value2, void *buffer)
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s + ", sc_print_hex(value1)));
-       DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
-
-       do_add(value1, value2, calc_buffer);
-
-       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+       do_add((const char*) value1, (const char*) value2, (char*) calc_buffer);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memcpy(buffer, calc_buffer, calc_buffer_size);
@@ -1415,12 +1119,7 @@ void sc_sub(const void *value1, const void *value2, void *buffer)
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s - ", sc_print_hex(value1)));
-       DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
-
-       do_sub(value1, value2, calc_buffer);
-
-       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+       do_sub((const char*) value1, (const char*) value2, calc_buffer);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memcpy(buffer, calc_buffer, calc_buffer_size);
@@ -1431,11 +1130,7 @@ void sc_neg(const void *value1, void *buffer)
 {
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("- %s ->", sc_print_hex(value1)));
-
-       do_negate(value1, calc_buffer);
-
-       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+       do_negate((const char*) value1, calc_buffer);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memcpy(buffer, calc_buffer, calc_buffer_size);
@@ -1447,12 +1142,7 @@ void sc_and(const void *value1, const void *value2, void *buffer)
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s & ", sc_print_hex(value1)));
-       DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
-
-       do_bitand(value1, value2, calc_buffer);
-
-       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+       do_bitand((const char*) value1, (const char*) value2, calc_buffer);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memcpy(buffer, calc_buffer, calc_buffer_size);
@@ -1464,12 +1154,7 @@ void sc_andnot(const void *value1, const void *value2, void *buffer)
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s & ", sc_print_hex(value1)));
-       DEBUGPRINTF_COMPUTATION(("~%s -> ", sc_print_hex(value2)));
-
-       do_bitandnot(value1, value2, calc_buffer);
-
-       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+       do_bitandnot((const char*) value1, (const char*) value2, calc_buffer);
 
        if (buffer != NULL && buffer != calc_buffer) {
                memcpy(buffer, calc_buffer, calc_buffer_size);
@@ -1481,12 +1166,7 @@ void sc_or(const void *value1, const void *value2, void *buffer)
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s | ", sc_print_hex(value1)));
-       DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
-
-       do_bitor(value1, value2, calc_buffer);
-
-       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+       do_bitor((const char*) value1, (const char*) value2, calc_buffer);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memcpy(buffer, calc_buffer, calc_buffer_size);
@@ -1498,12 +1178,7 @@ void sc_xor(const void *value1, const void *value2, void *buffer)
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s ^ ", sc_print_hex(value1)));
-       DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
-
-       do_bitxor(value1, value2, calc_buffer);
-
-       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+       do_bitxor((const char*) value1, (const char*) value2, calc_buffer);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memcpy(buffer, calc_buffer, calc_buffer_size);
@@ -1515,11 +1190,7 @@ void sc_not(const void *value1, void *buffer)
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("~ %s ->", sc_print_hex(value1)));
-
-       do_bitnot(value1, calc_buffer);
-
-       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+       do_bitnot((const char*) value1, calc_buffer);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memcpy(buffer, calc_buffer, calc_buffer_size);
@@ -1531,12 +1202,7 @@ void sc_mul(const void *value1, const void *value2, void *buffer)
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s * ", sc_print_hex(value1)));
-       DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
-
-       do_mul(value1, value2, calc_buffer);
-
-       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+       do_mul((const char*) value1, (const char*) value2, calc_buffer);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memcpy(buffer, calc_buffer, calc_buffer_size);
@@ -1546,17 +1212,12 @@ void sc_mul(const void *value1, const void *value2, void *buffer)
 void sc_div(const void *value1, const void *value2, void *buffer)
 {
        /* temp buffer holding unused result of divmod */
-       char *unused_res = alloca(calc_buffer_size);
+       char *unused_res = (char*) alloca(calc_buffer_size);
 
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s / ", sc_print_hex(value1)));
-       DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
-
-       do_divmod(value1, value2, calc_buffer, unused_res);
-
-       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+       do_divmod((const char*) value1, (const char*) value2, calc_buffer, unused_res);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memcpy(buffer, calc_buffer, calc_buffer_size);
@@ -1566,17 +1227,12 @@ void sc_div(const void *value1, const void *value2, void *buffer)
 void sc_mod(const void *value1, const void *value2, void *buffer)
 {
        /* temp buffer holding unused result of divmod */
-       char *unused_res = alloca(calc_buffer_size);
+       char *unused_res = (char*) alloca(calc_buffer_size);
 
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s %% ", sc_print_hex(value1)));
-       DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
-
-       do_divmod(value1, value2, unused_res, calc_buffer);
-
-       DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
+       do_divmod((const char*) value1, (const char*) value2, unused_res, calc_buffer);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memcpy(buffer, calc_buffer, calc_buffer_size);
@@ -1588,12 +1244,7 @@ void sc_divmod(const void *value1, const void *value2, void *div_buffer, void *m
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s %% ", sc_print_hex(value1)));
-       DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
-
-       do_divmod(value1, value2, div_buffer, mod_buffer);
-
-       DEBUGPRINTF_COMPUTATION(("%s:%s\n", sc_print_hex(div_buffer), sc_print_hex(mod_buffer)));
+       do_divmod((const char*) value1, (const char*) value2, (char*) div_buffer, (char*) mod_buffer);
 }
 
 
@@ -1601,10 +1252,7 @@ void sc_shlI(const void *val1, long shift_cnt, int bitsize, int sign, void *buff
 {
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s << %ld ", sc_print_hex(value1), shift_cnt));
-       do_shl(val1, calc_buffer, shift_cnt, bitsize, sign);
-
-       DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
+       do_shl((const char*) val1, calc_buffer, shift_cnt, bitsize, sign);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memmove(buffer, calc_buffer, calc_buffer_size);
@@ -1622,10 +1270,7 @@ void sc_shrI(const void *val1, long shift_cnt, int bitsize, int sign, void *buff
 {
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s >>u %ld ", sc_print_hex(value1), shift_cnt));
-       do_shr(val1, calc_buffer, shift_cnt, bitsize, sign, 0);
-
-       DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
+       do_shr((const char*) val1, calc_buffer, shift_cnt, bitsize, sign, 0);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memmove(buffer, calc_buffer, calc_buffer_size);
@@ -1639,16 +1284,24 @@ void sc_shr(const void *val1, const void *val2, int bitsize, int sign, void *buf
        sc_shrI(val1, shift_cnt, bitsize, sign, buffer);
 }
 
+void sc_shrsI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer)
+{
+       carry_flag = 0;
+
+       do_shr((const char*) val1, calc_buffer, shift_cnt, bitsize, sign, 1);
+
+       if ((buffer != NULL) && (buffer != calc_buffer)) {
+               memmove(buffer, calc_buffer, calc_buffer_size);
+       }
+}
+
 void sc_shrs(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
 {
        long offset = sc_val_to_long(val2);
 
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s >>s %ld ", sc_print_hex(value1), offset));
-       do_shr(val1, calc_buffer, offset, bitsize, sign, 1);
-
-       DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
+       do_shr((const char*) val1, calc_buffer, offset, bitsize, sign, 1);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memmove(buffer, calc_buffer, calc_buffer_size);
@@ -1661,10 +1314,7 @@ void sc_rotl(const void *val1, const void *val2, int bitsize, int sign, void *bu
 
        carry_flag = 0;
 
-       DEBUGPRINTF_COMPUTATION(("%s <<>> %ld ", sc_print_hex(value1), offset));
-       do_rotl(val1, calc_buffer, offset, bitsize, sign);
-
-       DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
+       do_rotl((const char*) val1, calc_buffer, offset, bitsize, sign);
 
        if ((buffer != NULL) && (buffer != calc_buffer)) {
                memmove(buffer, calc_buffer, calc_buffer_size);