2 * This file is part of libFirm.
3 * Copyright (C) 2012 University of Karlsruhe.
8 * @brief Provides basic mathematical operations on values represented as strings.
10 * @author Mathias Heil
25 * local definitions and macros
28 #define SC_RESULT(x) ((x) & ((1U << SC_BITS) - 1U))
29 #define SC_CARRY(x) ((unsigned)(x) >> SC_BITS)
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)
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 */
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! */
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 };
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} }
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"
82 /*****************************************************************************
84 *****************************************************************************/
87 * implements the bitwise NOT operation
89 static void do_bitnot(const char *val, char *buffer)
93 for (counter = 0; counter<calc_buffer_size; counter++)
94 buffer[counter] = val[counter] ^ SC_F;
98 * implements the bitwise OR operation
100 static void do_bitor(const char *val1, const char *val2, char *buffer)
104 for (counter = 0; counter<calc_buffer_size; counter++)
105 buffer[counter] = val1[counter] | val2[counter];
109 * implements the bitwise eXclusive OR operation
111 static void do_bitxor(const char *val1, const char *val2, char *buffer)
115 for (counter = 0; counter<calc_buffer_size; counter++)
116 buffer[counter] = val1[counter] ^ val2[counter];
120 * implements the bitwise AND operation
122 static void do_bitand(const char *val1, const char *val2, char *buffer)
126 for (counter = 0; counter<calc_buffer_size; counter++)
127 buffer[counter] = val1[counter] & val2[counter];
131 * implements the bitwise AND not operation
133 static void do_bitandnot(const char *val1, const char *val2, char *buffer)
137 for (counter = 0; counter < calc_buffer_size; ++counter)
138 buffer[counter] = val1[counter] & (SC_F ^ val2[counter]);
142 * returns the sign bit.
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
147 static int do_sign(const char *val)
149 return (val[calc_buffer_size-1] <= SC_7) ? (1) : (-1);
153 * returns non-zero if bit at position pos is set
155 static int do_bit(const char *val, int pos)
158 int nibble = pos >> 2;
160 return _bitisset(val[nibble], bit);
164 * Implements a fast ADD + 1
166 static void do_inc(const char *val, char *buffer)
170 while (counter++ < calc_buffer_size) {
175 /* No carry here, *val != SC_F */
176 *buffer = *val + SC_1;
180 /* here a carry could be lost, this is intended because this should
181 * happen only when a value changes sign. */
185 * Implements a unary MINUS
187 static void do_negate(const char *val, char *buffer)
189 do_bitnot(val, buffer);
190 do_inc(buffer, buffer);
194 * Implements a binary ADD
196 * @todo The implementation of carry is wrong, as it is the
197 * calc_buffer_size carry, not the mode depending
199 static void do_add(const char *val1, const char *val2, char *buffer)
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);
207 carry_flag = carry != SC_0;
211 * Implements a binary SUB
213 static void do_sub(const char *val1, const char *val2, char *buffer)
215 char *temp_buffer = (char*) alloca(calc_buffer_size); /* intermediate buffer to hold -val2 */
217 do_negate(val2, temp_buffer);
218 do_add(val1, temp_buffer, buffer);
222 * Implements a binary MUL
224 static void do_mul(const char *val1, const char *val2, char *buffer)
226 char *temp_buffer; /* result buffer */
227 char *neg_val1; /* abs of val1 */
228 char *neg_val2; /* abs of val2 */
230 char sign = 0; /* marks result sign */
231 int c_inner, c_outer; /* loop counters */
233 temp_buffer = (char*) alloca(calc_buffer_size);
234 neg_val1 = (char*) alloca(calc_buffer_size);
235 neg_val2 = (char*) alloca(calc_buffer_size);
237 /* init result buffer to zeros */
238 memset(temp_buffer, SC_0, calc_buffer_size);
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);
247 if (do_sign(val2) == -1) {
248 do_negate(val2, neg_val2);
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. */
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;
267 /* all carries together result in new carry. This is always smaller *
269 * Both multiplicands, the carry and the value already in the temp *
270 * buffer are single digits and their value is therefore at most *
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);
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;
287 do_negate(temp_buffer, buffer);
289 memcpy(buffer, temp_buffer, calc_buffer_size);
293 * Shift the buffer to left and add a 4 bit digit
295 static void do_push(const char digit, char *buffer)
299 for (counter = calc_buffer_size - 2; counter >= 0; counter--) {
300 buffer[counter+1] = buffer[counter];
306 * Implements truncating integer division and remainder.
308 * Note: This is MOST slow
310 static void do_divmod(const char *rDividend, const char *divisor, char *quot, char *rem)
312 const char *dividend = rDividend;
313 const char *minus_divisor;
317 char div_sign = 0; /* remember division result sign */
318 char rem_sign = 0; /* remember remainder result sign */
320 int c_dividend; /* loop counters */
322 neg_val1 = (char*) alloca(calc_buffer_size);
323 neg_val2 = (char*) alloca(calc_buffer_size);
325 /* clear result buffer */
326 memset(quot, SC_0, calc_buffer_size);
327 memset(rem, SC_0, calc_buffer_size);
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!");
332 /* if the dividend is zero result is zero (quot is zero) */
333 if (sc_comp(dividend, quot) == ir_relation_equal)
336 if (do_sign(dividend) == -1) {
337 do_negate(dividend, neg_val1);
343 do_negate(divisor, neg_val2);
344 if (do_sign(divisor) == -1) {
346 minus_divisor = divisor;
349 minus_divisor = neg_val2;
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 */
358 case ir_relation_less: /* dividend < divisor */
359 memcpy(rem, dividend, calc_buffer_size);
362 default: /* unluckily division is necessary :( */
366 for (c_dividend = calc_buffer_size - 1; c_dividend >= 0; c_dividend--) {
367 do_push(dividend[c_dividend], rem);
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);
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);
380 /* subtracted one too much */
381 do_add(rem, divisor, rem);
385 /* sets carry if remainder is non-zero ??? */
386 carry_flag = !sc_is_zero(rem);
389 do_negate(quot, quot);
396 * Implements a Shift Left, which can either preserve the sign bit
399 * @todo Assertions seems to be wrong
401 static void do_shl(const char *val1, char *buffer, long shift_cnt, int bitsize, unsigned is_signed)
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"));
411 /* if shifting far enough the result is zero */
412 if (shift_cnt >= bitsize) {
413 memset(buffer, SC_0, calc_buffer_size);
417 unsigned const shift = shift_cnt % SC_BITS;
418 shift_cnt = shift_cnt / 4;
420 /* shift the single digits some bytes (offset) and some bits (table)
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);
429 unsigned const shl = val1[counter] << shift | carry;
430 buffer[counter + shift_cnt] = SC_RESULT(shl);
433 bitoffset = counter - 1;
436 /* fill with zeroes */
437 for (counter = 0; counter < shift_cnt; counter++)
438 buffer[counter] = SC_0;
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;
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;
459 * Implements a Shift Right, which can either preserve the sign bit
462 * @param bitsize bitsize of the value to be shifted
464 * @todo Assertions seems to be wrong
466 static void do_shr(const char *val1, char *buffer, long shift_cnt, int bitsize, unsigned is_signed, int signed_shift)
472 int shift_mod, shift_nib;
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"));
481 sign = signed_shift && do_bit(val1, bitsize - 1) ? SC_F : SC_0;
483 /* if shifting far enough the result is either 0 or -1 */
484 if (shift_cnt >= bitsize) {
485 if (!sc_is_zero(val1)) {
488 memset(buffer, sign, calc_buffer_size);
492 shift_mod = shift_cnt & 3;
493 shift_nib = shift_cnt >> 2;
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) {
502 if ((_val(val1[counter]) & ((1<<shift_mod)-1)) != 0)
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];
513 /* the last digit is special in regard of signed/unsigned shift */
514 bitoffset = bitsize & 3;
515 msd = sign; /* most significant digit */
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];
522 shrs = shrs_table[_val(msd)][shift_mod];
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];
528 buffer[counter] = shrs[0];
532 buffer[counter - 1] |= shrs[1];
534 /* fill with SC_F or SC_0 depending on sign */
535 for (counter++; counter < calc_buffer_size; counter++) {
536 buffer[counter] = sign;
541 * Implements a Rotate Left.
542 * positive: low-order -> high order, negative other direction
544 static void do_rotl(const char *val1, char *buffer, long offset, int radius, unsigned is_signed)
547 temp1 = (char*) alloca(calc_buffer_size);
548 temp2 = (char*) alloca(calc_buffer_size);
550 offset = offset % radius;
552 /* rotation by multiples of the type length is identity */
554 memmove(buffer, val1, calc_buffer_size);
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 */
564 /*****************************************************************************
565 * public functions, declared in strcalc.h
566 *****************************************************************************/
567 const void *sc_get_buffer(void)
569 return (void*)calc_buffer;
572 int sc_get_buffer_length(void)
574 return calc_buffer_size;
578 * Do sign extension if the mode is signed, otherwise to zero extension.
580 void sign_extend(void *buffer, ir_mode *mode)
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];
588 if (mode_is_signed(mode)) {
589 if (calc_buffer[nibble] > max) {
590 /* sign bit is set, we need sign expansion */
592 for (i = nibble + 1; i < calc_buffer_size; ++i)
593 calc_buffer[i] = SC_F;
594 calc_buffer[nibble] |= sex_digit[bits & 3];
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];
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];
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)
613 /* C standard guarantees that '0'-'9' is a range */
626 int sc_val_from_str(char sign, unsigned base, const char *str,
627 size_t len, void *buffer)
631 assert(sign == -1 || sign == 1);
636 assert(base > 1 && base <= 16);
637 sc_base = (char*) alloca(calc_buffer_size);
638 sc_val_from_ulong(base, sc_base);
640 val = (char*) alloca(calc_buffer_size);
642 buffer = calc_buffer;
644 CLEAR_BUFFER(buffer);
647 /* BEGIN string evaluation, from left to right */
651 if (c >= '0' && c <= '9')
653 else if (c >= 'A' && c <= 'F')
655 else if (c >= 'a' && c <= 'f')
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);
671 /* get ready for the next letter */
677 do_negate((const char*) buffer, (char*) buffer);
682 void sc_val_from_long(long value, void *buffer)
685 char sign, is_minlong;
687 if (buffer == NULL) buffer = calc_buffer;
688 pos = (char*) buffer;
691 is_minlong = value == LONG_MIN;
693 /* use absolute value, special treatment of MIN_LONG to avoid overflow */
701 CLEAR_BUFFER(buffer);
703 while ((value != 0) && (pos < (char*)buffer + calc_buffer_size)) {
704 *pos++ = _digit(value & 0xf);
710 do_inc((const char*) buffer, (char*) buffer);
712 do_negate((const char*) buffer, (char*) buffer);
716 void sc_val_from_ulong(unsigned long value, void *buffer)
720 if (buffer == NULL) buffer = calc_buffer;
721 pos = (unsigned char*) buffer;
723 while (pos < (unsigned char *)buffer + calc_buffer_size) {
724 *pos++ = (unsigned char)_digit(value & 0xf);
729 long sc_val_to_long(const void *val)
734 for (i = calc_buffer_size - 1; i >= 0; i--) {
735 l = (l << 4) + _val(((char *)val)[i]);
740 void sc_min_from_bits(unsigned int num_bits, unsigned int sign, void *buffer)
745 if (buffer == NULL) buffer = calc_buffer;
746 CLEAR_BUFFER(buffer);
748 if (!sign) return; /* unsigned means minimum is 0(zero) */
750 pos = (char*) buffer;
753 for (i = 0; i < bits/4; i++)
756 *pos++ = min_digit[bits%4];
758 for (i++; i <= calc_buffer_size - 1; i++)
762 void sc_max_from_bits(unsigned int num_bits, unsigned int sign, void *buffer)
767 if (buffer == NULL) buffer = calc_buffer;
768 CLEAR_BUFFER(buffer);
769 pos = (char*) buffer;
771 bits = num_bits - sign;
772 for (i = 0; i < bits/4; i++)
775 *pos++ = max_digit[bits%4];
777 for (i++; i <= calc_buffer_size - 1; i++)
781 void sc_truncate(unsigned int num_bits, void *buffer)
783 char *cbuffer = (char*) buffer;
784 char *pos = cbuffer + (num_bits / 4);
785 char *end = cbuffer + calc_buffer_size;
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;
796 for ( ; pos < end; ++pos)
800 ir_relation sc_comp(void const* const value1, void const* const value2)
802 int counter = calc_buffer_size - 1;
803 const char *val1 = (const char *)value1;
804 const char *val2 = (const char *)value2;
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;
811 /* loop until two digits differ, the values are equal if there
812 * are no such two digits */
813 while (val1[counter] == val2[counter]) {
815 if (counter < 0) return ir_relation_equal;
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;
824 int sc_get_highest_set_bit(const void *value)
826 const char *val = (const char*)value;
829 high = calc_buffer_size * 4 - 1;
831 for (counter = calc_buffer_size-1; counter >= 0; counter--) {
832 if (val[counter] == SC_0)
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;
844 int sc_get_lowest_set_bit(const void *value)
846 const char *val = (const char*)value;
850 for (counter = 0; counter < calc_buffer_size; counter++) {
851 switch (val[counter]) {
878 int sc_get_bit_at(const void *value, unsigned pos)
880 const char *val = (const char*) value;
881 unsigned nibble = pos >> 2;
883 return (val[nibble] & SHIFT(pos & 3)) != SC_0;
886 void sc_set_bit_at(void *value, unsigned pos)
888 char *val = (char*) value;
889 unsigned nibble = pos >> 2;
891 val[nibble] |= SHIFT(pos & 3);
894 int sc_is_zero(const void *value)
896 const char* val = (const char *)value;
899 for (counter = 0; counter < calc_buffer_size; ++counter) {
900 if (val[counter] != SC_0)
906 int sc_is_negative(const void *value)
908 return do_sign((const char*) value) == -1;
911 int sc_had_carry(void)
916 unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs)
918 const char *val = (const char *)value;
919 int nibble_ofs = 2 * byte_ofs;
922 /* the current scheme uses one byte to store a nibble */
923 if (4 * nibble_ofs >= len)
926 res = _val(val[nibble_ofs]);
927 if (len > 4 * (nibble_ofs + 1))
928 res |= _val(val[nibble_ofs + 1]) << 4;
930 /* kick bits outsize */
931 if (len - 8 * byte_ofs < 8) {
932 res &= (1 << (len - 8 * byte_ofs)) - 1;
938 * convert to a string
939 * FIXME: Doesn't check buffer bounds
941 const char *sc_print(const void *value, unsigned bits, enum base_t base, int signed_mode)
943 static const char big_digits[] = "0123456789ABCDEF";
944 static const char small_digits[] = "0123456789abcdef";
946 char *base_val, *div1_res, *div2_res, *rem_res;
947 int counter, nibbles, i, sign, mask;
950 const char *val = (const char *)value;
954 const char *digits = small_digits;
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);
961 pos = output_buffer + bit_pattern_size;
966 bits = bit_pattern_size;
974 for (counter = 0; counter < nibbles; ++counter) {
975 *(--pos) = digits[_val(val[counter])];
978 /* last nibble must be masked */
980 mask = zex_digit[(bits & 3) - 1];
981 x = val[counter++] & mask;
982 *(--pos) = digits[_val(x)];
986 for (; counter > 1; --counter, ++pos) {
993 for (counter = 0; counter < nibbles; ++counter) {
995 p = binary_table[_val(val[counter])];
1002 /* last nibble must be masked */
1004 mask = zex_digit[(bits & 3) - 1];
1005 x = val[counter++] & mask;
1008 p = binary_table[_val(x)];
1015 /* now kill zeros */
1016 for (counter <<= 2; counter > 1; --counter, ++pos)
1023 memset(base_val, SC_0, calc_buffer_size);
1024 base_val[0] = base == SC_DEC ? SC_A : SC_8;
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);
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];
1042 /* last nibble must be masked */
1044 mask = zex_digit[(bits & 3) - 1];
1045 div1_res[counter] = p[counter] & mask;
1052 do_divmod(m, base_val, n, rem_res);
1056 *(--pos) = digits[_val(rem_res[0])];
1059 for (i = 0; i < calc_buffer_size; ++i)
1070 panic("Unsupported base %d", base);
1075 void init_strcalc(int precision)
1077 if (calc_buffer == NULL) {
1078 if (precision <= 0) precision = SC_DEFAULT_PRECISION;
1080 /* round up to multiple of 4 */
1081 precision = (precision + 3) & ~3;
1083 bit_pattern_size = (precision);
1084 calc_buffer_size = (precision / 2);
1085 max_value_size = (precision / 4);
1087 calc_buffer = XMALLOCN(char, calc_buffer_size + 1);
1088 output_buffer = XMALLOCN(char, bit_pattern_size + 1);
1093 void finish_strcalc(void)
1095 free(calc_buffer); calc_buffer = NULL;
1096 free(output_buffer); output_buffer = NULL;
1099 int sc_get_precision(void)
1101 return bit_pattern_size;
1105 void sc_add(const void *value1, const void *value2, void *buffer)
1107 CLEAR_BUFFER(calc_buffer);
1110 do_add((const char*) value1, (const char*) value2, (char*) calc_buffer);
1112 if ((buffer != NULL) && (buffer != calc_buffer)) {
1113 memcpy(buffer, calc_buffer, calc_buffer_size);
1117 void sc_sub(const void *value1, const void *value2, void *buffer)
1119 CLEAR_BUFFER(calc_buffer);
1122 do_sub((const char*) value1, (const char*) value2, calc_buffer);
1124 if ((buffer != NULL) && (buffer != calc_buffer)) {
1125 memcpy(buffer, calc_buffer, calc_buffer_size);
1129 void sc_neg(const void *value1, void *buffer)
1133 do_negate((const char*) value1, calc_buffer);
1135 if ((buffer != NULL) && (buffer != calc_buffer)) {
1136 memcpy(buffer, calc_buffer, calc_buffer_size);
1140 void sc_and(const void *value1, const void *value2, void *buffer)
1142 CLEAR_BUFFER(calc_buffer);
1145 do_bitand((const char*) value1, (const char*) value2, calc_buffer);
1147 if ((buffer != NULL) && (buffer != calc_buffer)) {
1148 memcpy(buffer, calc_buffer, calc_buffer_size);
1152 void sc_andnot(const void *value1, const void *value2, void *buffer)
1154 CLEAR_BUFFER(calc_buffer);
1157 do_bitandnot((const char*) value1, (const char*) value2, calc_buffer);
1159 if (buffer != NULL && buffer != calc_buffer) {
1160 memcpy(buffer, calc_buffer, calc_buffer_size);
1164 void sc_or(const void *value1, const void *value2, void *buffer)
1166 CLEAR_BUFFER(calc_buffer);
1169 do_bitor((const char*) value1, (const char*) value2, calc_buffer);
1171 if ((buffer != NULL) && (buffer != calc_buffer)) {
1172 memcpy(buffer, calc_buffer, calc_buffer_size);
1176 void sc_xor(const void *value1, const void *value2, void *buffer)
1178 CLEAR_BUFFER(calc_buffer);
1181 do_bitxor((const char*) value1, (const char*) value2, calc_buffer);
1183 if ((buffer != NULL) && (buffer != calc_buffer)) {
1184 memcpy(buffer, calc_buffer, calc_buffer_size);
1188 void sc_not(const void *value1, void *buffer)
1190 CLEAR_BUFFER(calc_buffer);
1193 do_bitnot((const char*) value1, calc_buffer);
1195 if ((buffer != NULL) && (buffer != calc_buffer)) {
1196 memcpy(buffer, calc_buffer, calc_buffer_size);
1200 void sc_mul(const void *value1, const void *value2, void *buffer)
1202 CLEAR_BUFFER(calc_buffer);
1205 do_mul((const char*) value1, (const char*) value2, calc_buffer);
1207 if ((buffer != NULL) && (buffer != calc_buffer)) {
1208 memcpy(buffer, calc_buffer, calc_buffer_size);
1212 void sc_div(const void *value1, const void *value2, void *buffer)
1214 /* temp buffer holding unused result of divmod */
1215 char *unused_res = (char*) alloca(calc_buffer_size);
1217 CLEAR_BUFFER(calc_buffer);
1220 do_divmod((const char*) value1, (const char*) value2, calc_buffer, unused_res);
1222 if ((buffer != NULL) && (buffer != calc_buffer)) {
1223 memcpy(buffer, calc_buffer, calc_buffer_size);
1227 void sc_mod(const void *value1, const void *value2, void *buffer)
1229 /* temp buffer holding unused result of divmod */
1230 char *unused_res = (char*) alloca(calc_buffer_size);
1232 CLEAR_BUFFER(calc_buffer);
1235 do_divmod((const char*) value1, (const char*) value2, unused_res, calc_buffer);
1237 if ((buffer != NULL) && (buffer != calc_buffer)) {
1238 memcpy(buffer, calc_buffer, calc_buffer_size);
1242 void sc_divmod(const void *value1, const void *value2, void *div_buffer, void *mod_buffer)
1244 CLEAR_BUFFER(calc_buffer);
1247 do_divmod((const char*) value1, (const char*) value2, (char*) div_buffer, (char*) mod_buffer);
1251 void sc_shlI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer)
1255 do_shl((const char*) val1, calc_buffer, shift_cnt, bitsize, sign);
1257 if ((buffer != NULL) && (buffer != calc_buffer)) {
1258 memmove(buffer, calc_buffer, calc_buffer_size);
1262 void sc_shl(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
1264 long offset = sc_val_to_long(val2);
1266 sc_shlI(val1, offset, bitsize, sign, buffer);
1269 void sc_shrI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer)
1273 do_shr((const char*) val1, calc_buffer, shift_cnt, bitsize, sign, 0);
1275 if ((buffer != NULL) && (buffer != calc_buffer)) {
1276 memmove(buffer, calc_buffer, calc_buffer_size);
1280 void sc_shr(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
1282 long shift_cnt = sc_val_to_long(val2);
1284 sc_shrI(val1, shift_cnt, bitsize, sign, buffer);
1287 void sc_shrsI(const void *val1, long shift_cnt, int bitsize, int sign, void *buffer)
1291 do_shr((const char*) val1, calc_buffer, shift_cnt, bitsize, sign, 1);
1293 if ((buffer != NULL) && (buffer != calc_buffer)) {
1294 memmove(buffer, calc_buffer, calc_buffer_size);
1298 void sc_shrs(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
1300 long offset = sc_val_to_long(val2);
1304 do_shr((const char*) val1, calc_buffer, offset, bitsize, sign, 1);
1306 if ((buffer != NULL) && (buffer != calc_buffer)) {
1307 memmove(buffer, calc_buffer, calc_buffer_size);
1311 void sc_rotl(const void *val1, const void *val2, int bitsize, int sign, void *buffer)
1313 long offset = sc_val_to_long(val2);
1317 do_rotl((const char*) val1, calc_buffer, offset, bitsize, sign);
1319 if ((buffer != NULL) && (buffer != calc_buffer)) {
1320 memmove(buffer, calc_buffer, calc_buffer_size);
1324 void sc_zero(void *buffer)
1327 buffer = calc_buffer;
1328 CLEAR_BUFFER(buffer);