print out times and reverse perfect elimination order no disabled
[libfirm] / ir / tv / strcalc.c
index 7f889a6..50aaf56 100644 (file)
  * local definitions and macros
  */
 #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_table[pos]) != SC_0)
-
-#define fail_char(a, b, c, d) _fail_char((a), (b), (c), (d), __FILE__,  __LINE__)
+#define _bitisset(digit, pos) (((digit) & SHIFT(pos)) != SC_0)
 
 /* shortcut output for debugging */
 #  define sc_print_hex(a) sc_print((a), 0, SC_HEX, 0)
@@ -84,57 +83,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 const char shift_table[4] = { SC_1, SC_2, SC_4, SC_8 };
-
-static const char or_table[16][16] = {
-                            { SC_0, SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7,
-                              SC_8, SC_9, SC_A, SC_B, SC_C, SC_D, SC_E, SC_F },
-
-                            { SC_1, SC_1, SC_3, SC_3, SC_5, SC_5, SC_7, SC_7,
-                              SC_9, SC_9, SC_B, SC_B, SC_D, SC_D, SC_F, SC_F },
-
-                            { SC_2, SC_3, SC_2, SC_3, SC_6, SC_7, SC_6, SC_7,
-                              SC_A, SC_B, SC_A, SC_B, SC_E, SC_F, SC_E, SC_F },
-
-                            { SC_3, SC_3, SC_3, SC_3, SC_7, SC_7, SC_7, SC_7,
-                              SC_B, SC_B, SC_B, SC_B, SC_F, SC_F, SC_F, SC_F },
-
-                            { SC_4, SC_5, SC_6, SC_7, SC_4, SC_5, SC_6, SC_7,
-                              SC_C, SC_D, SC_E, SC_F, SC_C, SC_D, SC_E, SC_F },
-
-                            { SC_5, SC_5, SC_7, SC_7, SC_5, SC_5, SC_7, SC_7,
-                              SC_D, SC_D, SC_F, SC_F, SC_D, SC_D, SC_F, SC_F },
-
-                            { SC_6, SC_7, SC_6, SC_7, SC_6, SC_7, SC_6, SC_7,
-                              SC_E, SC_F, SC_E, SC_F, SC_E, SC_F, SC_E, SC_F },
-
-                            { SC_7, SC_7, SC_7, SC_7, SC_7, SC_7, SC_7, SC_7,
-                              SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F },
-
-                            { SC_8, SC_9, SC_A, SC_B, SC_C, SC_D, SC_E, SC_F,
-                              SC_8, SC_9, SC_A, SC_B, SC_C, SC_D, SC_E, SC_F },
-
-                            { SC_9, SC_9, SC_B, SC_B, SC_D, SC_D, SC_F, SC_F,
-                              SC_9, SC_9, SC_B, SC_B, SC_D, SC_D, SC_F, SC_F },
-
-                            { SC_A, SC_B, SC_A, SC_B, SC_E, SC_F, SC_E, SC_F,
-                              SC_A, SC_B, SC_A, SC_B, SC_E, SC_F, SC_E, SC_F },
-
-                            { SC_B, SC_B, SC_B, SC_B, SC_F, SC_F, SC_F, SC_F,
-                              SC_B, SC_B, SC_B, SC_B, SC_F, SC_F, SC_F, SC_F },
-
-                            { SC_C, SC_D, SC_E, SC_F, SC_C, SC_D, SC_E, SC_F,
-                              SC_C, SC_D, SC_E, SC_F, SC_C, SC_D, SC_E, SC_F },
-
-                            { SC_D, SC_D, SC_F, SC_F, SC_D, SC_D, SC_F, SC_F,
-                              SC_D, SC_D, SC_F, SC_F, SC_D, SC_D, SC_F, SC_F },
-
-                            { SC_E, SC_F, SC_E, SC_F, SC_E, SC_F, SC_E, SC_F,
-                              SC_E, SC_F, SC_E, SC_F, SC_E, SC_F, SC_E, SC_F },
-
-                            { SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F,
-                              SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F } };
-
 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},
@@ -327,19 +275,12 @@ 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
  */
