ia32: Remove the ia32_x87_attr_t from ia32_asm_attr_t.
[libfirm] / ir / tv / strcalc.c
index 0901ef9..6a6e612 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
+ * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
  *
  * This file is part of libFirm.
  *
@@ -22,7 +22,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 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,8 +82,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 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},
@@ -270,7 +266,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"
 };
@@ -278,19 +274,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++)
@@ -300,7 +289,8 @@ 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++)
@@ -310,7 +300,8 @@ static void do_bitor(const char *val1, const char *val2, char *buffer) {
 /**
  * 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++)
@@ -320,7 +311,8 @@ 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++)
@@ -344,14 +336,16 @@ static void do_bitandnot(const char *val1, const char *val2, char *buffer)
  * @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;
 
@@ -361,7 +355,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) {
@@ -381,7 +376,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);
 }
@@ -392,7 +388,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;
@@ -410,8 +407,9 @@ 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) {
-       char *temp_buffer = alloca(calc_buffer_size); /* intermediate buffer to hold -val2 */
+static void do_sub(const char *val1, const char *val2, char *buffer)
+{
+       char *temp_buffer = (char*) alloca(calc_buffer_size); /* intermediate buffer to hold -val2 */
 
        do_negate(val2, temp_buffer);
        do_add(val1, temp_buffer, buffer);
@@ -420,7 +418,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 */
@@ -430,9 +429,9 @@ static void do_mul(const char *val1, const char *val2, char *buffer) {
        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);
@@ -496,7 +495,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--) {
@@ -510,7 +510,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;
@@ -521,8 +522,8 @@ 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);
@@ -600,7 +601,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;
@@ -619,7 +621,7 @@ 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)
@@ -667,7 +669,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;
@@ -744,10 +747,11 @@ 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);
+       temp1 = (char*) alloca(calc_buffer_size);
+       temp2 = (char*) alloca(calc_buffer_size);
 
        offset = offset % radius;
 
@@ -766,19 +770,22 @@ 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) {
-       char *calc_buffer = buffer;
+void sign_extend(void *buffer, ir_mode *mode)
+{
+       char *calc_buffer = (char*) buffer;
        int bits          = get_mode_size_bits(mode) - 1;
        int nibble        = bits >> 2;
        int max           = max_digit[bits & 3];
@@ -805,146 +812,86 @@ 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,
+                    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) {
+void sc_val_from_long(long value, void *buffer)
+{
        char *pos;
        char sign, is_minlong;
 
        if (buffer == NULL) buffer = calc_buffer;
-       pos = buffer;
+       pos = (char*) buffer;
 
        sign = (value < 0);
        is_minlong = value == LONG_MIN;
@@ -966,17 +913,18 @@ 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);
        }
 }
 
-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;
-       pos = buffer;
+       pos = (unsigned char*) buffer;
 
        while (pos < (unsigned char *)buffer + calc_buffer_size) {
                *pos++ = (unsigned char)_digit(value & 0xf);
@@ -984,7 +932,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;
 
@@ -994,7 +943,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;
 
@@ -1003,7 +953,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++)
@@ -1015,13 +965,14 @@ 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;
 
        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++)
