X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Ftv%2Fstrcalc.c;h=9d9ee6e695f0f24f1461aa59fc76ab61383d6e6b;hb=34e3b8d50bce639e760da7233524a4db85c80290;hp=9a968445372b007822fa6c92d85b857caedd4e13;hpb=e07b61c6ed5d198a484761f8a40a4f26520d964d;p=libfirm diff --git a/ir/tv/strcalc.c b/ir/tv/strcalc.c index 9a9684453..9d9ee6e69 100644 --- a/ir/tv/strcalc.c +++ b/ir/tv/strcalc.c @@ -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,22 +8,14 @@ * @brief Provides basic mathematical operations on values represented as strings. * @date 2003 * @author Mathias Heil - * @version $Id$ */ +#include "config.h" -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef HAVE_STDLIB_H -# include -#endif -#ifdef HAVE_STRING_H -# include /* memset/memcmp */ -#endif -#include /* assertions */ -#include /* output for error messages */ -#include /* definition of LONG_MIN, used in sc_get_val_from_long */ +#include +#include +#include +#include +#include #include "strcalc.h" #include "xmalloc.h" @@ -46,30 +24,15 @@ /* * 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) (and_table[_val(digit)][_val(shift_table[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 - +#define _bitisset(digit, pos) (((digit) & SHIFT(pos)) != SC_0) /* * private variables @@ -91,323 +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 const char not_table[16] = { SC_F, SC_E, SC_D, SC_C, SC_B, SC_A, SC_9, SC_8, - SC_7, SC_6, SC_5, SC_4, SC_3, SC_2, SC_1, SC_0 }; - -static const char shift_table[4] = { SC_1, SC_2, SC_4, SC_8 }; - -static const char and_table[16][16] = { - { 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_1, SC_0, SC_1, SC_0, SC_1, - SC_0, SC_1, SC_0, SC_1, SC_0, SC_1, SC_0, SC_1 }, - - { SC_0, SC_0, SC_2, SC_2, SC_0, SC_0, SC_2, SC_2, - SC_0, SC_0, SC_2, SC_2, SC_0, SC_0, SC_2, SC_2 }, - - { SC_0, SC_1, SC_2, SC_3, SC_0, SC_1, SC_2, SC_3, - SC_0, SC_1, SC_2, SC_3, SC_0, SC_1, SC_2, SC_3 }, - - { SC_0, SC_0, SC_0, SC_0, SC_4, SC_4, SC_4, SC_4, - SC_0, SC_0, SC_0, SC_0, SC_4, SC_4, SC_4, SC_4 }, - - { SC_0, SC_1, SC_0, SC_1, SC_4, SC_5, SC_4, SC_5, - SC_0, SC_1, SC_0, SC_1, SC_4, SC_5, SC_4, SC_5 }, - - { SC_0, SC_0, SC_2, SC_2, SC_4, SC_4, SC_6, SC_6, - SC_0, SC_0, SC_2, SC_2, SC_4, SC_4, SC_6, SC_6 }, - - { SC_0, SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7, - SC_0, SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7 }, - - { SC_0, SC_0, SC_0, SC_0, SC_0, SC_0, SC_0, SC_0, - SC_8, SC_8, SC_8, SC_8, SC_8, SC_8, SC_8, SC_8 }, - - { SC_0, SC_1, SC_0, SC_1, SC_0, SC_1, SC_0, SC_1, - SC_8, SC_9, SC_8, SC_9, SC_8, SC_9, SC_8, SC_9 }, - - { SC_0, SC_0, SC_2, SC_2, SC_0, SC_0, SC_2, SC_2, - SC_8, SC_8, SC_A, SC_A, SC_8, SC_8, SC_A, SC_A }, - - { SC_0, SC_1, SC_2, SC_3, SC_0, SC_1, SC_2, SC_3, - SC_8, SC_9, SC_A, SC_B, SC_8, SC_9, SC_A, SC_B }, - - { SC_0, SC_0, SC_0, SC_0, SC_4, SC_4, SC_4, SC_4, - SC_8, SC_8, SC_8, SC_8, SC_C, SC_C, SC_C, SC_C }, - - { SC_0, SC_1, SC_0, SC_1, SC_4, SC_5, SC_4, SC_5, - SC_8, SC_9, SC_8, SC_9, SC_C, SC_D, SC_C, SC_D }, - - { SC_0, SC_0, SC_2, SC_2, SC_4, SC_4, SC_6, SC_6, - SC_8, SC_8, SC_A, SC_A, SC_C, SC_C, SC_E, SC_E }, - - { 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 } }; - -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 xor_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_0, SC_3, SC_2, SC_5, SC_4, SC_7, SC_6, - SC_9, SC_8, SC_B, SC_A, SC_D, SC_C, SC_F, SC_E }, - - { SC_2, SC_3, SC_0, SC_1, SC_6, SC_7, SC_4, SC_5, - SC_A, SC_B, SC_8, SC_9, SC_E, SC_F, SC_C, SC_D }, - - { SC_3, SC_2, SC_1, SC_0, SC_7, SC_6, SC_5, SC_4, - SC_B, SC_A, SC_9, SC_8, SC_F, SC_E, SC_D, SC_C }, - - { SC_4, SC_5, SC_6, SC_7, SC_0, SC_1, SC_2, SC_3, - SC_C, SC_D, SC_E, SC_F, SC_8, SC_9, SC_A, SC_B }, - - { SC_5, SC_4, SC_7, SC_6, SC_1, SC_0, SC_3, SC_2, - SC_D, SC_C, SC_F, SC_E, SC_9, SC_8, SC_B, SC_A }, - - { SC_6, SC_7, SC_4, SC_5, SC_2, SC_3, SC_0, SC_1, - SC_E, SC_F, SC_C, SC_D, SC_A, SC_B, SC_8, SC_9 }, - - { SC_7, SC_6, SC_5, SC_4, SC_3, SC_2, SC_1, SC_0, - SC_F, SC_E, SC_D, SC_C, SC_B, SC_A, SC_9, SC_8 }, - - { SC_8, SC_9, SC_A, SC_B, SC_C, SC_D, SC_E, SC_F, - SC_0, SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7 }, - - { SC_9, SC_8, SC_B, SC_A, SC_D, SC_C, SC_F, SC_E, - SC_1, SC_0, SC_3, SC_2, SC_5, SC_4, SC_7, SC_6 }, - - { SC_A, SC_B, SC_8, SC_9, SC_E, SC_F, SC_C, SC_D, - SC_2, SC_3, SC_0, SC_1, SC_6, SC_7, SC_4, SC_5 }, - - { SC_B, SC_A, SC_9, SC_8, SC_F, SC_E, SC_D, SC_C, - SC_3, SC_2, SC_1, SC_0, SC_7, SC_6, SC_5, SC_4 }, - - { SC_C, SC_D, SC_E, SC_F, SC_8, SC_9, SC_A, SC_B, - SC_4, SC_5, SC_6, SC_7, SC_0, SC_1, SC_2, SC_3 }, - - { SC_D, SC_C, SC_F, SC_E, SC_9, SC_8, SC_B, SC_A, - SC_5, SC_4, SC_7, SC_6, SC_1, SC_0, SC_3, SC_2 }, - - { SC_E, SC_F, SC_C, SC_D, SC_A, SC_B, SC_8, SC_9, - SC_6, SC_7, SC_4, SC_5, SC_2, SC_3, SC_0, SC_1 }, - - { SC_F, SC_E, SC_D, SC_C, SC_B, SC_A, SC_9, SC_8, - SC_7, SC_6, SC_5, SC_4, SC_3, SC_2, SC_1, SC_0 } - }; - -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} }, @@ -428,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" }; @@ -436,53 +82,60 @@ 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> 2; @@ -508,7 +163,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) { @@ -517,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; } } @@ -528,7 +184,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); } @@ -539,17 +196,13 @@ 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) { - 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]; +static void do_add(const char *val1, const char *val2, char *buffer) +{ + 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; } @@ -557,8 +210,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); @@ -567,19 +221,18 @@ 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 */ - 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); @@ -599,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 * @@ -606,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: * @@ -621,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; } } @@ -643,7 +292,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--) { @@ -657,7 +307,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; @@ -668,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) { @@ -700,12 +351,12 @@ 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 */ - memcpy(rem, rDividend, calc_buffer_size); + case ir_relation_less: /* dividend < divisor */ + memcpy(rem, dividend, calc_buffer_size); goto end; default: /* unluckily division is necessary :( */ @@ -716,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); } @@ -747,11 +398,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) { - const char *shl; - char shift; - char carry = SC_0; - +static void do_shl(const char *val1, char *buffer, long shift_cnt, int bitsize, unsigned is_signed) +{ int counter; int bitoffset = 0; @@ -766,19 +414,20 @@ 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) */ + 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] = or_table[_val(shl[0])][_val(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] = or_table[_val(shl[0])][_val(carry)]; + unsigned const shl = val1[counter] << shift | carry; + buffer[counter + shift_cnt] = SC_RESULT(shl); bitoffset = counter; } else { bitoffset = counter - 1; @@ -793,13 +442,13 @@ 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; } } else if (is_signed && !_bitisset(buffer[shift_cnt], bitoffset)) { /* this clears the upper bits of the leftmost digit */ - buffer[shift_cnt] = and_table[_val(buffer[shift_cnt])][_val(max_digit[bitoffset])]; + buffer[shift_cnt] &= max_digit[bitoffset]; for (counter = shift_cnt+1; counter < calc_buffer_size; counter++) { buffer[counter] = SC_0; } @@ -814,7 +463,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; @@ -853,15 +503,11 @@ static void do_shr(const char *val1, char *buffer, long shift_cnt, int bitsize, carry_flag = 1; /* shift digits to the right with offset, carry and all */ - counter = 0; - if ((bitsize >> 2) > shift_nib) { - buffer[counter] = shrs_table[_val(val1[shift_nib])][shift_mod][0]; - counter = 1; - } - for (; counter < bitsize/4 - shift_nib; counter++) { + 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 */ @@ -870,20 +516,20 @@ static void do_shr(const char *val1, char *buffer, long shift_cnt, int bitsize, /* remove sign bits if mode was signed and this is an unsigned shift */ if (!signed_shift && is_signed) { - msd = and_table[_val(msd)][_val(max_digit[bitoffset])]; + msd &= max_digit[bitoffset]; } shrs = shrs_table[_val(msd)][shift_mod]; /* 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++) { @@ -895,10 +541,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; @@ -917,19 +564,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]; @@ -941,161 +591,101 @@ 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) calc_buffer[i] = SC_0; - calc_buffer[nibble] = and_table[(int)calc_buffer[nibble]][(int)zex_digit[bits & 3]]; + calc_buffer[nibble] &= zex_digit[bits & 3]; } } else { /* do zero extension */ for (i = nibble + 1; i < calc_buffer_size; ++i) calc_buffer[i] = SC_0; - calc_buffer[nibble] = and_table[(int)calc_buffer[nibble]][(int)zex_digit[bits & 3]]; + calc_buffer[nibble] &= zex_digit[bits & 3]; } } -/* 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_9 || 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_9 || 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_7 || 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; @@ -1117,17 +707,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); @@ -1135,7 +726,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; @@ -1145,7 +737,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; @@ -1154,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++) @@ -1166,13 +759,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++) @@ -1184,25 +778,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 = and_table[_val(*pos)][SC_1]; pos++; break; - case 2: *pos = and_table[_val(*pos)][SC_3]; pos++; break; - case 3: *pos = and_table[_val(*pos)][SC_7]; pos++; 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; const char *val2 = (const char *)value2; @@ -1210,22 +806,23 @@ 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) { +int sc_get_highest_set_bit(const void *value) +{ const char *val = (const char*)value; int high, counter; @@ -1244,7 +841,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; @@ -1277,7 +875,24 @@ int sc_get_lowest_set_bit(const void *value) { return -1; } -int sc_is_zero(const void *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(pos & 3)) != SC_0; +} + +void sc_set_bit_at(void *value, unsigned pos) +{ + char *val = (char*) value; + unsigned nibble = pos >> 2; + + val[nibble] |= SHIFT(pos & 3); +} + +int sc_is_zero(const void *value) +{ const char* val = (const char *)value; int counter; @@ -1288,15 +903,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; @@ -1320,12 +938,13 @@ 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"; char *base_val, *div1_res, *div2_res, *rem_res; - int counter, nibbles, i, sign; + int counter, nibbles, i, sign, mask; char x; const char *val = (const char *)value; @@ -1334,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'; @@ -1345,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) { @@ -1357,23 +973,17 @@ 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 */ if (bits & 3) { - x = and_table[_val(val[++counter])][bits & 3]; + mask = zex_digit[(bits & 3) - 1]; + x = val[counter++] & mask; *(--pos) = digits[_val(x)]; } /* now kill zeros */ for (; counter > 1; --counter, ++pos) { -#ifdef STRCALC_DEBUG_GROUPPRINT - if (pos[0] == ' ') ++pos; -#endif if (pos[0] != '0') break; } @@ -1391,7 +1001,8 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base, int sig /* last nibble must be masked */ if (bits & 3) { - x = and_table[_val(val[++counter])][bits & 3]; + mask = zex_digit[(bits & 3) - 1]; + x = val[counter++] & mask; pos -= 4; p = binary_table[_val(x)]; @@ -1430,9 +1041,9 @@ const char *sc_print(const void *value, unsigned bits, enum base_t base, int sig /* last nibble must be masked */ if (bits & 3) { + mask = zex_digit[(bits & 3) - 1]; + div1_res[counter] = p[counter] & mask; ++counter; - - div1_res[counter] = and_table[_val(p[counter])][bits & 3]; } m = div1_res; @@ -1461,7 +1072,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; @@ -1474,267 +1086,243 @@ 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)); } } -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); - - 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); } } -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); - - 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); } } -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); - - 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); } } -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); - - 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); } } -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((const char*) value1, (const char*) value2, calc_buffer); - do_bitor(value1, value2, calc_buffer); + if (buffer != NULL && buffer != calc_buffer) { + memcpy(buffer, calc_buffer, calc_buffer_size); + } +} - DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer))); +void sc_or(const void *value1, const void *value2, void *buffer) +{ + CLEAR_BUFFER(calc_buffer); + carry_flag = 0; + + do_bitor((const char*) value1, (const char*) value2, calc_buffer); if ((buffer != NULL) && (buffer != calc_buffer)) { memcpy(buffer, calc_buffer, calc_buffer_size); } } -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); - - 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); } } -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); - - 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); } } -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); - - 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); } } -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; - 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); } } -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; - 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); } } -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); - - 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); } -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); - - 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); } } -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); - - 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); } } -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; + + 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); } } -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); - - 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); } } -void sc_zero(void *buffer) { +void sc_zero(void *buffer) +{ if (buffer == NULL) buffer = calc_buffer; CLEAR_BUFFER(buffer);