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) {
72 for (i = 0; i < NUM_VALUE_PARTS; ++i) {
73 if (a->part[i] > b->part[i])
75 if (a->part[i] < b->part[i])
82 * Add two tc_values: res = a + b. Sets carry and overflow.
84 void tc_add(const tc_value *a, const tc_value *b, tc_value *res) {
85 int i, carry = 0, sign_a;
87 tc_Carry = tc_Overflow = 0;
89 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i) {
90 tc_temp t = (tc_temp)a->part[i] + (tc_temp)b->part[i] + carry;
91 if (t > TC_VALUE_PART_MAX_UINT) {
92 t -= TC_VALUE_PART_MAX_UINT;
96 res->part[i] = (tc_value_part)t;
98 /* Check for overflow. */
101 /* A signed overflow occurred if the two operands have the same sign and
102 the result has a different sign. */
104 tc_Overflow = (sign_a == SIGN(b)) && (sign_a != SIGN(res));
108 * Subtract two tc_values: res = a - b. Sets carry and overflow.
110 void tc_sub(const tc_value *a, const tc_value *b, tc_value *res) {
114 tc_Carry = tc_Overflow = 0;
115 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i) {
117 t = (tc_temp)a->part[i] - (tc_temp)b->part[i] - borrow;
119 t += TC_VALUE_PART_MAX_UINT + 1;
123 res->part[i] = (tc_value_part)t;
125 /* Check for underflow or overflow. */
127 /* A signed overflow occurred if the two operands have the same sign and
128 the result has a different sign. */
130 tc_Overflow = (sign_a == SIGN(b)) && (sign_a != SIGN(res));
134 * Negate an tc_value: res = -a. Sets carry and overflow.
136 void tc_neg(const tc_value *a, tc_value *res) {
137 tc_from_long(res, 0);
141 #define NUM_WORK_PARTS (NUM_VALUE_PARTS * 2)
144 * Multiply two unsigned tc_values producing a double precision result : w = a * b.
146 static void _tc_umul(const tc_value *a, const tc_value *b, unsigned tc_value_part *w) {
147 unsigned tc_value_part *u = &a->part;
148 unsigned tc_value_part *v = &b->part;
152 for (i = 0; i < NUM_WORK_PARTS; ++i)
155 for (j = NUM_VALUE_PARTS - 1; j >= 0; --j) {
156 unsigned tc_temp k = 0;
157 for (i = NUM_VALUE_PARTS - 1; i >= 0; --i) {
158 tc_temp t = u[i] * v[j] + k;
159 w[i + j] = t & TC_VALUE_PART_MASK;
162 w[j + NUM_VALUE_PARTS] = k & TC_VALUE_PART_MASK;
167 * Multiply two unsigned tc_values: res = a * b.
169 static void tc_umul(const tc_value *a, const tc_value *b, tc_value *res) {
170 unsigned tc_value_part w[NUM_WORK_PARTS];
175 /* copy the lower result bits */
176 for (i = 0; i < NUM_VALUE_PARTS; ++i)
177 res->part[i] = (tc_value_part)w[i];
179 /* check for overflow */
180 for (; i < NUM_WORK_PARTS; ++i) {
186 tc_Overflow = tc_Carry = ov;
190 * Multiply two unsigned tc_values: res = a * b.
192 static void tc_umul(const tc_value *a, const tc_value *b, tc_value *res) {
193 unsigned tc_value_part w[NUM_WORK_PARTS];
198 /* copy the lower result bits */
199 for (i = 0; i < NUM_VALUE_PARTS; ++i)
200 res->part[i] = (tc_value_part)w[i];
202 /* check for overflow */
203 for (; i < NUM_WORK_PARTS; ++i) {
209 tc_Overflow = tc_Carry = ov;
212 * Multiply two signed tc_values: res = a * b.
214 static void tc_smul(const tc_value *a, const tc_value *b, tc_value *res) {
215 unsigned tc_value_part w[NUM_WORK_PARTS];
216 int i, ov = 0, neg_res = 0;
217 const tc_value *u = a, *v = b;
233 /* copy the lower result bits */
234 for (i = 0; i < NUM_VALUE_PARTS; ++i)
235 res->part[i] = (tc_value_part)w[i];
237 /* check for overflow */
238 for (; i < NUM_WORK_PARTS; ++i) {
248 tc_Overflow = tc_Carry = ov;