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