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