1 /*
2  * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19 
20 /**
21  * @file
22  * @brief    Provides basic mathematical operations on values represented as strings.
23  * @date     2003
24  * @author   Mathias Heil
25  */
26 #include "config.h"
27 
28 #include <stdlib.h>
29 #include <string.h>
30 #include <assert.h>
31 #include <stdio.h>
32 #include <limits.h>
33 
34 #include "strcalc.h"
35 #include "xmalloc.h"
36 #include "error.h"
37 
38 /*
39  * local definitions and macros
40  */
41 #define CLEAR_BUFFER(b) assert(b); memset(b, SC_0, calc_buffer_size)
42 #define SHIFT(count) (SC_1 << (count))
43 #define _val(a) ((a)-SC_0)
44 #define _digit(a) ((a)+SC_0)
45 #define _bitisset(digit, pos) (((digit) & SHIFT(pos)) != SC_0)
46 
47 /* shortcut output for debugging */
48 #  define sc_print_hex(a) sc_print((a), 0, SC_HEX, 0)
49 #  define sc_print_dec(a) sc_print((a), 0, SC_DEC, 1)
50 #  define sc_print_oct(a) sc_print((a), 0, SC_OCT, 0)
51 #  define sc_print_bin(a) sc_print((a), 0, SC_BIN, 0)
52 
53 #ifdef STRCALC_DEBUG_PRINTCOMP
54 #  define DEBUGPRINTF_COMPUTATION(x) printf x
55 #else
56 #  define DEBUGPRINTF_COMPUTATION(x) ((void)0)
57 #endif
58 #ifdef STRCALC_DEBUG
59 #  define DEBUGPRINTF(x) printf x
60 #else
61 #  define DEBUGPRINTF(x) ((void)0)
62 #endif
63 
64 
65 /*
66  * private variables
67  */
68 static char *calc_buffer = NULL;    /* buffer holding all results */
69 static char *output_buffer = NULL;  /* buffer for output */
70 static int bit_pattern_size;        /* maximum number of bits */
71 static int calc_buffer_size;        /* size of internally stored values */
72 static int max_value_size;          /* maximum size of values */
73 
74 static int carry_flag;              /**< some computation set the carry_flag:
75                                          - right shift if bits were lost due to shifting
76                                          - division if there was a remainder
77                                          However, the meaning of carry is machine dependent
78                                          and often defined in other ways! */
79 
80 static const char sex_digit[4] = { SC_E, SC_C, SC_8, SC_0 };
81 static const char zex_digit[4] = { SC_1, SC_3, SC_7, SC_F };
82 static const char max_digit[4] = { SC_0, SC_1, SC_3, SC_7 };
83 static const char min_digit[4] = { SC_F, SC_E, SC_C, SC_8 };
84 
85 static char const add_table[16][16][2] = {
86                        { {SC_0, SC_0}, {SC_1, SC_0}, {SC_2, SC_0}, {SC_3, SC_0},
87                          {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0},
88                          {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
89                          {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0} },
90 
91                        { {SC_1, SC_0}, {SC_2, SC_0}, {SC_3, SC_0}, {SC_4, SC_0},
92                          {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0},
93                          {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0},
94                          {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1} },
95 
96                        { {SC_2, SC_0}, {SC_3, SC_0}, {SC_4, SC_0}, {SC_5, SC_0},
97                          {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0},
98                          {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0},
99                          {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1} },
100 
101                        { {SC_3, SC_0}, {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0},
102                          {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0},
103                          {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0},
104                          {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1} },
105 
106                        { {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0},
107                          {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
108                          {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0},
109                          {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1} },
110 
111                        { {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0},
112                          {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0},
113                          {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1},
114                          {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1} },
115 
116                        { {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0},
117                          {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0},
118                          {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1},
119                          {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1} },
120 
121                        { {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0},
122                          {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0},
123                          {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1},
124                          {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1} },
125 
126                        { {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
127                          {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0},
128                          {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1},
129                          {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1} },
130 
131                        { {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0},
132                          {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1},
133                          {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1},
134                          {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1} },
135 
136                        { {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0},
137                          {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1},
138                          {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1},
139                          {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1} },
140 
141                        { {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0},
142                          {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1},
143                          {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1},
144                          {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1}, {SC_A, SC_1} },
145 
146                        { {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0},
147                          {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1},
148                          {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1},
149                          {SC_8, SC_1}, {SC_9, SC_1}, {SC_A, SC_1}, {SC_B, SC_1} },
150 
151                        { {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1},
152                          {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1},
153                          {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1},
154                          {SC_9, SC_1}, {SC_A, SC_1}, {SC_B, SC_1}, {SC_C, SC_1} },
155 
156                        { {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1},
157                          {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1},
158                          {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1},
159                          {SC_A, SC_1}, {SC_B, SC_1}, {SC_C, SC_1}, {SC_D, SC_1} },
160 
161                        { {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1},
162                          {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1},
163                          {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1}, {SC_A, SC_1},
164                          {SC_B, SC_1}, {SC_C, SC_1}, {SC_D, SC_1}, {SC_E, SC_1} }
165                              };
166 
167 static char const mul_table[16][16][2] = {
168                        { {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0},
169                          {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0},
170                          {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0},
171                          {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0} },
172 
173                        { {SC_0, SC_0}, {SC_1, SC_0}, {SC_2, SC_0}, {SC_3, SC_0},
174                          {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0},
175                          {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
176                          {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0} },
177 
178                        { {SC_0, SC_0}, {SC_2, SC_0}, {SC_4, SC_0}, {SC_6, SC_0},
179                          {SC_8, SC_0}, {SC_A, SC_0}, {SC_C, SC_0}, {SC_E, SC_0},
180                          {SC_0, SC_1}, {SC_2, SC_1}, {SC_4, SC_1}, {SC_6, SC_1},
181                          {SC_8, SC_1}, {SC_A, SC_1}, {SC_C, SC_1}, {SC_E, SC_1} },
182 
183                        { {SC_0, SC_0}, {SC_3, SC_0}, {SC_6, SC_0}, {SC_9, SC_0},
184                          {SC_C, SC_0}, {SC_F, SC_0}, {SC_2, SC_1}, {SC_5, SC_1},
185                          {SC_8, SC_1}, {SC_B, SC_1}, {SC_E, SC_1}, {SC_1, SC_2},
186                          {SC_4, SC_2}, {SC_7, SC_2}, {SC_A, SC_2}, {SC_D, SC_2} },
187 
188                        { {SC_0, SC_0}, {SC_4, SC_0}, {SC_8, SC_0}, {SC_C, SC_0},
189                          {SC_0, SC_1}, {SC_4, SC_1}, {SC_8, SC_1}, {SC_C, SC_1},
190                          {SC_0, SC_2}, {SC_4, SC_2}, {SC_8, SC_2}, {SC_C, SC_2},
191                          {SC_0, SC_3}, {SC_4, SC_3}, {SC_8, SC_3}, {SC_C, SC_3} },
192 
193                        { {SC_0, SC_0}, {SC_5, SC_0}, {SC_A, SC_0}, {SC_F, SC_0},
194                          {SC_4, SC_1}, {SC_9, SC_1}, {SC_E, SC_1}, {SC_3, SC_2},
195                          {SC_8, SC_2}, {SC_D, SC_2}, {SC_2, SC_3}, {SC_7, SC_3},
196                          {SC_C, SC_3}, {SC_1, SC_4}, {SC_6, SC_4}, {SC_B, SC_4} },
197 
198                        { {SC_0, SC_0}, {SC_6, SC_0}, {SC_C, SC_0}, {SC_2, SC_1},
199                          {SC_8, SC_1}, {SC_E, SC_1}, {SC_4, SC_2}, {SC_A, SC_2},
200                          {SC_0, SC_3}, {SC_6, SC_3}, {SC_C, SC_3}, {SC_2, SC_4},
201                          {SC_8, SC_4}, {SC_E, SC_4}, {SC_4, SC_5}, {SC_A, SC_5} },
202 
203                        { {SC_0, SC_0}, {SC_7, SC_0}, {SC_E, SC_0}, {SC_5, SC_1},
204                          {SC_C, SC_1}, {SC_3, SC_2}, {SC_A, SC_2}, {SC_1, SC_3},
205                          {SC_8, SC_3}, {SC_F, SC_3}, {SC_6, SC_4}, {SC_D, SC_4},
206                          {SC_4, SC_5}, {SC_B, SC_5}, {SC_2, SC_6}, {SC_9, SC_6} },
207 
208                        { {SC_0, SC_0}, {SC_8, SC_0}, {SC_0, SC_1}, {SC_8, SC_1},
209                          {SC_0, SC_2}, {SC_8, SC_2}, {SC_0, SC_3}, {SC_8, SC_3},
210                          {SC_0, SC_4}, {SC_8, SC_4}, {SC_0, SC_5}, {SC_8, SC_5},
211                          {SC_0, SC_6}, {SC_8, SC_6}, {SC_0, SC_7}, {SC_8, SC_7} },
212 
213                        { {SC_0, SC_0}, {SC_9, SC_0}, {SC_2, SC_1}, {SC_B, SC_1},
214                          {SC_4, SC_2}, {SC_D, SC_2}, {SC_6, SC_3}, {SC_F, SC_3},
215                          {SC_8, SC_4}, {SC_1, SC_5}, {SC_A, SC_5}, {SC_3, SC_6},
216                          {SC_C, SC_6}, {SC_5, SC_7}, {SC_E, SC_7}, {SC_7, SC_8} },
217 
218                        { {SC_0, SC_0}, {SC_A, SC_0}, {SC_4, SC_1}, {SC_E, SC_1},
219                          {SC_8, SC_2}, {SC_2, SC_3}, {SC_C, SC_3}, {SC_6, SC_4},
220                          {SC_0, SC_5}, {SC_A, SC_5}, {SC_4, SC_6}, {SC_E, SC_6},
221                          {SC_8, SC_7}, {SC_2, SC_8}, {SC_C, SC_8}, {SC_6, SC_9} },
222 
223                        { {SC_0, SC_0}, {SC_B, SC_0}, {SC_6, SC_1}, {SC_1, SC_2},
224                          {SC_C, SC_2}, {SC_7, SC_3}, {SC_2, SC_4}, {SC_D, SC_4},
225                          {SC_8, SC_5}, {SC_3, SC_6}, {SC_E, SC_6}, {SC_9, SC_7},
226                          {SC_4, SC_8}, {SC_F, SC_8}, {SC_A, SC_9}, {SC_5, SC_A} },
227 
228                        { {SC_0, SC_0}, {SC_C, SC_0}, {SC_8, SC_1}, {SC_4, SC_2},
229                          {SC_0, SC_3}, {SC_C, SC_3}, {SC_8, SC_4}, {SC_4, SC_5},
230                          {SC_0, SC_6}, {SC_C, SC_6}, {SC_8, SC_7}, {SC_4, SC_8},
231                          {SC_0, SC_9}, {SC_C, SC_9}, {SC_8, SC_A}, {SC_4, SC_B} },
232 
233                        { {SC_0, SC_0}, {SC_D, SC_0}, {SC_A, SC_1}, {SC_7, SC_2},
234                          {SC_4, SC_3}, {SC_1, SC_4}, {SC_E, SC_4}, {SC_B, SC_5},
235                          {SC_8, SC_6}, {SC_5, SC_7}, {SC_2, SC_8}, {SC_F, SC_8},
236                          {SC_C, SC_9}, {SC_9, SC_A}, {SC_6, SC_B}, {SC_3, SC_C} },
237 
238                        { {SC_0, SC_0}, {SC_E, SC_0}, {SC_C, SC_1}, {SC_A, SC_2},
239                          {SC_8, SC_3}, {SC_6, SC_4}, {SC_4, SC_5}, {SC_2, SC_6},
240                          {SC_0, SC_7}, {SC_E, SC_7}, {SC_C, SC_8}, {SC_A, SC_9},
241                          {SC_8, SC_A}, {SC_6, SC_B}, {SC_4, SC_C}, {SC_2, SC_D} },
242 
243                        { {SC_0, SC_0}, {SC_F, SC_0}, {SC_E, SC_1}, {SC_D, SC_2},
244                          {SC_C, SC_3}, {SC_B, SC_4}, {SC_A, SC_5}, {SC_9, SC_6},
245                          {SC_8, SC_7}, {SC_7, SC_8}, {SC_6, SC_9}, {SC_5, SC_A},
246                          {SC_4, SC_B}, {SC_3, SC_C}, {SC_2, SC_D}, {SC_1, SC_E} }
247                              };
248 
249 static char const shrs_table[16][4][2] = {
250                        { {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0} },
251                        { {SC_1, SC_0}, {SC_0, SC_8}, {SC_0, SC_4}, {SC_0, SC_2} },
252                        { {SC_2, SC_0}, {SC_1, SC_0}, {SC_0, SC_8}, {SC_0, SC_4} },
253                        { {SC_3, SC_0}, {SC_1, SC_8}, {SC_0, SC_C}, {SC_0, SC_6} },
254                        { {SC_4, SC_0}, {SC_2, SC_0}, {SC_1, SC_0}, {SC_0, SC_8} },
255                        { {SC_5, SC_0}, {SC_2, SC_8}, {SC_1, SC_4}, {SC_0, SC_A} },
256                        { {SC_6, SC_0}, {SC_3, SC_0}, {SC_1, SC_8}, {SC_0, SC_C} },
257                        { {SC_7, SC_0}, {SC_3, SC_8}, {SC_1, SC_C}, {SC_0, SC_E} },
258                        { {SC_8, SC_0}, {SC_4, SC_0}, {SC_2, SC_0}, {SC_1, SC_0} },
259                        { {SC_9, SC_0}, {SC_4, SC_8}, {SC_2, SC_4}, {SC_1, SC_2} },
260                        { {SC_A, SC_0}, {SC_5, SC_0}, {SC_2, SC_8}, {SC_1, SC_4} },
261                        { {SC_B, SC_0}, {SC_5, SC_8}, {SC_2, SC_C}, {SC_1, SC_6} },
262                        { {SC_C, SC_0}, {SC_6, SC_0}, {SC_3, SC_0}, {SC_1, SC_8} },
263                        { {SC_D, SC_0}, {SC_6, SC_8}, {SC_3, SC_4}, {SC_1, SC_A} },
264                        { {SC_E, SC_0}, {SC_7, SC_0}, {SC_3, SC_8}, {SC_1, SC_C} },
265                        { {SC_F, SC_0}, {SC_7, SC_8}, {SC_3, SC_C}, {SC_1, SC_E} }
266                                    };
267 
268 /** converting a digit to a binary string */
269 static char const *const binary_table[] = {
270 	"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
271 	"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
272 };
273 
274 /*****************************************************************************
275  * private functions
276  *****************************************************************************/
277 
278 /**
279  * implements the bitwise NOT operation
280  */
do_bitnot(const char * val,char * buffer)281 static void do_bitnot(const char *val, char *buffer)
282 {
283 	int counter;
284 
285 	for (counter = 0; counter<calc_buffer_size; counter++)
286 		buffer[counter] = val[counter] ^ SC_F;
287 }
288 
289 /**
290  * implements the bitwise OR operation
291  */
do_bitor(const char * val1,const char * val2,char * buffer)292 static void do_bitor(const char *val1, const char *val2, char *buffer)
293 {
294 	int counter;
295 
296 	for (counter = 0; counter<calc_buffer_size; counter++)
297 		buffer[counter] = val1[counter] | val2[counter];
298 }
299 
300 /**
301  * implements the bitwise eXclusive OR operation
302  */
do_bitxor(const char * val1,const char * val2,char * buffer)303 static void do_bitxor(const char *val1, const char *val2, char *buffer)
304 {
305 	int counter;
306 
307 	for (counter = 0; counter<calc_buffer_size; counter++)
308 		buffer[counter] = val1[counter] ^ val2[counter];
309 }
310 
311 /**
312  * implements the bitwise AND operation
313  */
do_bitand(const char * val1,const char * val2,char * buffer)314 static void do_bitand(const char *val1, const char *val2, char *buffer)
315 {
316 	int counter;
317 
318 	for (counter = 0; counter<calc_buffer_size; counter++)
319 		buffer[counter] = val1[counter] & val2[counter];
320 }
321 
322 /**
323  * implements the bitwise AND not operation
324  */
do_bitandnot(const char * val1,const char * val2,char * buffer)325 static void do_bitandnot(const char *val1, const char *val2, char *buffer)
326 {
327 	int counter;
328 
329 	for (counter = 0; counter < calc_buffer_size; ++counter)
330 		buffer[counter] = val1[counter] & (SC_F ^ val2[counter]);
331 }
332 
333 /**
334  * returns the sign bit.
335  *
336  * @todo This implementation is wrong, as it returns the highest bit of the buffer
337  *       NOT the highest bit depending on the real mode
338  */
do_sign(const char * val)339 static int do_sign(const char *val)
340 {
341 	return (val[calc_buffer_size-1] <= SC_7) ? (1) : (-1);
342 }
343 
344 /**
345  * returns non-zero if bit at position pos is set
346  */
do_bit(const char * val,int pos)347 static int do_bit(const char *val, int pos)
348 {
349 	int bit    = pos & 3;
350 	int nibble = pos >> 2;
351 
352 	return _bitisset(val[nibble], bit);
353 }
354 
355 /**
356  * Implements a fast ADD + 1
357  */
do_inc(const char * val,char * buffer)358 static void do_inc(const char *val, char *buffer)
359 {
360 	int counter = 0;
361 
362 	while (counter++ < calc_buffer_size) {
363 		if (*val == SC_F) {
364 			*buffer++ = SC_0;
365 			val++;
366 		} else {
367 			/* No carry here, *val != SC_F */
368 			*buffer = add_table[_val(*val)][SC_1][0];
369 			return;
370 		}
371 	}
372 	/* here a carry could be lost, this is intended because this should
373 	 * happen only when a value changes sign. */
374 }
375 
376 /**
377  * Implements a unary MINUS
378  */
do_negate(const char * val,char * buffer)379 static void do_negate(const char *val, char *buffer)
380 {
381 	do_bitnot(val, buffer);
382 	do_inc(buffer, buffer);
383 }
384 
385 /**
386  * Implements a binary ADD
387  *
388  * @todo The implementation of carry is wrong, as it is the
389  *       calc_buffer_size carry, not the mode depending
390  */
do_add(const char * val1,const char * val2,char * buffer)391 static void do_add(const char *val1, const char *val2, char *buffer)
392 {
393 	int counter;
394 	const char *add1, *add2;
395 	char carry = SC_0;
396 
397 	for (counter = 0; counter < calc_buffer_size; counter++)   {
398 		add1 = add_table[_val(val1[counter])][_val(val2[counter])];
399 		add2 = add_table[_val(add1[0])][_val(carry)];
400 		/* carry might be zero */
401 		buffer[counter] = add2[0];
402 		carry = add_table[_val(add1[1])][_val(add2[1])][0];
403 	}
404 	carry_flag = carry != SC_0;
405 }
406 
407 /**
408  * Implements a binary SUB
409  */
do_sub(const char * val1,const char * val2,char * buffer)410 static void do_sub(const char *val1, const char *val2, char *buffer)
411 {
412 	char *temp_buffer = (char*) alloca(calc_buffer_size); /* intermediate buffer to hold -val2 */
413 
414 	do_negate(val2, temp_buffer);
415 	do_add(val1, temp_buffer, buffer);
416 }
417 
418 /**
419  * Implements a binary MUL
420  */
do_mul(const char * val1,const char * val2,char * buffer)421 static void do_mul(const char *val1, const char *val2, char *buffer)
422 {
423 	char *temp_buffer; /* result buffer */
424 	char *neg_val1;    /* abs of val1 */
425 	char *neg_val2;    /* abs of val2 */
426 
427 	const char *mul, *add1, *add2;      /* intermediate result containers */
428 	char carry = SC_0;                  /* container for carries */
429 	char sign = 0;                      /* marks result sign */
430 	int c_inner, c_outer;               /* loop counters */
431 
432 	temp_buffer = (char*) alloca(calc_buffer_size);
433 	neg_val1 = (char*) alloca(calc_buffer_size);
434 	neg_val2 = (char*) alloca(calc_buffer_size);
435 
436 	/* init result buffer to zeros */
437 	memset(temp_buffer, SC_0, calc_buffer_size);
438 
439 	/* the multiplication works only for positive values, for negative values *
440 	 * it is necessary to negate them and adjust the result accordingly       */
441 	if (do_sign(val1) == -1) {
442 		do_negate(val1, neg_val1);
443 		val1 = neg_val1;
444 		sign ^= 1;
445 	}
446 	if (do_sign(val2) == -1) {
447 		do_negate(val2, neg_val2);
448 		val2 = neg_val2;
449 		sign ^= 1;
450 	}
451 
452 	for (c_outer = 0; c_outer < max_value_size; c_outer++) {
453 		if (val2[c_outer] != SC_0) {
454 			for (c_inner = 0; c_inner < max_value_size; c_inner++) {
455 				/* do the following calculation:                                    *
456 				 * Add the current carry, the value at position c_outer+c_inner     *
457 				 * and the result of the multiplication of val1[c_inner] and        *
458 				 * val2[c_outer]. This is the usual pen-and-paper multiplication.   */
459 
460 				/* multiplicate the two digits */
461 				mul = mul_table[_val(val1[c_inner])][_val(val2[c_outer])];
462 				/* add old value to result of multiplication */
463 				add1 = add_table[_val(temp_buffer[c_inner + c_outer])][_val(mul[0])];
464 				/* add carry to the sum */
465 				add2 = add_table[_val(add1[0])][_val(carry)];
466 
467 				/* all carries together result in new carry. This is always smaller *
468 				 * than the base b:                                                 *
469 				 * Both multiplicands, the carry and the value already in the temp  *
470 				 * buffer are single digits and their value is therefore at most    *
471 				 * equal to (b-1).                                                  *
472 				 * This leads to:                                                   *
473 				 * (b-1)(b-1)+(b-1)+(b-1) = b*b-1                                   *
474 				 * The tables list all operations rem b, so the carry is at most    *
475 				 * (b*b-1)rem b = -1rem b = b-1                                     */
476 				carry = add_table[_val(mul[1])][_val(add1[1])][0];
477 				carry = add_table[_val(carry)][_val(add2[1])][0];
478 
479 				temp_buffer[c_inner + c_outer] = add2[0];
480 			}
481 
482 			/* A carry may hang over */
483 			/* c_outer is always smaller than max_value_size! */
484 			temp_buffer[max_value_size + c_outer] = carry;
485 			carry = SC_0;
486 		}
487 	}
488 
489 	if (sign)
490 		do_negate(temp_buffer, buffer);
491 	else
492 		memcpy(buffer, temp_buffer, calc_buffer_size);
493 }
494 
495 /**
496  * Shift the buffer to left and add a 4 bit digit
497  */
do_push(const char digit,char * buffer)498 static void do_push(const char digit, char *buffer)
499 {
500 	int counter;
501 
502 	for (counter = calc_buffer_size - 2; counter >= 0; counter--) {
503 		buffer[counter+1] = buffer[counter];
504 	}
505 	buffer[0] = digit;
506 }
507 
508 /**
509  * Implements truncating integer division and remainder.
510  *
511  * Note: This is MOST slow
512  */
do_divmod(const char * rDividend,const char * divisor,char * quot,char * rem)513 static void do_divmod(const char *rDividend, const char *divisor, char *quot, char *rem)
514 {
515 	const char *dividend = rDividend;
516 	const char *minus_divisor;
517 	char *neg_val1;
518 	char *neg_val2;
519 
520 	char div_sign = 0;     /* remember division result sign */
521 	char rem_sign = 0;     /* remember remainder result sign */
522 
523 	int c_dividend;      /* loop counters */
524 
525 	neg_val1 = (char*) alloca(calc_buffer_size);
526 	neg_val2 = (char*) alloca(calc_buffer_size);
527 
528 	/* clear result buffer */
529 	memset(quot, SC_0, calc_buffer_size);
530 	memset(rem, SC_0, calc_buffer_size);
531 
532 	/* if the divisor is zero this won't work (quot is zero) */
533 	if (sc_comp(divisor, quot) == 0) assert(0 && "division by zero!");
534 
535 	/* if the dividend is zero result is zero (quot is zero) */
536 	if (sc_comp(dividend, quot) == 0)
537 		return;
538 
539 	if (do_sign(dividend) == -1) {
540 		do_negate(dividend, neg_val1);
541 		div_sign ^= 1;
542 		rem_sign ^= 1;
543 		dividend = neg_val1;
544 	}
545 
546 	do_negate(divisor, neg_val2);
547 	if (do_sign(divisor) == -1) {
548 		div_sign ^= 1;
549 		minus_divisor = divisor;
550 		divisor = neg_val2;
551 	} else
552 		minus_divisor = neg_val2;
553 
554 	/* if divisor >= dividend division is easy
555 	 * (remember these are absolute values) */
556 	switch (sc_comp(dividend, divisor)) {
557 	case 0: /* dividend == divisor */
558 		quot[0] = SC_1;
559 		goto end;
560 
561 	case -1: /* dividend < divisor */
562 		memcpy(rem, dividend, calc_buffer_size);
563 		goto end;
564 
565 	default: /* unluckily division is necessary :( */
566 		break;
567 	}
568 
569 	for (c_dividend = calc_buffer_size - 1; c_dividend >= 0; c_dividend--) {
570 		do_push(dividend[c_dividend], rem);
571 		do_push(SC_0, quot);
572 
573 		if (sc_comp(rem, divisor) != -1) {  /* remainder >= divisor */
574 			/* subtract until the remainder becomes negative, this should
575 			 * be faster than comparing remainder with divisor  */
576 			do_add(rem, minus_divisor, rem);
577 
578 			while (do_sign(rem) == 1) {
579 				quot[0] = add_table[_val(quot[0])][SC_1][0];
580 				do_add(rem, minus_divisor, rem);
581 			}
582 
583 			/* subtracted one too much */
584 			do_add(rem, divisor, rem);
585 		}
586 	}
587 end:
588 	/* sets carry if remainder is non-zero ??? */
589 	carry_flag = !sc_is_zero(rem);
590 
591 	if (div_sign)
592 		do_negate(quot, quot);
593 
594 	if (rem_sign)
595 		do_negate(rem, rem);
596 }
597 
598 /**
599  * Implements a Shift Left, which can either preserve the sign bit
600  * or not.
601  *
602  * @todo Assertions seems to be wrong
603  */
do_shl(const char * val1,char * buffer,long shift_cnt,int bitsize,unsigned is_signed)604 static void do_shl(const char *val1, char *buffer, long shift_cnt, int bitsize, unsigned is_signed)
605 {
606 	const char *shl;
607 	char shift;
608 	char carry = SC_0;
609 
610 	int counter;
611 	int bitoffset = 0;
612 
613 	assert((shift_cnt >= 0) || (0 && "negative leftshift"));
614 	assert(((do_sign(val1) != -1) || is_signed) || (0 && "unsigned mode and negative value"));
615 	assert(((!_bitisset(val1[(bitsize-1)/4], (bitsize-1)%4)) || !is_signed || (do_sign(val1) == -1)) || (0 && "value is positive, should be negative"));
616 	assert(((_bitisset(val1[(bitsize-1)/4], (bitsize-1)%4)) || !is_signed || (do_sign(val1) == 1)) || (0 && "value is negative, should be positive"));
617 
618 	/* if shifting far enough the result is zero */
619 	if (shift_cnt >= bitsize) {
620 		memset(buffer, SC_0, calc_buffer_size);
621 		return;
622 	}
623 
624 	shift     = SHIFT(shift_cnt % 4); /* this is 2 ** (offset % 4) */
625 	shift_cnt = shift_cnt / 4;
626 
627 	/* shift the single digits some bytes (offset) and some bits (table)
628 	 * to the left */
629 	for (counter = 0; counter < bitsize/4 - shift_cnt; counter++) {
630 		shl = mul_table[_val(val1[counter])][_val(shift)];
631 		buffer[counter + shift_cnt] = shl[0] | carry;
632 		carry = shl[1];
633 	}
634 	if (bitsize%4 > 0) {
635 		shl = mul_table[_val(val1[counter])][_val(shift)];
636 		buffer[counter + shift_cnt] = shl[0] | carry;
637 		bitoffset = counter;
638 	} else {
639 		bitoffset = counter - 1;
640 	}
641 
642 	/* fill with zeroes */
643 	for (counter = 0; counter < shift_cnt; counter++)
644 		buffer[counter] = SC_0;
645 
646 	/* if the mode was signed, change sign when the mode's msb is now 1 */
647 	shift_cnt = bitoffset + shift_cnt;
648 	bitoffset = (bitsize-1) % 4;
649 	if (is_signed && _bitisset(buffer[shift_cnt], bitoffset)) {
650 		/* this sets the upper bits of the leftmost digit */
651 		buffer[shift_cnt] |= min_digit[bitoffset];
652 		for (counter = shift_cnt+1; counter < calc_buffer_size; counter++) {
653 			buffer[counter] = SC_F;
654 		}
655 	} else if (is_signed && !_bitisset(buffer[shift_cnt], bitoffset)) {
656 		/* this clears the upper bits of the leftmost digit */
657 		buffer[shift_cnt] &= max_digit[bitoffset];
658 		for (counter = shift_cnt+1; counter < calc_buffer_size; counter++) {
659 			buffer[counter] = SC_0;
660 		}
661 	}
662 }
663 
664 /**
665  * Implements a Shift Right, which can either preserve the sign bit
666  * or not.
667  *
668  * @param bitsize   bitsize of the value to be shifted
669  *
670  * @todo Assertions seems to be wrong
671  */
do_shr(const char * val1,char * buffer,long shift_cnt,int bitsize,unsigned is_signed,int signed_shift)672 static void do_shr(const char *val1, char *buffer, long shift_cnt, int bitsize, unsigned is_signed, int signed_shift)
673 {
674 	const char *shrs;
675 	char sign;
676 	char msd;
677 
678 	int shift_mod, shift_nib;
679 
680 	int counter;
681 	int bitoffset = 0;
682 
683 	assert((shift_cnt >= 0) || (0 && "negative rightshift"));
684 	assert(((!_bitisset(val1[(bitsize-1)/4], (bitsize-1)%4)) || !is_signed || (do_sign(val1) == -1)) || (0 && "value is positive, should be negative"));
685 	assert(((_bitisset(val1[(bitsize-1)/4], (bitsize-1)%4)) || !is_signed || (do_sign(val1) == 1)) || (0 && "value is negative, should be positive"));
686 
687 	sign = signed_shift && do_bit(val1, bitsize - 1) ? SC_F : SC_0;
688 
689 	/* if shifting far enough the result is either 0 or -1 */
690 	if (shift_cnt >= bitsize) {
691 		if (!sc_is_zero(val1)) {
692 			carry_flag = 1;
693 		}
694 		memset(buffer, sign, calc_buffer_size);
695 		return;
696 	}
697 
698 	shift_mod = shift_cnt &  3;
699 	shift_nib = shift_cnt >> 2;
700 
701 	/* check if any bits are lost, and set carry_flag if so */
702 	for (counter = 0; counter < shift_nib; ++counter) {
703 		if (val1[counter] != 0) {
704 			carry_flag = 1;
705 			break;
706 		}
707 	}
708 	if ((_val(val1[counter]) & ((1<<shift_mod)-1)) != 0)
709 		carry_flag = 1;
710 
711 	/* shift digits to the right with offset, carry and all */
712 	buffer[0] = shrs_table[_val(val1[shift_nib])][shift_mod][0];
713 	for (counter = 1; counter < ((bitsize + 3) >> 2) - shift_nib; counter++) {
714 		shrs = shrs_table[_val(val1[counter + shift_nib])][shift_mod];
715 		buffer[counter]      = shrs[0];
716 		buffer[counter - 1] |= shrs[1];
717 	}
718 
719 	/* the last digit is special in regard of signed/unsigned shift */
720 	bitoffset = bitsize & 3;
721 	msd = sign;  /* most significant digit */
722 
723 	/* remove sign bits if mode was signed and this is an unsigned shift */
724 	if (!signed_shift && is_signed) {
725 		msd &= max_digit[bitoffset];
726 	}
727 
728 	shrs = shrs_table[_val(msd)][shift_mod];
729 
730 	/* signed shift and signed mode and negative value means all bits to the left are set */
731 	if (signed_shift && sign == SC_F) {
732 		buffer[counter] = shrs[0] | min_digit[bitoffset];
733 	} else {
734 		buffer[counter] = shrs[0];
735 	}
736 
737 	if (counter > 0)
738 		buffer[counter - 1] |= shrs[1];
739 
740 	/* fill with SC_F or SC_0 depending on sign */
741 	for (counter++; counter < calc_buffer_size; counter++) {
742 		buffer[counter] = sign;
743 	}
744 }
745 
746 /**
747  * Implements a Rotate Left.
748  * positive: low-order -> high order, negative other direction
749  */
do_rotl(const char * val1,char * buffer,long offset,int radius,unsigned is_signed)750 static void do_rotl(const char *val1, char *buffer, long offset, int radius, unsigned is_signed)
751 {
752 	char *temp1, *temp2;
753 	temp1 = (char*) alloca(calc_buffer_size);
754 	temp2 = (char*) alloca(calc_buffer_size);
755 
756 	offset = offset % radius;
757 
758 	/* rotation by multiples of the type length is identity */
759 	if (offset == 0) {
760 		memmove(buffer, val1, calc_buffer_size);
761 		return;
762 	}
763 
764 	do_shl(val1, temp1, offset, radius, is_signed);
765 	do_shr(val1, temp2, radius - offset, radius, is_signed, 0);
766 	do_bitor(temp1, temp2, buffer);
767 	carry_flag = 0; /* set by shr, but due to rot this is false */
768 }
769 
770 /*****************************************************************************
771  * public functions, declared in strcalc.h
772  *****************************************************************************/
sc_get_buffer(void)773 const void *sc_get_buffer(void)
774 {
775 	return (void*)calc_buffer;
776 }
777 
sc_get_buffer_length(void)778 int sc_get_buffer_length(void)
779 {
780 	return calc_buffer_size;
781 }
782 
783 /**
784  * Do sign extension if the mode is signed, otherwise to zero extension.
785  */
sign_extend(void * buffer,ir_mode * mode)786 void sign_extend(void *buffer, ir_mode *mode)
787 {
788 	char *calc_buffer = (char*) buffer;
789 	int bits          = get_mode_size_bits(mode) - 1;
790 	int nibble        = bits >> 2;
791 	int max           = max_digit[bits & 3];
792 	int i;
793 
794 	if (mode_is_signed(mode)) {
795 		if (calc_buffer[nibble] > max) {
796 			/* sign bit is set, we need sign expansion */
797 
798 			for (i = nibble + 1; i < calc_buffer_size; ++i)
799 				calc_buffer[i] = SC_F;
800 			calc_buffer[nibble] |= sex_digit[bits & 3];
801 		} else {
802 			/* set all bits to zero */
803 			for (i = nibble + 1; i < calc_buffer_size; ++i)
804 				calc_buffer[i] = SC_0;
805 			calc_buffer[nibble] &= zex_digit[bits & 3];
806 		}
807 	} else {
808 		/* do zero extension */
809 		for (i = nibble + 1; i < calc_buffer_size; ++i)
810 			calc_buffer[i] = SC_0;
811 		calc_buffer[nibble] &= zex_digit[bits & 3];
812 	}
813 }
814 
815 /* we assume that '0'-'9', 'a'-'z' and 'A'-'Z' are a range.
816  * The C-standard does theoretically allow otherwise. */
check_ascii(void)817 static inline void check_ascii(void)
818 {
819 	/* C standard guarantees that '0'-'9' is a range */
820 	assert('b'-'a' == 1
821 		&& 'c'-'a' == 2
822 		&& 'd'-'a' == 3
823 		&& 'e'-'a' == 4
824 		&& 'f'-'a' == 5);
825 	assert('B'-'A' == 1
826 		&& 'C'-'A' == 2
827 		&& 'D'-'A' == 3
828 		&& 'E'-'A' == 4
829 		&& 'F'-'A' == 5);
830 }
831 
sc_val_from_str(char sign,unsigned base,const char * str,size_t len,void * buffer)832 int sc_val_from_str(char sign, unsigned base, const char *str,
833                     size_t len, void *buffer)
834 {
835 	char *sc_base, *val;
836 
837 	assert(sign == -1 || sign == 1);
838 	assert(str != NULL);
839 	assert(len > 0);
840 	check_ascii();
841 
842 	assert(base > 1 && base <= 16);
843 	sc_base = (char*) alloca(calc_buffer_size);
844 	sc_val_from_ulong(base, sc_base);
845 
846 	val = (char*) alloca(calc_buffer_size);
847 	if (buffer == NULL)
848 		buffer = calc_buffer;
849 
850 	CLEAR_BUFFER(buffer);
851 	CLEAR_BUFFER(val);
852 
853 	/* BEGIN string evaluation, from left to right */
854 	while (len > 0) {
855 		char c = *str;
856 		unsigned v;
857 		if (c >= '0' && c <= '9')
858 			v = c - '0';
859 		else if (c >= 'A' && c <= 'F')
860 			v = c - 'A' + 10;
861 		else if (c >= 'a' && c <= 'f')
862 			v = c - 'a' + 10;
863 		else
864 			return 0;
865 
866 		if (v >= base)
867 			return 0;
868 		val[0] = v;
869 
870 		/* Radix conversion from base b to base B:
871 		 *  (UnUn-1...U1U0)b == ((((Un*b + Un-1)*b + ...)*b + U1)*b + U0)B */
872 		/* multiply current value with base */
873 		do_mul(sc_base, (const char*) buffer, (char*) buffer);
874 		/* add next digit to current value  */
875 		do_add(val, (const char*) buffer, (char*) buffer);
876 
877 		/* get ready for the next letter */
878 		str++;
879 		len--;
880 	}
881 
882 	if (sign < 0)
883 		do_negate((const char*) buffer, (char*) buffer);
884 
885 	return 1;
886 }
887 
sc_val_from_long(long value,void * buffer)888 void sc_val_from_long(long value, void *buffer)
889 {
890 	char *pos;
891 	char sign, is_minlong;
892 
893 	if (buffer == NULL) buffer = calc_buffer;
894 	pos = (char*) buffer;
895 
896 	sign = (value < 0);
897 	is_minlong = value == LONG_MIN;
898 
899 	/* use absolute value, special treatment of MIN_LONG to avoid overflow */
900 	if (sign) {
901 		if (is_minlong)
902 			value = -(value+1);
903 		else
904 			value = -value;
905 	}
906 
907 	CLEAR_BUFFER(buffer);
908 
909 	while ((value != 0) && (pos < (char*)buffer + calc_buffer_size)) {
910 		*pos++ = _digit(value & 0xf);
911 		value >>= 4;
912 	}
913 
914 	if (sign) {
915 		if (is_minlong)
916 			do_inc((const char*) buffer, (char*) buffer);
917 
918 		do_negate((const char*) buffer, (char*) buffer);
919 	}
920 }
921 
sc_val_from_ulong(unsigned long value,void * buffer)922 void sc_val_from_ulong(unsigned long value, void *buffer)
923 {
924 	unsigned char *pos;
925 
926 	if (buffer == NULL) buffer = calc_buffer;
927 	pos = (unsigned char*) buffer;
928 
929 	while (pos < (unsigned char *)buffer + calc_buffer_size) {
930 		*pos++ = (unsigned char)_digit(value & 0xf);
931 		value >>= 4;
932 	}
933 }
934 
sc_val_to_long(const void * val)935 long sc_val_to_long(const void *val)
936 {
937 	int i;
938 	long l = 0;
939 
940 	for (i = calc_buffer_size - 1; i >= 0; i--) {
941 		l = (l << 4) + _val(((char *)val)[i]);
942 	}
943 	return l;
944 }
945 
sc_min_from_bits(unsigned int num_bits,unsigned int sign,void * buffer)946 void sc_min_from_bits(unsigned int num_bits, unsigned int sign, void *buffer)
947 {
948 	char *pos;
949 	int i, bits;
950 
951 	if (buffer == NULL) buffer = calc_buffer;
952 	CLEAR_BUFFER(buffer);
953 
954 	if (!sign) return;  /* unsigned means minimum is 0(zero) */
955 
956 	pos = (char*) buffer;
957 
958 	bits = num_bits - 1;
959 	for (i = 0; i < bits/4; i++)
960 		*pos++ = SC_0;
961 
962 	*pos++ = min_digit[bits%4];
963 
964 	for (i++; i <= calc_buffer_size - 1; i++)
965 		*pos++ = SC_F;
966 }
967 
sc_max_from_bits(unsigned int num_bits,unsigned int sign,void * buffer)968 void sc_max_from_bits(unsigned int num_bits, unsigned int sign, void *buffer)
969 {
970 	char* pos;
971 	int i, bits;
972 
973 	if (buffer == NULL) buffer = calc_buffer;
974 	CLEAR_BUFFER(buffer);
975 	pos = (char*) buffer;
976 
977 	bits = num_bits - sign;
978 	for (i = 0; i < bits/4; i++)
979 		*pos++ = SC_F;
980 
981 	*pos++ = max_digit[bits%4];
982 
983 	for (i++; i <= calc_buffer_size - 1; i++)
984 		*pos++ = SC_0;
985 }
986 
sc_truncate(unsigned int num_bits,void * buffer)987 void sc_truncate(unsigned int num_bits, void *buffer)
988 {
989 	char *cbuffer = (char*) buffer;
990 	char *pos = cbuffer + (num_bits / 4);
991 	char *end = cbuffer + calc_buffer_size;
992 
993 	assert(pos < end);
994 
995 	switch (num_bits % 4) {
996 	case 0: /* nothing to do */ break;
997 	case 1: *pos++ &= SC_1; break;
998 	case 2: *pos++ &= SC_3; break;
999 	case 3: *pos++ &= SC_7; break;
1000 	}
1001 
1002 	for ( ; pos < end; ++pos)
1003 		*pos = SC_0;
1004 }
1005 
sc_comp(const void * value1,const void * value2)1006 int sc_comp(const void* value1, const void* value2)
1007 {
1008 	int counter = calc_buffer_size - 1;
1009 	const char *val1 = (const char *)value1;
1010 	const char *val2 = (const char *)value2;
1011 
1012 	/* compare signs first:
1013 	 * the loop below can only compare values of the same sign! */
1014 	if (do_sign(val1) != do_sign(val2))
1015 		return (do_sign(val1) == 1)?(1):(-1);
1016 
1017 	/* loop until two digits differ, the values are equal if there
1018 	 * are no such two digits */
1019 	while (val1[counter] == val2[counter]) {
1020 		counter--;
1021 		if (counter < 0) return 0;
1022 	}
1023 
1024 	/* the leftmost digit is the most significant, so this returns
1025 	 * the correct result.
1026 	 * This implies the digit enum is ordered */
1027 	return (val1[counter] > val2[counter]) ? (1) : (-1);
1028 }
1029 
sc_get_highest_set_bit(const void * value)1030 int sc_get_highest_set_bit(const void *value)
1031 {
1032 	const char *val = (const char*)value;
1033 	int high, counter;
1034 
1035 	high = calc_buffer_size * 4 - 1;
1036 
1037 	for (counter = calc_buffer_size-1; counter >= 0; counter--) {
1038 		if (val[counter] == SC_0)
1039 			high -= 4;
1040 		else {
1041 			if (val[counter] > SC_7) return high;
1042 			else if (val[counter] > SC_3) return high - 1;
1043 			else if (val[counter] > SC_1) return high - 2;
1044 			else return high - 3;
1045 		}
1046 	}
1047 	return high;
1048 }
1049 
sc_get_lowest_set_bit(const void * value)1050 int sc_get_lowest_set_bit(const void *value)
1051 {
1052 	const char *val = (const char*)value;
1053 	int low, counter;
1054 
1055 	low = 0;
1056 	for (counter = 0; counter < calc_buffer_size; counter++) {
1057 		switch (val[counter]) {
1058 		case SC_1:
1059 		case SC_3:
1060 		case SC_5:
1061 		case SC_7:
1062 		case SC_9:
1063 		case SC_B:
1064 		case SC_D:
1065 		case SC_F:
1066 			return low;
1067 		case SC_2:
1068 		case SC_6:
1069 		case SC_A:
1070 		case SC_E:
1071 			return low + 1;
1072 		case SC_4:
1073 		case SC_C:
1074 			return low + 2;
1075 		case SC_8:
1076 			return low + 3;
1077 		default:
1078 			low += 4;
1079 		}
1080 	}
1081 	return -1;
1082 }
1083 
sc_get_bit_at(const void * value,unsigned pos)1084 int sc_get_bit_at(const void *value, unsigned pos)
1085 {
1086 	const char *val = (const char*) value;
1087 	unsigned nibble = pos >> 2;
1088 
1089 	return (val[nibble] & SHIFT(pos & 3)) != SC_0;
1090 }
1091 
sc_set_bit_at(void * value,unsigned pos)1092 void sc_set_bit_at(void *value, unsigned pos)
1093 {
1094 	char *val = (char*) value;
1095 	unsigned nibble = pos >> 2;
1096 
1097 	val[nibble] |= SHIFT(pos & 3);
1098 }
1099 
sc_is_zero(const void * value)1100 int sc_is_zero(const void *value)
1101 {
1102 	const char* val = (const char *)value;
1103 	int counter;
1104 
1105 	for (counter = 0; counter < calc_buffer_size; ++counter) {
1106 		if (val[counter] != SC_0)
1107 			return 0;
1108 	}
1109 	return 1;
1110 }
1111 
sc_is_negative(const void * value)1112 int sc_is_negative(const void *value)
1113 {
1114 	return do_sign((const char*) value) == -1;
1115 }
1116 
sc_had_carry(void)1117 int sc_had_carry(void)
1118 {
1119 	return carry_flag;
1120 }
1121 
sc_sub_bits(const void * value,int len,unsigned byte_ofs)1122 unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs)
1123 {
1124 	const char *val = (const char *)value;
1125 	int nibble_ofs  = 2 * byte_ofs;
1126 	unsigned char res;
1127 
1128 	/* the current scheme uses one byte to store a nibble */
1129 	if (4 * nibble_ofs >= len)
1130 		return 0;
1131 
1132 	res = _val(val[nibble_ofs]);
1133 	if (len > 4 * (nibble_ofs + 1))
1134 		res |= _val(val[nibble_ofs + 1]) << 4;
1135 
1136 	/* kick bits outsize */
1137 	if (len - 8 * byte_ofs < 8) {
1138 		res &= (1 << (len - 8 * byte_ofs)) - 1;
1139 	}
1140 	return res;
1141 }
1142 
1143 /*
1144  * convert to a string
1145  * FIXME: Doesn't check buffer bounds
1146  */
sc_print(const void * value,unsigned bits,enum base_t base,int signed_mode)1147 const char *sc_print(const void *value, unsigned bits, enum base_t base, int signed_mode)
1148 {
1149 	static const char big_digits[]   = "0123456789ABCDEF";
1150 	static const char small_digits[] = "0123456789abcdef";
1151 
1152 	char *base_val, *div1_res, *div2_res, *rem_res;
1153 	int counter, nibbles, i, sign, mask;
1154 	char x;
1155 
1156 	const char *val = (const char *)value;
1157 	const char *p;
1158 	char *m, *n, *t;
1159 	char *pos;
1160 	const char *digits = small_digits;
1161 
1162 	base_val = (char*) alloca(calc_buffer_size);
1163 	div1_res = (char*) alloca(calc_buffer_size);
1164 	div2_res = (char*) alloca(calc_buffer_size);
1165 	rem_res  = (char*) alloca(calc_buffer_size);
1166 
1167 	pos = output_buffer + bit_pattern_size;
1168 	*(--pos) = '\0';
1169 
1170 	/* special case */
1171 	if (bits == 0) {
1172 		bits = bit_pattern_size;
1173 #ifdef STRCALC_DEBUG_FULLPRINT
1174 		bits <<= 1;
1175 #endif
1176 	}
1177 	nibbles = bits >> 2;
1178 	switch (base) {
1179 
1180 	case SC_HEX:
1181 		digits = big_digits;
1182 	case SC_hex:
1183 		for (counter = 0; counter < nibbles; ++counter) {
1184 			*(--pos) = digits[_val(val[counter])];
1185 #ifdef STRCALC_DEBUG_GROUPPRINT
1186 			if ((counter+1)%8 == 0)
1187 				*(--pos) = ' ';
1188 #endif
1189 		}
1190 
1191 		/* last nibble must be masked */
1192 		if (bits & 3) {
1193 			mask = zex_digit[(bits & 3) - 1];
1194 			x    = val[counter++] & mask;
1195 			*(--pos) = digits[_val(x)];
1196 		}
1197 
1198 		/* now kill zeros */
1199 		for (; counter > 1; --counter, ++pos) {
1200 #ifdef STRCALC_DEBUG_GROUPPRINT
1201 			if (pos[0] == ' ') ++pos;
1202 #endif
1203 			if (pos[0] != '0')
1204 				break;
1205 		}
1206 		break;
1207 
1208 	case SC_BIN:
1209 		for (counter = 0; counter < nibbles; ++counter) {
1210 			pos -= 4;
1211 			p = binary_table[_val(val[counter])];
1212 			pos[0] = p[0];
1213 			pos[1] = p[1];
1214 			pos[2] = p[2];
1215 			pos[3] = p[3];
1216 		}
1217 
1218 		/* last nibble must be masked */
1219 		if (bits & 3) {
1220 			mask = zex_digit[(bits & 3) - 1];
1221 			x    = val[counter++] & mask;
1222 
1223 			pos -= 4;
1224 			p = binary_table[_val(x)];
1225 			pos[0] = p[0];
1226 			pos[1] = p[1];
1227 			pos[2] = p[2];
1228 			pos[3] = p[3];
1229 		}
1230 
1231 		/* now kill zeros */
1232 		for (counter <<= 2; counter > 1; --counter, ++pos)
1233 			if (pos[0] != '0')
1234 				break;
1235 			break;
1236 
1237 	case SC_DEC:
1238 	case SC_OCT:
1239 		memset(base_val, SC_0, calc_buffer_size);
1240 		base_val[0] = base == SC_DEC ? SC_A : SC_8;
1241 
1242 		p    = val;
1243 		sign = 0;
1244 		if (signed_mode && base == SC_DEC) {
1245 			/* check for negative values */
1246 			if (do_bit(val, bits - 1)) {
1247 				do_negate(val, div2_res);
1248 				sign = 1;
1249 				p = div2_res;
1250 			}
1251 		}
1252 
1253 		/* transfer data into oscillating buffers */
1254 		memset(div1_res, SC_0, calc_buffer_size);
1255 		for (counter = 0; counter < nibbles; ++counter)
1256 			div1_res[counter] = p[counter];
1257 
1258 		/* last nibble must be masked */
1259 		if (bits & 3) {
1260 			mask = zex_digit[(bits & 3) - 1];
1261 			div1_res[counter] = p[counter] & mask;
1262 			++counter;
1263 		}
1264 
1265 		m = div1_res;
1266 		n = div2_res;
1267 		for (;;) {
1268 			do_divmod(m, base_val, n, rem_res);
1269 			t = m;
1270 			m = n;
1271 			n = t;
1272 			*(--pos) = digits[_val(rem_res[0])];
1273 
1274 			x = 0;
1275 			for (i = 0; i < calc_buffer_size; ++i)
1276 				x |= _val(m[i]);
1277 
1278 			if (x == 0)
1279 				break;
1280 		}
1281 		if (sign)
1282 			*(--pos) = '-';
1283 		break;
1284 
1285 	default:
1286 		panic("Unsupported base %d", base);
1287 	}
1288 	return pos;
1289 }
1290 
init_strcalc(int precision)1291 void init_strcalc(int precision)
1292 {
1293 	if (calc_buffer == NULL) {
1294 		if (precision <= 0) precision = SC_DEFAULT_PRECISION;
1295 
1296 		/* round up to multiple of 4 */
1297 		precision = (precision + 3) & ~3;
1298 
1299 		bit_pattern_size = (precision);
1300 		calc_buffer_size = (precision / 2);
1301 		max_value_size   = (precision / 4);
1302 
1303 		calc_buffer   = XMALLOCN(char, calc_buffer_size + 1);
1304 		output_buffer = XMALLOCN(char, bit_pattern_size + 1);
1305 
1306 		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));
1307 	}
1308 }
1309 
1310 
finish_strcalc(void)1311 void finish_strcalc(void)
1312 {
1313 	free(calc_buffer);   calc_buffer   = NULL;
1314 	free(output_buffer); output_buffer = NULL;
1315 }
1316 
sc_get_precision(void)1317 int sc_get_precision(void)
1318 {
1319 	return bit_pattern_size;
1320 }
1321 
1322 
sc_add(const void * value1,const void * value2,void * buffer)1323 void sc_add(const void *value1, const void *value2, void *buffer)
1324 {
1325 	CLEAR_BUFFER(calc_buffer);
1326 	carry_flag = 0;
1327 
1328 	DEBUGPRINTF_COMPUTATION(("%s + ", sc_print_hex(value1)));
1329 	DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
1330 
1331 	do_add((const char*) value1, (const char*) value2, (char*) calc_buffer);
1332 
1333 	DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
1334 
1335 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1336 		memcpy(buffer, calc_buffer, calc_buffer_size);
1337 	}
1338 }
1339 
sc_sub(const void * value1,const void * value2,void * buffer)1340 void sc_sub(const void *value1, const void *value2, void *buffer)
1341 {
1342 	CLEAR_BUFFER(calc_buffer);
1343 	carry_flag = 0;
1344 
1345 	DEBUGPRINTF_COMPUTATION(("%s - ", sc_print_hex(value1)));
1346 	DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
1347 
1348 	do_sub((const char*) value1, (const char*) value2, calc_buffer);
1349 
1350 	DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
1351 
1352 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1353 		memcpy(buffer, calc_buffer, calc_buffer_size);
1354 	}
1355 }
1356 
sc_neg(const void * value1,void * buffer)1357 void sc_neg(const void *value1, void *buffer)
1358 {
1359 	carry_flag = 0;
1360 
1361 	DEBUGPRINTF_COMPUTATION(("- %s ->", sc_print_hex(value1)));
1362 
1363 	do_negate((const char*) value1, calc_buffer);
1364 
1365 	DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
1366 
1367 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1368 		memcpy(buffer, calc_buffer, calc_buffer_size);
1369 	}
1370 }
1371 
sc_and(const void * value1,const void * value2,void * buffer)1372 void sc_and(const void *value1, const void *value2, void *buffer)
1373 {
1374 	CLEAR_BUFFER(calc_buffer);
1375 	carry_flag = 0;
1376 
1377 	DEBUGPRINTF_COMPUTATION(("%s & ", sc_print_hex(value1)));
1378 	DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
1379 
1380 	do_bitand((const char*) value1, (const char*) value2, calc_buffer);
1381 
1382 	DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
1383 
1384 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1385 		memcpy(buffer, calc_buffer, calc_buffer_size);
1386 	}
1387 }
1388 
sc_andnot(const void * value1,const void * value2,void * buffer)1389 void sc_andnot(const void *value1, const void *value2, void *buffer)
1390 {
1391 	CLEAR_BUFFER(calc_buffer);
1392 	carry_flag = 0;
1393 
1394 	DEBUGPRINTF_COMPUTATION(("%s & ", sc_print_hex(value1)));
1395 	DEBUGPRINTF_COMPUTATION(("~%s -> ", sc_print_hex(value2)));
1396 
1397 	do_bitandnot((const char*) value1, (const char*) value2, calc_buffer);
1398 
1399 	DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
1400 
1401 	if (buffer != NULL && buffer != calc_buffer) {
1402 		memcpy(buffer, calc_buffer, calc_buffer_size);
1403 	}
1404 }
1405 
sc_or(const void * value1,const void * value2,void * buffer)1406 void sc_or(const void *value1, const void *value2, void *buffer)
1407 {
1408 	CLEAR_BUFFER(calc_buffer);
1409 	carry_flag = 0;
1410 
1411 	DEBUGPRINTF_COMPUTATION(("%s | ", sc_print_hex(value1)));
1412 	DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
1413 
1414 	do_bitor((const char*) value1, (const char*) value2, calc_buffer);
1415 
1416 	DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
1417 
1418 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1419 		memcpy(buffer, calc_buffer, calc_buffer_size);
1420 	}
1421 }
1422 
sc_xor(const void * value1,const void * value2,void * buffer)1423 void sc_xor(const void *value1, const void *value2, void *buffer)
1424 {
1425 	CLEAR_BUFFER(calc_buffer);
1426 	carry_flag = 0;
1427 
1428 	DEBUGPRINTF_COMPUTATION(("%s ^ ", sc_print_hex(value1)));
1429 	DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
1430 
1431 	do_bitxor((const char*) value1, (const char*) value2, calc_buffer);
1432 
1433 	DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
1434 
1435 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1436 		memcpy(buffer, calc_buffer, calc_buffer_size);
1437 	}
1438 }
1439 
sc_not(const void * value1,void * buffer)1440 void sc_not(const void *value1, void *buffer)
1441 {
1442 	CLEAR_BUFFER(calc_buffer);
1443 	carry_flag = 0;
1444 
1445 	DEBUGPRINTF_COMPUTATION(("~ %s ->", sc_print_hex(value1)));
1446 
1447 	do_bitnot((const char*) value1, calc_buffer);
1448 
1449 	DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
1450 
1451 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1452 		memcpy(buffer, calc_buffer, calc_buffer_size);
1453 	}
1454 }
1455 
sc_mul(const void * value1,const void * value2,void * buffer)1456 void sc_mul(const void *value1, const void *value2, void *buffer)
1457 {
1458 	CLEAR_BUFFER(calc_buffer);
1459 	carry_flag = 0;
1460 
1461 	DEBUGPRINTF_COMPUTATION(("%s * ", sc_print_hex(value1)));
1462 	DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
1463 
1464 	do_mul((const char*) value1, (const char*) value2, calc_buffer);
1465 
1466 	DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
1467 
1468 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1469 		memcpy(buffer, calc_buffer, calc_buffer_size);
1470 	}
1471 }
1472 
sc_div(const void * value1,const void * value2,void * buffer)1473 void sc_div(const void *value1, const void *value2, void *buffer)
1474 {
1475 	/* temp buffer holding unused result of divmod */
1476 	char *unused_res = (char*) alloca(calc_buffer_size);
1477 
1478 	CLEAR_BUFFER(calc_buffer);
1479 	carry_flag = 0;
1480 
1481 	DEBUGPRINTF_COMPUTATION(("%s / ", sc_print_hex(value1)));
1482 	DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
1483 
1484 	do_divmod((const char*) value1, (const char*) value2, calc_buffer, unused_res);
1485 
1486 	DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
1487 
1488 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1489 		memcpy(buffer, calc_buffer, calc_buffer_size);
1490 	}
1491 }
1492 
sc_mod(const void * value1,const void * value2,void * buffer)1493 void sc_mod(const void *value1, const void *value2, void *buffer)
1494 {
1495 	/* temp buffer holding unused result of divmod */
1496 	char *unused_res = (char*) alloca(calc_buffer_size);
1497 
1498 	CLEAR_BUFFER(calc_buffer);
1499 	carry_flag = 0;
1500 
1501 	DEBUGPRINTF_COMPUTATION(("%s %% ", sc_print_hex(value1)));
1502 	DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
1503 
1504 	do_divmod((const char*) value1, (const char*) value2, unused_res, calc_buffer);
1505 
1506 	DEBUGPRINTF_COMPUTATION(("%s\n", sc_print_hex(calc_buffer)));
1507 
1508 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1509 		memcpy(buffer, calc_buffer, calc_buffer_size);
1510 	}
1511 }
1512 
sc_divmod(const void * value1,const void * value2,void * div_buffer,void * mod_buffer)1513 void sc_divmod(const void *value1, const void *value2, void *div_buffer, void *mod_buffer)
1514 {
1515 	CLEAR_BUFFER(calc_buffer);
1516 	carry_flag = 0;
1517 
1518 	DEBUGPRINTF_COMPUTATION(("%s %% ", sc_print_hex(value1)));
1519 	DEBUGPRINTF_COMPUTATION(("%s -> ", sc_print_hex(value2)));
1520 
1521 	do_divmod((const char*) value1, (const char*) value2, (char*) div_buffer, (char*) mod_buffer);
1522 
1523 	DEBUGPRINTF_COMPUTATION(("%s:%s\n", sc_print_hex(div_buffer), sc_print_hex(mod_buffer)));
1524 }
1525 
1526 
sc_shlI(const void * val1,long shift_cnt,int bitsize,int sign,void * buffer)1527 void sc_shlI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer)
1528 {
1529 	carry_flag = 0;
1530 
1531 	DEBUGPRINTF_COMPUTATION(("%s << %ld ", sc_print_hex(value1), shift_cnt));
1532 	do_shl((const char*) val1, calc_buffer, shift_cnt, bitsize, sign);
1533 
1534 	DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
1535 
1536 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1537 		memmove(buffer, calc_buffer, calc_buffer_size);
1538 	}
1539 }
1540 
sc_shl(const void * val1,const void * val2,int bitsize,int sign,void * buffer)1541 void sc_shl(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
1542 {
1543 	long offset = sc_val_to_long(val2);
1544 
1545 	sc_shlI(val1, offset, bitsize, sign, buffer);
1546 }
1547 
sc_shrI(const void * val1,long shift_cnt,int bitsize,int sign,void * buffer)1548 void sc_shrI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer)
1549 {
1550 	carry_flag = 0;
1551 
1552 	DEBUGPRINTF_COMPUTATION(("%s >>u %ld ", sc_print_hex(value1), shift_cnt));
1553 	do_shr((const char*) val1, calc_buffer, shift_cnt, bitsize, sign, 0);
1554 
1555 	DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
1556 
1557 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1558 		memmove(buffer, calc_buffer, calc_buffer_size);
1559 	}
1560 }
1561 
sc_shr(const void * val1,const void * val2,int bitsize,int sign,void * buffer)1562 void sc_shr(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
1563 {
1564 	long shift_cnt = sc_val_to_long(val2);
1565 
1566 	sc_shrI(val1, shift_cnt, bitsize, sign, buffer);
1567 }
1568 
sc_shrsI(const void * val1,long shift_cnt,int bitsize,int sign,void * buffer)1569 void sc_shrsI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer)
1570 {
1571 	carry_flag = 0;
1572 
1573 	DEBUGPRINTF_COMPUTATION(("%s >>s %ld ", sc_print_hex(value1), shift_cnt));
1574 	do_shr((const char*) val1, calc_buffer, shift_cnt, bitsize, sign, 1);
1575 
1576 	DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
1577 
1578 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1579 		memmove(buffer, calc_buffer, calc_buffer_size);
1580 	}
1581 }
1582 
sc_shrs(const void * val1,const void * val2,int bitsize,int sign,void * buffer)1583 void sc_shrs(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
1584 {
1585 	long offset = sc_val_to_long(val2);
1586 
1587 	carry_flag = 0;
1588 
1589 	DEBUGPRINTF_COMPUTATION(("%s >>s %ld ", sc_print_hex(value1), offset));
1590 	do_shr((const char*) val1, calc_buffer, offset, bitsize, sign, 1);
1591 
1592 	DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
1593 
1594 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1595 		memmove(buffer, calc_buffer, calc_buffer_size);
1596 	}
1597 }
1598 
sc_rotl(const void * val1,const void * val2,int bitsize,int sign,void * buffer)1599 void sc_rotl(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
1600 {
1601 	long offset = sc_val_to_long(val2);
1602 
1603 	carry_flag = 0;
1604 
1605 	DEBUGPRINTF_COMPUTATION(("%s <<>> %ld ", sc_print_hex(value1), offset));
1606 	do_rotl((const char*) val1, calc_buffer, offset, bitsize, sign);
1607 
1608 	DEBUGPRINTF_COMPUTATION(("-> %s\n", sc_print_hex(calc_buffer)));
1609 
1610 	if ((buffer != NULL) && (buffer != calc_buffer)) {
1611 		memmove(buffer, calc_buffer, calc_buffer_size);
1612 	}
1613 }
1614 
sc_zero(void * buffer)1615 void sc_zero(void *buffer)
1616 {
1617 	if (buffer == NULL)
1618 		buffer = calc_buffer;
1619 	CLEAR_BUFFER(buffer);
1620 	carry_flag = 0;
1621 }
1622