4 /* shift bits with sign extension */
5 #define SHRS(v, c) ((v) < 0 ? ~((~(v)) >> (c)) : (v) >> (c))
7 #define SIGN(v) ((v)->part[0] & TC_VALUE_PART_SIGN_BIT)
9 /* the carry and overflow bits */
10 int tc_Carry, tc_Overflow;
13 * Produce a tc_value from a long value
15 void tc_from_long(tc_value *tcv, long value) {
18 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i) {
19 long part = value & TC_VALUE_PART_MASK;
20 tcv->part[i] = (tc_value_part)part;
21 value = SHRS(value, TC_VALUE_PART_SIZE);
26 * Bit complement an tc_value: res = ~a.
28 void tc_not(const tc_value *a, tc_value *res) {
31 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i)
32 res->part[i] = ~a->part[i] & TC_VALUE_PART_MAX_UINT;
36 * Logical AND of two tc_values: res = a & b.
38 void tc_and(const tc_value *a, const tc_value *b, tc_value *res) {
41 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i)
42 res->part[i] = a->part[i] & b->part[i];
46 * Logical OR of two tc_values: res = a | b.
48 void tc_or(const tc_value *a, const tc_value *b, tc_value *res) {
51 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i)
52 res->part[i] = a->part[i] | b->part[i];
56 * Logical exclusive OR of two tc_values: res = a ^ b.
58 void tc_eor(const tc_value *a, const tc_value *b, tc_value *res) {
61 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i)
62 res->part[i] = a->part[i] ^ b->part[i];
67 * Compare two tc_value's.
69 pn_Cmp tc_cmp(const tc_value *a, const tc_value *b, int signed_cmp) {
75 if (sign_a != !SIGN(b))
76 return sign_a ? pn_Cmp_Lt : pn_Cmp_Gt;
78 for (i = 0; i < NUM_VALUE_PARTS; ++i) {
79 if (a->part[i] > b->part[i])
81 if (a->part[i] < b->part[i])
88 * Add two tc_values: res = a + b. Sets carry and overflow.
90 void tc_add(const tc_value *a, const tc_value *b, tc_value *res) {
91 int i, carry = 0, sign_a;
93 tc_Carry = tc_Overflow = 0;
95 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i) {
96 tc_temp t = (tc_temp)a->part[i] + (tc_temp)b->part[i] + carry;
97 if (t > TC_VALUE_PART_MAX_UINT) {
98 t -= TC_VALUE_PART_MAX_UINT;
102 res->part[i] = (tc_value_part)t;
104 /* Check for overflow. */
107 /* A signed overflow occurred if the two operands have the same sign and
108 the result has a different sign. */
110 tc_Overflow = (sign_a == SIGN(b)) && (sign_a != SIGN(res));
114 * Subtract two tc_values: res = a - b. Sets carry and overflow.
116 void tc_sub(const tc_value *a, const tc_value *b, tc_value *res) {
120 tc_Carry = tc_Overflow = 0;
121 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i) {
123 t = (tc_temp)a->part[i] - (tc_temp)b->part[i] - borrow;
125 t += TC_VALUE_PART_MAX_UINT + 1;
129 res->part[i] = (tc_value_part)t;
131 /* Check for underflow or overflow. */
133 /* A signed overflow occurred if the two operands have the same sign and
134 the result has a different sign. */
136 tc_Overflow = (sign_a == SIGN(b)) && (sign_a != SIGN(res));
140 * Negate an tc_value: res = -a. Sets carry and overflow.
142 void tc_neg(const tc_value *a, tc_value *res) {
143 tc_from_long(res, 0);
147 #define NUM_WORK_PARTS (NUM_VALUE_PARTS * 2)
150 * Multiply two unsigned tc_values producing a double precision result : w = a * b.
152 static void _tc_umul(const tc_value *a, const tc_value *b, tc_value_part *w) {
153 const tc_value_part *u = a->part;
154 const tc_value_part *v = b->part;
158 for (i = 0; i < NUM_WORK_PARTS; ++i)
161 for (j = NUM_VALUE_PARTS - 1; j >= 0; --j) {
163 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i) {
164 tc_temp t = u[i] * v[j] + k;
165 w[i + j] = t & TC_VALUE_PART_MASK;
168 w[j + NUM_VALUE_PARTS] = k & TC_VALUE_PART_MASK;
173 * Multiply two unsigned tc_values: res = a * b.
175 void tc_umul(const tc_value *a, const tc_value *b, tc_value *res) {
176 tc_value_part w[NUM_WORK_PARTS];
181 /* copy the lower result bits */
182 for (i = 0; i < NUM_VALUE_PARTS; ++i)
183 res->part[i] = (tc_value_part)w[i];
185 /* check for overflow */
186 for (; i < NUM_WORK_PARTS; ++i) {
192 tc_Overflow = tc_Carry = ov;
197 * Multiply two signed tc_values: res = a * b.
199 void tc_smul(const tc_value *a, const tc_value *b, tc_value *res) {
200 tc_value_part w[NUM_WORK_PARTS];
201 int i, ov = 0, neg_res = 0;
202 const tc_value *u = a, *v = b;
218 /* copy the lower result bits */
219 for (i = 0; i < NUM_VALUE_PARTS; ++i)
220 res->part[i] = (tc_value_part)w[i];
222 /* check for overflow */
223 for (; i < NUM_WORK_PARTS; ++i) {
233 tc_Overflow = tc_Carry = ov;
237 * Multiply two unsigned tc_values: divres = a / b, modres = a % b.
239 static void _tc_divmodu(const tc_value *a, const tc_value *b, tc_value **divres, tc_value **modres) {
240 static tc_value zero;
243 /* Check for division by 0, 0 / x, and a < b */
244 tc_from_long(&zero, 0);
245 if (tc_cmp(b, &zero, 0) == pn_Cmp_Eq) {
249 tc_Carry = tc_Overflow = 1;
252 if (tc_cmp(a, &zero, 0) == pn_Cmp_Eq) {
256 tc_Carry = tc_Overflow = 0;
259 if (tc_cmp(a, b, 0) == pn_Cmp_Lt) {
260 /* a < b ==> a / b = 0 mod a */
263 tc_Carry = tc_Overflow = 0;