@@ -1033,25 +984,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) {
-       char *cbuffer = buffer;
+void sc_truncate(unsigned int num_bits, void *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) {
+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;
@@ -1074,7 +1027,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;
 
@@ -1093,7 +1047,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;
 
@@ -1126,22 +1081,24 @@ int sc_get_lowest_set_bit(const void *value) {
        return -1;
 }
 
-int sc_get_bit_at(const void *value, unsigned pos) {
-       const char *val = value;
+int sc_get_bit_at(const void *value, unsigned pos)
+{
+       const char *val = (const char*) 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)
 {
-       char *val = value;
+       char *val = (char*) value;
        unsigned nibble = pos >> 2;
 
-       val[nibble] |= 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;
 
@@ -1152,15 +1109,18 @@ int sc_is_zero(const void *value) {
        return 1;
 }
 
-int sc_is_negative(const void *value) {
-       return do_sign(value) == -1;
+int sc_is_negative(const void *value)
+{
+       return do_sign((const char*) 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;
@@ -1184,7 +1144,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";
 
@@ -1198,10 +1159,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';
@@ -1327,7 +1288,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;
 
@@ -1346,24 +1308,27 @@ 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;
 
        DEBUGPRINTF_COMPUTATION(("%s + ", sc_print_hex(value1)));
        DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
 
-       do_add(value1, value2, calc_buffer);
+       do_add((const char*) value1, (const char*) value2, (char*) calc_buffer);
 
        DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
 
@@ -1372,14 +1337,15 @@ 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;
 
        DEBUGPRINTF_COMPUTATION(("%s - ", sc_print_hex(value1)));
        DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
 
-       do_sub(value1, value2, calc_buffer);
+       do_sub((const char*) value1, (const char*) value2, calc_buffer);
 
        DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
 
@@ -1388,12 +1354,13 @@ 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)));
 
-       do_negate(value1, calc_buffer);
+       do_negate((const char*) value1, calc_buffer);
 
        DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
 
@@ -1402,14 +1369,15 @@ 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;
 
        DEBUGPRINTF_COMPUTATION(("%s & ", sc_print_hex(value1)));
        DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
 
-       do_bitand(value1, value2, calc_buffer);
+       do_bitand((const char*) value1, (const char*) value2, calc_buffer);
 
        DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
 
@@ -1426,7 +1394,7 @@ void sc_andnot(const void *value1, const void *value2, void *buffer)
        DEBUGPRINTF_COMPUTATION(("%s & ", sc_print_hex(value1)));
        DEBUGPRINTF_COMPUTATION(("~%s -> ", sc_print_hex(value2)));
 
-       do_bitandnot(value1, value2, calc_buffer);
+       do_bitandnot((const char*) value1, (const char*) value2, calc_buffer);
 
        DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
 
@@ -1435,14 +1403,15 @@ void sc_andnot(const void *value1, const void *value2, void *buffer)
        }
 }
 
-void sc_or(const void *value1, const void *value2, void *buffer) {
+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);
+       do_bitor((const char*) value1, (const char*) value2, calc_buffer);
 
        DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
 
@@ -1451,14 +1420,15 @@ 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;
 
        DEBUGPRINTF_COMPUTATION(("%s ^ ", sc_print_hex(value1)));
        DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
 
-       do_bitxor(value1, value2, calc_buffer);
+       do_bitxor((const char*) value1, (const char*) value2, calc_buffer);
 
        DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
 
@@ -1467,13 +1437,14 @@ 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;
 
        DEBUGPRINTF_COMPUTATION(("~ %s ->", sc_print_hex(value1)));
 
-       do_bitnot(value1, calc_buffer);
+       do_bitnot((const char*) value1, calc_buffer);
 
        DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
 
@@ -1482,14 +1453,15 @@ 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;
 
        DEBUGPRINTF_COMPUTATION(("%s * ", sc_print_hex(value1)));
        DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
 
-       do_mul(value1, value2, calc_buffer);
+       do_mul((const char*) value1, (const char*) value2, calc_buffer);
 
        DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
 
@@ -1498,9 +1470,10 @@ 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);
+       char *unused_res = (char*) alloca(calc_buffer_size);
 
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
@@ -1508,7 +1481,7 @@ void sc_div(const void *value1, const void *value2, void *buffer) {
        DEBUGPRINTF_COMPUTATION(("%s / ", sc_print_hex(value1)));
        DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
 
-       do_divmod(value1, value2, calc_buffer, unused_res);
+       do_divmod((const char*) value1, (const char*) value2, calc_buffer, unused_res);
 
        DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
 
@@ -1517,9 +1490,10 @@ 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);
+       char *unused_res = (char*) alloca(calc_buffer_size);
 
        CLEAR_BUFFER(calc_buffer);
        carry_flag = 0;
@@ -1527,7 +1501,7 @@ void sc_mod(const void *value1, const void *value2, void *buffer) {
        DEBUGPRINTF_COMPUTATION(("%s %% ", sc_print_hex(value1)));
        DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
 
-       do_divmod(value1, value2, unused_res, calc_buffer);
+       do_divmod((const char*) value1, (const char*) value2, unused_res, calc_buffer);
 
        DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
 
@@ -1536,24 +1510,26 @@ 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;
 
        DEBUGPRINTF_COMPUTATION(("%s %% ", sc_print_hex(value1)));
        DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
 
-       do_divmod(value1, value2, div_buffer, mod_buffer);
+       do_divmod((const char*) value1, (const char*) value2, (char*) div_buffer, (char*) mod_buffer);
 
        DEBUGPRINTF_COMPUTATION(("%s:%s\n", sc_print_hex(div_buffer), sc_print_hex(mod_buffer)));
 }
 
 
-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));
-       do_shl(val1, calc_buffer, shift_cnt, bitsize, sign);
+       do_shl((const char*) val1, calc_buffer, shift_cnt, bitsize, sign);
 
        DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
 
@@ -1562,17 +1538,19 @@ 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));
-       do_shr(val1, calc_buffer, shift_cnt, bitsize, sign, 0);
+       do_shr((const char*) val1, calc_buffer, shift_cnt, bitsize, sign, 0);
 
        DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
 
@@ -1581,19 +1559,35 @@ 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_shrsI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer)
+{
+       carry_flag = 0;
+
+       DEBUGPRINTF_COMPUTATION(("%s >>s %ld ", sc_print_hex(value1), shift_cnt));
+       do_shr((const char*) val1, calc_buffer, shift_cnt, bitsize, sign, 1);
+
+       DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
+
+       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);
+       do_shr((const char*) val1, calc_buffer, offset, bitsize, sign, 1);
 
        DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
 
@@ -1602,13 +1596,14 @@ 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;
 
        DEBUGPRINTF_COMPUTATION(("%s <<>> %ld ", sc_print_hex(value1), offset));
-       do_rotl(val1, calc_buffer, offset, bitsize, sign);
+       do_rotl((const char*) val1, calc_buffer, offset, bitsize, sign);
 
        DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
 
@@ -1617,7 +1612,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);