-static void do_bitnot(const char *val, char *buffer) {
+static void do_bitnot(const char *val, char *buffer)
+{
        int counter;
 
        for (counter = 0; counter<calc_buffer_size; counter++)
@@ -349,17 +290,19 @@ static void do_bitnot(const char *val, char *buffer) {
 /**
  * implements the bitwise OR operation
  */
-static void do_bitor(const char *val1, const char *val2, char *buffer) {
+static void do_bitor(const char *val1, const char *val2, char *buffer)
+{
        int counter;
 
        for (counter = 0; counter<calc_buffer_size; counter++)
-               buffer[counter] = or_table[_val(val1[counter])][_val(val2[counter])];
+               buffer[counter] = val1[counter] | val2[counter];
 }
 
 /**
  * implements the bitwise eXclusive OR operation
  */
-static void do_bitxor(const char *val1, const char *val2, char *buffer) {
+static void do_bitxor(const char *val1, const char *val2, char *buffer)
+{
        int counter;
 
        for (counter = 0; counter<calc_buffer_size; counter++)
@@ -369,27 +312,41 @@ static void do_bitxor(const char *val1, const char *val2, char *buffer) {
 /**
  * implements the bitwise AND operation
  */
-static void do_bitand(const char *val1, const char *val2, char *buffer) {
+static void do_bitand(const char *val1, const char *val2, char *buffer)
+{
        int counter;
 
        for (counter = 0; counter<calc_buffer_size; counter++)
                buffer[counter] = val1[counter] & val2[counter];
 }
 
+/**
+ * implements the bitwise AND not operation
+ */
+static void do_bitandnot(const char *val1, const char *val2, char *buffer)
+{
+       int counter;
+
+       for (counter = 0; counter < calc_buffer_size; ++counter)
+               buffer[counter] = val1[counter] & (SC_F ^ val2[counter]);
+}
+
 /**
  * returns the sign bit.
  *
  * @todo This implementation is wrong, as it returns the highest bit of the buffer
  *       NOT the highest bit depending on the real mode
  */
-static int do_sign(const char *val) {
+static int do_sign(const char *val)
+{
        return (val[calc_buffer_size-1] <= SC_7) ? (1) : (-1);
 }
 
 /**
  * returns non-zero if bit at position pos is set
  */
-static int do_bit(const char *val, int pos) {
+static int do_bit(const char *val, int pos)
+{
        int bit    = pos & 3;
        int nibble = pos >> 2;
 
@@ -399,7 +356,8 @@ static int do_bit(const char *val, int pos) {
 /**
  * Implements a fast ADD + 1
  */
-static void do_inc(const char *val, char *buffer) {
+static void do_inc(const char *val, char *buffer)
+{
        int counter = 0;
 
        while (counter++ < calc_buffer_size) {
@@ -419,7 +377,8 @@ static void do_inc(const char *val, char *buffer) {
 /**
  * Implements a unary MINUS
  */
-static void do_negate(const char *val, char *buffer) {
+static void do_negate(const char *val, char *buffer)
+{
        do_bitnot(val, buffer);
        do_inc(buffer, buffer);
 }
@@ -430,7 +389,8 @@ static void do_negate(const char *val, char *buffer) {
  * @todo The implementation of carry is wrong, as it is the
  *       calc_buffer_size carry, not the mode depending
  */
-static void do_add(const char *val1, const char *val2, char *buffer) {
+static void do_add(const char *val1, const char *val2, char *buffer)
+{
        int counter;
        const char *add1, *add2;
        char carry = SC_0;
@@ -448,7 +408,8 @@ static void do_add(const char *val1, const char *val2, char *buffer) {
 /**
  * Implements a binary SUB
  */
-static void do_sub(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 */
 
        do_negate(val2, temp_buffer);
@@ -458,7 +419,8 @@ static void do_sub(const char *val1, const char *val2, char *buffer) {
 /**
  * Implements a binary MUL
  */
-static void do_mul(const char *val1, const char *val2, char *buffer) {
+static void do_mul(const char *val1, const char *val2, char *buffer)
+{
        char *temp_buffer; /* result buffer */
        char *neg_val1;    /* abs of val1 */
        char *neg_val2;    /* abs of val2 */
@@ -534,7 +496,8 @@ static void do_mul(const char *val1, const char *val2, char *buffer) {
 /**
  * Shift the buffer to left and add a 4 bit digit
  */
-static void do_push(const char digit, char *buffer) {
+static void do_push(const char digit, char *buffer)
+{
        int counter;
 
        for (counter = calc_buffer_size - 2; counter >= 0; counter--) {
@@ -548,7 +511,8 @@ static void do_push(const char digit, char *buffer) {
  *
  * Note: This is MOST slow
  */
-static void do_divmod(const char *rDividend, const char *divisor, char *quot, char *rem) {
+static void do_divmod(const char *rDividend, const char *divisor, char *quot, char *rem)
+{
        const char *dividend = rDividend;
        const char *minus_divisor;
        char *neg_val1;
@@ -638,7 +602,8 @@ end:
  *
  * @todo Assertions seems to be wrong
  */
-static void do_shl(const char *val1, char *buffer, long shift_cnt, int bitsize, unsigned is_signed) {
+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;
@@ -657,19 +622,19 @@ static void do_shl(const char *val1, char *buffer, long shift_cnt, int bitsize,
                return;
        }
 
-       shift = shift_table[_val(shift_cnt%4)];      /* this is 2 ** (offset % 4) */
+       shift     = SHIFT(shift_cnt % 4); /* this is 2 ** (offset % 4) */
        shift_cnt = shift_cnt / 4;
 
        /* shift the single digits some bytes (offset) and some bits (table)
         * to the left */
        for (counter = 0; counter < bitsize/4 - shift_cnt; counter++) {
                shl = mul_table[_val(val1[counter])][_val(shift)];
-               buffer[counter + shift_cnt] = or_table[_val(shl[0])][_val(carry)];
+               buffer[counter + shift_cnt] = shl[0] | carry;
                carry = shl[1];
        }
        if (bitsize%4 > 0) {
                shl = mul_table[_val(val1[counter])][_val(shift)];
-               buffer[counter + shift_cnt] = or_table[_val(shl[0])][_val(carry)];
+               buffer[counter + shift_cnt] = shl[0] | carry;
                bitoffset = counter;
        } else {
                bitoffset = counter - 1;
@@ -684,7 +649,7 @@ static void do_shl(const char *val1, char *buffer, long shift_cnt, int bitsize,
        bitoffset = (bitsize-1) % 4;
        if (is_signed && _bitisset(buffer[shift_cnt], bitoffset)) {
                /* this sets the upper bits of the leftmost digit */
-               buffer[shift_cnt] = or_table[_val(buffer[shift_cnt])][_val(min_digit[bitoffset])];
+               buffer[shift_cnt] |= min_digit[bitoffset];
                for (counter = shift_cnt+1; counter < calc_buffer_size; counter++) {
                        buffer[counter] = SC_F;
                }
@@ -705,7 +670,8 @@ static void do_shl(const char *val1, char *buffer, long shift_cnt, int bitsize,
  *
  * @todo Assertions seems to be wrong
  */
-static void do_shr(const char *val1, char *buffer, long shift_cnt, int bitsize, unsigned is_signed, int signed_shift) {
+static void do_shr(const char *val1, char *buffer, long shift_cnt, int bitsize, unsigned is_signed, int signed_shift)
+{
        const char *shrs;
        char sign;
        char msd;
@@ -747,8 +713,8 @@ static void do_shr(const char *val1, char *buffer, long shift_cnt, int bitsize,
        buffer[0] = shrs_table[_val(val1[shift_nib])][shift_mod][0];
        for (counter = 1; counter < ((bitsize + 3) >> 2) - shift_nib; counter++) {
                shrs = shrs_table[_val(val1[counter + shift_nib])][shift_mod];
-               buffer[counter]     = shrs[0];
-               buffer[counter - 1] = or_table[_val(buffer[counter-1])][_val(shrs[1])];
+               buffer[counter]      = shrs[0];
+               buffer[counter - 1] |= shrs[1];
        }
 
        /* the last digit is special in regard of signed/unsigned shift */
@@ -764,13 +730,13 @@ static void do_shr(const char *val1, char *buffer, long shift_cnt, int bitsize,
 
        /* signed shift and signed mode and negative value means all bits to the left are set */
        if (signed_shift && sign == SC_F) {
-               buffer[counter] = or_table[_val(shrs[0])][_val(min_digit[bitoffset])];
+               buffer[counter] = shrs[0] | min_digit[bitoffset];
        } else {
                buffer[counter] = shrs[0];
        }
 
        if (counter > 0)
-               buffer[counter - 1] = or_table[_val(buffer[counter-1])][_val(shrs[1])];
+               buffer[counter - 1] |= shrs[1];
 
        /* fill with SC_F or SC_0 depending on sign */
        for (counter++; counter < calc_buffer_size; counter++) {
@@ -782,7 +748,8 @@ static void do_shr(const char *val1, char *buffer, long shift_cnt, int bitsize,
  * Implements a Rotate Left.
  * positive: low-order -> high order, negative other direction
  */
-static void do_rotl(const char *val1, char *buffer, long offset, int radius, unsigned is_signed) {
+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);
@@ -804,18 +771,21 @@ static void do_rotl(const char *val1, char *buffer, long offset, int radius, uns
 /*****************************************************************************
  * public functions, declared in strcalc.h
  *****************************************************************************/
-const void *sc_get_buffer(void) {
+const void *sc_get_buffer(void)
+{
        return (void*)calc_buffer;
 }
 
-int sc_get_buffer_length(void) {
+int sc_get_buffer_length(void)
+{
        return calc_buffer_size;
 }
 
 /**
  * Do sign extension if the mode is signed, otherwise to zero extension.
  */
-void sign_extend(void *buffer, ir_mode *mode) {
+void sign_extend(void *buffer, ir_mode *mode)
+{
        char *calc_buffer = buffer;
        int bits          = get_mode_size_bits(mode) - 1;
        int nibble        = bits >> 2;
@@ -828,7 +798,7 @@ void sign_extend(void *buffer, ir_mode *mode) {
 
                        for (i = nibble + 1; i < calc_buffer_size; ++i)
                                calc_buffer[i] = SC_F;
-                       calc_buffer[nibble] = or_table[(int)calc_buffer[nibble]][(int)sex_digit[bits & 3]];
+                       calc_buffer[nibble] |= sex_digit[bits & 3];
                } else {
                        /* set all bits to zero */
                        for (i = nibble + 1; i < calc_buffer_size; ++i)
@@ -843,141 +813,81 @@ 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) {
-       const char *orig_str = str;
-       unsigned int orig_len = len;
+/* 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)
+{
+       /* 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,
+                    unsigned int 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 = alloca(calc_buffer_size);
+       sc_val_from_ulong(base, sc_base);
 
-       if (buffer == NULL) buffer = calc_buffer;
+       val = 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, buffer, buffer);
+               /* add next digit to current value  */
+               do_add(val, buffer, 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(buffer, 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) {
+void sc_val_from_long(long value, void *buffer)
+{
        char *pos;
        char sign, is_minlong;
 
@@ -1010,7 +920,8 @@ void sc_val_from_long(long value, void *buffer) {
        }
 }
 
-void sc_val_from_ulong(unsigned long value, void *buffer) {
+void sc_val_from_ulong(unsigned long value, void *buffer)
+{
        unsigned char *pos;
 
        if (buffer == NULL) buffer = calc_buffer;
@@ -1022,7 +933,8 @@ void sc_val_from_ulong(unsigned long value, void *buffer) {
        }
 }
 
-long sc_val_to_long(const void *val) {
+long sc_val_to_long(const void *val)
+{
        int i;
        long l = 0;
 
@@ -1032,7 +944,8 @@ long sc_val_to_long(const void *val) {
        return l;
 }
 
-void sc_min_from_bits(unsigned int num_bits, unsigned int sign, void *buffer) {
+void sc_min_from_bits(unsigned int num_bits, unsigned int sign, void *buffer)
+{
        char *pos;
        int i, bits;
 
@@ -1053,7 +966,8 @@ void sc_min_from_bits(unsigned int num_bits, unsigned int sign, void *buffer) {
                *pos++ = SC_F;
 }
 
-void sc_max_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)
+{
        char* pos;
        int i, bits;
 
@@ -1071,25 +985,27 @@ 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) {
+void sc_truncate(unsigned int num_bits, void *buffer)
+{
        char *cbuffer = 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) {
+int sc_comp(const void* value1, const void* value2)
+{
        int counter = calc_buffer_size - 1;
        const char *val1 = (const char *)value1;
        const char *val2 = (const char *)value2;
@@ -1112,7 +1028,8 @@ int sc_comp(const void* value1, const void* value2) {
        return (val1[counter] > val2[counter]) ? (1) : (-1);
 }
 
-int sc_get_highest_set_bit(const void *value) {
+int sc_get_highest_set_bit(const void *value)
+{
        const char *val = (const char*)value;
        int high, counter;
 
@@ -1131,7 +1048,8 @@ int sc_get_highest_set_bit(const void *value) {
        return high;
 }
 
-int sc_get_lowest_set_bit(const void *value) {
+int sc_get_lowest_set_bit(const void *value)
+{
        const char *val = (const char*)value;
        int low, counter;
 
@@ -1164,11 +1082,12 @@ int sc_get_lowest_set_bit(const void *value) {
        return -1;
 }
 
-int sc_get_bit_at(const void *value, unsigned pos) {
+int sc_get_bit_at(const void *value, unsigned pos)
+{
        const char *val = value;
        unsigned nibble = pos >> 2;
 
-       return (val[nibble] & shift_table[pos & 3]) != SC_0;
+       return (val[nibble] & SHIFT(pos & 3)) != SC_0;
 }
 
 void sc_set_bit_at(void *value, unsigned pos)
@@ -1176,10 +1095,11 @@ void sc_set_bit_at(void *value, unsigned pos)
        char *val = value;
        unsigned nibble = pos >> 2;
 
-       val[nibble] = or_table[(int)val[nibble]][(int)shift_table[pos & 3]];
+       val[nibble] |= SHIFT(pos & 3);
 }
 
-int sc_is_zero(const void *value) {
+int sc_is_zero(const void *value)
+{
        const char* val = (const char *)value;
        int counter;
 
@@ -1190,15 +1110,18 @@ int sc_is_zero(const void *value) {
        return 1;
 }
 
-int sc_is_negative(const void *value) {
+int sc_is_negative(const void *value)
+{
        return do_sign(value) == -1;
 }
 
-int sc_had_carry(void) {
+int sc_had_carry(void)
+{
        return carry_flag;
 }
 
-unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs) {
+unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs)
+{
        const char *val = (const char *)value;
        int nibble_ofs  = 2 * byte_ofs;
        unsigned char res;
@@ -1222,7 +1145,8 @@ 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, int signed_mode) {
+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";
 
@@ -1365,7 +1289,8 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base, int sig
        return pos;
 }
 
-void init_strcalc(int precision) {
+void init_strcalc(int precision)
+{
        if (calc_buffer == NULL) {
                if (precision <= 0) precision = SC_DEFAULT_PRECISION;
 
@@ -1384,17 +1309,20 @@ void init_strcalc(int precision) {
 }
 
 
-void finish_strcalc(void) {
+void finish_strcalc(void)
+{
        free(calc_buffer);   calc_buffer   = NULL;
        free(output_buffer); output_buffer = NULL;
 }
 
-int sc_get_precision(void) {
+int sc_get_precision(void)
+{
        return bit_pattern_size;
 }
 
 
-void sc_add(const void *value1, const void *value2, void *buffer) {
+void sc_add(const void *value1, const void *value2, void *buffer)
+{
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
@@ -1410,7 +1338,8 @@ void sc_add(const void *value1, const void *value2, void *buffer) {
        }
 }
 
-void sc_sub(const void *value1, const void *value2, void *buffer) {
+void sc_sub(const void *value1, const void *value2, void *buffer)
+{
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
@@ -1426,7 +1355,8 @@ void sc_sub(const void *value1, const void *value2, void *buffer) {
        }
 }
 
-void sc_neg(const void *value1, void *buffer) {
+void sc_neg(const void *value1, void *buffer)
+{
        carry_flag = 0;
 
        DEBUGPRINTF_COMPUTATION(("- %s ->", sc_print_hex(value1)));
@@ -1440,7 +1370,8 @@ void sc_neg(const void *value1, void *buffer) {
        }
 }
 
-void sc_and(const void *value1, const void *value2, void *buffer) {
+void sc_and(const void *value1, const void *value2, void *buffer)
+{
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
@@ -1456,7 +1387,25 @@ void sc_and(const void *value1, const void *value2, void *buffer) {
        }
 }
 
-void sc_or(const void *value1, const void *value2, void *buffer) {
+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)));
+
+       if (buffer != NULL && buffer != calc_buffer) {
+               memcpy(buffer, calc_buffer, calc_buffer_size);
+       }
+}
+
+void sc_or(const void *value1, const void *value2, void *buffer)
+{
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
@@ -1472,7 +1421,8 @@ void sc_or(const void *value1, const void *value2, void *buffer) {
        }
 }
 
-void sc_xor(const void *value1, const void *value2, void *buffer) {
+void sc_xor(const void *value1, const void *value2, void *buffer)
+{
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
@@ -1488,7 +1438,8 @@ void sc_xor(const void *value1, const void *value2, void *buffer) {
        }
 }
 
-void sc_not(const void *value1, void *buffer) {
+void sc_not(const void *value1, void *buffer)
+{
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
@@ -1503,7 +1454,8 @@ void sc_not(const void *value1, void *buffer) {
        }
 }
 
-void sc_mul(const void *value1, const void *value2, void *buffer) {
+void sc_mul(const void *value1, const void *value2, void *buffer)
+{
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
@@ -1519,7 +1471,8 @@ void sc_mul(const void *value1, const void *value2, void *buffer) {
        }
 }
 
-void sc_div(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);
 
@@ -1538,7 +1491,8 @@ void sc_div(const void *value1, const void *value2, void *buffer) {
        }
 }
 
-void sc_mod(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);
 
@@ -1557,7 +1511,8 @@ void sc_mod(const void *value1, const void *value2, void *buffer) {
        }
 }
 
-void sc_divmod(const void *value1, const void *value2, void *div_buffer, void *mod_buffer) {
+void sc_divmod(const void *value1, const void *value2, void *div_buffer, void *mod_buffer)
+{
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
 
@@ -1570,7 +1525,8 @@ void sc_divmod(const void *value1, const void *value2, void *div_buffer, void *m
 }
 
 
-void sc_shlI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer) {
+void sc_shlI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer)
+{
        carry_flag = 0;
 
        DEBUGPRINTF_COMPUTATION(("%s << %ld ", sc_print_hex(value1), shift_cnt));
@@ -1583,13 +1539,15 @@ void sc_shlI(const void *val1, long shift_cnt, int bitsize, int sign, void *buff
        }
 }
 
-void sc_shl(const void *val1, const void *val2, int bitsize, int sign, void *buffer) {
+void sc_shl(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
+{
        long offset = sc_val_to_long(val2);
 
        sc_shlI(val1, offset, bitsize, sign, buffer);
 }
 
-void sc_shrI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer) {
+void sc_shrI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer)
+{
        carry_flag = 0;
 
        DEBUGPRINTF_COMPUTATION(("%s >>u %ld ", sc_print_hex(value1), shift_cnt));
@@ -1602,13 +1560,15 @@ void sc_shrI(const void *val1, long shift_cnt, int bitsize, int sign, void *buff
        }
 }
 
-void sc_shr(const void *val1, const void *val2, int bitsize, int sign, void *buffer) {
+void sc_shr(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
+{
        long shift_cnt = sc_val_to_long(val2);
 
        sc_shrI(val1, shift_cnt, bitsize, sign, buffer);
 }
 
-void sc_shrs(const void *val1, const void *val2, int bitsize, int sign, void *buffer) {
+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;
@@ -1623,7 +1583,8 @@ void sc_shrs(const void *val1, const void *val2, int bitsize, int sign, void *bu
        }
 }
 
-void sc_rotl(const void *val1, const void *val2, int bitsize, int sign, void *buffer) {
+void sc_rotl(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
+{
        long offset = sc_val_to_long(val2);
 
        carry_flag = 0;
@@ -1638,7 +1599,8 @@ void sc_rotl(const void *val1, const void *val2, int bitsize, int sign, void *bu
        }
 }
 
-void sc_zero(void *buffer) {
+void sc_zero(void *buffer)
+{
        if (buffer == NULL)
                buffer = calc_buffer;
        CLEAR_BUFFER(buffer);