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